From 871480933a1c28f8a9fed4c4d34d06c439a7a422 Mon Sep 17 00:00:00 2001 From: Srikant Patnaik Date: Sun, 11 Jan 2015 12:28:04 +0530 Subject: Moved, renamed, and deleted files The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure. --- ANDROID_3.4.5/drivers/gpu/drm/Kconfig | 188 - ANDROID_3.4.5/drivers/gpu/drm/Makefile | 45 - ANDROID_3.4.5/drivers/gpu/drm/README.drm | 43 - ANDROID_3.4.5/drivers/gpu/drm/ati_pcigart.c | 202 - ANDROID_3.4.5/drivers/gpu/drm/drm_agpsupport.c | 469 - ANDROID_3.4.5/drivers/gpu/drm/drm_auth.c | 194 - ANDROID_3.4.5/drivers/gpu/drm/drm_buffer.c | 185 - ANDROID_3.4.5/drivers/gpu/drm/drm_bufs.c | 1626 ---- ANDROID_3.4.5/drivers/gpu/drm/drm_cache.c | 100 - ANDROID_3.4.5/drivers/gpu/drm/drm_context.c | 462 - ANDROID_3.4.5/drivers/gpu/drm/drm_crtc.c | 3470 ------- ANDROID_3.4.5/drivers/gpu/drm/drm_crtc_helper.c | 1058 --- ANDROID_3.4.5/drivers/gpu/drm/drm_debugfs.c | 242 - ANDROID_3.4.5/drivers/gpu/drm/drm_dma.c | 162 - ANDROID_3.4.5/drivers/gpu/drm/drm_dp_i2c_helper.c | 208 - ANDROID_3.4.5/drivers/gpu/drm/drm_drv.c | 505 -- ANDROID_3.4.5/drivers/gpu/drm/drm_edid.c | 1816 ---- ANDROID_3.4.5/drivers/gpu/drm/drm_edid_load.c | 250 - ANDROID_3.4.5/drivers/gpu/drm/drm_edid_modes.h | 664 -- ANDROID_3.4.5/drivers/gpu/drm/drm_encoder_slave.c | 125 - ANDROID_3.4.5/drivers/gpu/drm/drm_fb_helper.c | 1410 --- ANDROID_3.4.5/drivers/gpu/drm/drm_fops.c | 674 -- ANDROID_3.4.5/drivers/gpu/drm/drm_gem.c | 722 -- ANDROID_3.4.5/drivers/gpu/drm/drm_global.c | 112 - ANDROID_3.4.5/drivers/gpu/drm/drm_hashtab.c | 197 - ANDROID_3.4.5/drivers/gpu/drm/drm_info.c | 315 - ANDROID_3.4.5/drivers/gpu/drm/drm_ioc32.c | 1085 --- ANDROID_3.4.5/drivers/gpu/drm/drm_ioctl.c | 356 - ANDROID_3.4.5/drivers/gpu/drm/drm_irq.c | 1348 --- ANDROID_3.4.5/drivers/gpu/drm/drm_lock.c | 377 - ANDROID_3.4.5/drivers/gpu/drm/drm_memory.c | 144 - ANDROID_3.4.5/drivers/gpu/drm/drm_mm.c | 717 -- ANDROID_3.4.5/drivers/gpu/drm/drm_modes.c | 1182 --- ANDROID_3.4.5/drivers/gpu/drm/drm_pci.c | 467 - ANDROID_3.4.5/drivers/gpu/drm/drm_platform.c | 206 - ANDROID_3.4.5/drivers/gpu/drm/drm_prime.c | 304 - ANDROID_3.4.5/drivers/gpu/drm/drm_proc.c | 221 - ANDROID_3.4.5/drivers/gpu/drm/drm_scatter.c | 213 - ANDROID_3.4.5/drivers/gpu/drm/drm_stub.c | 520 -- ANDROID_3.4.5/drivers/gpu/drm/drm_sysfs.c | 566 -- ANDROID_3.4.5/drivers/gpu/drm/drm_trace.h | 66 - ANDROID_3.4.5/drivers/gpu/drm/drm_trace_points.c | 4 - ANDROID_3.4.5/drivers/gpu/drm/drm_usb.c | 120 - ANDROID_3.4.5/drivers/gpu/drm/drm_vm.c | 692 -- ANDROID_3.4.5/drivers/gpu/drm/exynos/Kconfig | 29 - ANDROID_3.4.5/drivers/gpu/drm/exynos/Makefile | 17 - ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_ddc.c | 57 - .../drivers/gpu/drm/exynos/exynos_drm_buf.c | 213 - .../drivers/gpu/drm/exynos/exynos_drm_buf.h | 47 - .../drivers/gpu/drm/exynos/exynos_drm_connector.c | 354 - .../drivers/gpu/drm/exynos/exynos_drm_connector.h | 34 - .../drivers/gpu/drm/exynos/exynos_drm_core.c | 217 - .../drivers/gpu/drm/exynos/exynos_drm_crtc.c | 432 - .../drivers/gpu/drm/exynos/exynos_drm_crtc.h | 63 - .../drivers/gpu/drm/exynos/exynos_drm_drv.c | 366 - .../drivers/gpu/drm/exynos/exynos_drm_drv.h | 290 - .../drivers/gpu/drm/exynos/exynos_drm_encoder.c | 445 - .../drivers/gpu/drm/exynos/exynos_drm_encoder.h | 52 - .../drivers/gpu/drm/exynos/exynos_drm_fb.c | 213 - .../drivers/gpu/drm/exynos/exynos_drm_fb.h | 55 - .../drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 318 - .../drivers/gpu/drm/exynos/exynos_drm_fbdev.h | 37 - .../drivers/gpu/drm/exynos/exynos_drm_fimd.c | 1022 --- .../drivers/gpu/drm/exynos/exynos_drm_gem.c | 742 -- .../drivers/gpu/drm/exynos/exynos_drm_gem.h | 153 - .../drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 377 - .../drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 73 - .../drivers/gpu/drm/exynos/exynos_drm_plane.c | 171 - .../drivers/gpu/drm/exynos/exynos_drm_plane.h | 14 - .../drivers/gpu/drm/exynos/exynos_drm_vidi.c | 680 -- .../drivers/gpu/drm/exynos/exynos_drm_vidi.h | 36 - ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.c | 2389 ----- ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.h | 37 - .../drivers/gpu/drm/exynos/exynos_hdmiphy.c | 58 - .../drivers/gpu/drm/exynos/exynos_mixer.c | 1112 --- ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-hdmi.h | 561 -- ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-mixer.h | 141 - ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-vp.h | 91 - ANDROID_3.4.5/drivers/gpu/drm/gma500/Kconfig | 33 - ANDROID_3.4.5/drivers/gpu/drm/gma500/Makefile | 50 - ANDROID_3.4.5/drivers/gpu/drm/gma500/accel_2d.c | 364 - ANDROID_3.4.5/drivers/gpu/drm/gma500/backlight.c | 49 - ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.c | 484 - ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.h | 36 - .../drivers/gpu/drm/gma500/cdv_intel_crt.c | 340 - .../drivers/gpu/drm/gma500/cdv_intel_display.c | 1459 --- .../drivers/gpu/drm/gma500/cdv_intel_hdmi.c | 393 - .../drivers/gpu/drm/gma500/cdv_intel_lvds.c | 734 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.c | 800 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.h | 47 - ANDROID_3.4.5/drivers/gpu/drm/gma500/gem.c | 292 - ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.c | 90 - ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.h | 2 - ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.c | 551 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.h | 64 - ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.c | 303 - ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.h | 430 - ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_gmbus.c | 493 - ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_i2c.c | 169 - .../drivers/gpu/drm/gma500/intel_opregion.c | 81 - .../drivers/gpu/drm/gma500/mdfld_device.c | 691 -- .../drivers/gpu/drm/gma500/mdfld_dsi_dpi.c | 1017 --- .../drivers/gpu/drm/gma500/mdfld_dsi_dpi.h | 79 - .../drivers/gpu/drm/gma500/mdfld_dsi_output.c | 621 -- .../drivers/gpu/drm/gma500/mdfld_dsi_output.h | 377 - .../drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c | 694 -- .../drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h | 92 - .../drivers/gpu/drm/gma500/mdfld_intel_display.c | 1180 --- .../drivers/gpu/drm/gma500/mdfld_output.c | 74 - .../drivers/gpu/drm/gma500/mdfld_output.h | 77 - .../drivers/gpu/drm/gma500/mdfld_tmd_vid.c | 201 - .../drivers/gpu/drm/gma500/mdfld_tpo_vid.c | 124 - ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.c | 263 - ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.h | 21 - ANDROID_3.4.5/drivers/gpu/drm/gma500/mmu.c | 849 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail.h | 252 - .../drivers/gpu/drm/gma500/oaktrail_crtc.c | 592 -- .../drivers/gpu/drm/gma500/oaktrail_device.c | 509 -- .../drivers/gpu/drm/gma500/oaktrail_hdmi.c | 540 -- .../drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c | 328 - .../drivers/gpu/drm/gma500/oaktrail_lvds.c | 448 - ANDROID_3.4.5/drivers/gpu/drm/gma500/power.c | 315 - ANDROID_3.4.5/drivers/gpu/drm/gma500/power.h | 67 - ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_device.c | 332 - ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.c | 706 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.h | 993 -- .../drivers/gpu/drm/gma500/psb_intel_display.c | 1436 --- .../drivers/gpu/drm/gma500/psb_intel_display.h | 28 - .../drivers/gpu/drm/gma500/psb_intel_drv.h | 289 - .../drivers/gpu/drm/gma500/psb_intel_lvds.c | 867 -- .../drivers/gpu/drm/gma500/psb_intel_modes.c | 75 - .../drivers/gpu/drm/gma500/psb_intel_reg.h | 1318 --- .../drivers/gpu/drm/gma500/psb_intel_sdvo.c | 2607 ------ .../drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h | 723 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.c | 622 -- ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.h | 47 - ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_lid.c | 88 - ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_reg.h | 582 -- .../drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c | 829 -- .../drivers/gpu/drm/gma500/tc35876x-dsi-lvds.h | 38 - ANDROID_3.4.5/drivers/gpu/drm/i2c/Makefile | 7 - ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_drv.c | 554 -- ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_mode.c | 471 - ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_priv.h | 345 - ANDROID_3.4.5/drivers/gpu/drm/i2c/sil164_drv.c | 464 - ANDROID_3.4.5/drivers/gpu/drm/i810/Makefile | 8 - ANDROID_3.4.5/drivers/gpu/drm/i810/i810_dma.c | 1273 --- ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.c | 103 - ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.h | 245 - ANDROID_3.4.5/drivers/gpu/drm/i915/Makefile | 45 - ANDROID_3.4.5/drivers/gpu/drm/i915/dvo.h | 144 - ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7017.c | 401 - ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7xxx.c | 331 - ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ivch.c | 421 - ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_sil164.c | 263 - ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_tfp410.c | 304 - ANDROID_3.4.5/drivers/gpu/drm/i915/i915_debugfs.c | 1890 ---- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_dma.c | 2372 ----- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.c | 1037 --- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.h | 1497 ---- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem.c | 4276 --------- .../drivers/gpu/drm/i915/i915_gem_debug.c | 203 - .../drivers/gpu/drm/i915/i915_gem_evict.c | 207 - .../drivers/gpu/drm/i915/i915_gem_execbuffer.c | 1456 --- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_gtt.c | 421 - .../drivers/gpu/drm/i915/i915_gem_tiling.c | 499 -- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_ioc32.c | 219 - ANDROID_3.4.5/drivers/gpu/drm/i915/i915_irq.c | 2169 ----- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_reg.h | 3888 -------- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_suspend.c | 917 -- ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace.h | 418 - .../drivers/gpu/drm/i915/i915_trace_points.c | 11 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_acpi.c | 252 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.c | 732 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.h | 619 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_crt.c | 624 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_display.c | 9458 -------------------- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dp.c | 2566 ------ ANDROID_3.4.5/drivers/gpu/drm/i915/intel_drv.h | 426 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dvo.c | 447 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_fb.c | 293 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_hdmi.c | 573 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_i2c.c | 441 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_lvds.c | 1128 --- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_modes.c | 140 - .../drivers/gpu/drm/i915/intel_opregion.c | 522 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_overlay.c | 1613 ---- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_panel.c | 379 - .../drivers/gpu/drm/i915/intel_ringbuffer.c | 1583 ---- .../drivers/gpu/drm/i915/intel_ringbuffer.h | 220 - ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo.c | 2593 ------ .../drivers/gpu/drm/i915/intel_sdvo_regs.h | 728 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sprite.c | 666 -- ANDROID_3.4.5/drivers/gpu/drm/i915/intel_tv.c | 1662 ---- ANDROID_3.4.5/drivers/gpu/drm/mga/Makefile | 11 - ANDROID_3.4.5/drivers/gpu/drm/mga/mga_dma.c | 1156 --- ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.c | 145 - ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.h | 666 -- ANDROID_3.4.5/drivers/gpu/drm/mga/mga_ioc32.c | 226 - ANDROID_3.4.5/drivers/gpu/drm/mga/mga_irq.c | 174 - ANDROID_3.4.5/drivers/gpu/drm/mga/mga_state.c | 1103 --- ANDROID_3.4.5/drivers/gpu/drm/mga/mga_warp.c | 170 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/Kconfig | 57 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/Makefile | 47 - .../drivers/gpu/drm/nouveau/nouveau_acpi.c | 430 - .../drivers/gpu/drm/nouveau/nouveau_backlight.c | 257 - .../drivers/gpu/drm/nouveau/nouveau_bios.c | 6546 -------------- .../drivers/gpu/drm/nouveau/nouveau_bios.h | 312 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bo.c | 1207 --- .../drivers/gpu/drm/nouveau/nouveau_calc.c | 478 - .../drivers/gpu/drm/nouveau/nouveau_channel.c | 492 - .../drivers/gpu/drm/nouveau/nouveau_connector.c | 1114 --- .../drivers/gpu/drm/nouveau/nouveau_connector.h | 88 - .../drivers/gpu/drm/nouveau/nouveau_crtc.h | 97 - .../drivers/gpu/drm/nouveau/nouveau_debugfs.c | 198 - .../drivers/gpu/drm/nouveau/nouveau_display.c | 621 -- .../drivers/gpu/drm/nouveau/nouveau_dma.c | 286 - .../drivers/gpu/drm/nouveau/nouveau_dma.h | 175 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dp.c | 603 -- .../drivers/gpu/drm/nouveau/nouveau_drv.c | 497 - .../drivers/gpu/drm/nouveau/nouveau_drv.h | 1793 ---- .../drivers/gpu/drm/nouveau/nouveau_encoder.h | 104 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fb.h | 47 - .../drivers/gpu/drm/nouveau/nouveau_fbcon.c | 561 -- .../drivers/gpu/drm/nouveau/nouveau_fbcon.h | 69 - .../drivers/gpu/drm/nouveau/nouveau_fence.c | 614 -- .../drivers/gpu/drm/nouveau/nouveau_gem.c | 868 -- .../drivers/gpu/drm/nouveau/nouveau_gpio.c | 400 - .../drivers/gpu/drm/nouveau/nouveau_gpio.h | 71 - .../drivers/gpu/drm/nouveau/nouveau_grctx.h | 133 - .../drivers/gpu/drm/nouveau/nouveau_hdmi.c | 260 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.c | 1087 --- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.h | 474 - .../drivers/gpu/drm/nouveau/nouveau_hwsq.h | 115 - .../drivers/gpu/drm/nouveau/nouveau_i2c.c | 394 - .../drivers/gpu/drm/nouveau/nouveau_i2c.h | 59 - .../drivers/gpu/drm/nouveau/nouveau_ioc32.c | 70 - .../drivers/gpu/drm/nouveau/nouveau_irq.c | 151 - .../drivers/gpu/drm/nouveau/nouveau_mem.c | 1248 --- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.c | 175 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.h | 67 - .../drivers/gpu/drm/nouveau/nouveau_mxm.c | 723 -- .../drivers/gpu/drm/nouveau/nouveau_notifier.c | 204 - .../drivers/gpu/drm/nouveau/nouveau_object.c | 1045 --- .../drivers/gpu/drm/nouveau/nouveau_perf.c | 415 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.c | 949 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.h | 107 - .../drivers/gpu/drm/nouveau/nouveau_ramht.c | 309 - .../drivers/gpu/drm/nouveau/nouveau_ramht.h | 55 - .../drivers/gpu/drm/nouveau/nouveau_reg.h | 858 -- .../drivers/gpu/drm/nouveau/nouveau_sgdma.c | 444 - .../drivers/gpu/drm/nouveau/nouveau_state.c | 1449 --- .../drivers/gpu/drm/nouveau/nouveau_temp.c | 331 - .../drivers/gpu/drm/nouveau/nouveau_ttm.c | 103 - .../drivers/gpu/drm/nouveau/nouveau_util.c | 78 - .../drivers/gpu/drm/nouveau/nouveau_util.h | 49 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.c | 436 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.h | 115 - .../drivers/gpu/drm/nouveau/nouveau_volt.c | 247 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_crtc.c | 1063 --- .../drivers/gpu/drm/nouveau/nv04_cursor.c | 71 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dac.c | 544 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dfp.c | 720 -- .../drivers/gpu/drm/nouveau/nv04_display.c | 263 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fb.c | 55 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fbcon.c | 275 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fifo.c | 543 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_graph.c | 1353 --- .../drivers/gpu/drm/nouveau/nv04_instmem.c | 192 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_mc.c | 24 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_pm.c | 137 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_timer.c | 84 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_tv.c | 254 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fb.c | 104 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fifo.c | 246 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_gpio.c | 123 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_graph.c | 1194 --- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.c | 825 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.h | 161 - .../drivers/gpu/drm/nouveau/nv17_tv_modes.c | 593 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_fb.c | 148 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_graph.c | 842 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv30_fb.c | 116 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv31_mpeg.c | 344 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fb.c | 163 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fifo.c | 307 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_graph.c | 490 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_grctx.c | 662 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_mc.c | 28 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_pm.c | 394 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_calc.c | 97 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_crtc.c | 809 -- .../drivers/gpu/drm/nouveau/nv50_cursor.c | 139 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_dac.c | 311 - .../drivers/gpu/drm/nouveau/nv50_display.c | 1038 --- .../drivers/gpu/drm/nouveau/nv50_display.h | 93 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.c | 417 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.h | 120 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fb.c | 294 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fbcon.c | 264 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fifo.c | 506 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_gpio.c | 139 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_graph.c | 1079 --- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_grctx.c | 3333 ------- .../drivers/gpu/drm/nouveau/nv50_instmem.c | 428 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mc.c | 40 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mpeg.c | 256 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_pm.c | 886 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_sor.c | 514 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vm.c | 179 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vram.c | 237 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_bsp.c | 83 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_crypt.c | 193 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_vp.c | 83 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_crypt.c | 78 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_ppp.c | 78 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.c | 226 - .../drivers/gpu/drm/nouveau/nva3_copy.fuc | 872 -- .../drivers/gpu/drm/nouveau/nva3_copy.fuc.h | 534 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_pm.c | 346 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.c | 243 - .../drivers/gpu/drm/nouveau/nvc0_copy.fuc.h | 527 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fb.c | 134 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fbcon.c | 269 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fifo.c | 536 -- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.c | 895 -- .../drivers/gpu/drm/nouveau/nvc0_graph.fuc | 400 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.h | 97 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grctx.c | 2878 ------ .../drivers/gpu/drm/nouveau/nvc0_grgpc.fuc | 539 -- .../drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h | 538 -- .../drivers/gpu/drm/nouveau/nvc0_grhub.fuc | 856 -- .../drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h | 838 -- .../drivers/gpu/drm/nouveau/nvc0_instmem.c | 223 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_pm.c | 392 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vm.c | 136 - ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vram.c | 160 - .../drivers/gpu/drm/nouveau/nvd0_display.c | 2113 ----- ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvreg.h | 517 -- ANDROID_3.4.5/drivers/gpu/drm/r128/Makefile | 10 - ANDROID_3.4.5/drivers/gpu/drm/r128/r128_cce.c | 938 -- ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.c | 114 - ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.h | 530 -- ANDROID_3.4.5/drivers/gpu/drm/r128/r128_ioc32.c | 215 - ANDROID_3.4.5/drivers/gpu/drm/r128/r128_irq.c | 116 - ANDROID_3.4.5/drivers/gpu/drm/r128/r128_state.c | 1667 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/Kconfig | 31 - ANDROID_3.4.5/drivers/gpu/drm/radeon/Makefile | 82 - ANDROID_3.4.5/drivers/gpu/drm/radeon/ObjectID.h | 696 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-bits.h | 48 - ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-names.h | 100 - ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-types.h | 42 - ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.c | 1406 --- ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.h | 159 - ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios.h | 8010 ----------------- .../drivers/gpu/drm/radeon/atombios_crtc.c | 1727 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_dp.c | 987 -- .../drivers/gpu/drm/radeon/atombios_encoders.c | 2424 ----- .../drivers/gpu/drm/radeon/atombios_i2c.c | 139 - ANDROID_3.4.5/drivers/gpu/drm/radeon/avivod.h | 62 - .../drivers/gpu/drm/radeon/cayman_blit_shaders.c | 374 - .../drivers/gpu/drm/radeon/cayman_blit_shaders.h | 35 - ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen.c | 3507 -------- .../drivers/gpu/drm/radeon/evergreen_blit_kms.c | 730 -- .../gpu/drm/radeon/evergreen_blit_shaders.c | 357 - .../gpu/drm/radeon/evergreen_blit_shaders.h | 35 - .../drivers/gpu/drm/radeon/evergreen_cs.c | 2902 ------ .../drivers/gpu/drm/radeon/evergreen_reg.h | 237 - ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreend.h | 1652 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/mkregtable.c | 725 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/ni.c | 1888 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/ni_reg.h | 86 - ANDROID_3.4.5/drivers/gpu/drm/radeon/nid.h | 575 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/r100.c | 4190 --------- ANDROID_3.4.5/drivers/gpu/drm/radeon/r100_track.h | 101 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r100d.h | 880 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/r200.c | 549 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/r300.c | 1590 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_cmdbuf.c | 1185 --- ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_reg.h | 1789 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/r300d.h | 354 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r420.c | 501 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/r420d.h | 249 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r500_reg.h | 797 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/r520.c | 336 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r520d.h | 187 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r600.c | 3799 -------- ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_audio.c | 304 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit.c | 868 -- .../drivers/gpu/drm/radeon/r600_blit_kms.c | 796 -- .../drivers/gpu/drm/radeon/r600_blit_shaders.c | 719 -- .../drivers/gpu/drm/radeon/r600_blit_shaders.h | 38 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cp.c | 2664 ------ ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cs.c | 2357 ----- ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_hdmi.c | 625 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_reg.h | 200 - ANDROID_3.4.5/drivers/gpu/drm/radeon/r600d.h | 1578 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon.h | 1867 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_acpi.c | 68 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_agp.c | 283 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.c | 1748 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.h | 489 - .../drivers/gpu/drm/radeon/radeon_atombios.c | 3162 ------- .../drivers/gpu/drm/radeon/radeon_atpx_handler.c | 284 - .../drivers/gpu/drm/radeon/radeon_benchmark.c | 257 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_bios.c | 527 -- .../drivers/gpu/drm/radeon/radeon_blit_common.h | 44 - .../drivers/gpu/drm/radeon/radeon_clocks.c | 912 -- .../drivers/gpu/drm/radeon/radeon_combios.c | 3538 -------- .../drivers/gpu/drm/radeon/radeon_connectors.c | 1947 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cp.c | 2261 ----- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cs.c | 611 -- .../drivers/gpu/drm/radeon/radeon_cursor.c | 300 - .../drivers/gpu/drm/radeon/radeon_device.c | 1081 --- .../drivers/gpu/drm/radeon/radeon_display.c | 1589 ---- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.c | 441 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.h | 2171 ----- .../drivers/gpu/drm/radeon/radeon_encoders.c | 367 - .../drivers/gpu/drm/radeon/radeon_family.h | 114 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fb.c | 431 - .../drivers/gpu/drm/radeon/radeon_fence.c | 504 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gart.c | 688 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gem.c | 507 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_i2c.c | 1182 --- .../drivers/gpu/drm/radeon/radeon_ioc32.c | 425 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq.c | 401 - .../drivers/gpu/drm/radeon/radeon_irq_kms.c | 268 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_kms.c | 526 -- .../drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 1071 --- .../gpu/drm/radeon/radeon_legacy_encoders.c | 1666 ---- .../drivers/gpu/drm/radeon/radeon_legacy_tv.c | 923 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mem.c | 301 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mode.h | 706 -- .../drivers/gpu/drm/radeon/radeon_object.c | 665 -- .../drivers/gpu/drm/radeon/radeon_object.h | 165 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_pm.c | 895 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_reg.h | 3709 -------- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ring.c | 535 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_sa.c | 189 - .../drivers/gpu/drm/radeon/radeon_semaphore.c | 178 - .../drivers/gpu/drm/radeon/radeon_state.c | 3261 ------- ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_test.c | 497 - .../drivers/gpu/drm/radeon/radeon_trace.h | 82 - .../drivers/gpu/drm/radeon/radeon_trace_points.c | 9 - ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ttm.c | 913 -- .../drivers/gpu/drm/radeon/reg_srcs/cayman | 641 -- .../drivers/gpu/drm/radeon/reg_srcs/evergreen | 644 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r100 | 105 - ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r200 | 186 - ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r300 | 714 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r420 | 780 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r600 | 764 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rn50 | 30 - .../drivers/gpu/drm/radeon/reg_srcs/rs600 | 780 -- .../drivers/gpu/drm/radeon/reg_srcs/rv515 | 494 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rs100d.h | 40 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400.c | 575 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400d.h | 160 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600.c | 1028 --- ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600d.h | 671 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690.c | 793 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690d.h | 310 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rv200d.h | 36 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rv250d.h | 123 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rv350d.h | 52 - ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515.c | 1131 --- ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515d.h | 649 -- ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770.c | 1375 --- ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770d.h | 405 - ANDROID_3.4.5/drivers/gpu/drm/radeon/si.c | 4127 --------- .../drivers/gpu/drm/radeon/si_blit_shaders.c | 253 - .../drivers/gpu/drm/radeon/si_blit_shaders.h | 32 - ANDROID_3.4.5/drivers/gpu/drm/radeon/si_reg.h | 33 - ANDROID_3.4.5/drivers/gpu/drm/radeon/sid.h | 886 -- ANDROID_3.4.5/drivers/gpu/drm/savage/Makefile | 9 - ANDROID_3.4.5/drivers/gpu/drm/savage/savage_bci.c | 1088 --- ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.c | 90 - ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.h | 575 -- .../drivers/gpu/drm/savage/savage_state.c | 1163 --- ANDROID_3.4.5/drivers/gpu/drm/sis/Makefile | 10 - ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.c | 144 - ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.h | 76 - ANDROID_3.4.5/drivers/gpu/drm/sis/sis_mm.c | 358 - ANDROID_3.4.5/drivers/gpu/drm/tdfx/Makefile | 8 - ANDROID_3.4.5/drivers/gpu/drm/tdfx/tdfx_drv.c | 87 - ANDROID_3.4.5/drivers/gpu/drm/tdfx/tdfx_drv.h | 47 - ANDROID_3.4.5/drivers/gpu/drm/ttm/Makefile | 14 - .../drivers/gpu/drm/ttm/ttm_agp_backend.c | 151 - ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo.c | 1897 ---- ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo_manager.c | 157 - ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo_util.c | 687 -- ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo_vm.c | 465 - .../drivers/gpu/drm/ttm/ttm_execbuf_util.c | 238 - ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_lock.c | 310 - ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_memory.c | 602 -- ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_module.c | 102 - ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_object.c | 453 - ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_page_alloc.c | 916 -- .../drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 1134 --- ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_tt.c | 393 - ANDROID_3.4.5/drivers/gpu/drm/udl/Kconfig | 12 - ANDROID_3.4.5/drivers/gpu/drm/udl/Makefile | 6 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_connector.c | 141 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_drv.c | 112 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_drv.h | 142 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_encoder.c | 80 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_fb.c | 611 -- ANDROID_3.4.5/drivers/gpu/drm/udl/udl_gem.c | 241 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_main.c | 338 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_modeset.c | 414 - ANDROID_3.4.5/drivers/gpu/drm/udl/udl_transfer.c | 253 - ANDROID_3.4.5/drivers/gpu/drm/via/Makefile | 8 - ANDROID_3.4.5/drivers/gpu/drm/via/via_3d_reg.h | 1650 ---- ANDROID_3.4.5/drivers/gpu/drm/via/via_dma.c | 741 -- ANDROID_3.4.5/drivers/gpu/drm/via/via_dmablit.c | 808 -- ANDROID_3.4.5/drivers/gpu/drm/via/via_dmablit.h | 140 - ANDROID_3.4.5/drivers/gpu/drm/via/via_drv.c | 124 - ANDROID_3.4.5/drivers/gpu/drm/via/via_drv.h | 160 - ANDROID_3.4.5/drivers/gpu/drm/via/via_irq.c | 392 - ANDROID_3.4.5/drivers/gpu/drm/via/via_map.c | 129 - ANDROID_3.4.5/drivers/gpu/drm/via/via_mm.c | 235 - ANDROID_3.4.5/drivers/gpu/drm/via/via_verifier.c | 1111 --- ANDROID_3.4.5/drivers/gpu/drm/via/via_verifier.h | 62 - ANDROID_3.4.5/drivers/gpu/drm/via/via_video.c | 93 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/Kconfig | 14 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/Makefile | 10 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga3d_reg.h | 1896 ---- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_escape.h | 89 - .../drivers/gpu/drm/vmwgfx/svga_overlay.h | 201 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_reg.h | 1552 ---- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_types.h | 45 - .../drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | 357 - .../drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | 322 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1208 --- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 709 -- .../drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 1382 --- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 655 -- .../drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 1154 --- .../drivers/gpu/drm/vmwgfx/vmwgfx_fence.h | 120 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 568 -- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c | 280 - .../drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 161 - .../drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 329 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | 324 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2034 ----- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 166 - ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 444 - .../drivers/gpu/drm/vmwgfx/vmwgfx_marker.c | 171 - .../drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 616 -- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h | 57 - .../drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 1919 ---- ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 571 -- .../drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 98 - 553 files changed, 348287 deletions(-) delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/README.drm delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ati_pcigart.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_agpsupport.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_auth.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_buffer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_bufs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_cache.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_context.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_crtc_helper.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_debugfs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_dp_i2c_helper.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_edid.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_edid_load.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_edid_modes.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_encoder_slave.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_fb_helper.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_fops.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_global.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_hashtab.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_info.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_ioc32.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_ioctl.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_lock.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_memory.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_mm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_modes.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_pci.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_platform.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_prime.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_proc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_scatter.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_stub.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_sysfs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_trace.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_trace_points.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_usb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/drm_vm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_ddc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_core.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fimd.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmiphy.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_mixer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-hdmi.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-mixer.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-vp.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/accel_2d.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/backlight.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_crt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_lvds.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_gmbus.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_i2c.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_opregion.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_device.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_intel_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tmd_vid.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tpo_vid.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/mmu.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_device.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_lvds.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/power.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/power.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_device.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_lvds.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_modes.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_lid.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i2c/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_mode.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_priv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i2c/sil164_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i810/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i810/i810_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/dvo.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7017.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7xxx.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ivch.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_sil164.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_tfp410.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_debugfs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_debug.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_evict.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_execbuffer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_gtt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_tiling.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_ioc32.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_suspend.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace_points.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_acpi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_crt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dvo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_i2c.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_lvds.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_modes.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_opregion.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_overlay.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_panel.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo_regs.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sprite.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/i915/intel_tv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_ioc32.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_state.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/mga/mga_warp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_acpi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_backlight.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_calc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_channel.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_crtc.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_debugfs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_encoder.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fb.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fence.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_grctx.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hwsq.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ioc32.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mxm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_notifier.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_object.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_perf.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_sgdma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_state.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_temp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ttm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_volt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_cursor.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dac.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dfp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fbcon.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fifo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_graph.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_instmem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_mc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_timer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_tv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fifo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_gpio.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_graph.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv_modes.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_graph.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv30_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv31_mpeg.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fifo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_graph.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_grctx.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_mc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_calc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_cursor.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_dac.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fbcon.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fifo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_gpio.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_graph.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_grctx.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_instmem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mpeg.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_sor.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vram.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_bsp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_crypt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_vp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_crypt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_ppp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fbcon.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fifo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.fuc delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grctx.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_instmem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vram.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvd0_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvreg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/r128_cce.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/r128_ioc32.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/r128_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/r128/r128_state.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/ObjectID.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-bits.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-names.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-types.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_dp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_encoders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_i2c.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/avivod.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_kms.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_cs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreend.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/mkregtable.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/ni.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/ni_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/nid.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r100.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r100_track.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r100d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r200.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r300.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_cmdbuf.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r300d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r420.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r420d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r500_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r520.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r520d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_audio.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_kms.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_hdmi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/r600d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_acpi.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_agp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atombios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atpx_handler.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_benchmark.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_bios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_blit_common.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_clocks.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_combios.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_connectors.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cp.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cs.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cursor.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_device.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_display.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_encoders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_family.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fence.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gart.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_i2c.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ioc32.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq_kms.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_kms.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_crtc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_encoders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_tv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mode.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_pm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ring.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_sa.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_semaphore.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_state.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_test.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace_points.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ttm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/cayman delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/evergreen delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r100 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r200 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r300 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r420 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r600 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rn50 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rs600 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rv515 delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs100d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv200d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv250d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv350d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770d.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/si.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/si_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/radeon/sid.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/savage/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/savage/savage_bci.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/savage/savage_state.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/sis/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/sis/sis_mm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/tdfx/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/tdfx/tdfx_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/tdfx/tdfx_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_agp_backend.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo_manager.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo_util.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_bo_vm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_execbuf_util.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_lock.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_memory.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_module.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_object.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_page_alloc.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/ttm/ttm_tt.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_connector.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_encoder.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_gem.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_main.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_modeset.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/udl/udl_transfer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_3d_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_dma.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_dmablit.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_dmablit.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_map.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_mm.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_verifier.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_verifier.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/via/via_video.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/Kconfig delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/Makefile delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga3d_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_escape.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_overlay.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/svga_types.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_marker.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_reg.h delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c delete mode 100644 ANDROID_3.4.5/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c (limited to 'ANDROID_3.4.5/drivers/gpu/drm') diff --git a/ANDROID_3.4.5/drivers/gpu/drm/Kconfig b/ANDROID_3.4.5/drivers/gpu/drm/Kconfig deleted file mode 100644 index e354bc0b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/Kconfig +++ /dev/null @@ -1,188 +0,0 @@ -# -# Drm device configuration -# -# This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -# -menuconfig DRM - tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" - depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU - select I2C - select I2C_ALGOBIT - select DMA_SHARED_BUFFER - help - Kernel-level support for the Direct Rendering Infrastructure (DRI) - introduced in XFree86 4.0. If you say Y here, you need to select - the module that's right for your graphics card from the list below. - These modules provide support for synchronization, security, and - DMA transfers. Please see for more - details. You should also select and configure AGP - (/dev/agpgart) support if it is available for your platform. - -config DRM_USB - tristate - depends on DRM - select USB - -config DRM_KMS_HELPER - tristate - depends on DRM - select FB - select FRAMEBUFFER_CONSOLE if !EXPERT - select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE - help - FB and CRTC helpers for KMS drivers. - -config DRM_LOAD_EDID_FIRMWARE - bool "Allow to specify an EDID data set instead of probing for it" - depends on DRM_KMS_HELPER - help - Say Y here, if you want to use EDID data to be loaded from the - /lib/firmware directory or one of the provided built-in - data sets. This may be necessary, if the graphics adapter or - monitor are unable to provide appropriate EDID data. Since this - feature is provided as a workaround for broken hardware, the - default case is N. Details and instructions how to build your own - EDID data are given in Documentation/EDID/HOWTO.txt. - -config DRM_TTM - tristate - depends on DRM - help - GPU memory management subsystem for devices with multiple - GPU memory types. Will be enabled automatically if a device driver - uses it. - -config DRM_TDFX - tristate "3dfx Banshee/Voodoo3+" - depends on DRM && PCI - help - Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), - graphics card. If M is selected, the module will be called tdfx. - -config DRM_R128 - tristate "ATI Rage 128" - depends on DRM && PCI - select FW_LOADER - help - Choose this option if you have an ATI Rage 128 graphics card. If M - is selected, the module will be called r128. AGP support for - this card is strongly suggested (unless you have a PCI version). - -config DRM_RADEON - tristate "ATI Radeon" - depends on DRM && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FW_LOADER - select DRM_KMS_HELPER - select DRM_TTM - select POWER_SUPPLY - select HWMON - help - Choose this option if you have an ATI Radeon graphics card. There - are both PCI and AGP versions. You don't need to choose this to - run the Radeon in plain VGA mode. - - If M is selected, the module will be called radeon. - -source "drivers/gpu/drm/radeon/Kconfig" - -source "drivers/gpu/drm/nouveau/Kconfig" - -config DRM_I810 - tristate "Intel I810" - # !PREEMPT because of missing ioctl locking - depends on DRM && AGP && AGP_INTEL && (!PREEMPT || BROKEN) - help - Choose this option if you have an Intel I810 graphics card. If M is - selected, the module will be called i810. AGP support is required - for this driver to work. - -config DRM_I915 - tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics" - depends on DRM - depends on AGP - depends on AGP_INTEL - # we need shmfs for the swappable backing store, and in particular - # the shmem_readpage() which depends upon tmpfs - select SHMEM - select TMPFS - select DRM_KMS_HELPER - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - # i915 depends on ACPI_VIDEO when ACPI is enabled - # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select BACKLIGHT_LCD_SUPPORT if ACPI - select BACKLIGHT_CLASS_DEVICE if ACPI - select VIDEO_OUTPUT_CONTROL if ACPI - select INPUT if ACPI - select ACPI_VIDEO if ACPI - select ACPI_BUTTON if ACPI - help - Choose this option if you have a system that has "Intel Graphics - Media Accelerator" or "HD Graphics" integrated graphics, - including 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G, - G35, G41, G43, G45 chipsets and Celeron, Pentium, Core i3, - Core i5, Core i7 as well as Atom CPUs with integrated graphics. - If M is selected, the module will be called i915. AGP support - is required for this driver to work. This driver is used by - the Intel driver in X.org 6.8 and XFree86 4.4 and above. It - replaces the older i830 module that supported a subset of the - hardware in older X.org releases. - - Note that the older i810/i815 chipsets require the use of the - i810 driver instead, and the Atom z5xx series has an entirely - different implementation. - -config DRM_I915_KMS - bool "Enable modesetting on intel by default" - depends on DRM_I915 - help - Choose this option if you want kernel modesetting enabled by default, - and you have a new enough userspace to support this. Running old - userspaces with this enabled will cause pain. Note that this causes - the driver to bind to PCI devices, which precludes loading things - like intelfb. - -config DRM_MGA - tristate "Matrox g200/g400" - depends on DRM && PCI - select FW_LOADER - help - Choose this option if you have a Matrox G200, G400 or G450 graphics - card. If M is selected, the module will be called mga. AGP - support is required for this driver to work. - -config DRM_SIS - tristate "SiS video cards" - depends on DRM && AGP - depends on FB_SIS || FB_SIS=n - help - Choose this option if you have a SiS 630 or compatible video - chipset. If M is selected the module will be called sis. AGP - support is required for this driver to work. - -config DRM_VIA - tristate "Via unichrome video cards" - depends on DRM && PCI - help - Choose this option if you have a Via unichrome or compatible video - chipset. If M is selected the module will be called via. - -config DRM_SAVAGE - tristate "Savage video cards" - depends on DRM && PCI - help - Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister - chipset. If M is selected the module will be called savage. - -source "drivers/gpu/drm/exynos/Kconfig" - -source "drivers/gpu/drm/vmwgfx/Kconfig" - -source "drivers/gpu/drm/gma500/Kconfig" - -source "drivers/gpu/drm/udl/Kconfig" diff --git a/ANDROID_3.4.5/drivers/gpu/drm/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/Makefile deleted file mode 100644 index c20da5bd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm - -drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ - drm_context.o drm_dma.o \ - drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ - drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ - drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ - drm_crtc.o drm_modes.o drm_edid.o \ - drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o drm_global.o drm_prime.o - -drm-$(CONFIG_COMPAT) += drm_ioc32.o - -drm-usb-y := drm_usb.o - -drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o drm_dp_i2c_helper.o -drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o - -obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o - -CFLAGS_drm_trace_points.o := -I$(src) - -obj-$(CONFIG_DRM) += drm.o -obj-$(CONFIG_DRM_USB) += drm_usb.o -obj-$(CONFIG_DRM_TTM) += ttm/ -obj-$(CONFIG_DRM_TDFX) += tdfx/ -obj-$(CONFIG_DRM_R128) += r128/ -obj-$(CONFIG_DRM_RADEON)+= radeon/ -obj-$(CONFIG_DRM_MGA) += mga/ -obj-$(CONFIG_DRM_I810) += i810/ -obj-$(CONFIG_DRM_I915) += i915/ -obj-$(CONFIG_DRM_SIS) += sis/ -obj-$(CONFIG_DRM_SAVAGE)+= savage/ -obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ -obj-$(CONFIG_DRM_VIA) +=via/ -obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/ -obj-$(CONFIG_DRM_EXYNOS) +=exynos/ -obj-$(CONFIG_DRM_GMA500) += gma500/ -obj-$(CONFIG_DRM_UDL) += udl/ -obj-y += i2c/ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/README.drm b/ANDROID_3.4.5/drivers/gpu/drm/README.drm deleted file mode 100644 index b5b33272..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/README.drm +++ /dev/null @@ -1,43 +0,0 @@ -************************************************************ -* For the very latest on DRI development, please see: * -* http://dri.freedesktop.org/ * -************************************************************ - -The Direct Rendering Manager (drm) is a device-independent kernel-level -device driver that provides support for the XFree86 Direct Rendering -Infrastructure (DRI). - -The DRM supports the Direct Rendering Infrastructure (DRI) in four major -ways: - - 1. The DRM provides synchronized access to the graphics hardware via - the use of an optimized two-tiered lock. - - 2. The DRM enforces the DRI security policy for access to the graphics - hardware by only allowing authenticated X11 clients access to - restricted regions of memory. - - 3. The DRM provides a generic DMA engine, complete with multiple - queues and the ability to detect the need for an OpenGL context - switch. - - 4. The DRM is extensible via the use of small device-specific modules - that rely extensively on the API exported by the DRM module. - - -Documentation on the DRI is available from: - http://dri.freedesktop.org/wiki/Documentation - http://sourceforge.net/project/showfiles.php?group_id=387 - http://dri.sourceforge.net/doc/ - -For specific information about kernel-level support, see: - - The Direct Rendering Manager, Kernel Support for the Direct Rendering - Infrastructure - http://dri.sourceforge.net/doc/drm_low_level.html - - Hardware Locking for the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/hardware_locking_low_level.html - - A Security Analysis of the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/security_low_level.html diff --git a/ANDROID_3.4.5/drivers/gpu/drm/ati_pcigart.c b/ANDROID_3.4.5/drivers/gpu/drm/ati_pcigart.c deleted file mode 100644 index 9afe495c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/ati_pcigart.c +++ /dev/null @@ -1,202 +0,0 @@ -/** - * \file ati_pcigart.c - * ATI PCI GART support - * - * \author Gareth Hughes - */ - -/* - * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ - -static int drm_ati_alloc_pcigart_table(struct drm_device *dev, - struct drm_ati_pcigart_info *gart_info) -{ - gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, - PAGE_SIZE); - if (gart_info->table_handle == NULL) - return -ENOMEM; - - return 0; -} - -static void drm_ati_free_pcigart_table(struct drm_device *dev, - struct drm_ati_pcigart_info *gart_info) -{ - drm_pci_free(dev, gart_info->table_handle); - gart_info->table_handle = NULL; -} - -int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) -{ - struct drm_sg_mem *entry = dev->sg; - unsigned long pages; - int i; - int max_pages; - - /* we need to support large memory configurations */ - if (!entry) { - DRM_ERROR("no scatter/gather memory!\n"); - return 0; - } - - if (gart_info->bus_addr) { - - max_pages = (gart_info->table_size / sizeof(u32)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; - - for (i = 0; i < pages; i++) { - if (!entry->busaddr[i]) - break; - pci_unmap_page(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - } - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) - gart_info->bus_addr = 0; - } - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && - gart_info->table_handle) { - drm_ati_free_pcigart_table(dev, gart_info); - } - - return 1; -} -EXPORT_SYMBOL(drm_ati_pcigart_cleanup); - -int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) -{ - struct drm_local_map *map = &gart_info->mapping; - struct drm_sg_mem *entry = dev->sg; - void *address = NULL; - unsigned long pages; - u32 *pci_gart = NULL, page_base, gart_idx; - dma_addr_t bus_address = 0; - int i, j, ret = 0; - int max_ati_pages, max_real_pages; - - if (!entry) { - DRM_ERROR("no scatter/gather memory!\n"); - goto done; - } - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { - DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); - - if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { - DRM_ERROR("fail to set dma mask to 0x%Lx\n", - (unsigned long long)gart_info->table_mask); - ret = 1; - goto done; - } - - ret = drm_ati_alloc_pcigart_table(dev, gart_info); - if (ret) { - DRM_ERROR("cannot allocate PCI GART page!\n"); - goto done; - } - - pci_gart = gart_info->table_handle->vaddr; - address = gart_info->table_handle->vaddr; - bus_address = gart_info->table_handle->busaddr; - } else { - address = gart_info->addr; - bus_address = gart_info->bus_addr; - DRM_DEBUG("PCI: Gart Table: VRAM %08LX mapped at %08lX\n", - (unsigned long long)bus_address, - (unsigned long)address); - } - - - max_ati_pages = (gart_info->table_size / sizeof(u32)); - max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); - pages = (entry->pages <= max_real_pages) - ? entry->pages : max_real_pages; - - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { - memset(pci_gart, 0, max_ati_pages * sizeof(u32)); - } else { - memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32)); - } - - gart_idx = 0; - for (i = 0; i < pages; i++) { - /* we need to support large memory configurations */ - entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i], - 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, entry->busaddr[i])) { - DRM_ERROR("unable to map PCIGART pages!\n"); - drm_ati_pcigart_cleanup(dev, gart_info); - address = NULL; - bus_address = 0; - goto done; - } - page_base = (u32) entry->busaddr[i]; - - for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - u32 val; - - switch(gart_info->gart_reg_if) { - case DRM_ATI_GART_IGP: - val = page_base | 0xc; - break; - case DRM_ATI_GART_PCIE: - val = (page_base >> 8) | 0xc; - break; - default: - case DRM_ATI_GART_PCI: - val = page_base; - break; - } - if (gart_info->gart_table_location == - DRM_ATI_GART_MAIN) - pci_gart[gart_idx] = cpu_to_le32(val); - else - DRM_WRITE32(map, gart_idx * sizeof(u32), val); - gart_idx++; - page_base += ATI_PCIGART_PAGE_SIZE; - } - } - ret = 1; - -#if defined(__i386__) || defined(__x86_64__) - wbinvd(); -#else - mb(); -#endif - - done: - gart_info->addr = address; - gart_info->bus_addr = bus_address; - return ret; -} -EXPORT_SYMBOL(drm_ati_pcigart_init); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_agpsupport.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_agpsupport.c deleted file mode 100644 index 0cb2ba50..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_agpsupport.c +++ /dev/null @@ -1,469 +0,0 @@ -/** - * \file drm_agpsupport.c - * DRM support for AGP/GART backend - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include -#include - -#if __OS_HAS_AGP - -#include - -/** - * Get AGP information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a (output) drm_agp_info structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device has been initialized and acquired and fills in the - * drm_agp_info structure with the information in drm_agp_head::agp_info. - */ -int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info) -{ - DRM_AGP_KERN *kern; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - - kern = &dev->agp->agp_info; - info->agp_version_major = kern->version.major; - info->agp_version_minor = kern->version.minor; - info->mode = kern->mode; - info->aperture_base = kern->aper_base; - info->aperture_size = kern->aper_size * 1024 * 1024; - info->memory_allowed = kern->max_memory << PAGE_SHIFT; - info->memory_used = kern->current_memory << PAGE_SHIFT; - info->id_vendor = kern->device->vendor; - info->id_device = kern->device->device; - - return 0; -} - -EXPORT_SYMBOL(drm_agp_info); - -int drm_agp_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_info *info = data; - int err; - - err = drm_agp_info(dev, info); - if (err) - return err; - - return 0; -} - -/** - * Acquire the AGP device. - * - * \param dev DRM device that is to acquire AGP. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device hasn't been acquired before and calls - * \c agp_backend_acquire. - */ -int drm_agp_acquire(struct drm_device * dev) -{ - if (!dev->agp) - return -ENODEV; - if (dev->agp->acquired) - return -EBUSY; - if (!(dev->agp->bridge = agp_backend_acquire(dev->pdev))) - return -ENODEV; - dev->agp->acquired = 1; - return 0; -} - -EXPORT_SYMBOL(drm_agp_acquire); - -/** - * Acquire the AGP device (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device hasn't been acquired before and calls - * \c agp_backend_acquire. - */ -int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return drm_agp_acquire((struct drm_device *) file_priv->minor->dev); -} - -/** - * Release the AGP device. - * - * \param dev DRM device that is to release AGP. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device has been acquired and calls \c agp_backend_release. - */ -int drm_agp_release(struct drm_device * dev) -{ - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - agp_backend_release(dev->agp->bridge); - dev->agp->acquired = 0; - return 0; -} -EXPORT_SYMBOL(drm_agp_release); - -int drm_agp_release_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return drm_agp_release(dev); -} - -/** - * Enable the AGP bus. - * - * \param dev DRM device that has previously acquired AGP. - * \param mode Requested AGP mode. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device has been acquired but not enabled, and calls - * \c agp_enable. - */ -int drm_agp_enable(struct drm_device * dev, struct drm_agp_mode mode) -{ - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - - dev->agp->mode = mode.mode; - agp_enable(dev->agp->bridge, mode.mode); - dev->agp->enabled = 1; - return 0; -} - -EXPORT_SYMBOL(drm_agp_enable); - -int drm_agp_enable_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_mode *mode = data; - - return drm_agp_enable(dev, *mode); -} - -/** - * Allocate AGP memory. - * - * \param inode device inode. - * \param file_priv file private pointer. - * \param cmd command. - * \param arg pointer to a drm_agp_buffer structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and has been acquired, allocates the - * memory via agp_allocate_memory() and creates a drm_agp_mem entry for it. - */ -int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) -{ - struct drm_agp_mem *entry; - DRM_AGP_MEM *memory; - unsigned long pages; - u32 type; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL))) - return -ENOMEM; - - memset(entry, 0, sizeof(*entry)); - - pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; - type = (u32) request->type; - if (!(memory = agp_allocate_memory(dev->agp->bridge, pages, type))) { - kfree(entry); - return -ENOMEM; - } - - entry->handle = (unsigned long)memory->key + 1; - entry->memory = memory; - entry->bound = 0; - entry->pages = pages; - list_add(&entry->head, &dev->agp->memory); - - request->handle = entry->handle; - request->physical = memory->physical; - - return 0; -} -EXPORT_SYMBOL(drm_agp_alloc); - - -int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_buffer *request = data; - - return drm_agp_alloc(dev, request); -} - -/** - * Search for the AGP memory entry associated with a handle. - * - * \param dev DRM device structure. - * \param handle AGP memory handle. - * \return pointer to the drm_agp_mem structure associated with \p handle. - * - * Walks through drm_agp_head::memory until finding a matching handle. - */ -static struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device * dev, - unsigned long handle) -{ - struct drm_agp_mem *entry; - - list_for_each_entry(entry, &dev->agp->memory, head) { - if (entry->handle == handle) - return entry; - } - return NULL; -} - -/** - * Unbind AGP memory from the GATT (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_agp_binding structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and acquired, looks-up the AGP memory - * entry and passes it to the unbind_agp() function. - */ -int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request) -{ - struct drm_agp_mem *entry; - int ret; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) - return -EINVAL; - if (!entry->bound) - return -EINVAL; - ret = drm_unbind_agp(entry->memory); - if (ret == 0) - entry->bound = 0; - return ret; -} -EXPORT_SYMBOL(drm_agp_unbind); - - -int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_binding *request = data; - - return drm_agp_unbind(dev, request); -} - -/** - * Bind AGP memory into the GATT (ioctl) - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_agp_binding structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and has been acquired and that no memory - * is currently bound into the GATT. Looks-up the AGP memory entry and passes - * it to bind_agp() function. - */ -int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request) -{ - struct drm_agp_mem *entry; - int retcode; - int page; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) - return -EINVAL; - if (entry->bound) - return -EINVAL; - page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE; - if ((retcode = drm_bind_agp(entry->memory, page))) - return retcode; - entry->bound = dev->agp->base + (page << PAGE_SHIFT); - DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", - dev->agp->base, entry->bound); - return 0; -} -EXPORT_SYMBOL(drm_agp_bind); - - -int drm_agp_bind_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_binding *request = data; - - return drm_agp_bind(dev, request); -} - -/** - * Free AGP memory (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_agp_buffer structure. - * \return zero on success or a negative number on failure. - * - * Verifies the AGP device is present and has been acquired and looks up the - * AGP memory entry. If the memory it's currently bound, unbind it via - * unbind_agp(). Frees it via free_agp() as well as the entry itself - * and unlinks from the doubly linked list it's inserted in. - */ -int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) -{ - struct drm_agp_mem *entry; - - if (!dev->agp || !dev->agp->acquired) - return -EINVAL; - if (!(entry = drm_agp_lookup_entry(dev, request->handle))) - return -EINVAL; - if (entry->bound) - drm_unbind_agp(entry->memory); - - list_del(&entry->head); - - drm_free_agp(entry->memory, entry->pages); - kfree(entry); - return 0; -} -EXPORT_SYMBOL(drm_agp_free); - - - -int drm_agp_free_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_agp_buffer *request = data; - - return drm_agp_free(dev, request); -} - -/** - * Initialize the AGP resources. - * - * \return pointer to a drm_agp_head structure. - * - * Gets the drm_agp_t structure which is made available by the agpgart module - * via the inter_module_* functions. Creates and initializes a drm_agp_head - * structure. - */ -struct drm_agp_head *drm_agp_init(struct drm_device *dev) -{ - struct drm_agp_head *head = NULL; - - if (!(head = kmalloc(sizeof(*head), GFP_KERNEL))) - return NULL; - memset((void *)head, 0, sizeof(*head)); - head->bridge = agp_find_bridge(dev->pdev); - if (!head->bridge) { - if (!(head->bridge = agp_backend_acquire(dev->pdev))) { - kfree(head); - return NULL; - } - agp_copy_info(head->bridge, &head->agp_info); - agp_backend_release(head->bridge); - } else { - agp_copy_info(head->bridge, &head->agp_info); - } - if (head->agp_info.chipset == NOT_SUPPORTED) { - kfree(head); - return NULL; - } - INIT_LIST_HEAD(&head->memory); - head->cant_use_aperture = head->agp_info.cant_use_aperture; - head->page_mask = head->agp_info.page_mask; - head->base = head->agp_info.aper_base; - return head; -} - -/** - * Binds a collection of pages into AGP memory at the given offset, returning - * the AGP memory structure containing them. - * - * No reference is held on the pages during this time -- it is up to the - * caller to handle that. - */ -DRM_AGP_MEM * -drm_agp_bind_pages(struct drm_device *dev, - struct page **pages, - unsigned long num_pages, - uint32_t gtt_offset, - u32 type) -{ - DRM_AGP_MEM *mem; - int ret, i; - - DRM_DEBUG("\n"); - - mem = agp_allocate_memory(dev->agp->bridge, num_pages, - type); - if (mem == NULL) { - DRM_ERROR("Failed to allocate memory for %ld pages\n", - num_pages); - return NULL; - } - - for (i = 0; i < num_pages; i++) - mem->pages[i] = pages[i]; - mem->page_count = num_pages; - - mem->is_flushed = true; - ret = agp_bind_memory(mem, gtt_offset / PAGE_SIZE); - if (ret != 0) { - DRM_ERROR("Failed to bind AGP memory: %d\n", ret); - agp_free_memory(mem); - return NULL; - } - - return mem; -} -EXPORT_SYMBOL(drm_agp_bind_pages); - -#endif /* __OS_HAS_AGP */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_auth.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_auth.c deleted file mode 100644 index ba237904..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_auth.c +++ /dev/null @@ -1,194 +0,0 @@ -/** - * \file drm_auth.c - * IOCTLs for authentication - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -/** - * Find the file with the given magic number. - * - * \param dev DRM device. - * \param magic magic number. - * - * Searches in drm_device::magiclist within all files with the same hash key - * the one with matching magic number, while holding the drm_device::struct_mutex - * lock. - */ -static struct drm_file *drm_find_file(struct drm_master *master, drm_magic_t magic) -{ - struct drm_file *retval = NULL; - struct drm_magic_entry *pt; - struct drm_hash_item *hash; - struct drm_device *dev = master->minor->dev; - - mutex_lock(&dev->struct_mutex); - if (!drm_ht_find_item(&master->magiclist, (unsigned long)magic, &hash)) { - pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item); - retval = pt->priv; - } - mutex_unlock(&dev->struct_mutex); - return retval; -} - -/** - * Adds a magic number. - * - * \param dev DRM device. - * \param priv file private data. - * \param magic magic number. - * - * Creates a drm_magic_entry structure and appends to the linked list - * associated the magic number hash key in drm_device::magiclist, while holding - * the drm_device::struct_mutex lock. - */ -static int drm_add_magic(struct drm_master *master, struct drm_file *priv, - drm_magic_t magic) -{ - struct drm_magic_entry *entry; - struct drm_device *dev = master->minor->dev; - DRM_DEBUG("%d\n", magic); - - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; - entry->priv = priv; - entry->hash_item.key = (unsigned long)magic; - mutex_lock(&dev->struct_mutex); - drm_ht_insert_item(&master->magiclist, &entry->hash_item); - list_add_tail(&entry->head, &master->magicfree); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Remove a magic number. - * - * \param dev DRM device. - * \param magic magic number. - * - * Searches and unlinks the entry in drm_device::magiclist with the magic - * number hash key, while holding the drm_device::struct_mutex lock. - */ -int drm_remove_magic(struct drm_master *master, drm_magic_t magic) -{ - struct drm_magic_entry *pt; - struct drm_hash_item *hash; - struct drm_device *dev = master->minor->dev; - - DRM_DEBUG("%d\n", magic); - - mutex_lock(&dev->struct_mutex); - if (drm_ht_find_item(&master->magiclist, (unsigned long)magic, &hash)) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item); - drm_ht_remove_item(&master->magiclist, hash); - list_del(&pt->head); - mutex_unlock(&dev->struct_mutex); - - kfree(pt); - - return 0; -} - -/** - * Get a unique magic number (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a resulting drm_auth structure. - * \return zero on success, or a negative number on failure. - * - * If there is a magic number in drm_file::magic then use it, otherwise - * searches an unique non-zero magic number and add it associating it with \p - * file_priv. - * This ioctl needs protection by the drm_global_mutex, which protects - * struct drm_file::magic and struct drm_magic_entry::priv. - */ -int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - static drm_magic_t sequence = 0; - static DEFINE_SPINLOCK(lock); - struct drm_auth *auth = data; - - /* Find unique magic */ - if (file_priv->magic) { - auth->magic = file_priv->magic; - } else { - do { - spin_lock(&lock); - if (!sequence) - ++sequence; /* reserve 0 */ - auth->magic = sequence++; - spin_unlock(&lock); - } while (drm_find_file(file_priv->master, auth->magic)); - file_priv->magic = auth->magic; - drm_add_magic(file_priv->master, file_priv, auth->magic); - } - - DRM_DEBUG("%u\n", auth->magic); - - return 0; -} - -/** - * Authenticate with a magic. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_auth structure. - * \return zero if authentication successed, or a negative number otherwise. - * - * Checks if \p file_priv is associated with the magic number passed in \arg. - * This ioctl needs protection by the drm_global_mutex, which protects - * struct drm_file::magic and struct drm_magic_entry::priv. - */ -int drm_authmagic(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_auth *auth = data; - struct drm_file *file; - - DRM_DEBUG("%u\n", auth->magic); - if ((file = drm_find_file(file_priv->master, auth->magic))) { - file->authenticated = 1; - drm_remove_magic(file_priv->master, auth->magic); - return 0; - } - return -EINVAL; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_buffer.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_buffer.c deleted file mode 100644 index 08ccefed..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_buffer.c +++ /dev/null @@ -1,185 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 Pauli Nieminen. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Multipart buffer for coping data which is larger than the page size. - * - * Authors: - * Pauli Nieminen - */ - -#include -#include "drm_buffer.h" - -/** - * Allocate the drm buffer object. - * - * buf: Pointer to a pointer where the object is stored. - * size: The number of bytes to allocate. - */ -int drm_buffer_alloc(struct drm_buffer **buf, int size) -{ - int nr_pages = size / PAGE_SIZE + 1; - int idx; - - /* Allocating pointer table to end of structure makes drm_buffer - * variable sized */ - *buf = kzalloc(sizeof(struct drm_buffer) + nr_pages*sizeof(char *), - GFP_KERNEL); - - if (*buf == NULL) { - DRM_ERROR("Failed to allocate drm buffer object to hold" - " %d bytes in %d pages.\n", - size, nr_pages); - return -ENOMEM; - } - - (*buf)->size = size; - - for (idx = 0; idx < nr_pages; ++idx) { - - (*buf)->data[idx] = - kmalloc(min(PAGE_SIZE, size - idx * PAGE_SIZE), - GFP_KERNEL); - - - if ((*buf)->data[idx] == NULL) { - DRM_ERROR("Failed to allocate %dth page for drm" - " buffer with %d bytes and %d pages.\n", - idx + 1, size, nr_pages); - goto error_out; - } - - } - - return 0; - -error_out: - - /* Only last element can be null pointer so check for it first. */ - if ((*buf)->data[idx]) - kfree((*buf)->data[idx]); - - for (--idx; idx >= 0; --idx) - kfree((*buf)->data[idx]); - - kfree(*buf); - return -ENOMEM; -} -EXPORT_SYMBOL(drm_buffer_alloc); - -/** - * Copy the user data to the begin of the buffer and reset the processing - * iterator. - * - * user_data: A pointer the data that is copied to the buffer. - * size: The Number of bytes to copy. - */ -int drm_buffer_copy_from_user(struct drm_buffer *buf, - void __user *user_data, int size) -{ - int nr_pages = size / PAGE_SIZE + 1; - int idx; - - if (size > buf->size) { - DRM_ERROR("Requesting to copy %d bytes to a drm buffer with" - " %d bytes space\n", - size, buf->size); - return -EFAULT; - } - - for (idx = 0; idx < nr_pages; ++idx) { - - if (DRM_COPY_FROM_USER(buf->data[idx], - user_data + idx * PAGE_SIZE, - min(PAGE_SIZE, size - idx * PAGE_SIZE))) { - DRM_ERROR("Failed to copy user data (%p) to drm buffer" - " (%p) %dth page.\n", - user_data, buf, idx); - return -EFAULT; - - } - } - buf->iterator = 0; - return 0; -} -EXPORT_SYMBOL(drm_buffer_copy_from_user); - -/** - * Free the drm buffer object - */ -void drm_buffer_free(struct drm_buffer *buf) -{ - - if (buf != NULL) { - - int nr_pages = buf->size / PAGE_SIZE + 1; - int idx; - for (idx = 0; idx < nr_pages; ++idx) - kfree(buf->data[idx]); - - kfree(buf); - } -} -EXPORT_SYMBOL(drm_buffer_free); - -/** - * Read an object from buffer that may be split to multiple parts. If object - * is not split function just returns the pointer to object in buffer. But in - * case of split object data is copied to given stack object that is suplied - * by caller. - * - * The processing location of the buffer is also advanced to the next byte - * after the object. - * - * objsize: The size of the objet in bytes. - * stack_obj: A pointer to a memory location where object can be copied. - */ -void *drm_buffer_read_object(struct drm_buffer *buf, - int objsize, void *stack_obj) -{ - int idx = drm_buffer_index(buf); - int page = drm_buffer_page(buf); - void *obj = NULL; - - if (idx + objsize <= PAGE_SIZE) { - obj = &buf->data[page][idx]; - } else { - /* The object is split which forces copy to temporary object.*/ - int beginsz = PAGE_SIZE - idx; - memcpy(stack_obj, &buf->data[page][idx], beginsz); - - memcpy(stack_obj + beginsz, &buf->data[page + 1][0], - objsize - beginsz); - - obj = stack_obj; - } - - drm_buffer_advance(buf, objsize); - return obj; -} -EXPORT_SYMBOL(drm_buffer_read_object); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_bufs.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_bufs.c deleted file mode 100644 index 348b367d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_bufs.c +++ /dev/null @@ -1,1626 +0,0 @@ -/** - * \file drm_bufs.c - * Generic buffer template - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include "drmP.h" - -static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, - struct drm_local_map *map) -{ - struct drm_map_list *entry; - list_for_each_entry(entry, &dev->maplist, head) { - /* - * Because the kernel-userspace ABI is fixed at a 32-bit offset - * while PCI resources may live above that, we only compare the - * lower 32 bits of the map offset for maps of type - * _DRM_FRAMEBUFFER or _DRM_REGISTERS. - * It is assumed that if a driver have more than one resource - * of each type, the lower 32 bits are different. - */ - if (!entry->map || - map->type != entry->map->type || - entry->master != dev->primary->master) - continue; - switch (map->type) { - case _DRM_SHM: - if (map->flags != _DRM_CONTAINS_LOCK) - break; - return entry; - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: - if ((entry->map->offset & 0xffffffff) == - (map->offset & 0xffffffff)) - return entry; - default: /* Make gcc happy */ - ; - } - if (entry->map->offset == map->offset) - return entry; - } - - return NULL; -} - -static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash, - unsigned long user_token, int hashed_handle, int shm) -{ - int use_hashed_handle, shift; - unsigned long add; - -#if (BITS_PER_LONG == 64) - use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle); -#elif (BITS_PER_LONG == 32) - use_hashed_handle = hashed_handle; -#else -#error Unsupported long size. Neither 64 nor 32 bits. -#endif - - if (!use_hashed_handle) { - int ret; - hash->key = user_token >> PAGE_SHIFT; - ret = drm_ht_insert_item(&dev->map_hash, hash); - if (ret != -EINVAL) - return ret; - } - - shift = 0; - add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT; - if (shm && (SHMLBA > PAGE_SIZE)) { - int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1; - - /* For shared memory, we have to preserve the SHMLBA - * bits of the eventual vma->vm_pgoff value during - * mmap(). Otherwise we run into cache aliasing problems - * on some platforms. On these platforms, the pgoff of - * a mmap() request is used to pick a suitable virtual - * address for the mmap() region such that it will not - * cause cache aliasing problems. - * - * Therefore, make sure the SHMLBA relevant bits of the - * hash value we use are equal to those in the original - * kernel virtual address. - */ - shift = bits; - add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL)); - } - - return drm_ht_just_insert_please(&dev->map_hash, hash, - user_token, 32 - PAGE_SHIFT - 3, - shift, add); -} - -/** - * Core function to create a range of memory available for mapping by a - * non-root process. - * - * Adjusts the memory offset to its absolute value according to the mapping - * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where - * applicable and if supported by the kernel. - */ -static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, - unsigned int size, enum drm_map_type type, - enum drm_map_flags flags, - struct drm_map_list ** maplist) -{ - struct drm_local_map *map; - struct drm_map_list *list; - drm_dma_handle_t *dmah; - unsigned long user_token; - int ret; - - map = kmalloc(sizeof(*map), GFP_KERNEL); - if (!map) - return -ENOMEM; - - map->offset = offset; - map->size = size; - map->flags = flags; - map->type = type; - - /* Only allow shared memory to be removable since we only keep enough - * book keeping information about shared memory to allow for removal - * when processes fork. - */ - if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) { - kfree(map); - return -EINVAL; - } - DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", - (unsigned long long)map->offset, map->size, map->type); - - /* page-align _DRM_SHM maps. They are allocated here so there is no security - * hole created by that and it works around various broken drivers that use - * a non-aligned quantity to map the SAREA. --BenH - */ - if (map->type == _DRM_SHM) - map->size = PAGE_ALIGN(map->size); - - if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { - kfree(map); - return -EINVAL; - } - map->mtrr = -1; - map->handle = NULL; - - switch (map->type) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__) - if (map->offset + (map->size-1) < map->offset || - map->offset < virt_to_phys(high_memory)) { - kfree(map); - return -EINVAL; - } -#endif - /* Some drivers preinitialize some maps, without the X Server - * needing to be aware of it. Therefore, we just return success - * when the server tries to create a duplicate map. - */ - list = drm_find_matching_map(dev, map); - if (list != NULL) { - if (list->map->size != map->size) { - DRM_DEBUG("Matching maps of type %d with " - "mismatched sizes, (%ld vs %ld)\n", - map->type, map->size, - list->map->size); - list->map->size = map->size; - } - - kfree(map); - *maplist = list; - return 0; - } - - if (drm_core_has_MTRR(dev)) { - if (map->type == _DRM_FRAME_BUFFER || - (map->flags & _DRM_WRITE_COMBINING)) { - map->mtrr = mtrr_add(map->offset, map->size, - MTRR_TYPE_WRCOMB, 1); - } - } - if (map->type == _DRM_REGISTERS) { - map->handle = ioremap(map->offset, map->size); - if (!map->handle) { - kfree(map); - return -ENOMEM; - } - } - - break; - case _DRM_SHM: - list = drm_find_matching_map(dev, map); - if (list != NULL) { - if(list->map->size != map->size) { - DRM_DEBUG("Matching maps of type %d with " - "mismatched sizes, (%ld vs %ld)\n", - map->type, map->size, list->map->size); - list->map->size = map->size; - } - - kfree(map); - *maplist = list; - return 0; - } - map->handle = vmalloc_user(map->size); - DRM_DEBUG("%lu %d %p\n", - map->size, drm_order(map->size), map->handle); - if (!map->handle) { - kfree(map); - return -ENOMEM; - } - map->offset = (unsigned long)map->handle; - if (map->flags & _DRM_CONTAINS_LOCK) { - /* Prevent a 2nd X Server from creating a 2nd lock */ - if (dev->primary->master->lock.hw_lock != NULL) { - vfree(map->handle); - kfree(map); - return -EBUSY; - } - dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */ - } - break; - case _DRM_AGP: { - struct drm_agp_mem *entry; - int valid = 0; - - if (!drm_core_has_AGP(dev)) { - kfree(map); - return -EINVAL; - } -#ifdef __alpha__ - map->offset += dev->hose->mem_space->start; -#endif - /* In some cases (i810 driver), user space may have already - * added the AGP base itself, because dev->agp->base previously - * only got set during AGP enable. So, only add the base - * address if the map's offset isn't already within the - * aperture. - */ - if (map->offset < dev->agp->base || - map->offset > dev->agp->base + - dev->agp->agp_info.aper_size * 1024 * 1024 - 1) { - map->offset += dev->agp->base; - } - map->mtrr = dev->agp->agp_mtrr; /* for getmap */ - - /* This assumes the DRM is in total control of AGP space. - * It's not always the case as AGP can be in the control - * of user space (i.e. i810 driver). So this loop will get - * skipped and we double check that dev->agp->memory is - * actually set as well as being invalid before EPERM'ing - */ - list_for_each_entry(entry, &dev->agp->memory, head) { - if ((map->offset >= entry->bound) && - (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (!list_empty(&dev->agp->memory) && !valid) { - kfree(map); - return -EPERM; - } - DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n", - (unsigned long long)map->offset, map->size); - - break; - } - case _DRM_GEM: - DRM_ERROR("tried to addmap GEM object\n"); - break; - case _DRM_SCATTER_GATHER: - if (!dev->sg) { - kfree(map); - return -EINVAL; - } - map->offset += (unsigned long)dev->sg->virtual; - break; - case _DRM_CONSISTENT: - /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, - * As we're limiting the address to 2^32-1 (or less), - * casting it down to 32 bits is no problem, but we - * need to point to a 64bit variable first. */ - dmah = drm_pci_alloc(dev, map->size, map->size); - if (!dmah) { - kfree(map); - return -ENOMEM; - } - map->handle = dmah->vaddr; - map->offset = (unsigned long)dmah->busaddr; - kfree(dmah); - break; - default: - kfree(map); - return -EINVAL; - } - - list = kzalloc(sizeof(*list), GFP_KERNEL); - if (!list) { - if (map->type == _DRM_REGISTERS) - iounmap(map->handle); - kfree(map); - return -EINVAL; - } - list->map = map; - - mutex_lock(&dev->struct_mutex); - list_add(&list->head, &dev->maplist); - - /* Assign a 32-bit handle */ - /* We do it here so that dev->struct_mutex protects the increment */ - user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : - map->offset; - ret = drm_map_handle(dev, &list->hash, user_token, 0, - (map->type == _DRM_SHM)); - if (ret) { - if (map->type == _DRM_REGISTERS) - iounmap(map->handle); - kfree(map); - kfree(list); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - list->user_token = list->hash.key << PAGE_SHIFT; - mutex_unlock(&dev->struct_mutex); - - if (!(map->flags & _DRM_DRIVER)) - list->master = dev->primary->master; - *maplist = list; - return 0; - } - -int drm_addmap(struct drm_device * dev, resource_size_t offset, - unsigned int size, enum drm_map_type type, - enum drm_map_flags flags, struct drm_local_map ** map_ptr) -{ - struct drm_map_list *list; - int rc; - - rc = drm_addmap_core(dev, offset, size, type, flags, &list); - if (!rc) - *map_ptr = list->map; - return rc; -} - -EXPORT_SYMBOL(drm_addmap); - -/** - * Ioctl to specify a range of memory that is available for mapping by a - * non-root process. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_map structure. - * \return zero on success or a negative value on error. - * - */ -int drm_addmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *map = data; - struct drm_map_list *maplist; - int err; - - if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM)) - return -EPERM; - - err = drm_addmap_core(dev, map->offset, map->size, map->type, - map->flags, &maplist); - - if (err) - return err; - - /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */ - map->handle = (void *)(unsigned long)maplist->user_token; - return 0; -} - -/** - * Remove a map private from list and deallocate resources if the mapping - * isn't in use. - * - * Searches the map on drm_device::maplist, removes it from the list, see if - * its being used, and free any associate resource (such as MTRR's) if it's not - * being on use. - * - * \sa drm_addmap - */ -int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) -{ - struct drm_map_list *r_list = NULL, *list_t; - drm_dma_handle_t dmah; - int found = 0; - struct drm_master *master; - - /* Find the list entry for the map and remove it */ - list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { - if (r_list->map == map) { - master = r_list->master; - list_del(&r_list->head); - drm_ht_remove_key(&dev->map_hash, - r_list->user_token >> PAGE_SHIFT); - kfree(r_list); - found = 1; - break; - } - } - - if (!found) - return -EINVAL; - - switch (map->type) { - case _DRM_REGISTERS: - iounmap(map->handle); - /* FALLTHROUGH */ - case _DRM_FRAME_BUFFER: - if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { - int retcode; - retcode = mtrr_del(map->mtrr, map->offset, map->size); - DRM_DEBUG("mtrr_del=%d\n", retcode); - } - break; - case _DRM_SHM: - vfree(map->handle); - if (master) { - if (dev->sigdata.lock == master->lock.hw_lock) - dev->sigdata.lock = NULL; - master->lock.hw_lock = NULL; /* SHM removed */ - master->lock.file_priv = NULL; - wake_up_interruptible_all(&master->lock.lock_queue); - } - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; - case _DRM_CONSISTENT: - dmah.vaddr = map->handle; - dmah.busaddr = map->offset; - dmah.size = map->size; - __drm_pci_free(dev, &dmah); - break; - case _DRM_GEM: - DRM_ERROR("tried to rmmap GEM object\n"); - break; - } - kfree(map); - - return 0; -} -EXPORT_SYMBOL(drm_rmmap_locked); - -int drm_rmmap(struct drm_device *dev, struct drm_local_map *map) -{ - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm_rmmap_locked(dev, map); - mutex_unlock(&dev->struct_mutex); - - return ret; -} -EXPORT_SYMBOL(drm_rmmap); - -/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on - * the last close of the device, and this is necessary for cleanup when things - * exit uncleanly. Therefore, having userland manually remove mappings seems - * like a pointless exercise since they're going away anyway. - * - * One use case might be after addmap is allowed for normal users for SHM and - * gets used by drivers that the server doesn't need to care about. This seems - * unlikely. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a struct drm_map structure. - * \return zero on success or a negative value on error. - */ -int drm_rmmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *request = data; - struct drm_local_map *map = NULL; - struct drm_map_list *r_list; - int ret; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map && - r_list->user_token == (unsigned long)request->handle && - r_list->map->flags & _DRM_REMOVABLE) { - map = r_list->map; - break; - } - } - - /* List has wrapped around to the head pointer, or its empty we didn't - * find anything. - */ - if (list_empty(&dev->maplist) || !map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - /* Register and framebuffer maps are permanent */ - if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { - mutex_unlock(&dev->struct_mutex); - return 0; - } - - ret = drm_rmmap_locked(dev, map); - - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -/** - * Cleanup after an error on one of the addbufs() functions. - * - * \param dev DRM device. - * \param entry buffer entry where the error occurred. - * - * Frees any pages and buffers associated with the given entry. - */ -static void drm_cleanup_buf_error(struct drm_device * dev, - struct drm_buf_entry * entry) -{ - int i; - - if (entry->seg_count) { - for (i = 0; i < entry->seg_count; i++) { - if (entry->seglist[i]) { - drm_pci_free(dev, entry->seglist[i]); - } - } - kfree(entry->seglist); - - entry->seg_count = 0; - } - - if (entry->buf_count) { - for (i = 0; i < entry->buf_count; i++) { - kfree(entry->buflist[i].dev_private); - } - kfree(entry->buflist); - - entry->buf_count = 0; - } -} - -#if __OS_HAS_AGP -/** - * Add AGP buffers for DMA transfers. - * - * \param dev struct drm_device to which the buffers are to be added. - * \param request pointer to a struct drm_buf_desc describing the request. - * \return zero on success or a negative number on failure. - * - * After some sanity checks creates a drm_buf structure for each buffer and - * reallocates the buffer list of the same size order to accommodate the new - * buffers. - */ -int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_entry *entry; - struct drm_agp_mem *agp_entry; - struct drm_buf *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i, valid; - struct drm_buf **temp_buflist; - - if (!dma) - return -EINVAL; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = dev->agp->base + request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lx\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - /* Make sure buffers are located in AGP memory that we own */ - valid = 0; - list_for_each_entry(agp_entry, &dev->agp->memory, head) { - if ((agp_offset >= agp_entry->bound) && - (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (!list_empty(&dev->agp->memory) && !valid) { - DRM_DEBUG("zone invalid\n"); - return -EINVAL; - } - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = kzalloc(count * sizeof(*entry->buflist), GFP_KERNEL); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * - sizeof(*dma->buflist), GFP_KERNEL); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_AGP; - - atomic_dec(&dev->buf_alloc); - return 0; -} -EXPORT_SYMBOL(drm_addbufs_agp); -#endif /* __OS_HAS_AGP */ - -int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - int count; - int order; - int size; - int total; - int page_order; - struct drm_buf_entry *entry; - drm_dma_handle_t *dmah; - struct drm_buf *buf; - int alignment; - unsigned long offset; - int i; - int byte_count; - int page_count; - unsigned long *temp_pagelist; - struct drm_buf **temp_buflist; - - if (!drm_core_check_feature(dev, DRIVER_PCI_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n", - request->count, request->size, size, order, dev->queue_count); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = kzalloc(count * sizeof(*entry->buflist), GFP_KERNEL); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - entry->seglist = kzalloc(count * sizeof(*entry->seglist), GFP_KERNEL); - if (!entry->seglist) { - kfree(entry->buflist); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - /* Keep the original pagelist until we know all the allocations - * have succeeded - */ - temp_pagelist = kmalloc((dma->page_count + (count << page_order)) * - sizeof(*dma->pagelist), GFP_KERNEL); - if (!temp_pagelist) { - kfree(entry->buflist); - kfree(entry->seglist); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memcpy(temp_pagelist, - dma->pagelist, dma->page_count * sizeof(*dma->pagelist)); - DRM_DEBUG("pagelist: %d entries\n", - dma->page_count + (count << page_order)); - - entry->buf_size = size; - entry->page_order = page_order; - byte_count = 0; - page_count = 0; - - while (entry->buf_count < count) { - - dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000); - - if (!dmah) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - entry->seg_count = count; - drm_cleanup_buf_error(dev, entry); - kfree(temp_pagelist); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - entry->seglist[entry->seg_count++] = dmah; - for (i = 0; i < (1 << page_order); i++) { - DRM_DEBUG("page %d @ 0x%08lx\n", - dma->page_count + page_count, - (unsigned long)dmah->vaddr + PAGE_SIZE * i); - temp_pagelist[dma->page_count + page_count++] - = (unsigned long)dmah->vaddr + PAGE_SIZE * i; - } - for (offset = 0; - offset + size <= total && entry->buf_count < count; - offset += alignment, ++entry->buf_count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = (dma->byte_count + byte_count + offset); - buf->address = (void *)(dmah->vaddr + offset); - buf->bus_address = dmah->busaddr + offset; - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = kzalloc(buf->dev_priv_size, - GFP_KERNEL); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - entry->seg_count = count; - drm_cleanup_buf_error(dev, entry); - kfree(temp_pagelist); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } - byte_count += PAGE_SIZE << page_order; - } - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * - sizeof(*dma->buflist), GFP_KERNEL); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - kfree(temp_pagelist); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - /* No allocations failed, so now we can replace the original pagelist - * with the new one. - */ - if (dma->page_count) { - kfree(dma->pagelist); - } - dma->pagelist = temp_pagelist; - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += entry->seg_count << page_order; - dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - if (request->flags & _DRM_PCI_BUFFER_RO) - dma->flags = _DRM_DMA_USE_PCI_RO; - - atomic_dec(&dev->buf_alloc); - return 0; - -} -EXPORT_SYMBOL(drm_addbufs_pci); - -static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_entry *entry; - struct drm_buf *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - struct drm_buf **temp_buflist; - - if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lu\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = kzalloc(count * sizeof(*entry->buflist), - GFP_KERNEL); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset - + (unsigned long)dev->sg->virtual); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * - sizeof(*dma->buflist), GFP_KERNEL); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_SG; - - atomic_dec(&dev->buf_alloc); - return 0; -} - -static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_entry *entry; - struct drm_buf *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - struct drm_buf **temp_buflist; - - if (!drm_core_check_feature(dev, DRIVER_FB_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - count = request->count; - order = drm_order(request->size); - size = 1 << order; - - alignment = (request->flags & _DRM_PAGE_ALIGN) - ? PAGE_ALIGN(size) : size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - - byte_count = 0; - agp_offset = request->agp_start; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %lu\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - if (dev->queue_count) - return -EBUSY; /* Not while in use */ - - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); - - mutex_lock(&dev->struct_mutex); - entry = &dma->bufs[order]; - if (entry->buf_count) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } - - if (count < 0 || count > 4096) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -EINVAL; - } - - entry->buflist = kzalloc(count * sizeof(*entry->buflist), - GFP_KERNEL); - if (!entry->buflist) { - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - entry->buf_size = size; - entry->page_order = page_order; - - offset = 0; - - while (entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - buf->offset = (dma->byte_count + offset); - buf->bus_address = agp_offset + offset; - buf->address = (void *)(agp_offset + offset); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->file_priv = NULL; - - buf->dev_priv_size = dev->driver->dev_priv_size; - buf->dev_private = kzalloc(buf->dev_priv_size, GFP_KERNEL); - if (!buf->dev_private) { - /* Set count correctly so we free the proper amount. */ - entry->buf_count = count; - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - - DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address); - - offset += alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; - } - - DRM_DEBUG("byte_count: %d\n", byte_count); - - temp_buflist = krealloc(dma->buflist, - (dma->buf_count + entry->buf_count) * - sizeof(*dma->buflist), GFP_KERNEL); - if (!temp_buflist) { - /* Free the entry because it isn't valid */ - drm_cleanup_buf_error(dev, entry); - mutex_unlock(&dev->struct_mutex); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - dma->buflist = temp_buflist; - - for (i = 0; i < entry->buf_count; i++) { - dma->buflist[i + dma->buf_count] = &entry->buflist[i]; - } - - dma->buf_count += entry->buf_count; - dma->seg_count += entry->seg_count; - dma->page_count += byte_count >> PAGE_SHIFT; - dma->byte_count += byte_count; - - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - - mutex_unlock(&dev->struct_mutex); - - request->count = entry->buf_count; - request->size = size; - - dma->flags = _DRM_DMA_USE_FB; - - atomic_dec(&dev->buf_alloc); - return 0; -} - - -/** - * Add buffers for DMA transfers (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a struct drm_buf_desc request. - * \return zero on success or a negative number on failure. - * - * According with the memory type specified in drm_buf_desc::flags and the - * build options, it dispatches the call either to addbufs_agp(), - * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent - * PCI memory respectively. - */ -int drm_addbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_buf_desc *request = data; - int ret; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - -#if __OS_HAS_AGP - if (request->flags & _DRM_AGP_BUFFER) - ret = drm_addbufs_agp(dev, request); - else -#endif - if (request->flags & _DRM_SG_BUFFER) - ret = drm_addbufs_sg(dev, request); - else if (request->flags & _DRM_FB_BUFFER) - ret = drm_addbufs_fb(dev, request); - else - ret = drm_addbufs_pci(dev, request); - - return ret; -} - -/** - * Get information about the buffer mappings. - * - * This was originally mean for debugging purposes, or by a sophisticated - * client library to determine how best to use the available buffers (e.g., - * large buffers can be used for image transfer). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_buf_info structure. - * \return zero on success or a negative number on failure. - * - * Increments drm_device::buf_use while holding the drm_device::count_lock - * lock, preventing of allocating more buffers after this call. Information - * about each requested buffer is then copied into user space. - */ -int drm_infobufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_info *request = data; - int i; - int count; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - spin_lock(&dev->count_lock); - if (atomic_read(&dev->buf_alloc)) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - ++dev->buf_use; /* Can't allocate more after this call */ - spin_unlock(&dev->count_lock); - - for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) - ++count; - } - - DRM_DEBUG("count = %d\n", count); - - if (request->count >= count) { - for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) { - if (dma->bufs[i].buf_count) { - struct drm_buf_desc __user *to = - &request->list[count]; - struct drm_buf_entry *from = &dma->bufs[i]; - struct drm_freelist *list = &dma->bufs[i].freelist; - if (copy_to_user(&to->count, - &from->buf_count, - sizeof(from->buf_count)) || - copy_to_user(&to->size, - &from->buf_size, - sizeof(from->buf_size)) || - copy_to_user(&to->low_mark, - &list->low_mark, - sizeof(list->low_mark)) || - copy_to_user(&to->high_mark, - &list->high_mark, - sizeof(list->high_mark))) - return -EFAULT; - - DRM_DEBUG("%d %d %d %d %d\n", - i, - dma->bufs[i].buf_count, - dma->bufs[i].buf_size, - dma->bufs[i].freelist.low_mark, - dma->bufs[i].freelist.high_mark); - ++count; - } - } - } - request->count = count; - - return 0; -} - -/** - * Specifies a low and high water mark for buffer allocation - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg a pointer to a drm_buf_desc structure. - * \return zero on success or a negative number on failure. - * - * Verifies that the size order is bounded between the admissible orders and - * updates the respective drm_device_dma::bufs entry low and high water mark. - * - * \note This ioctl is deprecated and mostly never used. - */ -int drm_markbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_desc *request = data; - int order; - struct drm_buf_entry *entry; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - DRM_DEBUG("%d, %d, %d\n", - request->size, request->low_mark, request->high_mark); - order = drm_order(request->size); - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) - return -EINVAL; - entry = &dma->bufs[order]; - - if (request->low_mark < 0 || request->low_mark > entry->buf_count) - return -EINVAL; - if (request->high_mark < 0 || request->high_mark > entry->buf_count) - return -EINVAL; - - entry->freelist.low_mark = request->low_mark; - entry->freelist.high_mark = request->high_mark; - - return 0; -} - -/** - * Unreserve the buffers in list, previously reserved using drmDMA. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_buf_free structure. - * \return zero on success or a negative number on failure. - * - * Calls free_buffer() for each used buffer. - * This function is primarily used for debugging. - */ -int drm_freebufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf_free *request = data; - int i; - int idx; - struct drm_buf *buf; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - DRM_DEBUG("%d\n", request->count); - for (i = 0; i < request->count; i++) { - if (copy_from_user(&idx, &request->list[i], sizeof(idx))) - return -EFAULT; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("Index %d (of %d max)\n", - idx, dma->buf_count - 1); - return -EINVAL; - } - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv) { - DRM_ERROR("Process %d freeing buffer not owned\n", - task_pid_nr(current)); - return -EINVAL; - } - drm_free_buffer(dev, buf); - } - - return 0; -} - -/** - * Maps all of the DMA buffers into client-virtual space (ioctl). - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg pointer to a drm_buf_map structure. - * \return zero on success or a negative number on failure. - * - * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls vm_mmap() with - * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls - * drm_mmap_dma(). - */ -int drm_mapbufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int retcode = 0; - const int zero = 0; - unsigned long virtual; - unsigned long address; - struct drm_buf_map *request = data; - int i; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA)) - return -EINVAL; - - if (!dma) - return -EINVAL; - - spin_lock(&dev->count_lock); - if (atomic_read(&dev->buf_alloc)) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - dev->buf_use++; /* Can't allocate more after this call */ - spin_unlock(&dev->count_lock); - - if (request->count >= dma->buf_count) { - if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP)) - || (drm_core_check_feature(dev, DRIVER_SG) - && (dma->flags & _DRM_DMA_USE_SG)) - || (drm_core_check_feature(dev, DRIVER_FB_DMA) - && (dma->flags & _DRM_DMA_USE_FB))) { - struct drm_local_map *map = dev->agp_buffer_map; - unsigned long token = dev->agp_buffer_token; - - if (!map) { - retcode = -EINVAL; - goto done; - } - virtual = vm_mmap(file_priv->filp, 0, map->size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - token); - } else { - virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, - PROT_READ | PROT_WRITE, - MAP_SHARED, 0); - } - if (virtual > -1024UL) { - /* Real error */ - retcode = (signed long)virtual; - goto done; - } - request->virtual = (void __user *)virtual; - - for (i = 0; i < dma->buf_count; i++) { - if (copy_to_user(&request->list[i].idx, - &dma->buflist[i]->idx, - sizeof(request->list[0].idx))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request->list[i].total, - &dma->buflist[i]->total, - sizeof(request->list[0].total))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request->list[i].used, - &zero, sizeof(zero))) { - retcode = -EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; /* *** */ - if (copy_to_user(&request->list[i].address, - &address, sizeof(address))) { - retcode = -EFAULT; - goto done; - } - } - } - done: - request->count = dma->buf_count; - DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode); - - return retcode; -} - -/** - * Compute size order. Returns the exponent of the smaller power of two which - * is greater or equal to given number. - * - * \param size size. - * \return order. - * - * \todo Can be made faster. - */ -int drm_order(unsigned long size) -{ - int order; - unsigned long tmp; - - for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ; - - if (size & (size - 1)) - ++order; - - return order; -} -EXPORT_SYMBOL(drm_order); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_cache.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_cache.c deleted file mode 100644 index 4b8653b9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_cache.c +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** - * - * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include "drmP.h" - -#if defined(CONFIG_X86) -static void -drm_clflush_page(struct page *page) -{ - uint8_t *page_virtual; - unsigned int i; - - if (unlikely(page == NULL)) - return; - - page_virtual = kmap_atomic(page); - for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) - clflush(page_virtual + i); - kunmap_atomic(page_virtual); -} - -static void drm_cache_flush_clflush(struct page *pages[], - unsigned long num_pages) -{ - unsigned long i; - - mb(); - for (i = 0; i < num_pages; i++) - drm_clflush_page(*pages++); - mb(); -} - -static void -drm_clflush_ipi_handler(void *null) -{ - wbinvd(); -} -#endif - -void -drm_clflush_pages(struct page *pages[], unsigned long num_pages) -{ - -#if defined(CONFIG_X86) - if (cpu_has_clflush) { - drm_cache_flush_clflush(pages, num_pages); - return; - } - - if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) - printk(KERN_ERR "Timed out waiting for cache flush.\n"); - -#elif defined(__powerpc__) - unsigned long i; - for (i = 0; i < num_pages; i++) { - struct page *page = pages[i]; - void *page_virtual; - - if (unlikely(page == NULL)) - continue; - - page_virtual = kmap_atomic(page); - flush_dcache_range((unsigned long)page_virtual, - (unsigned long)page_virtual + PAGE_SIZE); - kunmap_atomic(page_virtual); - } -#else - printk(KERN_ERR "Architecture has no drm_cache.c support\n"); - WARN_ON_ONCE(1); -#endif -} -EXPORT_SYMBOL(drm_clflush_pages); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_context.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_context.c deleted file mode 100644 index 325365f6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_context.c +++ /dev/null @@ -1,462 +0,0 @@ -/** - * \file drm_context.c - * IOCTLs for generic contexts - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * ChangeLog: - * 2001-11-16 Torsten Duwe - * added context constructor/destructor hooks, - * needed by SiS driver's memory management. - */ - -#include "drmP.h" - -/******************************************************************/ -/** \name Context bitmap support */ -/*@{*/ - -/** - * Free a handle from the context bitmap. - * - * \param dev DRM device. - * \param ctx_handle context handle. - * - * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry - * in drm_device::ctx_idr, while holding the drm_device::struct_mutex - * lock. - */ -void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle) -{ - mutex_lock(&dev->struct_mutex); - idr_remove(&dev->ctx_idr, ctx_handle); - mutex_unlock(&dev->struct_mutex); -} - -/** - * Context bitmap allocation. - * - * \param dev DRM device. - * \return (non-negative) context handle on success or a negative number on failure. - * - * Allocate a new idr from drm_device::ctx_idr while holding the - * drm_device::struct_mutex lock. - */ -static int drm_ctxbitmap_next(struct drm_device * dev) -{ - int new_id; - int ret; - -again: - if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) { - DRM_ERROR("Out of memory expanding drawable idr\n"); - return -ENOMEM; - } - mutex_lock(&dev->struct_mutex); - ret = idr_get_new_above(&dev->ctx_idr, NULL, - DRM_RESERVED_CONTEXTS, &new_id); - if (ret == -EAGAIN) { - mutex_unlock(&dev->struct_mutex); - goto again; - } - mutex_unlock(&dev->struct_mutex); - return new_id; -} - -/** - * Context bitmap initialization. - * - * \param dev DRM device. - * - * Initialise the drm_device::ctx_idr - */ -int drm_ctxbitmap_init(struct drm_device * dev) -{ - idr_init(&dev->ctx_idr); - return 0; -} - -/** - * Context bitmap cleanup. - * - * \param dev DRM device. - * - * Free all idr members using drm_ctx_sarea_free helper function - * while holding the drm_device::struct_mutex lock. - */ -void drm_ctxbitmap_cleanup(struct drm_device * dev) -{ - mutex_lock(&dev->struct_mutex); - idr_remove_all(&dev->ctx_idr); - mutex_unlock(&dev->struct_mutex); -} - -/*@}*/ - -/******************************************************************/ -/** \name Per Context SAREA Support */ -/*@{*/ - -/** - * Get per-context SAREA. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx_priv_map structure. - * \return zero on success or a negative number on failure. - * - * Gets the map from drm_device::ctx_idr with the handle specified and - * returns its handle. - */ -int drm_getsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_priv_map *request = data; - struct drm_local_map *map; - struct drm_map_list *_entry; - - mutex_lock(&dev->struct_mutex); - - map = idr_find(&dev->ctx_idr, request->ctx_id); - if (!map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - request->handle = NULL; - list_for_each_entry(_entry, &dev->maplist, head) { - if (_entry->map == map) { - request->handle = - (void *)(unsigned long)_entry->user_token; - break; - } - } - - mutex_unlock(&dev->struct_mutex); - - if (request->handle == NULL) - return -EINVAL; - - return 0; -} - -/** - * Set per-context SAREA. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx_priv_map structure. - * \return zero on success or a negative number on failure. - * - * Searches the mapping specified in \p arg and update the entry in - * drm_device::ctx_idr with it. - */ -int drm_setsareactx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_priv_map *request = data; - struct drm_local_map *map = NULL; - struct drm_map_list *r_list = NULL; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map - && r_list->user_token == (unsigned long) request->handle) - goto found; - } - bad: - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - - found: - map = r_list->map; - if (!map) - goto bad; - - if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id))) - goto bad; - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/*@}*/ - -/******************************************************************/ -/** \name The actual DRM context handling routines */ -/*@{*/ - -/** - * Switch context. - * - * \param dev DRM device. - * \param old old context handle. - * \param new new context handle. - * \return zero on success or a negative number on failure. - * - * Attempt to set drm_device::context_flag. - */ -static int drm_context_switch(struct drm_device * dev, int old, int new) -{ - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return -EBUSY; - } - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - return 0; -} - -/** - * Complete context switch. - * - * \param dev DRM device. - * \param new new context handle. - * \return zero on success or a negative number on failure. - * - * Updates drm_device::last_context and drm_device::last_switch. Verifies the - * hardware lock is held, clears the drm_device::context_flag and wakes up - * drm_device::context_wait. - */ -static int drm_context_switch_complete(struct drm_device *dev, - struct drm_file *file_priv, int new) -{ - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; - - if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - /* If a context switch is ever initiated - when the kernel holds the lock, release - that lock here. */ - clear_bit(0, &dev->context_flag); - wake_up(&dev->context_wait); - - return 0; -} - -/** - * Reserve contexts. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx_res structure. - * \return zero on success or a negative number on failure. - */ -int drm_resctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_res *res = data; - struct drm_ctx ctx; - int i; - - if (res->count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx))) - return -EFAULT; - } - } - res->count = DRM_RESERVED_CONTEXTS; - - return 0; -} - -/** - * Add context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * Get a new handle for the context and copy to userspace. - */ -int drm_addctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx_list *ctx_entry; - struct drm_ctx *ctx = data; - - ctx->handle = drm_ctxbitmap_next(dev); - if (ctx->handle == DRM_KERNEL_CONTEXT) { - /* Skip kernel's context and get a new one. */ - ctx->handle = drm_ctxbitmap_next(dev); - } - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle == -1) { - DRM_DEBUG("Not enough free contexts.\n"); - /* Should this return -EBUSY instead? */ - return -ENOMEM; - } - - ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL); - if (!ctx_entry) { - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - - INIT_LIST_HEAD(&ctx_entry->head); - ctx_entry->handle = ctx->handle; - ctx_entry->tag = file_priv; - - mutex_lock(&dev->ctxlist_mutex); - list_add(&ctx_entry->head, &dev->ctxlist); - ++dev->ctx_count; - mutex_unlock(&dev->ctxlist_mutex); - - return 0; -} - -int drm_modctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - /* This does nothing */ - return 0; -} - -/** - * Get context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - */ -int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - /* This is 0, because we don't handle any context flags */ - ctx->flags = 0; - - return 0; -} - -/** - * Switch context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * Calls context_switch(). - */ -int drm_switchctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - return drm_context_switch(dev, dev->last_context, ctx->handle); -} - -/** - * New context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * Calls context_switch_complete(). - */ -int drm_newctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - drm_context_switch_complete(dev, file_priv, ctx->handle); - - return 0; -} - -/** - * Remove context. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument pointing to a drm_ctx structure. - * \return zero on success or a negative number on failure. - * - * If not the special kernel context, calls ctxbitmap_free() to free the specified context. - */ -int drm_rmctx(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_ctx *ctx = data; - - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_dtor) - dev->driver->context_dtor(dev, ctx->handle); - drm_ctxbitmap_free(dev, ctx->handle); - } - - mutex_lock(&dev->ctxlist_mutex); - if (!list_empty(&dev->ctxlist)) { - struct drm_ctx_list *pos, *n; - - list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { - if (pos->handle == ctx->handle) { - list_del(&pos->head); - kfree(pos); - --dev->ctx_count; - } - } - } - mutex_unlock(&dev->ctxlist_mutex); - - return 0; -} - -/*@}*/ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_crtc.c deleted file mode 100644 index c79870a7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_crtc.c +++ /dev/null @@ -1,3470 +0,0 @@ -/* - * Copyright (c) 2006-2008 Intel Corporation - * Copyright (c) 2007 Dave Airlie - * Copyright (c) 2008 Red Hat Inc. - * - * DRM core CRTC related functions - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - * - * Authors: - * Keith Packard - * Eric Anholt - * Dave Airlie - * Jesse Barnes - */ -#include -#include -#include -#include "drm.h" -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_edid.h" -#include "drm_fourcc.h" - -/* Avoid boilerplate. I'm tired of typing. */ -#define DRM_ENUM_NAME_FN(fnname, list) \ - char *fnname(int val) \ - { \ - int i; \ - for (i = 0; i < ARRAY_SIZE(list); i++) { \ - if (list[i].type == val) \ - return list[i].name; \ - } \ - return "(unknown)"; \ - } - -/* - * Global properties - */ -static struct drm_prop_enum_list drm_dpms_enum_list[] = -{ { DRM_MODE_DPMS_ON, "On" }, - { DRM_MODE_DPMS_STANDBY, "Standby" }, - { DRM_MODE_DPMS_SUSPEND, "Suspend" }, - { DRM_MODE_DPMS_OFF, "Off" } -}; - -DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) - -/* - * Optional properties - */ -static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = -{ - { DRM_MODE_SCALE_NONE, "None" }, - { DRM_MODE_SCALE_FULLSCREEN, "Full" }, - { DRM_MODE_SCALE_CENTER, "Center" }, - { DRM_MODE_SCALE_ASPECT, "Full aspect" }, -}; - -static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = -{ - { DRM_MODE_DITHERING_OFF, "Off" }, - { DRM_MODE_DITHERING_ON, "On" }, - { DRM_MODE_DITHERING_AUTO, "Automatic" }, -}; - -/* - * Non-global properties, but "required" for certain connectors. - */ -static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = -{ - { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ - { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ - { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ -}; - -DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list) - -static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = -{ - { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ - { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */ - { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */ -}; - -DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, - drm_dvi_i_subconnector_enum_list) - -static struct drm_prop_enum_list drm_tv_select_enum_list[] = -{ - { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ - { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ -}; - -DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) - -static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = -{ - { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */ - { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ -}; - -DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, - drm_tv_subconnector_enum_list) - -static struct drm_prop_enum_list drm_dirty_info_enum_list[] = { - { DRM_MODE_DIRTY_OFF, "Off" }, - { DRM_MODE_DIRTY_ON, "On" }, - { DRM_MODE_DIRTY_ANNOTATE, "Annotate" }, -}; - -DRM_ENUM_NAME_FN(drm_get_dirty_info_name, - drm_dirty_info_enum_list) - -struct drm_conn_prop_enum_list { - int type; - char *name; - int count; -}; - -/* - * Connector and encoder types. - */ -static struct drm_conn_prop_enum_list drm_connector_enum_list[] = -{ { DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 }, - { DRM_MODE_CONNECTOR_VGA, "VGA", 0 }, - { DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 }, - { DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 }, - { DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 }, - { DRM_MODE_CONNECTOR_Composite, "Composite", 0 }, - { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, - { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, - { DRM_MODE_CONNECTOR_Component, "Component", 0 }, - { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, - { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, - { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, - { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, - { DRM_MODE_CONNECTOR_TV, "TV", 0 }, - { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, - { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0}, -}; - -static struct drm_prop_enum_list drm_encoder_enum_list[] = -{ { DRM_MODE_ENCODER_NONE, "None" }, - { DRM_MODE_ENCODER_DAC, "DAC" }, - { DRM_MODE_ENCODER_TMDS, "TMDS" }, - { DRM_MODE_ENCODER_LVDS, "LVDS" }, - { DRM_MODE_ENCODER_TVDAC, "TV" }, - { DRM_MODE_ENCODER_VIRTUAL, "Virtual" }, -}; - -char *drm_get_encoder_name(struct drm_encoder *encoder) -{ - static char buf[32]; - - snprintf(buf, 32, "%s-%d", - drm_encoder_enum_list[encoder->encoder_type].name, - encoder->base.id); - return buf; -} -EXPORT_SYMBOL(drm_get_encoder_name); - -char *drm_get_connector_name(struct drm_connector *connector) -{ - static char buf[32]; - - snprintf(buf, 32, "%s-%d", - drm_connector_enum_list[connector->connector_type].name, - connector->connector_type_id); - return buf; -} -EXPORT_SYMBOL(drm_get_connector_name); - -char *drm_get_connector_status_name(enum drm_connector_status status) -{ - if (status == connector_status_connected) - return "connected"; - else if (status == connector_status_disconnected) - return "disconnected"; - else - return "unknown"; -} - -/** - * drm_mode_object_get - allocate a new identifier - * @dev: DRM device - * @ptr: object pointer, used to generate unique ID - * @type: object type - * - * LOCKING: - * - * Create a unique identifier based on @ptr in @dev's identifier space. Used - * for tracking modes, CRTCs and connectors. - * - * RETURNS: - * New unique (relative to other objects in @dev) integer identifier for the - * object. - */ -static int drm_mode_object_get(struct drm_device *dev, - struct drm_mode_object *obj, uint32_t obj_type) -{ - int new_id = 0; - int ret; - -again: - if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { - DRM_ERROR("Ran out memory getting a mode number\n"); - return -EINVAL; - } - - mutex_lock(&dev->mode_config.idr_mutex); - ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id); - mutex_unlock(&dev->mode_config.idr_mutex); - if (ret == -EAGAIN) - goto again; - - obj->id = new_id; - obj->type = obj_type; - return 0; -} - -/** - * drm_mode_object_put - free an identifer - * @dev: DRM device - * @id: ID to free - * - * LOCKING: - * Caller must hold DRM mode_config lock. - * - * Free @id from @dev's unique identifier pool. - */ -static void drm_mode_object_put(struct drm_device *dev, - struct drm_mode_object *object) -{ - mutex_lock(&dev->mode_config.idr_mutex); - idr_remove(&dev->mode_config.crtc_idr, object->id); - mutex_unlock(&dev->mode_config.idr_mutex); -} - -struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, - uint32_t id, uint32_t type) -{ - struct drm_mode_object *obj = NULL; - - mutex_lock(&dev->mode_config.idr_mutex); - obj = idr_find(&dev->mode_config.crtc_idr, id); - if (!obj || (obj->type != type) || (obj->id != id)) - obj = NULL; - mutex_unlock(&dev->mode_config.idr_mutex); - - return obj; -} -EXPORT_SYMBOL(drm_mode_object_find); - -/** - * drm_framebuffer_init - initialize a framebuffer - * @dev: DRM device - * - * LOCKING: - * Caller must hold mode config lock. - * - * Allocates an ID for the framebuffer's parent mode object, sets its mode - * functions & device file and adds it to the master fd list. - * - * RETURNS: - * Zero on success, error code on failure. - */ -int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, - const struct drm_framebuffer_funcs *funcs) -{ - int ret; - - ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); - if (ret) - return ret; - - fb->dev = dev; - fb->funcs = funcs; - dev->mode_config.num_fb++; - list_add(&fb->head, &dev->mode_config.fb_list); - - return 0; -} -EXPORT_SYMBOL(drm_framebuffer_init); - -/** - * drm_framebuffer_cleanup - remove a framebuffer object - * @fb: framebuffer to remove - * - * LOCKING: - * Caller must hold mode config lock. - * - * Scans all the CRTCs in @dev's mode_config. If they're using @fb, removes - * it, setting it to NULL. - */ -void drm_framebuffer_cleanup(struct drm_framebuffer *fb) -{ - struct drm_device *dev = fb->dev; - struct drm_crtc *crtc; - struct drm_plane *plane; - struct drm_mode_set set; - int ret; - - /* remove from any CRTC */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb == fb) { - /* should turn off the crtc */ - memset(&set, 0, sizeof(struct drm_mode_set)); - set.crtc = crtc; - set.fb = NULL; - ret = crtc->funcs->set_config(&set); - if (ret) - DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc); - } - } - - list_for_each_entry(plane, &dev->mode_config.plane_list, head) { - if (plane->fb == fb) { - /* should turn off the crtc */ - ret = plane->funcs->disable_plane(plane); - if (ret) - DRM_ERROR("failed to disable plane with busy fb\n"); - /* disconnect the plane from the fb and crtc: */ - plane->fb = NULL; - plane->crtc = NULL; - } - } - - drm_mode_object_put(dev, &fb->base); - list_del(&fb->head); - dev->mode_config.num_fb--; -} -EXPORT_SYMBOL(drm_framebuffer_cleanup); - -/** - * drm_crtc_init - Initialise a new CRTC object - * @dev: DRM device - * @crtc: CRTC object to init - * @funcs: callbacks for the new CRTC - * - * LOCKING: - * Caller must hold mode config lock. - * - * Inits a new object created as base part of an driver crtc object. - * - * RETURNS: - * Zero on success, error code on failure. - */ -int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, - const struct drm_crtc_funcs *funcs) -{ - int ret; - - crtc->dev = dev; - crtc->funcs = funcs; - - mutex_lock(&dev->mode_config.mutex); - - ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); - if (ret) - goto out; - - list_add_tail(&crtc->head, &dev->mode_config.crtc_list); - dev->mode_config.num_crtc++; - - out: - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} -EXPORT_SYMBOL(drm_crtc_init); - -/** - * drm_crtc_cleanup - Cleans up the core crtc usage. - * @crtc: CRTC to cleanup - * - * LOCKING: - * Caller must hold mode config lock. - * - * Cleanup @crtc. Removes from drm modesetting space - * does NOT free object, caller does that. - */ -void drm_crtc_cleanup(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - - if (crtc->gamma_store) { - kfree(crtc->gamma_store); - crtc->gamma_store = NULL; - } - - drm_mode_object_put(dev, &crtc->base); - list_del(&crtc->head); - dev->mode_config.num_crtc--; -} -EXPORT_SYMBOL(drm_crtc_cleanup); - -/** - * drm_mode_probed_add - add a mode to a connector's probed mode list - * @connector: connector the new mode - * @mode: mode data - * - * LOCKING: - * Caller must hold mode config lock. - * - * Add @mode to @connector's mode list for later use. - */ -void drm_mode_probed_add(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - list_add(&mode->head, &connector->probed_modes); -} -EXPORT_SYMBOL(drm_mode_probed_add); - -/** - * drm_mode_remove - remove and free a mode - * @connector: connector list to modify - * @mode: mode to remove - * - * LOCKING: - * Caller must hold mode config lock. - * - * Remove @mode from @connector's mode list, then free it. - */ -void drm_mode_remove(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - list_del(&mode->head); - drm_mode_destroy(connector->dev, mode); -} -EXPORT_SYMBOL(drm_mode_remove); - -/** - * drm_connector_init - Init a preallocated connector - * @dev: DRM device - * @connector: the connector to init - * @funcs: callbacks for this connector - * @name: user visible name of the connector - * - * LOCKING: - * Takes mode config lock. - * - * Initialises a preallocated connector. Connectors should be - * subclassed as part of driver connector objects. - * - * RETURNS: - * Zero on success, error code on failure. - */ -int drm_connector_init(struct drm_device *dev, - struct drm_connector *connector, - const struct drm_connector_funcs *funcs, - int connector_type) -{ - int ret; - - mutex_lock(&dev->mode_config.mutex); - - ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR); - if (ret) - goto out; - - connector->dev = dev; - connector->funcs = funcs; - connector->connector_type = connector_type; - connector->connector_type_id = - ++drm_connector_enum_list[connector_type].count; /* TODO */ - INIT_LIST_HEAD(&connector->user_modes); - INIT_LIST_HEAD(&connector->probed_modes); - INIT_LIST_HEAD(&connector->modes); - connector->edid_blob_ptr = NULL; - - list_add_tail(&connector->head, &dev->mode_config.connector_list); - dev->mode_config.num_connector++; - - if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) - drm_connector_attach_property(connector, - dev->mode_config.edid_property, - 0); - - drm_connector_attach_property(connector, - dev->mode_config.dpms_property, 0); - - out: - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} -EXPORT_SYMBOL(drm_connector_init); - -/** - * drm_connector_cleanup - cleans up an initialised connector - * @connector: connector to cleanup - * - * LOCKING: - * Takes mode config lock. - * - * Cleans up the connector but doesn't free the object. - */ -void drm_connector_cleanup(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_display_mode *mode, *t; - - list_for_each_entry_safe(mode, t, &connector->probed_modes, head) - drm_mode_remove(connector, mode); - - list_for_each_entry_safe(mode, t, &connector->modes, head) - drm_mode_remove(connector, mode); - - list_for_each_entry_safe(mode, t, &connector->user_modes, head) - drm_mode_remove(connector, mode); - - mutex_lock(&dev->mode_config.mutex); - drm_mode_object_put(dev, &connector->base); - list_del(&connector->head); - dev->mode_config.num_connector--; - mutex_unlock(&dev->mode_config.mutex); -} -EXPORT_SYMBOL(drm_connector_cleanup); - -void drm_connector_unplug_all(struct drm_device *dev) -{ - struct drm_connector *connector; - - /* taking the mode config mutex ends up in a clash with sysfs */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - drm_sysfs_connector_remove(connector); - -} -EXPORT_SYMBOL(drm_connector_unplug_all); - -int drm_encoder_init(struct drm_device *dev, - struct drm_encoder *encoder, - const struct drm_encoder_funcs *funcs, - int encoder_type) -{ - int ret; - - mutex_lock(&dev->mode_config.mutex); - - ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); - if (ret) - goto out; - - encoder->dev = dev; - encoder->encoder_type = encoder_type; - encoder->funcs = funcs; - - list_add_tail(&encoder->head, &dev->mode_config.encoder_list); - dev->mode_config.num_encoder++; - - out: - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} -EXPORT_SYMBOL(drm_encoder_init); - -void drm_encoder_cleanup(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - mutex_lock(&dev->mode_config.mutex); - drm_mode_object_put(dev, &encoder->base); - list_del(&encoder->head); - dev->mode_config.num_encoder--; - mutex_unlock(&dev->mode_config.mutex); -} -EXPORT_SYMBOL(drm_encoder_cleanup); - -int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, - unsigned long possible_crtcs, - const struct drm_plane_funcs *funcs, - const uint32_t *formats, uint32_t format_count, - bool priv) -{ - int ret; - - mutex_lock(&dev->mode_config.mutex); - - ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); - if (ret) - goto out; - - plane->dev = dev; - plane->funcs = funcs; - plane->format_types = kmalloc(sizeof(uint32_t) * format_count, - GFP_KERNEL); - if (!plane->format_types) { - DRM_DEBUG_KMS("out of memory when allocating plane\n"); - drm_mode_object_put(dev, &plane->base); - ret = -ENOMEM; - goto out; - } - - memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); - plane->format_count = format_count; - plane->possible_crtcs = possible_crtcs; - - /* private planes are not exposed to userspace, but depending on - * display hardware, might be convenient to allow sharing programming - * for the scanout engine with the crtc implementation. - */ - if (!priv) { - list_add_tail(&plane->head, &dev->mode_config.plane_list); - dev->mode_config.num_plane++; - } else { - INIT_LIST_HEAD(&plane->head); - } - - out: - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} -EXPORT_SYMBOL(drm_plane_init); - -void drm_plane_cleanup(struct drm_plane *plane) -{ - struct drm_device *dev = plane->dev; - - mutex_lock(&dev->mode_config.mutex); - kfree(plane->format_types); - drm_mode_object_put(dev, &plane->base); - /* if not added to a list, it must be a private plane */ - if (!list_empty(&plane->head)) { - list_del(&plane->head); - dev->mode_config.num_plane--; - } - mutex_unlock(&dev->mode_config.mutex); -} -EXPORT_SYMBOL(drm_plane_cleanup); - -/** - * drm_mode_create - create a new display mode - * @dev: DRM device - * - * LOCKING: - * Caller must hold DRM mode_config lock. - * - * Create a new drm_display_mode, give it an ID, and return it. - * - * RETURNS: - * Pointer to new mode on success, NULL on error. - */ -struct drm_display_mode *drm_mode_create(struct drm_device *dev) -{ - struct drm_display_mode *nmode; - - nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL); - if (!nmode) - return NULL; - - if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) { - kfree(nmode); - return NULL; - } - - return nmode; -} -EXPORT_SYMBOL(drm_mode_create); - -/** - * drm_mode_destroy - remove a mode - * @dev: DRM device - * @mode: mode to remove - * - * LOCKING: - * Caller must hold mode config lock. - * - * Free @mode's unique identifier, then free it. - */ -void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode) -{ - if (!mode) - return; - - drm_mode_object_put(dev, &mode->base); - - kfree(mode); -} -EXPORT_SYMBOL(drm_mode_destroy); - -static int drm_mode_create_standard_connector_properties(struct drm_device *dev) -{ - struct drm_property *edid; - struct drm_property *dpms; - - /* - * Standard properties (apply to all connectors) - */ - edid = drm_property_create(dev, DRM_MODE_PROP_BLOB | - DRM_MODE_PROP_IMMUTABLE, - "EDID", 0); - dev->mode_config.edid_property = edid; - - dpms = drm_property_create_enum(dev, 0, - "DPMS", drm_dpms_enum_list, - ARRAY_SIZE(drm_dpms_enum_list)); - dev->mode_config.dpms_property = dpms; - - return 0; -} - -/** - * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties - * @dev: DRM device - * - * Called by a driver the first time a DVI-I connector is made. - */ -int drm_mode_create_dvi_i_properties(struct drm_device *dev) -{ - struct drm_property *dvi_i_selector; - struct drm_property *dvi_i_subconnector; - - if (dev->mode_config.dvi_i_select_subconnector_property) - return 0; - - dvi_i_selector = - drm_property_create_enum(dev, 0, - "select subconnector", - drm_dvi_i_select_enum_list, - ARRAY_SIZE(drm_dvi_i_select_enum_list)); - dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; - - dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, - "subconnector", - drm_dvi_i_subconnector_enum_list, - ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); - dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; - - return 0; -} -EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); - -/** - * drm_create_tv_properties - create TV specific connector properties - * @dev: DRM device - * @num_modes: number of different TV formats (modes) supported - * @modes: array of pointers to strings containing name of each format - * - * Called by a driver's TV initialization routine, this function creates - * the TV specific connector properties for a given device. Caller is - * responsible for allocating a list of format names and passing them to - * this routine. - */ -int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, - char *modes[]) -{ - struct drm_property *tv_selector; - struct drm_property *tv_subconnector; - int i; - - if (dev->mode_config.tv_select_subconnector_property) - return 0; - - /* - * Basic connector properties - */ - tv_selector = drm_property_create_enum(dev, 0, - "select subconnector", - drm_tv_select_enum_list, - ARRAY_SIZE(drm_tv_select_enum_list)); - dev->mode_config.tv_select_subconnector_property = tv_selector; - - tv_subconnector = - drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, - "subconnector", - drm_tv_subconnector_enum_list, - ARRAY_SIZE(drm_tv_subconnector_enum_list)); - dev->mode_config.tv_subconnector_property = tv_subconnector; - - /* - * Other, TV specific properties: margins & TV modes. - */ - dev->mode_config.tv_left_margin_property = - drm_property_create_range(dev, 0, "left margin", 0, 100); - - dev->mode_config.tv_right_margin_property = - drm_property_create_range(dev, 0, "right margin", 0, 100); - - dev->mode_config.tv_top_margin_property = - drm_property_create_range(dev, 0, "top margin", 0, 100); - - dev->mode_config.tv_bottom_margin_property = - drm_property_create_range(dev, 0, "bottom margin", 0, 100); - - dev->mode_config.tv_mode_property = - drm_property_create(dev, DRM_MODE_PROP_ENUM, - "mode", num_modes); - for (i = 0; i < num_modes; i++) - drm_property_add_enum(dev->mode_config.tv_mode_property, i, - i, modes[i]); - - dev->mode_config.tv_brightness_property = - drm_property_create_range(dev, 0, "brightness", 0, 100); - - dev->mode_config.tv_contrast_property = - drm_property_create_range(dev, 0, "contrast", 0, 100); - - dev->mode_config.tv_flicker_reduction_property = - drm_property_create_range(dev, 0, "flicker reduction", 0, 100); - - dev->mode_config.tv_overscan_property = - drm_property_create_range(dev, 0, "overscan", 0, 100); - - dev->mode_config.tv_saturation_property = - drm_property_create_range(dev, 0, "saturation", 0, 100); - - dev->mode_config.tv_hue_property = - drm_property_create_range(dev, 0, "hue", 0, 100); - - return 0; -} -EXPORT_SYMBOL(drm_mode_create_tv_properties); - -/** - * drm_mode_create_scaling_mode_property - create scaling mode property - * @dev: DRM device - * - * Called by a driver the first time it's needed, must be attached to desired - * connectors. - */ -int drm_mode_create_scaling_mode_property(struct drm_device *dev) -{ - struct drm_property *scaling_mode; - - if (dev->mode_config.scaling_mode_property) - return 0; - - scaling_mode = - drm_property_create_enum(dev, 0, "scaling mode", - drm_scaling_mode_enum_list, - ARRAY_SIZE(drm_scaling_mode_enum_list)); - - dev->mode_config.scaling_mode_property = scaling_mode; - - return 0; -} -EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); - -/** - * drm_mode_create_dithering_property - create dithering property - * @dev: DRM device - * - * Called by a driver the first time it's needed, must be attached to desired - * connectors. - */ -int drm_mode_create_dithering_property(struct drm_device *dev) -{ - struct drm_property *dithering_mode; - - if (dev->mode_config.dithering_mode_property) - return 0; - - dithering_mode = - drm_property_create_enum(dev, 0, "dithering", - drm_dithering_mode_enum_list, - ARRAY_SIZE(drm_dithering_mode_enum_list)); - dev->mode_config.dithering_mode_property = dithering_mode; - - return 0; -} -EXPORT_SYMBOL(drm_mode_create_dithering_property); - -/** - * drm_mode_create_dirty_property - create dirty property - * @dev: DRM device - * - * Called by a driver the first time it's needed, must be attached to desired - * connectors. - */ -int drm_mode_create_dirty_info_property(struct drm_device *dev) -{ - struct drm_property *dirty_info; - - if (dev->mode_config.dirty_info_property) - return 0; - - dirty_info = - drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, - "dirty", - drm_dirty_info_enum_list, - ARRAY_SIZE(drm_dirty_info_enum_list)); - dev->mode_config.dirty_info_property = dirty_info; - - return 0; -} -EXPORT_SYMBOL(drm_mode_create_dirty_info_property); - -/** - * drm_mode_config_init - initialize DRM mode_configuration structure - * @dev: DRM device - * - * LOCKING: - * None, should happen single threaded at init time. - * - * Initialize @dev's mode_config structure, used for tracking the graphics - * configuration of @dev. - */ -void drm_mode_config_init(struct drm_device *dev) -{ - mutex_init(&dev->mode_config.mutex); - mutex_init(&dev->mode_config.idr_mutex); - INIT_LIST_HEAD(&dev->mode_config.fb_list); - INIT_LIST_HEAD(&dev->mode_config.crtc_list); - INIT_LIST_HEAD(&dev->mode_config.connector_list); - INIT_LIST_HEAD(&dev->mode_config.encoder_list); - INIT_LIST_HEAD(&dev->mode_config.property_list); - INIT_LIST_HEAD(&dev->mode_config.property_blob_list); - INIT_LIST_HEAD(&dev->mode_config.plane_list); - idr_init(&dev->mode_config.crtc_idr); - - mutex_lock(&dev->mode_config.mutex); - drm_mode_create_standard_connector_properties(dev); - mutex_unlock(&dev->mode_config.mutex); - - /* Just to be sure */ - dev->mode_config.num_fb = 0; - dev->mode_config.num_connector = 0; - dev->mode_config.num_crtc = 0; - dev->mode_config.num_encoder = 0; -} -EXPORT_SYMBOL(drm_mode_config_init); - -int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) -{ - uint32_t total_objects = 0; - - total_objects += dev->mode_config.num_crtc; - total_objects += dev->mode_config.num_connector; - total_objects += dev->mode_config.num_encoder; - - group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); - if (!group->id_list) - return -ENOMEM; - - group->num_crtcs = 0; - group->num_connectors = 0; - group->num_encoders = 0; - return 0; -} - -int drm_mode_group_init_legacy_group(struct drm_device *dev, - struct drm_mode_group *group) -{ - struct drm_crtc *crtc; - struct drm_encoder *encoder; - struct drm_connector *connector; - int ret; - - if ((ret = drm_mode_group_init(dev, group))) - return ret; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - group->id_list[group->num_crtcs++] = crtc->base.id; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - group->id_list[group->num_crtcs + group->num_encoders++] = - encoder->base.id; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - group->id_list[group->num_crtcs + group->num_encoders + - group->num_connectors++] = connector->base.id; - - return 0; -} -EXPORT_SYMBOL(drm_mode_group_init_legacy_group); - -/** - * drm_mode_config_cleanup - free up DRM mode_config info - * @dev: DRM device - * - * LOCKING: - * Caller must hold mode config lock. - * - * Free up all the connectors and CRTCs associated with this DRM device, then - * free up the framebuffers and associated buffer objects. - * - * FIXME: cleanup any dangling user buffer objects too - */ -void drm_mode_config_cleanup(struct drm_device *dev) -{ - struct drm_connector *connector, *ot; - struct drm_crtc *crtc, *ct; - struct drm_encoder *encoder, *enct; - struct drm_framebuffer *fb, *fbt; - struct drm_property *property, *pt; - struct drm_plane *plane, *plt; - - list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, - head) { - encoder->funcs->destroy(encoder); - } - - list_for_each_entry_safe(connector, ot, - &dev->mode_config.connector_list, head) { - connector->funcs->destroy(connector); - } - - list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, - head) { - drm_property_destroy(dev, property); - } - - list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { - fb->funcs->destroy(fb); - } - - list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { - crtc->funcs->destroy(crtc); - } - - list_for_each_entry_safe(plane, plt, &dev->mode_config.plane_list, - head) { - plane->funcs->destroy(plane); - } - - idr_remove_all(&dev->mode_config.crtc_idr); - idr_destroy(&dev->mode_config.crtc_idr); -} -EXPORT_SYMBOL(drm_mode_config_cleanup); - -/** - * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo - * @out: drm_mode_modeinfo struct to return to the user - * @in: drm_display_mode to use - * - * LOCKING: - * None. - * - * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to - * the user. - */ -static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, - const struct drm_display_mode *in) -{ - WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX || - in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX || - in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX || - in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX || - in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX, - "timing values too large for mode info\n"); - - out->clock = in->clock; - out->hdisplay = in->hdisplay; - out->hsync_start = in->hsync_start; - out->hsync_end = in->hsync_end; - out->htotal = in->htotal; - out->hskew = in->hskew; - out->vdisplay = in->vdisplay; - out->vsync_start = in->vsync_start; - out->vsync_end = in->vsync_end; - out->vtotal = in->vtotal; - out->vscan = in->vscan; - out->vrefresh = in->vrefresh; - out->flags = in->flags; - out->type = in->type; - strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); - out->name[DRM_DISPLAY_MODE_LEN-1] = 0; -} - -/** - * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode - * @out: drm_display_mode to return to the user - * @in: drm_mode_modeinfo to use - * - * LOCKING: - * None. - * - * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to - * the caller. - * - * RETURNS: - * Zero on success, errno on failure. - */ -static int drm_crtc_convert_umode(struct drm_display_mode *out, - const struct drm_mode_modeinfo *in) -{ - if (in->clock > INT_MAX || in->vrefresh > INT_MAX) - return -ERANGE; - - out->clock = in->clock; - out->hdisplay = in->hdisplay; - out->hsync_start = in->hsync_start; - out->hsync_end = in->hsync_end; - out->htotal = in->htotal; - out->hskew = in->hskew; - out->vdisplay = in->vdisplay; - out->vsync_start = in->vsync_start; - out->vsync_end = in->vsync_end; - out->vtotal = in->vtotal; - out->vscan = in->vscan; - out->vrefresh = in->vrefresh; - out->flags = in->flags; - out->type = in->type; - strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN); - out->name[DRM_DISPLAY_MODE_LEN-1] = 0; - - return 0; -} - -/** - * drm_mode_getresources - get graphics configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Construct a set of configuration description structures and return - * them to the user, including CRTC, connector and framebuffer configuration. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_getresources(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_card_res *card_res = data; - struct list_head *lh; - struct drm_framebuffer *fb; - struct drm_connector *connector; - struct drm_crtc *crtc; - struct drm_encoder *encoder; - int ret = 0; - int connector_count = 0; - int crtc_count = 0; - int fb_count = 0; - int encoder_count = 0; - int copied = 0, i; - uint32_t __user *fb_id; - uint32_t __user *crtc_id; - uint32_t __user *connector_id; - uint32_t __user *encoder_id; - struct drm_mode_group *mode_group; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - /* - * For the non-control nodes we need to limit the list of resources - * by IDs in the group list for this node - */ - list_for_each(lh, &file_priv->fbs) - fb_count++; - - mode_group = &file_priv->master->minor->mode_group; - if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { - - list_for_each(lh, &dev->mode_config.crtc_list) - crtc_count++; - - list_for_each(lh, &dev->mode_config.connector_list) - connector_count++; - - list_for_each(lh, &dev->mode_config.encoder_list) - encoder_count++; - } else { - - crtc_count = mode_group->num_crtcs; - connector_count = mode_group->num_connectors; - encoder_count = mode_group->num_encoders; - } - - card_res->max_height = dev->mode_config.max_height; - card_res->min_height = dev->mode_config.min_height; - card_res->max_width = dev->mode_config.max_width; - card_res->min_width = dev->mode_config.min_width; - - /* handle this in 4 parts */ - /* FBs */ - if (card_res->count_fbs >= fb_count) { - copied = 0; - fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr; - list_for_each_entry(fb, &file_priv->fbs, filp_head) { - if (put_user(fb->base.id, fb_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - card_res->count_fbs = fb_count; - - /* CRTCs */ - if (card_res->count_crtcs >= crtc_count) { - copied = 0; - crtc_id = (uint32_t __user *)(unsigned long)card_res->crtc_id_ptr; - if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { - list_for_each_entry(crtc, &dev->mode_config.crtc_list, - head) { - DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); - if (put_user(crtc->base.id, crtc_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } else { - for (i = 0; i < mode_group->num_crtcs; i++) { - if (put_user(mode_group->id_list[i], - crtc_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - } - card_res->count_crtcs = crtc_count; - - /* Encoders */ - if (card_res->count_encoders >= encoder_count) { - copied = 0; - encoder_id = (uint32_t __user *)(unsigned long)card_res->encoder_id_ptr; - if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { - list_for_each_entry(encoder, - &dev->mode_config.encoder_list, - head) { - DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", encoder->base.id, - drm_get_encoder_name(encoder)); - if (put_user(encoder->base.id, encoder_id + - copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } else { - for (i = mode_group->num_crtcs; i < mode_group->num_crtcs + mode_group->num_encoders; i++) { - if (put_user(mode_group->id_list[i], - encoder_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - - } - } - card_res->count_encoders = encoder_count; - - /* Connectors */ - if (card_res->count_connectors >= connector_count) { - copied = 0; - connector_id = (uint32_t __user *)(unsigned long)card_res->connector_id_ptr; - if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { - list_for_each_entry(connector, - &dev->mode_config.connector_list, - head) { - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, - drm_get_connector_name(connector)); - if (put_user(connector->base.id, - connector_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } else { - int start = mode_group->num_crtcs + - mode_group->num_encoders; - for (i = start; i < start + mode_group->num_connectors; i++) { - if (put_user(mode_group->id_list[i], - connector_id + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - } - card_res->count_connectors = connector_count; - - DRM_DEBUG_KMS("CRTC[%d] CONNECTORS[%d] ENCODERS[%d]\n", card_res->count_crtcs, - card_res->count_connectors, card_res->count_encoders); - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_getcrtc - get CRTC configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Construct a CRTC configuration structure to return to the user. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_getcrtc(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_crtc *crtc_resp = data; - struct drm_crtc *crtc; - struct drm_mode_object *obj; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, crtc_resp->crtc_id, - DRM_MODE_OBJECT_CRTC); - if (!obj) { - ret = -EINVAL; - goto out; - } - crtc = obj_to_crtc(obj); - - crtc_resp->x = crtc->x; - crtc_resp->y = crtc->y; - crtc_resp->gamma_size = crtc->gamma_size; - if (crtc->fb) - crtc_resp->fb_id = crtc->fb->base.id; - else - crtc_resp->fb_id = 0; - - if (crtc->enabled) { - - drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); - crtc_resp->mode_valid = 1; - - } else { - crtc_resp->mode_valid = 0; - } - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_getconnector - get connector configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Construct a connector configuration structure to return to the user. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_getconnector(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_get_connector *out_resp = data; - struct drm_mode_object *obj; - struct drm_connector *connector; - struct drm_display_mode *mode; - int mode_count = 0; - int props_count = 0; - int encoders_count = 0; - int ret = 0; - int copied = 0; - int i; - struct drm_mode_modeinfo u_mode; - struct drm_mode_modeinfo __user *mode_ptr; - uint32_t __user *prop_ptr; - uint64_t __user *prop_values; - uint32_t __user *encoder_ptr; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); - - DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id); - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, out_resp->connector_id, - DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - ret = -EINVAL; - goto out; - } - connector = obj_to_connector(obj); - - for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { - if (connector->property_ids[i] != 0) { - props_count++; - } - } - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] != 0) { - encoders_count++; - } - } - - if (out_resp->count_modes == 0) { - connector->funcs->fill_modes(connector, - dev->mode_config.max_width, - dev->mode_config.max_height); - } - - /* delayed so we get modes regardless of pre-fill_modes state */ - list_for_each_entry(mode, &connector->modes, head) - mode_count++; - - out_resp->connector_id = connector->base.id; - out_resp->connector_type = connector->connector_type; - out_resp->connector_type_id = connector->connector_type_id; - out_resp->mm_width = connector->display_info.width_mm; - out_resp->mm_height = connector->display_info.height_mm; - out_resp->subpixel = connector->display_info.subpixel_order; - out_resp->connection = connector->status; - if (connector->encoder) - out_resp->encoder_id = connector->encoder->base.id; - else - out_resp->encoder_id = 0; - - /* - * This ioctl is called twice, once to determine how much space is - * needed, and the 2nd time to fill it. - */ - if ((out_resp->count_modes >= mode_count) && mode_count) { - copied = 0; - mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr; - list_for_each_entry(mode, &connector->modes, head) { - drm_crtc_convert_to_umode(&u_mode, mode); - if (copy_to_user(mode_ptr + copied, - &u_mode, sizeof(u_mode))) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - out_resp->count_modes = mode_count; - - if ((out_resp->count_props >= props_count) && props_count) { - copied = 0; - prop_ptr = (uint32_t __user *)(unsigned long)(out_resp->props_ptr); - prop_values = (uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr); - for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { - if (connector->property_ids[i] != 0) { - if (put_user(connector->property_ids[i], - prop_ptr + copied)) { - ret = -EFAULT; - goto out; - } - - if (put_user(connector->property_values[i], - prop_values + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - } - out_resp->count_props = props_count; - - if ((out_resp->count_encoders >= encoders_count) && encoders_count) { - copied = 0; - encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr); - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] != 0) { - if (put_user(connector->encoder_ids[i], - encoder_ptr + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - } - out_resp->count_encoders = encoders_count; - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int drm_mode_getencoder(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_get_encoder *enc_resp = data; - struct drm_mode_object *obj; - struct drm_encoder *encoder; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, enc_resp->encoder_id, - DRM_MODE_OBJECT_ENCODER); - if (!obj) { - ret = -EINVAL; - goto out; - } - encoder = obj_to_encoder(obj); - - if (encoder->crtc) - enc_resp->crtc_id = encoder->crtc->base.id; - else - enc_resp->crtc_id = 0; - enc_resp->encoder_type = encoder->encoder_type; - enc_resp->encoder_id = encoder->base.id; - enc_resp->possible_crtcs = encoder->possible_crtcs; - enc_resp->possible_clones = encoder->possible_clones; - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_getplane_res - get plane info - * @dev: DRM device - * @data: ioctl data - * @file_priv: DRM file info - * - * LOCKING: - * Takes mode config lock. - * - * Return an plane count and set of IDs. - */ -int drm_mode_getplane_res(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_get_plane_res *plane_resp = data; - struct drm_mode_config *config; - struct drm_plane *plane; - uint32_t __user *plane_ptr; - int copied = 0, ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - config = &dev->mode_config; - - /* - * This ioctl is called twice, once to determine how much space is - * needed, and the 2nd time to fill it. - */ - if (config->num_plane && - (plane_resp->count_planes >= config->num_plane)) { - plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr; - - list_for_each_entry(plane, &config->plane_list, head) { - if (put_user(plane->base.id, plane_ptr + copied)) { - ret = -EFAULT; - goto out; - } - copied++; - } - } - plane_resp->count_planes = config->num_plane; - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_getplane - get plane info - * @dev: DRM device - * @data: ioctl data - * @file_priv: DRM file info - * - * LOCKING: - * Takes mode config lock. - * - * Return plane info, including formats supported, gamma size, any - * current fb, etc. - */ -int drm_mode_getplane(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_get_plane *plane_resp = data; - struct drm_mode_object *obj; - struct drm_plane *plane; - uint32_t __user *format_ptr; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, plane_resp->plane_id, - DRM_MODE_OBJECT_PLANE); - if (!obj) { - ret = -ENOENT; - goto out; - } - plane = obj_to_plane(obj); - - if (plane->crtc) - plane_resp->crtc_id = plane->crtc->base.id; - else - plane_resp->crtc_id = 0; - - if (plane->fb) - plane_resp->fb_id = plane->fb->base.id; - else - plane_resp->fb_id = 0; - - plane_resp->plane_id = plane->base.id; - plane_resp->possible_crtcs = plane->possible_crtcs; - plane_resp->gamma_size = plane->gamma_size; - - /* - * This ioctl is called twice, once to determine how much space is - * needed, and the 2nd time to fill it. - */ - if (plane->format_count && - (plane_resp->count_format_types >= plane->format_count)) { - format_ptr = (uint32_t __user *)(unsigned long)plane_resp->format_type_ptr; - if (copy_to_user(format_ptr, - plane->format_types, - sizeof(uint32_t) * plane->format_count)) { - ret = -EFAULT; - goto out; - } - } - plane_resp->count_format_types = plane->format_count; - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_setplane - set up or tear down an plane - * @dev: DRM device - * @data: ioctl data* - * @file_prive: DRM file info - * - * LOCKING: - * Takes mode config lock. - * - * Set plane info, including placement, fb, scaling, and other factors. - * Or pass a NULL fb to disable. - */ -int drm_mode_setplane(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_set_plane *plane_req = data; - struct drm_mode_object *obj; - struct drm_plane *plane; - struct drm_crtc *crtc; - struct drm_framebuffer *fb; - int ret = 0; - unsigned int fb_width, fb_height; - int i; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - /* - * First, find the plane, crtc, and fb objects. If not available, - * we don't bother to call the driver. - */ - obj = drm_mode_object_find(dev, plane_req->plane_id, - DRM_MODE_OBJECT_PLANE); - if (!obj) { - DRM_DEBUG_KMS("Unknown plane ID %d\n", - plane_req->plane_id); - ret = -ENOENT; - goto out; - } - plane = obj_to_plane(obj); - - /* No fb means shut it down */ - if (!plane_req->fb_id) { - plane->funcs->disable_plane(plane); - plane->crtc = NULL; - plane->fb = NULL; - goto out; - } - - obj = drm_mode_object_find(dev, plane_req->crtc_id, - DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_DEBUG_KMS("Unknown crtc ID %d\n", - plane_req->crtc_id); - ret = -ENOENT; - goto out; - } - crtc = obj_to_crtc(obj); - - obj = drm_mode_object_find(dev, plane_req->fb_id, - DRM_MODE_OBJECT_FB); - if (!obj) { - DRM_DEBUG_KMS("Unknown framebuffer ID %d\n", - plane_req->fb_id); - ret = -ENOENT; - goto out; - } - fb = obj_to_fb(obj); - - /* Check whether this plane supports the fb pixel format. */ - for (i = 0; i < plane->format_count; i++) - if (fb->pixel_format == plane->format_types[i]) - break; - if (i == plane->format_count) { - DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format); - ret = -EINVAL; - goto out; - } - - fb_width = fb->width << 16; - fb_height = fb->height << 16; - - /* Make sure source coordinates are inside the fb. */ - if (plane_req->src_w > fb_width || - plane_req->src_x > fb_width - plane_req->src_w || - plane_req->src_h > fb_height || - plane_req->src_y > fb_height - plane_req->src_h) { - DRM_DEBUG_KMS("Invalid source coordinates " - "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n", - plane_req->src_w >> 16, - ((plane_req->src_w & 0xffff) * 15625) >> 10, - plane_req->src_h >> 16, - ((plane_req->src_h & 0xffff) * 15625) >> 10, - plane_req->src_x >> 16, - ((plane_req->src_x & 0xffff) * 15625) >> 10, - plane_req->src_y >> 16, - ((plane_req->src_y & 0xffff) * 15625) >> 10); - ret = -ENOSPC; - goto out; - } - - /* Give drivers some help against integer overflows */ - if (plane_req->crtc_w > INT_MAX || - plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w || - plane_req->crtc_h > INT_MAX || - plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) { - DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", - plane_req->crtc_w, plane_req->crtc_h, - plane_req->crtc_x, plane_req->crtc_y); - ret = -ERANGE; - goto out; - } - - ret = plane->funcs->update_plane(plane, crtc, fb, - plane_req->crtc_x, plane_req->crtc_y, - plane_req->crtc_w, plane_req->crtc_h, - plane_req->src_x, plane_req->src_y, - plane_req->src_w, plane_req->src_h); - if (!ret) { - plane->crtc = crtc; - plane->fb = fb; - } - -out: - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} - -/** - * drm_mode_setcrtc - set CRTC configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Build a new CRTC configuration based on user request. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_setcrtc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_mode_config *config = &dev->mode_config; - struct drm_mode_crtc *crtc_req = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct drm_connector **connector_set = NULL, *connector; - struct drm_framebuffer *fb = NULL; - struct drm_display_mode *mode = NULL; - struct drm_mode_set set; - uint32_t __user *set_connectors_ptr; - int ret = 0; - int i; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - /* For some reason crtc x/y offsets are signed internally. */ - if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX) - return -ERANGE; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, crtc_req->crtc_id, - DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); - ret = -EINVAL; - goto out; - } - crtc = obj_to_crtc(obj); - DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); - - if (crtc_req->mode_valid) { - /* If we have a mode we need a framebuffer. */ - /* If we pass -1, set the mode with the currently bound fb */ - if (crtc_req->fb_id == -1) { - if (!crtc->fb) { - DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); - ret = -EINVAL; - goto out; - } - fb = crtc->fb; - } else { - obj = drm_mode_object_find(dev, crtc_req->fb_id, - DRM_MODE_OBJECT_FB); - if (!obj) { - DRM_DEBUG_KMS("Unknown FB ID%d\n", - crtc_req->fb_id); - ret = -EINVAL; - goto out; - } - fb = obj_to_fb(obj); - } - - mode = drm_mode_create(dev); - if (!mode) { - ret = -ENOMEM; - goto out; - } - - ret = drm_crtc_convert_umode(mode, &crtc_req->mode); - if (ret) { - DRM_DEBUG_KMS("Invalid mode\n"); - goto out; - } - - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - - if (mode->hdisplay > fb->width || - mode->vdisplay > fb->height || - crtc_req->x > fb->width - mode->hdisplay || - crtc_req->y > fb->height - mode->vdisplay) { - DRM_DEBUG_KMS("Invalid CRTC viewport %ux%u+%u+%u for fb size %ux%u.\n", - mode->hdisplay, mode->vdisplay, - crtc_req->x, crtc_req->y, - fb->width, fb->height); - ret = -ENOSPC; - goto out; - } - } - - if (crtc_req->count_connectors == 0 && mode) { - DRM_DEBUG_KMS("Count connectors is 0 but mode set\n"); - ret = -EINVAL; - goto out; - } - - if (crtc_req->count_connectors > 0 && (!mode || !fb)) { - DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n", - crtc_req->count_connectors); - ret = -EINVAL; - goto out; - } - - if (crtc_req->count_connectors > 0) { - u32 out_id; - - /* Avoid unbounded kernel memory allocation */ - if (crtc_req->count_connectors > config->num_connector) { - ret = -EINVAL; - goto out; - } - - connector_set = kmalloc(crtc_req->count_connectors * - sizeof(struct drm_connector *), - GFP_KERNEL); - if (!connector_set) { - ret = -ENOMEM; - goto out; - } - - for (i = 0; i < crtc_req->count_connectors; i++) { - set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr; - if (get_user(out_id, &set_connectors_ptr[i])) { - ret = -EFAULT; - goto out; - } - - obj = drm_mode_object_find(dev, out_id, - DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - DRM_DEBUG_KMS("Connector id %d unknown\n", - out_id); - ret = -EINVAL; - goto out; - } - connector = obj_to_connector(obj); - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", - connector->base.id, - drm_get_connector_name(connector)); - - connector_set[i] = connector; - } - } - - set.crtc = crtc; - set.x = crtc_req->x; - set.y = crtc_req->y; - set.mode = mode; - set.connectors = connector_set; - set.num_connectors = crtc_req->count_connectors; - set.fb = fb; - ret = crtc->funcs->set_config(&set); - -out: - kfree(connector_set); - drm_mode_destroy(dev, mode); - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int drm_mode_cursor_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_cursor *req = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - if (!req->flags) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); - ret = -EINVAL; - goto out; - } - crtc = obj_to_crtc(obj); - - if (req->flags & DRM_MODE_CURSOR_BO) { - if (!crtc->funcs->cursor_set) { - ret = -ENXIO; - goto out; - } - /* Turns off the cursor if handle is 0 */ - ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle, - req->width, req->height); - } - - if (req->flags & DRM_MODE_CURSOR_MOVE) { - if (crtc->funcs->cursor_move) { - ret = crtc->funcs->cursor_move(crtc, req->x, req->y); - } else { - ret = -EFAULT; - goto out; - } - } -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/* Original addfb only supported RGB formats, so figure out which one */ -uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth) -{ - uint32_t fmt; - - switch (bpp) { - case 8: - fmt = DRM_FORMAT_RGB332; - break; - case 16: - if (depth == 15) - fmt = DRM_FORMAT_XRGB1555; - else - fmt = DRM_FORMAT_RGB565; - break; - case 24: - fmt = DRM_FORMAT_RGB888; - break; - case 32: - if (depth == 24) - fmt = DRM_FORMAT_XRGB8888; - else if (depth == 30) - fmt = DRM_FORMAT_XRGB2101010; - else - fmt = DRM_FORMAT_ARGB8888; - break; - default: - DRM_ERROR("bad bpp, assuming x8r8g8b8 pixel format\n"); - fmt = DRM_FORMAT_XRGB8888; - break; - } - - return fmt; -} -EXPORT_SYMBOL(drm_mode_legacy_fb_format); - -/** - * drm_mode_addfb - add an FB to the graphics configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Add a new FB to the specified CRTC, given a user request. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_addfb(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_fb_cmd *or = data; - struct drm_mode_fb_cmd2 r = {}; - struct drm_mode_config *config = &dev->mode_config; - struct drm_framebuffer *fb; - int ret = 0; - - /* Use new struct with format internally */ - r.fb_id = or->fb_id; - r.width = or->width; - r.height = or->height; - r.pitches[0] = or->pitch; - r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth); - r.handles[0] = or->handle; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - if ((config->min_width > r.width) || (r.width > config->max_width)) - return -EINVAL; - - if ((config->min_height > r.height) || (r.height > config->max_height)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - /* TODO check buffer is sufficiently large */ - /* TODO setup destructor callback */ - - fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); - if (IS_ERR(fb)) { - DRM_ERROR("could not create framebuffer\n"); - ret = PTR_ERR(fb); - goto out; - } - - or->fb_id = fb->base.id; - list_add(&fb->filp_head, &file_priv->fbs); - DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -static int format_check(struct drm_mode_fb_cmd2 *r) -{ - uint32_t format = r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN; - - switch (format) { - case DRM_FORMAT_C8: - case DRM_FORMAT_RGB332: - case DRM_FORMAT_BGR233: - case DRM_FORMAT_XRGB4444: - case DRM_FORMAT_XBGR4444: - case DRM_FORMAT_RGBX4444: - case DRM_FORMAT_BGRX4444: - case DRM_FORMAT_ARGB4444: - case DRM_FORMAT_ABGR4444: - case DRM_FORMAT_RGBA4444: - case DRM_FORMAT_BGRA4444: - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XBGR1555: - case DRM_FORMAT_RGBX5551: - case DRM_FORMAT_BGRX5551: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ABGR1555: - case DRM_FORMAT_RGBA5551: - case DRM_FORMAT_BGRA5551: - case DRM_FORMAT_RGB565: - case DRM_FORMAT_BGR565: - case DRM_FORMAT_RGB888: - case DRM_FORMAT_BGR888: - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_RGBX8888: - case DRM_FORMAT_BGRX8888: - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_RGBA8888: - case DRM_FORMAT_BGRA8888: - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_RGBA1010102: - case DRM_FORMAT_BGRA1010102: - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - case DRM_FORMAT_AYUV: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV61: - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YVU410: - case DRM_FORMAT_YUV411: - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YUV422: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YUV444: - case DRM_FORMAT_YVU444: - return 0; - default: - return -EINVAL; - } -} - -/** - * drm_mode_addfb2 - add an FB to the graphics configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Add a new FB to the specified CRTC, given a user request with format. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_addfb2(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_fb_cmd2 *r = data; - struct drm_mode_config *config = &dev->mode_config; - struct drm_framebuffer *fb; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - if ((config->min_width > r->width) || (r->width > config->max_width)) { - DRM_ERROR("bad framebuffer width %d, should be >= %d && <= %d\n", - r->width, config->min_width, config->max_width); - return -EINVAL; - } - if ((config->min_height > r->height) || (r->height > config->max_height)) { - DRM_ERROR("bad framebuffer height %d, should be >= %d && <= %d\n", - r->height, config->min_height, config->max_height); - return -EINVAL; - } - - ret = format_check(r); - if (ret) { - DRM_ERROR("bad framebuffer format 0x%08x\n", r->pixel_format); - return ret; - } - - mutex_lock(&dev->mode_config.mutex); - - fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); - if (IS_ERR(fb)) { - DRM_ERROR("could not create framebuffer\n"); - ret = PTR_ERR(fb); - goto out; - } - - r->fb_id = fb->base.id; - list_add(&fb->filp_head, &file_priv->fbs); - DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id); - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_rmfb - remove an FB from the configuration - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Remove the FB specified by the user. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_rmfb(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_object *obj; - struct drm_framebuffer *fb = NULL; - struct drm_framebuffer *fbl = NULL; - uint32_t *id = data; - int ret = 0; - int found = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB); - /* TODO check that we really get a framebuffer back. */ - if (!obj) { - ret = -EINVAL; - goto out; - } - fb = obj_to_fb(obj); - - list_for_each_entry(fbl, &file_priv->fbs, filp_head) - if (fb == fbl) - found = 1; - - if (!found) { - ret = -EINVAL; - goto out; - } - - /* TODO release all crtc connected to the framebuffer */ - /* TODO unhock the destructor from the buffer object */ - - list_del(&fb->filp_head); - fb->funcs->destroy(fb); - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -/** - * drm_mode_getfb - get FB info - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Lookup the FB given its ID and return info about it. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_getfb(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_fb_cmd *r = data; - struct drm_mode_object *obj; - struct drm_framebuffer *fb; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); - if (!obj) { - ret = -EINVAL; - goto out; - } - fb = obj_to_fb(obj); - - r->height = fb->height; - r->width = fb->width; - r->depth = fb->depth; - r->bpp = fb->bits_per_pixel; - r->pitch = fb->pitches[0]; - fb->funcs->create_handle(fb, file_priv, &r->handle); - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int drm_mode_dirtyfb_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_clip_rect __user *clips_ptr; - struct drm_clip_rect *clips = NULL; - struct drm_mode_fb_dirty_cmd *r = data; - struct drm_mode_object *obj; - struct drm_framebuffer *fb; - unsigned flags; - int num_clips; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB); - if (!obj) { - ret = -EINVAL; - goto out_err1; - } - fb = obj_to_fb(obj); - - num_clips = r->num_clips; - clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr; - - if (!num_clips != !clips_ptr) { - ret = -EINVAL; - goto out_err1; - } - - flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags; - - /* If userspace annotates copy, clips must come in pairs */ - if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) { - ret = -EINVAL; - goto out_err1; - } - - if (num_clips && clips_ptr) { - if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { - ret = -EINVAL; - goto out_err1; - } - clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); - if (!clips) { - ret = -ENOMEM; - goto out_err1; - } - - ret = copy_from_user(clips, clips_ptr, - num_clips * sizeof(*clips)); - if (ret) { - ret = -EFAULT; - goto out_err2; - } - } - - if (fb->funcs->dirty) { - ret = fb->funcs->dirty(fb, file_priv, flags, r->color, - clips, num_clips); - } else { - ret = -ENOSYS; - goto out_err2; - } - -out_err2: - kfree(clips); -out_err1: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - - -/** - * drm_fb_release - remove and free the FBs on this file - * @filp: file * from the ioctl - * - * LOCKING: - * Takes mode config lock. - * - * Destroy all the FBs associated with @filp. - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -void drm_fb_release(struct drm_file *priv) -{ - struct drm_device *dev = priv->minor->dev; - struct drm_framebuffer *fb, *tfb; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) { - list_del(&fb->filp_head); - fb->funcs->destroy(fb); - } - mutex_unlock(&dev->mode_config.mutex); -} - -/** - * drm_mode_attachmode - add a mode to the user mode list - * @dev: DRM device - * @connector: connector to add the mode to - * @mode: mode to add - * - * Add @mode to @connector's user mode list. - */ -static void drm_mode_attachmode(struct drm_device *dev, - struct drm_connector *connector, - struct drm_display_mode *mode) -{ - list_add_tail(&mode->head, &connector->user_modes); -} - -int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc, - const struct drm_display_mode *mode) -{ - struct drm_connector *connector; - int ret = 0; - struct drm_display_mode *dup_mode, *next; - LIST_HEAD(list); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (!connector->encoder) - continue; - if (connector->encoder->crtc == crtc) { - dup_mode = drm_mode_duplicate(dev, mode); - if (!dup_mode) { - ret = -ENOMEM; - goto out; - } - list_add_tail(&dup_mode->head, &list); - } - } - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (!connector->encoder) - continue; - if (connector->encoder->crtc == crtc) - list_move_tail(list.next, &connector->user_modes); - } - - WARN_ON(!list_empty(&list)); - - out: - list_for_each_entry_safe(dup_mode, next, &list, head) - drm_mode_destroy(dev, dup_mode); - - return ret; -} -EXPORT_SYMBOL(drm_mode_attachmode_crtc); - -static int drm_mode_detachmode(struct drm_device *dev, - struct drm_connector *connector, - struct drm_display_mode *mode) -{ - int found = 0; - int ret = 0; - struct drm_display_mode *match_mode, *t; - - list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) { - if (drm_mode_equal(match_mode, mode)) { - list_del(&match_mode->head); - drm_mode_destroy(dev, match_mode); - found = 1; - break; - } - } - - if (!found) - ret = -EINVAL; - - return ret; -} - -int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode) -{ - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - drm_mode_detachmode(dev, connector, mode); - } - return 0; -} -EXPORT_SYMBOL(drm_mode_detachmode_crtc); - -/** - * drm_fb_attachmode - Attach a user mode to an connector - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * This attaches a user specified mode to an connector. - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_attachmode_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_mode_cmd *mode_cmd = data; - struct drm_connector *connector; - struct drm_display_mode *mode; - struct drm_mode_object *obj; - struct drm_mode_modeinfo *umode = &mode_cmd->mode; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - ret = -EINVAL; - goto out; - } - connector = obj_to_connector(obj); - - mode = drm_mode_create(dev); - if (!mode) { - ret = -ENOMEM; - goto out; - } - - ret = drm_crtc_convert_umode(mode, umode); - if (ret) { - DRM_DEBUG_KMS("Invalid mode\n"); - drm_mode_destroy(dev, mode); - goto out; - } - - drm_mode_attachmode(dev, connector, mode); -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - - -/** - * drm_fb_detachmode - Detach a user specified mode from an connector - * @inode: inode from the ioctl - * @filp: file * from the ioctl - * @cmd: cmd from ioctl - * @arg: arg from ioctl - * - * Called by the user via ioctl. - * - * RETURNS: - * Zero on success, errno on failure. - */ -int drm_mode_detachmode_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_object *obj; - struct drm_mode_mode_cmd *mode_cmd = data; - struct drm_connector *connector; - struct drm_display_mode mode; - struct drm_mode_modeinfo *umode = &mode_cmd->mode; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - ret = -EINVAL; - goto out; - } - connector = obj_to_connector(obj); - - ret = drm_crtc_convert_umode(&mode, umode); - if (ret) { - DRM_DEBUG_KMS("Invalid mode\n"); - goto out; - } - - ret = drm_mode_detachmode(dev, connector, &mode); -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -struct drm_property *drm_property_create(struct drm_device *dev, int flags, - const char *name, int num_values) -{ - struct drm_property *property = NULL; - int ret; - - property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); - if (!property) - return NULL; - - if (num_values) { - property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); - if (!property->values) - goto fail; - } - - ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); - if (ret) - goto fail; - - property->flags = flags; - property->num_values = num_values; - INIT_LIST_HEAD(&property->enum_blob_list); - - if (name) { - strncpy(property->name, name, DRM_PROP_NAME_LEN); - property->name[DRM_PROP_NAME_LEN-1] = '\0'; - } - - list_add_tail(&property->head, &dev->mode_config.property_list); - return property; -fail: - kfree(property->values); - kfree(property); - return NULL; -} -EXPORT_SYMBOL(drm_property_create); - -struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, - const char *name, - const struct drm_prop_enum_list *props, - int num_values) -{ - struct drm_property *property; - int i, ret; - - flags |= DRM_MODE_PROP_ENUM; - - property = drm_property_create(dev, flags, name, num_values); - if (!property) - return NULL; - - for (i = 0; i < num_values; i++) { - ret = drm_property_add_enum(property, i, - props[i].type, - props[i].name); - if (ret) { - drm_property_destroy(dev, property); - return NULL; - } - } - - return property; -} -EXPORT_SYMBOL(drm_property_create_enum); - -struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, - const char *name, - uint64_t min, uint64_t max) -{ - struct drm_property *property; - - flags |= DRM_MODE_PROP_RANGE; - - property = drm_property_create(dev, flags, name, 2); - if (!property) - return NULL; - - property->values[0] = min; - property->values[1] = max; - - return property; -} -EXPORT_SYMBOL(drm_property_create_range); - -int drm_property_add_enum(struct drm_property *property, int index, - uint64_t value, const char *name) -{ - struct drm_property_enum *prop_enum; - - if (!(property->flags & DRM_MODE_PROP_ENUM)) - return -EINVAL; - - if (!list_empty(&property->enum_blob_list)) { - list_for_each_entry(prop_enum, &property->enum_blob_list, head) { - if (prop_enum->value == value) { - strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); - prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; - return 0; - } - } - } - - prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); - if (!prop_enum) - return -ENOMEM; - - strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN); - prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0'; - prop_enum->value = value; - - property->values[index] = value; - list_add_tail(&prop_enum->head, &property->enum_blob_list); - return 0; -} -EXPORT_SYMBOL(drm_property_add_enum); - -void drm_property_destroy(struct drm_device *dev, struct drm_property *property) -{ - struct drm_property_enum *prop_enum, *pt; - - list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) { - list_del(&prop_enum->head); - kfree(prop_enum); - } - - if (property->num_values) - kfree(property->values); - drm_mode_object_put(dev, &property->base); - list_del(&property->head); - kfree(property); -} -EXPORT_SYMBOL(drm_property_destroy); - -int drm_connector_attach_property(struct drm_connector *connector, - struct drm_property *property, uint64_t init_val) -{ - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { - if (connector->property_ids[i] == 0) { - connector->property_ids[i] = property->base.id; - connector->property_values[i] = init_val; - break; - } - } - - if (i == DRM_CONNECTOR_MAX_PROPERTY) - return -EINVAL; - return 0; -} -EXPORT_SYMBOL(drm_connector_attach_property); - -int drm_connector_property_set_value(struct drm_connector *connector, - struct drm_property *property, uint64_t value) -{ - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { - if (connector->property_ids[i] == property->base.id) { - connector->property_values[i] = value; - break; - } - } - - if (i == DRM_CONNECTOR_MAX_PROPERTY) - return -EINVAL; - return 0; -} -EXPORT_SYMBOL(drm_connector_property_set_value); - -int drm_connector_property_get_value(struct drm_connector *connector, - struct drm_property *property, uint64_t *val) -{ - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { - if (connector->property_ids[i] == property->base.id) { - *val = connector->property_values[i]; - break; - } - } - - if (i == DRM_CONNECTOR_MAX_PROPERTY) - return -EINVAL; - return 0; -} -EXPORT_SYMBOL(drm_connector_property_get_value); - -int drm_mode_getproperty_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_object *obj; - struct drm_mode_get_property *out_resp = data; - struct drm_property *property; - int enum_count = 0; - int blob_count = 0; - int value_count = 0; - int ret = 0, i; - int copied; - struct drm_property_enum *prop_enum; - struct drm_mode_property_enum __user *enum_ptr; - struct drm_property_blob *prop_blob; - uint32_t __user *blob_id_ptr; - uint64_t __user *values_ptr; - uint32_t __user *blob_length_ptr; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); - if (!obj) { - ret = -EINVAL; - goto done; - } - property = obj_to_property(obj); - - if (property->flags & DRM_MODE_PROP_ENUM) { - list_for_each_entry(prop_enum, &property->enum_blob_list, head) - enum_count++; - } else if (property->flags & DRM_MODE_PROP_BLOB) { - list_for_each_entry(prop_blob, &property->enum_blob_list, head) - blob_count++; - } - - value_count = property->num_values; - - strncpy(out_resp->name, property->name, DRM_PROP_NAME_LEN); - out_resp->name[DRM_PROP_NAME_LEN-1] = 0; - out_resp->flags = property->flags; - - if ((out_resp->count_values >= value_count) && value_count) { - values_ptr = (uint64_t __user *)(unsigned long)out_resp->values_ptr; - for (i = 0; i < value_count; i++) { - if (copy_to_user(values_ptr + i, &property->values[i], sizeof(uint64_t))) { - ret = -EFAULT; - goto done; - } - } - } - out_resp->count_values = value_count; - - if (property->flags & DRM_MODE_PROP_ENUM) { - if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { - copied = 0; - enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; - list_for_each_entry(prop_enum, &property->enum_blob_list, head) { - - if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) { - ret = -EFAULT; - goto done; - } - - if (copy_to_user(&enum_ptr[copied].name, - &prop_enum->name, DRM_PROP_NAME_LEN)) { - ret = -EFAULT; - goto done; - } - copied++; - } - } - out_resp->count_enum_blobs = enum_count; - } - - if (property->flags & DRM_MODE_PROP_BLOB) { - if ((out_resp->count_enum_blobs >= blob_count) && blob_count) { - copied = 0; - blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr; - blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr; - - list_for_each_entry(prop_blob, &property->enum_blob_list, head) { - if (put_user(prop_blob->base.id, blob_id_ptr + copied)) { - ret = -EFAULT; - goto done; - } - - if (put_user(prop_blob->length, blob_length_ptr + copied)) { - ret = -EFAULT; - goto done; - } - - copied++; - } - } - out_resp->count_enum_blobs = blob_count; - } -done: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length, - void *data) -{ - struct drm_property_blob *blob; - int ret; - - if (!length || !data) - return NULL; - - blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); - if (!blob) - return NULL; - - ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); - if (ret) { - kfree(blob); - return NULL; - } - - blob->length = length; - - memcpy(blob->data, data, length); - - list_add_tail(&blob->head, &dev->mode_config.property_blob_list); - return blob; -} - -static void drm_property_destroy_blob(struct drm_device *dev, - struct drm_property_blob *blob) -{ - drm_mode_object_put(dev, &blob->base); - list_del(&blob->head); - kfree(blob); -} - -int drm_mode_getblob_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_object *obj; - struct drm_mode_get_blob *out_resp = data; - struct drm_property_blob *blob; - int ret = 0; - void __user *blob_ptr; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB); - if (!obj) { - ret = -EINVAL; - goto done; - } - blob = obj_to_blob(obj); - - if (out_resp->length == blob->length) { - blob_ptr = (void __user *)(unsigned long)out_resp->data; - if (copy_to_user(blob_ptr, blob->data, blob->length)){ - ret = -EFAULT; - goto done; - } - } - out_resp->length = blob->length; - -done: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int drm_mode_connector_update_edid_property(struct drm_connector *connector, - struct edid *edid) -{ - struct drm_device *dev = connector->dev; - int ret = 0, size; - - if (connector->edid_blob_ptr) - drm_property_destroy_blob(dev, connector->edid_blob_ptr); - - /* Delete edid, when there is none. */ - if (!edid) { - connector->edid_blob_ptr = NULL; - ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0); - return ret; - } - - size = EDID_LENGTH * (1 + edid->extensions); - connector->edid_blob_ptr = drm_property_create_blob(connector->dev, - size, edid); - - ret = drm_connector_property_set_value(connector, - dev->mode_config.edid_property, - connector->edid_blob_ptr->base.id); - - return ret; -} -EXPORT_SYMBOL(drm_mode_connector_update_edid_property); - -int drm_mode_connector_property_set_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_connector_set_property *out_resp = data; - struct drm_mode_object *obj; - struct drm_property *property; - struct drm_connector *connector; - int ret = -EINVAL; - int i; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, out_resp->connector_id, DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - goto out; - } - connector = obj_to_connector(obj); - - for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) { - if (connector->property_ids[i] == out_resp->prop_id) - break; - } - - if (i == DRM_CONNECTOR_MAX_PROPERTY) { - goto out; - } - - obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY); - if (!obj) { - goto out; - } - property = obj_to_property(obj); - - if (property->flags & DRM_MODE_PROP_IMMUTABLE) - goto out; - - if (property->flags & DRM_MODE_PROP_RANGE) { - if (out_resp->value < property->values[0]) - goto out; - - if (out_resp->value > property->values[1]) - goto out; - } else { - int found = 0; - for (i = 0; i < property->num_values; i++) { - if (property->values[i] == out_resp->value) { - found = 1; - break; - } - } - if (!found) { - goto out; - } - } - - /* Do DPMS ourselves */ - if (property == connector->dev->mode_config.dpms_property) { - if (connector->funcs->dpms) - (*connector->funcs->dpms)(connector, (int) out_resp->value); - ret = 0; - } else if (connector->funcs->set_property) - ret = connector->funcs->set_property(connector, property, out_resp->value); - - /* store the property value if successful */ - if (!ret) - drm_connector_property_set_value(connector, property, out_resp->value); -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int drm_mode_connector_attach_encoder(struct drm_connector *connector, - struct drm_encoder *encoder) -{ - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) { - connector->encoder_ids[i] = encoder->base.id; - return 0; - } - } - return -ENOMEM; -} -EXPORT_SYMBOL(drm_mode_connector_attach_encoder); - -void drm_mode_connector_detach_encoder(struct drm_connector *connector, - struct drm_encoder *encoder) -{ - int i; - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == encoder->base.id) { - connector->encoder_ids[i] = 0; - if (connector->encoder == encoder) - connector->encoder = NULL; - break; - } - } -} -EXPORT_SYMBOL(drm_mode_connector_detach_encoder); - -int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, - int gamma_size) -{ - crtc->gamma_size = gamma_size; - - crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); - if (!crtc->gamma_store) { - crtc->gamma_size = 0; - return -ENOMEM; - } - - return 0; -} -EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); - -int drm_mode_gamma_set_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_crtc_lut *crtc_lut = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - void *r_base, *g_base, *b_base; - int size; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - ret = -EINVAL; - goto out; - } - crtc = obj_to_crtc(obj); - - /* memcpy into gamma store */ - if (crtc_lut->gamma_size != crtc->gamma_size) { - ret = -EINVAL; - goto out; - } - - size = crtc_lut->gamma_size * (sizeof(uint16_t)); - r_base = crtc->gamma_store; - if (copy_from_user(r_base, (void __user *)(unsigned long)crtc_lut->red, size)) { - ret = -EFAULT; - goto out; - } - - g_base = r_base + size; - if (copy_from_user(g_base, (void __user *)(unsigned long)crtc_lut->green, size)) { - ret = -EFAULT; - goto out; - } - - b_base = g_base + size; - if (copy_from_user(b_base, (void __user *)(unsigned long)crtc_lut->blue, size)) { - ret = -EFAULT; - goto out; - } - - crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; - -} - -int drm_mode_gamma_get_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_crtc_lut *crtc_lut = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - void *r_base, *g_base, *b_base; - int size; - int ret = 0; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - ret = -EINVAL; - goto out; - } - crtc = obj_to_crtc(obj); - - /* memcpy into gamma store */ - if (crtc_lut->gamma_size != crtc->gamma_size) { - ret = -EINVAL; - goto out; - } - - size = crtc_lut->gamma_size * (sizeof(uint16_t)); - r_base = crtc->gamma_store; - if (copy_to_user((void __user *)(unsigned long)crtc_lut->red, r_base, size)) { - ret = -EFAULT; - goto out; - } - - g_base = r_base + size; - if (copy_to_user((void __user *)(unsigned long)crtc_lut->green, g_base, size)) { - ret = -EFAULT; - goto out; - } - - b_base = g_base + size; - if (copy_to_user((void __user *)(unsigned long)crtc_lut->blue, b_base, size)) { - ret = -EFAULT; - goto out; - } -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int drm_mode_page_flip_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_crtc_page_flip *page_flip = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct drm_framebuffer *fb; - struct drm_pending_vblank_event *e = NULL; - unsigned long flags; - int ret = -EINVAL; - - if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || - page_flip->reserved != 0) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) - goto out; - crtc = obj_to_crtc(obj); - - if (crtc->fb == NULL) { - /* The framebuffer is currently unbound, presumably - * due to a hotplug event, that userspace has not - * yet discovered. - */ - ret = -EBUSY; - goto out; - } - - if (crtc->funcs->page_flip == NULL) - goto out; - - obj = drm_mode_object_find(dev, page_flip->fb_id, DRM_MODE_OBJECT_FB); - if (!obj) - goto out; - fb = obj_to_fb(obj); - - if (crtc->mode.hdisplay > fb->width || - crtc->mode.vdisplay > fb->height || - crtc->x > fb->width - crtc->mode.hdisplay || - crtc->y > fb->height - crtc->mode.vdisplay) { - DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d.\n", - fb->width, fb->height, - crtc->mode.hdisplay, crtc->mode.vdisplay, - crtc->x, crtc->y); - ret = -ENOSPC; - goto out; - } - - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - ret = -ENOMEM; - spin_lock_irqsave(&dev->event_lock, flags); - if (file_priv->event_space < sizeof e->event) { - spin_unlock_irqrestore(&dev->event_lock, flags); - goto out; - } - file_priv->event_space -= sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - - e = kzalloc(sizeof *e, GFP_KERNEL); - if (e == NULL) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - goto out; - } - - e->event.base.type = DRM_EVENT_FLIP_COMPLETE; - e->event.base.length = sizeof e->event; - e->event.user_data = page_flip->user_data; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = - (void (*) (struct drm_pending_event *)) kfree; - } - - ret = crtc->funcs->page_flip(crtc, fb, e); - if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); - } - } - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -void drm_mode_config_reset(struct drm_device *dev) -{ - struct drm_crtc *crtc; - struct drm_encoder *encoder; - struct drm_connector *connector; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - if (crtc->funcs->reset) - crtc->funcs->reset(crtc); - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->funcs->reset) - encoder->funcs->reset(encoder); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->funcs->reset) - connector->funcs->reset(connector); -} -EXPORT_SYMBOL(drm_mode_config_reset); - -int drm_mode_create_dumb_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_create_dumb *args = data; - - if (!dev->driver->dumb_create) - return -ENOSYS; - return dev->driver->dumb_create(file_priv, dev, args); -} - -int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_map_dumb *args = data; - - /* call driver ioctl to get mmap offset */ - if (!dev->driver->dumb_map_offset) - return -ENOSYS; - - return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset); -} - -int drm_mode_destroy_dumb_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_destroy_dumb *args = data; - - if (!dev->driver->dumb_destroy) - return -ENOSYS; - - return dev->driver->dumb_destroy(file_priv, dev, args->handle); -} - -/* - * Just need to support RGB formats here for compat with code that doesn't - * use pixel formats directly yet. - */ -void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, - int *bpp) -{ - switch (format) { - case DRM_FORMAT_RGB332: - case DRM_FORMAT_BGR233: - *depth = 8; - *bpp = 8; - break; - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XBGR1555: - case DRM_FORMAT_RGBX5551: - case DRM_FORMAT_BGRX5551: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ABGR1555: - case DRM_FORMAT_RGBA5551: - case DRM_FORMAT_BGRA5551: - *depth = 15; - *bpp = 16; - break; - case DRM_FORMAT_RGB565: - case DRM_FORMAT_BGR565: - *depth = 16; - *bpp = 16; - break; - case DRM_FORMAT_RGB888: - case DRM_FORMAT_BGR888: - *depth = 24; - *bpp = 24; - break; - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_RGBX8888: - case DRM_FORMAT_BGRX8888: - *depth = 24; - *bpp = 32; - break; - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_RGBA1010102: - case DRM_FORMAT_BGRA1010102: - *depth = 30; - *bpp = 32; - break; - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_RGBA8888: - case DRM_FORMAT_BGRA8888: - *depth = 32; - *bpp = 32; - break; - default: - DRM_DEBUG_KMS("unsupported pixel format\n"); - *depth = 0; - *bpp = 0; - break; - } -} -EXPORT_SYMBOL(drm_fb_get_bpp_depth); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_crtc_helper.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_crtc_helper.c deleted file mode 100644 index 81118893..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_crtc_helper.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - * Copyright (c) 2006-2008 Intel Corporation - * Copyright (c) 2007 Dave Airlie - * - * DRM core CRTC related functions - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - * - * Authors: - * Keith Packard - * Eric Anholt - * Dave Airlie - * Jesse Barnes - */ - -#include -#include - -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_fourcc.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" -#include "drm_edid.h" - -static bool drm_kms_helper_poll = true; -module_param_named(poll, drm_kms_helper_poll, bool, 0600); - -static void drm_mode_validate_flag(struct drm_connector *connector, - int flags) -{ - struct drm_display_mode *mode; - - if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) - return; - - list_for_each_entry(mode, &connector->modes, head) { - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && - !(flags & DRM_MODE_FLAG_INTERLACE)) - mode->status = MODE_NO_INTERLACE; - if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) && - !(flags & DRM_MODE_FLAG_DBLSCAN)) - mode->status = MODE_NO_DBLESCAN; - } - - return; -} - -/** - * drm_helper_probe_single_connector_modes - get complete set of display modes - * @dev: DRM device - * @maxX: max width for modes - * @maxY: max height for modes - * - * LOCKING: - * Caller must hold mode config lock. - * - * Based on @dev's mode_config layout, scan all the connectors and try to detect - * modes on them. Modes will first be added to the connector's probed_modes - * list, then culled (based on validity and the @maxX, @maxY parameters) and - * put into the normal modes list. - * - * Intended to be used either at bootup time or when major configuration - * changes have occurred. - * - * FIXME: take into account monitor limits - * - * RETURNS: - * Number of modes found on @connector. - */ -int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY) -{ - struct drm_device *dev = connector->dev; - struct drm_display_mode *mode; - struct drm_connector_helper_funcs *connector_funcs = - connector->helper_private; - int count = 0; - int mode_flags = 0; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, - drm_get_connector_name(connector)); - /* set all modes to the unverified state */ - list_for_each_entry(mode, &connector->modes, head) - mode->status = MODE_UNVERIFIED; - - if (connector->force) { - if (connector->force == DRM_FORCE_ON) - connector->status = connector_status_connected; - else - connector->status = connector_status_disconnected; - if (connector->funcs->force) - connector->funcs->force(connector); - } else { - connector->status = connector->funcs->detect(connector, true); - drm_kms_helper_poll_enable(dev); - } - - if (connector->status == connector_status_disconnected) { - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", - connector->base.id, drm_get_connector_name(connector)); - drm_mode_connector_update_edid_property(connector, NULL); - goto prune; - } - -#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE - count = drm_load_edid_firmware(connector); - if (count == 0) -#endif - count = (*connector_funcs->get_modes)(connector); - - if (count == 0 && connector->status == connector_status_connected) - count = drm_add_modes_noedid(connector, 1024, 768); - if (count == 0) - goto prune; - - drm_mode_connector_list_update(connector); - - if (maxX && maxY) - drm_mode_validate_size(dev, &connector->modes, maxX, - maxY, 0); - - if (connector->interlace_allowed) - mode_flags |= DRM_MODE_FLAG_INTERLACE; - if (connector->doublescan_allowed) - mode_flags |= DRM_MODE_FLAG_DBLSCAN; - drm_mode_validate_flag(connector, mode_flags); - - list_for_each_entry(mode, &connector->modes, head) { - if (mode->status == MODE_OK) - mode->status = connector_funcs->mode_valid(connector, - mode); - } - -prune: - drm_mode_prune_invalid(dev, &connector->modes, true); - - if (list_empty(&connector->modes)) - return 0; - - drm_mode_sort(&connector->modes); - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, - drm_get_connector_name(connector)); - list_for_each_entry(mode, &connector->modes, head) { - mode->vrefresh = drm_mode_vrefresh(mode); - - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - drm_mode_debug_printmodeline(mode); - } - - return count; -} -EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); - -/** - * drm_helper_encoder_in_use - check if a given encoder is in use - * @encoder: encoder to check - * - * LOCKING: - * Caller must hold mode config lock. - * - * Walk @encoders's DRM device's mode_config and see if it's in use. - * - * RETURNS: - * True if @encoder is part of the mode_config, false otherwise. - */ -bool drm_helper_encoder_in_use(struct drm_encoder *encoder) -{ - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder) - return true; - return false; -} -EXPORT_SYMBOL(drm_helper_encoder_in_use); - -/** - * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config - * @crtc: CRTC to check - * - * LOCKING: - * Caller must hold mode config lock. - * - * Walk @crtc's DRM device's mode_config and see if it's in use. - * - * RETURNS: - * True if @crtc is part of the mode_config, false otherwise. - */ -bool drm_helper_crtc_in_use(struct drm_crtc *crtc) -{ - struct drm_encoder *encoder; - struct drm_device *dev = crtc->dev; - /* FIXME: Locking around list access? */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) - return true; - return false; -} -EXPORT_SYMBOL(drm_helper_crtc_in_use); - -static void -drm_encoder_disable(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - - if (encoder_funcs->disable) - (*encoder_funcs->disable)(encoder); - else - (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); -} - -/** - * drm_helper_disable_unused_functions - disable unused objects - * @dev: DRM device - * - * LOCKING: - * Caller must hold mode config lock. - * - * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled - * by calling its dpms function, which should power it off. - */ -void drm_helper_disable_unused_functions(struct drm_device *dev) -{ - struct drm_encoder *encoder; - struct drm_connector *connector; - struct drm_crtc *crtc; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (!connector->encoder) - continue; - if (connector->status == connector_status_disconnected) - connector->encoder = NULL; - } - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (!drm_helper_encoder_in_use(encoder)) { - drm_encoder_disable(encoder); - /* disconnector encoder from any connector */ - encoder->crtc = NULL; - } - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc->enabled = drm_helper_crtc_in_use(crtc); - if (!crtc->enabled) { - if (crtc_funcs->disable) - (*crtc_funcs->disable)(crtc); - else - (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF); - crtc->fb = NULL; - } - } -} -EXPORT_SYMBOL(drm_helper_disable_unused_functions); - -/** - * drm_encoder_crtc_ok - can a given crtc drive a given encoder? - * @encoder: encoder to test - * @crtc: crtc to test - * - * Return false if @encoder can't be driven by @crtc, true otherwise. - */ -static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, - struct drm_crtc *crtc) -{ - struct drm_device *dev; - struct drm_crtc *tmp; - int crtc_mask = 1; - - WARN(!crtc, "checking null crtc?\n"); - - dev = crtc->dev; - - list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { - if (tmp == crtc) - break; - crtc_mask <<= 1; - } - - if (encoder->possible_crtcs & crtc_mask) - return true; - return false; -} - -/* - * Check the CRTC we're going to map each output to vs. its current - * CRTC. If they don't match, we have to disable the output and the CRTC - * since the driver will have to re-route things. - */ -static void -drm_crtc_prepare_encoders(struct drm_device *dev) -{ - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_encoder *encoder; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - encoder_funcs = encoder->helper_private; - /* Disable unused encoders */ - if (encoder->crtc == NULL) - drm_encoder_disable(encoder); - /* Disable encoders whose CRTC is about to change */ - if (encoder_funcs->get_crtc && - encoder->crtc != (*encoder_funcs->get_crtc)(encoder)) - drm_encoder_disable(encoder); - } -} - -/** - * drm_crtc_set_mode - set a mode - * @crtc: CRTC to program - * @mode: mode to use - * @x: width of mode - * @y: height of mode - * - * LOCKING: - * Caller must hold mode config lock. - * - * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance - * to fixup or reject the mode prior to trying to set it. - * - * RETURNS: - * True if the mode was set successfully, or false otherwise. - */ -bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, - struct drm_display_mode *mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - struct drm_encoder_helper_funcs *encoder_funcs; - int saved_x, saved_y; - struct drm_encoder *encoder; - bool ret = true; - - crtc->enabled = drm_helper_crtc_in_use(crtc); - if (!crtc->enabled) - return true; - - adjusted_mode = drm_mode_duplicate(dev, mode); - if (!adjusted_mode) - return false; - - saved_hwmode = crtc->hwmode; - saved_mode = crtc->mode; - saved_x = crtc->x; - saved_y = crtc->y; - - /* Update crtc values up front so the driver can rely on them for mode - * setting. - */ - crtc->mode = *mode; - crtc->x = x; - crtc->y = y; - - /* Pass our mode to the connectors and the CRTC to give them a chance to - * adjust it according to limitations or connector properties, and also - * a chance to reject the mode entirely. - */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - - if (encoder->crtc != crtc) - continue; - encoder_funcs = encoder->helper_private; - if (!(ret = encoder_funcs->mode_fixup(encoder, mode, - adjusted_mode))) { - DRM_DEBUG_KMS("Encoder fixup failed\n"); - goto done; - } - } - - if (!(ret = crtc_funcs->mode_fixup(crtc, mode, adjusted_mode))) { - DRM_DEBUG_KMS("CRTC fixup failed\n"); - goto done; - } - DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); - - /* Prepare the encoders and CRTCs before setting the mode. */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - - if (encoder->crtc != crtc) - continue; - encoder_funcs = encoder->helper_private; - /* Disable the encoders as the first thing we do. */ - encoder_funcs->prepare(encoder); - } - - drm_crtc_prepare_encoders(dev); - - crtc_funcs->prepare(crtc); - - /* Set up the DPLL and any encoders state that needs to adjust or depend - * on the DPLL. - */ - ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb); - if (!ret) - goto done; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - - if (encoder->crtc != crtc) - continue; - - DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", - encoder->base.id, drm_get_encoder_name(encoder), - mode->base.id, mode->name); - encoder_funcs = encoder->helper_private; - encoder_funcs->mode_set(encoder, mode, adjusted_mode); - } - - /* Now enable the clocks, plane, pipe, and connectors that we set up. */ - crtc_funcs->commit(crtc); - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - - if (encoder->crtc != crtc) - continue; - - encoder_funcs = encoder->helper_private; - encoder_funcs->commit(encoder); - - } - - /* Store real post-adjustment hardware mode. */ - crtc->hwmode = *adjusted_mode; - - /* Calculate and store various constants which - * are later needed by vblank and swap-completion - * timestamping. They are derived from true hwmode. - */ - drm_calc_timestamping_constants(crtc); - - /* FIXME: add subpixel order */ -done: - drm_mode_destroy(dev, adjusted_mode); - if (!ret) { - crtc->hwmode = saved_hwmode; - crtc->mode = saved_mode; - crtc->x = saved_x; - crtc->y = saved_y; - } - - return ret; -} -EXPORT_SYMBOL(drm_crtc_helper_set_mode); - - -static int -drm_crtc_helper_disable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_connector *connector; - struct drm_encoder *encoder; - - /* Decouple all encoders and their attached connectors from this crtc */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc != crtc) - continue; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder != encoder) - continue; - - connector->encoder = NULL; - } - } - - drm_helper_disable_unused_functions(dev); - return 0; -} - -/** - * drm_crtc_helper_set_config - set a new config from userspace - * @crtc: CRTC to setup - * @crtc_info: user provided configuration - * @new_mode: new mode to set - * @connector_set: set of connectors for the new config - * @fb: new framebuffer - * - * LOCKING: - * Caller must hold mode config lock. - * - * Setup a new configuration, provided by the user in @crtc_info, and enable - * it. - * - * RETURNS: - * Zero. (FIXME) - */ -int drm_crtc_helper_set_config(struct drm_mode_set *set) -{ - struct drm_device *dev; - struct drm_crtc *save_crtcs, *new_crtc, *crtc; - struct drm_encoder *save_encoders, *new_encoder, *encoder; - struct drm_framebuffer *old_fb = NULL; - bool mode_changed = false; /* if true do a full mode set */ - bool fb_changed = false; /* if true and !mode_changed just do a flip */ - struct drm_connector *save_connectors, *connector; - int count = 0, ro, fail = 0; - struct drm_crtc_helper_funcs *crtc_funcs; - struct drm_mode_set save_set; - int ret = 0; - int i; - - DRM_DEBUG_KMS("\n"); - - if (!set) - return -EINVAL; - - if (!set->crtc) - return -EINVAL; - - if (!set->crtc->helper_private) - return -EINVAL; - - crtc_funcs = set->crtc->helper_private; - - if (!set->mode) - set->fb = NULL; - - if (set->fb) { - DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", - set->crtc->base.id, set->fb->base.id, - (int)set->num_connectors, set->x, set->y); - } else { - DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); - return drm_crtc_helper_disable(set->crtc); - } - - dev = set->crtc->dev; - - /* Allocate space for the backup of all (non-pointer) crtc, encoder and - * connector data. */ - save_crtcs = kzalloc(dev->mode_config.num_crtc * - sizeof(struct drm_crtc), GFP_KERNEL); - if (!save_crtcs) - return -ENOMEM; - - save_encoders = kzalloc(dev->mode_config.num_encoder * - sizeof(struct drm_encoder), GFP_KERNEL); - if (!save_encoders) { - kfree(save_crtcs); - return -ENOMEM; - } - - save_connectors = kzalloc(dev->mode_config.num_connector * - sizeof(struct drm_connector), GFP_KERNEL); - if (!save_connectors) { - kfree(save_crtcs); - kfree(save_encoders); - return -ENOMEM; - } - - /* Copy data. Note that driver private data is not affected. - * Should anything bad happen only the expected state is - * restored, not the drivers personal bookkeeping. - */ - count = 0; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - save_crtcs[count++] = *crtc; - } - - count = 0; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - save_encoders[count++] = *encoder; - } - - count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - save_connectors[count++] = *connector; - } - - save_set.crtc = set->crtc; - save_set.mode = &set->crtc->mode; - save_set.x = set->crtc->x; - save_set.y = set->crtc->y; - save_set.fb = set->crtc->fb; - - /* We should be able to check here if the fb has the same properties - * and then just flip_or_move it */ - if (set->crtc->fb != set->fb) { - /* If we have no fb then treat it as a full mode set */ - if (set->crtc->fb == NULL) { - DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); - mode_changed = true; - } else if (set->fb == NULL) { - mode_changed = true; - } else if (set->fb->depth != set->crtc->fb->depth) { - mode_changed = true; - } else if (set->fb->bits_per_pixel != - set->crtc->fb->bits_per_pixel) { - mode_changed = true; - } else - fb_changed = true; - } - - if (set->x != set->crtc->x || set->y != set->crtc->y) - fb_changed = true; - - if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { - DRM_DEBUG_KMS("modes are different, full mode set\n"); - drm_mode_debug_printmodeline(&set->crtc->mode); - drm_mode_debug_printmodeline(set->mode); - mode_changed = true; - } - - /* a) traverse passed in connector list and get encoders for them */ - count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct drm_connector_helper_funcs *connector_funcs = - connector->helper_private; - new_encoder = connector->encoder; - for (ro = 0; ro < set->num_connectors; ro++) { - if (set->connectors[ro] == connector) { - new_encoder = connector_funcs->best_encoder(connector); - /* if we can't get an encoder for a connector - we are setting now - then fail */ - if (new_encoder == NULL) - /* don't break so fail path works correct */ - fail = 1; - break; - } - } - - if (new_encoder != connector->encoder) { - DRM_DEBUG_KMS("encoder changed, full mode switch\n"); - mode_changed = true; - /* If the encoder is reused for another connector, then - * the appropriate crtc will be set later. - */ - if (connector->encoder) - connector->encoder->crtc = NULL; - connector->encoder = new_encoder; - } - } - - if (fail) { - ret = -EINVAL; - goto fail; - } - - count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (!connector->encoder) - continue; - - if (connector->encoder->crtc == set->crtc) - new_crtc = NULL; - else - new_crtc = connector->encoder->crtc; - - for (ro = 0; ro < set->num_connectors; ro++) { - if (set->connectors[ro] == connector) - new_crtc = set->crtc; - } - - /* Make sure the new CRTC will work with the encoder */ - if (new_crtc && - !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { - ret = -EINVAL; - goto fail; - } - if (new_crtc != connector->encoder->crtc) { - DRM_DEBUG_KMS("crtc changed, full mode switch\n"); - mode_changed = true; - connector->encoder->crtc = new_crtc; - } - if (new_crtc) { - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", - connector->base.id, drm_get_connector_name(connector), - new_crtc->base.id); - } else { - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", - connector->base.id, drm_get_connector_name(connector)); - } - } - - /* mode_set_base is not a required function */ - if (fb_changed && !crtc_funcs->mode_set_base) - mode_changed = true; - - if (mode_changed) { - set->crtc->enabled = drm_helper_crtc_in_use(set->crtc); - if (set->crtc->enabled) { - DRM_DEBUG_KMS("attempting to set mode from" - " userspace\n"); - drm_mode_debug_printmodeline(set->mode); - old_fb = set->crtc->fb; - set->crtc->fb = set->fb; - if (!drm_crtc_helper_set_mode(set->crtc, set->mode, - set->x, set->y, - old_fb)) { - DRM_ERROR("failed to set mode on [CRTC:%d]\n", - set->crtc->base.id); - set->crtc->fb = old_fb; - ret = -EINVAL; - goto fail; - } - DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); - for (i = 0; i < set->num_connectors; i++) { - DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, - drm_get_connector_name(set->connectors[i])); - set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON); - } - } - drm_helper_disable_unused_functions(dev); - } else if (fb_changed) { - set->crtc->x = set->x; - set->crtc->y = set->y; - - old_fb = set->crtc->fb; - if (set->crtc->fb != set->fb) - set->crtc->fb = set->fb; - ret = crtc_funcs->mode_set_base(set->crtc, - set->x, set->y, old_fb); - if (ret != 0) { - set->crtc->fb = old_fb; - goto fail; - } - } - - kfree(save_connectors); - kfree(save_encoders); - kfree(save_crtcs); - return 0; - -fail: - /* Restore all previous data. */ - count = 0; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - *crtc = save_crtcs[count++]; - } - - count = 0; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - *encoder = save_encoders[count++]; - } - - count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - *connector = save_connectors[count++]; - } - - /* Try to restore the config */ - if (mode_changed && - !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, - save_set.y, save_set.fb)) - DRM_ERROR("failed to restore config after modeset failure\n"); - - kfree(save_connectors); - kfree(save_encoders); - kfree(save_crtcs); - return ret; -} -EXPORT_SYMBOL(drm_crtc_helper_set_config); - -static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) -{ - int dpms = DRM_MODE_DPMS_OFF; - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder) - if (connector->dpms < dpms) - dpms = connector->dpms; - return dpms; -} - -static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) -{ - int dpms = DRM_MODE_DPMS_OFF; - struct drm_connector *connector; - struct drm_device *dev = crtc->dev; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder && connector->encoder->crtc == crtc) - if (connector->dpms < dpms) - dpms = connector->dpms; - return dpms; -} - -/** - * drm_helper_connector_dpms - * @connector affected connector - * @mode DPMS mode - * - * Calls the low-level connector DPMS function, then - * calls appropriate encoder and crtc DPMS functions as well - */ -void drm_helper_connector_dpms(struct drm_connector *connector, int mode) -{ - struct drm_encoder *encoder = connector->encoder; - struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; - int old_dpms; - - if (mode == connector->dpms) - return; - - old_dpms = connector->dpms; - connector->dpms = mode; - - /* from off to on, do crtc then encoder */ - if (mode < old_dpms) { - if (crtc) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - if (crtc_funcs->dpms) - (*crtc_funcs->dpms) (crtc, - drm_helper_choose_crtc_dpms(crtc)); - } - if (encoder) { - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - if (encoder_funcs->dpms) - (*encoder_funcs->dpms) (encoder, - drm_helper_choose_encoder_dpms(encoder)); - } - } - - /* from on to off, do encoder then crtc */ - if (mode > old_dpms) { - if (encoder) { - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - if (encoder_funcs->dpms) - (*encoder_funcs->dpms) (encoder, - drm_helper_choose_encoder_dpms(encoder)); - } - if (crtc) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - if (crtc_funcs->dpms) - (*crtc_funcs->dpms) (crtc, - drm_helper_choose_crtc_dpms(crtc)); - } - } - - return; -} -EXPORT_SYMBOL(drm_helper_connector_dpms); - -int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - int i; - - fb->width = mode_cmd->width; - fb->height = mode_cmd->height; - for (i = 0; i < 4; i++) { - fb->pitches[i] = mode_cmd->pitches[i]; - fb->offsets[i] = mode_cmd->offsets[i]; - } - drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth, - &fb->bits_per_pixel); - fb->pixel_format = mode_cmd->pixel_format; - - return 0; -} -EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct); - -int drm_helper_resume_force_mode(struct drm_device *dev) -{ - struct drm_crtc *crtc; - struct drm_encoder *encoder; - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_crtc_helper_funcs *crtc_funcs; - int ret; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - - if (!crtc->enabled) - continue; - - ret = drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); - - if (ret == false) - DRM_ERROR("failed to set mode on crtc %p\n", crtc); - - /* Turn off outputs that were already powered off */ - if (drm_helper_choose_crtc_dpms(crtc)) { - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - - if(encoder->crtc != crtc) - continue; - - encoder_funcs = encoder->helper_private; - if (encoder_funcs->dpms) - (*encoder_funcs->dpms) (encoder, - drm_helper_choose_encoder_dpms(encoder)); - } - - crtc_funcs = crtc->helper_private; - if (crtc_funcs->dpms) - (*crtc_funcs->dpms) (crtc, - drm_helper_choose_crtc_dpms(crtc)); - } - } - /* disable the unused connectors while restoring the modesetting */ - drm_helper_disable_unused_functions(dev); - return 0; -} -EXPORT_SYMBOL(drm_helper_resume_force_mode); - -#define DRM_OUTPUT_POLL_PERIOD (10*HZ) -static void output_poll_execute(struct work_struct *work) -{ - struct delayed_work *delayed_work = to_delayed_work(work); - struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); - struct drm_connector *connector; - enum drm_connector_status old_status; - bool repoll = false, changed = false; - - if (!drm_kms_helper_poll) - return; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - - /* if this is HPD or polled don't check it - - TV out for instance */ - if (!connector->polled) - continue; - - else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) - repoll = true; - - old_status = connector->status; - /* if we are connected and don't want to poll for disconnect - skip it */ - if (old_status == connector_status_connected && - !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT) && - !(connector->polled & DRM_CONNECTOR_POLL_HPD)) - continue; - - connector->status = connector->funcs->detect(connector, false); - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", - connector->base.id, - drm_get_connector_name(connector), - old_status, connector->status); - if (old_status != connector->status) - changed = true; - } - - mutex_unlock(&dev->mode_config.mutex); - - if (changed) { - /* send a uevent + call fbdev */ - drm_sysfs_hotplug_event(dev); - if (dev->mode_config.funcs->output_poll_changed) - dev->mode_config.funcs->output_poll_changed(dev); - } - - if (repoll) - queue_delayed_work(system_nrt_wq, delayed_work, DRM_OUTPUT_POLL_PERIOD); -} - -void drm_kms_helper_poll_disable(struct drm_device *dev) -{ - if (!dev->mode_config.poll_enabled) - return; - cancel_delayed_work_sync(&dev->mode_config.output_poll_work); -} -EXPORT_SYMBOL(drm_kms_helper_poll_disable); - -void drm_kms_helper_poll_enable(struct drm_device *dev) -{ - bool poll = false; - struct drm_connector *connector; - - if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) - return; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->polled) - poll = true; - } - - if (poll) - queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD); -} -EXPORT_SYMBOL(drm_kms_helper_poll_enable); - -void drm_kms_helper_poll_init(struct drm_device *dev) -{ - INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute); - dev->mode_config.poll_enabled = true; - - drm_kms_helper_poll_enable(dev); -} -EXPORT_SYMBOL(drm_kms_helper_poll_init); - -void drm_kms_helper_poll_fini(struct drm_device *dev) -{ - drm_kms_helper_poll_disable(dev); -} -EXPORT_SYMBOL(drm_kms_helper_poll_fini); - -void drm_helper_hpd_irq_event(struct drm_device *dev) -{ - if (!dev->mode_config.poll_enabled) - return; - - /* kill timer and schedule immediate execution, this doesn't block */ - cancel_delayed_work(&dev->mode_config.output_poll_work); - if (drm_kms_helper_poll) - queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); -} -EXPORT_SYMBOL(drm_helper_hpd_irq_event); - - -/** - * drm_format_num_planes - get the number of planes for format - * @format: pixel format (DRM_FORMAT_*) - * - * RETURNS: - * The number of planes used by the specified pixel format. - */ -int drm_format_num_planes(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_YUV410: - case DRM_FORMAT_YVU410: - case DRM_FORMAT_YUV411: - case DRM_FORMAT_YVU411: - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - case DRM_FORMAT_YUV422: - case DRM_FORMAT_YVU422: - case DRM_FORMAT_YUV444: - case DRM_FORMAT_YVU444: - return 3; - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: - case DRM_FORMAT_NV16: - case DRM_FORMAT_NV61: - return 2; - default: - return 1; - } -} -EXPORT_SYMBOL(drm_format_num_planes); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_debugfs.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_debugfs.c deleted file mode 100644 index 1c7a1c0d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_debugfs.c +++ /dev/null @@ -1,242 +0,0 @@ -/** - * \file drm_debugfs.c - * debugfs support for DRM - * - * \author Ben Gamari - */ - -/* - * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com - * - * Copyright 2008 Ben Gamari - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include "drmP.h" - -#if defined(CONFIG_DEBUG_FS) - -/*************************************************** - * Initialization, etc. - **************************************************/ - -static struct drm_info_list drm_debugfs_list[] = { - {"name", drm_name_info, 0}, - {"vm", drm_vm_info, 0}, - {"clients", drm_clients_info, 0}, - {"queues", drm_queues_info, 0}, - {"bufs", drm_bufs_info, 0}, - {"gem_names", drm_gem_name_info, DRIVER_GEM}, -#if DRM_DEBUG_CODE - {"vma", drm_vma_info, 0}, -#endif -}; -#define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list) - - -static int drm_debugfs_open(struct inode *inode, struct file *file) -{ - struct drm_info_node *node = inode->i_private; - - return single_open(file, node->info_ent->show, node); -} - - -static const struct file_operations drm_debugfs_fops = { - .owner = THIS_MODULE, - .open = drm_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - - -/** - * Initialize a given set of debugfs files for a device - * - * \param files The array of files to create - * \param count The number of files given - * \param root DRI debugfs dir entry. - * \param minor device minor number - * \return Zero on success, non-zero on failure - * - * Create a given set of debugfs files represented by an array of - * gdm_debugfs_lists in the given root directory. - */ -int drm_debugfs_create_files(struct drm_info_list *files, int count, - struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - struct drm_info_node *tmp; - int i, ret; - - for (i = 0; i < count; i++) { - u32 features = files[i].driver_features; - - if (features != 0 && - (dev->driver->driver_features & features) != features) - continue; - - tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); - if (tmp == NULL) { - ret = -1; - goto fail; - } - ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, - root, tmp, &drm_debugfs_fops); - if (!ent) { - DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n", - root->d_name.name, files[i].name); - kfree(tmp); - ret = -1; - goto fail; - } - - tmp->minor = minor; - tmp->dent = ent; - tmp->info_ent = &files[i]; - - mutex_lock(&minor->debugfs_lock); - list_add(&tmp->list, &minor->debugfs_list); - mutex_unlock(&minor->debugfs_lock); - } - return 0; - -fail: - drm_debugfs_remove_files(files, count, minor); - return ret; -} -EXPORT_SYMBOL(drm_debugfs_create_files); - -/** - * Initialize the DRI debugfs filesystem for a device - * - * \param dev DRM device - * \param minor device minor number - * \param root DRI debugfs dir entry. - * - * Create the DRI debugfs root entry "/sys/kernel/debug/dri", the device debugfs root entry - * "/sys/kernel/debug/dri/%minor%/", and each entry in debugfs_list as - * "/sys/kernel/debug/dri/%minor%/%name%". - */ -int drm_debugfs_init(struct drm_minor *minor, int minor_id, - struct dentry *root) -{ - struct drm_device *dev = minor->dev; - char name[64]; - int ret; - - INIT_LIST_HEAD(&minor->debugfs_list); - mutex_init(&minor->debugfs_lock); - sprintf(name, "%d", minor_id); - minor->debugfs_root = debugfs_create_dir(name, root); - if (!minor->debugfs_root) { - DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s\n", name); - return -1; - } - - ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, - minor->debugfs_root, minor); - if (ret) { - debugfs_remove(minor->debugfs_root); - minor->debugfs_root = NULL; - DRM_ERROR("Failed to create core drm debugfs files\n"); - return ret; - } - - if (dev->driver->debugfs_init) { - ret = dev->driver->debugfs_init(minor); - if (ret) { - DRM_ERROR("DRM: Driver failed to initialize " - "/sys/kernel/debug/dri.\n"); - return ret; - } - } - return 0; -} - - -/** - * Remove a list of debugfs files - * - * \param files The list of files - * \param count The number of files - * \param minor The minor of which we should remove the files - * \return always zero. - * - * Remove all debugfs entries created by debugfs_init(). - */ -int drm_debugfs_remove_files(struct drm_info_list *files, int count, - struct drm_minor *minor) -{ - struct list_head *pos, *q; - struct drm_info_node *tmp; - int i; - - mutex_lock(&minor->debugfs_lock); - for (i = 0; i < count; i++) { - list_for_each_safe(pos, q, &minor->debugfs_list) { - tmp = list_entry(pos, struct drm_info_node, list); - if (tmp->info_ent == &files[i]) { - debugfs_remove(tmp->dent); - list_del(pos); - kfree(tmp); - } - } - } - mutex_unlock(&minor->debugfs_lock); - return 0; -} -EXPORT_SYMBOL(drm_debugfs_remove_files); - -/** - * Cleanup the debugfs filesystem resources. - * - * \param minor device minor number. - * \return always zero. - * - * Remove all debugfs entries created by debugfs_init(). - */ -int drm_debugfs_cleanup(struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - - if (!minor->debugfs_root) - return 0; - - if (dev->driver->debugfs_cleanup) - dev->driver->debugfs_cleanup(minor); - - drm_debugfs_remove_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, minor); - - debugfs_remove(minor->debugfs_root); - minor->debugfs_root = NULL; - - return 0; -} - -#endif /* CONFIG_DEBUG_FS */ - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_dma.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_dma.c deleted file mode 100644 index cfb4e333..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_dma.c +++ /dev/null @@ -1,162 +0,0 @@ -/** - * \file drm_dma.c - * DMA IOCTL and function support - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -/** - * Initialize the DMA data. - * - * \param dev DRM device. - * \return zero on success or a negative value on failure. - * - * Allocate and initialize a drm_device_dma structure. - */ -int drm_dma_setup(struct drm_device *dev) -{ - int i; - - dev->dma = kzalloc(sizeof(*dev->dma), GFP_KERNEL); - if (!dev->dma) - return -ENOMEM; - - for (i = 0; i <= DRM_MAX_ORDER; i++) - memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0])); - - return 0; -} - -/** - * Cleanup the DMA resources. - * - * \param dev DRM device. - * - * Free all pages associated with DMA buffers, the buffers and pages lists, and - * finally the drm_device::dma structure itself. - */ -void drm_dma_takedown(struct drm_device *dev) -{ - struct drm_device_dma *dma = dev->dma; - int i, j; - - if (!dma) - return; - - /* Clear dma buffers */ - for (i = 0; i <= DRM_MAX_ORDER; i++) { - if (dma->bufs[i].seg_count) { - DRM_DEBUG("order %d: buf_count = %d," - " seg_count = %d\n", - i, - dma->bufs[i].buf_count, - dma->bufs[i].seg_count); - for (j = 0; j < dma->bufs[i].seg_count; j++) { - if (dma->bufs[i].seglist[j]) { - drm_pci_free(dev, dma->bufs[i].seglist[j]); - } - } - kfree(dma->bufs[i].seglist); - } - if (dma->bufs[i].buf_count) { - for (j = 0; j < dma->bufs[i].buf_count; j++) { - kfree(dma->bufs[i].buflist[j].dev_private); - } - kfree(dma->bufs[i].buflist); - } - } - - kfree(dma->buflist); - kfree(dma->pagelist); - kfree(dev->dma); - dev->dma = NULL; -} - -/** - * Free a buffer. - * - * \param dev DRM device. - * \param buf buffer to free. - * - * Resets the fields of \p buf. - */ -void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf) -{ - if (!buf) - return; - - buf->waiting = 0; - buf->pending = 0; - buf->file_priv = NULL; - buf->used = 0; - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) - && waitqueue_active(&buf->dma_wait)) { - wake_up_interruptible(&buf->dma_wait); - } -} - -/** - * Reclaim the buffers. - * - * \param file_priv DRM file private. - * - * Frees each buffer associated with \p file_priv not already on the hardware. - */ -void drm_core_reclaim_buffers(struct drm_device *dev, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - if (!dma) - return; - for (i = 0; i < dma->buf_count; i++) { - if (dma->buflist[i]->file_priv == file_priv) { - switch (dma->buflist[i]->list) { - case DRM_LIST_NONE: - drm_free_buffer(dev, dma->buflist[i]); - break; - case DRM_LIST_WAIT: - dma->buflist[i]->list = DRM_LIST_RECLAIM; - break; - default: - /* Buffer already on hardware. */ - break; - } - } - } -} - -EXPORT_SYMBOL(drm_core_reclaim_buffers); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_dp_i2c_helper.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_dp_i2c_helper.c deleted file mode 100644 index f7eba0a0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_dp_i2c_helper.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright © 2009 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "drm_dp_helper.h" -#include "drmP.h" - -/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ -static int -i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, - uint8_t write_byte, uint8_t *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - ret = (*algo_data->aux_ch)(adapter, mode, - write_byte, read_byte); - return ret; -} - -/* - * I2C over AUX CH - */ - -/* - * Send the address. If the I2C link is running, this 'restarts' - * the connection with the new address, this is used for doing - * a write followed by a read (as needed for DDC) - */ -static int -i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_START; - int ret; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - algo_data->address = address; - algo_data->running = true; - ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - return ret; -} - -/* - * Stop the I2C transaction. This closes out the link, sending - * a bare address packet with the MOT bit turned off - */ -static void -i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int mode = MODE_I2C_STOP; - - if (reading) - mode |= MODE_I2C_READ; - else - mode |= MODE_I2C_WRITE; - if (algo_data->running) { - (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); - algo_data->running = false; - } -} - -/* - * Write a single byte to the current I2C address, the - * the I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); - return ret; -} - -/* - * Read a single byte from the current I2C address, the - * I2C link must be running or this returns -EIO - */ -static int -i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - int ret; - - if (!algo_data->running) - return -EIO; - - ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); - return ret; -} - -static int -i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - int ret = 0; - bool reading = false; - int m; - int b; - - for (m = 0; m < num; m++) { - u16 len = msgs[m].len; - u8 *buf = msgs[m].buf; - reading = (msgs[m].flags & I2C_M_RD) != 0; - ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); - if (ret < 0) - break; - if (reading) { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); - if (ret < 0) - break; - } - } else { - for (b = 0; b < len; b++) { - ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); - if (ret < 0) - break; - } - } - if (ret < 0) - break; - } - if (ret >= 0) - ret = num; - i2c_algo_dp_aux_stop(adapter, reading); - DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret); - return ret; -} - -static u32 -i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL | - I2C_FUNC_10BIT_ADDR; -} - -static const struct i2c_algorithm i2c_dp_aux_algo = { - .master_xfer = i2c_algo_dp_aux_xfer, - .functionality = i2c_algo_dp_aux_functionality, -}; - -static void -i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) -{ - (void) i2c_algo_dp_aux_address(adapter, 0, false); - (void) i2c_algo_dp_aux_stop(adapter, false); - -} - -static int -i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) -{ - adapter->algo = &i2c_dp_aux_algo; - adapter->retries = 3; - i2c_dp_aux_reset_bus(adapter); - return 0; -} - -int -i2c_dp_aux_add_bus(struct i2c_adapter *adapter) -{ - int error; - - error = i2c_dp_aux_prepare_bus(adapter); - if (error) - return error; - error = i2c_add_adapter(adapter); - return error; -} -EXPORT_SYMBOL(i2c_dp_aux_add_bus); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_drv.c deleted file mode 100644 index 6116e3b7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_drv.c +++ /dev/null @@ -1,505 +0,0 @@ -/** - * \file drm_drv.c - * Generic driver template - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - * - * To use this template, you must at least define the following (samples - * given for the MGA driver): - * - * \code - * #define DRIVER_AUTHOR "VA Linux Systems, Inc." - * - * #define DRIVER_NAME "mga" - * #define DRIVER_DESC "Matrox G200/G400" - * #define DRIVER_DATE "20001127" - * - * #define drm_x mga_##x - * \endcode - */ - -/* - * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include "drmP.h" -#include "drm_core.h" - - -static int drm_version(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -#define DRM_IOCTL_DEF(ioctl, _func, _flags) \ - [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} - -/** Ioctl table */ -static struct drm_ioctl_desc drm_ioctls[] = { - DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), - DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH), - /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */ - DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - -#if __OS_HAS_AGP - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -#endif - - DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), - - DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), - - DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), - - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), - - DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), - - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED) -}; - -#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) - -/** - * Take down the DRM device. - * - * \param dev DRM device structure. - * - * Frees every resource in \p dev. - * - * \sa drm_device - */ -int drm_lastclose(struct drm_device * dev) -{ - struct drm_vma_entry *vma, *vma_temp; - int i; - - DRM_DEBUG("\n"); - - if (dev->driver->lastclose) - dev->driver->lastclose(dev); - DRM_DEBUG("driver lastclose completed\n"); - - if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET)) - drm_irq_uninstall(dev); - - mutex_lock(&dev->struct_mutex); - - /* Clear AGP information */ - if (drm_core_has_AGP(dev) && dev->agp && - !drm_core_check_feature(dev, DRIVER_MODESET)) { - struct drm_agp_mem *entry, *tempe; - - /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ - list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { - if (entry->bound) - drm_unbind_agp(entry->memory); - drm_free_agp(entry->memory, entry->pages); - kfree(entry); - } - INIT_LIST_HEAD(&dev->agp->memory); - - if (dev->agp->acquired) - drm_agp_release(dev); - - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } - if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg && - !drm_core_check_feature(dev, DRIVER_MODESET)) { - drm_sg_cleanup(dev->sg); - dev->sg = NULL; - } - - /* Clear vma list (only built for debugging) */ - list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) { - list_del(&vma->head); - kfree(vma); - } - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { - for (i = 0; i < dev->queue_count; i++) { - kfree(dev->queuelist[i]); - dev->queuelist[i] = NULL; - } - kfree(dev->queuelist); - dev->queuelist = NULL; - } - dev->queue_count = 0; - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && - !drm_core_check_feature(dev, DRIVER_MODESET)) - drm_dma_takedown(dev); - - dev->dev_mapping = NULL; - mutex_unlock(&dev->struct_mutex); - - DRM_DEBUG("lastclose completed\n"); - return 0; -} - -/** File operations structure */ -static const struct file_operations drm_stub_fops = { - .owner = THIS_MODULE, - .open = drm_stub_open, - .llseek = noop_llseek, -}; - -static int __init drm_core_init(void) -{ - int ret = -ENOMEM; - - drm_global_init(); - idr_init(&drm_minors_idr); - - if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) - goto err_p1; - - drm_class = drm_sysfs_create(THIS_MODULE, "drm"); - if (IS_ERR(drm_class)) { - printk(KERN_ERR "DRM: Error creating drm class.\n"); - ret = PTR_ERR(drm_class); - goto err_p2; - } - - drm_proc_root = proc_mkdir("dri", NULL); - if (!drm_proc_root) { - DRM_ERROR("Cannot create /proc/dri\n"); - ret = -1; - goto err_p3; - } - - drm_debugfs_root = debugfs_create_dir("dri", NULL); - if (!drm_debugfs_root) { - DRM_ERROR("Cannot create /sys/kernel/debug/dri\n"); - ret = -1; - goto err_p3; - } - - DRM_INFO("Initialized %s %d.%d.%d %s\n", - CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); - return 0; -err_p3: - drm_sysfs_destroy(); -err_p2: - unregister_chrdev(DRM_MAJOR, "drm"); - - idr_destroy(&drm_minors_idr); -err_p1: - return ret; -} - -static void __exit drm_core_exit(void) -{ - remove_proc_entry("dri", NULL); - debugfs_remove(drm_debugfs_root); - drm_sysfs_destroy(); - - unregister_chrdev(DRM_MAJOR, "drm"); - - idr_remove_all(&drm_minors_idr); - idr_destroy(&drm_minors_idr); -} - -module_init(drm_core_init); -module_exit(drm_core_exit); - -/** - * Copy and IOCTL return string to user space - */ -static int drm_copy_field(char *buf, size_t *buf_len, const char *value) -{ - int len; - - /* don't overflow userbuf */ - len = strlen(value); - if (len > *buf_len) - len = *buf_len; - - /* let userspace know exact length of driver value (which could be - * larger than the userspace-supplied buffer) */ - *buf_len = strlen(value); - - /* finally, try filling in the userbuf */ - if (len && buf) - if (copy_to_user(buf, value, len)) - return -EFAULT; - return 0; -} - -/** - * Get version information - * - * \param inode device inode. - * \param filp file pointer. - * \param cmd command. - * \param arg user argument, pointing to a drm_version structure. - * \return zero on success or negative number on failure. - * - * Fills in the version information in \p arg. - */ -static int drm_version(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_version *version = data; - int err; - - version->version_major = dev->driver->major; - version->version_minor = dev->driver->minor; - version->version_patchlevel = dev->driver->patchlevel; - err = drm_copy_field(version->name, &version->name_len, - dev->driver->name); - if (!err) - err = drm_copy_field(version->date, &version->date_len, - dev->driver->date); - if (!err) - err = drm_copy_field(version->desc, &version->desc_len, - dev->driver->desc); - - return err; -} - -/** - * Called whenever a process performs an ioctl on /dev/drm. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - * - * Looks up the ioctl function in the ::ioctls table, checking for root - * previleges if so required, and dispatches to the respective function. - */ -long drm_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_device *dev; - struct drm_ioctl_desc *ioctl; - drm_ioctl_t *func; - unsigned int nr = DRM_IOCTL_NR(cmd); - int retcode = -EINVAL; - char stack_kdata[128]; - char *kdata = NULL; - unsigned int usize, asize; - - dev = file_priv->minor->dev; - - if (drm_device_is_unplugged(dev)) - return -ENODEV; - - atomic_inc(&dev->ioctl_count); - atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); - ++file_priv->ioctl_count; - - DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", - task_pid_nr(current), cmd, nr, - (long)old_encode_dev(file_priv->minor->device), - file_priv->authenticated); - - if ((nr >= DRM_CORE_IOCTL_COUNT) && - ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) - goto err_i1; - if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && - (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { - u32 drv_size; - ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; - drv_size = _IOC_SIZE(ioctl->cmd_drv); - usize = asize = _IOC_SIZE(cmd); - if (drv_size > asize) - asize = drv_size; - } - else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { - ioctl = &drm_ioctls[nr]; - cmd = ioctl->cmd; - usize = asize = _IOC_SIZE(cmd); - } else - goto err_i1; - - /* Do not trust userspace, use our own definition */ - func = ioctl->func; - /* is there a local override? */ - if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl) - func = dev->driver->dma_ioctl; - - if (!func) { - DRM_DEBUG("no function\n"); - retcode = -EINVAL; - } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || - ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || - ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) || - (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL))) { - retcode = -EACCES; - } else { - if (cmd & (IOC_IN | IOC_OUT)) { - if (asize <= sizeof(stack_kdata)) { - kdata = stack_kdata; - } else { - kdata = kmalloc(asize, GFP_KERNEL); - if (!kdata) { - retcode = -ENOMEM; - goto err_i1; - } - } - if (asize > usize) - memset(kdata + usize, 0, asize - usize); - } - - if (cmd & IOC_IN) { - if (copy_from_user(kdata, (void __user *)arg, - usize) != 0) { - retcode = -EFAULT; - goto err_i1; - } - } else - memset(kdata, 0, usize); - - if (ioctl->flags & DRM_UNLOCKED) - retcode = func(dev, kdata, file_priv); - else { - mutex_lock(&drm_global_mutex); - retcode = func(dev, kdata, file_priv); - mutex_unlock(&drm_global_mutex); - } - - if (cmd & IOC_OUT) { - if (copy_to_user((void __user *)arg, kdata, - usize) != 0) - retcode = -EFAULT; - } - } - - err_i1: - if (kdata != stack_kdata) - kfree(kdata); - atomic_dec(&dev->ioctl_count); - if (retcode) - DRM_DEBUG("ret = %x\n", retcode); - return retcode; -} - -EXPORT_SYMBOL(drm_ioctl); - -struct drm_local_map *drm_getsarea(struct drm_device *dev) -{ - struct drm_map_list *entry; - - list_for_each_entry(entry, &dev->maplist, head) { - if (entry->map && entry->map->type == _DRM_SHM && - (entry->map->flags & _DRM_CONTAINS_LOCK)) { - return entry->map; - } - } - return NULL; -} -EXPORT_SYMBOL(drm_getsarea); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_edid.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_edid.c deleted file mode 100644 index 6e38325d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_edid.c +++ /dev/null @@ -1,1816 +0,0 @@ -/* - * Copyright (c) 2006 Luc Verhaegen (quirks list) - * Copyright (c) 2007-2008 Intel Corporation - * Jesse Barnes - * Copyright 2010 Red Hat, Inc. - * - * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from - * FB layer. - * Copyright (C) 2006 Dennis Munsie - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include -#include -#include "drmP.h" -#include "drm_edid.h" -#include "drm_edid_modes.h" - -#define version_greater(edid, maj, min) \ - (((edid)->version > (maj)) || \ - ((edid)->version == (maj) && (edid)->revision > (min))) - -#define EDID_EST_TIMINGS 16 -#define EDID_STD_TIMINGS 8 -#define EDID_DETAILED_TIMINGS 4 - -/* - * EDID blocks out in the wild have a variety of bugs, try to collect - * them here (note that userspace may work around broken monitors first, - * but fixes should make their way here so that the kernel "just works" - * on as many displays as possible). - */ - -/* First detailed mode wrong, use largest 60Hz mode */ -#define EDID_QUIRK_PREFER_LARGE_60 (1 << 0) -/* Reported 135MHz pixel clock is too high, needs adjustment */ -#define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1) -/* Prefer the largest mode at 75 Hz */ -#define EDID_QUIRK_PREFER_LARGE_75 (1 << 2) -/* Detail timing is in cm not mm */ -#define EDID_QUIRK_DETAILED_IN_CM (1 << 3) -/* Detailed timing descriptors have bogus size values, so just take the - * maximum size and use that. - */ -#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4) -/* Monitor forgot to set the first detailed is preferred bit. */ -#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) -/* use +hsync +vsync for detailed mode */ -#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) - -struct detailed_mode_closure { - struct drm_connector *connector; - struct edid *edid; - bool preferred; - u32 quirks; - int modes; -}; - -#define LEVEL_DMT 0 -#define LEVEL_GTF 1 -#define LEVEL_GTF2 2 -#define LEVEL_CVT 3 - -static struct edid_quirk { - char *vendor; - int product_id; - u32 quirks; -} edid_quirk_list[] = { - /* Acer AL1706 */ - { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, - /* Acer F51 */ - { "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 }, - /* Unknown Acer */ - { "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, - - /* Belinea 10 15 55 */ - { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 }, - { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 }, - - /* Envision Peripherals, Inc. EN-7100e */ - { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, - /* Envision EN2028 */ - { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 }, - - /* Funai Electronics PM36B */ - { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | - EDID_QUIRK_DETAILED_IN_CM }, - - /* LG Philips LCD LP154W01-A5 */ - { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, - { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, - - /* Philips 107p5 CRT */ - { "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, - - /* Proview AY765C */ - { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, - - /* Samsung SyncMaster 205BW. Note: irony */ - { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP }, - /* Samsung SyncMaster 22[5-6]BW */ - { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, - { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, -}; - -/*** DDC fetch and block validation ***/ - -static const u8 edid_header[] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 -}; - - /* - * Sanity check the header of the base EDID block. Return 8 if the header - * is perfect, down to 0 if it's totally wrong. - */ -int drm_edid_header_is_valid(const u8 *raw_edid) -{ - int i, score = 0; - - for (i = 0; i < sizeof(edid_header); i++) - if (raw_edid[i] == edid_header[i]) - score++; - - return score; -} -EXPORT_SYMBOL(drm_edid_header_is_valid); - - -/* - * Sanity check the EDID block (base or extension). Return 0 if the block - * doesn't check out, or 1 if it's valid. - */ -bool drm_edid_block_valid(u8 *raw_edid) -{ - int i; - u8 csum = 0; - struct edid *edid = (struct edid *)raw_edid; - - if (raw_edid[0] == 0x00) { - int score = drm_edid_header_is_valid(raw_edid); - if (score == 8) ; - else if (score >= 6) { - DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); - memcpy(raw_edid, edid_header, sizeof(edid_header)); - } else { - goto bad; - } - } - - for (i = 0; i < EDID_LENGTH; i++) - csum += raw_edid[i]; - if (csum) { - DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum); - - /* allow CEA to slide through, switches mangle this */ - if (raw_edid[0] != 0x02) - goto bad; - } - - /* per-block-type checks */ - switch (raw_edid[0]) { - case 0: /* base */ - if (edid->version != 1) { - DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); - goto bad; - } - - if (edid->revision > 4) - DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n"); - break; - - default: - break; - } - - return 1; - -bad: - if (raw_edid) { - printk(KERN_ERR "Raw EDID:\n"); - print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, - raw_edid, EDID_LENGTH, false); - } - return 0; -} -EXPORT_SYMBOL(drm_edid_block_valid); - -/** - * drm_edid_is_valid - sanity check EDID data - * @edid: EDID data - * - * Sanity-check an entire EDID record (including extensions) - */ -bool drm_edid_is_valid(struct edid *edid) -{ - int i; - u8 *raw = (u8 *)edid; - - if (!edid) - return false; - - for (i = 0; i <= edid->extensions; i++) - if (!drm_edid_block_valid(raw + i * EDID_LENGTH)) - return false; - - return true; -} -EXPORT_SYMBOL(drm_edid_is_valid); - -#define DDC_SEGMENT_ADDR 0x30 -/** - * Get EDID information via I2C. - * - * \param adapter : i2c device adaptor - * \param buf : EDID data buffer to be filled - * \param len : EDID data buffer length - * \return 0 on success or -1 on failure. - * - * Try to fetch EDID information by calling i2c driver function. - */ -static int -drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, - int block, int len) -{ - unsigned char start = block * EDID_LENGTH; - int ret, retries = 5; - - /* The core i2c driver will automatically retry the transfer if the - * adapter reports EAGAIN. However, we find that bit-banging transfers - * are susceptible to errors under a heavily loaded machine and - * generate spurious NAKs and timeouts. Retrying the transfer - * of the individual block a few times seems to overcome this. - */ - do { - struct i2c_msg msgs[] = { - { - .addr = DDC_ADDR, - .flags = 0, - .len = 1, - .buf = &start, - }, { - .addr = DDC_ADDR, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - } - }; - ret = i2c_transfer(adapter, msgs, 2); - if (ret == -ENXIO) { - DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n", - adapter->name); - break; - } - } while (ret != 2 && --retries); - - return ret == 2 ? 0 : -1; -} - -static bool drm_edid_is_zero(u8 *in_edid, int length) -{ - int i; - u32 *raw_edid = (u32 *)in_edid; - - for (i = 0; i < length / 4; i++) - if (*(raw_edid + i) != 0) - return false; - return true; -} - -static u8 * -drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) -{ - int i, j = 0, valid_extensions = 0; - u8 *block, *new; - - if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) - return NULL; - - /* base block fetch */ - for (i = 0; i < 4; i++) { - if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) - goto out; - if (drm_edid_block_valid(block)) - break; - if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { - connector->null_edid_counter++; - goto carp; - } - } - if (i == 4) - goto carp; - - /* if there's no extensions, we're done */ - if (block[0x7e] == 0) - return block; - - new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto out; - block = new; - - for (j = 1; j <= block[0x7e]; j++) { - for (i = 0; i < 4; i++) { - if (drm_do_probe_ddc_edid(adapter, - block + (valid_extensions + 1) * EDID_LENGTH, - j, EDID_LENGTH)) - goto out; - if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { - valid_extensions++; - break; - } - } - if (i == 4) - dev_warn(connector->dev->dev, - "%s: Ignoring invalid EDID block %d.\n", - drm_get_connector_name(connector), j); - } - - if (valid_extensions != block[0x7e]) { - block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; - block[0x7e] = valid_extensions; - new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto out; - block = new; - } - - return block; - -carp: - dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n", - drm_get_connector_name(connector), j); - -out: - kfree(block); - return NULL; -} - -/** - * Probe DDC presence. - * - * \param adapter : i2c device adaptor - * \return 1 on success - */ -static bool -drm_probe_ddc(struct i2c_adapter *adapter) -{ - unsigned char out; - - return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0); -} - -/** - * drm_get_edid - get EDID data, if available - * @connector: connector we're probing - * @adapter: i2c adapter to use for DDC - * - * Poke the given i2c channel to grab EDID data if possible. If found, - * attach it to the connector. - * - * Return edid data or NULL if we couldn't find any. - */ -struct edid *drm_get_edid(struct drm_connector *connector, - struct i2c_adapter *adapter) -{ - struct edid *edid = NULL; - - if (drm_probe_ddc(adapter)) - edid = (struct edid *)drm_do_get_edid(connector, adapter); - - connector->display_info.raw_edid = (char *)edid; - - return edid; - -} -EXPORT_SYMBOL(drm_get_edid); - -/*** EDID parsing ***/ - -/** - * edid_vendor - match a string against EDID's obfuscated vendor field - * @edid: EDID to match - * @vendor: vendor string - * - * Returns true if @vendor is in @edid, false otherwise - */ -static bool edid_vendor(struct edid *edid, char *vendor) -{ - char edid_vendor[3]; - - edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@'; - edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) | - ((edid->mfg_id[1] & 0xe0) >> 5)) + '@'; - edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@'; - - return !strncmp(edid_vendor, vendor, 3); -} - -/** - * edid_get_quirks - return quirk flags for a given EDID - * @edid: EDID to process - * - * This tells subsequent routines what fixes they need to apply. - */ -static u32 edid_get_quirks(struct edid *edid) -{ - struct edid_quirk *quirk; - int i; - - for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) { - quirk = &edid_quirk_list[i]; - - if (edid_vendor(edid, quirk->vendor) && - (EDID_PRODUCT_ID(edid) == quirk->product_id)) - return quirk->quirks; - } - - return 0; -} - -#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay) -#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh)) - -/** - * edid_fixup_preferred - set preferred modes based on quirk list - * @connector: has mode list to fix up - * @quirks: quirks list - * - * Walk the mode list for @connector, clearing the preferred status - * on existing modes and setting it anew for the right mode ala @quirks. - */ -static void edid_fixup_preferred(struct drm_connector *connector, - u32 quirks) -{ - struct drm_display_mode *t, *cur_mode, *preferred_mode; - int target_refresh = 0; - - if (list_empty(&connector->probed_modes)) - return; - - if (quirks & EDID_QUIRK_PREFER_LARGE_60) - target_refresh = 60; - if (quirks & EDID_QUIRK_PREFER_LARGE_75) - target_refresh = 75; - - preferred_mode = list_first_entry(&connector->probed_modes, - struct drm_display_mode, head); - - list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) { - cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED; - - if (cur_mode == preferred_mode) - continue; - - /* Largest mode is preferred */ - if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode)) - preferred_mode = cur_mode; - - /* At a given size, try to get closest to target refresh */ - if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) && - MODE_REFRESH_DIFF(cur_mode, target_refresh) < - MODE_REFRESH_DIFF(preferred_mode, target_refresh)) { - preferred_mode = cur_mode; - } - } - - preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; -} - -struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, - int hsize, int vsize, int fresh) -{ - struct drm_display_mode *mode = NULL; - int i; - - for (i = 0; i < drm_num_dmt_modes; i++) { - const struct drm_display_mode *ptr = &drm_dmt_modes[i]; - if (hsize == ptr->hdisplay && - vsize == ptr->vdisplay && - fresh == drm_mode_vrefresh(ptr)) { - /* get the expected default mode */ - mode = drm_mode_duplicate(dev, ptr); - break; - } - } - return mode; -} -EXPORT_SYMBOL(drm_mode_find_dmt); - -typedef void detailed_cb(struct detailed_timing *timing, void *closure); - -static void -cea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure) -{ - int i, n = 0; - u8 d = ext[0x02]; - u8 *det_base = ext + d; - - n = (127 - d) / 18; - for (i = 0; i < n; i++) - cb((struct detailed_timing *)(det_base + 18 * i), closure); -} - -static void -vtb_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure) -{ - unsigned int i, n = min((int)ext[0x02], 6); - u8 *det_base = ext + 5; - - if (ext[0x01] != 1) - return; /* unknown version */ - - for (i = 0; i < n; i++) - cb((struct detailed_timing *)(det_base + 18 * i), closure); -} - -static void -drm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure) -{ - int i; - struct edid *edid = (struct edid *)raw_edid; - - if (edid == NULL) - return; - - for (i = 0; i < EDID_DETAILED_TIMINGS; i++) - cb(&(edid->detailed_timings[i]), closure); - - for (i = 1; i <= raw_edid[0x7e]; i++) { - u8 *ext = raw_edid + (i * EDID_LENGTH); - switch (*ext) { - case CEA_EXT: - cea_for_each_detailed_block(ext, cb, closure); - break; - case VTB_EXT: - vtb_for_each_detailed_block(ext, cb, closure); - break; - default: - break; - } - } -} - -static void -is_rb(struct detailed_timing *t, void *data) -{ - u8 *r = (u8 *)t; - if (r[3] == EDID_DETAIL_MONITOR_RANGE) - if (r[15] & 0x10) - *(bool *)data = true; -} - -/* EDID 1.4 defines this explicitly. For EDID 1.3, we guess, badly. */ -static bool -drm_monitor_supports_rb(struct edid *edid) -{ - if (edid->revision >= 4) { - bool ret = false; - drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); - return ret; - } - - return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0); -} - -static void -find_gtf2(struct detailed_timing *t, void *data) -{ - u8 *r = (u8 *)t; - if (r[3] == EDID_DETAIL_MONITOR_RANGE && r[10] == 0x02) - *(u8 **)data = r; -} - -/* Secondary GTF curve kicks in above some break frequency */ -static int -drm_gtf2_hbreak(struct edid *edid) -{ - u8 *r = NULL; - drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); - return r ? (r[12] * 2) : 0; -} - -static int -drm_gtf2_2c(struct edid *edid) -{ - u8 *r = NULL; - drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); - return r ? r[13] : 0; -} - -static int -drm_gtf2_m(struct edid *edid) -{ - u8 *r = NULL; - drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); - return r ? (r[15] << 8) + r[14] : 0; -} - -static int -drm_gtf2_k(struct edid *edid) -{ - u8 *r = NULL; - drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); - return r ? r[16] : 0; -} - -static int -drm_gtf2_2j(struct edid *edid) -{ - u8 *r = NULL; - drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); - return r ? r[17] : 0; -} - -/** - * standard_timing_level - get std. timing level(CVT/GTF/DMT) - * @edid: EDID block to scan - */ -static int standard_timing_level(struct edid *edid) -{ - if (edid->revision >= 2) { - if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)) - return LEVEL_CVT; - if (drm_gtf2_hbreak(edid)) - return LEVEL_GTF2; - return LEVEL_GTF; - } - return LEVEL_DMT; -} - -/* - * 0 is reserved. The spec says 0x01 fill for unused timings. Some old - * monitors fill with ascii space (0x20) instead. - */ -static int -bad_std_timing(u8 a, u8 b) -{ - return (a == 0x00 && b == 0x00) || - (a == 0x01 && b == 0x01) || - (a == 0x20 && b == 0x20); -} - -/** - * drm_mode_std - convert standard mode info (width, height, refresh) into mode - * @t: standard timing params - * @timing_level: standard timing level - * - * Take the standard timing params (in this case width, aspect, and refresh) - * and convert them into a real mode using CVT/GTF/DMT. - */ -static struct drm_display_mode * -drm_mode_std(struct drm_connector *connector, struct edid *edid, - struct std_timing *t, int revision) -{ - struct drm_device *dev = connector->dev; - struct drm_display_mode *m, *mode = NULL; - int hsize, vsize; - int vrefresh_rate; - unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) - >> EDID_TIMING_ASPECT_SHIFT; - unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) - >> EDID_TIMING_VFREQ_SHIFT; - int timing_level = standard_timing_level(edid); - - if (bad_std_timing(t->hsize, t->vfreq_aspect)) - return NULL; - - /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ - hsize = t->hsize * 8 + 248; - /* vrefresh_rate = vfreq + 60 */ - vrefresh_rate = vfreq + 60; - /* the vdisplay is calculated based on the aspect ratio */ - if (aspect_ratio == 0) { - if (revision < 3) - vsize = hsize; - else - vsize = (hsize * 10) / 16; - } else if (aspect_ratio == 1) - vsize = (hsize * 3) / 4; - else if (aspect_ratio == 2) - vsize = (hsize * 4) / 5; - else - vsize = (hsize * 9) / 16; - - /* HDTV hack, part 1 */ - if (vrefresh_rate == 60 && - ((hsize == 1360 && vsize == 765) || - (hsize == 1368 && vsize == 769))) { - hsize = 1366; - vsize = 768; - } - - /* - * If this connector already has a mode for this size and refresh - * rate (because it came from detailed or CVT info), use that - * instead. This way we don't have to guess at interlace or - * reduced blanking. - */ - list_for_each_entry(m, &connector->probed_modes, head) - if (m->hdisplay == hsize && m->vdisplay == vsize && - drm_mode_vrefresh(m) == vrefresh_rate) - return NULL; - - /* HDTV hack, part 2 */ - if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) { - mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0, - false); - mode->hdisplay = 1366; - mode->hsync_start = mode->hsync_start - 1; - mode->hsync_end = mode->hsync_end - 1; - return mode; - } - - /* check whether it can be found in default mode table */ - mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate); - if (mode) - return mode; - - switch (timing_level) { - case LEVEL_DMT: - break; - case LEVEL_GTF: - mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); - break; - case LEVEL_GTF2: - /* - * This is potentially wrong if there's ever a monitor with - * more than one ranges section, each claiming a different - * secondary GTF curve. Please don't do that. - */ - mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); - if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { - drm_mode_destroy(dev, mode); - mode = drm_gtf_mode_complex(dev, hsize, vsize, - vrefresh_rate, 0, 0, - drm_gtf2_m(edid), - drm_gtf2_2c(edid), - drm_gtf2_k(edid), - drm_gtf2_2j(edid)); - } - break; - case LEVEL_CVT: - mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0, - false); - break; - } - return mode; -} - -/* - * EDID is delightfully ambiguous about how interlaced modes are to be - * encoded. Our internal representation is of frame height, but some - * HDTV detailed timings are encoded as field height. - * - * The format list here is from CEA, in frame size. Technically we - * should be checking refresh rate too. Whatever. - */ -static void -drm_mode_do_interlace_quirk(struct drm_display_mode *mode, - struct detailed_pixel_timing *pt) -{ - int i; - static const struct { - int w, h; - } cea_interlaced[] = { - { 1920, 1080 }, - { 720, 480 }, - { 1440, 480 }, - { 2880, 480 }, - { 720, 576 }, - { 1440, 576 }, - { 2880, 576 }, - }; - - if (!(pt->misc & DRM_EDID_PT_INTERLACED)) - return; - - for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) { - if ((mode->hdisplay == cea_interlaced[i].w) && - (mode->vdisplay == cea_interlaced[i].h / 2)) { - mode->vdisplay *= 2; - mode->vsync_start *= 2; - mode->vsync_end *= 2; - mode->vtotal *= 2; - mode->vtotal |= 1; - } - } - - mode->flags |= DRM_MODE_FLAG_INTERLACE; -} - -/** - * drm_mode_detailed - create a new mode from an EDID detailed timing section - * @dev: DRM device (needed to create new mode) - * @edid: EDID block - * @timing: EDID detailed timing info - * @quirks: quirks to apply - * - * An EDID detailed timing block contains enough info for us to create and - * return a new struct drm_display_mode. - */ -static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, - struct edid *edid, - struct detailed_timing *timing, - u32 quirks) -{ - struct drm_display_mode *mode; - struct detailed_pixel_timing *pt = &timing->data.pixel_data; - unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; - unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; - unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; - unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; - unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; - unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; - unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; - unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); - - /* ignore tiny modes */ - if (hactive < 64 || vactive < 64) - return NULL; - - if (pt->misc & DRM_EDID_PT_STEREO) { - printk(KERN_WARNING "stereo mode not supported\n"); - return NULL; - } - if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { - printk(KERN_WARNING "composite sync not supported\n"); - } - - /* it is incorrect if hsync/vsync width is zero */ - if (!hsync_pulse_width || !vsync_pulse_width) { - DRM_DEBUG_KMS("Incorrect Detailed timing. " - "Wrong Hsync/Vsync pulse width\n"); - return NULL; - } - mode = drm_mode_create(dev); - if (!mode) - return NULL; - - mode->type = DRM_MODE_TYPE_DRIVER; - - if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) - timing->pixel_clock = cpu_to_le16(1088); - - mode->clock = le16_to_cpu(timing->pixel_clock) * 10; - - mode->hdisplay = hactive; - mode->hsync_start = mode->hdisplay + hsync_offset; - mode->hsync_end = mode->hsync_start + hsync_pulse_width; - mode->htotal = mode->hdisplay + hblank; - - mode->vdisplay = vactive; - mode->vsync_start = mode->vdisplay + vsync_offset; - mode->vsync_end = mode->vsync_start + vsync_pulse_width; - mode->vtotal = mode->vdisplay + vblank; - - /* Some EDIDs have bogus h/vtotal values */ - if (mode->hsync_end > mode->htotal) - mode->htotal = mode->hsync_end + 1; - if (mode->vsync_end > mode->vtotal) - mode->vtotal = mode->vsync_end + 1; - - drm_mode_do_interlace_quirk(mode, pt); - - drm_mode_set_name(mode); - - if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { - pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; - } - - mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? - DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; - mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? - DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; - - mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; - mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; - - if (quirks & EDID_QUIRK_DETAILED_IN_CM) { - mode->width_mm *= 10; - mode->height_mm *= 10; - } - - if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) { - mode->width_mm = edid->width_cm * 10; - mode->height_mm = edid->height_cm * 10; - } - - return mode; -} - -static bool -mode_is_rb(const struct drm_display_mode *mode) -{ - return (mode->htotal - mode->hdisplay == 160) && - (mode->hsync_end - mode->hdisplay == 80) && - (mode->hsync_end - mode->hsync_start == 32) && - (mode->vsync_start - mode->vdisplay == 3); -} - -static bool -mode_in_hsync_range(const struct drm_display_mode *mode, - struct edid *edid, u8 *t) -{ - int hsync, hmin, hmax; - - hmin = t[7]; - if (edid->revision >= 4) - hmin += ((t[4] & 0x04) ? 255 : 0); - hmax = t[8]; - if (edid->revision >= 4) - hmax += ((t[4] & 0x08) ? 255 : 0); - hsync = drm_mode_hsync(mode); - - return (hsync <= hmax && hsync >= hmin); -} - -static bool -mode_in_vsync_range(const struct drm_display_mode *mode, - struct edid *edid, u8 *t) -{ - int vsync, vmin, vmax; - - vmin = t[5]; - if (edid->revision >= 4) - vmin += ((t[4] & 0x01) ? 255 : 0); - vmax = t[6]; - if (edid->revision >= 4) - vmax += ((t[4] & 0x02) ? 255 : 0); - vsync = drm_mode_vrefresh(mode); - - return (vsync <= vmax && vsync >= vmin); -} - -static u32 -range_pixel_clock(struct edid *edid, u8 *t) -{ - /* unspecified */ - if (t[9] == 0 || t[9] == 255) - return 0; - - /* 1.4 with CVT support gives us real precision, yay */ - if (edid->revision >= 4 && t[10] == 0x04) - return (t[9] * 10000) - ((t[12] >> 2) * 250); - - /* 1.3 is pathetic, so fuzz up a bit */ - return t[9] * 10000 + 5001; -} - -static bool -mode_in_range(const struct drm_display_mode *mode, struct edid *edid, - struct detailed_timing *timing) -{ - u32 max_clock; - u8 *t = (u8 *)timing; - - if (!mode_in_hsync_range(mode, edid, t)) - return false; - - if (!mode_in_vsync_range(mode, edid, t)) - return false; - - if ((max_clock = range_pixel_clock(edid, t))) - if (mode->clock > max_clock) - return false; - - /* 1.4 max horizontal check */ - if (edid->revision >= 4 && t[10] == 0x04) - if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3)))) - return false; - - if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid)) - return false; - - return true; -} - -/* - * XXX If drm_dmt_modes ever regrows the CVT-R modes (and it will) this will - * need to account for them. - */ -static int -drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, - struct detailed_timing *timing) -{ - int i, modes = 0; - struct drm_display_mode *newmode; - struct drm_device *dev = connector->dev; - - for (i = 0; i < drm_num_dmt_modes; i++) { - if (mode_in_range(drm_dmt_modes + i, edid, timing)) { - newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - } - - return modes; -} - -static void -do_inferred_modes(struct detailed_timing *timing, void *c) -{ - struct detailed_mode_closure *closure = c; - struct detailed_non_pixel *data = &timing->data.other_data; - int gtf = (closure->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF); - - if (gtf && data->type == EDID_DETAIL_MONITOR_RANGE) - closure->modes += drm_gtf_modes_for_range(closure->connector, - closure->edid, - timing); -} - -static int -add_inferred_modes(struct drm_connector *connector, struct edid *edid) -{ - struct detailed_mode_closure closure = { - connector, edid, 0, 0, 0 - }; - - if (version_greater(edid, 1, 0)) - drm_for_each_detailed_block((u8 *)edid, do_inferred_modes, - &closure); - - return closure.modes; -} - -static int -drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) -{ - int i, j, m, modes = 0; - struct drm_display_mode *mode; - u8 *est = ((u8 *)timing) + 5; - - for (i = 0; i < 6; i++) { - for (j = 7; j > 0; j--) { - m = (i * 8) + (7 - j); - if (m >= ARRAY_SIZE(est3_modes)) - break; - if (est[i] & (1 << j)) { - mode = drm_mode_find_dmt(connector->dev, - est3_modes[m].w, - est3_modes[m].h, - est3_modes[m].r - /*, est3_modes[m].rb */); - if (mode) { - drm_mode_probed_add(connector, mode); - modes++; - } - } - } - } - - return modes; -} - -static void -do_established_modes(struct detailed_timing *timing, void *c) -{ - struct detailed_mode_closure *closure = c; - struct detailed_non_pixel *data = &timing->data.other_data; - - if (data->type == EDID_DETAIL_EST_TIMINGS) - closure->modes += drm_est3_modes(closure->connector, timing); -} - -/** - * add_established_modes - get est. modes from EDID and add them - * @edid: EDID block to scan - * - * Each EDID block contains a bitmap of the supported "established modes" list - * (defined above). Tease them out and add them to the global modes list. - */ -static int -add_established_modes(struct drm_connector *connector, struct edid *edid) -{ - struct drm_device *dev = connector->dev; - unsigned long est_bits = edid->established_timings.t1 | - (edid->established_timings.t2 << 8) | - ((edid->established_timings.mfg_rsvd & 0x80) << 9); - int i, modes = 0; - struct detailed_mode_closure closure = { - connector, edid, 0, 0, 0 - }; - - for (i = 0; i <= EDID_EST_TIMINGS; i++) { - if (est_bits & (1<data.other_data; - struct drm_connector *connector = closure->connector; - struct edid *edid = closure->edid; - - if (data->type == EDID_DETAIL_STD_MODES) { - int i; - for (i = 0; i < 6; i++) { - struct std_timing *std; - struct drm_display_mode *newmode; - - std = &data->data.timings[i]; - newmode = drm_mode_std(connector, edid, std, - edid->revision); - if (newmode) { - drm_mode_probed_add(connector, newmode); - closure->modes++; - } - } - } -} - -/** - * add_standard_modes - get std. modes from EDID and add them - * @edid: EDID block to scan - * - * Standard modes can be calculated using the appropriate standard (DMT, - * GTF or CVT. Grab them from @edid and add them to the list. - */ -static int -add_standard_modes(struct drm_connector *connector, struct edid *edid) -{ - int i, modes = 0; - struct detailed_mode_closure closure = { - connector, edid, 0, 0, 0 - }; - - for (i = 0; i < EDID_STD_TIMINGS; i++) { - struct drm_display_mode *newmode; - - newmode = drm_mode_std(connector, edid, - &edid->standard_timings[i], - edid->revision); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - - if (version_greater(edid, 1, 0)) - drm_for_each_detailed_block((u8 *)edid, do_standard_modes, - &closure); - - /* XXX should also look for standard codes in VTB blocks */ - - return modes + closure.modes; -} - -static int drm_cvt_modes(struct drm_connector *connector, - struct detailed_timing *timing) -{ - int i, j, modes = 0; - struct drm_display_mode *newmode; - struct drm_device *dev = connector->dev; - struct cvt_timing *cvt; - const int rates[] = { 60, 85, 75, 60, 50 }; - const u8 empty[3] = { 0, 0, 0 }; - - for (i = 0; i < 4; i++) { - int uninitialized_var(width), height; - cvt = &(timing->data.other_data.data.cvt[i]); - - if (!memcmp(cvt->code, empty, 3)) - continue; - - height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2; - switch (cvt->code[1] & 0x0c) { - case 0x00: - width = height * 4 / 3; - break; - case 0x04: - width = height * 16 / 9; - break; - case 0x08: - width = height * 16 / 10; - break; - case 0x0c: - width = height * 15 / 9; - break; - } - - for (j = 1; j < 5; j++) { - if (cvt->code[2] & (1 << j)) { - newmode = drm_cvt_mode(dev, width, height, - rates[j], j == 0, - false, false); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - } - } - - return modes; -} - -static void -do_cvt_mode(struct detailed_timing *timing, void *c) -{ - struct detailed_mode_closure *closure = c; - struct detailed_non_pixel *data = &timing->data.other_data; - - if (data->type == EDID_DETAIL_CVT_3BYTE) - closure->modes += drm_cvt_modes(closure->connector, timing); -} - -static int -add_cvt_modes(struct drm_connector *connector, struct edid *edid) -{ - struct detailed_mode_closure closure = { - connector, edid, 0, 0, 0 - }; - - if (version_greater(edid, 1, 2)) - drm_for_each_detailed_block((u8 *)edid, do_cvt_mode, &closure); - - /* XXX should also look for CVT codes in VTB blocks */ - - return closure.modes; -} - -static void -do_detailed_mode(struct detailed_timing *timing, void *c) -{ - struct detailed_mode_closure *closure = c; - struct drm_display_mode *newmode; - - if (timing->pixel_clock) { - newmode = drm_mode_detailed(closure->connector->dev, - closure->edid, timing, - closure->quirks); - if (!newmode) - return; - - if (closure->preferred) - newmode->type |= DRM_MODE_TYPE_PREFERRED; - - drm_mode_probed_add(closure->connector, newmode); - closure->modes++; - closure->preferred = 0; - } -} - -/* - * add_detailed_modes - Add modes from detailed timings - * @connector: attached connector - * @edid: EDID block to scan - * @quirks: quirks to apply - */ -static int -add_detailed_modes(struct drm_connector *connector, struct edid *edid, - u32 quirks) -{ - struct detailed_mode_closure closure = { - connector, - edid, - 1, - quirks, - 0 - }; - - if (closure.preferred && !version_greater(edid, 1, 3)) - closure.preferred = - (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING); - - drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure); - - return closure.modes; -} - -#define HDMI_IDENTIFIER 0x000C03 -#define AUDIO_BLOCK 0x01 -#define VIDEO_BLOCK 0x02 -#define VENDOR_BLOCK 0x03 -#define SPEAKER_BLOCK 0x04 -#define EDID_BASIC_AUDIO (1 << 6) - -/** - * Search EDID for CEA extension block. - */ -u8 *drm_find_cea_extension(struct edid *edid) -{ - u8 *edid_ext = NULL; - int i; - - /* No EDID or EDID extensions */ - if (edid == NULL || edid->extensions == 0) - return NULL; - - /* Find CEA extension */ - for (i = 0; i < edid->extensions; i++) { - edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); - if (edid_ext[0] == CEA_EXT) - break; - } - - if (i == edid->extensions) - return NULL; - - return edid_ext; -} -EXPORT_SYMBOL(drm_find_cea_extension); - -static int -do_cea_modes (struct drm_connector *connector, u8 *db, u8 len) -{ - struct drm_device *dev = connector->dev; - u8 * mode, cea_mode; - int modes = 0; - - for (mode = db; mode < db + len; mode++) { - cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */ - if (cea_mode < drm_num_cea_modes) { - struct drm_display_mode *newmode; - newmode = drm_mode_duplicate(dev, - &edid_cea_modes[cea_mode]); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; - } - } - } - - return modes; -} - -static int -add_cea_modes(struct drm_connector *connector, struct edid *edid) -{ - u8 * cea = drm_find_cea_extension(edid); - u8 * db, dbl; - int modes = 0; - - if (cea && cea[1] >= 3) { - for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) { - dbl = db[0] & 0x1f; - if (((db[0] & 0xe0) >> 5) == VIDEO_BLOCK) - modes += do_cea_modes (connector, db+1, dbl); - } - } - - return modes; -} - -static void -parse_hdmi_vsdb(struct drm_connector *connector, uint8_t *db) -{ - connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */ - - connector->dvi_dual = db[6] & 1; - connector->max_tmds_clock = db[7] * 5; - - connector->latency_present[0] = db[8] >> 7; - connector->latency_present[1] = (db[8] >> 6) & 1; - connector->video_latency[0] = db[9]; - connector->audio_latency[0] = db[10]; - connector->video_latency[1] = db[11]; - connector->audio_latency[1] = db[12]; - - DRM_LOG_KMS("HDMI: DVI dual %d, " - "max TMDS clock %d, " - "latency present %d %d, " - "video latency %d %d, " - "audio latency %d %d\n", - connector->dvi_dual, - connector->max_tmds_clock, - (int) connector->latency_present[0], - (int) connector->latency_present[1], - connector->video_latency[0], - connector->video_latency[1], - connector->audio_latency[0], - connector->audio_latency[1]); -} - -static void -monitor_name(struct detailed_timing *t, void *data) -{ - if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME) - *(u8 **)data = t->data.other_data.data.str.str; -} - -/** - * drm_edid_to_eld - build ELD from EDID - * @connector: connector corresponding to the HDMI/DP sink - * @edid: EDID to parse - * - * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. - * Some ELD fields are left to the graphics driver caller: - * - Conn_Type - * - HDCP - * - Port_ID - */ -void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) -{ - uint8_t *eld = connector->eld; - u8 *cea; - u8 *name; - u8 *db; - int sad_count = 0; - int mnl; - int dbl; - - memset(eld, 0, sizeof(connector->eld)); - - cea = drm_find_cea_extension(edid); - if (!cea) { - DRM_DEBUG_KMS("ELD: no CEA Extension found\n"); - return; - } - - name = NULL; - drm_for_each_detailed_block((u8 *)edid, monitor_name, &name); - for (mnl = 0; name && mnl < 13; mnl++) { - if (name[mnl] == 0x0a) - break; - eld[20 + mnl] = name[mnl]; - } - eld[4] = (cea[1] << 5) | mnl; - DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20); - - eld[0] = 2 << 3; /* ELD version: 2 */ - - eld[16] = edid->mfg_id[0]; - eld[17] = edid->mfg_id[1]; - eld[18] = edid->prod_code[0]; - eld[19] = edid->prod_code[1]; - - if (cea[1] >= 3) - for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) { - dbl = db[0] & 0x1f; - - switch ((db[0] & 0xe0) >> 5) { - case AUDIO_BLOCK: - /* Audio Data Block, contains SADs */ - sad_count = dbl / 3; - memcpy(eld + 20 + mnl, &db[1], dbl); - break; - case SPEAKER_BLOCK: - /* Speaker Allocation Data Block */ - eld[7] = db[1]; - break; - case VENDOR_BLOCK: - /* HDMI Vendor-Specific Data Block */ - if (db[1] == 0x03 && db[2] == 0x0c && db[3] == 0) - parse_hdmi_vsdb(connector, db); - break; - default: - break; - } - } - eld[5] |= sad_count << 4; - eld[2] = (20 + mnl + sad_count * 3 + 3) / 4; - - DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count); -} -EXPORT_SYMBOL(drm_edid_to_eld); - -/** - * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond - * @connector: connector associated with the HDMI/DP sink - * @mode: the display mode - */ -int drm_av_sync_delay(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); - int a, v; - - if (!connector->latency_present[0]) - return 0; - if (!connector->latency_present[1]) - i = 0; - - a = connector->audio_latency[i]; - v = connector->video_latency[i]; - - /* - * HDMI/DP sink doesn't support audio or video? - */ - if (a == 255 || v == 255) - return 0; - - /* - * Convert raw EDID values to millisecond. - * Treat unknown latency as 0ms. - */ - if (a) - a = min(2 * (a - 1), 500); - if (v) - v = min(2 * (v - 1), 500); - - return max(v - a, 0); -} -EXPORT_SYMBOL(drm_av_sync_delay); - -/** - * drm_select_eld - select one ELD from multiple HDMI/DP sinks - * @encoder: the encoder just changed display mode - * @mode: the adjusted display mode - * - * It's possible for one encoder to be associated with multiple HDMI/DP sinks. - * The policy is now hard coded to simply use the first HDMI/DP sink's ELD. - */ -struct drm_connector *drm_select_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder && connector->eld[0]) - return connector; - - return NULL; -} -EXPORT_SYMBOL(drm_select_eld); - -/** - * drm_detect_hdmi_monitor - detect whether monitor is hdmi. - * @edid: monitor EDID information - * - * Parse the CEA extension according to CEA-861-B. - * Return true if HDMI, false if not or unknown. - */ -bool drm_detect_hdmi_monitor(struct edid *edid) -{ - u8 *edid_ext; - int i, hdmi_id; - int start_offset, end_offset; - bool is_hdmi = false; - - edid_ext = drm_find_cea_extension(edid); - if (!edid_ext) - goto end; - - /* Data block offset in CEA extension block */ - start_offset = 4; - end_offset = edid_ext[2]; - - /* - * Because HDMI identifier is in Vendor Specific Block, - * search it from all data blocks of CEA extension. - */ - for (i = start_offset; i < end_offset; - /* Increased by data block len */ - i += ((edid_ext[i] & 0x1f) + 1)) { - /* Find vendor specific block */ - if ((edid_ext[i] >> 5) == VENDOR_BLOCK) { - hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) | - edid_ext[i + 3] << 16; - /* Find HDMI identifier */ - if (hdmi_id == HDMI_IDENTIFIER) - is_hdmi = true; - break; - } - } - -end: - return is_hdmi; -} -EXPORT_SYMBOL(drm_detect_hdmi_monitor); - -/** - * drm_detect_monitor_audio - check monitor audio capability - * - * Monitor should have CEA extension block. - * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic - * audio' only. If there is any audio extension block and supported - * audio format, assume at least 'basic audio' support, even if 'basic - * audio' is not defined in EDID. - * - */ -bool drm_detect_monitor_audio(struct edid *edid) -{ - u8 *edid_ext; - int i, j; - bool has_audio = false; - int start_offset, end_offset; - - edid_ext = drm_find_cea_extension(edid); - if (!edid_ext) - goto end; - - has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0); - - if (has_audio) { - DRM_DEBUG_KMS("Monitor has basic audio support\n"); - goto end; - } - - /* Data block offset in CEA extension block */ - start_offset = 4; - end_offset = edid_ext[2]; - - for (i = start_offset; i < end_offset; - i += ((edid_ext[i] & 0x1f) + 1)) { - if ((edid_ext[i] >> 5) == AUDIO_BLOCK) { - has_audio = true; - for (j = 1; j < (edid_ext[i] & 0x1f); j += 3) - DRM_DEBUG_KMS("CEA audio format %d\n", - (edid_ext[i + j] >> 3) & 0xf); - goto end; - } - } -end: - return has_audio; -} -EXPORT_SYMBOL(drm_detect_monitor_audio); - -/** - * drm_add_display_info - pull display info out if present - * @edid: EDID data - * @info: display info (attached to connector) - * - * Grab any available display info and stuff it into the drm_display_info - * structure that's part of the connector. Useful for tracking bpp and - * color spaces. - */ -static void drm_add_display_info(struct edid *edid, - struct drm_display_info *info) -{ - u8 *edid_ext; - - info->width_mm = edid->width_cm * 10; - info->height_mm = edid->height_cm * 10; - - /* driver figures it out in this case */ - info->bpc = 0; - info->color_formats = 0; - - /* Only defined for 1.4 with digital displays */ - if (edid->revision < 4) - return; - - if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) - return; - - switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { - case DRM_EDID_DIGITAL_DEPTH_6: - info->bpc = 6; - break; - case DRM_EDID_DIGITAL_DEPTH_8: - info->bpc = 8; - break; - case DRM_EDID_DIGITAL_DEPTH_10: - info->bpc = 10; - break; - case DRM_EDID_DIGITAL_DEPTH_12: - info->bpc = 12; - break; - case DRM_EDID_DIGITAL_DEPTH_14: - info->bpc = 14; - break; - case DRM_EDID_DIGITAL_DEPTH_16: - info->bpc = 16; - break; - case DRM_EDID_DIGITAL_DEPTH_UNDEF: - default: - info->bpc = 0; - break; - } - - info->color_formats = DRM_COLOR_FORMAT_RGB444; - if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB444) - info->color_formats = DRM_COLOR_FORMAT_YCRCB444; - if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422) - info->color_formats = DRM_COLOR_FORMAT_YCRCB422; - - /* Get data from CEA blocks if present */ - edid_ext = drm_find_cea_extension(edid); - if (!edid_ext) - return; - - info->cea_rev = edid_ext[1]; -} - -/** - * drm_add_edid_modes - add modes from EDID data, if available - * @connector: connector we're probing - * @edid: edid data - * - * Add the specified modes to the connector's mode list. - * - * Return number of modes added or 0 if we couldn't find any. - */ -int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) -{ - int num_modes = 0; - u32 quirks; - - if (edid == NULL) { - return 0; - } - if (!drm_edid_is_valid(edid)) { - dev_warn(connector->dev->dev, "%s: EDID invalid.\n", - drm_get_connector_name(connector)); - return 0; - } - - quirks = edid_get_quirks(edid); - - /* - * EDID spec says modes should be preferred in this order: - * - preferred detailed mode - * - other detailed modes from base block - * - detailed modes from extension blocks - * - CVT 3-byte code modes - * - standard timing codes - * - established timing codes - * - modes inferred from GTF or CVT range information - * - * We get this pretty much right. - * - * XXX order for additional mode types in extension blocks? - */ - num_modes += add_detailed_modes(connector, edid, quirks); - num_modes += add_cvt_modes(connector, edid); - num_modes += add_standard_modes(connector, edid); - num_modes += add_established_modes(connector, edid); - num_modes += add_inferred_modes(connector, edid); - num_modes += add_cea_modes(connector, edid); - - if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) - edid_fixup_preferred(connector, quirks); - - drm_add_display_info(edid, &connector->display_info); - - return num_modes; -} -EXPORT_SYMBOL(drm_add_edid_modes); - -/** - * drm_add_modes_noedid - add modes for the connectors without EDID - * @connector: connector we're probing - * @hdisplay: the horizontal display limit - * @vdisplay: the vertical display limit - * - * Add the specified modes to the connector's mode list. Only when the - * hdisplay/vdisplay is not beyond the given limit, it will be added. - * - * Return number of modes added or 0 if we couldn't find any. - */ -int drm_add_modes_noedid(struct drm_connector *connector, - int hdisplay, int vdisplay) -{ - int i, count, num_modes = 0; - struct drm_display_mode *mode; - struct drm_device *dev = connector->dev; - - count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); - if (hdisplay < 0) - hdisplay = 0; - if (vdisplay < 0) - vdisplay = 0; - - for (i = 0; i < count; i++) { - const struct drm_display_mode *ptr = &drm_dmt_modes[i]; - if (hdisplay && vdisplay) { - /* - * Only when two are valid, they will be used to check - * whether the mode should be added to the mode list of - * the connector. - */ - if (ptr->hdisplay > hdisplay || - ptr->vdisplay > vdisplay) - continue; - } - if (drm_mode_vrefresh(ptr) > 61) - continue; - mode = drm_mode_duplicate(dev, ptr); - if (mode) { - drm_mode_probed_add(connector, mode); - num_modes++; - } - } - return num_modes; -} -EXPORT_SYMBOL(drm_add_modes_noedid); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_edid_load.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_edid_load.c deleted file mode 100644 index da9acba2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_edid_load.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - drm_edid_load.c: use a built-in EDID data set or load it via the firmware - interface - - Copyright (C) 2012 Carsten Emde - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "drm_edid.h" - -static char edid_firmware[PATH_MAX]; -module_param_string(edid_firmware, edid_firmware, sizeof(edid_firmware), 0644); -MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob " - "from built-in data or /lib/firmware instead. "); - -#define GENERIC_EDIDS 4 -static char *generic_edid_name[GENERIC_EDIDS] = { - "edid/1024x768.bin", - "edid/1280x1024.bin", - "edid/1680x1050.bin", - "edid/1920x1080.bin", -}; - -static u8 generic_edid[GENERIC_EDIDS][128] = { - { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x16, 0x01, 0x03, 0x6d, 0x23, 0x1a, 0x78, - 0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25, - 0x20, 0x50, 0x54, 0x00, 0x08, 0x00, 0x61, 0x40, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x19, - 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x08, 0x90, - 0x36, 0x00, 0x63, 0x0a, 0x11, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b, - 0x3d, 0x2f, 0x31, 0x07, 0x00, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, - 0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x58, - 0x47, 0x41, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x55, - }, - { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x16, 0x01, 0x03, 0x6d, 0x2c, 0x23, 0x78, - 0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25, - 0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0x81, 0x80, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x30, 0x2a, - 0x00, 0x98, 0x51, 0x00, 0x2a, 0x40, 0x30, 0x70, - 0x13, 0x00, 0xbc, 0x63, 0x11, 0x00, 0x00, 0x1e, - 0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b, - 0x3d, 0x3e, 0x40, 0x0b, 0x00, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, - 0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x53, - 0x58, 0x47, 0x41, 0x0a, 0x20, 0x20, 0x00, 0xa0, - }, - { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x16, 0x01, 0x03, 0x6d, 0x2b, 0x1b, 0x78, - 0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25, - 0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xb3, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x21, 0x39, - 0x90, 0x30, 0x62, 0x1a, 0x27, 0x40, 0x68, 0xb0, - 0x36, 0x00, 0xb5, 0x11, 0x11, 0x00, 0x00, 0x1e, - 0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b, - 0x3d, 0x40, 0x42, 0x0f, 0x00, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, - 0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x57, - 0x53, 0x58, 0x47, 0x41, 0x0a, 0x20, 0x00, 0x26, - }, - { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x16, 0x01, 0x03, 0x6d, 0x32, 0x1c, 0x78, - 0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25, - 0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xd1, 0xc0, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, - 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, - 0x45, 0x00, 0xf4, 0x19, 0x11, 0x00, 0x00, 0x1e, - 0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b, - 0x3d, 0x42, 0x44, 0x0f, 0x00, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, - 0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x46, - 0x48, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x05, - }, -}; - -static int edid_load(struct drm_connector *connector, char *name, - char *connector_name) -{ - const struct firmware *fw; - struct platform_device *pdev; - u8 *fwdata = NULL, *edid; - int fwsize, expected; - int builtin = 0, err = 0; - int i, valid_extensions = 0; - - pdev = platform_device_register_simple(connector_name, -1, NULL, 0); - if (IS_ERR(pdev)) { - DRM_ERROR("Failed to register EDID firmware platform device " - "for connector \"%s\"\n", connector_name); - err = -EINVAL; - goto out; - } - - err = request_firmware(&fw, name, &pdev->dev); - platform_device_unregister(pdev); - - if (err) { - i = 0; - while (i < GENERIC_EDIDS && strcmp(name, generic_edid_name[i])) - i++; - if (i < GENERIC_EDIDS) { - err = 0; - builtin = 1; - fwdata = generic_edid[i]; - fwsize = sizeof(generic_edid[i]); - } - } - - if (err) { - DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n", - name, err); - goto out; - } - - if (fwdata == NULL) { - fwdata = (u8 *) fw->data; - fwsize = fw->size; - } - - expected = (fwdata[0x7e] + 1) * EDID_LENGTH; - if (expected != fwsize) { - DRM_ERROR("Size of EDID firmware \"%s\" is invalid " - "(expected %d, got %d)\n", name, expected, (int) fwsize); - err = -EINVAL; - goto relfw_out; - } - - edid = kmalloc(fwsize, GFP_KERNEL); - if (edid == NULL) { - err = -ENOMEM; - goto relfw_out; - } - memcpy(edid, fwdata, fwsize); - - if (!drm_edid_block_valid(edid)) { - DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ", - name); - kfree(edid); - err = -EINVAL; - goto relfw_out; - } - - for (i = 1; i <= edid[0x7e]; i++) { - if (i != valid_extensions + 1) - memcpy(edid + (valid_extensions + 1) * EDID_LENGTH, - edid + i * EDID_LENGTH, EDID_LENGTH); - if (drm_edid_block_valid(edid + i * EDID_LENGTH)) - valid_extensions++; - } - - if (valid_extensions != edid[0x7e]) { - edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions; - DRM_INFO("Found %d valid extensions instead of %d in EDID data " - "\"%s\" for connector \"%s\"\n", valid_extensions, - edid[0x7e], name, connector_name); - edid[0x7e] = valid_extensions; - edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, - GFP_KERNEL); - if (edid == NULL) { - err = -ENOMEM; - goto relfw_out; - } - } - - connector->display_info.raw_edid = edid; - DRM_INFO("Got %s EDID base block and %d extension%s from " - "\"%s\" for connector \"%s\"\n", builtin ? "built-in" : - "external", valid_extensions, valid_extensions == 1 ? "" : "s", - name, connector_name); - -relfw_out: - release_firmware(fw); - -out: - return err; -} - -int drm_load_edid_firmware(struct drm_connector *connector) -{ - char *connector_name = drm_get_connector_name(connector); - char *edidname = edid_firmware, *last, *colon; - int ret = 0; - - if (*edidname == '\0') - return ret; - - colon = strchr(edidname, ':'); - if (colon != NULL) { - if (strncmp(connector_name, edidname, colon - edidname)) - return ret; - edidname = colon + 1; - if (*edidname == '\0') - return ret; - } - - last = edidname + strlen(edidname) - 1; - if (*last == '\n') - *last = '\0'; - - ret = edid_load(connector, edidname, connector_name); - if (ret) - return 0; - - drm_mode_connector_update_edid_property(connector, - (struct edid *) connector->display_info.raw_edid); - - return drm_add_edid_modes(connector, (struct edid *) - connector->display_info.raw_edid); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_edid_modes.h b/ANDROID_3.4.5/drivers/gpu/drm/drm_edid_modes.h deleted file mode 100644 index a91ffb11..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_edid_modes.h +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Copyright (c) 2007-2008 Intel Corporation - * Jesse Barnes - * Copyright 2010 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" -#include "drm_edid.h" - -/* - * Autogenerated from the DMT spec. - * This table is copied from xfree86/modes/xf86EdidModes.c. - * But the mode with Reduced blank feature is deleted. - */ -static const struct drm_display_mode drm_dmt_modes[] = { - /* 640x350@85Hz */ - { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, - 736, 832, 0, 350, 382, 385, 445, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 640x400@85Hz */ - { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, - 736, 832, 0, 400, 401, 404, 445, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 720x400@85Hz */ - { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756, - 828, 936, 0, 400, 401, 404, 446, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 640x480@60Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, - 752, 800, 0, 480, 489, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 640x480@72Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, - 704, 832, 0, 480, 489, 492, 520, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 640x480@75Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656, - 720, 840, 0, 480, 481, 484, 500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 640x480@85Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696, - 752, 832, 0, 480, 481, 484, 509, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 800x600@56Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824, - 896, 1024, 0, 600, 601, 603, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 800x600@60Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, - 968, 1056, 0, 600, 601, 605, 628, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 800x600@72Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856, - 976, 1040, 0, 600, 637, 643, 666, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 800x600@75Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816, - 896, 1056, 0, 600, 601, 604, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 800x600@85Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832, - 896, 1048, 0, 600, 601, 604, 631, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 848x480@60Hz */ - { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864, - 976, 1088, 0, 480, 486, 494, 517, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1024x768@43Hz, interlace */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, - 1208, 1264, 0, 768, 768, 772, 817, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1024x768@60Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1024x768@70Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, - 1184, 1328, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1024x768@75Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040, - 1136, 1312, 0, 768, 769, 772, 800, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1024x768@85Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, - 1168, 1376, 0, 768, 769, 772, 808, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1152x864@75Hz */ - { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, - 1344, 1600, 0, 864, 865, 868, 900, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x768@60Hz */ - { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, - 1472, 1664, 0, 768, 771, 778, 798, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x768@75Hz */ - { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360, - 1488, 1696, 0, 768, 771, 778, 805, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1280x768@85Hz */ - { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360, - 1496, 1712, 0, 768, 771, 778, 809, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x800@60Hz */ - { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, - 1480, 1680, 0, 800, 803, 809, 831, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1280x800@75Hz */ - { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360, - 1488, 1696, 0, 800, 803, 809, 838, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x800@85Hz */ - { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360, - 1496, 1712, 0, 800, 803, 809, 843, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x960@60Hz */ - { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, - 1488, 1800, 0, 960, 961, 964, 1000, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x960@85Hz */ - { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344, - 1504, 1728, 0, 960, 961, 964, 1011, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x1024@60Hz */ - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, - 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x1024@75Hz */ - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, - 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x1024@85Hz */ - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344, - 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1360x768@60Hz */ - { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, - 1536, 1792, 0, 768, 771, 777, 795, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x1050@60Hz */ - { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, - 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x1050@75Hz */ - { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504, - 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x1050@85Hz */ - { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504, - 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x900@60Hz */ - { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, - 1672, 1904, 0, 900, 903, 909, 934, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x900@75Hz */ - { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536, - 1688, 1936, 0, 900, 903, 909, 942, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x900@85Hz */ - { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544, - 1696, 1952, 0, 900, 903, 909, 948, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@60Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@65Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@70Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@75Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 202500, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@85Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1680x1050@60Hz */ - { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, - 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1680x1050@75Hz */ - { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800, - 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1680x1050@85Hz */ - { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808, - 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1792x1344@60Hz */ - { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, - 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1729x1344@75Hz */ - { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888, - 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1853x1392@60Hz */ - { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, - 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1856x1392@75Hz */ - { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984, - 2208, 2560, 0, 1392, 1395, 1399, 1500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1200@60Hz */ - { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, - 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1200@75Hz */ - { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056, - 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1200@85Hz */ - { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064, - 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1440@60Hz */ - { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, - 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1440@75Hz */ - { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064, - 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2560x1600@60Hz */ - { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, - 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2560x1600@75HZ */ - { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768, - 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2560x1600@85HZ */ - { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768, - 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -}; -static const int drm_num_dmt_modes = - sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); - -static const struct drm_display_mode edid_est_modes[] = { - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, - 968, 1056, 0, 600, 601, 605, 628, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@60Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824, - 896, 1024, 0, 600, 601, 603, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@56Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656, - 720, 840, 0, 480, 481, 484, 500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, - 704, 832, 0, 480, 489, 491, 520, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704, - 768, 864, 0, 480, 483, 486, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656, - 752, 800, 0, 480, 490, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */ - { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738, - 846, 900, 0, 400, 421, 423, 449, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 720x400@88Hz */ - { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738, - 846, 900, 0, 400, 412, 414, 449, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 720x400@70Hz */ - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, - 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040, - 1136, 1312, 0, 768, 769, 772, 800, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, - 1184, 1328, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@70Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 1024x768@60Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032, - 1208, 1264, 0, 768, 768, 776, 817, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_INTERLACE) }, /* 1024x768@43Hz */ - { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864, - 928, 1152, 0, 624, 625, 628, 667, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 832x624@75Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816, - 896, 1056, 0, 600, 601, 604, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@75Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856, - 976, 1040, 0, 600, 637, 643, 666, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 800x600@72Hz */ - { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, - 1344, 1600, 0, 864, 865, 868, 900, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ -}; - -static const struct { - short w; - short h; - short r; - short rb; -} est3_modes[] = { - /* byte 6 */ - { 640, 350, 85, 0 }, - { 640, 400, 85, 0 }, - { 720, 400, 85, 0 }, - { 640, 480, 85, 0 }, - { 848, 480, 60, 0 }, - { 800, 600, 85, 0 }, - { 1024, 768, 85, 0 }, - { 1152, 864, 75, 0 }, - /* byte 7 */ - { 1280, 768, 60, 1 }, - { 1280, 768, 60, 0 }, - { 1280, 768, 75, 0 }, - { 1280, 768, 85, 0 }, - { 1280, 960, 60, 0 }, - { 1280, 960, 85, 0 }, - { 1280, 1024, 60, 0 }, - { 1280, 1024, 85, 0 }, - /* byte 8 */ - { 1360, 768, 60, 0 }, - { 1440, 900, 60, 1 }, - { 1440, 900, 60, 0 }, - { 1440, 900, 75, 0 }, - { 1440, 900, 85, 0 }, - { 1400, 1050, 60, 1 }, - { 1400, 1050, 60, 0 }, - { 1400, 1050, 75, 0 }, - /* byte 9 */ - { 1400, 1050, 85, 0 }, - { 1680, 1050, 60, 1 }, - { 1680, 1050, 60, 0 }, - { 1680, 1050, 75, 0 }, - { 1680, 1050, 85, 0 }, - { 1600, 1200, 60, 0 }, - { 1600, 1200, 65, 0 }, - { 1600, 1200, 70, 0 }, - /* byte 10 */ - { 1600, 1200, 75, 0 }, - { 1600, 1200, 85, 0 }, - { 1792, 1344, 60, 0 }, - { 1792, 1344, 85, 0 }, - { 1856, 1392, 60, 0 }, - { 1856, 1392, 75, 0 }, - { 1920, 1200, 60, 1 }, - { 1920, 1200, 60, 0 }, - /* byte 11 */ - { 1920, 1200, 75, 0 }, - { 1920, 1200, 85, 0 }, - { 1920, 1440, 60, 0 }, - { 1920, 1440, 75, 0 }, -}; -static const int num_est3_modes = sizeof(est3_modes) / sizeof(est3_modes[0]); - -/* - * Probably taken from CEA-861 spec. - * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. - */ -static const struct drm_display_mode edid_cea_modes[] = { - /* 640x480@60Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, - 752, 800, 0, 480, 490, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x480@60Hz */ - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, - 798, 858, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x480@60Hz */ - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, - 798, 858, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1280x720@60Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390, - 1430, 1650, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080i@60Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, - 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x480i@60Hz */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x480i@60Hz */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x240@60Hz */ - { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 240, 244, 247, 262, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x240@60Hz */ - { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, - 1602, 1716, 0, 240, 244, 247, 262, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x480i@60Hz */ - { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, - 3204, 3432, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 2880x480i@60Hz */ - { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, - 3204, 3432, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 2880x240@60Hz */ - { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, - 3204, 3432, 0, 240, 244, 247, 262, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x240@60Hz */ - { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, - 3204, 3432, 0, 240, 244, 247, 262, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x480@60Hz */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, - 1596, 1716, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x480@60Hz */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, - 1596, 1716, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1920x1080@60Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, - 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 720x576@50Hz */ - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, - 796, 864, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x576@50Hz */ - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, - 796, 864, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1280x720@50Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720, - 1760, 1980, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080i@50Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, - 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x576i@50Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x576i@50Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x288@50Hz */ - { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 288, 290, 293, 312, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x288@50Hz */ - { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, - 1590, 1728, 0, 288, 290, 293, 312, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x576i@50Hz */ - { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, - 3180, 3456, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 2880x576i@50Hz */ - { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, - 3180, 3456, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 2880x288@50Hz */ - { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, - 3180, 3456, 0, 288, 290, 293, 312, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x288@50Hz */ - { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, - 3180, 3456, 0, 288, 290, 293, 312, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x576@50Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, - 1592, 1728, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x576@50Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, - 1592, 1728, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1920x1080@50Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, - 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@24Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558, - 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@25Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, - 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@30Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, - 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2880x480@60Hz */ - { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, - 3192, 3432, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x480@60Hz */ - { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, - 3192, 3432, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x576@50Hz */ - { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, - 3184, 3456, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2880x576@50Hz */ - { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, - 3184, 3456, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1920x1080i@50Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952, - 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1920x1080i@100Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, - 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1280x720@100Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720, - 1760, 1980, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 720x576@100Hz */ - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, - 796, 864, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x576@100Hz */ - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, - 796, 864, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x576i@100Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x576i@100Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1920x1080i@120Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, - 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1280x720@120Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390, - 1430, 1650, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 720x480@120Hz */ - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, - 798, 858, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x480@120Hz */ - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, - 798, 858, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x480i@120Hz */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x480i@120Hz */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 720x576@200Hz */ - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, - 796, 864, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x576@200Hz */ - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, - 796, 864, 0, 576, 581, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x576i@200Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x576i@200Hz */ - { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, - 1590, 1728, 0, 576, 580, 586, 625, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 720x480@240Hz */ - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, - 798, 858, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 720x480@240Hz */ - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, - 798, 858, 0, 480, 489, 495, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1440x480i@240 */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1440x480i@240 */ - { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, - 1602, 1716, 0, 480, 488, 494, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE) }, - /* 1280x720@24Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040, - 3080, 3300, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x720@25Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700, - 3740, 3960, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x720@30Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040, - 3080, 3300, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@120Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008, - 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@100Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448, - 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -}; -static const int drm_num_cea_modes = - sizeof (edid_cea_modes) / sizeof (edid_cea_modes[0]); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_encoder_slave.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_encoder_slave.c deleted file mode 100644 index fb943551..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_encoder_slave.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include - -#include "drm_encoder_slave.h" - -/** - * drm_i2c_encoder_init - Initialize an I2C slave encoder - * @dev: DRM device. - * @encoder: Encoder to be attached to the I2C device. You aren't - * required to have called drm_encoder_init() before. - * @adap: I2C adapter that will be used to communicate with - * the device. - * @info: Information that will be used to create the I2C device. - * Required fields are @addr and @type. - * - * Create an I2C device on the specified bus (the module containing its - * driver is transparently loaded) and attach it to the specified - * &drm_encoder_slave. The @slave_funcs field will be initialized with - * the hooks provided by the slave driver. - * - * If @info->platform_data is non-NULL it will be used as the initial - * slave config. - * - * Returns 0 on success or a negative errno on failure, in particular, - * -ENODEV is returned when no matching driver is found. - */ -int drm_i2c_encoder_init(struct drm_device *dev, - struct drm_encoder_slave *encoder, - struct i2c_adapter *adap, - const struct i2c_board_info *info) -{ - char modalias[sizeof(I2C_MODULE_PREFIX) - + I2C_NAME_SIZE]; - struct module *module = NULL; - struct i2c_client *client; - struct drm_i2c_encoder_driver *encoder_drv; - int err = 0; - - snprintf(modalias, sizeof(modalias), - "%s%s", I2C_MODULE_PREFIX, info->type); - request_module(modalias); - - client = i2c_new_device(adap, info); - if (!client) { - err = -ENOMEM; - goto fail; - } - - if (!client->driver) { - err = -ENODEV; - goto fail_unregister; - } - - module = client->driver->driver.owner; - if (!try_module_get(module)) { - err = -ENODEV; - goto fail_unregister; - } - - encoder->bus_priv = client; - - encoder_drv = to_drm_i2c_encoder_driver(client->driver); - - err = encoder_drv->encoder_init(client, dev, encoder); - if (err) - goto fail_unregister; - - if (info->platform_data) - encoder->slave_funcs->set_config(&encoder->base, - info->platform_data); - - return 0; - -fail_unregister: - i2c_unregister_device(client); - module_put(module); -fail: - return err; -} -EXPORT_SYMBOL(drm_i2c_encoder_init); - -/** - * drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder - * @drm_encoder: Encoder to be unregistered. - * - * This should be called from the @destroy method of an I2C slave - * encoder driver once I2C access is no longer needed. - */ -void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder) -{ - struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder); - struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder); - struct module *module = client->driver->driver.owner; - - i2c_unregister_device(client); - encoder->bus_priv = NULL; - - module_put(module); -} -EXPORT_SYMBOL(drm_i2c_encoder_destroy); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_fb_helper.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_fb_helper.c deleted file mode 100644 index a0d6e894..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_fb_helper.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* - * Copyright (c) 2006-2009 Red Hat Inc. - * Copyright (c) 2006-2008 Intel Corporation - * Copyright (c) 2007 Dave Airlie - * - * DRM framebuffer helper functions - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - * - * Authors: - * Dave Airlie - * Jesse Barnes - */ -#include -#include -#include -#include -#include -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_fb_helper.h" -#include "drm_crtc_helper.h" - -MODULE_AUTHOR("David Airlie, Jesse Barnes"); -MODULE_DESCRIPTION("DRM KMS helper"); -MODULE_LICENSE("GPL and additional rights"); - -static LIST_HEAD(kernel_fb_helper_list); - -/* simple single crtc case helper function */ -int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper) -{ - struct drm_device *dev = fb_helper->dev; - struct drm_connector *connector; - int i; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct drm_fb_helper_connector *fb_helper_connector; - - fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); - if (!fb_helper_connector) - goto fail; - - fb_helper_connector->connector = connector; - fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector; - } - return 0; -fail: - for (i = 0; i < fb_helper->connector_count; i++) { - kfree(fb_helper->connector_info[i]); - fb_helper->connector_info[i] = NULL; - } - fb_helper->connector_count = 0; - return -ENOMEM; -} -EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors); - -static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) -{ - struct drm_fb_helper_connector *fb_helper_conn; - int i; - - for (i = 0; i < fb_helper->connector_count; i++) { - struct drm_cmdline_mode *mode; - struct drm_connector *connector; - char *option = NULL; - - fb_helper_conn = fb_helper->connector_info[i]; - connector = fb_helper_conn->connector; - mode = &fb_helper_conn->cmdline_mode; - - /* do something on return - turn off connector maybe */ - if (fb_get_options(drm_get_connector_name(connector), &option)) - continue; - - if (drm_mode_parse_command_line_for_connector(option, - connector, - mode)) { - if (mode->force) { - const char *s; - switch (mode->force) { - case DRM_FORCE_OFF: s = "OFF"; break; - case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break; - default: - case DRM_FORCE_ON: s = "ON"; break; - } - - DRM_INFO("forcing %s connector %s\n", - drm_get_connector_name(connector), s); - connector->force = mode->force; - } - - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", - drm_get_connector_name(connector), - mode->xres, mode->yres, - mode->refresh_specified ? mode->refresh : 60, - mode->rb ? " reduced blanking" : "", - mode->margins ? " with margins" : "", - mode->interlace ? " interlaced" : ""); - } - - } - return 0; -} - -static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper) -{ - uint16_t *r_base, *g_base, *b_base; - int i; - - r_base = crtc->gamma_store; - g_base = r_base + crtc->gamma_size; - b_base = g_base + crtc->gamma_size; - - for (i = 0; i < crtc->gamma_size; i++) - helper->funcs->gamma_get(crtc, &r_base[i], &g_base[i], &b_base[i], i); -} - -static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) -{ - uint16_t *r_base, *g_base, *b_base; - - r_base = crtc->gamma_store; - g_base = r_base + crtc->gamma_size; - b_base = g_base + crtc->gamma_size; - - crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); -} - -int drm_fb_helper_debug_enter(struct fb_info *info) -{ - struct drm_fb_helper *helper = info->par; - struct drm_crtc_helper_funcs *funcs; - int i; - - if (list_empty(&kernel_fb_helper_list)) - return false; - - list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { - for (i = 0; i < helper->crtc_count; i++) { - struct drm_mode_set *mode_set = - &helper->crtc_info[i].mode_set; - - if (!mode_set->crtc->enabled) - continue; - - funcs = mode_set->crtc->helper_private; - drm_fb_helper_save_lut_atomic(mode_set->crtc, helper); - funcs->mode_set_base_atomic(mode_set->crtc, - mode_set->fb, - mode_set->x, - mode_set->y, - ENTER_ATOMIC_MODE_SET); - } - } - - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_debug_enter); - -/* Find the real fb for a given fb helper CRTC */ -static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_crtc *c; - - list_for_each_entry(c, &dev->mode_config.crtc_list, head) { - if (crtc->base.id == c->base.id) - return c->fb; - } - - return NULL; -} - -int drm_fb_helper_debug_leave(struct fb_info *info) -{ - struct drm_fb_helper *helper = info->par; - struct drm_crtc *crtc; - struct drm_crtc_helper_funcs *funcs; - struct drm_framebuffer *fb; - int i; - - for (i = 0; i < helper->crtc_count; i++) { - struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; - crtc = mode_set->crtc; - funcs = crtc->helper_private; - fb = drm_mode_config_fb(crtc); - - if (!crtc->enabled) - continue; - - if (!fb) { - DRM_ERROR("no fb to restore??\n"); - continue; - } - - drm_fb_helper_restore_lut_atomic(mode_set->crtc); - funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x, - crtc->y, LEAVE_ATOMIC_MODE_SET); - } - - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_debug_leave); - -bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) -{ - bool error = false; - int i, ret; - for (i = 0; i < fb_helper->crtc_count; i++) { - struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; - ret = drm_crtc_helper_set_config(mode_set); - if (ret) - error = true; - } - return error; -} -EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); - -bool drm_fb_helper_force_kernel_mode(void) -{ - bool ret, error = false; - struct drm_fb_helper *helper; - - if (list_empty(&kernel_fb_helper_list)) - return false; - - list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { - if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) - continue; - - ret = drm_fb_helper_restore_fbdev_mode(helper); - if (ret) - error = true; - } - return error; -} - -int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed, - void *panic_str) -{ - /* - * It's a waste of time and effort to switch back to text console - * if the kernel should reboot before panic messages can be seen. - */ - if (panic_timeout < 0) - return 0; - - printk(KERN_ERR "panic occurred, switching back to text console\n"); - return drm_fb_helper_force_kernel_mode(); -} -EXPORT_SYMBOL(drm_fb_helper_panic); - -static struct notifier_block paniced = { - .notifier_call = drm_fb_helper_panic, -}; - -/** - * drm_fb_helper_restore - restore the framebuffer console (kernel) config - * - * Restore's the kernel's fbcon mode, used for lastclose & panic paths. - */ -void drm_fb_helper_restore(void) -{ - bool ret; - ret = drm_fb_helper_force_kernel_mode(); - if (ret == true) - DRM_ERROR("Failed to restore crtc configuration\n"); -} -EXPORT_SYMBOL(drm_fb_helper_restore); - -#ifdef CONFIG_MAGIC_SYSRQ -static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) -{ - drm_fb_helper_restore(); -} -static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); - -static void drm_fb_helper_sysrq(int dummy1) -{ - schedule_work(&drm_fb_helper_restore_work); -} - -static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { - .handler = drm_fb_helper_sysrq, - .help_msg = "force-fb(V)", - .action_msg = "Restore framebuffer console", -}; -#else -static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; -#endif - -static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_device *dev = fb_helper->dev; - struct drm_crtc *crtc; - struct drm_connector *connector; - int i, j; - - /* - * For each CRTC in this fb, turn the connectors on/off. - */ - mutex_lock(&dev->mode_config.mutex); - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; - - if (!crtc->enabled) - continue; - - /* Walk the connectors & encoders on this fb turning them on/off */ - for (j = 0; j < fb_helper->connector_count; j++) { - connector = fb_helper->connector_info[j]->connector; - drm_helper_connector_dpms(connector, dpms_mode); - drm_connector_property_set_value(connector, - dev->mode_config.dpms_property, dpms_mode); - } - } - mutex_unlock(&dev->mode_config.mutex); -} - -int drm_fb_helper_blank(int blank, struct fb_info *info) -{ - switch (blank) { - /* Display: On; HSync: On, VSync: On */ - case FB_BLANK_UNBLANK: - drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON); - break; - /* Display: Off; HSync: On, VSync: On */ - case FB_BLANK_NORMAL: - drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); - break; - /* Display: Off; HSync: Off, VSync: On */ - case FB_BLANK_HSYNC_SUSPEND: - drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); - break; - /* Display: Off; HSync: On, VSync: Off */ - case FB_BLANK_VSYNC_SUSPEND: - drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND); - break; - /* Display: Off; HSync: Off, VSync: Off */ - case FB_BLANK_POWERDOWN: - drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF); - break; - } - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_blank); - -static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) -{ - int i; - - for (i = 0; i < helper->connector_count; i++) - kfree(helper->connector_info[i]); - kfree(helper->connector_info); - for (i = 0; i < helper->crtc_count; i++) { - kfree(helper->crtc_info[i].mode_set.connectors); - if (helper->crtc_info[i].mode_set.mode) - drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode); - } - kfree(helper->crtc_info); -} - -int drm_fb_helper_init(struct drm_device *dev, - struct drm_fb_helper *fb_helper, - int crtc_count, int max_conn_count) -{ - struct drm_crtc *crtc; - int ret = 0; - int i; - - fb_helper->dev = dev; - - INIT_LIST_HEAD(&fb_helper->kernel_fb_list); - - fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL); - if (!fb_helper->crtc_info) - return -ENOMEM; - - fb_helper->crtc_count = crtc_count; - fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL); - if (!fb_helper->connector_info) { - kfree(fb_helper->crtc_info); - return -ENOMEM; - } - fb_helper->connector_count = 0; - - for (i = 0; i < crtc_count; i++) { - fb_helper->crtc_info[i].mode_set.connectors = - kcalloc(max_conn_count, - sizeof(struct drm_connector *), - GFP_KERNEL); - - if (!fb_helper->crtc_info[i].mode_set.connectors) { - ret = -ENOMEM; - goto out_free; - } - fb_helper->crtc_info[i].mode_set.num_connectors = 0; - } - - i = 0; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - fb_helper->crtc_info[i].mode_set.crtc = crtc; - i++; - } - - return 0; -out_free: - drm_fb_helper_crtc_free(fb_helper); - return -ENOMEM; -} -EXPORT_SYMBOL(drm_fb_helper_init); - -void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) -{ - if (!list_empty(&fb_helper->kernel_fb_list)) { - list_del(&fb_helper->kernel_fb_list); - if (list_empty(&kernel_fb_helper_list)) { - printk(KERN_INFO "drm: unregistered panic notifier\n"); - atomic_notifier_chain_unregister(&panic_notifier_list, - &paniced); - unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); - } - } - - drm_fb_helper_crtc_free(fb_helper); - -} -EXPORT_SYMBOL(drm_fb_helper_fini); - -static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, u16 regno, struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_framebuffer *fb = fb_helper->fb; - int pindex; - - if (info->fix.visual == FB_VISUAL_TRUECOLOR) { - u32 *palette; - u32 value; - /* place color in psuedopalette */ - if (regno > 16) - return -EINVAL; - palette = (u32 *)info->pseudo_palette; - red >>= (16 - info->var.red.length); - green >>= (16 - info->var.green.length); - blue >>= (16 - info->var.blue.length); - value = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); - if (info->var.transp.length > 0) { - u32 mask = (1 << info->var.transp.length) - 1; - mask <<= info->var.transp.offset; - value |= mask; - } - palette[regno] = value; - return 0; - } - - pindex = regno; - - if (fb->bits_per_pixel == 16) { - pindex = regno << 3; - - if (fb->depth == 16 && regno > 63) - return -EINVAL; - if (fb->depth == 15 && regno > 31) - return -EINVAL; - - if (fb->depth == 16) { - u16 r, g, b; - int i; - if (regno < 32) { - for (i = 0; i < 8; i++) - fb_helper->funcs->gamma_set(crtc, red, - green, blue, pindex + i); - } - - fb_helper->funcs->gamma_get(crtc, &r, - &g, &b, - pindex >> 1); - - for (i = 0; i < 4; i++) - fb_helper->funcs->gamma_set(crtc, r, - green, b, - (pindex >> 1) + i); - } - } - - if (fb->depth != 16) - fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex); - return 0; -} - -int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_crtc_helper_funcs *crtc_funcs; - u16 *red, *green, *blue, *transp; - struct drm_crtc *crtc; - int i, j, rc = 0; - int start; - - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; - crtc_funcs = crtc->helper_private; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; - - for (j = 0; j < cmap->len; j++) { - u16 hred, hgreen, hblue, htransp = 0xffff; - - hred = *red++; - hgreen = *green++; - hblue = *blue++; - - if (transp) - htransp = *transp++; - - rc = setcolreg(crtc, hred, hgreen, hblue, start++, info); - if (rc) - return rc; - } - crtc_funcs->load_lut(crtc); - } - return rc; -} -EXPORT_SYMBOL(drm_fb_helper_setcmap); - -int drm_fb_helper_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_framebuffer *fb = fb_helper->fb; - int depth; - - if (var->pixclock != 0 || in_dbg_master()) - return -EINVAL; - - /* Need to resize the fb object !!! */ - if (var->bits_per_pixel > fb->bits_per_pixel || - var->xres > fb->width || var->yres > fb->height || - var->xres_virtual > fb->width || var->yres_virtual > fb->height) { - DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb " - "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n", - var->xres, var->yres, var->bits_per_pixel, - var->xres_virtual, var->yres_virtual, - fb->width, fb->height, fb->bits_per_pixel); - return -EINVAL; - } - - switch (var->bits_per_pixel) { - case 16: - depth = (var->green.length == 6) ? 16 : 15; - break; - case 32: - depth = (var->transp.length > 0) ? 32 : 24; - break; - default: - depth = var->bits_per_pixel; - break; - } - - switch (depth) { - case 8: - var->red.offset = 0; - var->green.offset = 0; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 0; - var->transp.offset = 0; - break; - case 15: - var->red.offset = 10; - var->green.offset = 5; - var->blue.offset = 0; - var->red.length = 5; - var->green.length = 5; - var->blue.length = 5; - var->transp.length = 1; - var->transp.offset = 15; - break; - case 16: - var->red.offset = 11; - var->green.offset = 5; - var->blue.offset = 0; - var->red.length = 5; - var->green.length = 6; - var->blue.length = 5; - var->transp.length = 0; - var->transp.offset = 0; - break; - case 24: - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 0; - var->transp.offset = 0; - break; - case 32: - var->red.offset = 16; - var->green.offset = 8; - var->blue.offset = 0; - var->red.length = 8; - var->green.length = 8; - var->blue.length = 8; - var->transp.length = 8; - var->transp.offset = 24; - break; - default: - return -EINVAL; - } - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_check_var); - -/* this will let fbcon do the mode init */ -int drm_fb_helper_set_par(struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_device *dev = fb_helper->dev; - struct fb_var_screeninfo *var = &info->var; - struct drm_crtc *crtc; - int ret; - int i; - - if (var->pixclock != 0) { - DRM_ERROR("PIXEL CLOCK SET\n"); - return -EINVAL; - } - - mutex_lock(&dev->mode_config.mutex); - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; - ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); - if (ret) { - mutex_unlock(&dev->mode_config.mutex); - return ret; - } - } - mutex_unlock(&dev->mode_config.mutex); - - if (fb_helper->delayed_hotplug) { - fb_helper->delayed_hotplug = false; - drm_fb_helper_hotplug_event(fb_helper); - } - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_set_par); - -int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_device *dev = fb_helper->dev; - struct drm_mode_set *modeset; - struct drm_crtc *crtc; - int ret = 0; - int i; - - mutex_lock(&dev->mode_config.mutex); - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; - - modeset = &fb_helper->crtc_info[i].mode_set; - - modeset->x = var->xoffset; - modeset->y = var->yoffset; - - if (modeset->num_connectors) { - ret = crtc->funcs->set_config(modeset); - if (!ret) { - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - } - } - } - mutex_unlock(&dev->mode_config.mutex); - return ret; -} -EXPORT_SYMBOL(drm_fb_helper_pan_display); - -int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, - int preferred_bpp) -{ - int new_fb = 0; - int crtc_count = 0; - int i; - struct fb_info *info; - struct drm_fb_helper_surface_size sizes; - int gamma_size = 0; - - memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size)); - sizes.surface_depth = 24; - sizes.surface_bpp = 32; - sizes.fb_width = (unsigned)-1; - sizes.fb_height = (unsigned)-1; - - /* if driver picks 8 or 16 by default use that - for both depth/bpp */ - if (preferred_bpp != sizes.surface_bpp) { - sizes.surface_depth = sizes.surface_bpp = preferred_bpp; - } - /* first up get a count of crtcs now in use and new min/maxes width/heights */ - for (i = 0; i < fb_helper->connector_count; i++) { - struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; - struct drm_cmdline_mode *cmdline_mode; - - cmdline_mode = &fb_helper_conn->cmdline_mode; - - if (cmdline_mode->bpp_specified) { - switch (cmdline_mode->bpp) { - case 8: - sizes.surface_depth = sizes.surface_bpp = 8; - break; - case 15: - sizes.surface_depth = 15; - sizes.surface_bpp = 16; - break; - case 16: - sizes.surface_depth = sizes.surface_bpp = 16; - break; - case 24: - sizes.surface_depth = sizes.surface_bpp = 24; - break; - case 32: - sizes.surface_depth = 24; - sizes.surface_bpp = 32; - break; - } - break; - } - } - - crtc_count = 0; - for (i = 0; i < fb_helper->crtc_count; i++) { - struct drm_display_mode *desired_mode; - desired_mode = fb_helper->crtc_info[i].desired_mode; - - if (desired_mode) { - if (gamma_size == 0) - gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size; - if (desired_mode->hdisplay < sizes.fb_width) - sizes.fb_width = desired_mode->hdisplay; - if (desired_mode->vdisplay < sizes.fb_height) - sizes.fb_height = desired_mode->vdisplay; - if (desired_mode->hdisplay > sizes.surface_width) - sizes.surface_width = desired_mode->hdisplay; - if (desired_mode->vdisplay > sizes.surface_height) - sizes.surface_height = desired_mode->vdisplay; - crtc_count++; - } - } - - if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) { - /* hmm everyone went away - assume VGA cable just fell out - and will come back later. */ - DRM_INFO("Cannot find any crtc or sizes - going 1024x768\n"); - sizes.fb_width = sizes.surface_width = 1024; - sizes.fb_height = sizes.surface_height = 768; - } - - /* push down into drivers */ - new_fb = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes); - if (new_fb < 0) - return new_fb; - - info = fb_helper->fbdev; - - /* set the fb pointer */ - for (i = 0; i < fb_helper->crtc_count; i++) { - fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb; - } - - if (new_fb) { - info->var.pixclock = 0; - if (register_framebuffer(info) < 0) { - return -EINVAL; - } - - printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, - info->fix.id); - - } else { - drm_fb_helper_set_par(info); - } - - /* Switch back to kernel console on panic */ - /* multi card linked list maybe */ - if (list_empty(&kernel_fb_helper_list)) { - printk(KERN_INFO "drm: registered panic notifier\n"); - atomic_notifier_chain_register(&panic_notifier_list, - &paniced); - register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); - } - if (new_fb) - list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); - - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_single_fb_probe); - -void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, - uint32_t depth) -{ - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : - FB_VISUAL_TRUECOLOR; - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; - info->fix.type_aux = 0; - info->fix.xpanstep = 1; /* doing it in hw */ - info->fix.ypanstep = 1; /* doing it in hw */ - info->fix.ywrapstep = 0; - info->fix.accel = FB_ACCEL_NONE; - info->fix.type_aux = 0; - - info->fix.line_length = pitch; - return; -} -EXPORT_SYMBOL(drm_fb_helper_fill_fix); - -void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper, - uint32_t fb_width, uint32_t fb_height) -{ - struct drm_framebuffer *fb = fb_helper->fb; - info->pseudo_palette = fb_helper->pseudo_palette; - info->var.xres_virtual = fb->width; - info->var.yres_virtual = fb->height; - info->var.bits_per_pixel = fb->bits_per_pixel; - info->var.accel_flags = FB_ACCELF_TEXT; - info->var.xoffset = 0; - info->var.yoffset = 0; - info->var.activate = FB_ACTIVATE_NOW; - info->var.height = -1; - info->var.width = -1; - - switch (fb->depth) { - case 8: - info->var.red.offset = 0; - info->var.green.offset = 0; - info->var.blue.offset = 0; - info->var.red.length = 8; /* 8bit DAC */ - info->var.green.length = 8; - info->var.blue.length = 8; - info->var.transp.offset = 0; - info->var.transp.length = 0; - break; - case 15: - info->var.red.offset = 10; - info->var.green.offset = 5; - info->var.blue.offset = 0; - info->var.red.length = 5; - info->var.green.length = 5; - info->var.blue.length = 5; - info->var.transp.offset = 15; - info->var.transp.length = 1; - break; - case 16: - info->var.red.offset = 11; - info->var.green.offset = 5; - info->var.blue.offset = 0; - info->var.red.length = 5; - info->var.green.length = 6; - info->var.blue.length = 5; - info->var.transp.offset = 0; - break; - case 24: - info->var.red.offset = 16; - info->var.green.offset = 8; - info->var.blue.offset = 0; - info->var.red.length = 8; - info->var.green.length = 8; - info->var.blue.length = 8; - info->var.transp.offset = 0; - info->var.transp.length = 0; - break; - case 32: - info->var.red.offset = 16; - info->var.green.offset = 8; - info->var.blue.offset = 0; - info->var.red.length = 8; - info->var.green.length = 8; - info->var.blue.length = 8; - info->var.transp.offset = 24; - info->var.transp.length = 8; - break; - default: - break; - } - - info->var.xres = fb_width; - info->var.yres = fb_height; -} -EXPORT_SYMBOL(drm_fb_helper_fill_var); - -static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper, - uint32_t maxX, - uint32_t maxY) -{ - struct drm_connector *connector; - int count = 0; - int i; - - for (i = 0; i < fb_helper->connector_count; i++) { - connector = fb_helper->connector_info[i]->connector; - count += connector->funcs->fill_modes(connector, maxX, maxY); - } - - return count; -} - -static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height) -{ - struct drm_display_mode *mode; - - list_for_each_entry(mode, &fb_connector->connector->modes, head) { - if (drm_mode_width(mode) > width || - drm_mode_height(mode) > height) - continue; - if (mode->type & DRM_MODE_TYPE_PREFERRED) - return mode; - } - return NULL; -} - -static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) -{ - struct drm_cmdline_mode *cmdline_mode; - cmdline_mode = &fb_connector->cmdline_mode; - return cmdline_mode->specified; -} - -static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, - int width, int height) -{ - struct drm_cmdline_mode *cmdline_mode; - struct drm_display_mode *mode = NULL; - - cmdline_mode = &fb_helper_conn->cmdline_mode; - if (cmdline_mode->specified == false) - return mode; - - /* attempt to find a matching mode in the list of modes - * we have gotten so far, if not add a CVT mode that conforms - */ - if (cmdline_mode->rb || cmdline_mode->margins) - goto create_mode; - - list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { - /* check width/height */ - if (mode->hdisplay != cmdline_mode->xres || - mode->vdisplay != cmdline_mode->yres) - continue; - - if (cmdline_mode->refresh_specified) { - if (mode->vrefresh != cmdline_mode->refresh) - continue; - } - - if (cmdline_mode->interlace) { - if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) - continue; - } - return mode; - } - -create_mode: - mode = drm_mode_create_from_cmdline_mode(fb_helper_conn->connector->dev, - cmdline_mode); - list_add(&mode->head, &fb_helper_conn->connector->modes); - return mode; -} - -static bool drm_connector_enabled(struct drm_connector *connector, bool strict) -{ - bool enable; - - if (strict) { - enable = connector->status == connector_status_connected; - } else { - enable = connector->status != connector_status_disconnected; - } - return enable; -} - -static void drm_enable_connectors(struct drm_fb_helper *fb_helper, - bool *enabled) -{ - bool any_enabled = false; - struct drm_connector *connector; - int i = 0; - - for (i = 0; i < fb_helper->connector_count; i++) { - connector = fb_helper->connector_info[i]->connector; - enabled[i] = drm_connector_enabled(connector, true); - DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id, - enabled[i] ? "yes" : "no"); - any_enabled |= enabled[i]; - } - - if (any_enabled) - return; - - for (i = 0; i < fb_helper->connector_count; i++) { - connector = fb_helper->connector_info[i]->connector; - enabled[i] = drm_connector_enabled(connector, false); - } -} - -static bool drm_target_cloned(struct drm_fb_helper *fb_helper, - struct drm_display_mode **modes, - bool *enabled, int width, int height) -{ - int count, i, j; - bool can_clone = false; - struct drm_fb_helper_connector *fb_helper_conn; - struct drm_display_mode *dmt_mode, *mode; - - /* only contemplate cloning in the single crtc case */ - if (fb_helper->crtc_count > 1) - return false; - - count = 0; - for (i = 0; i < fb_helper->connector_count; i++) { - if (enabled[i]) - count++; - } - - /* only contemplate cloning if more than one connector is enabled */ - if (count <= 1) - return false; - - /* check the command line or if nothing common pick 1024x768 */ - can_clone = true; - for (i = 0; i < fb_helper->connector_count; i++) { - if (!enabled[i]) - continue; - fb_helper_conn = fb_helper->connector_info[i]; - modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height); - if (!modes[i]) { - can_clone = false; - break; - } - for (j = 0; j < i; j++) { - if (!enabled[j]) - continue; - if (!drm_mode_equal(modes[j], modes[i])) - can_clone = false; - } - } - - if (can_clone) { - DRM_DEBUG_KMS("can clone using command line\n"); - return true; - } - - /* try and find a 1024x768 mode on each connector */ - can_clone = true; - dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60); - - for (i = 0; i < fb_helper->connector_count; i++) { - - if (!enabled[i]) - continue; - - fb_helper_conn = fb_helper->connector_info[i]; - list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) { - if (drm_mode_equal(mode, dmt_mode)) - modes[i] = mode; - } - if (!modes[i]) - can_clone = false; - } - - if (can_clone) { - DRM_DEBUG_KMS("can clone using 1024x768\n"); - return true; - } - DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); - return false; -} - -static bool drm_target_preferred(struct drm_fb_helper *fb_helper, - struct drm_display_mode **modes, - bool *enabled, int width, int height) -{ - struct drm_fb_helper_connector *fb_helper_conn; - int i; - - for (i = 0; i < fb_helper->connector_count; i++) { - fb_helper_conn = fb_helper->connector_info[i]; - - if (enabled[i] == false) - continue; - - DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", - fb_helper_conn->connector->base.id); - - /* got for command line mode first */ - modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height); - if (!modes[i]) { - DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", - fb_helper_conn->connector->base.id); - modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height); - } - /* No preferred modes, pick one off the list */ - if (!modes[i] && !list_empty(&fb_helper_conn->connector->modes)) { - list_for_each_entry(modes[i], &fb_helper_conn->connector->modes, head) - break; - } - DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : - "none"); - } - return true; -} - -static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_crtc **best_crtcs, - struct drm_display_mode **modes, - int n, int width, int height) -{ - int c, o; - struct drm_device *dev = fb_helper->dev; - struct drm_connector *connector; - struct drm_connector_helper_funcs *connector_funcs; - struct drm_encoder *encoder; - struct drm_fb_helper_crtc *best_crtc; - int my_score, best_score, score; - struct drm_fb_helper_crtc **crtcs, *crtc; - struct drm_fb_helper_connector *fb_helper_conn; - - if (n == fb_helper->connector_count) - return 0; - - fb_helper_conn = fb_helper->connector_info[n]; - connector = fb_helper_conn->connector; - - best_crtcs[n] = NULL; - best_crtc = NULL; - best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height); - if (modes[n] == NULL) - return best_score; - - crtcs = kzalloc(dev->mode_config.num_connector * - sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); - if (!crtcs) - return best_score; - - my_score = 1; - if (connector->status == connector_status_connected) - my_score++; - if (drm_has_cmdline_mode(fb_helper_conn)) - my_score++; - if (drm_has_preferred_mode(fb_helper_conn, width, height)) - my_score++; - - connector_funcs = connector->helper_private; - encoder = connector_funcs->best_encoder(connector); - if (!encoder) - goto out; - - /* select a crtc for this connector and then attempt to configure - remaining connectors */ - for (c = 0; c < fb_helper->crtc_count; c++) { - crtc = &fb_helper->crtc_info[c]; - - if ((encoder->possible_crtcs & (1 << c)) == 0) { - continue; - } - - for (o = 0; o < n; o++) - if (best_crtcs[o] == crtc) - break; - - if (o < n) { - /* ignore cloning unless only a single crtc */ - if (fb_helper->crtc_count > 1) - continue; - - if (!drm_mode_equal(modes[o], modes[n])) - continue; - } - - crtcs[n] = crtc; - memcpy(crtcs, best_crtcs, n * sizeof(struct drm_fb_helper_crtc *)); - score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1, - width, height); - if (score > best_score) { - best_crtc = crtc; - best_score = score; - memcpy(best_crtcs, crtcs, - dev->mode_config.num_connector * - sizeof(struct drm_fb_helper_crtc *)); - } - } -out: - kfree(crtcs); - return best_score; -} - -static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) -{ - struct drm_device *dev = fb_helper->dev; - struct drm_fb_helper_crtc **crtcs; - struct drm_display_mode **modes; - struct drm_encoder *encoder; - struct drm_mode_set *modeset; - bool *enabled; - int width, height; - int i, ret; - - DRM_DEBUG_KMS("\n"); - - width = dev->mode_config.max_width; - height = dev->mode_config.max_height; - - /* clean out all the encoder/crtc combos */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - encoder->crtc = NULL; - } - - crtcs = kcalloc(dev->mode_config.num_connector, - sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); - modes = kcalloc(dev->mode_config.num_connector, - sizeof(struct drm_display_mode *), GFP_KERNEL); - enabled = kcalloc(dev->mode_config.num_connector, - sizeof(bool), GFP_KERNEL); - - drm_enable_connectors(fb_helper, enabled); - - ret = drm_target_cloned(fb_helper, modes, enabled, width, height); - if (!ret) { - ret = drm_target_preferred(fb_helper, modes, enabled, width, height); - if (!ret) - DRM_ERROR("Unable to find initial modes\n"); - } - - DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height); - - drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height); - - /* need to set the modesets up here for use later */ - /* fill out the connector<->crtc mappings into the modesets */ - for (i = 0; i < fb_helper->crtc_count; i++) { - modeset = &fb_helper->crtc_info[i].mode_set; - modeset->num_connectors = 0; - } - - for (i = 0; i < fb_helper->connector_count; i++) { - struct drm_display_mode *mode = modes[i]; - struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; - modeset = &fb_crtc->mode_set; - - if (mode && fb_crtc) { - DRM_DEBUG_KMS("desired mode %s set on crtc %d\n", - mode->name, fb_crtc->mode_set.crtc->base.id); - fb_crtc->desired_mode = mode; - if (modeset->mode) - drm_mode_destroy(dev, modeset->mode); - modeset->mode = drm_mode_duplicate(dev, - fb_crtc->desired_mode); - modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector; - } - } - - kfree(crtcs); - kfree(modes); - kfree(enabled); -} - -/** - * drm_helper_initial_config - setup a sane initial connector configuration - * @dev: DRM device - * - * LOCKING: - * Called at init time, must take mode config lock. - * - * Scan the CRTCs and connectors and try to put together an initial setup. - * At the moment, this is a cloned configuration across all heads with - * a new framebuffer object as the backing store. - * - * RETURNS: - * Zero if everything went ok, nonzero otherwise. - */ -bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) -{ - struct drm_device *dev = fb_helper->dev; - int count = 0; - - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(fb_helper->dev); - - drm_fb_helper_parse_command_line(fb_helper); - - count = drm_fb_helper_probe_connector_modes(fb_helper, - dev->mode_config.max_width, - dev->mode_config.max_height); - /* - * we shouldn't end up with no modes here. - */ - if (count == 0) { - printk(KERN_INFO "No connectors reported connected with modes\n"); - } - drm_setup_crtcs(fb_helper); - - return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); -} -EXPORT_SYMBOL(drm_fb_helper_initial_config); - -/** - * drm_fb_helper_hotplug_event - respond to a hotplug notification by - * probing all the outputs attached to the fb. - * @fb_helper: the drm_fb_helper - * - * LOCKING: - * Called at runtime, must take mode config lock. - * - * Scan the connectors attached to the fb_helper and try to put together a - * setup after *notification of a change in output configuration. - * - * RETURNS: - * 0 on success and a non-zero error code otherwise. - */ -int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) -{ - struct drm_device *dev = fb_helper->dev; - int count = 0; - u32 max_width, max_height, bpp_sel; - bool bound = false, crtcs_bound = false; - struct drm_crtc *crtc; - - if (!fb_helper->fb) - return 0; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->fb) - crtcs_bound = true; - if (crtc->fb == fb_helper->fb) - bound = true; - } - - if (!bound && crtcs_bound) { - fb_helper->delayed_hotplug = true; - mutex_unlock(&dev->mode_config.mutex); - return 0; - } - DRM_DEBUG_KMS("\n"); - - max_width = fb_helper->fb->width; - max_height = fb_helper->fb->height; - bpp_sel = fb_helper->fb->bits_per_pixel; - - count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, - max_height); - drm_setup_crtcs(fb_helper); - mutex_unlock(&dev->mode_config.mutex); - - return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); -} -EXPORT_SYMBOL(drm_fb_helper_hotplug_event); - -/* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) - * but the module doesn't depend on any fb console symbols. At least - * attempt to load fbcon to avoid leaving the system without a usable console. - */ -#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT) -static int __init drm_fb_helper_modinit(void) -{ - const char *name = "fbcon"; - struct module *fbcon; - - mutex_lock(&module_mutex); - fbcon = find_module(name); - mutex_unlock(&module_mutex); - - if (!fbcon) - request_module_nowait(name); - return 0; -} - -module_init(drm_fb_helper_modinit); -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_fops.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_fops.c deleted file mode 100644 index 123de28f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_fops.c +++ /dev/null @@ -1,674 +0,0 @@ -/** - * \file drm_fops.c - * File operations for DRM - * - * \author Rickard E. (Rik) Faith - * \author Daryll Strauss - * \author Gareth Hughes - */ - -/* - * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include -#include -#include - -/* from BKL pushdown: note that nothing else serializes idr_find() */ -DEFINE_MUTEX(drm_global_mutex); -EXPORT_SYMBOL(drm_global_mutex); - -static int drm_open_helper(struct inode *inode, struct file *filp, - struct drm_device * dev); - -static int drm_setup(struct drm_device * dev) -{ - int i; - int ret; - - if (dev->driver->firstopen) { - ret = dev->driver->firstopen(dev); - if (ret != 0) - return ret; - } - - atomic_set(&dev->ioctl_count, 0); - atomic_set(&dev->vma_count, 0); - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && - !drm_core_check_feature(dev, DRIVER_MODESET)) { - dev->buf_use = 0; - atomic_set(&dev->buf_alloc, 0); - - i = drm_dma_setup(dev); - if (i < 0) - return i; - } - - for (i = 0; i < ARRAY_SIZE(dev->counts); i++) - atomic_set(&dev->counts[i], 0); - - dev->sigdata.lock = NULL; - - dev->queue_count = 0; - dev->queue_reserved = 0; - dev->queue_slots = 0; - dev->queuelist = NULL; - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - dev->last_context = 0; - dev->last_switch = 0; - dev->last_checked = 0; - init_waitqueue_head(&dev->context_wait); - dev->if_version = 0; - - dev->ctx_start = 0; - dev->lck_start = 0; - - dev->buf_async = NULL; - init_waitqueue_head(&dev->buf_readers); - init_waitqueue_head(&dev->buf_writers); - - DRM_DEBUG("\n"); - - /* - * The kernel's context could be created here, but is now created - * in drm_dma_enqueue. This is more resource-efficient for - * hardware that does not do DMA, but may mean that - * drm_select_queue fails between the time the interrupt is - * initialized and the time the queues are initialized. - */ - - return 0; -} - -/** - * Open file. - * - * \param inode device inode - * \param filp file pointer. - * \return zero on success or a negative number on failure. - * - * Searches the DRM device with the same minor number, calls open_helper(), and - * increments the device open count. If the open count was previous at zero, - * i.e., it's the first that the device is open, then calls setup(). - */ -int drm_open(struct inode *inode, struct file *filp) -{ - struct drm_device *dev = NULL; - int minor_id = iminor(inode); - struct drm_minor *minor; - int retcode = 0; - - minor = idr_find(&drm_minors_idr, minor_id); - if (!minor) - return -ENODEV; - - if (!(dev = minor->dev)) - return -ENODEV; - - if (drm_device_is_unplugged(dev)) - return -ENODEV; - - retcode = drm_open_helper(inode, filp, dev); - if (!retcode) { - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - if (!dev->open_count++) - retcode = drm_setup(dev); - } - if (!retcode) { - mutex_lock(&dev->struct_mutex); - if (minor->type == DRM_MINOR_LEGACY) { - if (dev->dev_mapping == NULL) - dev->dev_mapping = inode->i_mapping; - else if (dev->dev_mapping != inode->i_mapping) - retcode = -ENODEV; - } - mutex_unlock(&dev->struct_mutex); - } - - return retcode; -} -EXPORT_SYMBOL(drm_open); - -/** - * File \c open operation. - * - * \param inode device inode. - * \param filp file pointer. - * - * Puts the dev->fops corresponding to the device minor number into - * \p filp, call the \c open method, and restore the file operations. - */ -int drm_stub_open(struct inode *inode, struct file *filp) -{ - struct drm_device *dev = NULL; - struct drm_minor *minor; - int minor_id = iminor(inode); - int err = -ENODEV; - const struct file_operations *old_fops; - - DRM_DEBUG("\n"); - - mutex_lock(&drm_global_mutex); - minor = idr_find(&drm_minors_idr, minor_id); - if (!minor) - goto out; - - if (!(dev = minor->dev)) - goto out; - - if (drm_device_is_unplugged(dev)) - goto out; - - old_fops = filp->f_op; - filp->f_op = fops_get(dev->driver->fops); - if (filp->f_op == NULL) { - filp->f_op = old_fops; - goto out; - } - if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { - fops_put(filp->f_op); - filp->f_op = fops_get(old_fops); - } - fops_put(old_fops); - -out: - mutex_unlock(&drm_global_mutex); - return err; -} - -/** - * Check whether DRI will run on this CPU. - * - * \return non-zero if the DRI will run on this CPU, or zero otherwise. - */ -static int drm_cpu_valid(void) -{ -#if defined(__i386__) - if (boot_cpu_data.x86 == 3) - return 0; /* No cmpxchg on a 386 */ -#endif -#if defined(__sparc__) && !defined(__sparc_v9__) - return 0; /* No cmpxchg before v9 sparc. */ -#endif - return 1; -} - -/** - * Called whenever a process opens /dev/drm. - * - * \param inode device inode. - * \param filp file pointer. - * \param dev device. - * \return zero on success or a negative number on failure. - * - * Creates and initializes a drm_file structure for the file private data in \p - * filp and add it into the double linked list in \p dev. - */ -static int drm_open_helper(struct inode *inode, struct file *filp, - struct drm_device * dev) -{ - int minor_id = iminor(inode); - struct drm_file *priv; - int ret; - - if (filp->f_flags & O_EXCL) - return -EBUSY; /* No exclusive opens */ - if (!drm_cpu_valid()) - return -EINVAL; - if (dev->switch_power_state != DRM_SWITCH_POWER_ON) - return -EINVAL; - - DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - filp->private_data = priv; - priv->filp = filp; - priv->uid = current_euid(); - priv->pid = task_pid_nr(current); - priv->minor = idr_find(&drm_minors_idr, minor_id); - priv->ioctl_count = 0; - /* for compatibility root is always authenticated */ - priv->authenticated = capable(CAP_SYS_ADMIN); - priv->lock_count = 0; - - INIT_LIST_HEAD(&priv->lhead); - INIT_LIST_HEAD(&priv->fbs); - INIT_LIST_HEAD(&priv->event_list); - init_waitqueue_head(&priv->event_wait); - priv->event_space = 4096; /* set aside 4k for event buffer */ - - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_open(dev, priv); - - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_init_file_private(&priv->prime); - - if (dev->driver->open) { - ret = dev->driver->open(dev, priv); - if (ret < 0) - goto out_free; - } - - - /* if there is no current master make this fd it */ - mutex_lock(&dev->struct_mutex); - if (!priv->minor->master) { - /* create a new master */ - priv->minor->master = drm_master_create(priv->minor); - if (!priv->minor->master) { - mutex_unlock(&dev->struct_mutex); - ret = -ENOMEM; - goto out_free; - } - - priv->is_master = 1; - /* take another reference for the copy in the local file priv */ - priv->master = drm_master_get(priv->minor->master); - - priv->authenticated = 1; - - mutex_unlock(&dev->struct_mutex); - if (dev->driver->master_create) { - ret = dev->driver->master_create(dev, priv->master); - if (ret) { - mutex_lock(&dev->struct_mutex); - /* drop both references if this fails */ - drm_master_put(&priv->minor->master); - drm_master_put(&priv->master); - mutex_unlock(&dev->struct_mutex); - goto out_free; - } - } - mutex_lock(&dev->struct_mutex); - if (dev->driver->master_set) { - ret = dev->driver->master_set(dev, priv, true); - if (ret) { - /* drop both references if this fails */ - drm_master_put(&priv->minor->master); - drm_master_put(&priv->master); - mutex_unlock(&dev->struct_mutex); - goto out_free; - } - } - mutex_unlock(&dev->struct_mutex); - } else { - /* get a reference to the master */ - priv->master = drm_master_get(priv->minor->master); - mutex_unlock(&dev->struct_mutex); - } - - mutex_lock(&dev->struct_mutex); - list_add(&priv->lhead, &dev->filelist); - mutex_unlock(&dev->struct_mutex); - -#ifdef __alpha__ - /* - * Default the hose - */ - if (!dev->hose) { - struct pci_dev *pci_dev; - pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); - if (pci_dev) { - dev->hose = pci_dev->sysdata; - pci_dev_put(pci_dev); - } - if (!dev->hose) { - struct pci_bus *b = pci_bus_b(pci_root_buses.next); - if (b) - dev->hose = b->sysdata; - } - } -#endif - - return 0; - out_free: - kfree(priv); - filp->private_data = NULL; - return ret; -} - -/** No-op. */ -int drm_fasync(int fd, struct file *filp, int on) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - - DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, - (long)old_encode_dev(priv->minor->device)); - return fasync_helper(fd, filp, on, &dev->buf_async); -} -EXPORT_SYMBOL(drm_fasync); - -/* - * Reclaim locked buffers; note that this may be a bad idea if the current - * context doesn't have the hw lock... - */ -static void drm_reclaim_locked_buffers(struct drm_device *dev, struct file *f) -{ - struct drm_file *file_priv = f->private_data; - - if (drm_i_have_hw_lock(dev, file_priv)) { - dev->driver->reclaim_buffers_locked(dev, file_priv); - } else { - unsigned long _end = jiffies + 3 * DRM_HZ; - int locked = 0; - - drm_idlelock_take(&file_priv->master->lock); - - /* - * Wait for a while. - */ - do { - spin_lock_bh(&file_priv->master->lock.spinlock); - locked = file_priv->master->lock.idle_has_lock; - spin_unlock_bh(&file_priv->master->lock.spinlock); - if (locked) - break; - schedule(); - } while (!time_after_eq(jiffies, _end)); - - if (!locked) { - DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" - "\tdriver to use reclaim_buffers_idlelocked() instead.\n" - "\tI will go on reclaiming the buffers anyway.\n"); - } - - dev->driver->reclaim_buffers_locked(dev, file_priv); - drm_idlelock_release(&file_priv->master->lock); - } -} - -static void drm_master_release(struct drm_device *dev, struct file *filp) -{ - struct drm_file *file_priv = filp->private_data; - - if (dev->driver->reclaim_buffers_locked && - file_priv->master->lock.hw_lock) - drm_reclaim_locked_buffers(dev, filp); - - if (dev->driver->reclaim_buffers_idlelocked && - file_priv->master->lock.hw_lock) { - drm_idlelock_take(&file_priv->master->lock); - dev->driver->reclaim_buffers_idlelocked(dev, file_priv); - drm_idlelock_release(&file_priv->master->lock); - } - - - if (drm_i_have_hw_lock(dev, file_priv)) { - DRM_DEBUG("File %p released, freeing lock for context %d\n", - filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); - drm_lock_free(&file_priv->master->lock, - _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); - } - - if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && - !dev->driver->reclaim_buffers_locked) { - dev->driver->reclaim_buffers(dev, file_priv); - } -} - -static void drm_events_release(struct drm_file *file_priv) -{ - struct drm_device *dev = file_priv->minor->dev; - struct drm_pending_event *e, *et; - struct drm_pending_vblank_event *v, *vt; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - - /* Remove pending flips */ - list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link) - if (v->base.file_priv == file_priv) { - list_del(&v->base.link); - drm_vblank_put(dev, v->pipe); - v->base.destroy(&v->base); - } - - /* Remove unconsumed events */ - list_for_each_entry_safe(e, et, &file_priv->event_list, link) - e->destroy(e); - - spin_unlock_irqrestore(&dev->event_lock, flags); -} - -/** - * Release file. - * - * \param inode device inode - * \param file_priv DRM file private. - * \return zero on success or a negative number on failure. - * - * If the hardware lock is held then free it, and take it again for the kernel - * context since it's necessary to reclaim buffers. Unlink the file private - * data from its list and free it. Decreases the open count and if it reaches - * zero calls drm_lastclose(). - */ -int drm_release(struct inode *inode, struct file *filp) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->minor->dev; - int retcode = 0; - - mutex_lock(&drm_global_mutex); - - DRM_DEBUG("open_count = %d\n", dev->open_count); - - if (dev->driver->preclose) - dev->driver->preclose(dev, file_priv); - - /* ======================================================== - * Begin inline drm_release - */ - - DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - task_pid_nr(current), - (long)old_encode_dev(file_priv->minor->device), - dev->open_count); - - /* Release any auth tokens that might point to this file_priv, - (do that under the drm_global_mutex) */ - if (file_priv->magic) - (void) drm_remove_magic(file_priv->master, file_priv->magic); - - /* if the master has gone away we can't do anything with the lock */ - if (file_priv->minor->master) - drm_master_release(dev, filp); - - drm_events_release(file_priv); - - if (dev->driver->driver_features & DRIVER_MODESET) - drm_fb_release(file_priv); - - if (dev->driver->driver_features & DRIVER_GEM) - drm_gem_release(dev, file_priv); - - mutex_lock(&dev->ctxlist_mutex); - if (!list_empty(&dev->ctxlist)) { - struct drm_ctx_list *pos, *n; - - list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { - if (pos->tag == file_priv && - pos->handle != DRM_KERNEL_CONTEXT) { - if (dev->driver->context_dtor) - dev->driver->context_dtor(dev, - pos->handle); - - drm_ctxbitmap_free(dev, pos->handle); - - list_del(&pos->head); - kfree(pos); - --dev->ctx_count; - } - } - } - mutex_unlock(&dev->ctxlist_mutex); - - mutex_lock(&dev->struct_mutex); - - if (file_priv->is_master) { - struct drm_master *master = file_priv->master; - struct drm_file *temp; - list_for_each_entry(temp, &dev->filelist, lhead) { - if ((temp->master == file_priv->master) && - (temp != file_priv)) - temp->authenticated = 0; - } - - /** - * Since the master is disappearing, so is the - * possibility to lock. - */ - - if (master->lock.hw_lock) { - if (dev->sigdata.lock == master->lock.hw_lock) - dev->sigdata.lock = NULL; - master->lock.hw_lock = NULL; - master->lock.file_priv = NULL; - wake_up_interruptible_all(&master->lock.lock_queue); - } - - if (file_priv->minor->master == file_priv->master) { - /* drop the reference held my the minor */ - if (dev->driver->master_drop) - dev->driver->master_drop(dev, file_priv, true); - drm_master_put(&file_priv->minor->master); - } - } - - /* drop the reference held my the file priv */ - drm_master_put(&file_priv->master); - file_priv->is_master = 0; - list_del(&file_priv->lhead); - mutex_unlock(&dev->struct_mutex); - - if (dev->driver->postclose) - dev->driver->postclose(dev, file_priv); - - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_destroy_file_private(&file_priv->prime); - - kfree(file_priv); - - /* ======================================================== - * End inline drm_release - */ - - atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); - if (!--dev->open_count) { - if (atomic_read(&dev->ioctl_count)) { - DRM_ERROR("Device busy: %d\n", - atomic_read(&dev->ioctl_count)); - retcode = -EBUSY; - } else - retcode = drm_lastclose(dev); - if (drm_device_is_unplugged(dev)) - drm_put_dev(dev); - } - mutex_unlock(&drm_global_mutex); - - return retcode; -} -EXPORT_SYMBOL(drm_release); - -static bool -drm_dequeue_event(struct drm_file *file_priv, - size_t total, size_t max, struct drm_pending_event **out) -{ - struct drm_device *dev = file_priv->minor->dev; - struct drm_pending_event *e; - unsigned long flags; - bool ret = false; - - spin_lock_irqsave(&dev->event_lock, flags); - - *out = NULL; - if (list_empty(&file_priv->event_list)) - goto out; - e = list_first_entry(&file_priv->event_list, - struct drm_pending_event, link); - if (e->event->length + total > max) - goto out; - - file_priv->event_space += e->event->length; - list_del(&e->link); - *out = e; - ret = true; - -out: - spin_unlock_irqrestore(&dev->event_lock, flags); - return ret; -} - -ssize_t drm_read(struct file *filp, char __user *buffer, - size_t count, loff_t *offset) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_pending_event *e; - size_t total; - ssize_t ret; - - ret = wait_event_interruptible(file_priv->event_wait, - !list_empty(&file_priv->event_list)); - if (ret < 0) - return ret; - - total = 0; - while (drm_dequeue_event(file_priv, total, count, &e)) { - if (copy_to_user(buffer + total, - e->event, e->event->length)) { - total = -EFAULT; - break; - } - - total += e->event->length; - e->destroy(e); - } - - return total; -} -EXPORT_SYMBOL(drm_read); - -unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) -{ - struct drm_file *file_priv = filp->private_data; - unsigned int mask = 0; - - poll_wait(filp, &file_priv->event_wait, wait); - - if (!list_empty(&file_priv->event_list)) - mask |= POLLIN | POLLRDNORM; - - return mask; -} -EXPORT_SYMBOL(drm_poll); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_gem.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_gem.c deleted file mode 100644 index 83114b5e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_gem.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "drmP.h" - -/** @file drm_gem.c - * - * This file provides some of the base ioctls and library routines for - * the graphics memory manager implemented by each device driver. - * - * Because various devices have different requirements in terms of - * synchronization and migration strategies, implementing that is left up to - * the driver, and all that the general API provides should be generic -- - * allocating objects, reading/writing data with the cpu, freeing objects. - * Even there, platform-dependent optimizations for reading/writing data with - * the CPU mean we'll likely hook those out to driver-specific calls. However, - * the DRI2 implementation wants to have at least allocate/mmap be generic. - * - * The goal was to have swap-backed object allocation managed through - * struct file. However, file descriptors as handles to a struct file have - * two major failings: - * - Process limits prevent more than 1024 or so being used at a time by - * default. - * - Inability to allocate high fds will aggravate the X Server's select() - * handling, and likely that of many GL client applications as well. - * - * This led to a plan of using our own integer IDs (called handles, following - * DRM terminology) to mimic fds, and implement the fd syscalls we need as - * ioctls. The objects themselves will still include the struct file so - * that we can transition to fds if the required kernel infrastructure shows - * up at a later date, and as our interface with shmfs for memory allocation. - */ - -/* - * We make up offsets for buffer objects so we can recognize them at - * mmap time. - */ - -/* pgoff in mmap is an unsigned long, so we need to make sure that - * the faked up offset will fit - */ - -#if BITS_PER_LONG == 64 -#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) -#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) -#else -#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1) -#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16) -#endif - -/** - * Initialize the GEM device fields - */ - -int -drm_gem_init(struct drm_device *dev) -{ - struct drm_gem_mm *mm; - - spin_lock_init(&dev->object_name_lock); - idr_init(&dev->object_name_idr); - - mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL); - if (!mm) { - DRM_ERROR("out of memory\n"); - return -ENOMEM; - } - - dev->mm_private = mm; - - if (drm_ht_create(&mm->offset_hash, 12)) { - kfree(mm); - return -ENOMEM; - } - - if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, - DRM_FILE_PAGE_OFFSET_SIZE)) { - drm_ht_remove(&mm->offset_hash); - kfree(mm); - return -ENOMEM; - } - - return 0; -} - -void -drm_gem_destroy(struct drm_device *dev) -{ - struct drm_gem_mm *mm = dev->mm_private; - - drm_mm_takedown(&mm->offset_manager); - drm_ht_remove(&mm->offset_hash); - kfree(mm); - dev->mm_private = NULL; -} - -/** - * Initialize an already allocated GEM object of the specified size with - * shmfs backing store. - */ -int drm_gem_object_init(struct drm_device *dev, - struct drm_gem_object *obj, size_t size) -{ - BUG_ON((size & (PAGE_SIZE - 1)) != 0); - - obj->dev = dev; - obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); - if (IS_ERR(obj->filp)) - return PTR_ERR(obj->filp); - - kref_init(&obj->refcount); - atomic_set(&obj->handle_count, 0); - obj->size = size; - - return 0; -} -EXPORT_SYMBOL(drm_gem_object_init); - -/** - * Initialize an already allocated GEM object of the specified size with - * no GEM provided backing store. Instead the caller is responsible for - * backing the object and handling it. - */ -int drm_gem_private_object_init(struct drm_device *dev, - struct drm_gem_object *obj, size_t size) -{ - BUG_ON((size & (PAGE_SIZE - 1)) != 0); - - obj->dev = dev; - obj->filp = NULL; - - kref_init(&obj->refcount); - atomic_set(&obj->handle_count, 0); - obj->size = size; - - return 0; -} -EXPORT_SYMBOL(drm_gem_private_object_init); - -/** - * Allocate a GEM object of the specified size with shmfs backing store - */ -struct drm_gem_object * -drm_gem_object_alloc(struct drm_device *dev, size_t size) -{ - struct drm_gem_object *obj; - - obj = kzalloc(sizeof(*obj), GFP_KERNEL); - if (!obj) - goto free; - - if (drm_gem_object_init(dev, obj, size) != 0) - goto free; - - if (dev->driver->gem_init_object != NULL && - dev->driver->gem_init_object(obj) != 0) { - goto fput; - } - return obj; -fput: - /* Object_init mangles the global counters - readjust them. */ - fput(obj->filp); -free: - kfree(obj); - return NULL; -} -EXPORT_SYMBOL(drm_gem_object_alloc); - -/** - * Removes the mapping from handle to filp for this object. - */ -int -drm_gem_handle_delete(struct drm_file *filp, u32 handle) -{ - struct drm_device *dev; - struct drm_gem_object *obj; - - /* This is gross. The idr system doesn't let us try a delete and - * return an error code. It just spews if you fail at deleting. - * So, we have to grab a lock around finding the object and then - * doing the delete on it and dropping the refcount, or the user - * could race us to double-decrement the refcount and cause a - * use-after-free later. Given the frequency of our handle lookups, - * we may want to use ida for number allocation and a hash table - * for the pointers, anyway. - */ - spin_lock(&filp->table_lock); - - /* Check if we currently have a reference on the object */ - obj = idr_find(&filp->object_idr, handle); - if (obj == NULL) { - spin_unlock(&filp->table_lock); - return -EINVAL; - } - dev = obj->dev; - - /* Release reference and decrement refcount. */ - idr_remove(&filp->object_idr, handle); - spin_unlock(&filp->table_lock); - - if (obj->import_attach) - drm_prime_remove_imported_buf_handle(&filp->prime, - obj->import_attach->dmabuf); - - if (dev->driver->gem_close_object) - dev->driver->gem_close_object(obj, filp); - drm_gem_object_handle_unreference_unlocked(obj); - - return 0; -} -EXPORT_SYMBOL(drm_gem_handle_delete); - -/** - * Create a handle for this object. This adds a handle reference - * to the object, which includes a regular reference count. Callers - * will likely want to dereference the object afterwards. - */ -int -drm_gem_handle_create(struct drm_file *file_priv, - struct drm_gem_object *obj, - u32 *handlep) -{ - struct drm_device *dev = obj->dev; - int ret; - - /* - * Get the user-visible handle using idr. - */ -again: - /* ensure there is space available to allocate a handle */ - if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) - return -ENOMEM; - - /* do the allocation under our spinlock */ - spin_lock(&file_priv->table_lock); - ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep); - spin_unlock(&file_priv->table_lock); - if (ret == -EAGAIN) - goto again; - - if (ret != 0) - return ret; - - drm_gem_object_handle_reference(obj); - - if (dev->driver->gem_open_object) { - ret = dev->driver->gem_open_object(obj, file_priv); - if (ret) { - drm_gem_handle_delete(file_priv, *handlep); - return ret; - } - } - - return 0; -} -EXPORT_SYMBOL(drm_gem_handle_create); - - -/** - * drm_gem_free_mmap_offset - release a fake mmap offset for an object - * @obj: obj in question - * - * This routine frees fake offsets allocated by drm_gem_create_mmap_offset(). - */ -void -drm_gem_free_mmap_offset(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list = &obj->map_list; - - drm_ht_remove_item(&mm->offset_hash, &list->hash); - drm_mm_put_block(list->file_offset_node); - kfree(list->map); - list->map = NULL; -} -EXPORT_SYMBOL(drm_gem_free_mmap_offset); - -/** - * drm_gem_create_mmap_offset - create a fake mmap offset for an object - * @obj: obj in question - * - * GEM memory mapping works by handing back to userspace a fake mmap offset - * it can use in a subsequent mmap(2) call. The DRM core code then looks - * up the object based on the offset and sets up the various memory mapping - * structures. - * - * This routine allocates and attaches a fake offset for @obj. - */ -int -drm_gem_create_mmap_offset(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; - struct drm_local_map *map; - int ret = 0; - - /* Set the object up for mmap'ing */ - list = &obj->map_list; - list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); - if (!list->map) - return -ENOMEM; - - map = list->map; - map->type = _DRM_GEM; - map->size = obj->size; - map->handle = obj; - - /* Get a DRM GEM mmap offset allocated... */ - list->file_offset_node = drm_mm_search_free(&mm->offset_manager, - obj->size / PAGE_SIZE, 0, 0); - - if (!list->file_offset_node) { - DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); - ret = -ENOSPC; - goto out_free_list; - } - - list->file_offset_node = drm_mm_get_block(list->file_offset_node, - obj->size / PAGE_SIZE, 0); - if (!list->file_offset_node) { - ret = -ENOMEM; - goto out_free_list; - } - - list->hash.key = list->file_offset_node->start; - ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); - if (ret) { - DRM_ERROR("failed to add to map hash\n"); - goto out_free_mm; - } - - return 0; - -out_free_mm: - drm_mm_put_block(list->file_offset_node); -out_free_list: - kfree(list->map); - list->map = NULL; - - return ret; -} -EXPORT_SYMBOL(drm_gem_create_mmap_offset); - -/** Returns a reference to the object named by the handle. */ -struct drm_gem_object * -drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, - u32 handle) -{ - struct drm_gem_object *obj; - - spin_lock(&filp->table_lock); - - /* Check if we currently have a reference on the object */ - obj = idr_find(&filp->object_idr, handle); - if (obj == NULL) { - spin_unlock(&filp->table_lock); - return NULL; - } - - drm_gem_object_reference(obj); - - spin_unlock(&filp->table_lock); - - return obj; -} -EXPORT_SYMBOL(drm_gem_object_lookup); - -/** - * Releases the handle to an mm object. - */ -int -drm_gem_close_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_close *args = data; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - ret = drm_gem_handle_delete(file_priv, args->handle); - - return ret; -} - -/** - * Create a global name for an object, returning the name. - * - * Note that the name does not hold a reference; when the object - * is freed, the name goes away. - */ -int -drm_gem_flink_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_flink *args = data; - struct drm_gem_object *obj; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -ENOENT; - -again: - if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { - ret = -ENOMEM; - goto err; - } - - spin_lock(&dev->object_name_lock); - if (!obj->name) { - ret = idr_get_new_above(&dev->object_name_idr, obj, 1, - &obj->name); - args->name = (uint64_t) obj->name; - spin_unlock(&dev->object_name_lock); - - if (ret == -EAGAIN) - goto again; - - if (ret != 0) - goto err; - - /* Allocate a reference for the name table. */ - drm_gem_object_reference(obj); - } else { - args->name = (uint64_t) obj->name; - spin_unlock(&dev->object_name_lock); - ret = 0; - } - -err: - drm_gem_object_unreference_unlocked(obj); - return ret; -} - -/** - * Open an object using the global name, returning a handle and the size. - * - * This handle (of course) holds a reference to the object, so the object - * will not go away until the handle is deleted. - */ -int -drm_gem_open_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_gem_open *args = data; - struct drm_gem_object *obj; - int ret; - u32 handle; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - spin_lock(&dev->object_name_lock); - obj = idr_find(&dev->object_name_idr, (int) args->name); - if (obj) - drm_gem_object_reference(obj); - spin_unlock(&dev->object_name_lock); - if (!obj) - return -ENOENT; - - ret = drm_gem_handle_create(file_priv, obj, &handle); - drm_gem_object_unreference_unlocked(obj); - if (ret) - return ret; - - args->handle = handle; - args->size = obj->size; - - return 0; -} - -/** - * Called at device open time, sets up the structure for handling refcounting - * of mm objects. - */ -void -drm_gem_open(struct drm_device *dev, struct drm_file *file_private) -{ - idr_init(&file_private->object_idr); - spin_lock_init(&file_private->table_lock); -} - -/** - * Called at device close to release the file's - * handle references on objects. - */ -static int -drm_gem_object_release_handle(int id, void *ptr, void *data) -{ - struct drm_file *file_priv = data; - struct drm_gem_object *obj = ptr; - struct drm_device *dev = obj->dev; - - if (obj->import_attach) - drm_prime_remove_imported_buf_handle(&file_priv->prime, - obj->import_attach->dmabuf); - - if (dev->driver->gem_close_object) - dev->driver->gem_close_object(obj, file_priv); - - drm_gem_object_handle_unreference_unlocked(obj); - - return 0; -} - -/** - * Called at close time when the filp is going away. - * - * Releases any remaining references on objects by this filp. - */ -void -drm_gem_release(struct drm_device *dev, struct drm_file *file_private) -{ - idr_for_each(&file_private->object_idr, - &drm_gem_object_release_handle, file_private); - - idr_remove_all(&file_private->object_idr); - idr_destroy(&file_private->object_idr); -} - -void -drm_gem_object_release(struct drm_gem_object *obj) -{ - if (obj->filp) - fput(obj->filp); -} -EXPORT_SYMBOL(drm_gem_object_release); - -/** - * Called after the last reference to the object has been lost. - * Must be called holding struct_ mutex - * - * Frees the object - */ -void -drm_gem_object_free(struct kref *kref) -{ - struct drm_gem_object *obj = (struct drm_gem_object *) kref; - struct drm_device *dev = obj->dev; - - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - - if (dev->driver->gem_free_object != NULL) - dev->driver->gem_free_object(obj); -} -EXPORT_SYMBOL(drm_gem_object_free); - -static void drm_gem_object_ref_bug(struct kref *list_kref) -{ - BUG(); -} - -/** - * Called after the last handle to the object has been closed - * - * Removes any name for the object. Note that this must be - * called before drm_gem_object_free or we'll be touching - * freed memory - */ -void drm_gem_object_handle_free(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - - /* Remove any name for this object */ - spin_lock(&dev->object_name_lock); - if (obj->name) { - idr_remove(&dev->object_name_idr, obj->name); - obj->name = 0; - spin_unlock(&dev->object_name_lock); - /* - * The object name held a reference to this object, drop - * that now. - * - * This cannot be the last reference, since the handle holds one too. - */ - kref_put(&obj->refcount, drm_gem_object_ref_bug); - } else - spin_unlock(&dev->object_name_lock); - -} -EXPORT_SYMBOL(drm_gem_object_handle_free); - -void drm_gem_vm_open(struct vm_area_struct *vma) -{ - struct drm_gem_object *obj = vma->vm_private_data; - - drm_gem_object_reference(obj); - - mutex_lock(&obj->dev->struct_mutex); - drm_vm_open_locked(vma); - mutex_unlock(&obj->dev->struct_mutex); -} -EXPORT_SYMBOL(drm_gem_vm_open); - -void drm_gem_vm_close(struct vm_area_struct *vma) -{ - struct drm_gem_object *obj = vma->vm_private_data; - struct drm_device *dev = obj->dev; - - mutex_lock(&dev->struct_mutex); - drm_vm_close_locked(vma); - drm_gem_object_unreference(obj); - mutex_unlock(&dev->struct_mutex); -} -EXPORT_SYMBOL(drm_gem_vm_close); - - -/** - * drm_gem_mmap - memory map routine for GEM objects - * @filp: DRM file pointer - * @vma: VMA for the area to be mapped - * - * If a driver supports GEM object mapping, mmap calls on the DRM file - * descriptor will end up here. - * - * If we find the object based on the offset passed in (vma->vm_pgoff will - * contain the fake offset we created when the GTT map ioctl was called on - * the object), we set up the driver fault handler so that any accesses - * to the object can be trapped, to perform migration, GTT binding, surface - * register allocation, or performance monitoring. - */ -int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_local_map *map = NULL; - struct drm_gem_object *obj; - struct drm_hash_item *hash; - int ret = 0; - - if (drm_device_is_unplugged(dev)) - return -ENODEV; - - mutex_lock(&dev->struct_mutex); - - if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) { - mutex_unlock(&dev->struct_mutex); - return drm_mmap(filp, vma); - } - - map = drm_hash_entry(hash, struct drm_map_list, hash)->map; - if (!map || - ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) { - ret = -EPERM; - goto out_unlock; - } - - /* Check for valid size. */ - if (map->size < vma->vm_end - vma->vm_start) { - ret = -EINVAL; - goto out_unlock; - } - - obj = map->handle; - if (!obj->dev->driver->gem_vm_ops) { - ret = -EINVAL; - goto out_unlock; - } - - vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; - vma->vm_ops = obj->dev->driver->gem_vm_ops; - vma->vm_private_data = map->handle; - vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); - - /* Take a ref for this mapping of the object, so that the fault - * handler can dereference the mmap offset's pointer to the object. - * This reference is cleaned up by the corresponding vm_close - * (which should happen whether the vma was created by this call, or - * by a vm_open due to mremap or partial unmap or whatever). - */ - drm_gem_object_reference(obj); - - drm_vm_open_locked(vma); - -out_unlock: - mutex_unlock(&dev->struct_mutex); - - return ret; -} -EXPORT_SYMBOL(drm_gem_mmap); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_global.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_global.c deleted file mode 100644 index c87dc964..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_global.c +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************** - * - * Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include "drm_global.h" - -struct drm_global_item { - struct mutex mutex; - void *object; - int refcount; -}; - -static struct drm_global_item glob[DRM_GLOBAL_NUM]; - -void drm_global_init(void) -{ - int i; - - for (i = 0; i < DRM_GLOBAL_NUM; ++i) { - struct drm_global_item *item = &glob[i]; - mutex_init(&item->mutex); - item->object = NULL; - item->refcount = 0; - } -} - -void drm_global_release(void) -{ - int i; - for (i = 0; i < DRM_GLOBAL_NUM; ++i) { - struct drm_global_item *item = &glob[i]; - BUG_ON(item->object != NULL); - BUG_ON(item->refcount != 0); - } -} - -int drm_global_item_ref(struct drm_global_reference *ref) -{ - int ret; - struct drm_global_item *item = &glob[ref->global_type]; - void *object; - - mutex_lock(&item->mutex); - if (item->refcount == 0) { - item->object = kzalloc(ref->size, GFP_KERNEL); - if (unlikely(item->object == NULL)) { - ret = -ENOMEM; - goto out_err; - } - - ref->object = item->object; - ret = ref->init(ref); - if (unlikely(ret != 0)) - goto out_err; - - } - ++item->refcount; - ref->object = item->object; - object = item->object; - mutex_unlock(&item->mutex); - return 0; -out_err: - mutex_unlock(&item->mutex); - item->object = NULL; - return ret; -} -EXPORT_SYMBOL(drm_global_item_ref); - -void drm_global_item_unref(struct drm_global_reference *ref) -{ - struct drm_global_item *item = &glob[ref->global_type]; - - mutex_lock(&item->mutex); - BUG_ON(item->refcount == 0); - BUG_ON(ref->object != item->object); - if (--item->refcount == 0) { - ref->release(ref); - item->object = NULL; - } - mutex_unlock(&item->mutex); -} -EXPORT_SYMBOL(drm_global_item_unref); - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_hashtab.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_hashtab.c deleted file mode 100644 index 68dc8744..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_hashtab.c +++ /dev/null @@ -1,197 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "drm_hashtab.h" -#include -#include -#include - -int drm_ht_create(struct drm_open_hash *ht, unsigned int order) -{ - unsigned int size = 1 << order; - - ht->order = order; - ht->table = NULL; - if (size <= PAGE_SIZE / sizeof(*ht->table)) - ht->table = kcalloc(size, sizeof(*ht->table), GFP_KERNEL); - else - ht->table = vzalloc(size*sizeof(*ht->table)); - if (!ht->table) { - DRM_ERROR("Out of memory for hash table\n"); - return -ENOMEM; - } - return 0; -} -EXPORT_SYMBOL(drm_ht_create); - -void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key) -{ - struct drm_hash_item *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - int count = 0; - - hashed_key = hash_long(key, ht->order); - DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, struct drm_hash_item, head); - DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key); - } -} - -static struct hlist_node *drm_ht_find_key(struct drm_open_hash *ht, - unsigned long key) -{ - struct drm_hash_item *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, struct drm_hash_item, head); - if (entry->key == key) - return list; - if (entry->key > key) - break; - } - return NULL; -} - - -int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item) -{ - struct drm_hash_item *entry; - struct hlist_head *h_list; - struct hlist_node *list, *parent; - unsigned int hashed_key; - unsigned long key = item->key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - parent = NULL; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, struct drm_hash_item, head); - if (entry->key == key) - return -EINVAL; - if (entry->key > key) - break; - parent = list; - } - if (parent) { - hlist_add_after(parent, &item->head); - } else { - hlist_add_head(&item->head, h_list); - } - return 0; -} -EXPORT_SYMBOL(drm_ht_insert_item); - -/* - * Just insert an item and return any "bits" bit key that hasn't been - * used before. - */ -int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item, - unsigned long seed, int bits, int shift, - unsigned long add) -{ - int ret; - unsigned long mask = (1 << bits) - 1; - unsigned long first, unshifted_key; - - unshifted_key = hash_long(seed, bits); - first = unshifted_key; - do { - item->key = (unshifted_key << shift) + add; - ret = drm_ht_insert_item(ht, item); - if (ret) - unshifted_key = (unshifted_key + 1) & mask; - } while(ret && (unshifted_key != first)); - - if (ret) { - DRM_ERROR("Available key bit space exhausted\n"); - return -EINVAL; - } - return 0; -} -EXPORT_SYMBOL(drm_ht_just_insert_please); - -int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, - struct drm_hash_item **item) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (!list) - return -EINVAL; - - *item = hlist_entry(list, struct drm_hash_item, head); - return 0; -} -EXPORT_SYMBOL(drm_ht_find_item); - -int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (list) { - hlist_del_init(list); - return 0; - } - return -EINVAL; -} - -int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item) -{ - hlist_del_init(&item->head); - return 0; -} -EXPORT_SYMBOL(drm_ht_remove_item); - -void drm_ht_remove(struct drm_open_hash *ht) -{ - if (ht->table) { - if ((PAGE_SIZE / sizeof(*ht->table)) >> ht->order) - kfree(ht->table); - else - vfree(ht->table); - ht->table = NULL; - } -} -EXPORT_SYMBOL(drm_ht_remove); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_info.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_info.c deleted file mode 100644 index ab1162da..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_info.c +++ /dev/null @@ -1,315 +0,0 @@ -/** - * \file drm_info.c - * DRM info file implementations - * - * \author Ben Gamari - */ - -/* - * Created: Sun Dec 21 13:09:50 2008 by bgamari@gmail.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * Copyright 2008 Ben Gamari - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -/** - * Called when "/proc/dri/.../name" is read. - * - * Prints the device name together with the bus id if available. - */ -int drm_name_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_minor *minor = node->minor; - struct drm_device *dev = minor->dev; - struct drm_master *master = minor->master; - const char *bus_name; - if (!master) - return 0; - - bus_name = dev->driver->bus->get_name(dev); - if (master->unique) { - seq_printf(m, "%s %s %s\n", - bus_name, - dev_name(dev->dev), master->unique); - } else { - seq_printf(m, "%s %s\n", - bus_name, dev_name(dev->dev)); - } - return 0; -} - -/** - * Called when "/proc/dri/.../vm" is read. - * - * Prints information about all mappings in drm_device::maplist. - */ -int drm_vm_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_local_map *map; - struct drm_map_list *r_list; - - /* Hardcoded from _DRM_FRAME_BUFFER, - _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and - _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; - const char *type; - int i; - - mutex_lock(&dev->struct_mutex); - seq_printf(m, "slot offset size type flags address mtrr\n\n"); - i = 0; - list_for_each_entry(r_list, &dev->maplist, head) { - map = r_list->map; - if (!map) - continue; - if (map->type < 0 || map->type > 5) - type = "??"; - else - type = types[map->type]; - - seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ", - i, - (unsigned long long)map->offset, - map->size, type, map->flags, - (unsigned long) r_list->user_token); - if (map->mtrr < 0) - seq_printf(m, "none\n"); - else - seq_printf(m, "%4d\n", map->mtrr); - i++; - } - mutex_unlock(&dev->struct_mutex); - return 0; -} - -/** - * Called when "/proc/dri/.../queues" is read. - */ -int drm_queues_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - int i; - struct drm_queue *q; - - mutex_lock(&dev->struct_mutex); - seq_printf(m, " ctx/flags use fin" - " blk/rw/rwf wait flushed queued" - " locks\n\n"); - for (i = 0; i < dev->queue_count; i++) { - q = dev->queuelist[i]; - atomic_inc(&q->use_count); - seq_printf(m, "%5d/0x%03x %5d %5d" - " %5d/%c%c/%c%c%c %5Zd\n", - i, - q->flags, - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count), - atomic_read(&q->block_read) ? 'r' : '-', - atomic_read(&q->block_write) ? 'w' : '-', - waitqueue_active(&q->read_queue) ? 'r' : '-', - waitqueue_active(&q->write_queue) ? 'w' : '-', - waitqueue_active(&q->flush_queue) ? 'f' : '-', - DRM_BUFCOUNT(&q->waitlist)); - atomic_dec(&q->use_count); - } - mutex_unlock(&dev->struct_mutex); - return 0; -} - -/** - * Called when "/proc/dri/.../bufs" is read. - */ -int drm_bufs_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_device_dma *dma; - int i, seg_pages; - - mutex_lock(&dev->struct_mutex); - dma = dev->dma; - if (!dma) { - mutex_unlock(&dev->struct_mutex); - return 0; - } - - seq_printf(m, " o size count free segs pages kB\n\n"); - for (i = 0; i <= DRM_MAX_ORDER; i++) { - if (dma->bufs[i].buf_count) { - seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order); - seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n", - i, - dma->bufs[i].buf_size, - dma->bufs[i].buf_count, - atomic_read(&dma->bufs[i].freelist.count), - dma->bufs[i].seg_count, - seg_pages, - seg_pages * PAGE_SIZE / 1024); - } - } - seq_printf(m, "\n"); - for (i = 0; i < dma->buf_count; i++) { - if (i && !(i % 32)) - seq_printf(m, "\n"); - seq_printf(m, " %d", dma->buflist[i]->list); - } - seq_printf(m, "\n"); - mutex_unlock(&dev->struct_mutex); - return 0; -} - -/** - * Called when "/proc/dri/.../vblank" is read. - */ -int drm_vblank_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - int crtc; - - mutex_lock(&dev->struct_mutex); - for (crtc = 0; crtc < dev->num_crtcs; crtc++) { - seq_printf(m, "CRTC %d enable: %d\n", - crtc, atomic_read(&dev->vblank_refcount[crtc])); - seq_printf(m, "CRTC %d counter: %d\n", - crtc, drm_vblank_count(dev, crtc)); - seq_printf(m, "CRTC %d last wait: %d\n", - crtc, dev->last_vblank_wait[crtc]); - seq_printf(m, "CRTC %d in modeset: %d\n", - crtc, dev->vblank_inmodeset[crtc]); - } - mutex_unlock(&dev->struct_mutex); - return 0; -} - -/** - * Called when "/proc/dri/.../clients" is read. - * - */ -int drm_clients_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_file *priv; - - mutex_lock(&dev->struct_mutex); - seq_printf(m, "a dev pid uid magic ioctls\n\n"); - list_for_each_entry(priv, &dev->filelist, lhead) { - seq_printf(m, "%c %3d %5d %5d %10u %10lu\n", - priv->authenticated ? 'y' : 'n', - priv->minor->index, - priv->pid, - priv->uid, priv->magic, priv->ioctl_count); - } - mutex_unlock(&dev->struct_mutex); - return 0; -} - - -int drm_gem_one_name_info(int id, void *ptr, void *data) -{ - struct drm_gem_object *obj = ptr; - struct seq_file *m = data; - - seq_printf(m, "name %d size %zd\n", obj->name, obj->size); - - seq_printf(m, "%6d %8zd %7d %8d\n", - obj->name, obj->size, - atomic_read(&obj->handle_count), - atomic_read(&obj->refcount.refcount)); - return 0; -} - -int drm_gem_name_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - - seq_printf(m, " name size handles refcount\n"); - idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); - return 0; -} - -#if DRM_DEBUG_CODE - -int drm_vma_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_vma_entry *pt; - struct vm_area_struct *vma; -#if defined(__i386__) - unsigned int pgprot; -#endif - - mutex_lock(&dev->struct_mutex); - seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", - atomic_read(&dev->vma_count), - high_memory, (void *)virt_to_phys(high_memory)); - - list_for_each_entry(pt, &dev->vmalist, head) { - vma = pt->vma; - if (!vma) - continue; - seq_printf(m, - "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", - pt->pid, - (void *)vma->vm_start, (void *)vma->vm_end, - vma->vm_flags & VM_READ ? 'r' : '-', - vma->vm_flags & VM_WRITE ? 'w' : '-', - vma->vm_flags & VM_EXEC ? 'x' : '-', - vma->vm_flags & VM_MAYSHARE ? 's' : 'p', - vma->vm_flags & VM_LOCKED ? 'l' : '-', - vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_pgoff); - -#if defined(__i386__) - pgprot = pgprot_val(vma->vm_page_prot); - seq_printf(m, " %c%c%c%c%c%c%c%c%c", - pgprot & _PAGE_PRESENT ? 'p' : '-', - pgprot & _PAGE_RW ? 'w' : 'r', - pgprot & _PAGE_USER ? 'u' : 's', - pgprot & _PAGE_PWT ? 't' : 'b', - pgprot & _PAGE_PCD ? 'u' : 'c', - pgprot & _PAGE_ACCESSED ? 'a' : '-', - pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_PSE ? 'm' : 'k', - pgprot & _PAGE_GLOBAL ? 'g' : 'l'); -#endif - seq_printf(m, "\n"); - } - mutex_unlock(&dev->struct_mutex); - return 0; -} - -#endif - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_ioc32.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_ioc32.c deleted file mode 100644 index 637fcc37..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_ioc32.c +++ /dev/null @@ -1,1085 +0,0 @@ -/** - * \file drm_ioc32.c - * - * 32-bit ioctl compatibility routines for the DRM. - * - * \author Paul Mackerras - * - * Copyright (C) Paul Mackerras 2005. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include -#include -#include - -#include "drmP.h" -#include "drm_core.h" - -#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t) -#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t) -#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t) -#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t) -#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t) - -#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t) -#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t) -#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t) -#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t) -#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t) -#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t) -#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t) - -#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t) - -#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t) -#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t) - -#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t) -#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t) - -#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t) -#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t) -#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t) -#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t) -#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t) -#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t) - -#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t) -#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t) - -#define DRM_IOCTL_UPDATE_DRAW32 DRM_IOW( 0x3f, drm_update_draw32_t) - -#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t) - -typedef struct drm_version_32 { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - u32 name_len; /**< Length of name buffer */ - u32 name; /**< Name of driver */ - u32 date_len; /**< Length of date buffer */ - u32 date; /**< User-space buffer to hold date */ - u32 desc_len; /**< Length of desc buffer */ - u32 desc; /**< User-space buffer to hold desc */ -} drm_version32_t; - -static int compat_drm_version(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_version32_t v32; - struct drm_version __user *version; - int err; - - if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) - return -EFAULT; - - version = compat_alloc_user_space(sizeof(*version)); - if (!access_ok(VERIFY_WRITE, version, sizeof(*version))) - return -EFAULT; - if (__put_user(v32.name_len, &version->name_len) - || __put_user((void __user *)(unsigned long)v32.name, - &version->name) - || __put_user(v32.date_len, &version->date_len) - || __put_user((void __user *)(unsigned long)v32.date, - &version->date) - || __put_user(v32.desc_len, &version->desc_len) - || __put_user((void __user *)(unsigned long)v32.desc, - &version->desc)) - return -EFAULT; - - err = drm_ioctl(file, - DRM_IOCTL_VERSION, (unsigned long)version); - if (err) - return err; - - if (__get_user(v32.version_major, &version->version_major) - || __get_user(v32.version_minor, &version->version_minor) - || __get_user(v32.version_patchlevel, &version->version_patchlevel) - || __get_user(v32.name_len, &version->name_len) - || __get_user(v32.date_len, &version->date_len) - || __get_user(v32.desc_len, &version->desc_len)) - return -EFAULT; - - if (copy_to_user((void __user *)arg, &v32, sizeof(v32))) - return -EFAULT; - return 0; -} - -typedef struct drm_unique32 { - u32 unique_len; /**< Length of unique */ - u32 unique; /**< Unique name for driver instantiation */ -} drm_unique32_t; - -static int compat_drm_getunique(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_unique32_t uq32; - struct drm_unique __user *u; - int err; - - if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) - return -EFAULT; - - u = compat_alloc_user_space(sizeof(*u)); - if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) - return -EFAULT; - if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long)uq32.unique, - &u->unique)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u); - if (err) - return err; - - if (__get_user(uq32.unique_len, &u->unique_len)) - return -EFAULT; - if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32))) - return -EFAULT; - return 0; -} - -static int compat_drm_setunique(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_unique32_t uq32; - struct drm_unique __user *u; - - if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) - return -EFAULT; - - u = compat_alloc_user_space(sizeof(*u)); - if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) - return -EFAULT; - if (__put_user(uq32.unique_len, &u->unique_len) - || __put_user((void __user *)(unsigned long)uq32.unique, - &u->unique)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u); -} - -typedef struct drm_map32 { - u32 offset; /**< Requested physical address (0 for SAREA)*/ - u32 size; /**< Requested physical size (bytes) */ - enum drm_map_type type; /**< Type of memory to map */ - enum drm_map_flags flags; /**< Flags */ - u32 handle; /**< User-space: "Handle" to pass to mmap() */ - int mtrr; /**< MTRR slot used */ -} drm_map32_t; - -static int compat_drm_getmap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_map32_t __user *argp = (void __user *)arg; - drm_map32_t m32; - struct drm_map __user *map; - int idx, err; - void *handle; - - if (get_user(idx, &argp->offset)) - return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) - return -EFAULT; - if (__put_user(idx, &map->offset)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map); - if (err) - return err; - - if (__get_user(m32.offset, &map->offset) - || __get_user(m32.size, &map->size) - || __get_user(m32.type, &map->type) - || __get_user(m32.flags, &map->flags) - || __get_user(handle, &map->handle) - || __get_user(m32.mtrr, &map->mtrr)) - return -EFAULT; - - m32.handle = (unsigned long)handle; - if (copy_to_user(argp, &m32, sizeof(m32))) - return -EFAULT; - return 0; - -} - -static int compat_drm_addmap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_map32_t __user *argp = (void __user *)arg; - drm_map32_t m32; - struct drm_map __user *map; - int err; - void *handle; - - if (copy_from_user(&m32, argp, sizeof(m32))) - return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) - return -EFAULT; - if (__put_user(m32.offset, &map->offset) - || __put_user(m32.size, &map->size) - || __put_user(m32.type, &map->type) - || __put_user(m32.flags, &map->flags)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map); - if (err) - return err; - - if (__get_user(m32.offset, &map->offset) - || __get_user(m32.mtrr, &map->mtrr) - || __get_user(handle, &map->handle)) - return -EFAULT; - - m32.handle = (unsigned long)handle; - if (m32.handle != (unsigned long)handle) - printk_ratelimited(KERN_ERR "compat_drm_addmap truncated handle" - " %p for type %d offset %x\n", - handle, m32.type, m32.offset); - - if (copy_to_user(argp, &m32, sizeof(m32))) - return -EFAULT; - - return 0; -} - -static int compat_drm_rmmap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_map32_t __user *argp = (void __user *)arg; - struct drm_map __user *map; - u32 handle; - - if (get_user(handle, &argp->handle)) - return -EFAULT; - - map = compat_alloc_user_space(sizeof(*map)); - if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) - return -EFAULT; - if (__put_user((void *)(unsigned long)handle, &map->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map); -} - -typedef struct drm_client32 { - int idx; /**< Which client desired? */ - int auth; /**< Is client authenticated? */ - u32 pid; /**< Process ID */ - u32 uid; /**< User ID */ - u32 magic; /**< Magic */ - u32 iocs; /**< Ioctl count */ -} drm_client32_t; - -static int compat_drm_getclient(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_client32_t c32; - drm_client32_t __user *argp = (void __user *)arg; - struct drm_client __user *client; - int idx, err; - - if (get_user(idx, &argp->idx)) - return -EFAULT; - - client = compat_alloc_user_space(sizeof(*client)); - if (!access_ok(VERIFY_WRITE, client, sizeof(*client))) - return -EFAULT; - if (__put_user(idx, &client->idx)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client); - if (err) - return err; - - if (__get_user(c32.idx, &client->idx) - || __get_user(c32.auth, &client->auth) - || __get_user(c32.pid, &client->pid) - || __get_user(c32.uid, &client->uid) - || __get_user(c32.magic, &client->magic) - || __get_user(c32.iocs, &client->iocs)) - return -EFAULT; - - if (copy_to_user(argp, &c32, sizeof(c32))) - return -EFAULT; - return 0; -} - -typedef struct drm_stats32 { - u32 count; - struct { - u32 value; - enum drm_stat_type type; - } data[15]; -} drm_stats32_t; - -static int compat_drm_getstats(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_stats32_t s32; - drm_stats32_t __user *argp = (void __user *)arg; - struct drm_stats __user *stats; - int i, err; - - stats = compat_alloc_user_space(sizeof(*stats)); - if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats); - if (err) - return err; - - if (__get_user(s32.count, &stats->count)) - return -EFAULT; - for (i = 0; i < 15; ++i) - if (__get_user(s32.data[i].value, &stats->data[i].value) - || __get_user(s32.data[i].type, &stats->data[i].type)) - return -EFAULT; - - if (copy_to_user(argp, &s32, sizeof(s32))) - return -EFAULT; - return 0; -} - -typedef struct drm_buf_desc32 { - int count; /**< Number of buffers of this size */ - int size; /**< Size in bytes */ - int low_mark; /**< Low water mark */ - int high_mark; /**< High water mark */ - int flags; - u32 agp_start; /**< Start address in the AGP aperture */ -} drm_buf_desc32_t; - -static int compat_drm_addbufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_desc32_t __user *argp = (void __user *)arg; - struct drm_buf_desc __user *buf; - int err; - unsigned long agp_start; - - buf = compat_alloc_user_space(sizeof(*buf)); - if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)) - || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))) - return -EFAULT; - - if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start)) - || __get_user(agp_start, &argp->agp_start) - || __put_user(agp_start, &buf->agp_start)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf); - if (err) - return err; - - if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start)) - || __get_user(agp_start, &buf->agp_start) - || __put_user(agp_start, &argp->agp_start)) - return -EFAULT; - - return 0; -} - -static int compat_drm_markbufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_desc32_t b32; - drm_buf_desc32_t __user *argp = (void __user *)arg; - struct drm_buf_desc __user *buf; - - if (copy_from_user(&b32, argp, sizeof(b32))) - return -EFAULT; - - buf = compat_alloc_user_space(sizeof(*buf)); - if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))) - return -EFAULT; - - if (__put_user(b32.size, &buf->size) - || __put_user(b32.low_mark, &buf->low_mark) - || __put_user(b32.high_mark, &buf->high_mark)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf); -} - -typedef struct drm_buf_info32 { - int count; /**< Entries in list */ - u32 list; -} drm_buf_info32_t; - -static int compat_drm_infobufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_info32_t req32; - drm_buf_info32_t __user *argp = (void __user *)arg; - drm_buf_desc32_t __user *to; - struct drm_buf_info __user *request; - struct drm_buf_desc __user *list; - size_t nbytes; - int i, err; - int count, actual; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - count = req32.count; - to = (drm_buf_desc32_t __user *) (unsigned long)req32.list; - if (count < 0) - count = 0; - if (count > 0 - && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t))) - return -EFAULT; - - nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc); - request = compat_alloc_user_space(nbytes); - if (!access_ok(VERIFY_WRITE, request, nbytes)) - return -EFAULT; - list = (struct drm_buf_desc *) (request + 1); - - if (__put_user(count, &request->count) - || __put_user(list, &request->list)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request); - if (err) - return err; - - if (__get_user(actual, &request->count)) - return -EFAULT; - if (count >= actual) - for (i = 0; i < actual; ++i) - if (__copy_in_user(&to[i], &list[i], - offsetof(struct drm_buf_desc, flags))) - return -EFAULT; - - if (__put_user(actual, &argp->count)) - return -EFAULT; - - return 0; -} - -typedef struct drm_buf_pub32 { - int idx; /**< Index into the master buffer list */ - int total; /**< Buffer size */ - int used; /**< Amount of buffer in use (for DMA) */ - u32 address; /**< Address of buffer */ -} drm_buf_pub32_t; - -typedef struct drm_buf_map32 { - int count; /**< Length of the buffer list */ - u32 virtual; /**< Mmap'd area in user-virtual */ - u32 list; /**< Buffer information */ -} drm_buf_map32_t; - -static int compat_drm_mapbufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_map32_t __user *argp = (void __user *)arg; - drm_buf_map32_t req32; - drm_buf_pub32_t __user *list32; - struct drm_buf_map __user *request; - struct drm_buf_pub __user *list; - int i, err; - int count, actual; - size_t nbytes; - void __user *addr; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - count = req32.count; - list32 = (void __user *)(unsigned long)req32.list; - - if (count < 0) - return -EINVAL; - nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub); - request = compat_alloc_user_space(nbytes); - if (!access_ok(VERIFY_WRITE, request, nbytes)) - return -EFAULT; - list = (struct drm_buf_pub *) (request + 1); - - if (__put_user(count, &request->count) - || __put_user(list, &request->list)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request); - if (err) - return err; - - if (__get_user(actual, &request->count)) - return -EFAULT; - if (count >= actual) - for (i = 0; i < actual; ++i) - if (__copy_in_user(&list32[i], &list[i], - offsetof(struct drm_buf_pub, address)) - || __get_user(addr, &list[i].address) - || __put_user((unsigned long)addr, - &list32[i].address)) - return -EFAULT; - - if (__put_user(actual, &argp->count) - || __get_user(addr, &request->virtual) - || __put_user((unsigned long)addr, &argp->virtual)) - return -EFAULT; - - return 0; -} - -typedef struct drm_buf_free32 { - int count; - u32 list; -} drm_buf_free32_t; - -static int compat_drm_freebufs(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_buf_free32_t req32; - struct drm_buf_free __user *request; - drm_buf_free32_t __user *argp = (void __user *)arg; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) - return -EFAULT; - if (__put_user(req32.count, &request->count) - || __put_user((int __user *)(unsigned long)req32.list, - &request->list)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request); -} - -typedef struct drm_ctx_priv_map32 { - unsigned int ctx_id; /**< Context requesting private mapping */ - u32 handle; /**< Handle of map */ -} drm_ctx_priv_map32_t; - -static int compat_drm_setsareactx(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_priv_map32_t req32; - struct drm_ctx_priv_map __user *request; - drm_ctx_priv_map32_t __user *argp = (void __user *)arg; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) - return -EFAULT; - if (__put_user(req32.ctx_id, &request->ctx_id) - || __put_user((void *)(unsigned long)req32.handle, - &request->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); -} - -static int compat_drm_getsareactx(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct drm_ctx_priv_map __user *request; - drm_ctx_priv_map32_t __user *argp = (void __user *)arg; - int err; - unsigned int ctx_id; - void *handle; - - if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(ctx_id, &argp->ctx_id)) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request))) - return -EFAULT; - if (__put_user(ctx_id, &request->ctx_id)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); - if (err) - return err; - - if (__get_user(handle, &request->handle) - || __put_user((unsigned long)handle, &argp->handle)) - return -EFAULT; - - return 0; -} - -typedef struct drm_ctx_res32 { - int count; - u32 contexts; -} drm_ctx_res32_t; - -static int compat_drm_resctx(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_res32_t __user *argp = (void __user *)arg; - drm_ctx_res32_t res32; - struct drm_ctx_res __user *res; - int err; - - if (copy_from_user(&res32, argp, sizeof(res32))) - return -EFAULT; - - res = compat_alloc_user_space(sizeof(*res)); - if (!access_ok(VERIFY_WRITE, res, sizeof(*res))) - return -EFAULT; - if (__put_user(res32.count, &res->count) - || __put_user((struct drm_ctx __user *) (unsigned long)res32.contexts, - &res->contexts)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res); - if (err) - return err; - - if (__get_user(res32.count, &res->count) - || __put_user(res32.count, &argp->count)) - return -EFAULT; - - return 0; -} - -typedef struct drm_dma32 { - int context; /**< Context handle */ - int send_count; /**< Number of buffers to send */ - u32 send_indices; /**< List of handles to buffers */ - u32 send_sizes; /**< Lengths of data to send */ - enum drm_dma_flags flags; /**< Flags */ - int request_count; /**< Number of buffers requested */ - int request_size; /**< Desired size for buffers */ - u32 request_indices; /**< Buffer information */ - u32 request_sizes; - int granted_count; /**< Number of buffers granted */ -} drm_dma32_t; - -static int compat_drm_dma(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_dma32_t d32; - drm_dma32_t __user *argp = (void __user *)arg; - struct drm_dma __user *d; - int err; - - if (copy_from_user(&d32, argp, sizeof(d32))) - return -EFAULT; - - d = compat_alloc_user_space(sizeof(*d)); - if (!access_ok(VERIFY_WRITE, d, sizeof(*d))) - return -EFAULT; - - if (__put_user(d32.context, &d->context) - || __put_user(d32.send_count, &d->send_count) - || __put_user((int __user *)(unsigned long)d32.send_indices, - &d->send_indices) - || __put_user((int __user *)(unsigned long)d32.send_sizes, - &d->send_sizes) - || __put_user(d32.flags, &d->flags) - || __put_user(d32.request_count, &d->request_count) - || __put_user((int __user *)(unsigned long)d32.request_indices, - &d->request_indices) - || __put_user((int __user *)(unsigned long)d32.request_sizes, - &d->request_sizes)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d); - if (err) - return err; - - if (__get_user(d32.request_size, &d->request_size) - || __get_user(d32.granted_count, &d->granted_count) - || __put_user(d32.request_size, &argp->request_size) - || __put_user(d32.granted_count, &argp->granted_count)) - return -EFAULT; - - return 0; -} - -#if __OS_HAS_AGP -typedef struct drm_agp_mode32 { - u32 mode; /**< AGP mode */ -} drm_agp_mode32_t; - -static int compat_drm_agp_enable(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_mode32_t __user *argp = (void __user *)arg; - drm_agp_mode32_t m32; - struct drm_agp_mode __user *mode; - - if (get_user(m32.mode, &argp->mode)) - return -EFAULT; - - mode = compat_alloc_user_space(sizeof(*mode)); - if (put_user(m32.mode, &mode->mode)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); -} - -typedef struct drm_agp_info32 { - int agp_version_major; - int agp_version_minor; - u32 mode; - u32 aperture_base; /* physical address */ - u32 aperture_size; /* bytes */ - u32 memory_allowed; /* bytes */ - u32 memory_used; - - /* PCI information */ - unsigned short id_vendor; - unsigned short id_device; -} drm_agp_info32_t; - -static int compat_drm_agp_info(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_info32_t __user *argp = (void __user *)arg; - drm_agp_info32_t i32; - struct drm_agp_info __user *info; - int err; - - info = compat_alloc_user_space(sizeof(*info)); - if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info); - if (err) - return err; - - if (__get_user(i32.agp_version_major, &info->agp_version_major) - || __get_user(i32.agp_version_minor, &info->agp_version_minor) - || __get_user(i32.mode, &info->mode) - || __get_user(i32.aperture_base, &info->aperture_base) - || __get_user(i32.aperture_size, &info->aperture_size) - || __get_user(i32.memory_allowed, &info->memory_allowed) - || __get_user(i32.memory_used, &info->memory_used) - || __get_user(i32.id_vendor, &info->id_vendor) - || __get_user(i32.id_device, &info->id_device)) - return -EFAULT; - - if (copy_to_user(argp, &i32, sizeof(i32))) - return -EFAULT; - - return 0; -} - -typedef struct drm_agp_buffer32 { - u32 size; /**< In bytes -- will round to page boundary */ - u32 handle; /**< Used for binding / unbinding */ - u32 type; /**< Type of memory to allocate */ - u32 physical; /**< Physical used by i810 */ -} drm_agp_buffer32_t; - -static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_buffer32_t __user *argp = (void __user *)arg; - drm_agp_buffer32_t req32; - struct drm_agp_buffer __user *request; - int err; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.size, &request->size) - || __put_user(req32.type, &request->type)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request); - if (err) - return err; - - if (__get_user(req32.handle, &request->handle) - || __get_user(req32.physical, &request->physical) - || copy_to_user(argp, &req32, sizeof(req32))) { - drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); - return -EFAULT; - } - - return 0; -} - -static int compat_drm_agp_free(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_buffer32_t __user *argp = (void __user *)arg; - struct drm_agp_buffer __user *request; - u32 handle; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || get_user(handle, &argp->handle) - || __put_user(handle, &request->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request); -} - -typedef struct drm_agp_binding32 { - u32 handle; /**< From drm_agp_buffer */ - u32 offset; /**< In bytes -- will round to page boundary */ -} drm_agp_binding32_t; - -static int compat_drm_agp_bind(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_binding32_t __user *argp = (void __user *)arg; - drm_agp_binding32_t req32; - struct drm_agp_binding __user *request; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.handle, &request->handle) - || __put_user(req32.offset, &request->offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request); -} - -static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_agp_binding32_t __user *argp = (void __user *)arg; - struct drm_agp_binding __user *request; - u32 handle; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || get_user(handle, &argp->handle) - || __put_user(handle, &request->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request); -} -#endif /* __OS_HAS_AGP */ - -typedef struct drm_scatter_gather32 { - u32 size; /**< In bytes -- will round to page boundary */ - u32 handle; /**< Used for mapping / unmapping */ -} drm_scatter_gather32_t; - -static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_scatter_gather32_t __user *argp = (void __user *)arg; - struct drm_scatter_gather __user *request; - int err; - unsigned long x; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(x, &argp->size) - || __put_user(x, &request->size)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request); - if (err) - return err; - - /* XXX not sure about the handle conversion here... */ - if (__get_user(x, &request->handle) - || __put_user(x >> PAGE_SHIFT, &argp->handle)) - return -EFAULT; - - return 0; -} - -static int compat_drm_sg_free(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_scatter_gather32_t __user *argp = (void __user *)arg; - struct drm_scatter_gather __user *request; - unsigned long x; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)) - || __get_user(x, &argp->handle) - || __put_user(x << PAGE_SHIFT, &request->handle)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request); -} - -#if defined(CONFIG_X86) || defined(CONFIG_IA64) -typedef struct drm_update_draw32 { - drm_drawable_t handle; - unsigned int type; - unsigned int num; - /* 64-bit version has a 32-bit pad here */ - u64 data; /**< Pointer */ -} __attribute__((packed)) drm_update_draw32_t; - -static int compat_drm_update_draw(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_update_draw32_t update32; - struct drm_update_draw __user *request; - int err; - - if (copy_from_user(&update32, (void __user *)arg, sizeof(update32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) || - __put_user(update32.handle, &request->handle) || - __put_user(update32.type, &request->type) || - __put_user(update32.num, &request->num) || - __put_user(update32.data, &request->data)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request); - return err; -} -#endif - -struct drm_wait_vblank_request32 { - enum drm_vblank_seq_type type; - unsigned int sequence; - u32 signal; -}; - -struct drm_wait_vblank_reply32 { - enum drm_vblank_seq_type type; - unsigned int sequence; - s32 tval_sec; - s32 tval_usec; -}; - -typedef union drm_wait_vblank32 { - struct drm_wait_vblank_request32 request; - struct drm_wait_vblank_reply32 reply; -} drm_wait_vblank32_t; - -static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_wait_vblank32_t __user *argp = (void __user *)arg; - drm_wait_vblank32_t req32; - union drm_wait_vblank __user *request; - int err; - - if (copy_from_user(&req32, argp, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.request.type, &request->request.type) - || __put_user(req32.request.sequence, &request->request.sequence) - || __put_user(req32.request.signal, &request->request.signal)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); - if (err) - return err; - - if (__get_user(req32.reply.type, &request->reply.type) - || __get_user(req32.reply.sequence, &request->reply.sequence) - || __get_user(req32.reply.tval_sec, &request->reply.tval_sec) - || __get_user(req32.reply.tval_usec, &request->reply.tval_usec)) - return -EFAULT; - - if (copy_to_user(argp, &req32, sizeof(req32))) - return -EFAULT; - - return 0; -} - -drm_ioctl_compat_t *drm_compat_ioctls[] = { - [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, - [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, - [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap, - [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient, - [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats, - [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs, - [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs, - [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs, - [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs, - [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap, - [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx, - [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx, - [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx, - [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma, -#if __OS_HAS_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind, -#endif - [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc, - [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free, -#if defined(CONFIG_X86) || defined(CONFIG_IA64) - [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw, -#endif - [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/drm. - * - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn; - int ret; - - /* Assume that ioctls without an explicit compat routine will just - * work. This may not always be a good assumption, but it's better - * than always failing. - */ - if (nr >= ARRAY_SIZE(drm_compat_ioctls)) - return drm_ioctl(filp, cmd, arg); - - fn = drm_compat_ioctls[nr]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} - -EXPORT_SYMBOL(drm_compat_ioctl); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_ioctl.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_ioctl.c deleted file mode 100644 index cf85155d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_ioctl.c +++ /dev/null @@ -1,356 +0,0 @@ -/** - * \file drm_ioctl.c - * IOCTL processing for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_core.h" - -#include "linux/pci.h" -#include "linux/export.h" - -/** - * Get the bus id. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_unique structure. - * \return zero on success or a negative number on failure. - * - * Copies the bus id from drm_device::unique into user space. - */ -int drm_getunique(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_unique *u = data; - struct drm_master *master = file_priv->master; - - if (u->unique_len >= master->unique_len) { - if (copy_to_user(u->unique, master->unique, master->unique_len)) - return -EFAULT; - } - u->unique_len = master->unique_len; - - return 0; -} - -static void -drm_unset_busid(struct drm_device *dev, - struct drm_master *master) -{ - kfree(dev->devname); - dev->devname = NULL; - - kfree(master->unique); - master->unique = NULL; - master->unique_len = 0; - master->unique_size = 0; -} - -/** - * Set the bus id. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_unique structure. - * \return zero on success or a negative number on failure. - * - * Copies the bus id from userspace into drm_device::unique, and verifies that - * it matches the device this DRM is attached to (EINVAL otherwise). Deprecated - * in interface version 1.1 and will return EBUSY when setversion has requested - * version 1.1 or greater. - */ -int drm_setunique(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_unique *u = data; - struct drm_master *master = file_priv->master; - int ret; - - if (master->unique_len || master->unique) - return -EBUSY; - - if (!u->unique_len || u->unique_len > 1024) - return -EINVAL; - - if (!dev->driver->bus->set_unique) - return -EINVAL; - - ret = dev->driver->bus->set_unique(dev, master, u); - if (ret) - goto err; - - return 0; - -err: - drm_unset_busid(dev, master); - return ret; -} - -static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_master *master = file_priv->master; - int ret; - - if (master->unique != NULL) - drm_unset_busid(dev, master); - - ret = dev->driver->bus->set_busid(dev, master); - if (ret) - goto err; - return 0; -err: - drm_unset_busid(dev, master); - return ret; -} - -/** - * Get a mapping information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_map structure. - * - * \return zero on success or a negative number on failure. - * - * Searches for the mapping with the specified offset and copies its information - * into userspace - */ -int drm_getmap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_map *map = data; - struct drm_map_list *r_list = NULL; - struct list_head *list; - int idx; - int i; - - idx = map->offset; - if (idx < 0) - return -EINVAL; - - i = 0; - mutex_lock(&dev->struct_mutex); - list_for_each(list, &dev->maplist) { - if (i == idx) { - r_list = list_entry(list, struct drm_map_list, head); - break; - } - i++; - } - if (!r_list || !r_list->map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - map->offset = r_list->map->offset; - map->size = r_list->map->size; - map->type = r_list->map->type; - map->flags = r_list->map->flags; - map->handle = (void *)(unsigned long) r_list->user_token; - map->mtrr = r_list->map->mtrr; - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Get client information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_client structure. - * - * \return zero on success or a negative number on failure. - * - * Searches for the client with the specified index and copies its information - * into userspace - */ -int drm_getclient(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_client *client = data; - struct drm_file *pt; - int idx; - int i; - - idx = client->idx; - i = 0; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry(pt, &dev->filelist, lhead) { - if (i++ >= idx) { - client->auth = pt->authenticated; - client->pid = pt->pid; - client->uid = pt->uid; - client->magic = pt->magic; - client->iocs = pt->ioctl_count; - mutex_unlock(&dev->struct_mutex); - - return 0; - } - } - mutex_unlock(&dev->struct_mutex); - - return -EINVAL; -} - -/** - * Get statistics information. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_stats structure. - * - * \return zero on success or a negative number on failure. - */ -int drm_getstats(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_stats *stats = data; - int i; - - memset(stats, 0, sizeof(*stats)); - - for (i = 0; i < dev->counters; i++) { - if (dev->types[i] == _DRM_STAT_LOCK) - stats->data[i].value = - (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0); - else - stats->data[i].value = atomic_read(&dev->counts[i]); - stats->data[i].type = dev->types[i]; - } - - stats->count = dev->counters; - - return 0; -} - -/** - * Get device/driver capabilities - */ -int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_get_cap *req = data; - - req->value = 0; - switch (req->capability) { - case DRM_CAP_DUMB_BUFFER: - if (dev->driver->dumb_create) - req->value = 1; - break; - case DRM_CAP_VBLANK_HIGH_CRTC: - req->value = 1; - break; - case DRM_CAP_DUMB_PREFERRED_DEPTH: - req->value = dev->mode_config.preferred_depth; - break; - case DRM_CAP_DUMB_PREFER_SHADOW: - req->value = dev->mode_config.prefer_shadow; - break; - default: - return -EINVAL; - } - return 0; -} - -/** - * Setversion ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_lock structure. - * \return zero on success or negative number on failure. - * - * Sets the requested interface version - */ -int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_set_version *sv = data; - int if_version, retcode = 0; - - if (sv->drm_di_major != -1) { - if (sv->drm_di_major != DRM_IF_MAJOR || - sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) { - retcode = -EINVAL; - goto done; - } - if_version = DRM_IF_VERSION(sv->drm_di_major, - sv->drm_di_minor); - dev->if_version = max(if_version, dev->if_version); - if (sv->drm_di_minor >= 1) { - /* - * Version 1.1 includes tying of DRM to specific device - * Version 1.4 has proper PCI domain support - */ - retcode = drm_set_busid(dev, file_priv); - if (retcode) - goto done; - } - } - - if (sv->drm_dd_major != -1) { - if (sv->drm_dd_major != dev->driver->major || - sv->drm_dd_minor < 0 || sv->drm_dd_minor > - dev->driver->minor) { - retcode = -EINVAL; - goto done; - } - - if (dev->driver->set_version) - dev->driver->set_version(dev, sv); - } - -done: - sv->drm_di_major = DRM_IF_MAJOR; - sv->drm_di_minor = DRM_IF_MINOR; - sv->drm_dd_major = dev->driver->major; - sv->drm_dd_minor = dev->driver->minor; - - return retcode; -} - -/** No-op ioctl. */ -int drm_noop(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - return 0; -} -EXPORT_SYMBOL(drm_noop); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_irq.c deleted file mode 100644 index c869436e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_irq.c +++ /dev/null @@ -1,1348 +0,0 @@ -/** - * \file drm_irq.c - * IRQ support - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com - * - * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_trace.h" - -#include /* For task queue support */ -#include - -#include -#include - -/* Access macro for slots in vblank timestamp ringbuffer. */ -#define vblanktimestamp(dev, crtc, count) ( \ - (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \ - ((count) % DRM_VBLANKTIME_RBSIZE)]) - -/* Retry timestamp calculation up to 3 times to satisfy - * drm_timestamp_precision before giving up. - */ -#define DRM_TIMESTAMP_MAXRETRIES 3 - -/* Threshold in nanoseconds for detection of redundant - * vblank irq in drm_handle_vblank(). 1 msec should be ok. - */ -#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 - -/** - * Get interrupt from bus id. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_irq_busid structure. - * \return zero on success or a negative number on failure. - * - * Finds the PCI device with the specified bus id and gets its IRQ number. - * This IOCTL is deprecated, and will now return EINVAL for any busid not equal - * to that of the device that this DRM instance attached to. - */ -int drm_irq_by_busid(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_irq_busid *p = data; - - if (!dev->driver->bus->irq_by_busid) - return -EINVAL; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; - - return dev->driver->bus->irq_by_busid(dev, p); -} - -/* - * Clear vblank timestamp buffer for a crtc. - */ -static void clear_vblank_timestamps(struct drm_device *dev, int crtc) -{ - memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, - DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval)); -} - -/* - * Disable vblank irq's on crtc, make sure that last vblank count - * of hardware and corresponding consistent software vblank counter - * are preserved, even if there are any spurious vblank irq's after - * disable. - */ -static void vblank_disable_and_save(struct drm_device *dev, int crtc) -{ - unsigned long irqflags; - u32 vblcount; - s64 diff_ns; - int vblrc; - struct timeval tvblank; - - /* Prevent vblank irq processing while disabling vblank irqs, - * so no updates of timestamps or count can happen after we've - * disabled. Needed to prevent races in case of delayed irq's. - */ - spin_lock_irqsave(&dev->vblank_time_lock, irqflags); - - dev->driver->disable_vblank(dev, crtc); - dev->vblank_enabled[crtc] = 0; - - /* No further vblank irq's will be processed after - * this point. Get current hardware vblank count and - * vblank timestamp, repeat until they are consistent. - * - * FIXME: There is still a race condition here and in - * drm_update_vblank_count() which can cause off-by-one - * reinitialization of software vblank counter. If gpu - * vblank counter doesn't increment exactly at the leading - * edge of a vblank interval, then we can lose 1 count if - * we happen to execute between start of vblank and the - * delayed gpu counter increment. - */ - do { - dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); - vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); - } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc)); - - /* Compute time difference to stored timestamp of last vblank - * as updated by last invocation of drm_handle_vblank() in vblank irq. - */ - vblcount = atomic_read(&dev->_vblank_count[crtc]); - diff_ns = timeval_to_ns(&tvblank) - - timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); - - /* If there is at least 1 msec difference between the last stored - * timestamp and tvblank, then we are currently executing our - * disable inside a new vblank interval, the tvblank timestamp - * corresponds to this new vblank interval and the irq handler - * for this vblank didn't run yet and won't run due to our disable. - * Therefore we need to do the job of drm_handle_vblank() and - * increment the vblank counter by one to account for this vblank. - * - * Skip this step if there isn't any high precision timestamp - * available. In that case we can't account for this and just - * hope for the best. - */ - if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { - atomic_inc(&dev->_vblank_count[crtc]); - smp_mb__after_atomic_inc(); - } - - /* Invalidate all timestamps while vblank irq's are off. */ - clear_vblank_timestamps(dev, crtc); - - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); -} - -static void vblank_disable_fn(unsigned long arg) -{ - struct drm_device *dev = (struct drm_device *)arg; - unsigned long irqflags; - int i; - - if (!dev->vblank_disable_allowed) - return; - - for (i = 0; i < dev->num_crtcs; i++) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - if (atomic_read(&dev->vblank_refcount[i]) == 0 && - dev->vblank_enabled[i]) { - DRM_DEBUG("disabling vblank on crtc %d\n", i); - vblank_disable_and_save(dev, i); - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - } -} - -void drm_vblank_cleanup(struct drm_device *dev) -{ - /* Bail if the driver didn't call drm_vblank_init() */ - if (dev->num_crtcs == 0) - return; - - del_timer(&dev->vblank_disable_timer); - - vblank_disable_fn((unsigned long)dev); - - kfree(dev->vbl_queue); - kfree(dev->_vblank_count); - kfree(dev->vblank_refcount); - kfree(dev->vblank_enabled); - kfree(dev->last_vblank); - kfree(dev->last_vblank_wait); - kfree(dev->vblank_inmodeset); - kfree(dev->_vblank_time); - - dev->num_crtcs = 0; -} -EXPORT_SYMBOL(drm_vblank_cleanup); - -int drm_vblank_init(struct drm_device *dev, int num_crtcs) -{ - int i, ret = -ENOMEM; - - setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, - (unsigned long)dev); - spin_lock_init(&dev->vbl_lock); - spin_lock_init(&dev->vblank_time_lock); - - dev->num_crtcs = num_crtcs; - - dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs, - GFP_KERNEL); - if (!dev->vbl_queue) - goto err; - - dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL); - if (!dev->_vblank_count) - goto err; - - dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, - GFP_KERNEL); - if (!dev->vblank_refcount) - goto err; - - dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); - if (!dev->vblank_enabled) - goto err; - - dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); - if (!dev->last_vblank) - goto err; - - dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); - if (!dev->last_vblank_wait) - goto err; - - dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); - if (!dev->vblank_inmodeset) - goto err; - - dev->_vblank_time = kcalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE, - sizeof(struct timeval), GFP_KERNEL); - if (!dev->_vblank_time) - goto err; - - DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); - - /* Driver specific high-precision vblank timestamping supported? */ - if (dev->driver->get_vblank_timestamp) - DRM_INFO("Driver supports precise vblank timestamp query.\n"); - else - DRM_INFO("No driver support for vblank timestamp query.\n"); - - /* Zero per-crtc vblank stuff */ - for (i = 0; i < num_crtcs; i++) { - init_waitqueue_head(&dev->vbl_queue[i]); - atomic_set(&dev->_vblank_count[i], 0); - atomic_set(&dev->vblank_refcount[i], 0); - } - - dev->vblank_disable_allowed = 0; - return 0; - -err: - drm_vblank_cleanup(dev); - return ret; -} -EXPORT_SYMBOL(drm_vblank_init); - -static void drm_irq_vgaarb_nokms(void *cookie, bool state) -{ - struct drm_device *dev = cookie; - - if (dev->driver->vgaarb_irq) { - dev->driver->vgaarb_irq(dev, state); - return; - } - - if (!dev->irq_enabled) - return; - - if (state) { - if (dev->driver->irq_uninstall) - dev->driver->irq_uninstall(dev); - } else { - if (dev->driver->irq_preinstall) - dev->driver->irq_preinstall(dev); - if (dev->driver->irq_postinstall) - dev->driver->irq_postinstall(dev); - } -} - -/** - * Install IRQ handler. - * - * \param dev DRM device. - * - * Initializes the IRQ related data. Installs the handler, calling the driver - * \c irq_preinstall() and \c irq_postinstall() functions - * before and after the installation. - */ -int drm_irq_install(struct drm_device *dev) -{ - int ret = 0; - unsigned long sh_flags = 0; - char *irqname; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; - - if (drm_dev_to_irq(dev) == 0) - return -EINVAL; - - mutex_lock(&dev->struct_mutex); - - /* Driver must have been initialized */ - if (!dev->dev_private) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - if (dev->irq_enabled) { - mutex_unlock(&dev->struct_mutex); - return -EBUSY; - } - dev->irq_enabled = 1; - mutex_unlock(&dev->struct_mutex); - - DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); - - /* Before installing handler */ - if (dev->driver->irq_preinstall) - dev->driver->irq_preinstall(dev); - - /* Install handler */ - if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) - sh_flags = IRQF_SHARED; - - if (dev->devname) - irqname = dev->devname; - else - irqname = dev->driver->name; - - ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, - sh_flags, irqname, dev); - - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - return ret; - } - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL); - - /* After installing handler */ - if (dev->driver->irq_postinstall) - ret = dev->driver->irq_postinstall(dev); - - if (ret < 0) { - mutex_lock(&dev->struct_mutex); - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - vga_client_register(dev->pdev, NULL, NULL, NULL); - free_irq(drm_dev_to_irq(dev), dev); - } - - return ret; -} -EXPORT_SYMBOL(drm_irq_install); - -/** - * Uninstall the IRQ handler. - * - * \param dev DRM device. - * - * Calls the driver's \c irq_uninstall() function, and stops the irq. - */ -int drm_irq_uninstall(struct drm_device *dev) -{ - unsigned long irqflags; - int irq_enabled, i; - - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return -EINVAL; - - mutex_lock(&dev->struct_mutex); - irq_enabled = dev->irq_enabled; - dev->irq_enabled = 0; - mutex_unlock(&dev->struct_mutex); - - /* - * Wake up any waiters so they don't hang. - */ - if (dev->num_crtcs) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - for (i = 0; i < dev->num_crtcs; i++) { - DRM_WAKEUP(&dev->vbl_queue[i]); - dev->vblank_enabled[i] = 0; - dev->last_vblank[i] = - dev->driver->get_vblank_counter(dev, i); - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - } - - if (!irq_enabled) - return -EINVAL; - - DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - vga_client_register(dev->pdev, NULL, NULL, NULL); - - if (dev->driver->irq_uninstall) - dev->driver->irq_uninstall(dev); - - free_irq(drm_dev_to_irq(dev), dev); - - return 0; -} -EXPORT_SYMBOL(drm_irq_uninstall); - -/** - * IRQ control ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_control structure. - * \return zero on success or a negative number on failure. - * - * Calls irq_install() or irq_uninstall() according to \p arg. - */ -int drm_control(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_control *ctl = data; - - /* if we haven't irq we fallback for compatibility reasons - - * this used to be a separate function in drm_dma.h - */ - - - switch (ctl->func) { - case DRM_INST_HANDLER: - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return 0; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - if (dev->if_version < DRM_IF_VERSION(1, 2) && - ctl->irq != drm_dev_to_irq(dev)) - return -EINVAL; - return drm_irq_install(dev); - case DRM_UNINST_HANDLER: - if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) - return 0; - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - return drm_irq_uninstall(dev); - default: - return -EINVAL; - } -} - -/** - * drm_calc_timestamping_constants - Calculate and - * store various constants which are later needed by - * vblank and swap-completion timestamping, e.g, by - * drm_calc_vbltimestamp_from_scanoutpos(). - * They are derived from crtc's true scanout timing, - * so they take things like panel scaling or other - * adjustments into account. - * - * @crtc drm_crtc whose timestamp constants should be updated. - * - */ -void drm_calc_timestamping_constants(struct drm_crtc *crtc) -{ - s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; - u64 dotclock; - - /* Dot clock in Hz: */ - dotclock = (u64) crtc->hwmode.clock * 1000; - - /* Fields of interlaced scanout modes are only halve a frame duration. - * Double the dotclock to get halve the frame-/line-/pixelduration. - */ - if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) - dotclock *= 2; - - /* Valid dotclock? */ - if (dotclock > 0) { - /* Convert scanline length in pixels and video dot clock to - * line duration, frame duration and pixel duration in - * nanoseconds: - */ - pixeldur_ns = (s64) div64_u64(1000000000, dotclock); - linedur_ns = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal * - 1000000000), dotclock); - framedur_ns = (s64) crtc->hwmode.crtc_vtotal * linedur_ns; - } else - DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", - crtc->base.id); - - crtc->pixeldur_ns = pixeldur_ns; - crtc->linedur_ns = linedur_ns; - crtc->framedur_ns = framedur_ns; - - DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", - crtc->base.id, crtc->hwmode.crtc_htotal, - crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); - DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", - crtc->base.id, (int) dotclock/1000, (int) framedur_ns, - (int) linedur_ns, (int) pixeldur_ns); -} -EXPORT_SYMBOL(drm_calc_timestamping_constants); - -/** - * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms - * drivers. Implements calculation of exact vblank timestamps from - * given drm_display_mode timings and current video scanout position - * of a crtc. This can be called from within get_vblank_timestamp() - * implementation of a kms driver to implement the actual timestamping. - * - * Should return timestamps conforming to the OML_sync_control OpenML - * extension specification. The timestamp corresponds to the end of - * the vblank interval, aka start of scanout of topmost-leftmost display - * pixel in the following video frame. - * - * Requires support for optional dev->driver->get_scanout_position() - * in kms driver, plus a bit of setup code to provide a drm_display_mode - * that corresponds to the true scanout timing. - * - * The current implementation only handles standard video modes. It - * returns as no operation if a doublescan or interlaced video mode is - * active. Higher level code is expected to handle this. - * - * @dev: DRM device. - * @crtc: Which crtc's vblank timestamp to retrieve. - * @max_error: Desired maximum allowable error in timestamps (nanosecs). - * On return contains true maximum error of timestamp. - * @vblank_time: Pointer to struct timeval which should receive the timestamp. - * @flags: Flags to pass to driver: - * 0 = Default. - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. - * @refcrtc: drm_crtc* of crtc which defines scanout timing. - * - * Returns negative value on error, failure or if not supported in current - * video mode: - * - * -EINVAL - Invalid crtc. - * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. - * -ENOTSUPP - Function not supported in current display mode. - * -EIO - Failed, e.g., due to failed scanout position query. - * - * Returns or'ed positive status flags on success: - * - * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. - * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. - * - */ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags, - struct drm_crtc *refcrtc) -{ - struct timeval stime, raw_time; - struct drm_display_mode *mode; - int vbl_status, vtotal, vdisplay; - int vpos, hpos, i; - s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; - bool invbl; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; - } - - /* Scanout position query not supported? Should not happen. */ - if (!dev->driver->get_scanout_position) { - DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; - } - - mode = &refcrtc->hwmode; - vtotal = mode->crtc_vtotal; - vdisplay = mode->crtc_vdisplay; - - /* Durations of frames, lines, pixels in nanoseconds. */ - framedur_ns = refcrtc->framedur_ns; - linedur_ns = refcrtc->linedur_ns; - pixeldur_ns = refcrtc->pixeldur_ns; - - /* If mode timing undefined, just return as no-op: - * Happens during initial modesetting of a crtc. - */ - if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { - DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); - return -EAGAIN; - } - - /* Get current scanout position with system timestamp. - * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times - * if single query takes longer than max_error nanoseconds. - * - * This guarantees a tight bound on maximum error if - * code gets preempted or delayed for some reason. - */ - for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { - /* Disable preemption to make it very likely to - * succeed in the first iteration even on PREEMPT_RT kernel. - */ - preempt_disable(); - - /* Get system timestamp before query. */ - do_gettimeofday(&stime); - - /* Get vertical and horizontal scanout pos. vpos, hpos. */ - vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); - - /* Get system timestamp after query. */ - do_gettimeofday(&raw_time); - - preempt_enable(); - - /* Return as no-op if scanout query unsupported or failed. */ - if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", - crtc, vbl_status); - return -EIO; - } - - duration_ns = timeval_to_ns(&raw_time) - timeval_to_ns(&stime); - - /* Accept result with < max_error nsecs timing uncertainty. */ - if (duration_ns <= (s64) *max_error) - break; - } - - /* Noisy system timing? */ - if (i == DRM_TIMESTAMP_MAXRETRIES) { - DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", - crtc, (int) duration_ns/1000, *max_error/1000, i); - } - - /* Return upper bound of timestamp precision error. */ - *max_error = (int) duration_ns; - - /* Check if in vblank area: - * vpos is >=0 in video scanout area, but negative - * within vblank area, counting down the number of lines until - * start of scanout. - */ - invbl = vbl_status & DRM_SCANOUTPOS_INVBL; - - /* Convert scanout position into elapsed time at raw_time query - * since start of scanout at first display scanline. delta_ns - * can be negative if start of scanout hasn't happened yet. - */ - delta_ns = (s64) vpos * linedur_ns + (s64) hpos * pixeldur_ns; - - /* Is vpos outside nominal vblank area, but less than - * 1/100 of a frame height away from start of vblank? - * If so, assume this isn't a massively delayed vblank - * interrupt, but a vblank interrupt that fired a few - * microseconds before true start of vblank. Compensate - * by adding a full frame duration to the final timestamp. - * Happens, e.g., on ATI R500, R600. - * - * We only do this if DRM_CALLED_FROM_VBLIRQ. - */ - if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && - ((vdisplay - vpos) < vtotal / 100)) { - delta_ns = delta_ns - framedur_ns; - - /* Signal this correction as "applied". */ - vbl_status |= 0x8; - } - - /* Subtract time delta from raw timestamp to get final - * vblank_time timestamp for end of vblank. - */ - *vblank_time = ns_to_timeval(timeval_to_ns(&raw_time) - delta_ns); - - DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", - crtc, (int)vbl_status, hpos, vpos, - (long)raw_time.tv_sec, (long)raw_time.tv_usec, - (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, - (int)duration_ns/1000, i); - - vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; - if (invbl) - vbl_status |= DRM_VBLANKTIME_INVBL; - - return vbl_status; -} -EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); - -/** - * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent - * vblank interval. - * - * @dev: DRM device - * @crtc: which crtc's vblank timestamp to retrieve - * @tvblank: Pointer to target struct timeval which should receive the timestamp - * @flags: Flags to pass to driver: - * 0 = Default. - * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. - * - * Fetches the system timestamp corresponding to the time of the most recent - * vblank interval on specified crtc. May call into kms-driver to - * compute the timestamp with a high-precision GPU specific method. - * - * Returns zero if timestamp originates from uncorrected do_gettimeofday() - * call, i.e., it isn't very precisely locked to the true vblank. - * - * Returns non-zero if timestamp is considered to be very precise. - */ -u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, - struct timeval *tvblank, unsigned flags) -{ - int ret = 0; - - /* Define requested maximum error on timestamps (nanoseconds). */ - int max_error = (int) drm_timestamp_precision * 1000; - - /* Query driver if possible and precision timestamping enabled. */ - if (dev->driver->get_vblank_timestamp && (max_error > 0)) { - ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, - tvblank, flags); - if (ret > 0) - return (u32) ret; - } - - /* GPU high precision timestamp query unsupported or failed. - * Return gettimeofday timestamp as best estimate. - */ - do_gettimeofday(tvblank); - - return 0; -} -EXPORT_SYMBOL(drm_get_last_vbltimestamp); - -/** - * drm_vblank_count - retrieve "cooked" vblank counter value - * @dev: DRM device - * @crtc: which counter to retrieve - * - * Fetches the "cooked" vblank count value that represents the number of - * vblank events since the system was booted, including lost events due to - * modesetting activity. - */ -u32 drm_vblank_count(struct drm_device *dev, int crtc) -{ - return atomic_read(&dev->_vblank_count[crtc]); -} -EXPORT_SYMBOL(drm_vblank_count); - -/** - * drm_vblank_count_and_time - retrieve "cooked" vblank counter value - * and the system timestamp corresponding to that vblank counter value. - * - * @dev: DRM device - * @crtc: which counter to retrieve - * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. - * - * Fetches the "cooked" vblank count value that represents the number of - * vblank events since the system was booted, including lost events due to - * modesetting activity. Returns corresponding system timestamp of the time - * of the vblank interval that corresponds to the current value vblank counter - * value. - */ -u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, - struct timeval *vblanktime) -{ - u32 cur_vblank; - - /* Read timestamp from slot of _vblank_time ringbuffer - * that corresponds to current vblank count. Retry if - * count has incremented during readout. This works like - * a seqlock. - */ - do { - cur_vblank = atomic_read(&dev->_vblank_count[crtc]); - *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); - smp_rmb(); - } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); - - return cur_vblank; -} -EXPORT_SYMBOL(drm_vblank_count_and_time); - -/** - * drm_update_vblank_count - update the master vblank counter - * @dev: DRM device - * @crtc: counter to update - * - * Call back into the driver to update the appropriate vblank counter - * (specified by @crtc). Deal with wraparound, if it occurred, and - * update the last read value so we can deal with wraparound on the next - * call if necessary. - * - * Only necessary when going from off->on, to account for frames we - * didn't get an interrupt for. - * - * Note: caller must hold dev->vbl_lock since this reads & writes - * device vblank fields. - */ -static void drm_update_vblank_count(struct drm_device *dev, int crtc) -{ - u32 cur_vblank, diff, tslot, rc; - struct timeval t_vblank; - - /* - * Interrupts were disabled prior to this call, so deal with counter - * wrap if needed. - * NOTE! It's possible we lost a full dev->max_vblank_count events - * here if the register is small or we had vblank interrupts off for - * a long time. - * - * We repeat the hardware vblank counter & timestamp query until - * we get consistent results. This to prevent races between gpu - * updating its hardware counter while we are retrieving the - * corresponding vblank timestamp. - */ - do { - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); - rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); - } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); - - /* Deal with counter wrap */ - diff = cur_vblank - dev->last_vblank[crtc]; - if (cur_vblank < dev->last_vblank[crtc]) { - diff += dev->max_vblank_count; - - DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", - crtc, dev->last_vblank[crtc], cur_vblank, diff); - } - - DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", - crtc, diff); - - /* Reinitialize corresponding vblank timestamp if high-precision query - * available. Skip this step if query unsupported or failed. Will - * reinitialize delayed at next vblank interrupt in that case. - */ - if (rc) { - tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; - vblanktimestamp(dev, crtc, tslot) = t_vblank; - } - - smp_mb__before_atomic_inc(); - atomic_add(diff, &dev->_vblank_count[crtc]); - smp_mb__after_atomic_inc(); -} - -/** - * drm_vblank_get - get a reference count on vblank events - * @dev: DRM device - * @crtc: which CRTC to own - * - * Acquire a reference count on vblank events to avoid having them disabled - * while in use. - * - * RETURNS - * Zero on success, nonzero on failure. - */ -int drm_vblank_get(struct drm_device *dev, int crtc) -{ - unsigned long irqflags, irqflags2; - int ret = 0; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); - /* Going from 0->1 means we have to enable interrupts again */ - if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { - spin_lock_irqsave(&dev->vblank_time_lock, irqflags2); - if (!dev->vblank_enabled[crtc]) { - /* Enable vblank irqs under vblank_time_lock protection. - * All vblank count & timestamp updates are held off - * until we are done reinitializing master counter and - * timestamps. Filtercode in drm_handle_vblank() will - * prevent double-accounting of same vblank interval. - */ - ret = dev->driver->enable_vblank(dev, crtc); - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", - crtc, ret); - if (ret) - atomic_dec(&dev->vblank_refcount[crtc]); - else { - dev->vblank_enabled[crtc] = 1; - drm_update_vblank_count(dev, crtc); - } - } - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2); - } else { - if (!dev->vblank_enabled[crtc]) { - atomic_dec(&dev->vblank_refcount[crtc]); - ret = -EINVAL; - } - } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - return ret; -} -EXPORT_SYMBOL(drm_vblank_get); - -/** - * drm_vblank_put - give up ownership of vblank events - * @dev: DRM device - * @crtc: which counter to give up - * - * Release ownership of a given vblank counter, turning off interrupts - * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. - */ -void drm_vblank_put(struct drm_device *dev, int crtc) -{ - BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); - - /* Last user schedules interrupt disable */ - if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && - (drm_vblank_offdelay > 0)) - mod_timer(&dev->vblank_disable_timer, - jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000)); -} -EXPORT_SYMBOL(drm_vblank_put); - -void drm_vblank_off(struct drm_device *dev, int crtc) -{ - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long irqflags; - unsigned int seq; - - spin_lock_irqsave(&dev->vbl_lock, irqflags); - vblank_disable_and_save(dev, crtc); - DRM_WAKEUP(&dev->vbl_queue[crtc]); - - /* Send any queued vblank events, lest the natives grow disquiet */ - seq = drm_vblank_count_and_time(dev, crtc, &now); - list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { - if (e->pipe != crtc) - continue; - DRM_DEBUG("Sending premature vblank event on disable: \ - wanted %d, current %d\n", - e->event.sequence, seq); - - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, e->pipe); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - trace_drm_vblank_event_delivered(e->base.pid, e->pipe, - e->event.sequence); - } - - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); -} -EXPORT_SYMBOL(drm_vblank_off); - -/** - * drm_vblank_pre_modeset - account for vblanks across mode sets - * @dev: DRM device - * @crtc: CRTC in question - * @post: post or pre mode set? - * - * Account for vblank events across mode setting events, which will likely - * reset the hardware frame counter. - */ -void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) -{ - /* vblank is not initialized (IRQ not installed ?) */ - if (!dev->num_crtcs) - return; - /* - * To avoid all the problems that might happen if interrupts - * were enabled/disabled around or between these calls, we just - * have the kernel take a reference on the CRTC (just once though - * to avoid corrupting the count if multiple, mismatch calls occur), - * so that interrupts remain enabled in the interim. - */ - if (!dev->vblank_inmodeset[crtc]) { - dev->vblank_inmodeset[crtc] = 0x1; - if (drm_vblank_get(dev, crtc) == 0) - dev->vblank_inmodeset[crtc] |= 0x2; - } -} -EXPORT_SYMBOL(drm_vblank_pre_modeset); - -void drm_vblank_post_modeset(struct drm_device *dev, int crtc) -{ - unsigned long irqflags; - - if (dev->vblank_inmodeset[crtc]) { - spin_lock_irqsave(&dev->vbl_lock, irqflags); - dev->vblank_disable_allowed = 1; - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - - if (dev->vblank_inmodeset[crtc] & 0x2) - drm_vblank_put(dev, crtc); - - dev->vblank_inmodeset[crtc] = 0; - } -} -EXPORT_SYMBOL(drm_vblank_post_modeset); - -/** - * drm_modeset_ctl - handle vblank event counter changes across mode switch - * @DRM_IOCTL_ARGS: standard ioctl arguments - * - * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET - * ioctls around modesetting so that any lost vblank events are accounted for. - * - * Generally the counter will reset across mode sets. If interrupts are - * enabled around this call, we don't have to do anything since the counter - * will have already been incremented. - */ -int drm_modeset_ctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_modeset_ctl *modeset = data; - int ret = 0; - unsigned int crtc; - - /* If drm_vblank_init() hasn't been called yet, just no-op */ - if (!dev->num_crtcs) - goto out; - - crtc = modeset->crtc; - if (crtc >= dev->num_crtcs) { - ret = -EINVAL; - goto out; - } - - switch (modeset->cmd) { - case _DRM_PRE_MODESET: - drm_vblank_pre_modeset(dev, crtc); - break; - case _DRM_POST_MODESET: - drm_vblank_post_modeset(dev, crtc); - break; - default: - ret = -EINVAL; - break; - } - -out: - return ret; -} - -static int drm_queue_vblank_event(struct drm_device *dev, int pipe, - union drm_wait_vblank *vblwait, - struct drm_file *file_priv) -{ - struct drm_pending_vblank_event *e; - struct timeval now; - unsigned long flags; - unsigned int seq; - int ret; - - e = kzalloc(sizeof *e, GFP_KERNEL); - if (e == NULL) { - ret = -ENOMEM; - goto err_put; - } - - e->pipe = pipe; - e->base.pid = current->pid; - e->event.base.type = DRM_EVENT_VBLANK; - e->event.base.length = sizeof e->event; - e->event.user_data = vblwait->request.signal; - e->base.event = &e->event.base; - e->base.file_priv = file_priv; - e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; - - spin_lock_irqsave(&dev->event_lock, flags); - - if (file_priv->event_space < sizeof e->event) { - ret = -EBUSY; - goto err_unlock; - } - - file_priv->event_space -= sizeof e->event; - seq = drm_vblank_count_and_time(dev, pipe, &now); - - if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && - (seq - vblwait->request.sequence) <= (1 << 23)) { - vblwait->request.sequence = seq + 1; - vblwait->reply.sequence = vblwait->request.sequence; - } - - DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n", - vblwait->request.sequence, seq, pipe); - - trace_drm_vblank_event_queued(current->pid, pipe, - vblwait->request.sequence); - - e->event.sequence = vblwait->request.sequence; - if ((seq - vblwait->request.sequence) <= (1 << 23)) { - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, pipe); - list_add_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - vblwait->reply.sequence = seq; - trace_drm_vblank_event_delivered(current->pid, pipe, - vblwait->request.sequence); - } else { - /* drm_handle_vblank_events will call drm_vblank_put */ - list_add_tail(&e->base.link, &dev->vblank_event_list); - vblwait->reply.sequence = vblwait->request.sequence; - } - - spin_unlock_irqrestore(&dev->event_lock, flags); - - return 0; - -err_unlock: - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); -err_put: - drm_vblank_put(dev, pipe); - return ret; -} - -/** - * Wait for VBLANK. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param data user argument, pointing to a drm_wait_vblank structure. - * \return zero on success or a negative number on failure. - * - * This function enables the vblank interrupt on the pipe requested, then - * sleeps waiting for the requested sequence number to occur, and drops - * the vblank interrupt refcount afterwards. (vblank irq disable follows that - * after a timeout with no further vblank waits scheduled). - */ -int drm_wait_vblank(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - union drm_wait_vblank *vblwait = data; - int ret = 0; - unsigned int flags, seq, crtc, high_crtc; - - if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled)) - return -EINVAL; - - if (vblwait->request.type & _DRM_VBLANK_SIGNAL) - return -EINVAL; - - if (vblwait->request.type & - ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | - _DRM_VBLANK_HIGH_CRTC_MASK)) { - DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n", - vblwait->request.type, - (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK | - _DRM_VBLANK_HIGH_CRTC_MASK)); - return -EINVAL; - } - - flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; - high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK); - if (high_crtc) - crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT; - else - crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; - if (crtc >= dev->num_crtcs) - return -EINVAL; - - ret = drm_vblank_get(dev, crtc); - if (ret) { - DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); - return ret; - } - seq = drm_vblank_count(dev, crtc); - - switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) { - case _DRM_VBLANK_RELATIVE: - vblwait->request.sequence += seq; - vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; - case _DRM_VBLANK_ABSOLUTE: - break; - default: - ret = -EINVAL; - goto done; - } - - if (flags & _DRM_VBLANK_EVENT) { - /* must hold on to the vblank ref until the event fires - * drm_vblank_put will be called asynchronously - */ - return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); - } - - if ((flags & _DRM_VBLANK_NEXTONMISS) && - (seq - vblwait->request.sequence) <= (1<<23)) { - vblwait->request.sequence = seq + 1; - } - - DRM_DEBUG("waiting on vblank count %d, crtc %d\n", - vblwait->request.sequence, crtc); - dev->last_vblank_wait[crtc] = vblwait->request.sequence; - DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, - (((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23)) || - !dev->irq_enabled)); - - if (ret != -EINTR) { - struct timeval now; - - vblwait->reply.sequence = drm_vblank_count_and_time(dev, crtc, &now); - vblwait->reply.tval_sec = now.tv_sec; - vblwait->reply.tval_usec = now.tv_usec; - - DRM_DEBUG("returning %d to client\n", - vblwait->reply.sequence); - } else { - DRM_DEBUG("vblank wait interrupted by signal\n"); - } - -done: - drm_vblank_put(dev, crtc); - return ret; -} - -void drm_handle_vblank_events(struct drm_device *dev, int crtc) -{ - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - unsigned int seq; - - seq = drm_vblank_count_and_time(dev, crtc, &now); - - spin_lock_irqsave(&dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { - if (e->pipe != crtc) - continue; - if ((seq - e->event.sequence) > (1<<23)) - continue; - - DRM_DEBUG("vblank event on %d, current %d\n", - e->event.sequence, seq); - - e->event.sequence = seq; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, e->pipe); - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - trace_drm_vblank_event_delivered(e->base.pid, e->pipe, - e->event.sequence); - } - - spin_unlock_irqrestore(&dev->event_lock, flags); - - trace_drm_vblank_event(crtc, seq); -} - -/** - * drm_handle_vblank - handle a vblank event - * @dev: DRM device - * @crtc: where this event occurred - * - * Drivers should call this routine in their vblank interrupt handlers to - * update the vblank counter and send any signals that may be pending. - */ -bool drm_handle_vblank(struct drm_device *dev, int crtc) -{ - u32 vblcount; - s64 diff_ns; - struct timeval tvblank; - unsigned long irqflags; - - if (!dev->num_crtcs) - return false; - - /* Need timestamp lock to prevent concurrent execution with - * vblank enable/disable, as this would cause inconsistent - * or corrupted timestamps and vblank counts. - */ - spin_lock_irqsave(&dev->vblank_time_lock, irqflags); - - /* Vblank irq handling disabled. Nothing to do. */ - if (!dev->vblank_enabled[crtc]) { - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); - return false; - } - - /* Fetch corresponding timestamp for this vblank interval from - * driver and store it in proper slot of timestamp ringbuffer. - */ - - /* Get current timestamp and count. */ - vblcount = atomic_read(&dev->_vblank_count[crtc]); - drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); - - /* Compute time difference to timestamp of last vblank */ - diff_ns = timeval_to_ns(&tvblank) - - timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); - - /* Update vblank timestamp and count if at least - * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds - * difference between last stored timestamp and current - * timestamp. A smaller difference means basically - * identical timestamps. Happens if this vblank has - * been already processed and this is a redundant call, - * e.g., due to spurious vblank interrupts. We need to - * ignore those for accounting. - */ - if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { - /* Store new timestamp in ringbuffer. */ - vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; - - /* Increment cooked vblank count. This also atomically commits - * the timestamp computed above. - */ - smp_mb__before_atomic_inc(); - atomic_inc(&dev->_vblank_count[crtc]); - smp_mb__after_atomic_inc(); - } else { - DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", - crtc, (int) diff_ns); - } - - DRM_WAKEUP(&dev->vbl_queue[crtc]); - drm_handle_vblank_events(dev, crtc); - - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); - return true; -} -EXPORT_SYMBOL(drm_handle_vblank); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_lock.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_lock.c deleted file mode 100644 index c79c713e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_lock.c +++ /dev/null @@ -1,377 +0,0 @@ -/** - * \file drm_lock.c - * IOCTLs for locking - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -static int drm_notifier(void *priv); - -static int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context); - -/** - * Lock ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_lock structure. - * \return zero on success or negative number on failure. - * - * Add the current task to the lock wait queue, and attempt to take to lock. - */ -int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - DECLARE_WAITQUEUE(entry, current); - struct drm_lock *lock = data; - struct drm_master *master = file_priv->master; - int ret = 0; - - ++file_priv->lock_count; - - if (lock->context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - task_pid_nr(current), lock->context); - return -EINVAL; - } - - DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock->context, task_pid_nr(current), - master->lock.hw_lock->lock, lock->flags); - - if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)) - if (lock->context < 0) - return -EINVAL; - - add_wait_queue(&master->lock.lock_queue, &entry); - spin_lock_bh(&master->lock.spinlock); - master->lock.user_waiters++; - spin_unlock_bh(&master->lock.spinlock); - - for (;;) { - __set_current_state(TASK_INTERRUPTIBLE); - if (!master->lock.hw_lock) { - /* Device has been unregistered */ - send_sig(SIGTERM, current, 0); - ret = -EINTR; - break; - } - if (drm_lock_take(&master->lock, lock->context)) { - master->lock.file_priv = file_priv; - master->lock.lock_time = jiffies; - atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); - break; /* Got lock */ - } - - /* Contention */ - mutex_unlock(&drm_global_mutex); - schedule(); - mutex_lock(&drm_global_mutex); - if (signal_pending(current)) { - ret = -EINTR; - break; - } - } - spin_lock_bh(&master->lock.spinlock); - master->lock.user_waiters--; - spin_unlock_bh(&master->lock.spinlock); - __set_current_state(TASK_RUNNING); - remove_wait_queue(&master->lock.lock_queue, &entry); - - DRM_DEBUG("%d %s\n", lock->context, - ret ? "interrupted" : "has lock"); - if (ret) return ret; - - /* don't set the block all signals on the master process for now - * really probably not the correct answer but lets us debug xkb - * xserver for now */ - if (!file_priv->is_master) { - sigemptyset(&dev->sigmask); - sigaddset(&dev->sigmask, SIGSTOP); - sigaddset(&dev->sigmask, SIGTSTP); - sigaddset(&dev->sigmask, SIGTTIN); - sigaddset(&dev->sigmask, SIGTTOU); - dev->sigdata.context = lock->context; - dev->sigdata.lock = master->lock.hw_lock; - block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); - } - - if (dev->driver->dma_quiescent && (lock->flags & _DRM_LOCK_QUIESCENT)) - { - if (dev->driver->dma_quiescent(dev)) { - DRM_DEBUG("%d waiting for DMA quiescent\n", - lock->context); - return -EBUSY; - } - } - - return 0; -} - -/** - * Unlock ioctl. - * - * \param inode device inode. - * \param file_priv DRM file private. - * \param cmd command. - * \param arg user argument, pointing to a drm_lock structure. - * \return zero on success or negative number on failure. - * - * Transfer and free the lock. - */ -int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_lock *lock = data; - struct drm_master *master = file_priv->master; - - if (lock->context == DRM_KERNEL_CONTEXT) { - DRM_ERROR("Process %d using kernel context %d\n", - task_pid_nr(current), lock->context); - return -EINVAL; - } - - atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); - - if (drm_lock_free(&master->lock, lock->context)) { - /* FIXME: Should really bail out here. */ - } - - unblock_all_signals(); - return 0; -} - -/** - * Take the heavyweight lock. - * - * \param lock lock pointer. - * \param context locking context. - * \return one if the lock is held, or zero otherwise. - * - * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. - */ -static -int drm_lock_take(struct drm_lock_data *lock_data, - unsigned int context) -{ - unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock_bh(&lock_data->spinlock); - do { - old = *lock; - if (old & _DRM_LOCK_HELD) - new = old | _DRM_LOCK_CONT; - else { - new = context | _DRM_LOCK_HELD | - ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ? - _DRM_LOCK_CONT : 0); - } - prev = cmpxchg(lock, old, new); - } while (prev != old); - spin_unlock_bh(&lock_data->spinlock); - - if (_DRM_LOCKING_CONTEXT(old) == context) { - if (old & _DRM_LOCK_HELD) { - if (context != DRM_KERNEL_CONTEXT) { - DRM_ERROR("%d holds heavyweight lock\n", - context); - } - return 0; - } - } - - if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) { - /* Have lock */ - return 1; - } - return 0; -} - -/** - * This takes a lock forcibly and hands it to context. Should ONLY be used - * inside *_unlock to give lock to kernel before calling *_dma_schedule. - * - * \param dev DRM device. - * \param lock lock pointer. - * \param context locking context. - * \return always one. - * - * Resets the lock file pointer. - * Marks the lock as held by the given context, via the \p cmpxchg instruction. - */ -static int drm_lock_transfer(struct drm_lock_data *lock_data, - unsigned int context) -{ - unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - lock_data->file_priv = NULL; - do { - old = *lock; - new = context | _DRM_LOCK_HELD; - prev = cmpxchg(lock, old, new); - } while (prev != old); - return 1; -} - -/** - * Free lock. - * - * \param dev DRM device. - * \param lock lock. - * \param context context. - * - * Resets the lock file pointer. - * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task - * waiting on the lock queue. - */ -int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context) -{ - unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock_bh(&lock_data->spinlock); - if (lock_data->kernel_waiters != 0) { - drm_lock_transfer(lock_data, 0); - lock_data->idle_has_lock = 1; - spin_unlock_bh(&lock_data->spinlock); - return 1; - } - spin_unlock_bh(&lock_data->spinlock); - - do { - old = *lock; - new = _DRM_LOCKING_CONTEXT(old); - prev = cmpxchg(lock, old, new); - } while (prev != old); - - if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { - DRM_ERROR("%d freed heavyweight lock held by %d\n", - context, _DRM_LOCKING_CONTEXT(old)); - return 1; - } - wake_up_interruptible(&lock_data->lock_queue); - return 0; -} - -/** - * If we get here, it means that the process has called DRM_IOCTL_LOCK - * without calling DRM_IOCTL_UNLOCK. - * - * If the lock is not held, then let the signal proceed as usual. If the lock - * is held, then set the contended flag and keep the signal blocked. - * - * \param priv pointer to a drm_sigdata structure. - * \return one if the signal should be delivered normally, or zero if the - * signal should be blocked. - */ -static int drm_notifier(void *priv) -{ - struct drm_sigdata *s = (struct drm_sigdata *) priv; - unsigned int old, new, prev; - - /* Allow signal delivery if lock isn't held */ - if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock) - || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) - return 1; - - /* Otherwise, set flag to force call to - drmUnlock */ - do { - old = s->lock->lock; - new = old | _DRM_LOCK_CONT; - prev = cmpxchg(&s->lock->lock, old, new); - } while (prev != old); - return 0; -} - -/** - * This function returns immediately and takes the hw lock - * with the kernel context if it is free, otherwise it gets the highest priority when and if - * it is eventually released. - * - * This guarantees that the kernel will _eventually_ have the lock _unless_ it is held - * by a blocked process. (In the latter case an explicit wait for the hardware lock would cause - * a deadlock, which is why the "idlelock" was invented). - * - * This should be sufficient to wait for GPU idle without - * having to worry about starvation. - */ - -void drm_idlelock_take(struct drm_lock_data *lock_data) -{ - int ret = 0; - - spin_lock_bh(&lock_data->spinlock); - lock_data->kernel_waiters++; - if (!lock_data->idle_has_lock) { - - spin_unlock_bh(&lock_data->spinlock); - ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); - spin_lock_bh(&lock_data->spinlock); - - if (ret == 1) - lock_data->idle_has_lock = 1; - } - spin_unlock_bh(&lock_data->spinlock); -} -EXPORT_SYMBOL(drm_idlelock_take); - -void drm_idlelock_release(struct drm_lock_data *lock_data) -{ - unsigned int old, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock_bh(&lock_data->spinlock); - if (--lock_data->kernel_waiters == 0) { - if (lock_data->idle_has_lock) { - do { - old = *lock; - prev = cmpxchg(lock, old, DRM_KERNEL_CONTEXT); - } while (prev != old); - wake_up_interruptible(&lock_data->lock_queue); - lock_data->idle_has_lock = 0; - } - } - spin_unlock_bh(&lock_data->spinlock); -} -EXPORT_SYMBOL(drm_idlelock_release); - -int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_master *master = file_priv->master; - return (file_priv->lock_count && master->lock.hw_lock && - _DRM_LOCK_IS_HELD(master->lock.hw_lock->lock) && - master->lock.file_priv == file_priv); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_memory.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_memory.c deleted file mode 100644 index c86a0f1a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_memory.c +++ /dev/null @@ -1,144 +0,0 @@ -/** - * \file drm_memory.c - * Memory management wrappers for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "drmP.h" - -#if __OS_HAS_AGP -static void *agp_remap(unsigned long offset, unsigned long size, - struct drm_device * dev) -{ - unsigned long i, num_pages = - PAGE_ALIGN(size) / PAGE_SIZE; - struct drm_agp_mem *agpmem; - struct page **page_map; - struct page **phys_page_map; - void *addr; - - size = PAGE_ALIGN(size); - -#ifdef __alpha__ - offset -= dev->hose->mem_space->start; -#endif - - list_for_each_entry(agpmem, &dev->agp->memory, head) - if (agpmem->bound <= offset - && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= - (offset + size)) - break; - if (&agpmem->head == &dev->agp->memory) - return NULL; - - /* - * OK, we're mapping AGP space on a chipset/platform on which memory accesses by - * the CPU do not get remapped by the GART. We fix this by using the kernel's - * page-table instead (that's probably faster anyhow...). - */ - /* note: use vmalloc() because num_pages could be large... */ - page_map = vmalloc(num_pages * sizeof(struct page *)); - if (!page_map) - return NULL; - - phys_page_map = (agpmem->memory->pages + (offset - agpmem->bound) / PAGE_SIZE); - for (i = 0; i < num_pages; ++i) - page_map[i] = phys_page_map[i]; - addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); - vfree(page_map); - - return addr; -} - -/** Wrapper around agp_free_memory() */ -void drm_free_agp(DRM_AGP_MEM * handle, int pages) -{ - agp_free_memory(handle); -} -EXPORT_SYMBOL(drm_free_agp); - -/** Wrapper around agp_bind_memory() */ -int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start) -{ - return agp_bind_memory(handle, start); -} - -/** Wrapper around agp_unbind_memory() */ -int drm_unbind_agp(DRM_AGP_MEM * handle) -{ - return agp_unbind_memory(handle); -} -EXPORT_SYMBOL(drm_unbind_agp); - -#else /* __OS_HAS_AGP */ -static inline void *agp_remap(unsigned long offset, unsigned long size, - struct drm_device * dev) -{ - return NULL; -} - -#endif /* agp */ - -void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) -{ - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - map->handle = agp_remap(map->offset, map->size, dev); - else - map->handle = ioremap(map->offset, map->size); -} -EXPORT_SYMBOL(drm_core_ioremap); - -void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev) -{ - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - map->handle = agp_remap(map->offset, map->size, dev); - else - map->handle = ioremap_wc(map->offset, map->size); -} -EXPORT_SYMBOL(drm_core_ioremap_wc); - -void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev) -{ - if (!map->handle || !map->size) - return; - - if (drm_core_has_AGP(dev) && - dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP) - vunmap(map->handle); - else - iounmap(map->handle); -} -EXPORT_SYMBOL(drm_core_ioremapfree); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_mm.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_mm.c deleted file mode 100644 index 961fb54f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_mm.c +++ /dev/null @@ -1,717 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Generic simple memory manager implementation. Intended to be used as a base - * class implementation for more advanced memory managers. - * - * Note that the algorithm used is quite simple and there might be substantial - * performance gains if a smarter free list is implemented. Currently it is just an - * unordered stack of free regions. This could easily be improved if an RB-tree - * is used instead. At least if we expect heavy fragmentation. - * - * Aligned allocations can also see improvement. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "drm_mm.h" -#include -#include -#include - -#define MM_UNUSED_TARGET 4 - -static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) -{ - struct drm_mm_node *child; - - if (atomic) - child = kzalloc(sizeof(*child), GFP_ATOMIC); - else - child = kzalloc(sizeof(*child), GFP_KERNEL); - - if (unlikely(child == NULL)) { - spin_lock(&mm->unused_lock); - if (list_empty(&mm->unused_nodes)) - child = NULL; - else { - child = - list_entry(mm->unused_nodes.next, - struct drm_mm_node, node_list); - list_del(&child->node_list); - --mm->num_unused; - } - spin_unlock(&mm->unused_lock); - } - return child; -} - -/* drm_mm_pre_get() - pre allocate drm_mm_node structure - * drm_mm: memory manager struct we are pre-allocating for - * - * Returns 0 on success or -ENOMEM if allocation fails. - */ -int drm_mm_pre_get(struct drm_mm *mm) -{ - struct drm_mm_node *node; - - spin_lock(&mm->unused_lock); - while (mm->num_unused < MM_UNUSED_TARGET) { - spin_unlock(&mm->unused_lock); - node = kzalloc(sizeof(*node), GFP_KERNEL); - spin_lock(&mm->unused_lock); - - if (unlikely(node == NULL)) { - int ret = (mm->num_unused < 2) ? -ENOMEM : 0; - spin_unlock(&mm->unused_lock); - return ret; - } - ++mm->num_unused; - list_add_tail(&node->node_list, &mm->unused_nodes); - } - spin_unlock(&mm->unused_lock); - return 0; -} -EXPORT_SYMBOL(drm_mm_pre_get); - -static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) -{ - return hole_node->start + hole_node->size; -} - -static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) -{ - struct drm_mm_node *next_node = - list_entry(hole_node->node_list.next, struct drm_mm_node, - node_list); - - return next_node->start; -} - -static void drm_mm_insert_helper(struct drm_mm_node *hole_node, - struct drm_mm_node *node, - unsigned long size, unsigned alignment) -{ - struct drm_mm *mm = hole_node->mm; - unsigned long tmp = 0, wasted = 0; - unsigned long hole_start = drm_mm_hole_node_start(hole_node); - unsigned long hole_end = drm_mm_hole_node_end(hole_node); - - BUG_ON(!hole_node->hole_follows || node->allocated); - - if (alignment) - tmp = hole_start % alignment; - - if (!tmp) { - hole_node->hole_follows = 0; - list_del_init(&hole_node->hole_stack); - } else - wasted = alignment - tmp; - - node->start = hole_start + wasted; - node->size = size; - node->mm = mm; - node->allocated = 1; - - INIT_LIST_HEAD(&node->hole_stack); - list_add(&node->node_list, &hole_node->node_list); - - BUG_ON(node->start + node->size > hole_end); - - if (node->start + node->size < hole_end) { - list_add(&node->hole_stack, &mm->hole_stack); - node->hole_follows = 1; - } else { - node->hole_follows = 0; - } -} - -struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, - unsigned long size, - unsigned alignment, - int atomic) -{ - struct drm_mm_node *node; - - node = drm_mm_kmalloc(hole_node->mm, atomic); - if (unlikely(node == NULL)) - return NULL; - - drm_mm_insert_helper(hole_node, node, size, alignment); - - return node; -} -EXPORT_SYMBOL(drm_mm_get_block_generic); - -/** - * Search for free space and insert a preallocated memory node. Returns - * -ENOSPC if no suitable free area is available. The preallocated memory node - * must be cleared. - */ -int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment) -{ - struct drm_mm_node *hole_node; - - hole_node = drm_mm_search_free(mm, size, alignment, 0); - if (!hole_node) - return -ENOSPC; - - drm_mm_insert_helper(hole_node, node, size, alignment); - - return 0; -} -EXPORT_SYMBOL(drm_mm_insert_node); - -static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node, - struct drm_mm_node *node, - unsigned long size, unsigned alignment, - unsigned long start, unsigned long end) -{ - struct drm_mm *mm = hole_node->mm; - unsigned long tmp = 0, wasted = 0; - unsigned long hole_start = drm_mm_hole_node_start(hole_node); - unsigned long hole_end = drm_mm_hole_node_end(hole_node); - - BUG_ON(!hole_node->hole_follows || node->allocated); - - if (hole_start < start) - wasted += start - hole_start; - if (alignment) - tmp = (hole_start + wasted) % alignment; - - if (tmp) - wasted += alignment - tmp; - - if (!wasted) { - hole_node->hole_follows = 0; - list_del_init(&hole_node->hole_stack); - } - - node->start = hole_start + wasted; - node->size = size; - node->mm = mm; - node->allocated = 1; - - INIT_LIST_HEAD(&node->hole_stack); - list_add(&node->node_list, &hole_node->node_list); - - BUG_ON(node->start + node->size > hole_end); - BUG_ON(node->start + node->size > end); - - if (node->start + node->size < hole_end) { - list_add(&node->hole_stack, &mm->hole_stack); - node->hole_follows = 1; - } else { - node->hole_follows = 0; - } -} - -struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *hole_node, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end, - int atomic) -{ - struct drm_mm_node *node; - - node = drm_mm_kmalloc(hole_node->mm, atomic); - if (unlikely(node == NULL)) - return NULL; - - drm_mm_insert_helper_range(hole_node, node, size, alignment, - start, end); - - return node; -} -EXPORT_SYMBOL(drm_mm_get_block_range_generic); - -/** - * Search for free space and insert a preallocated memory node. Returns - * -ENOSPC if no suitable free area is available. This is for range - * restricted allocations. The preallocated memory node must be cleared. - */ -int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long size, unsigned alignment, - unsigned long start, unsigned long end) -{ - struct drm_mm_node *hole_node; - - hole_node = drm_mm_search_free_in_range(mm, size, alignment, - start, end, 0); - if (!hole_node) - return -ENOSPC; - - drm_mm_insert_helper_range(hole_node, node, size, alignment, - start, end); - - return 0; -} -EXPORT_SYMBOL(drm_mm_insert_node_in_range); - -/** - * Remove a memory node from the allocator. - */ -void drm_mm_remove_node(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - struct drm_mm_node *prev_node; - - BUG_ON(node->scanned_block || node->scanned_prev_free - || node->scanned_next_free); - - prev_node = - list_entry(node->node_list.prev, struct drm_mm_node, node_list); - - if (node->hole_follows) { - BUG_ON(drm_mm_hole_node_start(node) - == drm_mm_hole_node_end(node)); - list_del(&node->hole_stack); - } else - BUG_ON(drm_mm_hole_node_start(node) - != drm_mm_hole_node_end(node)); - - if (!prev_node->hole_follows) { - prev_node->hole_follows = 1; - list_add(&prev_node->hole_stack, &mm->hole_stack); - } else - list_move(&prev_node->hole_stack, &mm->hole_stack); - - list_del(&node->node_list); - node->allocated = 0; -} -EXPORT_SYMBOL(drm_mm_remove_node); - -/* - * Remove a memory node from the allocator and free the allocated struct - * drm_mm_node. Only to be used on a struct drm_mm_node obtained by one of the - * drm_mm_get_block functions. - */ -void drm_mm_put_block(struct drm_mm_node *node) -{ - - struct drm_mm *mm = node->mm; - - drm_mm_remove_node(node); - - spin_lock(&mm->unused_lock); - if (mm->num_unused < MM_UNUSED_TARGET) { - list_add(&node->node_list, &mm->unused_nodes); - ++mm->num_unused; - } else - kfree(node); - spin_unlock(&mm->unused_lock); -} -EXPORT_SYMBOL(drm_mm_put_block); - -static int check_free_hole(unsigned long start, unsigned long end, - unsigned long size, unsigned alignment) -{ - unsigned wasted = 0; - - if (end - start < size) - return 0; - - if (alignment) { - unsigned tmp = start % alignment; - if (tmp) - wasted = alignment - tmp; - } - - if (end >= start + size + wasted) { - return 1; - } - - return 0; -} - -struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, - unsigned long size, - unsigned alignment, int best_match) -{ - struct drm_mm_node *entry; - struct drm_mm_node *best; - unsigned long best_size; - - BUG_ON(mm->scanned_blocks); - - best = NULL; - best_size = ~0UL; - - list_for_each_entry(entry, &mm->hole_stack, hole_stack) { - BUG_ON(!entry->hole_follows); - if (!check_free_hole(drm_mm_hole_node_start(entry), - drm_mm_hole_node_end(entry), - size, alignment)) - continue; - - if (!best_match) - return entry; - - if (entry->size < best_size) { - best = entry; - best_size = entry->size; - } - } - - return best; -} -EXPORT_SYMBOL(drm_mm_search_free); - -struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, - unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end, - int best_match) -{ - struct drm_mm_node *entry; - struct drm_mm_node *best; - unsigned long best_size; - - BUG_ON(mm->scanned_blocks); - - best = NULL; - best_size = ~0UL; - - list_for_each_entry(entry, &mm->hole_stack, hole_stack) { - unsigned long adj_start = drm_mm_hole_node_start(entry) < start ? - start : drm_mm_hole_node_start(entry); - unsigned long adj_end = drm_mm_hole_node_end(entry) > end ? - end : drm_mm_hole_node_end(entry); - - BUG_ON(!entry->hole_follows); - if (!check_free_hole(adj_start, adj_end, size, alignment)) - continue; - - if (!best_match) - return entry; - - if (entry->size < best_size) { - best = entry; - best_size = entry->size; - } - } - - return best; -} -EXPORT_SYMBOL(drm_mm_search_free_in_range); - -/** - * Moves an allocation. To be used with embedded struct drm_mm_node. - */ -void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) -{ - list_replace(&old->node_list, &new->node_list); - list_replace(&old->hole_stack, &new->hole_stack); - new->hole_follows = old->hole_follows; - new->mm = old->mm; - new->start = old->start; - new->size = old->size; - - old->allocated = 0; - new->allocated = 1; -} -EXPORT_SYMBOL(drm_mm_replace_node); - -/** - * Initializa lru scanning. - * - * This simply sets up the scanning routines with the parameters for the desired - * hole. - * - * Warning: As long as the scan list is non-empty, no other operations than - * adding/removing nodes to/from the scan list are allowed. - */ -void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, - unsigned alignment) -{ - mm->scan_alignment = alignment; - mm->scan_size = size; - mm->scanned_blocks = 0; - mm->scan_hit_start = 0; - mm->scan_hit_size = 0; - mm->scan_check_range = 0; - mm->prev_scanned_node = NULL; -} -EXPORT_SYMBOL(drm_mm_init_scan); - -/** - * Initializa lru scanning. - * - * This simply sets up the scanning routines with the parameters for the desired - * hole. This version is for range-restricted scans. - * - * Warning: As long as the scan list is non-empty, no other operations than - * adding/removing nodes to/from the scan list are allowed. - */ -void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, - unsigned alignment, - unsigned long start, - unsigned long end) -{ - mm->scan_alignment = alignment; - mm->scan_size = size; - mm->scanned_blocks = 0; - mm->scan_hit_start = 0; - mm->scan_hit_size = 0; - mm->scan_start = start; - mm->scan_end = end; - mm->scan_check_range = 1; - mm->prev_scanned_node = NULL; -} -EXPORT_SYMBOL(drm_mm_init_scan_with_range); - -/** - * Add a node to the scan list that might be freed to make space for the desired - * hole. - * - * Returns non-zero, if a hole has been found, zero otherwise. - */ -int drm_mm_scan_add_block(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - struct drm_mm_node *prev_node; - unsigned long hole_start, hole_end; - unsigned long adj_start; - unsigned long adj_end; - - mm->scanned_blocks++; - - BUG_ON(node->scanned_block); - node->scanned_block = 1; - - prev_node = list_entry(node->node_list.prev, struct drm_mm_node, - node_list); - - node->scanned_preceeds_hole = prev_node->hole_follows; - prev_node->hole_follows = 1; - list_del(&node->node_list); - node->node_list.prev = &prev_node->node_list; - node->node_list.next = &mm->prev_scanned_node->node_list; - mm->prev_scanned_node = node; - - hole_start = drm_mm_hole_node_start(prev_node); - hole_end = drm_mm_hole_node_end(prev_node); - if (mm->scan_check_range) { - adj_start = hole_start < mm->scan_start ? - mm->scan_start : hole_start; - adj_end = hole_end > mm->scan_end ? - mm->scan_end : hole_end; - } else { - adj_start = hole_start; - adj_end = hole_end; - } - - if (check_free_hole(adj_start , adj_end, - mm->scan_size, mm->scan_alignment)) { - mm->scan_hit_start = hole_start; - mm->scan_hit_size = hole_end; - - return 1; - } - - return 0; -} -EXPORT_SYMBOL(drm_mm_scan_add_block); - -/** - * Remove a node from the scan list. - * - * Nodes _must_ be removed in the exact same order from the scan list as they - * have been added, otherwise the internal state of the memory manager will be - * corrupted. - * - * When the scan list is empty, the selected memory nodes can be freed. An - * immediately following drm_mm_search_free with best_match = 0 will then return - * the just freed block (because its at the top of the free_stack list). - * - * Returns one if this block should be evicted, zero otherwise. Will always - * return zero when no hole has been found. - */ -int drm_mm_scan_remove_block(struct drm_mm_node *node) -{ - struct drm_mm *mm = node->mm; - struct drm_mm_node *prev_node; - - mm->scanned_blocks--; - - BUG_ON(!node->scanned_block); - node->scanned_block = 0; - - prev_node = list_entry(node->node_list.prev, struct drm_mm_node, - node_list); - - prev_node->hole_follows = node->scanned_preceeds_hole; - INIT_LIST_HEAD(&node->node_list); - list_add(&node->node_list, &prev_node->node_list); - - /* Only need to check for containement because start&size for the - * complete resulting free block (not just the desired part) is - * stored. */ - if (node->start >= mm->scan_hit_start && - node->start + node->size - <= mm->scan_hit_start + mm->scan_hit_size) { - return 1; - } - - return 0; -} -EXPORT_SYMBOL(drm_mm_scan_remove_block); - -int drm_mm_clean(struct drm_mm * mm) -{ - struct list_head *head = &mm->head_node.node_list; - - return (head->next->next == head); -} -EXPORT_SYMBOL(drm_mm_clean); - -int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size) -{ - INIT_LIST_HEAD(&mm->hole_stack); - INIT_LIST_HEAD(&mm->unused_nodes); - mm->num_unused = 0; - mm->scanned_blocks = 0; - spin_lock_init(&mm->unused_lock); - - /* Clever trick to avoid a special case in the free hole tracking. */ - INIT_LIST_HEAD(&mm->head_node.node_list); - INIT_LIST_HEAD(&mm->head_node.hole_stack); - mm->head_node.hole_follows = 1; - mm->head_node.scanned_block = 0; - mm->head_node.scanned_prev_free = 0; - mm->head_node.scanned_next_free = 0; - mm->head_node.mm = mm; - mm->head_node.start = start + size; - mm->head_node.size = start - mm->head_node.start; - list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack); - - return 0; -} -EXPORT_SYMBOL(drm_mm_init); - -void drm_mm_takedown(struct drm_mm * mm) -{ - struct drm_mm_node *entry, *next; - - if (!list_empty(&mm->head_node.node_list)) { - DRM_ERROR("Memory manager not clean. Delaying takedown\n"); - return; - } - - spin_lock(&mm->unused_lock); - list_for_each_entry_safe(entry, next, &mm->unused_nodes, node_list) { - list_del(&entry->node_list); - kfree(entry); - --mm->num_unused; - } - spin_unlock(&mm->unused_lock); - - BUG_ON(mm->num_unused != 0); -} -EXPORT_SYMBOL(drm_mm_takedown); - -void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) -{ - struct drm_mm_node *entry; - unsigned long total_used = 0, total_free = 0, total = 0; - unsigned long hole_start, hole_end, hole_size; - - hole_start = drm_mm_hole_node_start(&mm->head_node); - hole_end = drm_mm_hole_node_end(&mm->head_node); - hole_size = hole_end - hole_start; - if (hole_size) - printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n", - prefix, hole_start, hole_end, - hole_size); - total_free += hole_size; - - drm_mm_for_each_node(entry, mm) { - printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: used\n", - prefix, entry->start, entry->start + entry->size, - entry->size); - total_used += entry->size; - - if (entry->hole_follows) { - hole_start = drm_mm_hole_node_start(entry); - hole_end = drm_mm_hole_node_end(entry); - hole_size = hole_end - hole_start; - printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n", - prefix, hole_start, hole_end, - hole_size); - total_free += hole_size; - } - } - total = total_free + total_used; - - printk(KERN_DEBUG "%s total: %lu, used %lu free %lu\n", prefix, total, - total_used, total_free); -} -EXPORT_SYMBOL(drm_mm_debug_table); - -#if defined(CONFIG_DEBUG_FS) -int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) -{ - struct drm_mm_node *entry; - unsigned long total_used = 0, total_free = 0, total = 0; - unsigned long hole_start, hole_end, hole_size; - - hole_start = drm_mm_hole_node_start(&mm->head_node); - hole_end = drm_mm_hole_node_end(&mm->head_node); - hole_size = hole_end - hole_start; - if (hole_size) - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", - hole_start, hole_end, hole_size); - total_free += hole_size; - - drm_mm_for_each_node(entry, mm) { - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", - entry->start, entry->start + entry->size, - entry->size); - total_used += entry->size; - if (entry->hole_follows) { - hole_start = drm_mm_hole_node_start(entry); - hole_end = drm_mm_hole_node_end(entry); - hole_size = hole_end - hole_start; - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", - hole_start, hole_end, hole_size); - total_free += hole_size; - } - } - total = total_free + total_used; - - seq_printf(m, "total: %lu, used %lu free %lu\n", total, total_used, total_free); - return 0; -} -EXPORT_SYMBOL(drm_mm_dump_table); -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_modes.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_modes.c deleted file mode 100644 index b7adb4a9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_modes.c +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * Copyright © 1997-2003 by The XFree86 Project, Inc. - * Copyright © 2007 Dave Airlie - * Copyright © 2007-2008 Intel Corporation - * Jesse Barnes - * Copyright 2005-2006 Luc Verhaegen - * Copyright (c) 2001, Andy Ritger aritger@nvidia.com - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the copyright holder(s) - * and author(s) shall not be used in advertising or otherwise to promote - * the sale, use or other dealings in this Software without prior written - * authorization from the copyright holder(s) and author(s). - */ - -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" - -/** - * drm_mode_debug_printmodeline - debug print a mode - * @dev: DRM device - * @mode: mode to print - * - * LOCKING: - * None. - * - * Describe @mode using DRM_DEBUG. - */ -void drm_mode_debug_printmodeline(struct drm_display_mode *mode) -{ - DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d " - "0x%x 0x%x\n", - mode->base.id, mode->name, mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, mode->type, mode->flags); -} -EXPORT_SYMBOL(drm_mode_debug_printmodeline); - -/** - * drm_cvt_mode -create a modeline based on CVT algorithm - * @dev: DRM device - * @hdisplay: hdisplay size - * @vdisplay: vdisplay size - * @vrefresh : vrefresh rate - * @reduced : Whether the GTF calculation is simplified - * @interlaced:Whether the interlace is supported - * - * LOCKING: - * none. - * - * return the modeline based on CVT algorithm - * - * This function is called to generate the modeline based on CVT algorithm - * according to the hdisplay, vdisplay, vrefresh. - * It is based from the VESA(TM) Coordinated Video Timing Generator by - * Graham Loveridge April 9, 2003 available at - * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls - * - * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. - * What I have done is to translate it by using integer calculation. - */ -#define HV_FACTOR 1000 -struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, - int vdisplay, int vrefresh, - bool reduced, bool interlaced, bool margins) -{ - /* 1) top/bottom margin size (% of height) - default: 1.8, */ -#define CVT_MARGIN_PERCENTAGE 18 - /* 2) character cell horizontal granularity (pixels) - default 8 */ -#define CVT_H_GRANULARITY 8 - /* 3) Minimum vertical porch (lines) - default 3 */ -#define CVT_MIN_V_PORCH 3 - /* 4) Minimum number of vertical back porch lines - default 6 */ -#define CVT_MIN_V_BPORCH 6 - /* Pixel Clock step (kHz) */ -#define CVT_CLOCK_STEP 250 - struct drm_display_mode *drm_mode; - unsigned int vfieldrate, hperiod; - int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; - int interlace; - - /* allocate the drm_display_mode structure. If failure, we will - * return directly - */ - drm_mode = drm_mode_create(dev); - if (!drm_mode) - return NULL; - - /* the CVT default refresh rate is 60Hz */ - if (!vrefresh) - vrefresh = 60; - - /* the required field fresh rate */ - if (interlaced) - vfieldrate = vrefresh * 2; - else - vfieldrate = vrefresh; - - /* horizontal pixels */ - hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY); - - /* determine the left&right borders */ - hmargin = 0; - if (margins) { - hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; - hmargin -= hmargin % CVT_H_GRANULARITY; - } - /* find the total active pixels */ - drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin; - - /* find the number of lines per field */ - if (interlaced) - vdisplay_rnd = vdisplay / 2; - else - vdisplay_rnd = vdisplay; - - /* find the top & bottom borders */ - vmargin = 0; - if (margins) - vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; - - drm_mode->vdisplay = vdisplay + 2 * vmargin; - - /* Interlaced */ - if (interlaced) - interlace = 1; - else - interlace = 0; - - /* Determine VSync Width from aspect ratio */ - if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay)) - vsync = 4; - else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay)) - vsync = 5; - else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay)) - vsync = 6; - else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay)) - vsync = 7; - else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay)) - vsync = 7; - else /* custom */ - vsync = 10; - - if (!reduced) { - /* simplify the GTF calculation */ - /* 4) Minimum time of vertical sync + back porch interval (µs) - * default 550.0 - */ - int tmp1, tmp2; -#define CVT_MIN_VSYNC_BP 550 - /* 3) Nominal HSync width (% of line period) - default 8 */ -#define CVT_HSYNC_PERCENTAGE 8 - unsigned int hblank_percentage; - int vsyncandback_porch, vback_porch, hblank; - - /* estimated the horizontal period */ - tmp1 = HV_FACTOR * 1000000 - - CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate; - tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 + - interlace; - hperiod = tmp1 * 2 / (tmp2 * vfieldrate); - - tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1; - /* 9. Find number of lines in sync + backporch */ - if (tmp1 < (vsync + CVT_MIN_V_PORCH)) - vsyncandback_porch = vsync + CVT_MIN_V_PORCH; - else - vsyncandback_porch = tmp1; - /* 10. Find number of lines in back porch */ - vback_porch = vsyncandback_porch - vsync; - drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + - vsyncandback_porch + CVT_MIN_V_PORCH; - /* 5) Definition of Horizontal blanking time limitation */ - /* Gradient (%/kHz) - default 600 */ -#define CVT_M_FACTOR 600 - /* Offset (%) - default 40 */ -#define CVT_C_FACTOR 40 - /* Blanking time scaling factor - default 128 */ -#define CVT_K_FACTOR 128 - /* Scaling factor weighting - default 20 */ -#define CVT_J_FACTOR 20 -#define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256) -#define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ - CVT_J_FACTOR) - /* 12. Find ideal blanking duty cycle from formula */ - hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME * - hperiod / 1000; - /* 13. Blanking time */ - if (hblank_percentage < 20 * HV_FACTOR) - hblank_percentage = 20 * HV_FACTOR; - hblank = drm_mode->hdisplay * hblank_percentage / - (100 * HV_FACTOR - hblank_percentage); - hblank -= hblank % (2 * CVT_H_GRANULARITY); - /* 14. find the total pixes per line */ - drm_mode->htotal = drm_mode->hdisplay + hblank; - drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2; - drm_mode->hsync_start = drm_mode->hsync_end - - (drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100; - drm_mode->hsync_start += CVT_H_GRANULARITY - - drm_mode->hsync_start % CVT_H_GRANULARITY; - /* fill the Vsync values */ - drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH; - drm_mode->vsync_end = drm_mode->vsync_start + vsync; - } else { - /* Reduced blanking */ - /* Minimum vertical blanking interval time (µs)- default 460 */ -#define CVT_RB_MIN_VBLANK 460 - /* Fixed number of clocks for horizontal sync */ -#define CVT_RB_H_SYNC 32 - /* Fixed number of clocks for horizontal blanking */ -#define CVT_RB_H_BLANK 160 - /* Fixed number of lines for vertical front porch - default 3*/ -#define CVT_RB_VFPORCH 3 - int vbilines; - int tmp1, tmp2; - /* 8. Estimate Horizontal period. */ - tmp1 = HV_FACTOR * 1000000 - - CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate; - tmp2 = vdisplay_rnd + 2 * vmargin; - hperiod = tmp1 / (tmp2 * vfieldrate); - /* 9. Find number of lines in vertical blanking */ - vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1; - /* 10. Check if vertical blanking is sufficient */ - if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH)) - vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH; - /* 11. Find total number of lines in vertical field */ - drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines; - /* 12. Find total number of pixels in a line */ - drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; - /* Fill in HSync values */ - drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; - drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC; - /* Fill in VSync values */ - drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH; - drm_mode->vsync_end = drm_mode->vsync_start + vsync; - } - /* 15/13. Find pixel clock frequency (kHz for xf86) */ - drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; - drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; - /* 18/16. Find actual vertical frame frequency */ - /* ignore - just set the mode flag for interlaced */ - if (interlaced) { - drm_mode->vtotal *= 2; - drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; - } - /* Fill the mode line name */ - drm_mode_set_name(drm_mode); - if (reduced) - drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC | - DRM_MODE_FLAG_NVSYNC); - else - drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | - DRM_MODE_FLAG_NHSYNC); - - return drm_mode; -} -EXPORT_SYMBOL(drm_cvt_mode); - -/** - * drm_gtf_mode_complex - create the modeline based on full GTF algorithm - * - * @dev :drm device - * @hdisplay :hdisplay size - * @vdisplay :vdisplay size - * @vrefresh :vrefresh rate. - * @interlaced :whether the interlace is supported - * @margins :desired margin size - * @GTF_[MCKJ] :extended GTF formula parameters - * - * LOCKING. - * none. - * - * return the modeline based on full GTF algorithm. - * - * GTF feature blocks specify C and J in multiples of 0.5, so we pass them - * in here multiplied by two. For a C of 40, pass in 80. - */ -struct drm_display_mode * -drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay, - int vrefresh, bool interlaced, int margins, - int GTF_M, int GTF_2C, int GTF_K, int GTF_2J) -{ /* 1) top/bottom margin size (% of height) - default: 1.8, */ -#define GTF_MARGIN_PERCENTAGE 18 - /* 2) character cell horizontal granularity (pixels) - default 8 */ -#define GTF_CELL_GRAN 8 - /* 3) Minimum vertical porch (lines) - default 3 */ -#define GTF_MIN_V_PORCH 1 - /* width of vsync in lines */ -#define V_SYNC_RQD 3 - /* width of hsync as % of total line */ -#define H_SYNC_PERCENT 8 - /* min time of vsync + back porch (microsec) */ -#define MIN_VSYNC_PLUS_BP 550 - /* C' and M' are part of the Blanking Duty Cycle computation */ -#define GTF_C_PRIME ((((GTF_2C - GTF_2J) * GTF_K / 256) + GTF_2J) / 2) -#define GTF_M_PRIME (GTF_K * GTF_M / 256) - struct drm_display_mode *drm_mode; - unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; - int top_margin, bottom_margin; - int interlace; - unsigned int hfreq_est; - int vsync_plus_bp, vback_porch; - unsigned int vtotal_lines, vfieldrate_est, hperiod; - unsigned int vfield_rate, vframe_rate; - int left_margin, right_margin; - unsigned int total_active_pixels, ideal_duty_cycle; - unsigned int hblank, total_pixels, pixel_freq; - int hsync, hfront_porch, vodd_front_porch_lines; - unsigned int tmp1, tmp2; - - drm_mode = drm_mode_create(dev); - if (!drm_mode) - return NULL; - - /* 1. In order to give correct results, the number of horizontal - * pixels requested is first processed to ensure that it is divisible - * by the character size, by rounding it to the nearest character - * cell boundary: - */ - hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; - hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN; - - /* 2. If interlace is requested, the number of vertical lines assumed - * by the calculation must be halved, as the computation calculates - * the number of vertical lines per field. - */ - if (interlaced) - vdisplay_rnd = vdisplay / 2; - else - vdisplay_rnd = vdisplay; - - /* 3. Find the frame rate required: */ - if (interlaced) - vfieldrate_rqd = vrefresh * 2; - else - vfieldrate_rqd = vrefresh; - - /* 4. Find number of lines in Top margin: */ - top_margin = 0; - if (margins) - top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / - 1000; - /* 5. Find number of lines in bottom margin: */ - bottom_margin = top_margin; - - /* 6. If interlace is required, then set variable interlace: */ - if (interlaced) - interlace = 1; - else - interlace = 0; - - /* 7. Estimate the Horizontal frequency */ - { - tmp1 = (1000000 - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500; - tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) * - 2 + interlace; - hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1; - } - - /* 8. Find the number of lines in V sync + back porch */ - /* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */ - vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000; - vsync_plus_bp = (vsync_plus_bp + 500) / 1000; - /* 9. Find the number of lines in V back porch alone: */ - vback_porch = vsync_plus_bp - V_SYNC_RQD; - /* 10. Find the total number of lines in Vertical field period: */ - vtotal_lines = vdisplay_rnd + top_margin + bottom_margin + - vsync_plus_bp + GTF_MIN_V_PORCH; - /* 11. Estimate the Vertical field frequency: */ - vfieldrate_est = hfreq_est / vtotal_lines; - /* 12. Find the actual horizontal period: */ - hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines); - - /* 13. Find the actual Vertical field frequency: */ - vfield_rate = hfreq_est / vtotal_lines; - /* 14. Find the Vertical frame frequency: */ - if (interlaced) - vframe_rate = vfield_rate / 2; - else - vframe_rate = vfield_rate; - /* 15. Find number of pixels in left margin: */ - if (margins) - left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / - 1000; - else - left_margin = 0; - - /* 16.Find number of pixels in right margin: */ - right_margin = left_margin; - /* 17.Find total number of active pixels in image and left and right */ - total_active_pixels = hdisplay_rnd + left_margin + right_margin; - /* 18.Find the ideal blanking duty cycle from blanking duty cycle */ - ideal_duty_cycle = GTF_C_PRIME * 1000 - - (GTF_M_PRIME * 1000000 / hfreq_est); - /* 19.Find the number of pixels in the blanking time to the nearest - * double character cell: */ - hblank = total_active_pixels * ideal_duty_cycle / - (100000 - ideal_duty_cycle); - hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN); - hblank = hblank * 2 * GTF_CELL_GRAN; - /* 20.Find total number of pixels: */ - total_pixels = total_active_pixels + hblank; - /* 21.Find pixel clock frequency: */ - pixel_freq = total_pixels * hfreq_est / 1000; - /* Stage 1 computations are now complete; I should really pass - * the results to another function and do the Stage 2 computations, - * but I only need a few more values so I'll just append the - * computations here for now */ - /* 17. Find the number of pixels in the horizontal sync period: */ - hsync = H_SYNC_PERCENT * total_pixels / 100; - hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; - hsync = hsync * GTF_CELL_GRAN; - /* 18. Find the number of pixels in horizontal front porch period */ - hfront_porch = hblank / 2 - hsync; - /* 36. Find the number of lines in the odd front porch period: */ - vodd_front_porch_lines = GTF_MIN_V_PORCH ; - - /* finally, pack the results in the mode struct */ - drm_mode->hdisplay = hdisplay_rnd; - drm_mode->hsync_start = hdisplay_rnd + hfront_porch; - drm_mode->hsync_end = drm_mode->hsync_start + hsync; - drm_mode->htotal = total_pixels; - drm_mode->vdisplay = vdisplay_rnd; - drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines; - drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD; - drm_mode->vtotal = vtotal_lines; - - drm_mode->clock = pixel_freq; - - if (interlaced) { - drm_mode->vtotal *= 2; - drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; - } - - drm_mode_set_name(drm_mode); - if (GTF_M == 600 && GTF_2C == 80 && GTF_K == 128 && GTF_2J == 40) - drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; - else - drm_mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC; - - return drm_mode; -} -EXPORT_SYMBOL(drm_gtf_mode_complex); - -/** - * drm_gtf_mode - create the modeline based on GTF algorithm - * - * @dev :drm device - * @hdisplay :hdisplay size - * @vdisplay :vdisplay size - * @vrefresh :vrefresh rate. - * @interlaced :whether the interlace is supported - * @margins :whether the margin is supported - * - * LOCKING. - * none. - * - * return the modeline based on GTF algorithm - * - * This function is to create the modeline based on the GTF algorithm. - * Generalized Timing Formula is derived from: - * GTF Spreadsheet by Andy Morrish (1/5/97) - * available at http://www.vesa.org - * - * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. - * What I have done is to translate it by using integer calculation. - * I also refer to the function of fb_get_mode in the file of - * drivers/video/fbmon.c - * - * Standard GTF parameters: - * M = 600 - * C = 40 - * K = 128 - * J = 20 - */ -struct drm_display_mode * -drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, - bool lace, int margins) -{ - return drm_gtf_mode_complex(dev, hdisplay, vdisplay, vrefresh, lace, - margins, 600, 40 * 2, 128, 20 * 2); -} -EXPORT_SYMBOL(drm_gtf_mode); - -/** - * drm_mode_set_name - set the name on a mode - * @mode: name will be set in this mode - * - * LOCKING: - * None. - * - * Set the name of @mode to a standard format. - */ -void drm_mode_set_name(struct drm_display_mode *mode) -{ - bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); - - snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d%s", - mode->hdisplay, mode->vdisplay, - interlaced ? "i" : ""); -} -EXPORT_SYMBOL(drm_mode_set_name); - -/** - * drm_mode_list_concat - move modes from one list to another - * @head: source list - * @new: dst list - * - * LOCKING: - * Caller must ensure both lists are locked. - * - * Move all the modes from @head to @new. - */ -void drm_mode_list_concat(struct list_head *head, struct list_head *new) -{ - - struct list_head *entry, *tmp; - - list_for_each_safe(entry, tmp, head) { - list_move_tail(entry, new); - } -} -EXPORT_SYMBOL(drm_mode_list_concat); - -/** - * drm_mode_width - get the width of a mode - * @mode: mode - * - * LOCKING: - * None. - * - * Return @mode's width (hdisplay) value. - * - * FIXME: is this needed? - * - * RETURNS: - * @mode->hdisplay - */ -int drm_mode_width(struct drm_display_mode *mode) -{ - return mode->hdisplay; - -} -EXPORT_SYMBOL(drm_mode_width); - -/** - * drm_mode_height - get the height of a mode - * @mode: mode - * - * LOCKING: - * None. - * - * Return @mode's height (vdisplay) value. - * - * FIXME: is this needed? - * - * RETURNS: - * @mode->vdisplay - */ -int drm_mode_height(struct drm_display_mode *mode) -{ - return mode->vdisplay; -} -EXPORT_SYMBOL(drm_mode_height); - -/** drm_mode_hsync - get the hsync of a mode - * @mode: mode - * - * LOCKING: - * None. - * - * Return @modes's hsync rate in kHz, rounded to the nearest int. - */ -int drm_mode_hsync(const struct drm_display_mode *mode) -{ - unsigned int calc_val; - - if (mode->hsync) - return mode->hsync; - - if (mode->htotal < 0) - return 0; - - calc_val = (mode->clock * 1000) / mode->htotal; /* hsync in Hz */ - calc_val += 500; /* round to 1000Hz */ - calc_val /= 1000; /* truncate to kHz */ - - return calc_val; -} -EXPORT_SYMBOL(drm_mode_hsync); - -/** - * drm_mode_vrefresh - get the vrefresh of a mode - * @mode: mode - * - * LOCKING: - * None. - * - * Return @mode's vrefresh rate in Hz or calculate it if necessary. - * - * FIXME: why is this needed? shouldn't vrefresh be set already? - * - * RETURNS: - * Vertical refresh rate. It will be the result of actual value plus 0.5. - * If it is 70.288, it will return 70Hz. - * If it is 59.6, it will return 60Hz. - */ -int drm_mode_vrefresh(const struct drm_display_mode *mode) -{ - int refresh = 0; - unsigned int calc_val; - - if (mode->vrefresh > 0) - refresh = mode->vrefresh; - else if (mode->htotal > 0 && mode->vtotal > 0) { - int vtotal; - vtotal = mode->vtotal; - /* work out vrefresh the value will be x1000 */ - calc_val = (mode->clock * 1000); - calc_val /= mode->htotal; - refresh = (calc_val + vtotal / 2) / vtotal; - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - refresh *= 2; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - refresh /= 2; - if (mode->vscan > 1) - refresh /= mode->vscan; - } - return refresh; -} -EXPORT_SYMBOL(drm_mode_vrefresh); - -/** - * drm_mode_set_crtcinfo - set CRTC modesetting parameters - * @p: mode - * @adjust_flags: unused? (FIXME) - * - * LOCKING: - * None. - * - * Setup the CRTC modesetting parameters for @p, adjusting if necessary. - */ -void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) -{ - if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) - return; - - p->crtc_hdisplay = p->hdisplay; - p->crtc_hsync_start = p->hsync_start; - p->crtc_hsync_end = p->hsync_end; - p->crtc_htotal = p->htotal; - p->crtc_hskew = p->hskew; - p->crtc_vdisplay = p->vdisplay; - p->crtc_vsync_start = p->vsync_start; - p->crtc_vsync_end = p->vsync_end; - p->crtc_vtotal = p->vtotal; - - if (p->flags & DRM_MODE_FLAG_INTERLACE) { - if (adjust_flags & CRTC_INTERLACE_HALVE_V) { - p->crtc_vdisplay /= 2; - p->crtc_vsync_start /= 2; - p->crtc_vsync_end /= 2; - p->crtc_vtotal /= 2; - } - } - - if (p->flags & DRM_MODE_FLAG_DBLSCAN) { - p->crtc_vdisplay *= 2; - p->crtc_vsync_start *= 2; - p->crtc_vsync_end *= 2; - p->crtc_vtotal *= 2; - } - - if (p->vscan > 1) { - p->crtc_vdisplay *= p->vscan; - p->crtc_vsync_start *= p->vscan; - p->crtc_vsync_end *= p->vscan; - p->crtc_vtotal *= p->vscan; - } - - p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); - p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); - p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); - p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); - - p->crtc_hadjusted = false; - p->crtc_vadjusted = false; -} -EXPORT_SYMBOL(drm_mode_set_crtcinfo); - - -/** - * drm_mode_copy - copy the mode - * @dst: mode to overwrite - * @src: mode to copy - * - * LOCKING: - * None. - * - * Copy an existing mode into another mode, preserving the object id - * of the destination mode. - */ -void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src) -{ - int id = dst->base.id; - - *dst = *src; - dst->base.id = id; - INIT_LIST_HEAD(&dst->head); -} -EXPORT_SYMBOL(drm_mode_copy); - -/** - * drm_mode_duplicate - allocate and duplicate an existing mode - * @m: mode to duplicate - * - * LOCKING: - * None. - * - * Just allocate a new mode, copy the existing mode into it, and return - * a pointer to it. Used to create new instances of established modes. - */ -struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, - const struct drm_display_mode *mode) -{ - struct drm_display_mode *nmode; - - nmode = drm_mode_create(dev); - if (!nmode) - return NULL; - - drm_mode_copy(nmode, mode); - - return nmode; -} -EXPORT_SYMBOL(drm_mode_duplicate); - -/** - * drm_mode_equal - test modes for equality - * @mode1: first mode - * @mode2: second mode - * - * LOCKING: - * None. - * - * Check to see if @mode1 and @mode2 are equivalent. - * - * RETURNS: - * True if the modes are equal, false otherwise. - */ -bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2) -{ - /* do clock check convert to PICOS so fb modes get matched - * the same */ - if (mode1->clock && mode2->clock) { - if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock)) - return false; - } else if (mode1->clock != mode2->clock) - return false; - - if (mode1->hdisplay == mode2->hdisplay && - mode1->hsync_start == mode2->hsync_start && - mode1->hsync_end == mode2->hsync_end && - mode1->htotal == mode2->htotal && - mode1->hskew == mode2->hskew && - mode1->vdisplay == mode2->vdisplay && - mode1->vsync_start == mode2->vsync_start && - mode1->vsync_end == mode2->vsync_end && - mode1->vtotal == mode2->vtotal && - mode1->vscan == mode2->vscan && - mode1->flags == mode2->flags) - return true; - - return false; -} -EXPORT_SYMBOL(drm_mode_equal); - -/** - * drm_mode_validate_size - make sure modes adhere to size constraints - * @dev: DRM device - * @mode_list: list of modes to check - * @maxX: maximum width - * @maxY: maximum height - * @maxPitch: max pitch - * - * LOCKING: - * Caller must hold a lock protecting @mode_list. - * - * The DRM device (@dev) has size and pitch limits. Here we validate the - * modes we probed for @dev against those limits and set their status as - * necessary. - */ -void drm_mode_validate_size(struct drm_device *dev, - struct list_head *mode_list, - int maxX, int maxY, int maxPitch) -{ - struct drm_display_mode *mode; - - list_for_each_entry(mode, mode_list, head) { - if (maxPitch > 0 && mode->hdisplay > maxPitch) - mode->status = MODE_BAD_WIDTH; - - if (maxX > 0 && mode->hdisplay > maxX) - mode->status = MODE_VIRTUAL_X; - - if (maxY > 0 && mode->vdisplay > maxY) - mode->status = MODE_VIRTUAL_Y; - } -} -EXPORT_SYMBOL(drm_mode_validate_size); - -/** - * drm_mode_validate_clocks - validate modes against clock limits - * @dev: DRM device - * @mode_list: list of modes to check - * @min: minimum clock rate array - * @max: maximum clock rate array - * @n_ranges: number of clock ranges (size of arrays) - * - * LOCKING: - * Caller must hold a lock protecting @mode_list. - * - * Some code may need to check a mode list against the clock limits of the - * device in question. This function walks the mode list, testing to make - * sure each mode falls within a given range (defined by @min and @max - * arrays) and sets @mode->status as needed. - */ -void drm_mode_validate_clocks(struct drm_device *dev, - struct list_head *mode_list, - int *min, int *max, int n_ranges) -{ - struct drm_display_mode *mode; - int i; - - list_for_each_entry(mode, mode_list, head) { - bool good = false; - for (i = 0; i < n_ranges; i++) { - if (mode->clock >= min[i] && mode->clock <= max[i]) { - good = true; - break; - } - } - if (!good) - mode->status = MODE_CLOCK_RANGE; - } -} -EXPORT_SYMBOL(drm_mode_validate_clocks); - -/** - * drm_mode_prune_invalid - remove invalid modes from mode list - * @dev: DRM device - * @mode_list: list of modes to check - * @verbose: be verbose about it - * - * LOCKING: - * Caller must hold a lock protecting @mode_list. - * - * Once mode list generation is complete, a caller can use this routine to - * remove invalid modes from a mode list. If any of the modes have a - * status other than %MODE_OK, they are removed from @mode_list and freed. - */ -void drm_mode_prune_invalid(struct drm_device *dev, - struct list_head *mode_list, bool verbose) -{ - struct drm_display_mode *mode, *t; - - list_for_each_entry_safe(mode, t, mode_list, head) { - if (mode->status != MODE_OK) { - list_del(&mode->head); - if (verbose) { - drm_mode_debug_printmodeline(mode); - DRM_DEBUG_KMS("Not using %s mode %d\n", - mode->name, mode->status); - } - drm_mode_destroy(dev, mode); - } - } -} -EXPORT_SYMBOL(drm_mode_prune_invalid); - -/** - * drm_mode_compare - compare modes for favorability - * @priv: unused - * @lh_a: list_head for first mode - * @lh_b: list_head for second mode - * - * LOCKING: - * None. - * - * Compare two modes, given by @lh_a and @lh_b, returning a value indicating - * which is better. - * - * RETURNS: - * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or - * positive if @lh_b is better than @lh_a. - */ -static int drm_mode_compare(void *priv, struct list_head *lh_a, struct list_head *lh_b) -{ - struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head); - struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head); - int diff; - - diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) - - ((a->type & DRM_MODE_TYPE_PREFERRED) != 0); - if (diff) - return diff; - diff = b->hdisplay * b->vdisplay - a->hdisplay * a->vdisplay; - if (diff) - return diff; - diff = b->clock - a->clock; - return diff; -} - -/** - * drm_mode_sort - sort mode list - * @mode_list: list to sort - * - * LOCKING: - * Caller must hold a lock protecting @mode_list. - * - * Sort @mode_list by favorability, putting good modes first. - */ -void drm_mode_sort(struct list_head *mode_list) -{ - list_sort(NULL, mode_list, drm_mode_compare); -} -EXPORT_SYMBOL(drm_mode_sort); - -/** - * drm_mode_connector_list_update - update the mode list for the connector - * @connector: the connector to update - * - * LOCKING: - * Caller must hold a lock protecting @mode_list. - * - * This moves the modes from the @connector probed_modes list - * to the actual mode list. It compares the probed mode against the current - * list and only adds different modes. All modes unverified after this point - * will be removed by the prune invalid modes. - */ -void drm_mode_connector_list_update(struct drm_connector *connector) -{ - struct drm_display_mode *mode; - struct drm_display_mode *pmode, *pt; - int found_it; - - list_for_each_entry_safe(pmode, pt, &connector->probed_modes, - head) { - found_it = 0; - /* go through current modes checking for the new probed mode */ - list_for_each_entry(mode, &connector->modes, head) { - if (drm_mode_equal(pmode, mode)) { - found_it = 1; - /* if equal delete the probed mode */ - mode->status = pmode->status; - /* Merge type bits together */ - mode->type |= pmode->type; - list_del(&pmode->head); - drm_mode_destroy(connector->dev, pmode); - break; - } - } - - if (!found_it) { - list_move_tail(&pmode->head, &connector->modes); - } - } -} -EXPORT_SYMBOL(drm_mode_connector_list_update); - -/** - * drm_mode_parse_command_line_for_connector - parse command line for connector - * @mode_option - per connector mode option - * @connector - connector to parse line for - * - * This parses the connector specific then generic command lines for - * modes and options to configure the connector. - * - * This uses the same parameters as the fb modedb.c, except for extra - * x[M][R][-][@][i][m][eDd] - * - * enable/enable Digital/disable bit at the end - */ -bool drm_mode_parse_command_line_for_connector(const char *mode_option, - struct drm_connector *connector, - struct drm_cmdline_mode *mode) -{ - const char *name; - unsigned int namelen; - bool res_specified = false, bpp_specified = false, refresh_specified = false; - unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; - bool yres_specified = false, cvt = false, rb = false; - bool interlace = false, margins = false, was_digit = false; - int i; - enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; - -#ifdef CONFIG_FB - if (!mode_option) - mode_option = fb_mode_option; -#endif - - if (!mode_option) { - mode->specified = false; - return false; - } - - name = mode_option; - namelen = strlen(name); - for (i = namelen-1; i >= 0; i--) { - switch (name[i]) { - case '@': - if (!refresh_specified && !bpp_specified && - !yres_specified && !cvt && !rb && was_digit) { - refresh = simple_strtol(&name[i+1], NULL, 10); - refresh_specified = true; - was_digit = false; - } else - goto done; - break; - case '-': - if (!bpp_specified && !yres_specified && !cvt && - !rb && was_digit) { - bpp = simple_strtol(&name[i+1], NULL, 10); - bpp_specified = true; - was_digit = false; - } else - goto done; - break; - case 'x': - if (!yres_specified && was_digit) { - yres = simple_strtol(&name[i+1], NULL, 10); - yres_specified = true; - was_digit = false; - } else - goto done; - case '0' ... '9': - was_digit = true; - break; - case 'M': - if (yres_specified || cvt || was_digit) - goto done; - cvt = true; - break; - case 'R': - if (yres_specified || cvt || rb || was_digit) - goto done; - rb = true; - break; - case 'm': - if (cvt || yres_specified || was_digit) - goto done; - margins = true; - break; - case 'i': - if (cvt || yres_specified || was_digit) - goto done; - interlace = true; - break; - case 'e': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; - - force = DRM_FORCE_ON; - break; - case 'D': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; - - if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && - (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) - force = DRM_FORCE_ON; - else - force = DRM_FORCE_ON_DIGITAL; - break; - case 'd': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; - - force = DRM_FORCE_OFF; - break; - default: - goto done; - } - } - - if (i < 0 && yres_specified) { - char *ch; - xres = simple_strtol(name, &ch, 10); - if ((ch != NULL) && (*ch == 'x')) - res_specified = true; - else - i = ch - name; - } else if (!yres_specified && was_digit) { - /* catch mode that begins with digits but has no 'x' */ - i = 0; - } -done: - if (i >= 0) { - printk(KERN_WARNING - "parse error at position %i in video mode '%s'\n", - i, name); - mode->specified = false; - return false; - } - - if (res_specified) { - mode->specified = true; - mode->xres = xres; - mode->yres = yres; - } - - if (refresh_specified) { - mode->refresh_specified = true; - mode->refresh = refresh; - } - - if (bpp_specified) { - mode->bpp_specified = true; - mode->bpp = bpp; - } - mode->rb = rb; - mode->cvt = cvt; - mode->interlace = interlace; - mode->margins = margins; - mode->force = force; - - return true; -} -EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector); - -struct drm_display_mode * -drm_mode_create_from_cmdline_mode(struct drm_device *dev, - struct drm_cmdline_mode *cmd) -{ - struct drm_display_mode *mode; - - if (cmd->cvt) - mode = drm_cvt_mode(dev, - cmd->xres, cmd->yres, - cmd->refresh_specified ? cmd->refresh : 60, - cmd->rb, cmd->interlace, - cmd->margins); - else - mode = drm_gtf_mode(dev, - cmd->xres, cmd->yres, - cmd->refresh_specified ? cmd->refresh : 60, - cmd->interlace, - cmd->margins); - if (!mode) - return NULL; - - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - return mode; -} -EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_pci.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_pci.c deleted file mode 100644 index 13f3d936..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_pci.c +++ /dev/null @@ -1,467 +0,0 @@ -/* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */ -/** - * \file drm_pci.c - * \brief Functions and ioctls to manage PCI memory - * - * \warning These interfaces aren't stable yet. - * - * \todo Implement the remaining ioctl's for the PCI pools. - * \todo The wrappers here are so thin that they would be better off inlined.. - * - * \author José Fonseca - * \author Leif Delgass - */ - -/* - * Copyright 2003 José Fonseca. - * Copyright 2003 Leif Delgass. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include "drmP.h" - -/**********************************************************************/ -/** \name PCI memory */ -/*@{*/ - -/** - * \brief Allocate a PCI consistent memory block, for DMA. - */ -drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align) -{ - drm_dma_handle_t *dmah; -#if 1 - unsigned long addr; - size_t sz; -#endif - - /* pci_alloc_consistent only guarantees alignment to the smallest - * PAGE_SIZE order which is greater than or equal to the requested size. - * Return NULL here for now to make sure nobody tries for larger alignment - */ - if (align > size) - return NULL; - - dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); - if (!dmah) - return NULL; - - dmah->size = size; - dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); - - if (dmah->vaddr == NULL) { - kfree(dmah); - return NULL; - } - - memset(dmah->vaddr, 0, size); - - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Reserve */ - for (addr = (unsigned long)dmah->vaddr, sz = size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - SetPageReserved(virt_to_page(addr)); - } - - return dmah; -} - -EXPORT_SYMBOL(drm_pci_alloc); - -/** - * \brief Free a PCI consistent memory block without freeing its descriptor. - * - * This function is for internal use in the Linux-specific DRM core code. - */ -void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) -{ -#if 1 - unsigned long addr; - size_t sz; -#endif - - if (dmah->vaddr) { - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Unreserve */ - for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - } - dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, - dmah->busaddr); - } -} - -/** - * \brief Free a PCI consistent memory block - */ -void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) -{ - __drm_pci_free(dev, dmah); - kfree(dmah); -} - -EXPORT_SYMBOL(drm_pci_free); - -#ifdef CONFIG_PCI - -static int drm_get_pci_domain(struct drm_device *dev) -{ -#ifndef __alpha__ - /* For historical reasons, drm_get_pci_domain() is busticated - * on most archs and has to remain so for userspace interface - * < 1.4, except on alpha which was right from the beginning - */ - if (dev->if_version < 0x10004) - return 0; -#endif /* __alpha__ */ - - return pci_domain_nr(dev->pdev->bus); -} - -static int drm_pci_get_irq(struct drm_device *dev) -{ - return dev->pdev->irq; -} - -static const char *drm_pci_get_name(struct drm_device *dev) -{ - struct pci_driver *pdriver = dev->driver->kdriver.pci; - return pdriver->name; -} - -int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master) -{ - int len, ret; - struct pci_driver *pdriver = dev->driver->kdriver.pci; - master->unique_len = 40; - master->unique_size = master->unique_len; - master->unique = kmalloc(master->unique_size, GFP_KERNEL); - if (master->unique == NULL) - return -ENOMEM; - - - len = snprintf(master->unique, master->unique_len, - "pci:%04x:%02x:%02x.%d", - drm_get_pci_domain(dev), - dev->pdev->bus->number, - PCI_SLOT(dev->pdev->devfn), - PCI_FUNC(dev->pdev->devfn)); - - if (len >= master->unique_len) { - DRM_ERROR("buffer overflow"); - ret = -EINVAL; - goto err; - } else - master->unique_len = len; - - dev->devname = - kmalloc(strlen(pdriver->name) + - master->unique_len + 2, GFP_KERNEL); - - if (dev->devname == NULL) { - ret = -ENOMEM; - goto err; - } - - sprintf(dev->devname, "%s@%s", pdriver->name, - master->unique); - - return 0; -err: - return ret; -} - -int drm_pci_set_unique(struct drm_device *dev, - struct drm_master *master, - struct drm_unique *u) -{ - int domain, bus, slot, func, ret; - const char *bus_name; - - master->unique_len = u->unique_len; - master->unique_size = u->unique_len + 1; - master->unique = kmalloc(master->unique_size, GFP_KERNEL); - if (!master->unique) { - ret = -ENOMEM; - goto err; - } - - if (copy_from_user(master->unique, u->unique, master->unique_len)) { - ret = -EFAULT; - goto err; - } - - master->unique[master->unique_len] = '\0'; - - bus_name = dev->driver->bus->get_name(dev); - dev->devname = kmalloc(strlen(bus_name) + - strlen(master->unique) + 2, GFP_KERNEL); - if (!dev->devname) { - ret = -ENOMEM; - goto err; - } - - sprintf(dev->devname, "%s@%s", bus_name, - master->unique); - - /* Return error if the busid submitted doesn't match the device's actual - * busid. - */ - ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func); - if (ret != 3) { - ret = -EINVAL; - goto err; - } - - domain = bus >> 8; - bus &= 0xff; - - if ((domain != drm_get_pci_domain(dev)) || - (bus != dev->pdev->bus->number) || - (slot != PCI_SLOT(dev->pdev->devfn)) || - (func != PCI_FUNC(dev->pdev->devfn))) { - ret = -EINVAL; - goto err; - } - return 0; -err: - return ret; -} - - -static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) -{ - if ((p->busnum >> 8) != drm_get_pci_domain(dev) || - (p->busnum & 0xff) != dev->pdev->bus->number || - p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) - return -EINVAL; - - p->irq = dev->pdev->irq; - - DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, - p->irq); - return 0; -} - -int drm_pci_agp_init(struct drm_device *dev) -{ - if (drm_core_has_AGP(dev)) { - if (drm_pci_device_is_agp(dev)) - dev->agp = drm_agp_init(dev); - if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) - && (dev->agp == NULL)) { - DRM_ERROR("Cannot initialize the agpgart module.\n"); - return -EINVAL; - } - if (drm_core_has_MTRR(dev)) { - if (dev->agp) - dev->agp->agp_mtrr = - mtrr_add(dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * - 1024 * 1024, MTRR_TYPE_WRCOMB, 1); - } - } - return 0; -} - -static struct drm_bus drm_pci_bus = { - .bus_type = DRIVER_BUS_PCI, - .get_irq = drm_pci_get_irq, - .get_name = drm_pci_get_name, - .set_busid = drm_pci_set_busid, - .set_unique = drm_pci_set_unique, - .irq_by_busid = drm_pci_irq_by_busid, - .agp_init = drm_pci_agp_init, -}; - -/** - * Register. - * - * \param pdev - PCI device structure - * \param ent entry from the PCI ID table with device type flags - * \return zero on success or a negative number on failure. - * - * Attempt to gets inter module "drm" information. If we are first - * then register the character device and inter module information. - * Try and register, if we fail to register, backout previous work. - */ -int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver) -{ - struct drm_device *dev; - int ret; - - DRM_DEBUG("\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - ret = pci_enable_device(pdev); - if (ret) - goto err_g1; - - dev->pdev = pdev; - dev->dev = &pdev->dev; - - dev->pci_device = pdev->device; - dev->pci_vendor = pdev->vendor; - -#ifdef __alpha__ - dev->hose = pdev->sysdata; -#endif - - mutex_lock(&drm_global_mutex); - - if ((ret = drm_fill_in_dev(dev, ent, driver))) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g2; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - pci_set_drvdata(pdev, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g2; - } - - if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) - goto err_g3; - - if (dev->driver->load) { - ret = dev->driver->load(dev, ent->driver_data); - if (ret) - goto err_g4; - } - - /* setup the grouping for the legacy output */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = drm_mode_group_init_legacy_group(dev, - &dev->primary->mode_group); - if (ret) - goto err_g4; - } - - list_add_tail(&dev->driver_item, &driver->device_list); - - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, pci_name(pdev), dev->primary->index); - - mutex_unlock(&drm_global_mutex); - return 0; - -err_g4: - drm_put_minor(&dev->primary); -err_g3: - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); -err_g2: - pci_disable_device(pdev); -err_g1: - kfree(dev); - mutex_unlock(&drm_global_mutex); - return ret; -} -EXPORT_SYMBOL(drm_get_pci_dev); - -/** - * PCI device initialization. Called direct from modules at load time. - * - * \return zero on success or a negative number on failure. - * - * Initializes a drm_device structures,registering the - * stubs and initializing the AGP device. - * - * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and - * after the initialization for driver customization. - */ -int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) -{ - struct pci_dev *pdev = NULL; - const struct pci_device_id *pid; - int i; - - DRM_DEBUG("\n"); - - INIT_LIST_HEAD(&driver->device_list); - driver->kdriver.pci = pdriver; - driver->bus = &drm_pci_bus; - - if (driver->driver_features & DRIVER_MODESET) - return pci_register_driver(pdriver); - - /* If not using KMS, fall back to stealth mode manual scanning. */ - for (i = 0; pdriver->id_table[i].vendor != 0; i++) { - pid = &pdriver->id_table[i]; - - /* Loop around setting up a DRM device for each PCI device - * matching our ID and device class. If we had the internal - * function that pci_get_subsys and pci_get_class used, we'd - * be able to just pass pid in instead of doing a two-stage - * thing. - */ - pdev = NULL; - while ((pdev = - pci_get_subsys(pid->vendor, pid->device, pid->subvendor, - pid->subdevice, pdev)) != NULL) { - if ((pdev->class & pid->class_mask) != pid->class) - continue; - - /* stealth mode requires a manual probe */ - pci_dev_get(pdev); - drm_get_pci_dev(pdev, pid, driver); - } - } - return 0; -} - -#else - -int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) -{ - return -1; -} - -#endif - -EXPORT_SYMBOL(drm_pci_init); - -/*@}*/ -void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) -{ - struct drm_device *dev, *tmp; - DRM_DEBUG("\n"); - - if (driver->driver_features & DRIVER_MODESET) { - pci_unregister_driver(pdriver); - } else { - list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) - drm_put_dev(dev); - } - DRM_INFO("Module unloaded\n"); -} -EXPORT_SYMBOL(drm_pci_exit); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_platform.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_platform.c deleted file mode 100644 index 82431dca..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_platform.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Derived from drm_pci.c - * - * Copyright 2003 José Fonseca. - * Copyright 2003 Leif Delgass. - * Copyright (c) 2009, Code Aurora Forum. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include "drmP.h" - -/** - * Register. - * - * \param platdev - Platform device struture - * \return zero on success or a negative number on failure. - * - * Attempt to gets inter module "drm" information. If we are first - * then register the character device and inter module information. - * Try and register, if we fail to register, backout previous work. - */ - -int drm_get_platform_dev(struct platform_device *platdev, - struct drm_driver *driver) -{ - struct drm_device *dev; - int ret; - - DRM_DEBUG("\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->platformdev = platdev; - dev->dev = &platdev->dev; - - mutex_lock(&drm_global_mutex); - - ret = drm_fill_in_dev(dev, NULL, driver); - - if (ret) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g1; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - dev_set_drvdata(&platdev->dev, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g1; - } - - ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); - if (ret) - goto err_g2; - - if (dev->driver->load) { - ret = dev->driver->load(dev, 0); - if (ret) - goto err_g3; - } - - /* setup the grouping for the legacy output */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = drm_mode_group_init_legacy_group(dev, - &dev->primary->mode_group); - if (ret) - goto err_g3; - } - - list_add_tail(&dev->driver_item, &driver->device_list); - - mutex_unlock(&drm_global_mutex); - - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - - return 0; - -err_g3: - drm_put_minor(&dev->primary); -err_g2: - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); -err_g1: - kfree(dev); - mutex_unlock(&drm_global_mutex); - return ret; -} -EXPORT_SYMBOL(drm_get_platform_dev); - -static int drm_platform_get_irq(struct drm_device *dev) -{ - return platform_get_irq(dev->platformdev, 0); -} - -static const char *drm_platform_get_name(struct drm_device *dev) -{ - return dev->platformdev->name; -} - -static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master) -{ - int len, ret, id; - - master->unique_len = 13 + strlen(dev->platformdev->name); - master->unique_size = master->unique_len; - master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL); - - if (master->unique == NULL) - return -ENOMEM; - - id = dev->platformdev->id; - - /* if only a single instance of the platform device, id will be - * set to -1.. use 0 instead to avoid a funny looking bus-id: - */ - if (id == -1) - id = 0; - - len = snprintf(master->unique, master->unique_len, - "platform:%s:%02d", dev->platformdev->name, id); - - if (len > master->unique_len) { - DRM_ERROR("Unique buffer overflowed\n"); - ret = -EINVAL; - goto err; - } - - dev->devname = - kmalloc(strlen(dev->platformdev->name) + - master->unique_len + 2, GFP_KERNEL); - - if (dev->devname == NULL) { - ret = -ENOMEM; - goto err; - } - - sprintf(dev->devname, "%s@%s", dev->platformdev->name, - master->unique); - return 0; -err: - return ret; -} - -static struct drm_bus drm_platform_bus = { - .bus_type = DRIVER_BUS_PLATFORM, - .get_irq = drm_platform_get_irq, - .get_name = drm_platform_get_name, - .set_busid = drm_platform_set_busid, -}; - -/** - * Platform device initialization. Called direct from modules. - * - * \return zero on success or a negative number on failure. - * - * Initializes a drm_device structures,registering the - * stubs - * - * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and - * after the initialization for driver customization. - */ - -int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device) -{ - DRM_DEBUG("\n"); - - driver->kdriver.platform_device = platform_device; - driver->bus = &drm_platform_bus; - INIT_LIST_HEAD(&driver->device_list); - return drm_get_platform_dev(platform_device, driver); -} -EXPORT_SYMBOL(drm_platform_init); - -void drm_platform_exit(struct drm_driver *driver, struct platform_device *platform_device) -{ - struct drm_device *dev, *tmp; - DRM_DEBUG("\n"); - - list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) - drm_put_dev(dev); - DRM_INFO("Module unloaded\n"); -} -EXPORT_SYMBOL(drm_platform_exit); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_prime.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_prime.c deleted file mode 100644 index 1bdf2b54..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_prime.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright © 2012 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Dave Airlie - * Rob Clark - * - */ - -#include -#include -#include "drmP.h" - -/* - * DMA-BUF/GEM Object references and lifetime overview: - * - * On the export the dma_buf holds a reference to the exporting GEM - * object. It takes this reference in handle_to_fd_ioctl, when it - * first calls .prime_export and stores the exporting GEM object in - * the dma_buf priv. This reference is released when the dma_buf - * object goes away in the driver .release function. - * - * On the import the importing GEM object holds a reference to the - * dma_buf (which in turn holds a ref to the exporting GEM object). - * It takes that reference in the fd_to_handle ioctl. - * It calls dma_buf_get, creates an attachment to it and stores the - * attachment in the GEM object. When this attachment is destroyed - * when the imported object is destroyed, we remove the attachment - * and drop the reference to the dma_buf. - * - * Thus the chain of references always flows in one direction - * (avoiding loops): importing_gem -> dmabuf -> exporting_gem - * - * Self-importing: if userspace is using PRIME as a replacement for flink - * then it will get a fd->handle request for a GEM object that it created. - * Drivers should detect this situation and return back the gem object - * from the dma-buf private. - */ - -struct drm_prime_member { - struct list_head entry; - struct dma_buf *dma_buf; - uint32_t handle; -}; - -int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, uint32_t flags, - int *prime_fd) -{ - struct drm_gem_object *obj; - void *buf; - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) - return -ENOENT; - - mutex_lock(&file_priv->prime.lock); - /* re-export the original imported object */ - if (obj->import_attach) { - get_dma_buf(obj->import_attach->dmabuf); - *prime_fd = dma_buf_fd(obj->import_attach->dmabuf, flags); - drm_gem_object_unreference_unlocked(obj); - mutex_unlock(&file_priv->prime.lock); - return 0; - } - - if (obj->export_dma_buf) { - get_dma_buf(obj->export_dma_buf); - *prime_fd = dma_buf_fd(obj->export_dma_buf, flags); - drm_gem_object_unreference_unlocked(obj); - } else { - buf = dev->driver->gem_prime_export(dev, obj, flags); - if (IS_ERR(buf)) { - /* normally the created dma-buf takes ownership of the ref, - * but if that fails then drop the ref - */ - drm_gem_object_unreference_unlocked(obj); - mutex_unlock(&file_priv->prime.lock); - return PTR_ERR(buf); - } - obj->export_dma_buf = buf; - *prime_fd = dma_buf_fd(buf, flags); - } - mutex_unlock(&file_priv->prime.lock); - return 0; -} -EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); - -int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, uint32_t *handle) -{ - struct dma_buf *dma_buf; - struct drm_gem_object *obj; - int ret; - - dma_buf = dma_buf_get(prime_fd); - if (IS_ERR(dma_buf)) - return PTR_ERR(dma_buf); - - mutex_lock(&file_priv->prime.lock); - - ret = drm_prime_lookup_imported_buf_handle(&file_priv->prime, - dma_buf, handle); - if (!ret) { - ret = 0; - goto out_put; - } - - /* never seen this one, need to import */ - obj = dev->driver->gem_prime_import(dev, dma_buf); - if (IS_ERR(obj)) { - ret = PTR_ERR(obj); - goto out_put; - } - - ret = drm_gem_handle_create(file_priv, obj, handle); - drm_gem_object_unreference_unlocked(obj); - if (ret) - goto out_put; - - ret = drm_prime_add_imported_buf_handle(&file_priv->prime, - dma_buf, *handle); - if (ret) - goto fail; - - mutex_unlock(&file_priv->prime.lock); - return 0; - -fail: - /* hmm, if driver attached, we are relying on the free-object path - * to detach.. which seems ok.. - */ - drm_gem_object_handle_unreference_unlocked(obj); -out_put: - dma_buf_put(dma_buf); - mutex_unlock(&file_priv->prime.lock); - return ret; -} -EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); - -int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_prime_handle *args = data; - uint32_t flags; - - if (!drm_core_check_feature(dev, DRIVER_PRIME)) - return -EINVAL; - - if (!dev->driver->prime_handle_to_fd) - return -ENOSYS; - - /* check flags are valid */ - if (args->flags & ~DRM_CLOEXEC) - return -EINVAL; - - /* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */ - flags = args->flags & DRM_CLOEXEC; - - return dev->driver->prime_handle_to_fd(dev, file_priv, - args->handle, flags, &args->fd); -} - -int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_prime_handle *args = data; - - if (!drm_core_check_feature(dev, DRIVER_PRIME)) - return -EINVAL; - - if (!dev->driver->prime_fd_to_handle) - return -ENOSYS; - - return dev->driver->prime_fd_to_handle(dev, file_priv, - args->fd, &args->handle); -} - -/* - * drm_prime_pages_to_sg - * - * this helper creates an sg table object from a set of pages - * the driver is responsible for mapping the pages into the - * importers address space - */ -struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) -{ - struct sg_table *sg = NULL; - struct scatterlist *iter; - int i; - int ret; - - sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!sg) - goto out; - - ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); - if (ret) - goto out; - - for_each_sg(sg->sgl, iter, nr_pages, i) - sg_set_page(iter, pages[i], PAGE_SIZE, 0); - - return sg; -out: - kfree(sg); - return NULL; -} -EXPORT_SYMBOL(drm_prime_pages_to_sg); - -/* helper function to cleanup a GEM/prime object */ -void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) -{ - struct dma_buf_attachment *attach; - struct dma_buf *dma_buf; - attach = obj->import_attach; - if (sg) - dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL); - dma_buf = attach->dmabuf; - dma_buf_detach(attach->dmabuf, attach); - /* remove the reference */ - dma_buf_put(dma_buf); -} -EXPORT_SYMBOL(drm_prime_gem_destroy); - -void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) -{ - INIT_LIST_HEAD(&prime_fpriv->head); - mutex_init(&prime_fpriv->lock); -} -EXPORT_SYMBOL(drm_prime_init_file_private); - -void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) -{ - struct drm_prime_member *member, *safe; - list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { - list_del(&member->entry); - kfree(member); - } -} -EXPORT_SYMBOL(drm_prime_destroy_file_private); - -int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) -{ - struct drm_prime_member *member; - - member = kmalloc(sizeof(*member), GFP_KERNEL); - if (!member) - return -ENOMEM; - - member->dma_buf = dma_buf; - member->handle = handle; - list_add(&member->entry, &prime_fpriv->head); - return 0; -} -EXPORT_SYMBOL(drm_prime_add_imported_buf_handle); - -int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle) -{ - struct drm_prime_member *member; - - list_for_each_entry(member, &prime_fpriv->head, entry) { - if (member->dma_buf == dma_buf) { - *handle = member->handle; - return 0; - } - } - return -ENOENT; -} -EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle); - -void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) -{ - struct drm_prime_member *member, *safe; - - mutex_lock(&prime_fpriv->lock); - list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { - if (member->dma_buf == dma_buf) { - list_del(&member->entry); - kfree(member); - } - } - mutex_unlock(&prime_fpriv->lock); -} -EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_proc.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_proc.c deleted file mode 100644 index fff87221..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_proc.c +++ /dev/null @@ -1,221 +0,0 @@ -/** - * \file drm_proc.c - * /proc support for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - * - * \par Acknowledgements: - * Matthew J Sottek sent in a patch to fix - * the problem with the proc files not outputting all their information. - */ - -/* - * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include "drmP.h" - -/*************************************************** - * Initialization, etc. - **************************************************/ - -/** - * Proc file list. - */ -static struct drm_info_list drm_proc_list[] = { - {"name", drm_name_info, 0}, - {"vm", drm_vm_info, 0}, - {"clients", drm_clients_info, 0}, - {"queues", drm_queues_info, 0}, - {"bufs", drm_bufs_info, 0}, - {"gem_names", drm_gem_name_info, DRIVER_GEM}, -#if DRM_DEBUG_CODE - {"vma", drm_vma_info, 0}, -#endif -}; -#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) - -static int drm_proc_open(struct inode *inode, struct file *file) -{ - struct drm_info_node* node = PDE(inode)->data; - - return single_open(file, node->info_ent->show, node); -} - -static const struct file_operations drm_proc_fops = { - .owner = THIS_MODULE, - .open = drm_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - - -/** - * Initialize a given set of proc files for a device - * - * \param files The array of files to create - * \param count The number of files given - * \param root DRI proc dir entry. - * \param minor device minor number - * \return Zero on success, non-zero on failure - * - * Create a given set of proc files represented by an array of - * gdm_proc_lists in the given root directory. - */ -int drm_proc_create_files(struct drm_info_list *files, int count, - struct proc_dir_entry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct proc_dir_entry *ent; - struct drm_info_node *tmp; - int i, ret; - - for (i = 0; i < count; i++) { - u32 features = files[i].driver_features; - - if (features != 0 && - (dev->driver->driver_features & features) != features) - continue; - - tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); - if (tmp == NULL) { - ret = -1; - goto fail; - } - tmp->minor = minor; - tmp->info_ent = &files[i]; - list_add(&tmp->list, &minor->proc_nodes.list); - - ent = proc_create_data(files[i].name, S_IRUGO, root, - &drm_proc_fops, tmp); - if (!ent) { - DRM_ERROR("Cannot create /proc/dri/%s/%s\n", - root->name, files[i].name); - list_del(&tmp->list); - kfree(tmp); - ret = -1; - goto fail; - } - - } - return 0; - -fail: - for (i = 0; i < count; i++) - remove_proc_entry(drm_proc_list[i].name, minor->proc_root); - return ret; -} - -/** - * Initialize the DRI proc filesystem for a device - * - * \param dev DRM device - * \param minor device minor number - * \param root DRI proc dir entry. - * \param dev_root resulting DRI device proc dir entry. - * \return root entry pointer on success, or NULL on failure. - * - * Create the DRI proc root entry "/proc/dri", the device proc root entry - * "/proc/dri/%minor%/", and each entry in proc_list as - * "/proc/dri/%minor%/%name%". - */ -int drm_proc_init(struct drm_minor *minor, int minor_id, - struct proc_dir_entry *root) -{ - char name[64]; - int ret; - - INIT_LIST_HEAD(&minor->proc_nodes.list); - sprintf(name, "%d", minor_id); - minor->proc_root = proc_mkdir(name, root); - if (!minor->proc_root) { - DRM_ERROR("Cannot create /proc/dri/%s\n", name); - return -1; - } - - ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES, - minor->proc_root, minor); - if (ret) { - remove_proc_entry(name, root); - minor->proc_root = NULL; - DRM_ERROR("Failed to create core drm proc files\n"); - return ret; - } - - return 0; -} - -int drm_proc_remove_files(struct drm_info_list *files, int count, - struct drm_minor *minor) -{ - struct list_head *pos, *q; - struct drm_info_node *tmp; - int i; - - for (i = 0; i < count; i++) { - list_for_each_safe(pos, q, &minor->proc_nodes.list) { - tmp = list_entry(pos, struct drm_info_node, list); - if (tmp->info_ent == &files[i]) { - remove_proc_entry(files[i].name, - minor->proc_root); - list_del(pos); - kfree(tmp); - } - } - } - return 0; -} - -/** - * Cleanup the proc filesystem resources. - * - * \param minor device minor number. - * \param root DRI proc dir entry. - * \param dev_root DRI device proc dir entry. - * \return always zero. - * - * Remove all proc entries created by proc_init(). - */ -int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) -{ - char name[64]; - - if (!root || !minor->proc_root) - return 0; - - drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor); - - sprintf(name, "%d", minor->index); - remove_proc_entry(name, root); - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_scatter.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_scatter.c deleted file mode 100644 index 7525e031..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_scatter.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * \file drm_scatter.c - * IOCTLs to manage scatter/gather memory - * - * \author Gareth Hughes - */ - -/* - * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "drmP.h" - -#define DEBUG_SCATTER 0 - -static inline void *drm_vmalloc_dma(unsigned long size) -{ -#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE) - return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE); -#else - return vmalloc_32(size); -#endif -} - -void drm_sg_cleanup(struct drm_sg_mem * entry) -{ - struct page *page; - int i; - - for (i = 0; i < entry->pages; i++) { - page = entry->pagelist[i]; - if (page) - ClearPageReserved(page); - } - - vfree(entry->virtual); - - kfree(entry->busaddr); - kfree(entry->pagelist); - kfree(entry); -} - -#ifdef _LP64 -# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1))) -#else -# define ScatterHandle(x) (unsigned int)(x) -#endif - -int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) -{ - struct drm_sg_mem *entry; - unsigned long pages, i, j; - - DRM_DEBUG("\n"); - - if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; - - if (dev->sg) - return -EINVAL; - - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages); - - entry->pages = pages; - entry->pagelist = kcalloc(pages, sizeof(*entry->pagelist), GFP_KERNEL); - if (!entry->pagelist) { - kfree(entry); - return -ENOMEM; - } - - entry->busaddr = kcalloc(pages, sizeof(*entry->busaddr), GFP_KERNEL); - if (!entry->busaddr) { - kfree(entry->pagelist); - kfree(entry); - return -ENOMEM; - } - - entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); - if (!entry->virtual) { - kfree(entry->busaddr); - kfree(entry->pagelist); - kfree(entry); - return -ENOMEM; - } - - /* This also forces the mapping of COW pages, so our page list - * will be valid. Please don't remove it... - */ - memset(entry->virtual, 0, pages << PAGE_SHIFT); - - entry->handle = ScatterHandle((unsigned long)entry->virtual); - - DRM_DEBUG("handle = %08lx\n", entry->handle); - DRM_DEBUG("virtual = %p\n", entry->virtual); - - for (i = (unsigned long)entry->virtual, j = 0; j < pages; - i += PAGE_SIZE, j++) { - entry->pagelist[j] = vmalloc_to_page((void *)i); - if (!entry->pagelist[j]) - goto failed; - SetPageReserved(entry->pagelist[j]); - } - - request->handle = entry->handle; - - dev->sg = entry; - -#if DEBUG_SCATTER - /* Verify that each page points to its virtual address, and vice - * versa. - */ - { - int error = 0; - - for (i = 0; i < pages; i++) { - unsigned long *tmp; - - tmp = page_address(entry->pagelist[i]); - for (j = 0; - j < PAGE_SIZE / sizeof(unsigned long); - j++, tmp++) { - *tmp = 0xcafebabe; - } - tmp = (unsigned long *)((u8 *) entry->virtual + - (PAGE_SIZE * i)); - for (j = 0; - j < PAGE_SIZE / sizeof(unsigned long); - j++, tmp++) { - if (*tmp != 0xcafebabe && error == 0) { - error = 1; - DRM_ERROR("Scatter allocation error, " - "pagelist does not match " - "virtual mapping\n"); - } - } - tmp = page_address(entry->pagelist[i]); - for (j = 0; - j < PAGE_SIZE / sizeof(unsigned long); - j++, tmp++) { - *tmp = 0; - } - } - if (error == 0) - DRM_ERROR("Scatter allocation matches pagelist\n"); - } -#endif - - return 0; - - failed: - drm_sg_cleanup(entry); - return -ENOMEM; -} - -int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_scatter_gather *request = data; - - return drm_sg_alloc(dev, request); - -} - -int drm_sg_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_scatter_gather *request = data; - struct drm_sg_mem *entry; - - if (!drm_core_check_feature(dev, DRIVER_SG)) - return -EINVAL; - - entry = dev->sg; - dev->sg = NULL; - - if (!entry || entry->handle != request->handle) - return -EINVAL; - - DRM_DEBUG("virtual = %p\n", entry->virtual); - - drm_sg_cleanup(entry); - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_stub.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_stub.c deleted file mode 100644 index aa454f80..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_stub.c +++ /dev/null @@ -1,520 +0,0 @@ -/** - * \file drm_stub.h - * Stub support - * - * \author Rickard E. (Rik) Faith - */ - -/* - * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org - * - * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include "drmP.h" -#include "drm_core.h" - -unsigned int drm_debug = 0; /* 1 to enable debug output */ -EXPORT_SYMBOL(drm_debug); - -unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ -EXPORT_SYMBOL(drm_vblank_offdelay); - -unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ -EXPORT_SYMBOL(drm_timestamp_precision); - -MODULE_AUTHOR(CORE_AUTHOR); -MODULE_DESCRIPTION(CORE_DESC); -MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(debug, "Enable debug output"); -MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); -MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); - -module_param_named(debug, drm_debug, int, 0600); -module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); -module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); - -struct idr drm_minors_idr; - -struct class *drm_class; -struct proc_dir_entry *drm_proc_root; -struct dentry *drm_debugfs_root; - -int drm_err(const char *func, const char *format, ...) -{ - struct va_format vaf; - va_list args; - int r; - - va_start(args, format); - - vaf.fmt = format; - vaf.va = &args; - - r = printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf); - - va_end(args); - - return r; -} -EXPORT_SYMBOL(drm_err); - -void drm_ut_debug_printk(unsigned int request_level, - const char *prefix, - const char *function_name, - const char *format, ...) -{ - va_list args; - - if (drm_debug & request_level) { - if (function_name) - printk(KERN_DEBUG "[%s:%s], ", prefix, function_name); - va_start(args, format); - vprintk(format, args); - va_end(args); - } -} -EXPORT_SYMBOL(drm_ut_debug_printk); - -static int drm_minor_get_id(struct drm_device *dev, int type) -{ - int new_id; - int ret; - int base = 0, limit = 63; - - if (type == DRM_MINOR_CONTROL) { - base += 64; - limit = base + 127; - } else if (type == DRM_MINOR_RENDER) { - base += 128; - limit = base + 255; - } - -again: - if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { - DRM_ERROR("Out of memory expanding drawable idr\n"); - return -ENOMEM; - } - mutex_lock(&dev->struct_mutex); - ret = idr_get_new_above(&drm_minors_idr, NULL, - base, &new_id); - mutex_unlock(&dev->struct_mutex); - if (ret == -EAGAIN) { - goto again; - } else if (ret) { - return ret; - } - - if (new_id >= limit) { - idr_remove(&drm_minors_idr, new_id); - return -EINVAL; - } - return new_id; -} - -struct drm_master *drm_master_create(struct drm_minor *minor) -{ - struct drm_master *master; - - master = kzalloc(sizeof(*master), GFP_KERNEL); - if (!master) - return NULL; - - kref_init(&master->refcount); - spin_lock_init(&master->lock.spinlock); - init_waitqueue_head(&master->lock.lock_queue); - drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); - INIT_LIST_HEAD(&master->magicfree); - master->minor = minor; - - list_add_tail(&master->head, &minor->master_list); - - return master; -} - -struct drm_master *drm_master_get(struct drm_master *master) -{ - kref_get(&master->refcount); - return master; -} -EXPORT_SYMBOL(drm_master_get); - -static void drm_master_destroy(struct kref *kref) -{ - struct drm_master *master = container_of(kref, struct drm_master, refcount); - struct drm_magic_entry *pt, *next; - struct drm_device *dev = master->minor->dev; - struct drm_map_list *r_list, *list_temp; - - list_del(&master->head); - - if (dev->driver->master_destroy) - dev->driver->master_destroy(dev, master); - - list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) { - if (r_list->master == master) { - drm_rmmap_locked(dev, r_list->map); - r_list = NULL; - } - } - - if (master->unique) { - kfree(master->unique); - master->unique = NULL; - master->unique_len = 0; - } - - kfree(dev->devname); - dev->devname = NULL; - - list_for_each_entry_safe(pt, next, &master->magicfree, head) { - list_del(&pt->head); - drm_ht_remove_item(&master->magiclist, &pt->hash_item); - kfree(pt); - } - - drm_ht_remove(&master->magiclist); - - kfree(master); -} - -void drm_master_put(struct drm_master **master) -{ - kref_put(&(*master)->refcount, drm_master_destroy); - *master = NULL; -} -EXPORT_SYMBOL(drm_master_put); - -int drm_setmaster_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret = 0; - - if (file_priv->is_master) - return 0; - - if (file_priv->minor->master && file_priv->minor->master != file_priv->master) - return -EINVAL; - - if (!file_priv->master) - return -EINVAL; - - if (!file_priv->minor->master && - file_priv->minor->master != file_priv->master) { - mutex_lock(&dev->struct_mutex); - file_priv->minor->master = drm_master_get(file_priv->master); - file_priv->is_master = 1; - if (dev->driver->master_set) { - ret = dev->driver->master_set(dev, file_priv, false); - if (unlikely(ret != 0)) { - file_priv->is_master = 0; - drm_master_put(&file_priv->minor->master); - } - } - mutex_unlock(&dev->struct_mutex); - } - - return 0; -} - -int drm_dropmaster_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - if (!file_priv->is_master) - return -EINVAL; - - if (!file_priv->minor->master) - return -EINVAL; - - mutex_lock(&dev->struct_mutex); - if (dev->driver->master_drop) - dev->driver->master_drop(dev, file_priv, false); - drm_master_put(&file_priv->minor->master); - file_priv->is_master = 0; - mutex_unlock(&dev->struct_mutex); - return 0; -} - -int drm_fill_in_dev(struct drm_device *dev, - const struct pci_device_id *ent, - struct drm_driver *driver) -{ - int retcode; - - INIT_LIST_HEAD(&dev->filelist); - INIT_LIST_HEAD(&dev->ctxlist); - INIT_LIST_HEAD(&dev->vmalist); - INIT_LIST_HEAD(&dev->maplist); - INIT_LIST_HEAD(&dev->vblank_event_list); - - spin_lock_init(&dev->count_lock); - spin_lock_init(&dev->event_lock); - mutex_init(&dev->struct_mutex); - mutex_init(&dev->ctxlist_mutex); - - if (drm_ht_create(&dev->map_hash, 12)) { - return -ENOMEM; - } - - /* the DRM has 6 basic counters */ - dev->counters = 6; - dev->types[0] = _DRM_STAT_LOCK; - dev->types[1] = _DRM_STAT_OPENS; - dev->types[2] = _DRM_STAT_CLOSES; - dev->types[3] = _DRM_STAT_IOCTLS; - dev->types[4] = _DRM_STAT_LOCKS; - dev->types[5] = _DRM_STAT_UNLOCKS; - - dev->driver = driver; - - if (dev->driver->bus->agp_init) { - retcode = dev->driver->bus->agp_init(dev); - if (retcode) - goto error_out_unreg; - } - - - - retcode = drm_ctxbitmap_init(dev); - if (retcode) { - DRM_ERROR("Cannot allocate memory for context bitmap.\n"); - goto error_out_unreg; - } - - if (driver->driver_features & DRIVER_GEM) { - retcode = drm_gem_init(dev); - if (retcode) { - DRM_ERROR("Cannot initialize graphics execution " - "manager (GEM)\n"); - goto error_out_unreg; - } - } - - return 0; - - error_out_unreg: - drm_lastclose(dev); - return retcode; -} -EXPORT_SYMBOL(drm_fill_in_dev); - - -/** - * Get a secondary minor number. - * - * \param dev device data structure - * \param sec-minor structure to hold the assigned minor - * \return negative number on failure. - * - * Search an empty entry and initialize it to the given parameters, and - * create the proc init entry via proc_init(). This routines assigns - * minor numbers to secondary heads of multi-headed cards - */ -int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) -{ - struct drm_minor *new_minor; - int ret; - int minor_id; - - DRM_DEBUG("\n"); - - minor_id = drm_minor_get_id(dev, type); - if (minor_id < 0) - return minor_id; - - new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); - if (!new_minor) { - ret = -ENOMEM; - goto err_idr; - } - - new_minor->type = type; - new_minor->device = MKDEV(DRM_MAJOR, minor_id); - new_minor->dev = dev; - new_minor->index = minor_id; - INIT_LIST_HEAD(&new_minor->master_list); - - idr_replace(&drm_minors_idr, new_minor, minor_id); - - if (type == DRM_MINOR_LEGACY) { - ret = drm_proc_init(new_minor, minor_id, drm_proc_root); - if (ret) { - DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); - goto err_mem; - } - } else - new_minor->proc_root = NULL; - -#if defined(CONFIG_DEBUG_FS) - ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); - if (ret) { - DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); - goto err_g2; - } -#endif - - ret = drm_sysfs_device_add(new_minor); - if (ret) { - printk(KERN_ERR - "DRM: Error sysfs_device_add.\n"); - goto err_g2; - } - *minor = new_minor; - - DRM_DEBUG("new minor assigned %d\n", minor_id); - return 0; - - -err_g2: - if (new_minor->type == DRM_MINOR_LEGACY) - drm_proc_cleanup(new_minor, drm_proc_root); -err_mem: - kfree(new_minor); -err_idr: - idr_remove(&drm_minors_idr, minor_id); - *minor = NULL; - return ret; -} -EXPORT_SYMBOL(drm_get_minor); - -/** - * Put a secondary minor number. - * - * \param sec_minor - structure to be released - * \return always zero - * - * Cleans up the proc resources. Not legal for this to be the - * last minor released. - * - */ -int drm_put_minor(struct drm_minor **minor_p) -{ - struct drm_minor *minor = *minor_p; - - DRM_DEBUG("release secondary minor %d\n", minor->index); - - if (minor->type == DRM_MINOR_LEGACY) - drm_proc_cleanup(minor, drm_proc_root); -#if defined(CONFIG_DEBUG_FS) - drm_debugfs_cleanup(minor); -#endif - - drm_sysfs_device_remove(minor); - - idr_remove(&drm_minors_idr, minor->index); - - kfree(minor); - *minor_p = NULL; - return 0; -} -EXPORT_SYMBOL(drm_put_minor); - -static void drm_unplug_minor(struct drm_minor *minor) -{ - drm_sysfs_device_remove(minor); -} - -/** - * Called via drm_exit() at module unload time or when pci device is - * unplugged. - * - * Cleans up all DRM device, calling drm_lastclose(). - * - */ -void drm_put_dev(struct drm_device *dev) -{ - struct drm_driver *driver; - struct drm_map_list *r_list, *list_temp; - - DRM_DEBUG("\n"); - - if (!dev) { - DRM_ERROR("cleanup called no dev\n"); - return; - } - driver = dev->driver; - - drm_lastclose(dev); - - if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && - dev->agp && dev->agp->agp_mtrr >= 0) { - int retval; - retval = mtrr_del(dev->agp->agp_mtrr, - dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size * 1024 * 1024); - DRM_DEBUG("mtrr_del=%d\n", retval); - } - - if (dev->driver->unload) - dev->driver->unload(dev); - - if (drm_core_has_AGP(dev) && dev->agp) { - kfree(dev->agp); - dev->agp = NULL; - } - - drm_vblank_cleanup(dev); - - list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) - drm_rmmap(dev, r_list->map); - drm_ht_remove(&dev->map_hash); - - drm_ctxbitmap_cleanup(dev); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); - - if (driver->driver_features & DRIVER_GEM) - drm_gem_destroy(dev); - - drm_put_minor(&dev->primary); - - list_del(&dev->driver_item); - if (dev->devname) { - kfree(dev->devname); - dev->devname = NULL; - } - kfree(dev); -} -EXPORT_SYMBOL(drm_put_dev); - -void drm_unplug_dev(struct drm_device *dev) -{ - /* for a USB device */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_unplug_minor(dev->control); - drm_unplug_minor(dev->primary); - - mutex_lock(&drm_global_mutex); - - drm_device_set_unplugged(dev); - - if (dev->open_count == 0) { - drm_put_dev(dev); - } - mutex_unlock(&drm_global_mutex); -} -EXPORT_SYMBOL(drm_unplug_dev); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_sysfs.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_sysfs.c deleted file mode 100644 index 5a7bd51f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_sysfs.c +++ /dev/null @@ -1,566 +0,0 @@ - -/* - * drm_sysfs.c - Modifications to drm_sysfs_class.c to support - * extra sysfs attribute from DRM. Normal drm_sysfs_class - * does not allow adding attributes. - * - * Copyright (c) 2004 Jon Smirl - * Copyright (c) 2003-2004 Greg Kroah-Hartman - * Copyright (c) 2003-2004 IBM Corp. - * - * This file is released under the GPLv2 - * - */ - -#include -#include -#include -#include -#include - -#include "drm_sysfs.h" -#include "drm_core.h" -#include "drmP.h" - -#define to_drm_minor(d) container_of(d, struct drm_minor, kdev) -#define to_drm_connector(d) container_of(d, struct drm_connector, kdev) - -static struct device_type drm_sysfs_device_minor = { - .name = "drm_minor" -}; - -/** - * drm_class_suspend - DRM class suspend hook - * @dev: Linux device to suspend - * @state: power state to enter - * - * Just figures out what the actual struct drm_device associated with - * @dev is and calls its suspend hook, if present. - */ -static int drm_class_suspend(struct device *dev, pm_message_t state) -{ - if (dev->type == &drm_sysfs_device_minor) { - struct drm_minor *drm_minor = to_drm_minor(dev); - struct drm_device *drm_dev = drm_minor->dev; - - if (drm_minor->type == DRM_MINOR_LEGACY && - !drm_core_check_feature(drm_dev, DRIVER_MODESET) && - drm_dev->driver->suspend) - return drm_dev->driver->suspend(drm_dev, state); - } - return 0; -} - -/** - * drm_class_resume - DRM class resume hook - * @dev: Linux device to resume - * - * Just figures out what the actual struct drm_device associated with - * @dev is and calls its resume hook, if present. - */ -static int drm_class_resume(struct device *dev) -{ - if (dev->type == &drm_sysfs_device_minor) { - struct drm_minor *drm_minor = to_drm_minor(dev); - struct drm_device *drm_dev = drm_minor->dev; - - if (drm_minor->type == DRM_MINOR_LEGACY && - !drm_core_check_feature(drm_dev, DRIVER_MODESET) && - drm_dev->driver->resume) - return drm_dev->driver->resume(drm_dev); - } - return 0; -} - -static char *drm_devnode(struct device *dev, umode_t *mode) -{ - return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); -} - -static CLASS_ATTR_STRING(version, S_IRUGO, - CORE_NAME " " - __stringify(CORE_MAJOR) "." - __stringify(CORE_MINOR) "." - __stringify(CORE_PATCHLEVEL) " " - CORE_DATE); - -/** - * drm_sysfs_create - create a struct drm_sysfs_class structure - * @owner: pointer to the module that is to "own" this struct drm_sysfs_class - * @name: pointer to a string for the name of this class. - * - * This is used to create DRM class pointer that can then be used - * in calls to drm_sysfs_device_add(). - * - * Note, the pointer created here is to be destroyed when finished by making a - * call to drm_sysfs_destroy(). - */ -struct class *drm_sysfs_create(struct module *owner, char *name) -{ - struct class *class; - int err; - - class = class_create(owner, name); - if (IS_ERR(class)) { - err = PTR_ERR(class); - goto err_out; - } - - class->suspend = drm_class_suspend; - class->resume = drm_class_resume; - - err = class_create_file(class, &class_attr_version.attr); - if (err) - goto err_out_class; - - class->devnode = drm_devnode; - - return class; - -err_out_class: - class_destroy(class); -err_out: - return ERR_PTR(err); -} - -/** - * drm_sysfs_destroy - destroys DRM class - * - * Destroy the DRM device class. - */ -void drm_sysfs_destroy(void) -{ - if ((drm_class == NULL) || (IS_ERR(drm_class))) - return; - class_remove_file(drm_class, &class_attr_version.attr); - class_destroy(drm_class); -} - -/** - * drm_sysfs_device_release - do nothing - * @dev: Linux device - * - * Normally, this would free the DRM device associated with @dev, along - * with cleaning up any other stuff. But we do that in the DRM core, so - * this function can just return and hope that the core does its job. - */ -static void drm_sysfs_device_release(struct device *dev) -{ - memset(dev, 0, sizeof(struct device)); - return; -} - -/* - * Connector properties - */ -static ssize_t status_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - enum drm_connector_status status; - int ret; - - ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex); - if (ret) - return ret; - - status = connector->funcs->detect(connector, true); - mutex_unlock(&connector->dev->mode_config.mutex); - - return snprintf(buf, PAGE_SIZE, "%s\n", - drm_get_connector_status_name(status)); -} - -static ssize_t dpms_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - uint64_t dpms_status; - int ret; - - ret = drm_connector_property_get_value(connector, - dev->mode_config.dpms_property, - &dpms_status); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s\n", - drm_get_dpms_name((int)dpms_status)); -} - -static ssize_t enabled_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - - return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" : - "disabled"); -} - -static ssize_t edid_show(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, loff_t off, - size_t count) -{ - struct device *connector_dev = container_of(kobj, struct device, kobj); - struct drm_connector *connector = to_drm_connector(connector_dev); - unsigned char *edid; - size_t size; - - if (!connector->edid_blob_ptr) - return 0; - - edid = connector->edid_blob_ptr->data; - size = connector->edid_blob_ptr->length; - if (!edid) - return 0; - - if (off >= size) - return 0; - - if (off + count > size) - count = size - off; - memcpy(buf, edid + off, count); - - return count; -} - -static ssize_t modes_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_display_mode *mode; - int written = 0; - - list_for_each_entry(mode, &connector->modes, head) { - written += snprintf(buf + written, PAGE_SIZE - written, "%s\n", - mode->name); - } - - return written; -} - -static ssize_t subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop = NULL; - uint64_t subconnector; - int is_tv = 0; - int ret; - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - prop = dev->mode_config.dvi_i_subconnector_property; - break; - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_TV: - prop = dev->mode_config.tv_subconnector_property; - is_tv = 1; - break; - default: - DRM_ERROR("Wrong connector type for this property\n"); - return 0; - } - - if (!prop) { - DRM_ERROR("Unable to find subconnector property\n"); - return 0; - } - - ret = drm_connector_property_get_value(connector, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", is_tv ? - drm_get_tv_subconnector_name((int)subconnector) : - drm_get_dvi_i_subconnector_name((int)subconnector)); -} - -static ssize_t select_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop = NULL; - uint64_t subconnector; - int is_tv = 0; - int ret; - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - prop = dev->mode_config.dvi_i_select_subconnector_property; - break; - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_TV: - prop = dev->mode_config.tv_select_subconnector_property; - is_tv = 1; - break; - default: - DRM_ERROR("Wrong connector type for this property\n"); - return 0; - } - - if (!prop) { - DRM_ERROR("Unable to find select subconnector property\n"); - return 0; - } - - ret = drm_connector_property_get_value(connector, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", is_tv ? - drm_get_tv_select_name((int)subconnector) : - drm_get_dvi_i_select_name((int)subconnector)); -} - -static struct device_attribute connector_attrs[] = { - __ATTR_RO(status), - __ATTR_RO(enabled), - __ATTR_RO(dpms), - __ATTR_RO(modes), -}; - -/* These attributes are for both DVI-I connectors and all types of tv-out. */ -static struct device_attribute connector_attrs_opt1[] = { - __ATTR_RO(subconnector), - __ATTR_RO(select_subconnector), -}; - -static struct bin_attribute edid_attr = { - .attr.name = "edid", - .attr.mode = 0444, - .size = 0, - .read = edid_show, -}; - -/** - * drm_sysfs_connector_add - add an connector to sysfs - * @connector: connector to add - * - * Create an connector device in sysfs, along with its associated connector - * properties (so far, connection status, dpms, mode list & edid) and - * generate a hotplug event so userspace knows there's a new connector - * available. - * - * Note: - * This routine should only be called *once* for each DRM minor registered. - * A second call for an already registered device will trigger the BUG_ON - * below. - */ -int drm_sysfs_connector_add(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - int attr_cnt = 0; - int opt_cnt = 0; - int i; - int ret = 0; - - /* We shouldn't get called more than once for the same connector */ - BUG_ON(device_is_registered(&connector->kdev)); - - connector->kdev.parent = &dev->primary->kdev; - connector->kdev.class = drm_class; - connector->kdev.release = drm_sysfs_device_release; - - DRM_DEBUG("adding \"%s\" to sysfs\n", - drm_get_connector_name(connector)); - - dev_set_name(&connector->kdev, "card%d-%s", - dev->primary->index, drm_get_connector_name(connector)); - ret = device_register(&connector->kdev); - - if (ret) { - DRM_ERROR("failed to register connector device: %d\n", ret); - goto out; - } - - /* Standard attributes */ - - for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) { - ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]); - if (ret) - goto err_out_files; - } - - /* Optional attributes */ - /* - * In the long run it maybe a good idea to make one set of - * optionals per connector type. - */ - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_TV: - for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) { - ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]); - if (ret) - goto err_out_files; - } - break; - default: - break; - } - - ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr); - if (ret) - goto err_out_files; - - /* Let userspace know we have a new connector */ - drm_sysfs_hotplug_event(dev); - - return 0; - -err_out_files: - for (i = 0; i < opt_cnt; i++) - device_remove_file(&connector->kdev, &connector_attrs_opt1[i]); - for (i = 0; i < attr_cnt; i++) - device_remove_file(&connector->kdev, &connector_attrs[i]); - device_unregister(&connector->kdev); - -out: - return ret; -} -EXPORT_SYMBOL(drm_sysfs_connector_add); - -/** - * drm_sysfs_connector_remove - remove an connector device from sysfs - * @connector: connector to remove - * - * Remove @connector and its associated attributes from sysfs. Note that - * the device model core will take care of sending the "remove" uevent - * at this time, so we don't need to do it. - * - * Note: - * This routine should only be called if the connector was previously - * successfully registered. If @connector hasn't been registered yet, - * you'll likely see a panic somewhere deep in sysfs code when called. - */ -void drm_sysfs_connector_remove(struct drm_connector *connector) -{ - int i; - - if (!connector->kdev.parent) - return; - DRM_DEBUG("removing \"%s\" from sysfs\n", - drm_get_connector_name(connector)); - - for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) - device_remove_file(&connector->kdev, &connector_attrs[i]); - sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr); - device_unregister(&connector->kdev); - connector->kdev.parent = NULL; -} -EXPORT_SYMBOL(drm_sysfs_connector_remove); - -/** - * drm_sysfs_hotplug_event - generate a DRM uevent - * @dev: DRM device - * - * Send a uevent for the DRM device specified by @dev. Currently we only - * set HOTPLUG=1 in the uevent environment, but this could be expanded to - * deal with other types of events. - */ -void drm_sysfs_hotplug_event(struct drm_device *dev) -{ - char *event_string = "HOTPLUG=1"; - char *envp[] = { event_string, NULL }; - - DRM_DEBUG("generating hotplug event\n"); - - kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); -} -EXPORT_SYMBOL(drm_sysfs_hotplug_event); - -/** - * drm_sysfs_device_add - adds a class device to sysfs for a character driver - * @dev: DRM device to be added - * @head: DRM head in question - * - * Add a DRM device to the DRM's device model class. We use @dev's PCI device - * as the parent for the Linux device, and make sure it has a file containing - * the driver we're using (for userspace compatibility). - */ -int drm_sysfs_device_add(struct drm_minor *minor) -{ - int err; - char *minor_str; - - minor->kdev.parent = minor->dev->dev; - - minor->kdev.class = drm_class; - minor->kdev.release = drm_sysfs_device_release; - minor->kdev.devt = minor->device; - minor->kdev.type = &drm_sysfs_device_minor; - if (minor->type == DRM_MINOR_CONTROL) - minor_str = "controlD%d"; - else if (minor->type == DRM_MINOR_RENDER) - minor_str = "renderD%d"; - else - minor_str = "card%d"; - - dev_set_name(&minor->kdev, minor_str, minor->index); - - err = device_register(&minor->kdev); - if (err) { - DRM_ERROR("device add failed: %d\n", err); - goto err_out; - } - - return 0; - -err_out: - return err; -} - -/** - * drm_sysfs_device_remove - remove DRM device - * @dev: DRM device to remove - * - * This call unregisters and cleans up a class device that was created with a - * call to drm_sysfs_device_add() - */ -void drm_sysfs_device_remove(struct drm_minor *minor) -{ - if (minor->kdev.parent) - device_unregister(&minor->kdev); - minor->kdev.parent = NULL; -} - - -/** - * drm_class_device_register - Register a struct device in the drm class. - * - * @dev: pointer to struct device to register. - * - * @dev should have all relevant members pre-filled with the exception - * of the class member. In particular, the device_type member must - * be set. - */ - -int drm_class_device_register(struct device *dev) -{ - dev->class = drm_class; - return device_register(dev); -} -EXPORT_SYMBOL_GPL(drm_class_device_register); - -void drm_class_device_unregister(struct device *dev) -{ - return device_unregister(dev); -} -EXPORT_SYMBOL_GPL(drm_class_device_unregister); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_trace.h b/ANDROID_3.4.5/drivers/gpu/drm/drm_trace.h deleted file mode 100644 index 03ea964a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_trace.h +++ /dev/null @@ -1,66 +0,0 @@ -#if !defined(_DRM_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) -#define _DRM_TRACE_H_ - -#include -#include -#include - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM drm -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) -#define TRACE_INCLUDE_FILE drm_trace - -TRACE_EVENT(drm_vblank_event, - TP_PROTO(int crtc, unsigned int seq), - TP_ARGS(crtc, seq), - TP_STRUCT__entry( - __field(int, crtc) - __field(unsigned int, seq) - ), - TP_fast_assign( - __entry->crtc = crtc; - __entry->seq = seq; - ), - TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq) -); - -TRACE_EVENT(drm_vblank_event_queued, - TP_PROTO(pid_t pid, int crtc, unsigned int seq), - TP_ARGS(pid, crtc, seq), - TP_STRUCT__entry( - __field(pid_t, pid) - __field(int, crtc) - __field(unsigned int, seq) - ), - TP_fast_assign( - __entry->pid = pid; - __entry->crtc = crtc; - __entry->seq = seq; - ), - TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \ - __entry->seq) -); - -TRACE_EVENT(drm_vblank_event_delivered, - TP_PROTO(pid_t pid, int crtc, unsigned int seq), - TP_ARGS(pid, crtc, seq), - TP_STRUCT__entry( - __field(pid_t, pid) - __field(int, crtc) - __field(unsigned int, seq) - ), - TP_fast_assign( - __entry->pid = pid; - __entry->crtc = crtc; - __entry->seq = seq; - ), - TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \ - __entry->seq) -); - -#endif /* _DRM_TRACE_H_ */ - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#include diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_trace_points.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_trace_points.c deleted file mode 100644 index 0d0eb908..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_trace_points.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "drmP.h" - -#define CREATE_TRACE_POINTS -#include "drm_trace.h" diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_usb.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_usb.c deleted file mode 100644 index 37c9a523..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_usb.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "drmP.h" -#include -#include - -int drm_get_usb_dev(struct usb_interface *interface, - const struct usb_device_id *id, - struct drm_driver *driver) -{ - struct drm_device *dev; - struct usb_device *usbdev; - int ret; - - DRM_DEBUG("\n"); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - usbdev = interface_to_usbdev(interface); - dev->usbdev = usbdev; - dev->dev = &usbdev->dev; - - mutex_lock(&drm_global_mutex); - - ret = drm_fill_in_dev(dev, NULL, driver); - if (ret) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g1; - } - - usb_set_intfdata(interface, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g1; - - ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); - if (ret) - goto err_g2; - - if (dev->driver->load) { - ret = dev->driver->load(dev, 0); - if (ret) - goto err_g3; - } - - /* setup the grouping for the legacy output */ - ret = drm_mode_group_init_legacy_group(dev, - &dev->primary->mode_group); - if (ret) - goto err_g3; - - list_add_tail(&dev->driver_item, &driver->device_list); - - mutex_unlock(&drm_global_mutex); - - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - - return 0; - -err_g3: - drm_put_minor(&dev->primary); -err_g2: - drm_put_minor(&dev->control); -err_g1: - kfree(dev); - mutex_unlock(&drm_global_mutex); - return ret; - -} -EXPORT_SYMBOL(drm_get_usb_dev); - -static int drm_usb_get_irq(struct drm_device *dev) -{ - return 0; -} - -static const char *drm_usb_get_name(struct drm_device *dev) -{ - return "USB"; -} - -static int drm_usb_set_busid(struct drm_device *dev, - struct drm_master *master) -{ - return 0; -} - -static struct drm_bus drm_usb_bus = { - .bus_type = DRIVER_BUS_USB, - .get_irq = drm_usb_get_irq, - .get_name = drm_usb_get_name, - .set_busid = drm_usb_set_busid, -}; - -int drm_usb_init(struct drm_driver *driver, struct usb_driver *udriver) -{ - int res; - DRM_DEBUG("\n"); - - INIT_LIST_HEAD(&driver->device_list); - driver->kdriver.usb = udriver; - driver->bus = &drm_usb_bus; - - res = usb_register(udriver); - return res; -} -EXPORT_SYMBOL(drm_usb_init); - -void drm_usb_exit(struct drm_driver *driver, - struct usb_driver *udriver) -{ - usb_deregister(udriver); -} -EXPORT_SYMBOL(drm_usb_exit); - -MODULE_AUTHOR("David Airlie"); -MODULE_DESCRIPTION("USB DRM support"); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/drm_vm.c b/ANDROID_3.4.5/drivers/gpu/drm/drm_vm.c deleted file mode 100644 index 14956181..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/drm_vm.c +++ /dev/null @@ -1,692 +0,0 @@ -/** - * \file drm_vm.c - * Memory mapping for DRM - * - * \author Rickard E. (Rik) Faith - * \author Gareth Hughes - */ - -/* - * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include -#if defined(__ia64__) -#include -#include -#endif - -static void drm_vm_open(struct vm_area_struct *vma); -static void drm_vm_close(struct vm_area_struct *vma); - -static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) -{ - pgprot_t tmp = vm_get_page_prot(vma->vm_flags); - -#if defined(__i386__) || defined(__x86_64__) - if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { - pgprot_val(tmp) |= _PAGE_PCD; - pgprot_val(tmp) &= ~_PAGE_PWT; - } -#elif defined(__powerpc__) - pgprot_val(tmp) |= _PAGE_NO_CACHE; - if (map_type == _DRM_REGISTERS) - pgprot_val(tmp) |= _PAGE_GUARDED; -#elif defined(__ia64__) - if (efi_range_is_wc(vma->vm_start, vma->vm_end - - vma->vm_start)) - tmp = pgprot_writecombine(tmp); - else - tmp = pgprot_noncached(tmp); -#elif defined(__sparc__) || defined(__arm__) - tmp = pgprot_noncached(tmp); -#endif - return tmp; -} - -static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma) -{ - pgprot_t tmp = vm_get_page_prot(vma->vm_flags); - -#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE) - tmp |= _PAGE_NO_CACHE; -#endif - return tmp; -} - -/** - * \c fault method for AGP virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Find the right map and if it's AGP memory find the real physical page to - * map, get the page, increment the use count and return it. - */ -#if __OS_HAS_AGP -static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_local_map *map = NULL; - struct drm_map_list *r_list; - struct drm_hash_item *hash; - - /* - * Find the right map - */ - if (!drm_core_has_AGP(dev)) - goto vm_fault_error; - - if (!dev->agp || !dev->agp->cant_use_aperture) - goto vm_fault_error; - - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) - goto vm_fault_error; - - r_list = drm_hash_entry(hash, struct drm_map_list, hash); - map = r_list->map; - - if (map && map->type == _DRM_AGP) { - /* - * Using vm_pgoff as a selector forces us to use this unusual - * addressing scheme. - */ - resource_size_t offset = (unsigned long)vmf->virtual_address - - vma->vm_start; - resource_size_t baddr = map->offset + offset; - struct drm_agp_mem *agpmem; - struct page *page; - -#ifdef __alpha__ - /* - * Adjust to a bus-relative address - */ - baddr -= dev->hose->mem_space->start; -#endif - - /* - * It's AGP memory - find the real physical page to map - */ - list_for_each_entry(agpmem, &dev->agp->memory, head) { - if (agpmem->bound <= baddr && - agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) - break; - } - - if (&agpmem->head == &dev->agp->memory) - goto vm_fault_error; - - /* - * Get the page, inc the use count, and return it - */ - offset = (baddr - agpmem->bound) >> PAGE_SHIFT; - page = agpmem->memory->pages[offset]; - get_page(page); - vmf->page = page; - - DRM_DEBUG - ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", - (unsigned long long)baddr, - agpmem->memory->pages[offset], - (unsigned long long)offset, - page_count(page)); - return 0; - } -vm_fault_error: - return VM_FAULT_SIGBUS; /* Disallow mremap */ -} -#else /* __OS_HAS_AGP */ -static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return VM_FAULT_SIGBUS; -} -#endif /* __OS_HAS_AGP */ - -/** - * \c nopage method for shared virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Get the mapping, find the real physical page to map, get the page, and - * return it. - */ -static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_local_map *map = vma->vm_private_data; - unsigned long offset; - unsigned long i; - struct page *page; - - if (!map) - return VM_FAULT_SIGBUS; /* Nothing allocated */ - - offset = (unsigned long)vmf->virtual_address - vma->vm_start; - i = (unsigned long)map->handle + offset; - page = vmalloc_to_page((void *)i); - if (!page) - return VM_FAULT_SIGBUS; - get_page(page); - vmf->page = page; - - DRM_DEBUG("shm_fault 0x%lx\n", offset); - return 0; -} - -/** - * \c close method for shared virtual memory. - * - * \param vma virtual memory area. - * - * Deletes map information if we are the last - * person to close a mapping and it's not in the global maplist. - */ -static void drm_vm_shm_close(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_vma_entry *pt, *temp; - struct drm_local_map *map; - struct drm_map_list *r_list; - int found_maps = 0; - - DRM_DEBUG("0x%08lx,0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - atomic_dec(&dev->vma_count); - - map = vma->vm_private_data; - - mutex_lock(&dev->struct_mutex); - list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { - if (pt->vma->vm_private_data == map) - found_maps++; - if (pt->vma == vma) { - list_del(&pt->head); - kfree(pt); - } - } - - /* We were the only map that was found */ - if (found_maps == 1 && map->flags & _DRM_REMOVABLE) { - /* Check to see if we are in the maplist, if we are not, then - * we delete this mappings information. - */ - found_maps = 0; - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map == map) - found_maps++; - } - - if (!found_maps) { - drm_dma_handle_t dmah; - - switch (map->type) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: - if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { - int retcode; - retcode = mtrr_del(map->mtrr, - map->offset, - map->size); - DRM_DEBUG("mtrr_del = %d\n", retcode); - } - iounmap(map->handle); - break; - case _DRM_SHM: - vfree(map->handle); - break; - case _DRM_AGP: - case _DRM_SCATTER_GATHER: - break; - case _DRM_CONSISTENT: - dmah.vaddr = map->handle; - dmah.busaddr = map->offset; - dmah.size = map->size; - __drm_pci_free(dev, &dmah); - break; - case _DRM_GEM: - DRM_ERROR("tried to rmmap GEM object\n"); - break; - } - kfree(map); - } - } - mutex_unlock(&dev->struct_mutex); -} - -/** - * \c fault method for DMA virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Determine the page number from the page offset and get it from drm_device_dma::pagelist. - */ -static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_device_dma *dma = dev->dma; - unsigned long offset; - unsigned long page_nr; - struct page *page; - - if (!dma) - return VM_FAULT_SIGBUS; /* Error */ - if (!dma->pagelist) - return VM_FAULT_SIGBUS; /* Nothing allocated */ - - offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ - page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */ - page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK)))); - - get_page(page); - vmf->page = page; - - DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr); - return 0; -} - -/** - * \c fault method for scatter-gather virtual memory. - * - * \param vma virtual memory area. - * \param address access address. - * \return pointer to the page structure. - * - * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist. - */ -static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_local_map *map = vma->vm_private_data; - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_sg_mem *entry = dev->sg; - unsigned long offset; - unsigned long map_offset; - unsigned long page_offset; - struct page *page; - - if (!entry) - return VM_FAULT_SIGBUS; /* Error */ - if (!entry->pagelist) - return VM_FAULT_SIGBUS; /* Nothing allocated */ - - offset = (unsigned long)vmf->virtual_address - vma->vm_start; - map_offset = map->offset - (unsigned long)dev->sg->virtual; - page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); - page = entry->pagelist[page_offset]; - get_page(page); - vmf->page = page; - - return 0; -} - -static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_fault(vma, vmf); -} - -static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_shm_fault(vma, vmf); -} - -static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_dma_fault(vma, vmf); -} - -static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - return drm_do_vm_sg_fault(vma, vmf); -} - -/** AGP virtual memory operations */ -static const struct vm_operations_struct drm_vm_ops = { - .fault = drm_vm_fault, - .open = drm_vm_open, - .close = drm_vm_close, -}; - -/** Shared virtual memory operations */ -static const struct vm_operations_struct drm_vm_shm_ops = { - .fault = drm_vm_shm_fault, - .open = drm_vm_open, - .close = drm_vm_shm_close, -}; - -/** DMA virtual memory operations */ -static const struct vm_operations_struct drm_vm_dma_ops = { - .fault = drm_vm_dma_fault, - .open = drm_vm_open, - .close = drm_vm_close, -}; - -/** Scatter-gather virtual memory operations */ -static const struct vm_operations_struct drm_vm_sg_ops = { - .fault = drm_vm_sg_fault, - .open = drm_vm_open, - .close = drm_vm_close, -}; - -/** - * \c open method for shared virtual memory. - * - * \param vma virtual memory area. - * - * Create a new drm_vma_entry structure as the \p vma private data entry and - * add it to drm_device::vmalist. - */ -void drm_vm_open_locked(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_vma_entry *vma_entry; - - DRM_DEBUG("0x%08lx,0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - atomic_inc(&dev->vma_count); - - vma_entry = kmalloc(sizeof(*vma_entry), GFP_KERNEL); - if (vma_entry) { - vma_entry->vma = vma; - vma_entry->pid = current->pid; - list_add(&vma_entry->head, &dev->vmalist); - } -} - -static void drm_vm_open(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - - mutex_lock(&dev->struct_mutex); - drm_vm_open_locked(vma); - mutex_unlock(&dev->struct_mutex); -} - -void drm_vm_close_locked(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_vma_entry *pt, *temp; - - DRM_DEBUG("0x%08lx,0x%08lx\n", - vma->vm_start, vma->vm_end - vma->vm_start); - atomic_dec(&dev->vma_count); - - list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { - if (pt->vma == vma) { - list_del(&pt->head); - kfree(pt); - break; - } - } -} - -/** - * \c close method for all virtual memory types. - * - * \param vma virtual memory area. - * - * Search the \p vma private data entry in drm_device::vmalist, unlink it, and - * free it. - */ -static void drm_vm_close(struct vm_area_struct *vma) -{ - struct drm_file *priv = vma->vm_file->private_data; - struct drm_device *dev = priv->minor->dev; - - mutex_lock(&dev->struct_mutex); - drm_vm_close_locked(vma); - mutex_unlock(&dev->struct_mutex); -} - -/** - * mmap DMA memory. - * - * \param file_priv DRM file private. - * \param vma virtual memory area. - * \return zero on success or a negative number on failure. - * - * Sets the virtual memory area operations structure to vm_dma_ops, the file - * pointer, and calls vm_open(). - */ -static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev; - struct drm_device_dma *dma; - unsigned long length = vma->vm_end - vma->vm_start; - - dev = priv->minor->dev; - dma = dev->dma; - DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff); - - /* Length must match exact page count */ - if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { - return -EINVAL; - } - - if (!capable(CAP_SYS_ADMIN) && - (dma->flags & _DRM_DMA_USE_PCI_RO)) { - vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); -#if defined(__i386__) || defined(__x86_64__) - pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; -#else - /* Ye gads this is ugly. With more thought - we could move this up higher and use - `protection_map' instead. */ - vma->vm_page_prot = - __pgprot(pte_val - (pte_wrprotect - (__pte(pgprot_val(vma->vm_page_prot))))); -#endif - } - - vma->vm_ops = &drm_vm_dma_ops; - - vma->vm_flags |= VM_RESERVED; /* Don't swap */ - vma->vm_flags |= VM_DONTEXPAND; - - drm_vm_open_locked(vma); - return 0; -} - -static resource_size_t drm_core_get_reg_ofs(struct drm_device *dev) -{ -#ifdef __alpha__ - return dev->hose->dense_mem_base; -#else - return 0; -#endif -} - -/** - * mmap DMA memory. - * - * \param file_priv DRM file private. - * \param vma virtual memory area. - * \return zero on success or a negative number on failure. - * - * If the virtual memory area has no offset associated with it then it's a DMA - * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist, - * checks that the restricted flag is not set, sets the virtual memory operations - * according to the mapping type and remaps the pages. Finally sets the file - * pointer and calls vm_open(). - */ -int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - struct drm_local_map *map = NULL; - resource_size_t offset = 0; - struct drm_hash_item *hash; - - DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff); - - if (!priv->authenticated) - return -EACCES; - - /* We check for "dma". On Apple's UniNorth, it's valid to have - * the AGP mapped at physical address 0 - * --BenH. - */ - if (!vma->vm_pgoff -#if __OS_HAS_AGP - && (!dev->agp - || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) -#endif - ) - return drm_mmap_dma(filp, vma); - - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) { - DRM_ERROR("Could not find map\n"); - return -EINVAL; - } - - map = drm_hash_entry(hash, struct drm_map_list, hash)->map; - if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) - return -EPERM; - - /* Check for valid size. */ - if (map->size < vma->vm_end - vma->vm_start) - return -EINVAL; - - if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { - vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); -#if defined(__i386__) || defined(__x86_64__) - pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; -#else - /* Ye gads this is ugly. With more thought - we could move this up higher and use - `protection_map' instead. */ - vma->vm_page_prot = - __pgprot(pte_val - (pte_wrprotect - (__pte(pgprot_val(vma->vm_page_prot))))); -#endif - } - - switch (map->type) { -#if !defined(__arm__) - case _DRM_AGP: - if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) { - /* - * On some platforms we can't talk to bus dma address from the CPU, so for - * memory of type DRM_AGP, we'll deal with sorting out the real physical - * pages and mappings in fault() - */ -#if defined(__powerpc__) - pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; -#endif - vma->vm_ops = &drm_vm_ops; - break; - } - /* fall through to _DRM_FRAME_BUFFER... */ -#endif - case _DRM_FRAME_BUFFER: - case _DRM_REGISTERS: - offset = drm_core_get_reg_ofs(dev); - vma->vm_flags |= VM_IO; /* not in core dump */ - vma->vm_page_prot = drm_io_prot(map->type, vma); -#if !defined(__arm__) - if (io_remap_pfn_range(vma, vma->vm_start, - (map->offset + offset) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; -#else - if (remap_pfn_range(vma, vma->vm_start, - (map->offset + offset) >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; -#endif - - DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," - " offset = 0x%llx\n", - map->type, - vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset)); - - vma->vm_ops = &drm_vm_ops; - break; - case _DRM_CONSISTENT: - /* Consistent memory is really like shared memory. But - * it's allocated in a different way, so avoid fault */ - if (remap_pfn_range(vma, vma->vm_start, - page_to_pfn(virt_to_page(map->handle)), - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - vma->vm_page_prot = drm_dma_prot(map->type, vma); - /* fall through to _DRM_SHM */ - case _DRM_SHM: - vma->vm_ops = &drm_vm_shm_ops; - vma->vm_private_data = (void *)map; - /* Don't let this area swap. Change when - DRM_KERNEL advisory is supported. */ - vma->vm_flags |= VM_RESERVED; - break; - case _DRM_SCATTER_GATHER: - vma->vm_ops = &drm_vm_sg_ops; - vma->vm_private_data = (void *)map; - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = drm_dma_prot(map->type, vma); - break; - default: - return -EINVAL; /* This should never happen. */ - } - vma->vm_flags |= VM_RESERVED; /* Don't swap */ - vma->vm_flags |= VM_DONTEXPAND; - - drm_vm_open_locked(vma); - return 0; -} - -int drm_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev = priv->minor->dev; - int ret; - - if (drm_device_is_unplugged(dev)) - return -ENODEV; - - mutex_lock(&dev->struct_mutex); - ret = drm_mmap_locked(filp, vma); - mutex_unlock(&dev->struct_mutex); - - return ret; -} -EXPORT_SYMBOL(drm_mmap); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/Kconfig b/ANDROID_3.4.5/drivers/gpu/drm/exynos/Kconfig deleted file mode 100644 index 3343ac43..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -config DRM_EXYNOS - tristate "DRM Support for Samsung SoC EXYNOS Series" - depends on DRM && PLAT_SAMSUNG - select DRM_KMS_HELPER - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE - help - Choose this option if you have a Samsung SoC EXYNOS chipset. - If M is selected the module will be called exynosdrm. - -config DRM_EXYNOS_FIMD - bool "Exynos DRM FIMD" - depends on DRM_EXYNOS && !FB_S3C - help - Choose this option if you want to use Exynos FIMD for DRM. - -config DRM_EXYNOS_HDMI - bool "Exynos DRM HDMI" - depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV - help - Choose this option if you want to use Exynos HDMI for DRM. - -config DRM_EXYNOS_VIDI - bool "Exynos DRM Virtual Display" - depends on DRM_EXYNOS - help - Choose this option if you want to use Exynos VIDI for DRM. diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/exynos/Makefile deleted file mode 100644 index 9e0bff8b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos -exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \ - exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \ - exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \ - exynos_drm_plane.o - -exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o -exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o \ - exynos_ddc.o exynos_hdmiphy.o \ - exynos_drm_hdmi.o -exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o - -obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_ddc.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_ddc.c deleted file mode 100644 index 7e1051d0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_ddc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim - * Inki Dae - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include "drmP.h" - -#include -#include -#include - - -#include "exynos_drm_drv.h" -#include "exynos_hdmi.h" - -static int s5p_ddc_probe(struct i2c_client *client, - const struct i2c_device_id *dev_id) -{ - hdmi_attach_ddc_client(client); - - dev_info(&client->adapter->dev, "attached s5p_ddc " - "into i2c adapter successfully\n"); - - return 0; -} - -static int s5p_ddc_remove(struct i2c_client *client) -{ - dev_info(&client->adapter->dev, "detached s5p_ddc " - "from i2c adapter successfully\n"); - - return 0; -} - -static struct i2c_device_id ddc_idtable[] = { - {"s5p_ddc", 0}, - { }, -}; - -struct i2c_driver ddc_driver = { - .driver = { - .name = "s5p_ddc", - .owner = THIS_MODULE, - }, - .id_table = ddc_idtable, - .probe = s5p_ddc_probe, - .remove = __devexit_p(s5p_ddc_remove), - .command = NULL, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.c deleted file mode 100644 index de8d2090..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ /dev/null @@ -1,213 +0,0 @@ -/* exynos_drm_buf.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "exynos_drm.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_buf.h" - -static int lowlevel_buffer_allocate(struct drm_device *dev, - unsigned int flags, struct exynos_drm_gem_buf *buf) -{ - dma_addr_t start_addr; - unsigned int npages, page_size, i = 0; - struct scatterlist *sgl; - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (IS_NONCONTIG_BUFFER(flags)) { - DRM_DEBUG_KMS("not support allocation type.\n"); - return -EINVAL; - } - - if (buf->dma_addr) { - DRM_DEBUG_KMS("already allocated.\n"); - return 0; - } - - if (buf->size >= SZ_1M) { - npages = buf->size >> SECTION_SHIFT; - page_size = SECTION_SIZE; - } else if (buf->size >= SZ_64K) { - npages = buf->size >> 16; - page_size = SZ_64K; - } else { - npages = buf->size >> PAGE_SHIFT; - page_size = PAGE_SIZE; - } - - buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!buf->sgt) { - DRM_ERROR("failed to allocate sg table.\n"); - return -ENOMEM; - } - - ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL); - if (ret < 0) { - DRM_ERROR("failed to initialize sg table.\n"); - kfree(buf->sgt); - buf->sgt = NULL; - return -ENOMEM; - } - - buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL); - if (!buf->kvaddr) { - DRM_ERROR("failed to allocate buffer.\n"); - ret = -ENOMEM; - goto err1; - } - - buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); - if (!buf->pages) { - DRM_ERROR("failed to allocate pages.\n"); - ret = -ENOMEM; - goto err2; - } - - sgl = buf->sgt->sgl; - start_addr = buf->dma_addr; - - while (i < npages) { - buf->pages[i] = phys_to_page(start_addr); - sg_set_page(sgl, buf->pages[i], page_size, 0); - sg_dma_address(sgl) = start_addr; - start_addr += page_size; - sgl = sg_next(sgl); - i++; - } - - DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", - (unsigned long)buf->kvaddr, - (unsigned long)buf->dma_addr, - buf->size); - - return ret; -err2: - dma_free_writecombine(dev->dev, buf->size, buf->kvaddr, - (dma_addr_t)buf->dma_addr); - buf->dma_addr = (dma_addr_t)NULL; -err1: - sg_free_table(buf->sgt); - kfree(buf->sgt); - buf->sgt = NULL; - - return ret; -} - -static void lowlevel_buffer_deallocate(struct drm_device *dev, - unsigned int flags, struct exynos_drm_gem_buf *buf) -{ - DRM_DEBUG_KMS("%s.\n", __FILE__); - - /* - * release only physically continuous memory and - * non-continuous memory would be released by exynos - * gem framework. - */ - if (IS_NONCONTIG_BUFFER(flags)) { - DRM_DEBUG_KMS("not support allocation type.\n"); - return; - } - - if (!buf->dma_addr) { - DRM_DEBUG_KMS("dma_addr is invalid.\n"); - return; - } - - DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", - (unsigned long)buf->kvaddr, - (unsigned long)buf->dma_addr, - buf->size); - - sg_free_table(buf->sgt); - - kfree(buf->sgt); - buf->sgt = NULL; - - kfree(buf->pages); - buf->pages = NULL; - - dma_free_writecombine(dev->dev, buf->size, buf->kvaddr, - (dma_addr_t)buf->dma_addr); - buf->dma_addr = (dma_addr_t)NULL; -} - -struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, - unsigned int size) -{ - struct exynos_drm_gem_buf *buffer; - - DRM_DEBUG_KMS("%s.\n", __FILE__); - DRM_DEBUG_KMS("desired size = 0x%x\n", size); - - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); - if (!buffer) { - DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); - return NULL; - } - - buffer->size = size; - return buffer; -} - -void exynos_drm_fini_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buffer) -{ - DRM_DEBUG_KMS("%s.\n", __FILE__); - - if (!buffer) { - DRM_DEBUG_KMS("buffer is null.\n"); - return; - } - - kfree(buffer); - buffer = NULL; -} - -int exynos_drm_alloc_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buf, unsigned int flags) -{ - - /* - * allocate memory region and set the memory information - * to vaddr and dma_addr of a buffer object. - */ - if (lowlevel_buffer_allocate(dev, flags, buf) < 0) - return -ENOMEM; - - return 0; -} - -void exynos_drm_free_buf(struct drm_device *dev, - unsigned int flags, struct exynos_drm_gem_buf *buffer) -{ - - lowlevel_buffer_deallocate(dev, flags, buffer); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.h deleted file mode 100644 index 3388e4eb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_buf.h +++ /dev/null @@ -1,47 +0,0 @@ -/* exynos_drm_buf.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_BUF_H_ -#define _EXYNOS_DRM_BUF_H_ - -/* create and initialize buffer object. */ -struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, - unsigned int size); - -/* destroy buffer object. */ -void exynos_drm_fini_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buffer); - -/* allocate physical memory region and setup sgt and pages. */ -int exynos_drm_alloc_buf(struct drm_device *dev, - struct exynos_drm_gem_buf *buf, - unsigned int flags); - -/* release physical memory region, sgt and pages. */ -void exynos_drm_free_buf(struct drm_device *dev, - unsigned int flags, - struct exynos_drm_gem_buf *buffer); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.c deleted file mode 100644 index bf791fa0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include -#include "exynos_drm_drv.h" -#include "exynos_drm_encoder.h" - -#define MAX_EDID 256 -#define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ - drm_connector) - -struct exynos_drm_connector { - struct drm_connector drm_connector; - uint32_t encoder_id; - struct exynos_drm_manager *manager; -}; - -/* convert exynos_video_timings to drm_display_mode */ -static inline void -convert_to_display_mode(struct drm_display_mode *mode, - struct exynos_drm_panel_info *panel) -{ - struct fb_videomode *timing = &panel->timing; - DRM_DEBUG_KMS("%s\n", __FILE__); - - mode->clock = timing->pixclock / 1000; - mode->vrefresh = timing->refresh; - - mode->hdisplay = timing->xres; - mode->hsync_start = mode->hdisplay + timing->right_margin; - mode->hsync_end = mode->hsync_start + timing->hsync_len; - mode->htotal = mode->hsync_end + timing->left_margin; - - mode->vdisplay = timing->yres; - mode->vsync_start = mode->vdisplay + timing->lower_margin; - mode->vsync_end = mode->vsync_start + timing->vsync_len; - mode->vtotal = mode->vsync_end + timing->upper_margin; - mode->width_mm = panel->width_mm; - mode->height_mm = panel->height_mm; - - if (timing->vmode & FB_VMODE_INTERLACED) - mode->flags |= DRM_MODE_FLAG_INTERLACE; - - if (timing->vmode & FB_VMODE_DOUBLE) - mode->flags |= DRM_MODE_FLAG_DBLSCAN; -} - -/* convert drm_display_mode to exynos_video_timings */ -static inline void -convert_to_video_timing(struct fb_videomode *timing, - struct drm_display_mode *mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - memset(timing, 0, sizeof(*timing)); - - timing->pixclock = mode->clock * 1000; - timing->refresh = drm_mode_vrefresh(mode); - - timing->xres = mode->hdisplay; - timing->right_margin = mode->hsync_start - mode->hdisplay; - timing->hsync_len = mode->hsync_end - mode->hsync_start; - timing->left_margin = mode->htotal - mode->hsync_end; - - timing->yres = mode->vdisplay; - timing->lower_margin = mode->vsync_start - mode->vdisplay; - timing->vsync_len = mode->vsync_end - mode->vsync_start; - timing->upper_margin = mode->vtotal - mode->vsync_end; - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - timing->vmode = FB_VMODE_INTERLACED; - else - timing->vmode = FB_VMODE_NONINTERLACED; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - timing->vmode |= FB_VMODE_DOUBLE; -} - -static int exynos_drm_connector_get_modes(struct drm_connector *connector) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_display_ops *display_ops = manager->display_ops; - unsigned int count; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!display_ops) { - DRM_DEBUG_KMS("display_ops is null.\n"); - return 0; - } - - /* - * if get_edid() exists then get_edid() callback of hdmi side - * is called to get edid data through i2c interface else - * get timing from the FIMD driver(display controller). - * - * P.S. in case of lcd panel, count is always 1 if success - * because lcd panel has only one mode. - */ - if (display_ops->get_edid) { - int ret; - void *edid; - - edid = kzalloc(MAX_EDID, GFP_KERNEL); - if (!edid) { - DRM_ERROR("failed to allocate edid\n"); - return 0; - } - - ret = display_ops->get_edid(manager->dev, connector, - edid, MAX_EDID); - if (ret < 0) { - DRM_ERROR("failed to get edid data.\n"); - kfree(edid); - edid = NULL; - return 0; - } - - drm_mode_connector_update_edid_property(connector, edid); - count = drm_add_edid_modes(connector, edid); - - kfree(connector->display_info.raw_edid); - connector->display_info.raw_edid = edid; - } else { - struct drm_display_mode *mode = drm_mode_create(connector->dev); - struct exynos_drm_panel_info *panel; - - if (display_ops->get_panel) - panel = display_ops->get_panel(manager->dev); - else { - drm_mode_destroy(connector->dev, mode); - return 0; - } - - convert_to_display_mode(mode, panel); - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); - - count = 1; - } - - return count; -} - -static int exynos_drm_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_display_ops *display_ops = manager->display_ops; - struct fb_videomode timing; - int ret = MODE_BAD; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - convert_to_video_timing(&timing, mode); - - if (display_ops && display_ops->check_timing) - if (!display_ops->check_timing(manager->dev, (void *)&timing)) - ret = MODE_OK; - - return ret; -} - -struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct drm_mode_object *obj; - struct drm_encoder *encoder; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - obj = drm_mode_object_find(dev, exynos_connector->encoder_id, - DRM_MODE_OBJECT_ENCODER); - if (!obj) { - DRM_DEBUG_KMS("Unknown ENCODER ID %d\n", - exynos_connector->encoder_id); - return NULL; - } - - encoder = obj_to_encoder(obj); - - return encoder; -} - -static struct drm_connector_helper_funcs exynos_connector_helper_funcs = { - .get_modes = exynos_drm_connector_get_modes, - .mode_valid = exynos_drm_connector_mode_valid, - .best_encoder = exynos_drm_best_encoder, -}; - -static int exynos_drm_connector_fill_modes(struct drm_connector *connector, - unsigned int max_width, unsigned int max_height) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_manager_ops *ops = manager->ops; - unsigned int width, height; - - width = max_width; - height = max_height; - - /* - * if specific driver want to find desired_mode using maxmum - * resolution then get max width and height from that driver. - */ - if (ops && ops->get_max_resol) - ops->get_max_resol(manager->dev, &width, &height); - - return drm_helper_probe_single_connector_modes(connector, width, - height); -} - -/* get detection status of display device. */ -static enum drm_connector_status -exynos_drm_connector_detect(struct drm_connector *connector, bool force) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - struct exynos_drm_manager *manager = exynos_connector->manager; - struct exynos_drm_display_ops *display_ops = - manager->display_ops; - enum drm_connector_status status = connector_status_disconnected; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (display_ops && display_ops->is_connected) { - if (display_ops->is_connected(manager->dev)) - status = connector_status_connected; - else - status = connector_status_disconnected; - } - - return status; -} - -static void exynos_drm_connector_destroy(struct drm_connector *connector) -{ - struct exynos_drm_connector *exynos_connector = - to_exynos_connector(connector); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(exynos_connector); -} - -static struct drm_connector_funcs exynos_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .fill_modes = exynos_drm_connector_fill_modes, - .detect = exynos_drm_connector_detect, - .destroy = exynos_drm_connector_destroy, -}; - -struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, - struct drm_encoder *encoder) -{ - struct exynos_drm_connector *exynos_connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct drm_connector *connector; - int type; - int err; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL); - if (!exynos_connector) { - DRM_ERROR("failed to allocate connector\n"); - return NULL; - } - - connector = &exynos_connector->drm_connector; - - switch (manager->display_ops->type) { - case EXYNOS_DISPLAY_TYPE_HDMI: - type = DRM_MODE_CONNECTOR_HDMIA; - connector->interlace_allowed = true; - connector->polled = DRM_CONNECTOR_POLL_HPD; - break; - case EXYNOS_DISPLAY_TYPE_VIDI: - type = DRM_MODE_CONNECTOR_VIRTUAL; - connector->polled = DRM_CONNECTOR_POLL_HPD; - break; - default: - type = DRM_MODE_CONNECTOR_Unknown; - break; - } - - drm_connector_init(dev, connector, &exynos_connector_funcs, type); - drm_connector_helper_add(connector, &exynos_connector_helper_funcs); - - err = drm_sysfs_connector_add(connector); - if (err) - goto err_connector; - - exynos_connector->encoder_id = encoder->base.id; - exynos_connector->manager = manager; - connector->encoder = encoder; - - err = drm_mode_connector_attach_encoder(connector, encoder); - if (err) { - DRM_ERROR("failed to attach a connector to a encoder\n"); - goto err_sysfs; - } - - DRM_DEBUG_KMS("connector has been created\n"); - - return connector; - -err_sysfs: - drm_sysfs_connector_remove(connector); -err_connector: - drm_connector_cleanup(connector); - kfree(exynos_connector); - return NULL; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.h deleted file mode 100644 index 1c7b2b5b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_connector.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_CONNECTOR_H_ -#define _EXYNOS_DRM_CONNECTOR_H_ - -struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, - struct drm_encoder *encoder); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_core.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_core.c deleted file mode 100644 index eaf630dc..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_core.c +++ /dev/null @@ -1,217 +0,0 @@ -/* exynos_drm_core.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_encoder.h" -#include "exynos_drm_connector.h" -#include "exynos_drm_fbdev.h" - -static LIST_HEAD(exynos_drm_subdrv_list); -static struct drm_device *drm_dev; - -static int exynos_drm_subdrv_probe(struct drm_device *dev, - struct exynos_drm_subdrv *subdrv) -{ - struct drm_encoder *encoder; - struct drm_connector *connector; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (subdrv->probe) { - int ret; - - /* - * this probe callback would be called by sub driver - * after setting of all resources to this sub driver, - * such as clock, irq and register map are done or by load() - * of exynos drm driver. - * - * P.S. note that this driver is considered for modularization. - */ - ret = subdrv->probe(dev, subdrv->dev); - if (ret) - return ret; - } - - if (!subdrv->manager) - return 0; - - subdrv->manager->dev = subdrv->dev; - - /* create and initialize a encoder for this sub driver. */ - encoder = exynos_drm_encoder_create(dev, subdrv->manager, - (1 << MAX_CRTC) - 1); - if (!encoder) { - DRM_ERROR("failed to create encoder\n"); - return -EFAULT; - } - - /* - * create and initialize a connector for this sub driver and - * attach the encoder created above to the connector. - */ - connector = exynos_drm_connector_create(dev, encoder); - if (!connector) { - DRM_ERROR("failed to create connector\n"); - encoder->funcs->destroy(encoder); - return -EFAULT; - } - - subdrv->encoder = encoder; - subdrv->connector = connector; - - return 0; -} - -static void exynos_drm_subdrv_remove(struct drm_device *dev, - struct exynos_drm_subdrv *subdrv) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (subdrv->remove) - subdrv->remove(dev); - - if (subdrv->encoder) { - struct drm_encoder *encoder = subdrv->encoder; - encoder->funcs->destroy(encoder); - subdrv->encoder = NULL; - } - - if (subdrv->connector) { - struct drm_connector *connector = subdrv->connector; - connector->funcs->destroy(connector); - subdrv->connector = NULL; - } -} - -int exynos_drm_device_register(struct drm_device *dev) -{ - struct exynos_drm_subdrv *subdrv, *n; - int err; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!dev) - return -EINVAL; - - drm_dev = dev; - - list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { - subdrv->drm_dev = dev; - err = exynos_drm_subdrv_probe(dev, subdrv); - if (err) { - DRM_DEBUG("exynos drm subdrv probe failed.\n"); - list_del(&subdrv->list); - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_device_register); - -int exynos_drm_device_unregister(struct drm_device *dev) -{ - struct exynos_drm_subdrv *subdrv; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!dev) { - WARN(1, "Unexpected drm device unregister!\n"); - return -EINVAL; - } - - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) - exynos_drm_subdrv_remove(dev, subdrv); - - drm_dev = NULL; - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_device_unregister); - -int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!subdrv) - return -EINVAL; - - list_add_tail(&subdrv->list, &exynos_drm_subdrv_list); - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register); - -int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!subdrv) - return -EINVAL; - - list_del(&subdrv->list); - - return 0; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister); - -int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) -{ - struct exynos_drm_subdrv *subdrv; - int ret; - - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { - if (subdrv->open) { - ret = subdrv->open(dev, subdrv->dev, file); - if (ret) - goto err; - } - } - - return 0; - -err: - list_for_each_entry_reverse(subdrv, &subdrv->list, list) { - if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); - } - return ret; -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_open); - -void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) -{ - struct exynos_drm_subdrv *subdrv; - - list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { - if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); - } -} -EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.c deleted file mode 100644 index 3486ffed..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ /dev/null @@ -1,432 +0,0 @@ -/* exynos_drm_crtc.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_crtc.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_encoder.h" -#include "exynos_drm_gem.h" - -#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\ - drm_crtc) - -/* - * Exynos specific crtc structure. - * - * @drm_crtc: crtc object. - * @overlay: contain information common to display controller and hdmi and - * contents of this overlay object would be copied to sub driver size. - * @pipe: a crtc index created at load() with a new crtc object creation - * and the crtc object would be set to private->crtc array - * to get a crtc object corresponding to this pipe from private->crtc - * array when irq interrupt occured. the reason of using this pipe is that - * drm framework doesn't support multiple irq yet. - * we can refer to the crtc to current hardware interrupt occured through - * this pipe value. - * @dpms: store the crtc dpms value - */ -struct exynos_drm_crtc { - struct drm_crtc drm_crtc; - struct exynos_drm_overlay overlay; - unsigned int pipe; - unsigned int dpms; -}; - -static void exynos_drm_crtc_apply(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct exynos_drm_overlay *overlay = &exynos_crtc->overlay; - - exynos_drm_fn_encoder(crtc, overlay, - exynos_drm_encoder_crtc_mode_set); - exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, - exynos_drm_encoder_crtc_commit); -} - -int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, - struct drm_framebuffer *fb, - struct drm_display_mode *mode, - struct exynos_drm_crtc_pos *pos) -{ - struct exynos_drm_gem_buf *buffer; - unsigned int actual_w; - unsigned int actual_h; - int nr = exynos_drm_format_num_buffers(fb->pixel_format); - int i; - - for (i = 0; i < nr; i++) { - buffer = exynos_drm_fb_buffer(fb, i); - if (!buffer) { - DRM_LOG_KMS("buffer is null\n"); - return -EFAULT; - } - - overlay->dma_addr[i] = buffer->dma_addr; - overlay->vaddr[i] = buffer->kvaddr; - - DRM_DEBUG_KMS("buffer: %d, vaddr = 0x%lx, dma_addr = 0x%lx\n", - i, (unsigned long)overlay->vaddr[i], - (unsigned long)overlay->dma_addr[i]); - } - - actual_w = min((mode->hdisplay - pos->crtc_x), pos->crtc_w); - actual_h = min((mode->vdisplay - pos->crtc_y), pos->crtc_h); - - /* set drm framebuffer data. */ - overlay->fb_x = pos->fb_x; - overlay->fb_y = pos->fb_y; - overlay->fb_width = fb->width; - overlay->fb_height = fb->height; - overlay->bpp = fb->bits_per_pixel; - overlay->pitch = fb->pitches[0]; - overlay->pixel_format = fb->pixel_format; - - /* set overlay range to be displayed. */ - overlay->crtc_x = pos->crtc_x; - overlay->crtc_y = pos->crtc_y; - overlay->crtc_width = actual_w; - overlay->crtc_height = actual_h; - - /* set drm mode data. */ - overlay->mode_width = mode->hdisplay; - overlay->mode_height = mode->vdisplay; - overlay->refresh = mode->vrefresh; - overlay->scan_flag = mode->flags; - - DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)", - overlay->crtc_x, overlay->crtc_y, - overlay->crtc_width, overlay->crtc_height); - - return 0; -} - -static int exynos_drm_crtc_update(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc; - struct exynos_drm_overlay *overlay; - struct exynos_drm_crtc_pos pos; - struct drm_display_mode *mode = &crtc->mode; - struct drm_framebuffer *fb = crtc->fb; - - if (!mode || !fb) - return -EINVAL; - - exynos_crtc = to_exynos_crtc(crtc); - overlay = &exynos_crtc->overlay; - - memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos)); - - /* it means the offset of framebuffer to be displayed. */ - pos.fb_x = crtc->x; - pos.fb_y = crtc->y; - - /* OSD position to be displayed. */ - pos.crtc_x = 0; - pos.crtc_y = 0; - pos.crtc_w = fb->width - crtc->x; - pos.crtc_h = fb->height - crtc->y; - - return exynos_drm_overlay_update(overlay, crtc->fb, mode, &pos); -} - -static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - - DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); - - if (exynos_crtc->dpms == mode) { - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); - return; - } - - mutex_lock(&dev->struct_mutex); - - switch (mode) { - case DRM_MODE_DPMS_ON: - exynos_drm_fn_encoder(crtc, &mode, - exynos_drm_encoder_crtc_dpms); - exynos_crtc->dpms = mode; - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - exynos_drm_fn_encoder(crtc, &mode, - exynos_drm_encoder_crtc_dpms); - exynos_crtc->dpms = mode; - break; - default: - DRM_ERROR("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&dev->struct_mutex); -} - -static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* drm framework doesn't check NULL. */ -} - -static void exynos_drm_crtc_commit(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * when set_crtc is requested from user or at booting time, - * crtc->commit would be called without dpms call so if dpms is - * no power on then crtc->dpms should be called - * with DRM_MODE_DPMS_ON for the hardware power to be on. - */ - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) { - int mode = DRM_MODE_DPMS_ON; - - /* - * enable hardware(power on) to all encoders hdmi connected - * to current crtc. - */ - exynos_drm_crtc_dpms(crtc, mode); - /* - * enable dma to all encoders connected to current crtc and - * lcd panel. - */ - exynos_drm_fn_encoder(crtc, &mode, - exynos_drm_encoder_dpms_from_crtc); - } - - exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe, - exynos_drm_encoder_crtc_commit); -} - -static bool -exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* drm framework doesn't check NULL */ - return true; -} - -static int -exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, - struct drm_framebuffer *old_fb) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * copy the mode data adjusted by mode_fixup() into crtc->mode - * so that hardware can be seet to proper mode. - */ - memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); - - return exynos_drm_crtc_update(crtc); -} - -static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = exynos_drm_crtc_update(crtc); - if (ret) - return ret; - - exynos_drm_crtc_apply(crtc); - - return ret; -} - -static void exynos_drm_crtc_load_lut(struct drm_crtc *crtc) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - /* drm framework doesn't check NULL */ -} - -static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { - .dpms = exynos_drm_crtc_dpms, - .prepare = exynos_drm_crtc_prepare, - .commit = exynos_drm_crtc_commit, - .mode_fixup = exynos_drm_crtc_mode_fixup, - .mode_set = exynos_drm_crtc_mode_set, - .mode_set_base = exynos_drm_crtc_mode_set_base, - .load_lut = exynos_drm_crtc_load_lut, -}; - -static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event) -{ - struct drm_device *dev = crtc->dev; - struct exynos_drm_private *dev_priv = dev->dev_private; - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct drm_framebuffer *old_fb = crtc->fb; - int ret = -EINVAL; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - mutex_lock(&dev->struct_mutex); - - if (event) { - /* - * the pipe from user always is 0 so we can set pipe number - * of current owner to event. - */ - event->pipe = exynos_crtc->pipe; - - ret = drm_vblank_get(dev, exynos_crtc->pipe); - if (ret) { - DRM_DEBUG("failed to acquire vblank counter\n"); - list_del(&event->base.link); - - goto out; - } - - list_add_tail(&event->base.link, - &dev_priv->pageflip_event_list); - - crtc->fb = fb; - ret = exynos_drm_crtc_update(crtc); - if (ret) { - crtc->fb = old_fb; - drm_vblank_put(dev, exynos_crtc->pipe); - list_del(&event->base.link); - - goto out; - } - - /* - * the values related to a buffer of the drm framebuffer - * to be applied should be set at here. because these values - * first, are set to shadow registers and then to - * real registers at vsync front porch period. - */ - exynos_drm_crtc_apply(crtc); - } -out: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct exynos_drm_private *private = crtc->dev->dev_private; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - private->crtc[exynos_crtc->pipe] = NULL; - - drm_crtc_cleanup(crtc); - kfree(exynos_crtc); -} - -static struct drm_crtc_funcs exynos_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, - .page_flip = exynos_drm_crtc_page_flip, - .destroy = exynos_drm_crtc_destroy, -}; - -struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - - return &exynos_crtc->overlay; -} - -int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr) -{ - struct exynos_drm_crtc *exynos_crtc; - struct exynos_drm_private *private = dev->dev_private; - struct drm_crtc *crtc; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); - if (!exynos_crtc) { - DRM_ERROR("failed to allocate exynos crtc\n"); - return -ENOMEM; - } - - exynos_crtc->pipe = nr; - exynos_crtc->dpms = DRM_MODE_DPMS_OFF; - exynos_crtc->overlay.zpos = DEFAULT_ZPOS; - crtc = &exynos_crtc->drm_crtc; - - private->crtc[nr] = crtc; - - drm_crtc_init(dev, crtc, &exynos_crtc_funcs); - drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs); - - return 0; -} - -int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc) -{ - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_crtc *exynos_crtc = - to_exynos_crtc(private->crtc[crtc]); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) - return -EPERM; - - exynos_drm_fn_encoder(private->crtc[crtc], &crtc, - exynos_drm_enable_vblank); - - return 0; -} - -void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc) -{ - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_crtc *exynos_crtc = - to_exynos_crtc(private->crtc[crtc]); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) - return; - - exynos_drm_fn_encoder(private->crtc[crtc], &crtc, - exynos_drm_disable_vblank); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.h deleted file mode 100644 index 25f72a62..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ /dev/null @@ -1,63 +0,0 @@ -/* exynos_drm_crtc.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_CRTC_H_ -#define _EXYNOS_DRM_CRTC_H_ - -struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_device *dev, - struct drm_crtc *crtc); -int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr); -int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc); -void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc); - -/* - * Exynos specific crtc postion structure. - * - * @fb_x: offset x on a framebuffer to be displyed - * - the unit is screen coordinates. - * @fb_y: offset y on a framebuffer to be displayed - * - the unit is screen coordinates. - * @crtc_x: offset x on hardware screen. - * @crtc_y: offset y on hardware screen. - * @crtc_w: width of hardware screen. - * @crtc_h: height of hardware screen. - */ -struct exynos_drm_crtc_pos { - unsigned int fb_x; - unsigned int fb_y; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_w; - unsigned int crtc_h; -}; - -int exynos_drm_overlay_update(struct exynos_drm_overlay *overlay, - struct drm_framebuffer *fb, - struct drm_display_mode *mode, - struct exynos_drm_crtc_pos *pos); -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.c deleted file mode 100644 index a6819b5f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc_helper.h" - -#include - -#include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_encoder.h" -#include "exynos_drm_fbdev.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_plane.h" -#include "exynos_drm_vidi.h" - -#define DRIVER_NAME "exynos" -#define DRIVER_DESC "Samsung SoC DRM" -#define DRIVER_DATE "20110530" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 - -#define VBLANK_OFF_DELAY 50000 - -static int exynos_drm_load(struct drm_device *dev, unsigned long flags) -{ - struct exynos_drm_private *private; - int ret; - int nr; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); - if (!private) { - DRM_ERROR("failed to allocate private\n"); - return -ENOMEM; - } - - INIT_LIST_HEAD(&private->pageflip_event_list); - dev->dev_private = (void *)private; - - drm_mode_config_init(dev); - - /* init kms poll for handling hpd */ - drm_kms_helper_poll_init(dev); - - exynos_drm_mode_config_init(dev); - - /* - * EXYNOS4 is enough to have two CRTCs and each crtc would be used - * without dependency of hardware. - */ - for (nr = 0; nr < MAX_CRTC; nr++) { - ret = exynos_drm_crtc_create(dev, nr); - if (ret) - goto err_crtc; - } - - for (nr = 0; nr < MAX_PLANE; nr++) { - ret = exynos_plane_init(dev, nr); - if (ret) - goto err_crtc; - } - - ret = drm_vblank_init(dev, MAX_CRTC); - if (ret) - goto err_crtc; - - /* - * probe sub drivers such as display controller and hdmi driver, - * that were registered at probe() of platform driver - * to the sub driver and create encoder and connector for them. - */ - ret = exynos_drm_device_register(dev); - if (ret) - goto err_vblank; - - /* setup possible_clones. */ - exynos_drm_encoder_setup(dev); - - /* - * create and configure fb helper and also exynos specific - * fbdev object. - */ - ret = exynos_drm_fbdev_init(dev); - if (ret) { - DRM_ERROR("failed to initialize drm fbdev\n"); - goto err_drm_device; - } - - drm_vblank_offdelay = VBLANK_OFF_DELAY; - - return 0; - -err_drm_device: - exynos_drm_device_unregister(dev); -err_vblank: - drm_vblank_cleanup(dev); -err_crtc: - drm_mode_config_cleanup(dev); - kfree(private); - - return ret; -} - -static int exynos_drm_unload(struct drm_device *dev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - exynos_drm_fbdev_fini(dev); - exynos_drm_device_unregister(dev); - drm_vblank_cleanup(dev); - drm_kms_helper_poll_fini(dev); - drm_mode_config_cleanup(dev); - kfree(dev->dev_private); - - dev->dev_private = NULL; - - return 0; -} - -static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - return exynos_drm_subdrv_open(dev, file); -} - -static void exynos_drm_preclose(struct drm_device *dev, - struct drm_file *file) -{ - struct exynos_drm_private *private = dev->dev_private; - struct drm_pending_vblank_event *e, *t; - unsigned long flags; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - /* release events of current file */ - spin_lock_irqsave(&dev->event_lock, flags); - list_for_each_entry_safe(e, t, &private->pageflip_event_list, - base.link) { - if (e->base.file_priv == file) { - list_del(&e->base.link); - e->base.destroy(&e->base); - } - } - spin_unlock_irqrestore(&dev->event_lock, flags); - - exynos_drm_subdrv_close(dev, file); -} - -static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - if (!file->driver_priv) - return; - - kfree(file->driver_priv); - file->driver_priv = NULL; -} - -static void exynos_drm_lastclose(struct drm_device *dev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - exynos_drm_fbdev_restore_mode(dev); -} - -static struct vm_operations_struct exynos_drm_gem_vm_ops = { - .fault = exynos_drm_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static struct drm_ioctl_desc exynos_ioctls[] = { - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl, - DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET, - exynos_drm_gem_map_offset_ioctl, DRM_UNLOCKED | - DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP, - exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl, - DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, - vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH), -}; - -static const struct file_operations exynos_drm_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .mmap = exynos_drm_gem_mmap, - .poll = drm_poll, - .read = drm_read, - .unlocked_ioctl = drm_ioctl, - .release = drm_release, -}; - -static struct drm_driver exynos_drm_driver = { - .driver_features = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM | - DRIVER_MODESET | DRIVER_GEM, - .load = exynos_drm_load, - .unload = exynos_drm_unload, - .open = exynos_drm_open, - .preclose = exynos_drm_preclose, - .lastclose = exynos_drm_lastclose, - .postclose = exynos_drm_postclose, - .get_vblank_counter = drm_vblank_count, - .enable_vblank = exynos_drm_crtc_enable_vblank, - .disable_vblank = exynos_drm_crtc_disable_vblank, - .gem_init_object = exynos_drm_gem_init_object, - .gem_free_object = exynos_drm_gem_free_object, - .gem_vm_ops = &exynos_drm_gem_vm_ops, - .dumb_create = exynos_drm_gem_dumb_create, - .dumb_map_offset = exynos_drm_gem_dumb_map_offset, - .dumb_destroy = exynos_drm_gem_dumb_destroy, - .ioctls = exynos_ioctls, - .fops = &exynos_drm_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, -}; - -static int exynos_drm_platform_probe(struct platform_device *pdev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); - - return drm_platform_init(&exynos_drm_driver, pdev); -} - -static int exynos_drm_platform_remove(struct platform_device *pdev) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - drm_platform_exit(&exynos_drm_driver, pdev); - - return 0; -} - -static struct platform_driver exynos_drm_platform_driver = { - .probe = exynos_drm_platform_probe, - .remove = __devexit_p(exynos_drm_platform_remove), - .driver = { - .owner = THIS_MODULE, - .name = "exynos-drm", - }, -}; - -static int __init exynos_drm_init(void) -{ - int ret; - - DRM_DEBUG_DRIVER("%s\n", __FILE__); - -#ifdef CONFIG_DRM_EXYNOS_FIMD - ret = platform_driver_register(&fimd_driver); - if (ret < 0) - goto out_fimd; -#endif - -#ifdef CONFIG_DRM_EXYNOS_HDMI - ret = platform_driver_register(&hdmi_driver); - if (ret < 0) - goto out_hdmi; - ret = platform_driver_register(&mixer_driver); - if (ret < 0) - goto out_mixer; - ret = platform_driver_register(&exynos_drm_common_hdmi_driver); - if (ret < 0) - goto out_common_hdmi; -#endif - -#ifdef CONFIG_DRM_EXYNOS_VIDI - ret = platform_driver_register(&vidi_driver); - if (ret < 0) - goto out_vidi; -#endif - - ret = platform_driver_register(&exynos_drm_platform_driver); - if (ret < 0) - goto out; - - return 0; - -out: -#ifdef CONFIG_DRM_EXYNOS_VIDI -out_vidi: - platform_driver_unregister(&vidi_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_HDMI - platform_driver_unregister(&exynos_drm_common_hdmi_driver); -out_common_hdmi: - platform_driver_unregister(&mixer_driver); -out_mixer: - platform_driver_unregister(&hdmi_driver); -out_hdmi: -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMD - platform_driver_unregister(&fimd_driver); -out_fimd: -#endif - return ret; -} - -static void __exit exynos_drm_exit(void) -{ - DRM_DEBUG_DRIVER("%s\n", __FILE__); - - platform_driver_unregister(&exynos_drm_platform_driver); - -#ifdef CONFIG_DRM_EXYNOS_HDMI - platform_driver_unregister(&exynos_drm_common_hdmi_driver); - platform_driver_unregister(&mixer_driver); - platform_driver_unregister(&hdmi_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_VIDI - platform_driver_unregister(&vidi_driver); -#endif - -#ifdef CONFIG_DRM_EXYNOS_FIMD - platform_driver_unregister(&fimd_driver); -#endif -} - -module_init(exynos_drm_init); -module_exit(exynos_drm_exit); - -MODULE_AUTHOR("Inki Dae "); -MODULE_AUTHOR("Joonyoung Shim "); -MODULE_AUTHOR("Seung-Woo Kim "); -MODULE_DESCRIPTION("Samsung SoC DRM Driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.h deleted file mode 100644 index 1d814175..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ /dev/null @@ -1,290 +0,0 @@ -/* exynos_drm_drv.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_DRV_H_ -#define _EXYNOS_DRM_DRV_H_ - -#include -#include "drm.h" - -#define MAX_CRTC 3 -#define MAX_PLANE 5 -#define MAX_FB_BUFFER 4 -#define DEFAULT_ZPOS -1 - -struct drm_device; -struct exynos_drm_overlay; -struct drm_connector; - -extern unsigned int drm_vblank_offdelay; - -/* this enumerates display type. */ -enum exynos_drm_output_type { - EXYNOS_DISPLAY_TYPE_NONE, - /* RGB or CPU Interface. */ - EXYNOS_DISPLAY_TYPE_LCD, - /* HDMI Interface. */ - EXYNOS_DISPLAY_TYPE_HDMI, - /* Virtual Display Interface. */ - EXYNOS_DISPLAY_TYPE_VIDI, -}; - -/* - * Exynos drm overlay ops structure. - * - * @mode_set: copy drm overlay info to hw specific overlay info. - * @commit: apply hardware specific overlay data to registers. - * @disable: disable hardware specific overlay. - */ -struct exynos_drm_overlay_ops { - void (*mode_set)(struct device *subdrv_dev, - struct exynos_drm_overlay *overlay); - void (*commit)(struct device *subdrv_dev, int zpos); - void (*disable)(struct device *subdrv_dev, int zpos); -}; - -/* - * Exynos drm common overlay structure. - * - * @fb_x: offset x on a framebuffer to be displayed. - * - the unit is screen coordinates. - * @fb_y: offset y on a framebuffer to be displayed. - * - the unit is screen coordinates. - * @fb_width: width of a framebuffer. - * @fb_height: height of a framebuffer. - * @crtc_x: offset x on hardware screen. - * @crtc_y: offset y on hardware screen. - * @crtc_width: window width to be displayed (hardware screen). - * @crtc_height: window height to be displayed (hardware screen). - * @mode_width: width of screen mode. - * @mode_height: height of screen mode. - * @refresh: refresh rate. - * @scan_flag: interlace or progressive way. - * (it could be DRM_MODE_FLAG_*) - * @bpp: pixel size.(in bit) - * @pixel_format: fourcc pixel format of this overlay - * @dma_addr: array of bus(accessed by dma) address to the memory region - * allocated for a overlay. - * @vaddr: array of virtual memory addresss to this overlay. - * @zpos: order of overlay layer(z position). - * @default_win: a window to be enabled. - * @color_key: color key on or off. - * @index_color: if using color key feature then this value would be used - * as index color. - * @local_path: in case of lcd type, local path mode on or off. - * @transparency: transparency on or off. - * @activated: activated or not. - * - * this structure is common to exynos SoC and its contents would be copied - * to hardware specific overlay info. - */ -struct exynos_drm_overlay { - unsigned int fb_x; - unsigned int fb_y; - unsigned int fb_width; - unsigned int fb_height; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_width; - unsigned int crtc_height; - unsigned int mode_width; - unsigned int mode_height; - unsigned int refresh; - unsigned int scan_flag; - unsigned int bpp; - unsigned int pitch; - uint32_t pixel_format; - dma_addr_t dma_addr[MAX_FB_BUFFER]; - void __iomem *vaddr[MAX_FB_BUFFER]; - int zpos; - - bool default_win; - bool color_key; - unsigned int index_color; - bool local_path; - bool transparency; - bool activated; -}; - -/* - * Exynos DRM Display Structure. - * - this structure is common to analog tv, digital tv and lcd panel. - * - * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. - * @is_connected: check for that display is connected or not. - * @get_edid: get edid modes from display driver. - * @get_panel: get panel object from display driver. - * @check_timing: check if timing is valid or not. - * @power_on: display device on or off. - */ -struct exynos_drm_display_ops { - enum exynos_drm_output_type type; - bool (*is_connected)(struct device *dev); - int (*get_edid)(struct device *dev, struct drm_connector *connector, - u8 *edid, int len); - void *(*get_panel)(struct device *dev); - int (*check_timing)(struct device *dev, void *timing); - int (*power_on)(struct device *dev, int mode); -}; - -/* - * Exynos drm manager ops - * - * @dpms: control device power. - * @apply: set timing, vblank and overlay data to registers. - * @mode_fixup: fix mode data comparing to hw specific display mode. - * @mode_set: convert drm_display_mode to hw specific display mode and - * would be called by encoder->mode_set(). - * @get_max_resol: get maximum resolution to specific hardware. - * @commit: set current hw specific display mode to hw. - * @enable_vblank: specific driver callback for enabling vblank interrupt. - * @disable_vblank: specific driver callback for disabling vblank interrupt. - */ -struct exynos_drm_manager_ops { - void (*dpms)(struct device *subdrv_dev, int mode); - void (*apply)(struct device *subdrv_dev); - void (*mode_fixup)(struct device *subdrv_dev, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - void (*mode_set)(struct device *subdrv_dev, void *mode); - void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width, - unsigned int *height); - void (*commit)(struct device *subdrv_dev); - int (*enable_vblank)(struct device *subdrv_dev); - void (*disable_vblank)(struct device *subdrv_dev); -}; - -/* - * Exynos drm common manager structure. - * - * @dev: pointer to device object for subdrv device driver. - * sub drivers such as display controller or hdmi driver, - * have their own device object. - * @ops: pointer to callbacks for exynos drm specific framebuffer. - * these callbacks should be set by specific drivers such fimd - * or hdmi driver and are used to control hardware global registers. - * @overlay_ops: pointer to callbacks for exynos drm specific framebuffer. - * these callbacks should be set by specific drivers such fimd - * or hdmi driver and are used to control hardware overlay reigsters. - * @display: pointer to callbacks for exynos drm specific framebuffer. - * these callbacks should be set by specific drivers such fimd - * or hdmi driver and are used to control display devices such as - * analog tv, digital tv and lcd panel and also get timing data for them. - */ -struct exynos_drm_manager { - struct device *dev; - int pipe; - struct exynos_drm_manager_ops *ops; - struct exynos_drm_overlay_ops *overlay_ops; - struct exynos_drm_display_ops *display_ops; -}; - -/* - * Exynos drm private structure. - */ -struct exynos_drm_private { - struct drm_fb_helper *fb_helper; - - /* list head for new event to be added. */ - struct list_head pageflip_event_list; - - /* - * created crtc object would be contained at this array and - * this array is used to be aware of which crtc did it request vblank. - */ - struct drm_crtc *crtc[MAX_CRTC]; -}; - -/* - * Exynos drm sub driver structure. - * - * @list: sub driver has its own list object to register to exynos drm driver. - * @dev: pointer to device object for subdrv device driver. - * @drm_dev: pointer to drm_device and this pointer would be set - * when sub driver calls exynos_drm_subdrv_register(). - * @manager: subdrv has its own manager to control a hardware appropriately - * and we can access a hardware drawing on this manager. - * @probe: this callback would be called by exynos drm driver after - * subdrv is registered to it. - * @remove: this callback is used to release resources created - * by probe callback. - * @open: this would be called with drm device file open. - * @close: this would be called with drm device file close. - * @encoder: encoder object owned by this sub driver. - * @connector: connector object owned by this sub driver. - */ -struct exynos_drm_subdrv { - struct list_head list; - struct device *dev; - struct drm_device *drm_dev; - struct exynos_drm_manager *manager; - - int (*probe)(struct drm_device *drm_dev, struct device *dev); - void (*remove)(struct drm_device *dev); - int (*open)(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file); - void (*close)(struct drm_device *drm_dev, struct device *dev, - struct drm_file *file); - - struct drm_encoder *encoder; - struct drm_connector *connector; -}; - -/* - * this function calls a probe callback registered to sub driver list and - * create its own encoder and connector and then set drm_device object - * to global one. - */ -int exynos_drm_device_register(struct drm_device *dev); -/* - * this function calls a remove callback registered to sub driver list and - * destroy its own encoder and connetor. - */ -int exynos_drm_device_unregister(struct drm_device *dev); - -/* - * this function would be called by sub drivers such as display controller - * or hdmi driver to register this sub driver object to exynos drm driver - * and when a sub driver is registered to exynos drm driver a probe callback - * of the sub driver is called and creates its own encoder and connector. - */ -int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv); - -/* this function removes subdrv list from exynos drm driver */ -int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv); - -int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); -void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); - -extern struct platform_driver fimd_driver; -extern struct platform_driver hdmi_driver; -extern struct platform_driver mixer_driver; -extern struct platform_driver exynos_drm_common_hdmi_driver; -extern struct platform_driver vidi_driver; -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.c deleted file mode 100644 index 6e9ac7bd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ /dev/null @@ -1,445 +0,0 @@ -/* exynos_drm_encoder.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_encoder.h" - -#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\ - drm_encoder) - -/* - * exynos specific encoder structure. - * - * @drm_encoder: encoder object. - * @manager: specific encoder has its own manager to control a hardware - * appropriately and we can access a hardware drawing on this manager. - * @dpms: store the encoder dpms value. - */ -struct exynos_drm_encoder { - struct drm_encoder drm_encoder; - struct exynos_drm_manager *manager; - int dpms; -}; - -static void exynos_drm_display_power(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - struct exynos_drm_display_ops *display_ops = - manager->display_ops; - - DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", - connector->base.id, mode); - if (display_ops && display_ops->power_on) - display_ops->power_on(manager->dev, mode); - } - } -} - -static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - - DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode); - - if (exynos_encoder->dpms == mode) { - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); - return; - } - - mutex_lock(&dev->struct_mutex); - - switch (mode) { - case DRM_MODE_DPMS_ON: - if (manager_ops && manager_ops->apply) - manager_ops->apply(manager->dev); - exynos_drm_display_power(encoder, mode); - exynos_encoder->dpms = mode; - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - exynos_drm_display_power(encoder, mode); - exynos_encoder->dpms = mode; - break; - default: - DRM_ERROR("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&dev->struct_mutex); -} - -static bool -exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) - if (manager_ops && manager_ops->mode_fixup) - manager_ops->mode_fixup(manager->dev, connector, - mode, adjusted_mode); - } - - return true; -} - -static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_connector *connector; - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - struct exynos_drm_overlay *overlay = get_exynos_drm_overlay(dev, - encoder->crtc); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - if (manager_ops && manager_ops->mode_set) - manager_ops->mode_set(manager->dev, - adjusted_mode); - - if (overlay_ops && overlay_ops->mode_set) - overlay_ops->mode_set(manager->dev, overlay); - } - } -} - -static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* drm framework doesn't check NULL. */ -} - -static void exynos_drm_encoder_commit(struct drm_encoder *encoder) -{ - struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); - struct exynos_drm_manager_ops *manager_ops = manager->ops; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (manager_ops && manager_ops->commit) - manager_ops->commit(manager->dev); -} - -static struct drm_crtc * -exynos_drm_encoder_get_crtc(struct drm_encoder *encoder) -{ - return encoder->crtc; -} - -static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { - .dpms = exynos_drm_encoder_dpms, - .mode_fixup = exynos_drm_encoder_mode_fixup, - .mode_set = exynos_drm_encoder_mode_set, - .prepare = exynos_drm_encoder_prepare, - .commit = exynos_drm_encoder_commit, - .get_crtc = exynos_drm_encoder_get_crtc, -}; - -static void exynos_drm_encoder_destroy(struct drm_encoder *encoder) -{ - struct exynos_drm_encoder *exynos_encoder = - to_exynos_encoder(encoder); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_encoder->manager->pipe = -1; - - drm_encoder_cleanup(encoder); - kfree(exynos_encoder); -} - -static struct drm_encoder_funcs exynos_encoder_funcs = { - .destroy = exynos_drm_encoder_destroy, -}; - -static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder) -{ - struct drm_encoder *clone; - struct drm_device *dev = encoder->dev; - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_display_ops *display_ops = - exynos_encoder->manager->display_ops; - unsigned int clone_mask = 0; - int cnt = 0; - - list_for_each_entry(clone, &dev->mode_config.encoder_list, head) { - switch (display_ops->type) { - case EXYNOS_DISPLAY_TYPE_LCD: - case EXYNOS_DISPLAY_TYPE_HDMI: - case EXYNOS_DISPLAY_TYPE_VIDI: - clone_mask |= (1 << (cnt++)); - break; - default: - continue; - } - } - - return clone_mask; -} - -void exynos_drm_encoder_setup(struct drm_device *dev) -{ - struct drm_encoder *encoder; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - encoder->possible_clones = exynos_drm_encoder_clones(encoder); -} - -struct drm_encoder * -exynos_drm_encoder_create(struct drm_device *dev, - struct exynos_drm_manager *manager, - unsigned int possible_crtcs) -{ - struct drm_encoder *encoder; - struct exynos_drm_encoder *exynos_encoder; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!manager || !possible_crtcs) - return NULL; - - if (!manager->dev) - return NULL; - - exynos_encoder = kzalloc(sizeof(*exynos_encoder), GFP_KERNEL); - if (!exynos_encoder) { - DRM_ERROR("failed to allocate encoder\n"); - return NULL; - } - - exynos_encoder->dpms = DRM_MODE_DPMS_OFF; - exynos_encoder->manager = manager; - encoder = &exynos_encoder->drm_encoder; - encoder->possible_crtcs = possible_crtcs; - - DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); - - drm_encoder_init(dev, encoder, &exynos_encoder_funcs, - DRM_MODE_ENCODER_TMDS); - - drm_encoder_helper_add(encoder, &exynos_encoder_helper_funcs); - - DRM_DEBUG_KMS("encoder has been created\n"); - - return encoder; -} - -struct exynos_drm_manager *exynos_drm_get_manager(struct drm_encoder *encoder) -{ - return to_exynos_encoder(encoder)->manager; -} - -void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, - void (*fn)(struct drm_encoder *, void *)) -{ - struct drm_device *dev = crtc->dev; - struct drm_encoder *encoder; - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_manager *manager; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - /* - * if crtc is detached from encoder, check pipe, - * otherwise check crtc attached to encoder - */ - if (!encoder->crtc) { - manager = to_exynos_encoder(encoder)->manager; - if (manager->pipe < 0 || - private->crtc[manager->pipe] != crtc) - continue; - } else { - if (encoder->crtc != crtc) - continue; - } - - fn(encoder, data); - } -} - -void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_manager_ops *manager_ops = manager->ops; - int crtc = *(int *)data; - - if (manager->pipe == -1) - manager->pipe = crtc; - - if (manager_ops->enable_vblank) - manager_ops->enable_vblank(manager->dev); -} - -void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_manager_ops *manager_ops = manager->ops; - int crtc = *(int *)data; - - if (manager->pipe == -1) - manager->pipe = crtc; - - if (manager_ops->disable_vblank) - manager_ops->disable_vblank(manager->dev); -} - -void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder, - void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - int zpos = DEFAULT_ZPOS; - - if (data) - zpos = *(int *)data; - - if (overlay_ops && overlay_ops->commit) - overlay_ops->commit(manager->dev, zpos); -} - -void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - int crtc = *(int *)data; - int zpos = DEFAULT_ZPOS; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * when crtc is detached from encoder, this pipe is used - * to select manager operation - */ - manager->pipe = crtc; - - exynos_drm_encoder_crtc_plane_commit(encoder, &zpos); -} - -void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - int mode = *(int *)data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_encoder_dpms(encoder, mode); - - exynos_encoder->dpms = mode; -} - -void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) -{ - struct drm_device *dev = encoder->dev; - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_manager *manager = exynos_encoder->manager; - struct exynos_drm_manager_ops *manager_ops = manager->ops; - struct drm_connector *connector; - int mode = *(int *)data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (manager_ops && manager_ops->dpms) - manager_ops->dpms(manager->dev, mode); - - /* - * set current dpms mode to the connector connected to - * current encoder. connector->dpms would be checked - * at drm_helper_connector_dpms() - */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder) - connector->dpms = mode; - - /* - * if this condition is ok then it means that the crtc is already - * detached from encoder and last function for detaching is properly - * done, so clear pipe from manager to prevent repeated call. - */ - if (mode > DRM_MODE_DPMS_ON) { - if (!encoder->crtc) - manager->pipe = -1; - } -} - -void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - struct exynos_drm_overlay *overlay = data; - - if (overlay_ops && overlay_ops->mode_set) - overlay_ops->mode_set(manager->dev, overlay); -} - -void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data) -{ - struct exynos_drm_manager *manager = - to_exynos_encoder(encoder)->manager; - struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; - int zpos = DEFAULT_ZPOS; - - DRM_DEBUG_KMS("\n"); - - if (data) - zpos = *(int *)data; - - if (overlay_ops && overlay_ops->disable) - overlay_ops->disable(manager->dev, zpos); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.h deleted file mode 100644 index eb7d2316..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_ENCODER_H_ -#define _EXYNOS_DRM_ENCODER_H_ - -struct exynos_drm_manager; - -void exynos_drm_encoder_setup(struct drm_device *dev); -struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev, - struct exynos_drm_manager *mgr, - unsigned int possible_crtcs); -struct exynos_drm_manager * -exynos_drm_get_manager(struct drm_encoder *encoder); -void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data, - void (*fn)(struct drm_encoder *, void *)); -void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data); -void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder, - void *data); -void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, - void *data); -void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_crtc_mode_set(struct drm_encoder *encoder, void *data); -void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.c deleted file mode 100644 index c38c8f46..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ /dev/null @@ -1,213 +0,0 @@ -/* exynos_drm_fb.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_gem.h" - -#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) - -/* - * exynos specific framebuffer structure. - * - * @fb: drm framebuffer obejct. - * @exynos_gem_obj: array of exynos specific gem object containing a gem object. - */ -struct exynos_drm_fb { - struct drm_framebuffer fb; - struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; -}; - -static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) -{ - struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - drm_framebuffer_cleanup(fb); - - kfree(exynos_fb); - exynos_fb = NULL; -} - -static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return drm_gem_handle_create(file_priv, - &exynos_fb->exynos_gem_obj[0]->base, handle); -} - -static int exynos_drm_fb_dirty(struct drm_framebuffer *fb, - struct drm_file *file_priv, unsigned flags, - unsigned color, struct drm_clip_rect *clips, - unsigned num_clips) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO */ - - return 0; -} - -static struct drm_framebuffer_funcs exynos_drm_fb_funcs = { - .destroy = exynos_drm_fb_destroy, - .create_handle = exynos_drm_fb_create_handle, - .dirty = exynos_drm_fb_dirty, -}; - -struct drm_framebuffer * -exynos_drm_framebuffer_init(struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) -{ - struct exynos_drm_fb *exynos_fb; - int ret; - - exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL); - if (!exynos_fb) { - DRM_ERROR("failed to allocate exynos drm framebuffer\n"); - return ERR_PTR(-ENOMEM); - } - - ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs); - if (ret) { - DRM_ERROR("failed to initialize framebuffer\n"); - return ERR_PTR(ret); - } - - drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); - exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj); - - return &exynos_fb->fb; -} - -static struct drm_framebuffer * -exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_gem_object *obj; - struct drm_framebuffer *fb; - struct exynos_drm_fb *exynos_fb; - int nr; - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); - if (!obj) { - DRM_ERROR("failed to lookup gem object\n"); - return ERR_PTR(-ENOENT); - } - - drm_gem_object_unreference_unlocked(obj); - - fb = exynos_drm_framebuffer_init(dev, mode_cmd, obj); - if (IS_ERR(fb)) - return fb; - - exynos_fb = to_exynos_fb(fb); - nr = exynos_drm_format_num_buffers(fb->pixel_format); - - for (i = 1; i < nr; i++) { - obj = drm_gem_object_lookup(dev, file_priv, - mode_cmd->handles[i]); - if (!obj) { - DRM_ERROR("failed to lookup gem object\n"); - exynos_drm_fb_destroy(fb); - return ERR_PTR(-ENOENT); - } - - drm_gem_object_unreference_unlocked(obj); - - exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); - } - - return fb; -} - -struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, - int index) -{ - struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); - struct exynos_drm_gem_buf *buffer; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (index >= MAX_FB_BUFFER) - return NULL; - - buffer = exynos_fb->exynos_gem_obj[index]->buffer; - if (!buffer) - return NULL; - - DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n", - (unsigned long)buffer->kvaddr, - (unsigned long)buffer->dma_addr); - - return buffer; -} - -static void exynos_drm_output_poll_changed(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - struct drm_fb_helper *fb_helper = private->fb_helper; - - if (fb_helper) - drm_fb_helper_hotplug_event(fb_helper); -} - -static struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { - .fb_create = exynos_user_fb_create, - .output_poll_changed = exynos_drm_output_poll_changed, -}; - -void exynos_drm_mode_config_init(struct drm_device *dev) -{ - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - - /* - * set max width and height as default value(4096x4096). - * this value would be used to check framebuffer size limitation - * at drm_mode_addfb(). - */ - dev->mode_config.max_width = 4096; - dev->mode_config.max_height = 4096; - - dev->mode_config.funcs = &exynos_drm_mode_config_funcs; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.h deleted file mode 100644 index 3ecb30d9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fb.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_FB_H_ -#define _EXYNOS_DRM_FB_H - -static inline int exynos_drm_format_num_buffers(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_NV12M: - case DRM_FORMAT_NV12MT: - return 2; - case DRM_FORMAT_YUV420M: - return 3; - default: - return 1; - } -} - -struct drm_framebuffer * -exynos_drm_framebuffer_init(struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); - -/* get memory information of a drm framebuffer */ -struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, - int index); - -void exynos_drm_mode_config_init(struct drm_device *dev); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.c deleted file mode 100644 index d5586cc7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ /dev/null @@ -1,318 +0,0 @@ -/* exynos_drm_fbdev.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_fb_helper.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_fb.h" -#include "exynos_drm_gem.h" - -#define MAX_CONNECTOR 4 -#define PREFERRED_BPP 32 - -#define to_exynos_fbdev(x) container_of(x, struct exynos_drm_fbdev,\ - drm_fb_helper) - -struct exynos_drm_fbdev { - struct drm_fb_helper drm_fb_helper; - struct exynos_drm_gem_obj *exynos_gem_obj; -}; - -static struct fb_ops exynos_drm_fb_ops = { - .owner = THIS_MODULE, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_setcmap = drm_fb_helper_setcmap, -}; - -static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, - struct drm_framebuffer *fb) -{ - struct fb_info *fbi = helper->fbdev; - struct drm_device *dev = helper->dev; - struct exynos_drm_gem_buf *buffer; - unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3); - unsigned long offset; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); - drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height); - - /* RGB formats use only one buffer */ - buffer = exynos_drm_fb_buffer(fb, 0); - if (!buffer) { - DRM_LOG_KMS("buffer is null.\n"); - return -EFAULT; - } - - offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); - offset += fbi->var.yoffset * fb->pitches[0]; - - dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; - fbi->screen_base = buffer->kvaddr + offset; - fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); - fbi->screen_size = size; - fbi->fix.smem_len = size; - - return 0; -} - -static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper); - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_device *dev = helper->dev; - struct fb_info *fbi; - struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - struct platform_device *pdev = dev->platformdev; - unsigned long size; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3); - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - mutex_lock(&dev->struct_mutex); - - fbi = framebuffer_alloc(0, &pdev->dev); - if (!fbi) { - DRM_ERROR("failed to allocate fb info.\n"); - ret = -ENOMEM; - goto out; - } - - size = mode_cmd.pitches[0] * mode_cmd.height; - - /* 0 means to allocate physically continuous memory */ - exynos_gem_obj = exynos_drm_gem_create(dev, 0, size); - if (IS_ERR(exynos_gem_obj)) { - ret = PTR_ERR(exynos_gem_obj); - goto out; - } - - exynos_fbdev->exynos_gem_obj = exynos_gem_obj; - - helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd, - &exynos_gem_obj->base); - if (IS_ERR_OR_NULL(helper->fb)) { - DRM_ERROR("failed to create drm framebuffer.\n"); - ret = PTR_ERR(helper->fb); - goto out; - } - - helper->fbdev = fbi; - - fbi->par = helper; - fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->fbops = &exynos_drm_fb_ops; - - ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) { - DRM_ERROR("failed to allocate cmap.\n"); - goto out; - } - - ret = exynos_drm_fbdev_update(helper, helper->fb); - if (ret < 0) { - fb_dealloc_cmap(&fbi->cmap); - goto out; - } - -/* - * if failed, all resources allocated above would be released by - * drm_mode_config_cleanup() when drm_load() had been called prior - * to any specific driver such as fimd or hdmi driver. - */ -out: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * with !helper->fb, it means that this funcion is called first time - * and after that, the helper->fb would be used as clone mode. - */ - if (!helper->fb) { - ret = exynos_drm_fbdev_create(helper, sizes); - if (ret < 0) { - DRM_ERROR("failed to create fbdev.\n"); - return ret; - } - - /* - * fb_helper expects a value more than 1 if succeed - * because register_framebuffer() should be called. - */ - ret = 1; - } - - return ret; -} - -static struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = { - .fb_probe = exynos_drm_fbdev_probe, -}; - -int exynos_drm_fbdev_init(struct drm_device *dev) -{ - struct exynos_drm_fbdev *fbdev; - struct exynos_drm_private *private = dev->dev_private; - struct drm_fb_helper *helper; - unsigned int num_crtc; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector) - return 0; - - fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); - if (!fbdev) { - DRM_ERROR("failed to allocate drm fbdev.\n"); - return -ENOMEM; - } - - private->fb_helper = helper = &fbdev->drm_fb_helper; - helper->funcs = &exynos_drm_fb_helper_funcs; - - num_crtc = dev->mode_config.num_crtc; - - ret = drm_fb_helper_init(dev, helper, num_crtc, MAX_CONNECTOR); - if (ret < 0) { - DRM_ERROR("failed to initialize drm fb helper.\n"); - goto err_init; - } - - ret = drm_fb_helper_single_add_all_connectors(helper); - if (ret < 0) { - DRM_ERROR("failed to register drm_fb_helper_connector.\n"); - goto err_setup; - - } - - ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); - if (ret < 0) { - DRM_ERROR("failed to set up hw configuration.\n"); - goto err_setup; - } - - return 0; - -err_setup: - drm_fb_helper_fini(helper); - -err_init: - private->fb_helper = NULL; - kfree(fbdev); - - return ret; -} - -static void exynos_drm_fbdev_destroy(struct drm_device *dev, - struct drm_fb_helper *fb_helper) -{ - struct drm_framebuffer *fb; - - /* release drm framebuffer and real buffer */ - if (fb_helper->fb && fb_helper->fb->funcs) { - fb = fb_helper->fb; - if (fb && fb->funcs->destroy) - fb->funcs->destroy(fb); - } - - /* release linux framebuffer */ - if (fb_helper->fbdev) { - struct fb_info *info; - int ret; - - info = fb_helper->fbdev; - ret = unregister_framebuffer(info); - if (ret < 0) - DRM_DEBUG_KMS("failed unregister_framebuffer()\n"); - - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - - framebuffer_release(info); - } - - drm_fb_helper_fini(fb_helper); -} - -void exynos_drm_fbdev_fini(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - struct exynos_drm_fbdev *fbdev; - - if (!private || !private->fb_helper) - return; - - fbdev = to_exynos_fbdev(private->fb_helper); - - if (fbdev->exynos_gem_obj) - exynos_drm_gem_destroy(fbdev->exynos_gem_obj); - - exynos_drm_fbdev_destroy(dev, private->fb_helper); - kfree(fbdev); - private->fb_helper = NULL; -} - -void exynos_drm_fbdev_restore_mode(struct drm_device *dev) -{ - struct exynos_drm_private *private = dev->dev_private; - - if (!private || !private->fb_helper) - return; - - drm_fb_helper_restore_fbdev_mode(private->fb_helper); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.h deleted file mode 100644 index ccfce8a1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fbdev.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * - * Authors: - * Inki Dae - * Joonyoung Shim - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_FBDEV_H_ -#define _EXYNOS_DRM_FBDEV_H_ - -int exynos_drm_fbdev_init(struct drm_device *dev); -int exynos_drm_fbdev_reinit(struct drm_device *dev); -void exynos_drm_fbdev_fini(struct drm_device *dev); -void exynos_drm_fbdev_restore_mode(struct drm_device *dev); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fimd.c deleted file mode 100644 index 29fdbfeb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ /dev/null @@ -1,1022 +0,0 @@ -/* exynos_drm_fimd.c - * - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Joonyoung Shim - * Inki Dae - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ -#include "drmP.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "exynos_drm_drv.h" -#include "exynos_drm_fbdev.h" -#include "exynos_drm_crtc.h" - -/* - * FIMD is stand for Fully Interactive Mobile Display and - * as a display controller, it transfers contents drawn on memory - * to a LCD Panel through Display Interfaces such as RGB or - * CPU Interface. - */ - -/* position control register for hardware window 0, 2 ~ 4.*/ -#define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16) -#define VIDOSD_B(win) (VIDOSD_BASE + 0x04 + (win) * 16) -/* size control register for hardware window 0. */ -#define VIDOSD_C_SIZE_W0 (VIDOSD_BASE + 0x08) -/* alpha control register for hardware window 1 ~ 4. */ -#define VIDOSD_C(win) (VIDOSD_BASE + 0x18 + (win) * 16) -/* size control register for hardware window 1 ~ 4. */ -#define VIDOSD_D(win) (VIDOSD_BASE + 0x0C + (win) * 16) - -#define VIDWx_BUF_START(win, buf) (VIDW_BUF_START(buf) + (win) * 8) -#define VIDWx_BUF_END(win, buf) (VIDW_BUF_END(buf) + (win) * 8) -#define VIDWx_BUF_SIZE(win, buf) (VIDW_BUF_SIZE(buf) + (win) * 4) - -/* color key control register for hardware window 1 ~ 4. */ -#define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + (x * 8)) -/* color key value register for hardware window 1 ~ 4. */ -#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + (x * 8)) - -/* FIMD has totally five hardware windows. */ -#define WINDOWS_NR 5 - -#define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct fimd_win_data { - unsigned int offset_x; - unsigned int offset_y; - unsigned int ovl_width; - unsigned int ovl_height; - unsigned int fb_width; - unsigned int fb_height; - unsigned int bpp; - dma_addr_t dma_addr; - void __iomem *vaddr; - unsigned int buf_offsize; - unsigned int line_size; /* bytes */ - bool enabled; -}; - -struct fimd_context { - struct exynos_drm_subdrv subdrv; - int irq; - struct drm_crtc *crtc; - struct clk *bus_clk; - struct clk *lcd_clk; - struct resource *regs_res; - void __iomem *regs; - struct fimd_win_data win_data[WINDOWS_NR]; - unsigned int clkdiv; - unsigned int default_win; - unsigned long irq_flags; - u32 vidcon0; - u32 vidcon1; - bool suspended; - struct mutex lock; - - struct exynos_drm_panel_info *panel; -}; - -static bool fimd_display_is_connected(struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return true; -} - -static void *fimd_get_panel(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return ctx->panel; -} - -static int fimd_check_timing(struct device *dev, void *timing) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return 0; -} - -static int fimd_display_power_on(struct device *dev, int mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO */ - - return 0; -} - -static struct exynos_drm_display_ops fimd_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_LCD, - .is_connected = fimd_display_is_connected, - .get_panel = fimd_get_panel, - .check_timing = fimd_check_timing, - .power_on = fimd_display_power_on, -}; - -static void fimd_dpms(struct device *subdrv_dev, int mode) -{ - struct fimd_context *ctx = get_fimd_context(subdrv_dev); - - DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); - - mutex_lock(&ctx->lock); - - switch (mode) { - case DRM_MODE_DPMS_ON: - /* - * enable fimd hardware only if suspended status. - * - * P.S. fimd_dpms function would be called at booting time so - * clk_enable could be called double time. - */ - if (ctx->suspended) - pm_runtime_get_sync(subdrv_dev); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (!ctx->suspended) - pm_runtime_put_sync(subdrv_dev); - break; - default: - DRM_DEBUG_KMS("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&ctx->lock); -} - -static void fimd_apply(struct device *subdrv_dev) -{ - struct fimd_context *ctx = get_fimd_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; - struct exynos_drm_manager_ops *mgr_ops = mgr->ops; - struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; - struct fimd_win_data *win_data; - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - for (i = 0; i < WINDOWS_NR; i++) { - win_data = &ctx->win_data[i]; - if (win_data->enabled && (ovl_ops && ovl_ops->commit)) - ovl_ops->commit(subdrv_dev, i); - } - - if (mgr_ops && mgr_ops->commit) - mgr_ops->commit(subdrv_dev); -} - -static void fimd_commit(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct exynos_drm_panel_info *panel = ctx->panel; - struct fb_videomode *timing = &panel->timing; - u32 val; - - if (ctx->suspended) - return; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* setup polarity values from machine code. */ - writel(ctx->vidcon1, ctx->regs + VIDCON1); - - /* setup vertical timing values. */ - val = VIDTCON0_VBPD(timing->upper_margin - 1) | - VIDTCON0_VFPD(timing->lower_margin - 1) | - VIDTCON0_VSPW(timing->vsync_len - 1); - writel(val, ctx->regs + VIDTCON0); - - /* setup horizontal timing values. */ - val = VIDTCON1_HBPD(timing->left_margin - 1) | - VIDTCON1_HFPD(timing->right_margin - 1) | - VIDTCON1_HSPW(timing->hsync_len - 1); - writel(val, ctx->regs + VIDTCON1); - - /* setup horizontal and vertical display size. */ - val = VIDTCON2_LINEVAL(timing->yres - 1) | - VIDTCON2_HOZVAL(timing->xres - 1); - writel(val, ctx->regs + VIDTCON2); - - /* setup clock source, clock divider, enable dma. */ - val = ctx->vidcon0; - val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); - - if (ctx->clkdiv > 1) - val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) | VIDCON0_CLKDIR; - else - val &= ~VIDCON0_CLKDIR; /* 1:1 clock */ - - /* - * fields of register with prefix '_F' would be updated - * at vsync(same as dma start) - */ - val |= VIDCON0_ENVID | VIDCON0_ENVID_F; - writel(val, ctx->regs + VIDCON0); -} - -static int fimd_enable_vblank(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return -EPERM; - - if (!test_and_set_bit(0, &ctx->irq_flags)) { - val = readl(ctx->regs + VIDINTCON0); - - val |= VIDINTCON0_INT_ENABLE; - val |= VIDINTCON0_INT_FRAME; - - val &= ~VIDINTCON0_FRAMESEL0_MASK; - val |= VIDINTCON0_FRAMESEL0_VSYNC; - val &= ~VIDINTCON0_FRAMESEL1_MASK; - val |= VIDINTCON0_FRAMESEL1_NONE; - - writel(val, ctx->regs + VIDINTCON0); - } - - return 0; -} - -static void fimd_disable_vblank(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (test_and_clear_bit(0, &ctx->irq_flags)) { - val = readl(ctx->regs + VIDINTCON0); - - val &= ~VIDINTCON0_INT_FRAME; - val &= ~VIDINTCON0_INT_ENABLE; - - writel(val, ctx->regs + VIDINTCON0); - } -} - -static struct exynos_drm_manager_ops fimd_manager_ops = { - .dpms = fimd_dpms, - .apply = fimd_apply, - .commit = fimd_commit, - .enable_vblank = fimd_enable_vblank, - .disable_vblank = fimd_disable_vblank, -}; - -static void fimd_win_mode_set(struct device *dev, - struct exynos_drm_overlay *overlay) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data; - int win; - unsigned long offset; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!overlay) { - dev_err(dev, "overlay is NULL\n"); - return; - } - - win = overlay->zpos; - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - offset = overlay->fb_x * (overlay->bpp >> 3); - offset += overlay->fb_y * overlay->pitch; - - DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); - - win_data = &ctx->win_data[win]; - - win_data->offset_x = overlay->crtc_x; - win_data->offset_y = overlay->crtc_y; - win_data->ovl_width = overlay->crtc_width; - win_data->ovl_height = overlay->crtc_height; - win_data->fb_width = overlay->fb_width; - win_data->fb_height = overlay->fb_height; - win_data->dma_addr = overlay->dma_addr[0] + offset; - win_data->vaddr = overlay->vaddr[0] + offset; - win_data->bpp = overlay->bpp; - win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * - (overlay->bpp >> 3); - win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); - - DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", - win_data->offset_x, win_data->offset_y); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n", - (unsigned long)win_data->dma_addr, - (unsigned long)win_data->vaddr); - DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", - overlay->fb_width, overlay->crtc_width); -} - -static void fimd_win_set_pixfmt(struct device *dev, unsigned int win) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data = &ctx->win_data[win]; - unsigned long val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - val = WINCONx_ENWIN; - - switch (win_data->bpp) { - case 1: - val |= WINCON0_BPPMODE_1BPP; - val |= WINCONx_BITSWP; - val |= WINCONx_BURSTLEN_4WORD; - break; - case 2: - val |= WINCON0_BPPMODE_2BPP; - val |= WINCONx_BITSWP; - val |= WINCONx_BURSTLEN_8WORD; - break; - case 4: - val |= WINCON0_BPPMODE_4BPP; - val |= WINCONx_BITSWP; - val |= WINCONx_BURSTLEN_8WORD; - break; - case 8: - val |= WINCON0_BPPMODE_8BPP_PALETTE; - val |= WINCONx_BURSTLEN_8WORD; - val |= WINCONx_BYTSWP; - break; - case 16: - val |= WINCON0_BPPMODE_16BPP_565; - val |= WINCONx_HAWSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - case 24: - val |= WINCON0_BPPMODE_24BPP_888; - val |= WINCONx_WSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - case 32: - val |= WINCON1_BPPMODE_28BPP_A4888 - | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; - val |= WINCONx_WSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - default: - DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n"); - - val |= WINCON0_BPPMODE_24BPP_888; - val |= WINCONx_WSWP; - val |= WINCONx_BURSTLEN_16WORD; - break; - } - - DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp); - - writel(val, ctx->regs + WINCON(win)); -} - -static void fimd_win_set_colkey(struct device *dev, unsigned int win) -{ - struct fimd_context *ctx = get_fimd_context(dev); - unsigned int keycon0 = 0, keycon1 = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | - WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); - - keycon1 = WxKEYCON1_COLVAL(0xffffffff); - - writel(keycon0, ctx->regs + WKEYCON0_BASE(win)); - writel(keycon1, ctx->regs + WKEYCON1_BASE(win)); -} - -static void fimd_win_commit(struct device *dev, int zpos) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data; - int win = zpos; - unsigned long val, alpha, size; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - - /* - * SHADOWCON register is used for enabling timing. - * - * for example, once only width value of a register is set, - * if the dma is started then fimd hardware could malfunction so - * with protect window setting, the register fields with prefix '_F' - * wouldn't be updated at vsync also but updated once unprotect window - * is set. - */ - - /* protect windows */ - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - /* buffer start address */ - val = (unsigned long)win_data->dma_addr; - writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); - - /* buffer end address */ - size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3); - val = (unsigned long)(win_data->dma_addr + size); - writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); - - DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", - (unsigned long)win_data->dma_addr, val, size); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - - /* buffer size */ - val = VIDW_BUF_SIZE_OFFSET(win_data->buf_offsize) | - VIDW_BUF_SIZE_PAGEWIDTH(win_data->line_size); - writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); - - /* OSD position */ - val = VIDOSDxA_TOPLEFT_X(win_data->offset_x) | - VIDOSDxA_TOPLEFT_Y(win_data->offset_y); - writel(val, ctx->regs + VIDOSD_A(win)); - - val = VIDOSDxB_BOTRIGHT_X(win_data->offset_x + - win_data->ovl_width - 1) | - VIDOSDxB_BOTRIGHT_Y(win_data->offset_y + - win_data->ovl_height - 1); - writel(val, ctx->regs + VIDOSD_B(win)); - - DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", - win_data->offset_x, win_data->offset_y, - win_data->offset_x + win_data->ovl_width - 1, - win_data->offset_y + win_data->ovl_height - 1); - - /* hardware window 0 doesn't support alpha channel. */ - if (win != 0) { - /* OSD alpha */ - alpha = VIDISD14C_ALPHA1_R(0xf) | - VIDISD14C_ALPHA1_G(0xf) | - VIDISD14C_ALPHA1_B(0xf); - - writel(alpha, ctx->regs + VIDOSD_C(win)); - } - - /* OSD size */ - if (win != 3 && win != 4) { - u32 offset = VIDOSD_D(win); - if (win == 0) - offset = VIDOSD_C_SIZE_W0; - val = win_data->ovl_width * win_data->ovl_height; - writel(val, ctx->regs + offset); - - DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); - } - - fimd_win_set_pixfmt(dev, win); - - /* hardware window 0 doesn't support color key. */ - if (win != 0) - fimd_win_set_colkey(dev, win); - - /* wincon */ - val = readl(ctx->regs + WINCON(win)); - val |= WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); - - /* Enable DMA channel and unprotect windows */ - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_CHx_ENABLE(win); - val &= ~SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - win_data->enabled = true; -} - -static void fimd_win_disable(struct device *dev, int zpos) -{ - struct fimd_context *ctx = get_fimd_context(dev); - struct fimd_win_data *win_data; - int win = zpos; - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - - /* protect windows */ - val = readl(ctx->regs + SHADOWCON); - val |= SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - /* wincon */ - val = readl(ctx->regs + WINCON(win)); - val &= ~WINCONx_ENWIN; - writel(val, ctx->regs + WINCON(win)); - - /* unprotect windows */ - val = readl(ctx->regs + SHADOWCON); - val &= ~SHADOWCON_CHx_ENABLE(win); - val &= ~SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); - - win_data->enabled = false; -} - -static struct exynos_drm_overlay_ops fimd_overlay_ops = { - .mode_set = fimd_win_mode_set, - .commit = fimd_win_commit, - .disable = fimd_win_disable, -}; - -static struct exynos_drm_manager fimd_manager = { - .pipe = -1, - .ops = &fimd_manager_ops, - .overlay_ops = &fimd_overlay_ops, - .display_ops = &fimd_display_ops, -}; - -static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) -{ - struct exynos_drm_private *dev_priv = drm_dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - bool is_checked = false; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - is_checked = true; - - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - if (is_checked) { - /* - * call drm_vblank_put only in case that drm_vblank_get was - * called. - */ - if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) - drm_vblank_put(drm_dev, crtc); - - /* - * don't off vblank if vblank_disable_allowed is 1, - * because vblank would be off by timer handler. - */ - if (!drm_dev->vblank_disable_allowed) - drm_vblank_off(drm_dev, crtc); - } - - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static irqreturn_t fimd_irq_handler(int irq, void *dev_id) -{ - struct fimd_context *ctx = (struct fimd_context *)dev_id; - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct drm_device *drm_dev = subdrv->drm_dev; - struct exynos_drm_manager *manager = subdrv->manager; - u32 val; - - val = readl(ctx->regs + VIDINTCON1); - - if (val & VIDINTCON1_INT_FRAME) - /* VSYNC interrupt */ - writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1); - - /* check the crtc is detached already from encoder */ - if (manager->pipe < 0) - goto out; - - drm_handle_vblank(drm_dev, manager->pipe); - fimd_finish_pageflip(drm_dev, manager->pipe); - -out: - return IRQ_HANDLED; -} - -static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * enable drm irq mode. - * - with irq_enabled = 1, we can use the vblank feature. - * - * P.S. note that we wouldn't use drm irq handler but - * just specific driver own one instead because - * drm framework supports only one irq handler. - */ - drm_dev->irq_enabled = 1; - - /* - * with vblank_disable_allowed = 1, vblank interrupt will be disabled - * by drm timer once a current process gives up ownership of - * vblank event.(after drm_vblank_put function is called) - */ - drm_dev->vblank_disable_allowed = 1; - - return 0; -} - -static void fimd_subdrv_remove(struct drm_device *drm_dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ -} - -static int fimd_calc_clkdiv(struct fimd_context *ctx, - struct fb_videomode *timing) -{ - unsigned long clk = clk_get_rate(ctx->lcd_clk); - u32 retrace; - u32 clkdiv; - u32 best_framerate = 0; - u32 framerate; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - retrace = timing->left_margin + timing->hsync_len + - timing->right_margin + timing->xres; - retrace *= timing->upper_margin + timing->vsync_len + - timing->lower_margin + timing->yres; - - /* default framerate is 60Hz */ - if (!timing->refresh) - timing->refresh = 60; - - clk /= retrace; - - for (clkdiv = 1; clkdiv < 0x100; clkdiv++) { - int tmp; - - /* get best framerate */ - framerate = clk / clkdiv; - tmp = timing->refresh - framerate; - if (tmp < 0) { - best_framerate = framerate; - continue; - } else { - if (!best_framerate) - best_framerate = framerate; - else if (tmp < (best_framerate - framerate)) - best_framerate = framerate; - break; - } - } - - return clkdiv; -} - -static void fimd_clear_win(struct fimd_context *ctx, int win) -{ - u32 val; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - writel(0, ctx->regs + WINCON(win)); - writel(0, ctx->regs + VIDOSD_A(win)); - writel(0, ctx->regs + VIDOSD_B(win)); - writel(0, ctx->regs + VIDOSD_C(win)); - - if (win == 1 || win == 2) - writel(0, ctx->regs + VIDOSD_D(win)); - - val = readl(ctx->regs + SHADOWCON); - val &= ~SHADOWCON_WINx_PROTECT(win); - writel(val, ctx->regs + SHADOWCON); -} - -static int fimd_power_on(struct fimd_context *ctx, bool enable) -{ - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - int ret; - - ret = clk_enable(ctx->bus_clk); - if (ret < 0) - return ret; - - ret = clk_enable(ctx->lcd_clk); - if (ret < 0) { - clk_disable(ctx->bus_clk); - return ret; - } - - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - fimd_enable_vblank(dev); - - fimd_apply(dev); - } else { - clk_disable(ctx->lcd_clk); - clk_disable(ctx->bus_clk); - - ctx->suspended = true; - } - - return 0; -} - -static int __devinit fimd_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct fimd_context *ctx; - struct exynos_drm_subdrv *subdrv; - struct exynos_drm_fimd_pdata *pdata; - struct exynos_drm_panel_info *panel; - struct resource *res; - int win; - int ret = -EINVAL; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(dev, "no platform data specified\n"); - return -EINVAL; - } - - panel = &pdata->panel; - if (!panel) { - dev_err(dev, "panel is null.\n"); - return -EINVAL; - } - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->bus_clk = clk_get(dev, "fimd"); - if (IS_ERR(ctx->bus_clk)) { - dev_err(dev, "failed to get bus clock\n"); - ret = PTR_ERR(ctx->bus_clk); - goto err_clk_get; - } - - ctx->lcd_clk = clk_get(dev, "sclk_fimd"); - if (IS_ERR(ctx->lcd_clk)) { - dev_err(dev, "failed to get lcd clock\n"); - ret = PTR_ERR(ctx->lcd_clk); - goto err_bus_clk; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "failed to find registers\n"); - ret = -ENOENT; - goto err_clk; - } - - ctx->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!ctx->regs_res) { - dev_err(dev, "failed to claim register region\n"); - ret = -ENOENT; - goto err_clk; - } - - ctx->regs = ioremap(res->start, resource_size(res)); - if (!ctx->regs) { - dev_err(dev, "failed to map registers\n"); - ret = -ENXIO; - goto err_req_region_io; - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "irq request failed.\n"); - goto err_req_region_irq; - } - - ctx->irq = res->start; - - ret = request_irq(ctx->irq, fimd_irq_handler, 0, "drm_fimd", ctx); - if (ret < 0) { - dev_err(dev, "irq request failed.\n"); - goto err_req_irq; - } - - ctx->vidcon0 = pdata->vidcon0; - ctx->vidcon1 = pdata->vidcon1; - ctx->default_win = pdata->default_win; - ctx->panel = panel; - - subdrv = &ctx->subdrv; - - subdrv->dev = dev; - subdrv->manager = &fimd_manager; - subdrv->probe = fimd_subdrv_probe; - subdrv->remove = fimd_subdrv_remove; - - mutex_init(&ctx->lock); - - platform_set_drvdata(pdev, ctx); - - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - - ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); - panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; - - DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", - panel->timing.pixclock, ctx->clkdiv); - - for (win = 0; win < WINDOWS_NR; win++) - fimd_clear_win(ctx, win); - - exynos_drm_subdrv_register(subdrv); - - return 0; - -err_req_irq: -err_req_region_irq: - iounmap(ctx->regs); - -err_req_region_io: - release_resource(ctx->regs_res); - kfree(ctx->regs_res); - -err_clk: - clk_disable(ctx->lcd_clk); - clk_put(ctx->lcd_clk); - -err_bus_clk: - clk_disable(ctx->bus_clk); - clk_put(ctx->bus_clk); - -err_clk_get: - kfree(ctx); - return ret; -} - -static int __devexit fimd_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct fimd_context *ctx = platform_get_drvdata(pdev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_subdrv_unregister(&ctx->subdrv); - - if (ctx->suspended) - goto out; - - clk_disable(ctx->lcd_clk); - clk_disable(ctx->bus_clk); - - pm_runtime_set_suspended(dev); - pm_runtime_put_sync(dev); - -out: - pm_runtime_disable(dev); - - clk_put(ctx->lcd_clk); - clk_put(ctx->bus_clk); - - iounmap(ctx->regs); - release_resource(ctx->regs_res); - kfree(ctx->regs_res); - free_irq(ctx->irq, ctx); - - kfree(ctx); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int fimd_suspend(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - if (pm_runtime_suspended(dev)) - return 0; - - /* - * do not use pm_runtime_suspend(). if pm_runtime_suspend() is - * called here, an error would be returned by that interface - * because the usage_count of pm runtime is more than 1. - */ - return fimd_power_on(ctx, false); -} - -static int fimd_resume(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - /* - * if entered to sleep when lcd panel was on, the usage_count - * of pm runtime would still be 1 so in this case, fimd driver - * should be on directly not drawing on pm runtime interface. - */ - if (!pm_runtime_suspended(dev)) - return fimd_power_on(ctx, true); - - return 0; -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int fimd_runtime_suspend(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return fimd_power_on(ctx, false); -} - -static int fimd_runtime_resume(struct device *dev) -{ - struct fimd_context *ctx = get_fimd_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - return fimd_power_on(ctx, true); -} -#endif - -static const struct dev_pm_ops fimd_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) - SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) -}; - -struct platform_driver fimd_driver = { - .probe = fimd_probe, - .remove = __devexit_p(fimd_remove), - .driver = { - .name = "exynos4-fb", - .owner = THIS_MODULE, - .pm = &fimd_pm_ops, - }, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.c deleted file mode 100644 index 1dffa835..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ /dev/null @@ -1,742 +0,0 @@ -/* exynos_drm_gem.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Author: Inki Dae - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" - -#include -#include - -#include "exynos_drm_drv.h" -#include "exynos_drm_gem.h" -#include "exynos_drm_buf.h" - -static unsigned int convert_to_vm_err_msg(int msg) -{ - unsigned int out_msg; - - switch (msg) { - case 0: - case -ERESTARTSYS: - case -EINTR: - out_msg = VM_FAULT_NOPAGE; - break; - - case -ENOMEM: - out_msg = VM_FAULT_OOM; - break; - - default: - out_msg = VM_FAULT_SIGBUS; - break; - } - - return out_msg; -} - -static int check_gem_flags(unsigned int flags) -{ - if (flags & ~(EXYNOS_BO_MASK)) { - DRM_ERROR("invalid flags.\n"); - return -EINVAL; - } - - return 0; -} - -static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) -{ - if (!IS_NONCONTIG_BUFFER(flags)) { - if (size >= SZ_1M) - return roundup(size, SECTION_SIZE); - else if (size >= SZ_64K) - return roundup(size, SZ_64K); - else - goto out; - } -out: - return roundup(size, PAGE_SIZE); -} - -static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, - gfp_t gfpmask) -{ - struct inode *inode; - struct address_space *mapping; - struct page *p, **pages; - int i, npages; - - /* This is the shared memory object that backs the GEM resource */ - inode = obj->filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - - npages = obj->size >> PAGE_SHIFT; - - pages = drm_malloc_ab(npages, sizeof(struct page *)); - if (pages == NULL) - return ERR_PTR(-ENOMEM); - - gfpmask |= mapping_gfp_mask(mapping); - - for (i = 0; i < npages; i++) { - p = shmem_read_mapping_page_gfp(mapping, i, gfpmask); - if (IS_ERR(p)) - goto fail; - pages[i] = p; - } - - return pages; - -fail: - while (i--) - page_cache_release(pages[i]); - - drm_free_large(pages); - return ERR_PTR(PTR_ERR(p)); -} - -static void exynos_gem_put_pages(struct drm_gem_object *obj, - struct page **pages, - bool dirty, bool accessed) -{ - int i, npages; - - npages = obj->size >> PAGE_SHIFT; - - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } - - drm_free_large(pages); -} - -static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, - struct vm_area_struct *vma, - unsigned long f_vaddr, - pgoff_t page_offset) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - unsigned long pfn; - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - if (!buf->pages) - return -EINTR; - - pfn = page_to_pfn(buf->pages[page_offset++]); - } else - pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; - - return vm_insert_mixed(vma, f_vaddr, pfn); -} - -static int exynos_drm_gem_get_pages(struct drm_gem_object *obj) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - struct scatterlist *sgl; - struct page **pages; - unsigned int npages, i = 0; - int ret; - - if (buf->pages) { - DRM_DEBUG_KMS("already allocated.\n"); - return -EINVAL; - } - - pages = exynos_gem_get_pages(obj, GFP_KERNEL); - if (IS_ERR(pages)) { - DRM_ERROR("failed to get pages.\n"); - return PTR_ERR(pages); - } - - npages = obj->size >> PAGE_SHIFT; - - buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!buf->sgt) { - DRM_ERROR("failed to allocate sg table.\n"); - ret = -ENOMEM; - goto err; - } - - ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL); - if (ret < 0) { - DRM_ERROR("failed to initialize sg table.\n"); - ret = -EFAULT; - goto err1; - } - - sgl = buf->sgt->sgl; - - /* set all pages to sg list. */ - while (i < npages) { - sg_set_page(sgl, pages[i], PAGE_SIZE, 0); - sg_dma_address(sgl) = page_to_phys(pages[i]); - i++; - sgl = sg_next(sgl); - } - - /* add some codes for UNCACHED type here. TODO */ - - buf->pages = pages; - return ret; -err1: - kfree(buf->sgt); - buf->sgt = NULL; -err: - exynos_gem_put_pages(obj, pages, true, false); - return ret; - -} - -static void exynos_drm_gem_put_pages(struct drm_gem_object *obj) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; - - /* - * if buffer typs is EXYNOS_BO_NONCONTIG then release all pages - * allocated at gem fault handler. - */ - sg_free_table(buf->sgt); - kfree(buf->sgt); - buf->sgt = NULL; - - exynos_gem_put_pages(obj, buf->pages, true, false); - buf->pages = NULL; - - /* add some codes for UNCACHED type here. TODO */ -} - -static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, - struct drm_file *file_priv, - unsigned int *handle) -{ - int ret; - - /* - * allocate a id of idr table where the obj is registered - * and handle has the id what user can see. - */ - ret = drm_gem_handle_create(file_priv, obj, handle); - if (ret) - return ret; - - DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle); - - /* drop reference from allocate - handle holds it now. */ - drm_gem_object_unreference_unlocked(obj); - - return 0; -} - -void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj) -{ - struct drm_gem_object *obj; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!exynos_gem_obj) - return; - - obj = &exynos_gem_obj->base; - - DRM_DEBUG_KMS("handle count = %d\n", atomic_read(&obj->handle_count)); - - if ((exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) && - exynos_gem_obj->buffer->pages) - exynos_drm_gem_put_pages(obj); - else - exynos_drm_free_buf(obj->dev, exynos_gem_obj->flags, - exynos_gem_obj->buffer); - - exynos_drm_fini_buf(obj->dev, exynos_gem_obj->buffer); - exynos_gem_obj->buffer = NULL; - - if (obj->map_list.map) - drm_gem_free_mmap_offset(obj); - - /* release file pointer to gem object. */ - drm_gem_object_release(obj); - - kfree(exynos_gem_obj); - exynos_gem_obj = NULL; -} - -static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, - unsigned long size) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - int ret; - - exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); - if (!exynos_gem_obj) { - DRM_ERROR("failed to allocate exynos gem object\n"); - return NULL; - } - - exynos_gem_obj->size = size; - obj = &exynos_gem_obj->base; - - ret = drm_gem_object_init(dev, obj, size); - if (ret < 0) { - DRM_ERROR("failed to initialize gem object\n"); - kfree(exynos_gem_obj); - return NULL; - } - - DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp); - - return exynos_gem_obj; -} - -struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, - unsigned int flags, - unsigned long size) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct exynos_drm_gem_buf *buf; - int ret; - - if (!size) { - DRM_ERROR("invalid size.\n"); - return ERR_PTR(-EINVAL); - } - - size = roundup_gem_size(size, flags); - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = check_gem_flags(flags); - if (ret) - return ERR_PTR(ret); - - buf = exynos_drm_init_buf(dev, size); - if (!buf) - return ERR_PTR(-ENOMEM); - - exynos_gem_obj = exynos_drm_gem_init(dev, size); - if (!exynos_gem_obj) { - ret = -ENOMEM; - goto err_fini_buf; - } - - exynos_gem_obj->buffer = buf; - - /* set memory type and cache attribute from user side. */ - exynos_gem_obj->flags = flags; - - /* - * allocate all pages as desired size if user wants to allocate - * physically non-continuous memory. - */ - if (flags & EXYNOS_BO_NONCONTIG) { - ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); - if (ret < 0) { - drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; - } - } else { - ret = exynos_drm_alloc_buf(dev, buf, flags); - if (ret < 0) { - drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; - } - } - - return exynos_gem_obj; - -err_fini_buf: - exynos_drm_fini_buf(dev, buf); - return ERR_PTR(ret); -} - -int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_create *args = data; - struct exynos_drm_gem_obj *exynos_gem_obj; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); - if (IS_ERR(exynos_gem_obj)) - return PTR_ERR(exynos_gem_obj); - - ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, - &args->handle); - if (ret) { - exynos_drm_gem_destroy(exynos_gem_obj); - return ret; - } - - return 0; -} - -void *exynos_drm_gem_get_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return ERR_PTR(-EINVAL); - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - DRM_DEBUG_KMS("not support NONCONTIG type.\n"); - drm_gem_object_unreference_unlocked(obj); - - /* TODO */ - return ERR_PTR(-EINVAL); - } - - return &exynos_gem_obj->buffer->dma_addr; -} - -void exynos_drm_gem_put_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - - obj = drm_gem_object_lookup(dev, file_priv, gem_handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - DRM_DEBUG_KMS("not support NONCONTIG type.\n"); - drm_gem_object_unreference_unlocked(obj); - - /* TODO */ - return; - } - - drm_gem_object_unreference_unlocked(obj); - - /* - * decrease obj->refcount one more time because we has already - * increased it at exynos_drm_gem_get_dma_addr(). - */ - drm_gem_object_unreference_unlocked(obj); -} - -int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_map_off *args = data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - DRM_DEBUG_KMS("handle = 0x%x, offset = 0x%lx\n", - args->handle, (unsigned long)args->offset); - - if (!(dev->driver->driver_features & DRIVER_GEM)) { - DRM_ERROR("does not support GEM.\n"); - return -ENODEV; - } - - return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle, - &args->offset); -} - -static int exynos_drm_gem_mmap_buffer(struct file *filp, - struct vm_area_struct *vma) -{ - struct drm_gem_object *obj = filp->private_data; - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - struct exynos_drm_gem_buf *buffer; - unsigned long pfn, vm_size, usize, uaddr = vma->vm_start; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - vma->vm_flags |= (VM_IO | VM_RESERVED); - - /* in case of direct mapping, always having non-cachable attribute */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - vm_size = usize = vma->vm_end - vma->vm_start; - - /* - * a buffer contains information to physically continuous memory - * allocated by user request or at framebuffer creation. - */ - buffer = exynos_gem_obj->buffer; - - /* check if user-requested size is valid. */ - if (vm_size > buffer->size) - return -EINVAL; - - if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { - int i = 0; - - if (!buffer->pages) - return -EINVAL; - - vma->vm_flags |= VM_MIXEDMAP; - - do { - ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); - if (ret) { - DRM_ERROR("failed to remap user space.\n"); - return ret; - } - - uaddr += PAGE_SIZE; - usize -= PAGE_SIZE; - } while (usize > 0); - } else { - /* - * get page frame number to physical memory to be mapped - * to user space. - */ - pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> - PAGE_SHIFT; - - DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); - - if (remap_pfn_range(vma, vma->vm_start, pfn, vm_size, - vma->vm_page_prot)) { - DRM_ERROR("failed to remap pfn range.\n"); - return -EAGAIN; - } - } - - return 0; -} - -static const struct file_operations exynos_drm_gem_fops = { - .mmap = exynos_drm_gem_mmap_buffer, -}; - -int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_gem_mmap *args = data; - struct drm_gem_object *obj; - unsigned int addr; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!(dev->driver->driver_features & DRIVER_GEM)) { - DRM_ERROR("does not support GEM.\n"); - return -ENODEV; - } - - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - return -EINVAL; - } - - obj->filp->f_op = &exynos_drm_gem_fops; - obj->filp->private_data = obj; - - addr = vm_mmap(obj->filp, 0, args->size, - PROT_READ | PROT_WRITE, MAP_SHARED, 0); - - drm_gem_object_unreference_unlocked(obj); - - if (IS_ERR((void *)addr)) - return PTR_ERR((void *)addr); - - args->mapped = addr; - - DRM_DEBUG_KMS("mapped = 0x%lx\n", (unsigned long)args->mapped); - - return 0; -} - -int exynos_drm_gem_init_object(struct drm_gem_object *obj) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - return 0; -} - -void exynos_drm_gem_free_object(struct drm_gem_object *obj) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_gem_destroy(to_exynos_gem_obj(obj)); -} - -int exynos_drm_gem_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * alocate memory to be used for framebuffer. - * - this callback would be called by user application - * with DRM_IOCTL_MODE_CREATE_DUMB command. - */ - - args->pitch = args->width * args->bpp >> 3; - args->size = PAGE_ALIGN(args->pitch * args->height); - - exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); - if (IS_ERR(exynos_gem_obj)) - return PTR_ERR(exynos_gem_obj); - - ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, - &args->handle); - if (ret) { - exynos_drm_gem_destroy(exynos_gem_obj); - return ret; - } - - return 0; -} - -int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset) -{ - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_gem_object *obj; - int ret = 0; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - mutex_lock(&dev->struct_mutex); - - /* - * get offset of memory allocated for drm framebuffer. - * - this callback would be called by user application - * with DRM_IOCTL_MODE_MAP_DUMB command. - */ - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); - ret = -EINVAL; - goto unlock; - } - - exynos_gem_obj = to_exynos_gem_obj(obj); - - if (!exynos_gem_obj->base.map_list.map) { - ret = drm_gem_create_mmap_offset(&exynos_gem_obj->base); - if (ret) - goto out; - } - - *offset = (u64)exynos_gem_obj->base.map_list.hash.key << PAGE_SHIFT; - DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); - -out: - drm_gem_object_unreference(obj); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - unsigned int handle) -{ - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * obj->refcount and obj->handle_count are decreased and - * if both them are 0 then exynos_drm_gem_free_object() - * would be called by callback to release resources. - */ - ret = drm_gem_handle_delete(file_priv, handle); - if (ret < 0) { - DRM_ERROR("failed to delete drm_gem_handle.\n"); - return ret; - } - - return 0; -} - -int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_gem_object *obj = vma->vm_private_data; - struct drm_device *dev = obj->dev; - unsigned long f_vaddr; - pgoff_t page_offset; - int ret; - - page_offset = ((unsigned long)vmf->virtual_address - - vma->vm_start) >> PAGE_SHIFT; - f_vaddr = (unsigned long)vmf->virtual_address; - - mutex_lock(&dev->struct_mutex); - - ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); - if (ret < 0) - DRM_ERROR("failed to map pages.\n"); - - mutex_unlock(&dev->struct_mutex); - - return convert_to_vm_err_msg(ret); -} - -int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* set vm_area_struct. */ - ret = drm_gem_mmap(filp, vma); - if (ret < 0) { - DRM_ERROR("failed to mmap.\n"); - return ret; - } - - vma->vm_flags &= ~VM_PFNMAP; - vma->vm_flags |= VM_MIXEDMAP; - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.h deleted file mode 100644 index 4ed84203..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ /dev/null @@ -1,153 +0,0 @@ -/* exynos_drm_gem.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authoer: Inki Dae - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_GEM_H_ -#define _EXYNOS_DRM_GEM_H_ - -#define to_exynos_gem_obj(x) container_of(x,\ - struct exynos_drm_gem_obj, base) - -#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) - -/* - * exynos drm gem buffer structure. - * - * @kvaddr: kernel virtual address to allocated memory region. - * @dma_addr: bus address(accessed by dma) to allocated memory region. - * - this address could be physical address without IOMMU and - * device address with IOMMU. - * @sgt: sg table to transfer page data. - * @pages: contain all pages to allocated memory region. - * @size: size of allocated memory region. - */ -struct exynos_drm_gem_buf { - void __iomem *kvaddr; - dma_addr_t dma_addr; - struct sg_table *sgt; - struct page **pages; - unsigned long size; -}; - -/* - * exynos drm buffer structure. - * - * @base: a gem object. - * - a new handle to this gem object would be created - * by drm_gem_handle_create(). - * @buffer: a pointer to exynos_drm_gem_buffer object. - * - contain the information to memory region allocated - * by user request or at framebuffer creation. - * continuous memory region allocated by user request - * or at framebuffer creation. - * @size: total memory size to physically non-continuous memory region. - * @flags: indicate memory type to allocated buffer and cache attruibute. - * - * P.S. this object would be transfered to user as kms_bo.handle so - * user can access the buffer through kms_bo.handle. - */ -struct exynos_drm_gem_obj { - struct drm_gem_object base; - struct exynos_drm_gem_buf *buffer; - unsigned long size; - unsigned int flags; -}; - -/* destroy a buffer with gem object */ -void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj); - -/* create a new buffer with gem object */ -struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, - unsigned int flags, - unsigned long size); - -/* - * request gem object creation and buffer allocation as the size - * that it is calculated with framebuffer information such as width, - * height and bpp. - */ -int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* - * get dma address from gem handle and this function could be used for - * other drivers such as 2d/3d acceleration drivers. - * with this function call, gem object reference count would be increased. - */ -void *exynos_drm_gem_get_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv); - -/* - * put dma address from gem handle and this function could be used for - * other drivers such as 2d/3d acceleration drivers. - * with this function call, gem object reference count would be decreased. - */ -void exynos_drm_gem_put_dma_addr(struct drm_device *dev, - unsigned int gem_handle, - struct drm_file *file_priv); - -/* get buffer offset to map to user space. */ -int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* - * mmap the physically continuous memory that a gem object contains - * to user space. - */ -int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -/* initialize gem object. */ -int exynos_drm_gem_init_object(struct drm_gem_object *obj); - -/* free gem object. */ -void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj); - -/* create memory region for drm framebuffer. */ -int exynos_drm_gem_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); - -/* map memory region for drm framebuffer to user space. */ -int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, uint32_t handle, - uint64_t *offset); - -/* - * destroy memory region allocated. - * - a gem handle and physical memory region pointed by a gem object - * would be released by drm_gem_handle_delete(). - */ -int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - unsigned int handle); - -/* page fault handler and mmap fault address(virtual) to physical memory. */ -int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); - -/* set vm_flags and we can change the vm attribute to other one at here. */ -int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.c deleted file mode 100644 index 34244636..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Inki Dae - * Seung-Woo Kim - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include "drmP.h" - -#include -#include -#include -#include -#include - -#include - -#include "exynos_drm_drv.h" -#include "exynos_drm_hdmi.h" - -#define to_context(dev) platform_get_drvdata(to_platform_device(dev)) -#define to_subdrv(dev) to_context(dev) -#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\ - struct drm_hdmi_context, subdrv); - -/* these callback points shoud be set by specific drivers. */ -static struct exynos_hdmi_ops *hdmi_ops; -static struct exynos_mixer_ops *mixer_ops; - -struct drm_hdmi_context { - struct exynos_drm_subdrv subdrv; - struct exynos_drm_hdmi_context *hdmi_ctx; - struct exynos_drm_hdmi_context *mixer_ctx; -}; - -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ops) - hdmi_ops = ops; -} - -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ops) - mixer_ops = ops; -} - -static bool drm_hdmi_is_connected(struct device *dev) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->is_connected) - return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); - - return false; -} - -static int drm_hdmi_get_edid(struct device *dev, - struct drm_connector *connector, u8 *edid, int len) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->get_edid) - return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, - len); - - return 0; -} - -static int drm_hdmi_check_timing(struct device *dev, void *timing) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->check_timing) - return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); - - return 0; -} - -static int drm_hdmi_power_on(struct device *dev, int mode) -{ - struct drm_hdmi_context *ctx = to_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->power_on) - return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); - - return 0; -} - -static struct exynos_drm_display_ops drm_hdmi_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_HDMI, - .is_connected = drm_hdmi_is_connected, - .get_edid = drm_hdmi_get_edid, - .check_timing = drm_hdmi_check_timing, - .power_on = drm_hdmi_power_on, -}; - -static int drm_hdmi_enable_vblank(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->enable_vblank) - return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, - manager->pipe); - - return 0; -} - -static void drm_hdmi_disable_vblank(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->disable_vblank) - return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); -} - -static void drm_hdmi_mode_fixup(struct device *subdrv_dev, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->mode_fixup) - hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, - adjusted_mode); -} - -static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->mode_set) - hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); -} - -static void drm_hdmi_get_max_resol(struct device *subdrv_dev, - unsigned int *width, unsigned int *height) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->get_max_resol) - hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); -} - -static void drm_hdmi_commit(struct device *subdrv_dev) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (hdmi_ops && hdmi_ops->commit) - hdmi_ops->commit(ctx->hdmi_ctx->ctx); -} - -static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - switch (mode) { - case DRM_MODE_DPMS_ON: - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (hdmi_ops && hdmi_ops->disable) - hdmi_ops->disable(ctx->hdmi_ctx->ctx); - break; - default: - DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); - break; - } -} - -static struct exynos_drm_manager_ops drm_hdmi_manager_ops = { - .dpms = drm_hdmi_dpms, - .enable_vblank = drm_hdmi_enable_vblank, - .disable_vblank = drm_hdmi_disable_vblank, - .mode_fixup = drm_hdmi_mode_fixup, - .mode_set = drm_hdmi_mode_set, - .get_max_resol = drm_hdmi_get_max_resol, - .commit = drm_hdmi_commit, -}; - -static void drm_mixer_mode_set(struct device *subdrv_dev, - struct exynos_drm_overlay *overlay) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->win_mode_set) - mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); -} - -static void drm_mixer_commit(struct device *subdrv_dev, int zpos) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->win_commit) - mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); -} - -static void drm_mixer_disable(struct device *subdrv_dev, int zpos) -{ - struct drm_hdmi_context *ctx = to_context(subdrv_dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (mixer_ops && mixer_ops->win_disable) - mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); -} - -static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { - .mode_set = drm_mixer_mode_set, - .commit = drm_mixer_commit, - .disable = drm_mixer_disable, -}; - -static struct exynos_drm_manager hdmi_manager = { - .pipe = -1, - .ops = &drm_hdmi_manager_ops, - .overlay_ops = &drm_hdmi_overlay_ops, - .display_ops = &drm_hdmi_display_ops, -}; - -static int hdmi_subdrv_probe(struct drm_device *drm_dev, - struct device *dev) -{ - struct exynos_drm_subdrv *subdrv = to_subdrv(dev); - struct drm_hdmi_context *ctx; - struct platform_device *pdev = to_platform_device(dev); - struct exynos_drm_common_hdmi_pd *pd; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - pd = pdev->dev.platform_data; - - if (!pd) { - DRM_DEBUG_KMS("platform data is null.\n"); - return -EFAULT; - } - - if (!pd->hdmi_dev) { - DRM_DEBUG_KMS("hdmi device is null.\n"); - return -EFAULT; - } - - if (!pd->mixer_dev) { - DRM_DEBUG_KMS("mixer device is null.\n"); - return -EFAULT; - } - - ctx = get_ctx_from_subdrv(subdrv); - - ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *) - to_context(pd->hdmi_dev); - if (!ctx->hdmi_ctx) { - DRM_DEBUG_KMS("hdmi context is null.\n"); - return -EFAULT; - } - - ctx->hdmi_ctx->drm_dev = drm_dev; - - ctx->mixer_ctx = (struct exynos_drm_hdmi_context *) - to_context(pd->mixer_dev); - if (!ctx->mixer_ctx) { - DRM_DEBUG_KMS("mixer context is null.\n"); - return -EFAULT; - } - - ctx->mixer_ctx->drm_dev = drm_dev; - - return 0; -} - -static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_subdrv *subdrv; - struct drm_hdmi_context *ctx; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - DRM_LOG_KMS("failed to alloc common hdmi context.\n"); - return -ENOMEM; - } - - subdrv = &ctx->subdrv; - - subdrv->dev = dev; - subdrv->manager = &hdmi_manager; - subdrv->probe = hdmi_subdrv_probe; - - platform_set_drvdata(pdev, subdrv); - - exynos_drm_subdrv_register(subdrv); - - return 0; -} - -static int hdmi_runtime_suspend(struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - return 0; -} - -static int hdmi_runtime_resume(struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - return 0; -} - -static const struct dev_pm_ops hdmi_pm_ops = { - .runtime_suspend = hdmi_runtime_suspend, - .runtime_resume = hdmi_runtime_resume, -}; - -static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) -{ - struct drm_hdmi_context *ctx = platform_get_drvdata(pdev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_subdrv_unregister(&ctx->subdrv); - kfree(ctx); - - return 0; -} - -struct platform_driver exynos_drm_common_hdmi_driver = { - .probe = exynos_drm_hdmi_probe, - .remove = __devexit_p(exynos_drm_hdmi_remove), - .driver = { - .name = "exynos-drm-hdmi", - .owner = THIS_MODULE, - .pm = &hdmi_pm_ops, - }, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.h deleted file mode 100644 index f3ae192c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ /dev/null @@ -1,73 +0,0 @@ -/* exynos_drm_hdmi.h - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authoer: Inki Dae - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_HDMI_H_ -#define _EXYNOS_DRM_HDMI_H_ - -/* - * exynos hdmi common context structure. - * - * @drm_dev: pointer to drm_device. - * @ctx: pointer to the context of specific device driver. - * this context should be hdmi_context or mixer_context. - */ -struct exynos_drm_hdmi_context { - struct drm_device *drm_dev; - void *ctx; -}; - -struct exynos_hdmi_ops { - /* display */ - bool (*is_connected)(void *ctx); - int (*get_edid)(void *ctx, struct drm_connector *connector, - u8 *edid, int len); - int (*check_timing)(void *ctx, void *timing); - int (*power_on)(void *ctx, int mode); - - /* manager */ - void (*mode_fixup)(void *ctx, struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - void (*mode_set)(void *ctx, void *mode); - void (*get_max_resol)(void *ctx, unsigned int *width, - unsigned int *height); - void (*commit)(void *ctx); - void (*disable)(void *ctx); -}; - -struct exynos_mixer_ops { - /* manager */ - int (*enable_vblank)(void *ctx, int pipe); - void (*disable_vblank)(void *ctx); - - /* overlay */ - void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); - void (*win_commit)(void *ctx, int zpos); - void (*win_disable)(void *ctx, int zpos); -}; - -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.c deleted file mode 100644 index f92fe4c6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include "drmP.h" - -#include "exynos_drm.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_drv.h" -#include "exynos_drm_encoder.h" - -struct exynos_plane { - struct drm_plane base; - struct exynos_drm_overlay overlay; - bool enabled; -}; - -static const uint32_t formats[] = { - DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV12M, - DRM_FORMAT_NV12MT, -}; - -static int -exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) -{ - struct exynos_plane *exynos_plane = - container_of(plane, struct exynos_plane, base); - struct exynos_drm_overlay *overlay = &exynos_plane->overlay; - struct exynos_drm_crtc_pos pos; - unsigned int x = src_x >> 16; - unsigned int y = src_y >> 16; - int ret; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos)); - pos.crtc_x = crtc_x; - pos.crtc_y = crtc_y; - pos.crtc_w = crtc_w; - pos.crtc_h = crtc_h; - - pos.fb_x = x; - pos.fb_y = y; - - /* TODO: scale feature */ - ret = exynos_drm_overlay_update(overlay, fb, &crtc->mode, &pos); - if (ret < 0) - return ret; - - exynos_drm_fn_encoder(crtc, overlay, - exynos_drm_encoder_crtc_mode_set); - exynos_drm_fn_encoder(crtc, &overlay->zpos, - exynos_drm_encoder_crtc_plane_commit); - - exynos_plane->enabled = true; - - return 0; -} - -static int exynos_disable_plane(struct drm_plane *plane) -{ - struct exynos_plane *exynos_plane = - container_of(plane, struct exynos_plane, base); - struct exynos_drm_overlay *overlay = &exynos_plane->overlay; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!exynos_plane->enabled) - return 0; - - exynos_drm_fn_encoder(plane->crtc, &overlay->zpos, - exynos_drm_encoder_crtc_disable); - - exynos_plane->enabled = false; - exynos_plane->overlay.zpos = DEFAULT_ZPOS; - - return 0; -} - -static void exynos_plane_destroy(struct drm_plane *plane) -{ - struct exynos_plane *exynos_plane = - container_of(plane, struct exynos_plane, base); - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - exynos_disable_plane(plane); - drm_plane_cleanup(plane); - kfree(exynos_plane); -} - -static struct drm_plane_funcs exynos_plane_funcs = { - .update_plane = exynos_update_plane, - .disable_plane = exynos_disable_plane, - .destroy = exynos_plane_destroy, -}; - -int exynos_plane_init(struct drm_device *dev, unsigned int nr) -{ - struct exynos_plane *exynos_plane; - uint32_t possible_crtcs; - - exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL); - if (!exynos_plane) - return -ENOMEM; - - /* all CRTCs are available */ - possible_crtcs = (1 << MAX_CRTC) - 1; - - exynos_plane->overlay.zpos = DEFAULT_ZPOS; - - return drm_plane_init(dev, &exynos_plane->base, possible_crtcs, - &exynos_plane_funcs, formats, ARRAY_SIZE(formats), - false); -} - -int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_exynos_plane_set_zpos *zpos_req = data; - struct drm_mode_object *obj; - struct drm_plane *plane; - struct exynos_plane *exynos_plane; - int ret = 0; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return -EINVAL; - - if (zpos_req->zpos < 0 || zpos_req->zpos >= MAX_PLANE) { - if (zpos_req->zpos != DEFAULT_ZPOS) { - DRM_ERROR("zpos not within limits\n"); - return -EINVAL; - } - } - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, zpos_req->plane_id, - DRM_MODE_OBJECT_PLANE); - if (!obj) { - DRM_DEBUG_KMS("Unknown plane ID %d\n", - zpos_req->plane_id); - ret = -EINVAL; - goto out; - } - - plane = obj_to_plane(obj); - exynos_plane = container_of(plane, struct exynos_plane, base); - - exynos_plane->overlay.zpos = zpos_req->zpos; - -out: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.h deleted file mode 100644 index 16b71f82..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_plane.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: Joonyoung Shim - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -int exynos_plane_init(struct drm_device *dev, unsigned int nr); -int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.c deleted file mode 100644 index 7b9c153d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ /dev/null @@ -1,680 +0,0 @@ -/* exynos_drm_vidi.c - * - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Authors: - * Inki Dae - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ -#include "drmP.h" - -#include -#include -#include - -#include - -#include "drm_edid.h" -#include "drm_crtc_helper.h" - -#include "exynos_drm_drv.h" -#include "exynos_drm_crtc.h" -#include "exynos_drm_encoder.h" - -/* vidi has totally three virtual windows. */ -#define WINDOWS_NR 3 - -#define get_vidi_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct vidi_win_data { - unsigned int offset_x; - unsigned int offset_y; - unsigned int ovl_width; - unsigned int ovl_height; - unsigned int fb_width; - unsigned int fb_height; - unsigned int bpp; - dma_addr_t dma_addr; - void __iomem *vaddr; - unsigned int buf_offsize; - unsigned int line_size; /* bytes */ - bool enabled; -}; - -struct vidi_context { - struct exynos_drm_subdrv subdrv; - struct drm_crtc *crtc; - struct vidi_win_data win_data[WINDOWS_NR]; - struct edid *raw_edid; - unsigned int clkdiv; - unsigned int default_win; - unsigned long irq_flags; - unsigned int connected; - bool vblank_on; - bool suspended; - struct work_struct work; - struct mutex lock; -}; - -static const char fake_edid_info[] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78, - 0x0a, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0xbd, - 0xee, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x66, 0x21, 0x50, 0xb0, 0x51, 0x00, - 0x1b, 0x30, 0x40, 0x70, 0x36, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, - 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, - 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, - 0x4b, 0x1a, 0x44, 0x17, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xbc, 0x02, 0x03, 0x1e, 0xf1, - 0x46, 0x84, 0x05, 0x03, 0x10, 0x20, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83, - 0x01, 0x00, 0x00, 0xe2, 0x00, 0x0f, 0x67, 0x03, 0x0c, 0x00, 0x10, 0x00, - 0xb8, 0x2d, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, 0x16, 0x20, 0x58, 0x2c, - 0x25, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x9e, 0x8c, 0x0a, 0xd0, 0x8a, - 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xa0, 0x5a, 0x00, 0x00, - 0x00, 0x18, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, - 0x45, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06 -}; - -static void vidi_fake_vblank_handler(struct work_struct *work); - -static bool vidi_display_is_connected(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * connection request would come from user side - * to do hotplug through specific ioctl. - */ - return ctx->connected ? true : false; -} - -static int vidi_get_edid(struct device *dev, struct drm_connector *connector, - u8 *edid, int len) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct edid *raw_edid; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * the edid data comes from user side and it would be set - * to ctx->raw_edid through specific ioctl. - */ - if (!ctx->raw_edid) { - DRM_DEBUG_KMS("raw_edid is null.\n"); - return -EFAULT; - } - - raw_edid = kzalloc(len, GFP_KERNEL); - if (!raw_edid) { - DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); - return -ENOMEM; - } - - memcpy(raw_edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) - * EDID_LENGTH, len)); - - /* attach the edid data to connector. */ - connector->display_info.raw_edid = (char *)raw_edid; - - memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) - * EDID_LENGTH, len)); - - return 0; -} - -static void *vidi_get_panel(struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return NULL; -} - -static int vidi_check_timing(struct device *dev, void *timing) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ - - return 0; -} - -static int vidi_display_power_on(struct device *dev, int mode) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO */ - - return 0; -} - -static struct exynos_drm_display_ops vidi_display_ops = { - .type = EXYNOS_DISPLAY_TYPE_VIDI, - .is_connected = vidi_display_is_connected, - .get_edid = vidi_get_edid, - .get_panel = vidi_get_panel, - .check_timing = vidi_check_timing, - .power_on = vidi_display_power_on, -}; - -static void vidi_dpms(struct device *subdrv_dev, int mode) -{ - struct vidi_context *ctx = get_vidi_context(subdrv_dev); - - DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); - - mutex_lock(&ctx->lock); - - switch (mode) { - case DRM_MODE_DPMS_ON: - /* TODO. */ - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - /* TODO. */ - break; - default: - DRM_DEBUG_KMS("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&ctx->lock); -} - -static void vidi_apply(struct device *subdrv_dev) -{ - struct vidi_context *ctx = get_vidi_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; - struct exynos_drm_manager_ops *mgr_ops = mgr->ops; - struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; - struct vidi_win_data *win_data; - int i; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - for (i = 0; i < WINDOWS_NR; i++) { - win_data = &ctx->win_data[i]; - if (win_data->enabled && (ovl_ops && ovl_ops->commit)) - ovl_ops->commit(subdrv_dev, i); - } - - if (mgr_ops && mgr_ops->commit) - mgr_ops->commit(subdrv_dev); -} - -static void vidi_commit(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; -} - -static int vidi_enable_vblank(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return -EPERM; - - if (!test_and_set_bit(0, &ctx->irq_flags)) - ctx->vblank_on = true; - - return 0; -} - -static void vidi_disable_vblank(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (test_and_clear_bit(0, &ctx->irq_flags)) - ctx->vblank_on = false; -} - -static struct exynos_drm_manager_ops vidi_manager_ops = { - .dpms = vidi_dpms, - .apply = vidi_apply, - .commit = vidi_commit, - .enable_vblank = vidi_enable_vblank, - .disable_vblank = vidi_disable_vblank, -}; - -static void vidi_win_mode_set(struct device *dev, - struct exynos_drm_overlay *overlay) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct vidi_win_data *win_data; - int win; - unsigned long offset; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!overlay) { - dev_err(dev, "overlay is NULL\n"); - return; - } - - win = overlay->zpos; - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - offset = overlay->fb_x * (overlay->bpp >> 3); - offset += overlay->fb_y * overlay->pitch; - - DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); - - win_data = &ctx->win_data[win]; - - win_data->offset_x = overlay->crtc_x; - win_data->offset_y = overlay->crtc_y; - win_data->ovl_width = overlay->crtc_width; - win_data->ovl_height = overlay->crtc_height; - win_data->fb_width = overlay->fb_width; - win_data->fb_height = overlay->fb_height; - win_data->dma_addr = overlay->dma_addr[0] + offset; - win_data->vaddr = overlay->vaddr[0] + offset; - win_data->bpp = overlay->bpp; - win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * - (overlay->bpp >> 3); - win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); - - /* - * some parts of win_data should be transferred to user side - * through specific ioctl. - */ - - DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", - win_data->offset_x, win_data->offset_y); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n", - (unsigned long)win_data->dma_addr, - (unsigned long)win_data->vaddr); - DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", - overlay->fb_width, overlay->crtc_width); -} - -static void vidi_win_commit(struct device *dev, int zpos) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct vidi_win_data *win_data; - int win = zpos; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (ctx->suspended) - return; - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - - win_data->enabled = true; - - DRM_DEBUG_KMS("dma_addr = 0x%x\n", win_data->dma_addr); - - if (ctx->vblank_on) - schedule_work(&ctx->work); -} - -static void vidi_win_disable(struct device *dev, int zpos) -{ - struct vidi_context *ctx = get_vidi_context(dev); - struct vidi_win_data *win_data; - int win = zpos; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win > WINDOWS_NR) - return; - - win_data = &ctx->win_data[win]; - win_data->enabled = false; - - /* TODO. */ -} - -static struct exynos_drm_overlay_ops vidi_overlay_ops = { - .mode_set = vidi_win_mode_set, - .commit = vidi_win_commit, - .disable = vidi_win_disable, -}; - -static struct exynos_drm_manager vidi_manager = { - .pipe = -1, - .ops = &vidi_manager_ops, - .overlay_ops = &vidi_overlay_ops, - .display_ops = &vidi_display_ops, -}; - -static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) -{ - struct exynos_drm_private *dev_priv = drm_dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - bool is_checked = false; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - is_checked = true; - - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - if (is_checked) { - /* - * call drm_vblank_put only in case that drm_vblank_get was - * called. - */ - if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) - drm_vblank_put(drm_dev, crtc); - - /* - * don't off vblank if vblank_disable_allowed is 1, - * because vblank would be off by timer handler. - */ - if (!drm_dev->vblank_disable_allowed) - drm_vblank_off(drm_dev, crtc); - } - - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static void vidi_fake_vblank_handler(struct work_struct *work) -{ - struct vidi_context *ctx = container_of(work, struct vidi_context, - work); - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; - - if (manager->pipe < 0) - return; - - /* refresh rate is about 50Hz. */ - usleep_range(16000, 20000); - - drm_handle_vblank(subdrv->drm_dev, manager->pipe); - vidi_finish_pageflip(subdrv->drm_dev, manager->pipe); -} - -static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* - * enable drm irq mode. - * - with irq_enabled = 1, we can use the vblank feature. - * - * P.S. note that we wouldn't use drm irq handler but - * just specific driver own one instead because - * drm framework supports only one irq handler. - */ - drm_dev->irq_enabled = 1; - - /* - * with vblank_disable_allowed = 1, vblank interrupt will be disabled - * by drm timer once a current process gives up ownership of - * vblank event.(after drm_vblank_put function is called) - */ - drm_dev->vblank_disable_allowed = 1; - - return 0; -} - -static void vidi_subdrv_remove(struct drm_device *drm_dev) -{ - DRM_DEBUG_KMS("%s\n", __FILE__); - - /* TODO. */ -} - -static int vidi_power_on(struct vidi_context *ctx, bool enable) -{ - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - vidi_enable_vblank(dev); - - vidi_apply(dev); - } else { - ctx->suspended = true; - } - - return 0; -} - -static int vidi_show_connection(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int rc; - struct vidi_context *ctx = get_vidi_context(dev); - - mutex_lock(&ctx->lock); - - rc = sprintf(buf, "%d\n", ctx->connected); - - mutex_unlock(&ctx->lock); - - return rc; -} - -static int vidi_store_connection(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct vidi_context *ctx = get_vidi_context(dev); - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ret = kstrtoint(buf, 0, &ctx->connected); - if (ret) - return ret; - - if (ctx->connected > 1) - return -EINVAL; - - DRM_DEBUG_KMS("requested connection.\n"); - - drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); - - return len; -} - -static DEVICE_ATTR(connection, 0644, vidi_show_connection, - vidi_store_connection); - -int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv) -{ - struct vidi_context *ctx = NULL; - struct drm_encoder *encoder; - struct exynos_drm_manager *manager; - struct exynos_drm_display_ops *display_ops; - struct drm_exynos_vidi_connection *vidi = data; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (!vidi) { - DRM_DEBUG_KMS("user data for vidi is null.\n"); - return -EINVAL; - } - - if (!vidi->edid) { - DRM_DEBUG_KMS("edid data is null.\n"); - return -EINVAL; - } - - if (vidi->connection > 1) { - DRM_DEBUG_KMS("connection should be 0 or 1.\n"); - return -EINVAL; - } - - list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list, - head) { - manager = exynos_drm_get_manager(encoder); - display_ops = manager->display_ops; - - if (display_ops->type == EXYNOS_DISPLAY_TYPE_VIDI) { - ctx = get_vidi_context(manager->dev); - break; - } - } - - if (!ctx) { - DRM_DEBUG_KMS("not found virtual device type encoder.\n"); - return -EINVAL; - } - - if (ctx->connected == vidi->connection) { - DRM_DEBUG_KMS("same connection request.\n"); - return -EINVAL; - } - - if (vidi->connection) - ctx->raw_edid = (struct edid *)vidi->edid; - - ctx->connected = vidi->connection; - drm_helper_hpd_irq_event(ctx->subdrv.drm_dev); - - return 0; -} - -static int __devinit vidi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct vidi_context *ctx; - struct exynos_drm_subdrv *subdrv; - int ret; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->default_win = 0; - - INIT_WORK(&ctx->work, vidi_fake_vblank_handler); - - /* for test */ - ctx->raw_edid = (struct edid *)fake_edid_info; - - subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &vidi_manager; - subdrv->probe = vidi_subdrv_probe; - subdrv->remove = vidi_subdrv_remove; - - mutex_init(&ctx->lock); - - platform_set_drvdata(pdev, ctx); - - ret = device_create_file(&pdev->dev, &dev_attr_connection); - if (ret < 0) - DRM_INFO("failed to create connection sysfs.\n"); - - exynos_drm_subdrv_register(subdrv); - - return 0; -} - -static int __devexit vidi_remove(struct platform_device *pdev) -{ - struct vidi_context *ctx = platform_get_drvdata(pdev); - - DRM_DEBUG_KMS("%s\n", __FILE__); - - exynos_drm_subdrv_unregister(&ctx->subdrv); - - kfree(ctx); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int vidi_suspend(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - return vidi_power_on(ctx, false); -} - -static int vidi_resume(struct device *dev) -{ - struct vidi_context *ctx = get_vidi_context(dev); - - return vidi_power_on(ctx, true); -} -#endif - -static const struct dev_pm_ops vidi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(vidi_suspend, vidi_resume) -}; - -struct platform_driver vidi_driver = { - .probe = vidi_probe, - .remove = __devexit_p(vidi_remove), - .driver = { - .name = "exynos-drm-vidi", - .owner = THIS_MODULE, - .pm = &vidi_pm_ops, - }, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.h deleted file mode 100644 index a4babe4e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_drm_vidi.h +++ /dev/null @@ -1,36 +0,0 @@ -/* exynos_drm_vidi.h - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * Author: Inki Dae - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_DRM_VIDI_H_ -#define _EXYNOS_DRM_VIDI_H_ - -#ifdef CONFIG_DRM_EXYNOS_VIDI -int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, - struct drm_file *file_priv); -#else -#define vidi_connection_ioctl NULL -#endif - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.c deleted file mode 100644 index b0035387..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.c +++ /dev/null @@ -1,2389 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim - * Inki Dae - * Joonyoung Shim - * - * Based on drivers/media/video/s5p-tv/hdmi_drv.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include "drmP.h" -#include "drm_edid.h" -#include "drm_crtc_helper.h" - -#include "regs-hdmi.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "exynos_drm_drv.h" -#include "exynos_drm_hdmi.h" - -#include "exynos_hdmi.h" - -#define MAX_WIDTH 1920 -#define MAX_HEIGHT 1080 -#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct hdmi_resources { - struct clk *hdmi; - struct clk *sclk_hdmi; - struct clk *sclk_pixel; - struct clk *sclk_hdmiphy; - struct clk *hdmiphy; - struct regulator_bulk_data *regul_bulk; - int regul_count; -}; - -struct hdmi_context { - struct device *dev; - struct drm_device *drm_dev; - struct fb_videomode *default_timing; - unsigned int is_v13:1; - unsigned int default_win; - unsigned int default_bpp; - bool hpd_handle; - bool enabled; - - struct resource *regs_res; - void __iomem *regs; - unsigned int irq; - struct workqueue_struct *wq; - struct work_struct hotplug_work; - - struct i2c_client *ddc_port; - struct i2c_client *hdmiphy_port; - - /* current hdmiphy conf index */ - int cur_conf; - - struct hdmi_resources res; - void *parent_ctx; -}; - -/* HDMI Version 1.3 */ -static const u8 hdmiphy_v13_conf27[32] = { - 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, - 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, - 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf27_027[32] = { - 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, - 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, - 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf74_175[32] = { - 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, - 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, - 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf74_25[32] = { - 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, - 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, - 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0, - 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, -}; - -static const u8 hdmiphy_v13_conf148_5[32] = { - 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, - 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, - 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, - 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, -}; - -struct hdmi_v13_tg_regs { - u8 cmd; - u8 h_fsz_l; - u8 h_fsz_h; - u8 hact_st_l; - u8 hact_st_h; - u8 hact_sz_l; - u8 hact_sz_h; - u8 v_fsz_l; - u8 v_fsz_h; - u8 vsync_l; - u8 vsync_h; - u8 vsync2_l; - u8 vsync2_h; - u8 vact_st_l; - u8 vact_st_h; - u8 vact_sz_l; - u8 vact_sz_h; - u8 field_chg_l; - u8 field_chg_h; - u8 vact_st2_l; - u8 vact_st2_h; - u8 vsync_top_hdmi_l; - u8 vsync_top_hdmi_h; - u8 vsync_bot_hdmi_l; - u8 vsync_bot_hdmi_h; - u8 field_top_hdmi_l; - u8 field_top_hdmi_h; - u8 field_bot_hdmi_l; - u8 field_bot_hdmi_h; -}; - -struct hdmi_v13_core_regs { - u8 h_blank[2]; - u8 v_blank[3]; - u8 h_v_line[3]; - u8 vsync_pol[1]; - u8 int_pro_mode[1]; - u8 v_blank_f[3]; - u8 h_sync_gen[3]; - u8 v_sync_gen1[3]; - u8 v_sync_gen2[3]; - u8 v_sync_gen3[3]; -}; - -struct hdmi_v13_preset_conf { - struct hdmi_v13_core_regs core; - struct hdmi_v13_tg_regs tg; -}; - -struct hdmi_v13_conf { - int width; - int height; - int vrefresh; - bool interlace; - const u8 *hdmiphy_data; - const struct hdmi_v13_preset_conf *conf; -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = { - .core = { - .h_blank = {0x8a, 0x00}, - .v_blank = {0x0d, 0x6a, 0x01}, - .h_v_line = {0x0d, 0xa2, 0x35}, - .vsync_pol = {0x01}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, - .h_sync_gen = {0x0e, 0x30, 0x11}, - .v_sync_gen1 = {0x0f, 0x90, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x5a, 0x03, /* h_fsz */ - 0x8a, 0x00, 0xd0, 0x02, /* hact */ - 0x0d, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0xe0, 0x01, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = { - .core = { - .h_blank = {0x72, 0x01}, - .v_blank = {0xee, 0xf2, 0x00}, - .h_v_line = {0xee, 0x22, 0x67}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ - .h_sync_gen = {0x6c, 0x50, 0x02}, - .v_sync_gen1 = {0x0a, 0x50, 0x00}, - .v_sync_gen2 = {0x01, 0x10, 0x00}, - .v_sync_gen3 = {0x01, 0x10, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x72, 0x06, /* h_fsz */ - 0x71, 0x01, 0x01, 0x05, /* hact */ - 0xee, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x1e, 0x00, 0xd0, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v_blank = {0x32, 0xB2, 0x00}, - .h_v_line = {0x65, 0x04, 0xa5}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f = {0x49, 0x2A, 0x23}, - .h_sync_gen = {0x0E, 0xEA, 0x08}, - .v_sync_gen1 = {0x07, 0x20, 0x00}, - .v_sync_gen2 = {0x39, 0x42, 0x23}, - .v_sync_gen3 = {0x38, 0x87, 0x73}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0A, /* h_fsz */ - 0xCF, 0x02, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v_blank = {0x65, 0x6c, 0x01}, - .h_v_line = {0x65, 0x04, 0xa5}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ - .h_sync_gen = {0x0e, 0xea, 0x08}, - .v_sync_gen1 = {0x09, 0x40, 0x00}, - .v_sync_gen2 = {0x01, 0x10, 0x00}, - .v_sync_gen3 = {0x01, 0x10, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0A, /* h_fsz */ - 0xCF, 0x02, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v_blank = {0x32, 0xB2, 0x00}, - .h_v_line = {0x65, 0x84, 0x89}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f = {0x49, 0x2A, 0x23}, - .h_sync_gen = {0x56, 0x08, 0x02}, - .v_sync_gen1 = {0x07, 0x20, 0x00}, - .v_sync_gen2 = {0x39, 0x42, 0x23}, - .v_sync_gen3 = {0xa4, 0x44, 0x4a}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x17, 0x01, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v_blank = {0x65, 0x6c, 0x01}, - .h_v_line = {0x65, 0x84, 0x89}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f = {0x00, 0x00, 0x00}, /* don't care */ - .h_sync_gen = {0x56, 0x08, 0x02}, - .v_sync_gen1 = {0x09, 0x40, 0x00}, - .v_sync_gen2 = {0x01, 0x10, 0x00}, - .v_sync_gen3 = {0x01, 0x10, 0x00}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x17, 0x01, 0x81, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - }, -}; - -static const struct hdmi_v13_conf hdmi_v13_confs[] = { - { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, - { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 }, - { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p }, - { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 }, - { 1920, 1080, 50, false, hdmiphy_v13_conf148_5, - &hdmi_v13_conf_1080p50 }, - { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 }, - { 1920, 1080, 60, false, hdmiphy_v13_conf148_5, - &hdmi_v13_conf_1080p60 }, -}; - -/* HDMI Version 1.4 */ -static const u8 hdmiphy_conf27_027[32] = { - 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08, - 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80, - 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, -}; - -static const u8 hdmiphy_conf74_25[32] = { - 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08, - 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, - 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, -}; - -static const u8 hdmiphy_conf148_5[32] = { - 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08, - 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, - 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, - 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, -}; - -struct hdmi_tg_regs { - u8 cmd; - u8 h_fsz_l; - u8 h_fsz_h; - u8 hact_st_l; - u8 hact_st_h; - u8 hact_sz_l; - u8 hact_sz_h; - u8 v_fsz_l; - u8 v_fsz_h; - u8 vsync_l; - u8 vsync_h; - u8 vsync2_l; - u8 vsync2_h; - u8 vact_st_l; - u8 vact_st_h; - u8 vact_sz_l; - u8 vact_sz_h; - u8 field_chg_l; - u8 field_chg_h; - u8 vact_st2_l; - u8 vact_st2_h; - u8 vact_st3_l; - u8 vact_st3_h; - u8 vact_st4_l; - u8 vact_st4_h; - u8 vsync_top_hdmi_l; - u8 vsync_top_hdmi_h; - u8 vsync_bot_hdmi_l; - u8 vsync_bot_hdmi_h; - u8 field_top_hdmi_l; - u8 field_top_hdmi_h; - u8 field_bot_hdmi_l; - u8 field_bot_hdmi_h; - u8 tg_3d; -}; - -struct hdmi_core_regs { - u8 h_blank[2]; - u8 v2_blank[2]; - u8 v1_blank[2]; - u8 v_line[2]; - u8 h_line[2]; - u8 hsync_pol[1]; - u8 vsync_pol[1]; - u8 int_pro_mode[1]; - u8 v_blank_f0[2]; - u8 v_blank_f1[2]; - u8 h_sync_start[2]; - u8 h_sync_end[2]; - u8 v_sync_line_bef_2[2]; - u8 v_sync_line_bef_1[2]; - u8 v_sync_line_aft_2[2]; - u8 v_sync_line_aft_1[2]; - u8 v_sync_line_aft_pxl_2[2]; - u8 v_sync_line_aft_pxl_1[2]; - u8 v_blank_f2[2]; /* for 3D mode */ - u8 v_blank_f3[2]; /* for 3D mode */ - u8 v_blank_f4[2]; /* for 3D mode */ - u8 v_blank_f5[2]; /* for 3D mode */ - u8 v_sync_line_aft_3[2]; - u8 v_sync_line_aft_4[2]; - u8 v_sync_line_aft_5[2]; - u8 v_sync_line_aft_6[2]; - u8 v_sync_line_aft_pxl_3[2]; - u8 v_sync_line_aft_pxl_4[2]; - u8 v_sync_line_aft_pxl_5[2]; - u8 v_sync_line_aft_pxl_6[2]; - u8 vact_space_1[2]; - u8 vact_space_2[2]; - u8 vact_space_3[2]; - u8 vact_space_4[2]; - u8 vact_space_5[2]; - u8 vact_space_6[2]; -}; - -struct hdmi_preset_conf { - struct hdmi_core_regs core; - struct hdmi_tg_regs tg; -}; - -struct hdmi_conf { - int width; - int height; - int vrefresh; - bool interlace; - const u8 *hdmiphy_data; - const struct hdmi_preset_conf *conf; -}; - -static const struct hdmi_preset_conf hdmi_conf_480p60 = { - .core = { - .h_blank = {0x8a, 0x00}, - .v2_blank = {0x0d, 0x02}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x0d, 0x02}, - .h_line = {0x5a, 0x03}, - .hsync_pol = {0x01}, - .vsync_pol = {0x01}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x0e, 0x00}, - .h_sync_end = {0x4c, 0x00}, - .v_sync_line_bef_2 = {0x0f, 0x00}, - .v_sync_line_bef_1 = {0x09, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x5a, 0x03, /* h_fsz */ - 0x8a, 0x00, 0xd0, 0x02, /* hact */ - 0x0d, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0xe0, 0x01, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_720p50 = { - .core = { - .h_blank = {0xbc, 0x02}, - .v2_blank = {0xee, 0x02}, - .v1_blank = {0x1e, 0x00}, - .v_line = {0xee, 0x02}, - .h_line = {0xbc, 0x07}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0xb6, 0x01}, - .h_sync_end = {0xde, 0x01}, - .v_sync_line_bef_2 = {0x0a, 0x00}, - .v_sync_line_bef_1 = {0x05, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0xbc, 0x07, /* h_fsz */ - 0xbc, 0x02, 0x00, 0x05, /* hact */ - 0xee, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x1e, 0x00, 0xd0, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_720p60 = { - .core = { - .h_blank = {0x72, 0x01}, - .v2_blank = {0xee, 0x02}, - .v1_blank = {0x1e, 0x00}, - .v_line = {0xee, 0x02}, - .h_line = {0x72, 0x06}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x6c, 0x00}, - .h_sync_end = {0x94, 0x00}, - .v_sync_line_bef_2 = {0x0a, 0x00}, - .v_sync_line_bef_1 = {0x05, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x72, 0x06, /* h_fsz */ - 0x72, 0x01, 0x00, 0x05, /* hact */ - 0xee, 0x02, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x1e, 0x00, 0xd0, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080i50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v2_blank = {0x32, 0x02}, - .v1_blank = {0x16, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x50, 0x0a}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f0 = {0x49, 0x02}, - .v_blank_f1 = {0x65, 0x04}, - .h_sync_start = {0x0e, 0x02}, - .h_sync_end = {0x3a, 0x02}, - .v_sync_line_bef_2 = {0x07, 0x00}, - .v_sync_line_bef_1 = {0x02, 0x00}, - .v_sync_line_aft_2 = {0x39, 0x02}, - .v_sync_line_aft_1 = {0x34, 0x02}, - .v_sync_line_aft_pxl_2 = {0x38, 0x07}, - .v_sync_line_aft_pxl_1 = {0x38, 0x07}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0a, /* h_fsz */ - 0xd0, 0x02, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080i60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v2_blank = {0x32, 0x02}, - .v1_blank = {0x16, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x98, 0x08}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x01}, - .v_blank_f0 = {0x49, 0x02}, - .v_blank_f1 = {0x65, 0x04}, - .h_sync_start = {0x56, 0x00}, - .h_sync_end = {0x82, 0x00}, - .v_sync_line_bef_2 = {0x07, 0x00}, - .v_sync_line_bef_1 = {0x02, 0x00}, - .v_sync_line_aft_2 = {0x39, 0x02}, - .v_sync_line_aft_1 = {0x34, 0x02}, - .v_sync_line_aft_pxl_2 = {0xa4, 0x04}, - .v_sync_line_aft_pxl_1 = {0xa4, 0x04}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x18, 0x01, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x16, 0x00, 0x1c, 0x02, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x49, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080p50 = { - .core = { - .h_blank = {0xd0, 0x02}, - .v2_blank = {0x65, 0x04}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x50, 0x0a}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x0e, 0x02}, - .h_sync_end = {0x3a, 0x02}, - .v_sync_line_bef_2 = {0x09, 0x00}, - .v_sync_line_bef_1 = {0x04, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - .vact_space_1 = {0xff, 0xff}, - .vact_space_2 = {0xff, 0xff}, - .vact_space_3 = {0xff, 0xff}, - .vact_space_4 = {0xff, 0xff}, - .vact_space_5 = {0xff, 0xff}, - .vact_space_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x50, 0x0a, /* h_fsz */ - 0xd0, 0x02, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_preset_conf hdmi_conf_1080p60 = { - .core = { - .h_blank = {0x18, 0x01}, - .v2_blank = {0x65, 0x04}, - .v1_blank = {0x2d, 0x00}, - .v_line = {0x65, 0x04}, - .h_line = {0x98, 0x08}, - .hsync_pol = {0x00}, - .vsync_pol = {0x00}, - .int_pro_mode = {0x00}, - .v_blank_f0 = {0xff, 0xff}, - .v_blank_f1 = {0xff, 0xff}, - .h_sync_start = {0x56, 0x00}, - .h_sync_end = {0x82, 0x00}, - .v_sync_line_bef_2 = {0x09, 0x00}, - .v_sync_line_bef_1 = {0x04, 0x00}, - .v_sync_line_aft_2 = {0xff, 0xff}, - .v_sync_line_aft_1 = {0xff, 0xff}, - .v_sync_line_aft_pxl_2 = {0xff, 0xff}, - .v_sync_line_aft_pxl_1 = {0xff, 0xff}, - .v_blank_f2 = {0xff, 0xff}, - .v_blank_f3 = {0xff, 0xff}, - .v_blank_f4 = {0xff, 0xff}, - .v_blank_f5 = {0xff, 0xff}, - .v_sync_line_aft_3 = {0xff, 0xff}, - .v_sync_line_aft_4 = {0xff, 0xff}, - .v_sync_line_aft_5 = {0xff, 0xff}, - .v_sync_line_aft_6 = {0xff, 0xff}, - .v_sync_line_aft_pxl_3 = {0xff, 0xff}, - .v_sync_line_aft_pxl_4 = {0xff, 0xff}, - .v_sync_line_aft_pxl_5 = {0xff, 0xff}, - .v_sync_line_aft_pxl_6 = {0xff, 0xff}, - /* other don't care */ - }, - .tg = { - 0x00, /* cmd */ - 0x98, 0x08, /* h_fsz */ - 0x18, 0x01, 0x80, 0x07, /* hact */ - 0x65, 0x04, /* v_fsz */ - 0x01, 0x00, 0x33, 0x02, /* vsync */ - 0x2d, 0x00, 0x38, 0x04, /* vact */ - 0x33, 0x02, /* field_chg */ - 0x48, 0x02, /* vact_st2 */ - 0x00, 0x00, /* vact_st3 */ - 0x00, 0x00, /* vact_st4 */ - 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */ - 0x01, 0x00, 0x33, 0x02, /* field top/bot */ - 0x00, /* 3d FP */ - }, -}; - -static const struct hdmi_conf hdmi_confs[] = { - { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 }, - { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 }, - { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, - { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, - { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, - { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 }, - { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 }, -}; - - -static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) -{ - return readl(hdata->regs + reg_id); -} - -static inline void hdmi_reg_writeb(struct hdmi_context *hdata, - u32 reg_id, u8 value) -{ - writeb(value, hdata->regs + reg_id); -} - -static inline void hdmi_reg_writemask(struct hdmi_context *hdata, - u32 reg_id, u32 value, u32 mask) -{ - u32 old = readl(hdata->regs + reg_id); - value = (value & mask) | (old & ~mask); - writel(value, hdata->regs + reg_id); -} - -static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) -{ -#define DUMPREG(reg_id) \ - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ - readl(hdata->regs + reg_id)) - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); - DUMPREG(HDMI_INTC_FLAG); - DUMPREG(HDMI_INTC_CON); - DUMPREG(HDMI_HPD_STATUS); - DUMPREG(HDMI_V13_PHY_RSTOUT); - DUMPREG(HDMI_V13_PHY_VPLL); - DUMPREG(HDMI_V13_PHY_CMU); - DUMPREG(HDMI_V13_CORE_RSTOUT); - - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); - DUMPREG(HDMI_CON_0); - DUMPREG(HDMI_CON_1); - DUMPREG(HDMI_CON_2); - DUMPREG(HDMI_SYS_STATUS); - DUMPREG(HDMI_V13_PHY_STATUS); - DUMPREG(HDMI_STATUS_EN); - DUMPREG(HDMI_HPD); - DUMPREG(HDMI_MODE_SEL); - DUMPREG(HDMI_V13_HPD_GEN); - DUMPREG(HDMI_V13_DC_CONTROL); - DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN); - - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); - DUMPREG(HDMI_H_BLANK_0); - DUMPREG(HDMI_H_BLANK_1); - DUMPREG(HDMI_V13_V_BLANK_0); - DUMPREG(HDMI_V13_V_BLANK_1); - DUMPREG(HDMI_V13_V_BLANK_2); - DUMPREG(HDMI_V13_H_V_LINE_0); - DUMPREG(HDMI_V13_H_V_LINE_1); - DUMPREG(HDMI_V13_H_V_LINE_2); - DUMPREG(HDMI_VSYNC_POL); - DUMPREG(HDMI_INT_PRO_MODE); - DUMPREG(HDMI_V13_V_BLANK_F_0); - DUMPREG(HDMI_V13_V_BLANK_F_1); - DUMPREG(HDMI_V13_V_BLANK_F_2); - DUMPREG(HDMI_V13_H_SYNC_GEN_0); - DUMPREG(HDMI_V13_H_SYNC_GEN_1); - DUMPREG(HDMI_V13_H_SYNC_GEN_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_1_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_2_2); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_0); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_1); - DUMPREG(HDMI_V13_V_SYNC_GEN_3_2); - - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); - DUMPREG(HDMI_TG_CMD); - DUMPREG(HDMI_TG_H_FSZ_L); - DUMPREG(HDMI_TG_H_FSZ_H); - DUMPREG(HDMI_TG_HACT_ST_L); - DUMPREG(HDMI_TG_HACT_ST_H); - DUMPREG(HDMI_TG_HACT_SZ_L); - DUMPREG(HDMI_TG_HACT_SZ_H); - DUMPREG(HDMI_TG_V_FSZ_L); - DUMPREG(HDMI_TG_V_FSZ_H); - DUMPREG(HDMI_TG_VSYNC_L); - DUMPREG(HDMI_TG_VSYNC_H); - DUMPREG(HDMI_TG_VSYNC2_L); - DUMPREG(HDMI_TG_VSYNC2_H); - DUMPREG(HDMI_TG_VACT_ST_L); - DUMPREG(HDMI_TG_VACT_ST_H); - DUMPREG(HDMI_TG_VACT_SZ_L); - DUMPREG(HDMI_TG_VACT_SZ_H); - DUMPREG(HDMI_TG_FIELD_CHG_L); - DUMPREG(HDMI_TG_FIELD_CHG_H); - DUMPREG(HDMI_TG_VACT_ST2_L); - DUMPREG(HDMI_TG_VACT_ST2_H); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); -#undef DUMPREG -} - -static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) -{ - int i; - -#define DUMPREG(reg_id) \ - DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ - readl(hdata->regs + reg_id)) - - DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); - DUMPREG(HDMI_INTC_CON); - DUMPREG(HDMI_INTC_FLAG); - DUMPREG(HDMI_HPD_STATUS); - DUMPREG(HDMI_INTC_CON_1); - DUMPREG(HDMI_INTC_FLAG_1); - DUMPREG(HDMI_PHY_STATUS_0); - DUMPREG(HDMI_PHY_STATUS_PLL); - DUMPREG(HDMI_PHY_CON_0); - DUMPREG(HDMI_PHY_RSTOUT); - DUMPREG(HDMI_PHY_VPLL); - DUMPREG(HDMI_PHY_CMU); - DUMPREG(HDMI_CORE_RSTOUT); - - DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); - DUMPREG(HDMI_CON_0); - DUMPREG(HDMI_CON_1); - DUMPREG(HDMI_CON_2); - DUMPREG(HDMI_SYS_STATUS); - DUMPREG(HDMI_PHY_STATUS_0); - DUMPREG(HDMI_STATUS_EN); - DUMPREG(HDMI_HPD); - DUMPREG(HDMI_MODE_SEL); - DUMPREG(HDMI_ENC_EN); - DUMPREG(HDMI_DC_CONTROL); - DUMPREG(HDMI_VIDEO_PATTERN_GEN); - - DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); - DUMPREG(HDMI_H_BLANK_0); - DUMPREG(HDMI_H_BLANK_1); - DUMPREG(HDMI_V2_BLANK_0); - DUMPREG(HDMI_V2_BLANK_1); - DUMPREG(HDMI_V1_BLANK_0); - DUMPREG(HDMI_V1_BLANK_1); - DUMPREG(HDMI_V_LINE_0); - DUMPREG(HDMI_V_LINE_1); - DUMPREG(HDMI_H_LINE_0); - DUMPREG(HDMI_H_LINE_1); - DUMPREG(HDMI_HSYNC_POL); - - DUMPREG(HDMI_VSYNC_POL); - DUMPREG(HDMI_INT_PRO_MODE); - DUMPREG(HDMI_V_BLANK_F0_0); - DUMPREG(HDMI_V_BLANK_F0_1); - DUMPREG(HDMI_V_BLANK_F1_0); - DUMPREG(HDMI_V_BLANK_F1_1); - - DUMPREG(HDMI_H_SYNC_START_0); - DUMPREG(HDMI_H_SYNC_START_1); - DUMPREG(HDMI_H_SYNC_END_0); - DUMPREG(HDMI_H_SYNC_END_1); - - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0); - DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1); - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0); - DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1); - - DUMPREG(HDMI_V_BLANK_F2_0); - DUMPREG(HDMI_V_BLANK_F2_1); - DUMPREG(HDMI_V_BLANK_F3_0); - DUMPREG(HDMI_V_BLANK_F3_1); - DUMPREG(HDMI_V_BLANK_F4_0); - DUMPREG(HDMI_V_BLANK_F4_1); - DUMPREG(HDMI_V_BLANK_F5_0); - DUMPREG(HDMI_V_BLANK_F5_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1); - - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0); - DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1); - - DUMPREG(HDMI_VACT_SPACE_1_0); - DUMPREG(HDMI_VACT_SPACE_1_1); - DUMPREG(HDMI_VACT_SPACE_2_0); - DUMPREG(HDMI_VACT_SPACE_2_1); - DUMPREG(HDMI_VACT_SPACE_3_0); - DUMPREG(HDMI_VACT_SPACE_3_1); - DUMPREG(HDMI_VACT_SPACE_4_0); - DUMPREG(HDMI_VACT_SPACE_4_1); - DUMPREG(HDMI_VACT_SPACE_5_0); - DUMPREG(HDMI_VACT_SPACE_5_1); - DUMPREG(HDMI_VACT_SPACE_6_0); - DUMPREG(HDMI_VACT_SPACE_6_1); - - DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); - DUMPREG(HDMI_TG_CMD); - DUMPREG(HDMI_TG_H_FSZ_L); - DUMPREG(HDMI_TG_H_FSZ_H); - DUMPREG(HDMI_TG_HACT_ST_L); - DUMPREG(HDMI_TG_HACT_ST_H); - DUMPREG(HDMI_TG_HACT_SZ_L); - DUMPREG(HDMI_TG_HACT_SZ_H); - DUMPREG(HDMI_TG_V_FSZ_L); - DUMPREG(HDMI_TG_V_FSZ_H); - DUMPREG(HDMI_TG_VSYNC_L); - DUMPREG(HDMI_TG_VSYNC_H); - DUMPREG(HDMI_TG_VSYNC2_L); - DUMPREG(HDMI_TG_VSYNC2_H); - DUMPREG(HDMI_TG_VACT_ST_L); - DUMPREG(HDMI_TG_VACT_ST_H); - DUMPREG(HDMI_TG_VACT_SZ_L); - DUMPREG(HDMI_TG_VACT_SZ_H); - DUMPREG(HDMI_TG_FIELD_CHG_L); - DUMPREG(HDMI_TG_FIELD_CHG_H); - DUMPREG(HDMI_TG_VACT_ST2_L); - DUMPREG(HDMI_TG_VACT_ST2_H); - DUMPREG(HDMI_TG_VACT_ST3_L); - DUMPREG(HDMI_TG_VACT_ST3_H); - DUMPREG(HDMI_TG_VACT_ST4_L); - DUMPREG(HDMI_TG_VACT_ST4_H); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); - DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L); - DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); - DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); - DUMPREG(HDMI_TG_3D); - - DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix); - DUMPREG(HDMI_AVI_CON); - DUMPREG(HDMI_AVI_HEADER0); - DUMPREG(HDMI_AVI_HEADER1); - DUMPREG(HDMI_AVI_HEADER2); - DUMPREG(HDMI_AVI_CHECK_SUM); - DUMPREG(HDMI_VSI_CON); - DUMPREG(HDMI_VSI_HEADER0); - DUMPREG(HDMI_VSI_HEADER1); - DUMPREG(HDMI_VSI_HEADER2); - for (i = 0; i < 7; ++i) - DUMPREG(HDMI_VSI_DATA(i)); - -#undef DUMPREG -} - -static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) -{ - if (hdata->is_v13) - hdmi_v13_regs_dump(hdata, prefix); - else - hdmi_v14_regs_dump(hdata, prefix); -} - -static int hdmi_v13_conf_index(struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) - if (hdmi_v13_confs[i].width == mode->hdisplay && - hdmi_v13_confs[i].height == mode->vdisplay && - hdmi_v13_confs[i].vrefresh == mode->vrefresh && - hdmi_v13_confs[i].interlace == - ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? - true : false)) - return i; - - return -EINVAL; -} - -static int hdmi_v14_conf_index(struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i) - if (hdmi_confs[i].width == mode->hdisplay && - hdmi_confs[i].height == mode->vdisplay && - hdmi_confs[i].vrefresh == mode->vrefresh && - hdmi_confs[i].interlace == - ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? - true : false)) - return i; - - return -EINVAL; -} - -static int hdmi_conf_index(struct hdmi_context *hdata, - struct drm_display_mode *mode) -{ - if (hdata->is_v13) - return hdmi_v13_conf_index(mode); - - return hdmi_v14_conf_index(mode); -} - -static bool hdmi_is_connected(void *ctx) -{ - struct hdmi_context *hdata = ctx; - u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); - - if (val) - return true; - - return false; -} - -static int hdmi_get_edid(void *ctx, struct drm_connector *connector, - u8 *edid, int len) -{ - struct edid *raw_edid; - struct hdmi_context *hdata = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!hdata->ddc_port) - return -ENODEV; - - raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); - if (raw_edid) { - memcpy(edid, raw_edid, min((1 + raw_edid->extensions) - * EDID_LENGTH, len)); - DRM_DEBUG_KMS("width[%d] x height[%d]\n", - raw_edid->width_cm, raw_edid->height_cm); - } else { - return -ENODEV; - } - - return 0; -} - -static int hdmi_v13_check_timing(struct fb_videomode *check_timing) -{ - int i; - - DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", - check_timing->xres, check_timing->yres, - check_timing->refresh, (check_timing->vmode & - FB_VMODE_INTERLACED) ? true : false); - - for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i) - if (hdmi_v13_confs[i].width == check_timing->xres && - hdmi_v13_confs[i].height == check_timing->yres && - hdmi_v13_confs[i].vrefresh == check_timing->refresh && - hdmi_v13_confs[i].interlace == - ((check_timing->vmode & FB_VMODE_INTERLACED) ? - true : false)) - return 0; - - /* TODO */ - - return -EINVAL; -} - -static int hdmi_v14_check_timing(struct fb_videomode *check_timing) -{ - int i; - - DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n", - check_timing->xres, check_timing->yres, - check_timing->refresh, (check_timing->vmode & - FB_VMODE_INTERLACED) ? true : false); - - for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++) - if (hdmi_confs[i].width == check_timing->xres && - hdmi_confs[i].height == check_timing->yres && - hdmi_confs[i].vrefresh == check_timing->refresh && - hdmi_confs[i].interlace == - ((check_timing->vmode & FB_VMODE_INTERLACED) ? - true : false)) - return 0; - - /* TODO */ - - return -EINVAL; -} - -static int hdmi_check_timing(void *ctx, void *timing) -{ - struct hdmi_context *hdata = ctx; - struct fb_videomode *check_timing = timing; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, - check_timing->yres, check_timing->refresh, - check_timing->vmode); - - if (hdata->is_v13) - return hdmi_v13_check_timing(check_timing); - else - return hdmi_v14_check_timing(check_timing); -} - -static int hdmi_display_power_on(void *ctx, int mode) -{ - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - switch (mode) { - case DRM_MODE_DPMS_ON: - DRM_DEBUG_KMS("hdmi [on]\n"); - break; - case DRM_MODE_DPMS_STANDBY: - break; - case DRM_MODE_DPMS_SUSPEND: - break; - case DRM_MODE_DPMS_OFF: - DRM_DEBUG_KMS("hdmi [off]\n"); - break; - default: - break; - } - - return 0; -} - -static void hdmi_set_acr(u32 freq, u8 *acr) -{ - u32 n, cts; - - switch (freq) { - case 32000: - n = 4096; - cts = 27000; - break; - case 44100: - n = 6272; - cts = 30000; - break; - case 88200: - n = 12544; - cts = 30000; - break; - case 176400: - n = 25088; - cts = 30000; - break; - case 48000: - n = 6144; - cts = 27000; - break; - case 96000: - n = 12288; - cts = 27000; - break; - case 192000: - n = 24576; - cts = 27000; - break; - default: - n = 0; - cts = 0; - break; - } - - acr[1] = cts >> 16; - acr[2] = cts >> 8 & 0xff; - acr[3] = cts & 0xff; - - acr[4] = n >> 16; - acr[5] = n >> 8 & 0xff; - acr[6] = n & 0xff; -} - -static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr) -{ - hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]); - hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]); - hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]); - hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]); - hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]); - hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]); - hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]); - hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]); - hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]); - - if (hdata->is_v13) - hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4); - else - hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); -} - -static void hdmi_audio_init(struct hdmi_context *hdata) -{ - u32 sample_rate, bits_per_sample, frame_size_code; - u32 data_num, bit_ch, sample_frq; - u32 val; - u8 acr[7]; - - sample_rate = 44100; - bits_per_sample = 16; - frame_size_code = 0; - - switch (bits_per_sample) { - case 20: - data_num = 2; - bit_ch = 1; - break; - case 24: - data_num = 3; - bit_ch = 1; - break; - default: - data_num = 1; - bit_ch = 0; - break; - } - - hdmi_set_acr(sample_rate, acr); - hdmi_reg_acr(hdata, acr); - - hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE - | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE - | HDMI_I2S_MUX_ENABLE); - - hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN - | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN); - - hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN); - - sample_frq = (sample_rate == 44100) ? 0 : - (sample_rate == 48000) ? 2 : - (sample_rate == 32000) ? 3 : - (sample_rate == 96000) ? 0xa : 0x0; - - hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS); - hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN); - - val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01; - hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val); - - /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */ - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5) - | HDMI_I2S_SEL_LRCK(6)); - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1) - | HDMI_I2S_SEL_SDATA2(4)); - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1) - | HDMI_I2S_SEL_SDATA2(2)); - hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0)); - - /* I2S_CON_1 & 2 */ - hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE - | HDMI_I2S_L_CH_LOW_POL); - hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE - | HDMI_I2S_SET_BIT_CH(bit_ch) - | HDMI_I2S_SET_SDATA_BIT(data_num) - | HDMI_I2S_BASIC_FORMAT); - - /* Configure register related to CUV information */ - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0 - | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH - | HDMI_I2S_COPYRIGHT - | HDMI_I2S_LINEAR_PCM - | HDMI_I2S_CONSUMER_FORMAT); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0)); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2 - | HDMI_I2S_SET_SMP_FREQ(sample_frq)); - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4, - HDMI_I2S_ORG_SMP_FREQ_44_1 - | HDMI_I2S_WORD_LEN_MAX24_24BITS - | HDMI_I2S_WORD_LEN_MAX_24BITS); - - hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD); -} - -static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff) -{ - u32 mod; - - mod = hdmi_reg_read(hdata, HDMI_MODE_SEL); - if (mod & HDMI_DVI_MODE_EN) - return; - - hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0); - hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ? - HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); -} - -static void hdmi_conf_reset(struct hdmi_context *hdata) -{ - u32 reg; - - /* disable hpd handle for drm */ - hdata->hpd_handle = false; - - if (hdata->is_v13) - reg = HDMI_V13_CORE_RSTOUT; - else - reg = HDMI_CORE_RSTOUT; - - /* resetting HDMI core */ - hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT); - mdelay(10); - hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT); - mdelay(10); - - /* enable hpd handle for drm */ - hdata->hpd_handle = true; -} - -static void hdmi_conf_init(struct hdmi_context *hdata) -{ - /* disable hpd handle for drm */ - hdata->hpd_handle = false; - - /* enable HPD interrupts */ - hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | - HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); - mdelay(10); - hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL | - HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); - - /* choose HDMI mode */ - hdmi_reg_writemask(hdata, HDMI_MODE_SEL, - HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); - /* disable bluescreen */ - hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); - - if (hdata->is_v13) { - /* choose bluescreen (fecal) color */ - hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12); - hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34); - hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56); - - /* enable AVI packet every vsync, fixes purple line problem */ - hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02); - /* force RGB, look to CEA-861-D, table 7 for more detail */ - hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5); - hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5); - - hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02); - hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); - hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); - } else { - /* enable AVI packet every vsync, fixes purple line problem */ - hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02); - hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5); - hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5); - } - - /* enable hpd handle for drm */ - hdata->hpd_handle = true; -} - -static void hdmi_v13_timing_apply(struct hdmi_context *hdata) -{ - const struct hdmi_v13_preset_conf *conf = - hdmi_v13_confs[hdata->cur_conf].conf; - const struct hdmi_v13_core_regs *core = &conf->core; - const struct hdmi_v13_tg_regs *tg = &conf->tg; - int tries; - - /* setting core registers */ - hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); - hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]); - hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]); - hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]); - hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]); - hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); - hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]); - hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]); - hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]); - hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); - hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); - /* Timing generator registers */ - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); - - /* waiting for HDMIPHY's PLL to get to steady state */ - for (tries = 100; tries; --tries) { - u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS); - if (val & HDMI_PHY_STATUS_READY) - break; - mdelay(1); - } - /* steady state not achieved */ - if (tries == 0) { - DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); - hdmi_regs_dump(hdata, "timing apply"); - } - - clk_disable(hdata->res.sclk_hdmi); - clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); - clk_enable(hdata->res.sclk_hdmi); - - /* enable HDMI and timing generator */ - hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); - if (core->int_pro_mode[0]) - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | - HDMI_FIELD_EN); - else - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); -} - -static void hdmi_v14_timing_apply(struct hdmi_context *hdata) -{ - const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf; - const struct hdmi_core_regs *core = &conf->core; - const struct hdmi_tg_regs *tg = &conf->tg; - int tries; - - /* setting core registers */ - hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); - hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]); - hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]); - hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]); - hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]); - hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]); - hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]); - hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]); - hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]); - hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); - hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]); - hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0, - core->v_sync_line_bef_2[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1, - core->v_sync_line_bef_2[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0, - core->v_sync_line_bef_1[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1, - core->v_sync_line_bef_1[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0, - core->v_sync_line_aft_2[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1, - core->v_sync_line_aft_2[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0, - core->v_sync_line_aft_1[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1, - core->v_sync_line_aft_1[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0, - core->v_sync_line_aft_pxl_2[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1, - core->v_sync_line_aft_pxl_2[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0, - core->v_sync_line_aft_pxl_1[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1, - core->v_sync_line_aft_pxl_1[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]); - hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0, - core->v_sync_line_aft_3[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1, - core->v_sync_line_aft_3[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0, - core->v_sync_line_aft_4[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1, - core->v_sync_line_aft_4[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0, - core->v_sync_line_aft_5[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1, - core->v_sync_line_aft_5[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0, - core->v_sync_line_aft_6[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1, - core->v_sync_line_aft_6[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0, - core->v_sync_line_aft_pxl_3[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1, - core->v_sync_line_aft_pxl_3[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0, - core->v_sync_line_aft_pxl_4[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1, - core->v_sync_line_aft_pxl_4[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, - core->v_sync_line_aft_pxl_5[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1, - core->v_sync_line_aft_pxl_5[1]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, - core->v_sync_line_aft_pxl_6[0]); - hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1, - core->v_sync_line_aft_pxl_6[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]); - hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]); - - /* Timing generator registers */ - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l); - hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l); - hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); - hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); - hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d); - - /* waiting for HDMIPHY's PLL to get to steady state */ - for (tries = 100; tries; --tries) { - u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0); - if (val & HDMI_PHY_STATUS_READY) - break; - mdelay(1); - } - /* steady state not achieved */ - if (tries == 0) { - DRM_ERROR("hdmiphy's pll could not reach steady state.\n"); - hdmi_regs_dump(hdata, "timing apply"); - } - - clk_disable(hdata->res.sclk_hdmi); - clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy); - clk_enable(hdata->res.sclk_hdmi); - - /* enable HDMI and timing generator */ - hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); - if (core->int_pro_mode[0]) - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN | - HDMI_FIELD_EN); - else - hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); -} - -static void hdmi_timing_apply(struct hdmi_context *hdata) -{ - if (hdata->is_v13) - hdmi_v13_timing_apply(hdata); - else - hdmi_v14_timing_apply(hdata); -} - -static void hdmiphy_conf_reset(struct hdmi_context *hdata) -{ - u8 buffer[2]; - u32 reg; - - clk_disable(hdata->res.sclk_hdmi); - clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel); - clk_enable(hdata->res.sclk_hdmi); - - /* operation mode */ - buffer[0] = 0x1f; - buffer[1] = 0x00; - - if (hdata->hdmiphy_port) - i2c_master_send(hdata->hdmiphy_port, buffer, 2); - - if (hdata->is_v13) - reg = HDMI_V13_PHY_RSTOUT; - else - reg = HDMI_PHY_RSTOUT; - - /* reset hdmiphy */ - hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT); - mdelay(10); - hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT); - mdelay(10); -} - -static void hdmiphy_conf_apply(struct hdmi_context *hdata) -{ - const u8 *hdmiphy_data; - u8 buffer[32]; - u8 operation[2]; - u8 read_buffer[32] = {0, }; - int ret; - int i; - - if (!hdata->hdmiphy_port) { - DRM_ERROR("hdmiphy is not attached\n"); - return; - } - - /* pixel clock */ - if (hdata->is_v13) - hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data; - else - hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data; - - memcpy(buffer, hdmiphy_data, 32); - ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); - if (ret != 32) { - DRM_ERROR("failed to configure HDMIPHY via I2C\n"); - return; - } - - mdelay(10); - - /* operation mode */ - operation[0] = 0x1f; - operation[1] = 0x80; - - ret = i2c_master_send(hdata->hdmiphy_port, operation, 2); - if (ret != 2) { - DRM_ERROR("failed to enable hdmiphy\n"); - return; - } - - ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32); - if (ret < 0) { - DRM_ERROR("failed to read hdmiphy config\n"); - return; - } - - for (i = 0; i < ret; i++) - DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - " - "recv [0x%02x]\n", i, buffer[i], read_buffer[i]); -} - -static void hdmi_conf_apply(struct hdmi_context *hdata) -{ - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - hdmiphy_conf_reset(hdata); - hdmiphy_conf_apply(hdata); - - hdmi_conf_reset(hdata); - hdmi_conf_init(hdata); - hdmi_audio_init(hdata); - - /* setting core registers */ - hdmi_timing_apply(hdata); - hdmi_audio_control(hdata, true); - - hdmi_regs_dump(hdata, "start"); -} - -static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_display_mode *m; - struct hdmi_context *hdata = ctx; - int index; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - drm_mode_set_crtcinfo(adjusted_mode, 0); - - if (hdata->is_v13) - index = hdmi_v13_conf_index(adjusted_mode); - else - index = hdmi_v14_conf_index(adjusted_mode); - - /* just return if user desired mode exists. */ - if (index >= 0) - return; - - /* - * otherwise, find the most suitable mode among modes and change it - * to adjusted_mode. - */ - list_for_each_entry(m, &connector->modes, head) { - if (hdata->is_v13) - index = hdmi_v13_conf_index(m); - else - index = hdmi_v14_conf_index(m); - - if (index >= 0) { - DRM_INFO("desired mode doesn't exist so\n"); - DRM_INFO("use the most suitable mode among modes.\n"); - memcpy(adjusted_mode, m, sizeof(*m)); - break; - } - } -} - -static void hdmi_mode_set(void *ctx, void *mode) -{ - struct hdmi_context *hdata = ctx; - int conf_idx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - conf_idx = hdmi_conf_index(hdata, mode); - if (conf_idx >= 0) - hdata->cur_conf = conf_idx; - else - DRM_DEBUG_KMS("not supported mode\n"); -} - -static void hdmi_get_max_resol(void *ctx, unsigned int *width, - unsigned int *height) -{ - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - *width = MAX_WIDTH; - *height = MAX_HEIGHT; -} - -static void hdmi_commit(void *ctx) -{ - struct hdmi_context *hdata = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - hdmi_conf_apply(hdata); - - hdata->enabled = true; -} - -static void hdmi_disable(void *ctx) -{ - struct hdmi_context *hdata = ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (hdata->enabled) { - hdmi_audio_control(hdata, false); - hdmiphy_conf_reset(hdata); - hdmi_conf_reset(hdata); - } -} - -static struct exynos_hdmi_ops hdmi_ops = { - /* display */ - .is_connected = hdmi_is_connected, - .get_edid = hdmi_get_edid, - .check_timing = hdmi_check_timing, - .power_on = hdmi_display_power_on, - - /* manager */ - .mode_fixup = hdmi_mode_fixup, - .mode_set = hdmi_mode_set, - .get_max_resol = hdmi_get_max_resol, - .commit = hdmi_commit, - .disable = hdmi_disable, -}; - -/* - * Handle hotplug events outside the interrupt handler proper. - */ -static void hdmi_hotplug_func(struct work_struct *work) -{ - struct hdmi_context *hdata = - container_of(work, struct hdmi_context, hotplug_work); - struct exynos_drm_hdmi_context *ctx = - (struct exynos_drm_hdmi_context *)hdata->parent_ctx; - - drm_helper_hpd_irq_event(ctx->drm_dev); -} - -static irqreturn_t hdmi_irq_handler(int irq, void *arg) -{ - struct exynos_drm_hdmi_context *ctx = arg; - struct hdmi_context *hdata = ctx->ctx; - u32 intc_flag; - - intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); - /* clearing flags for HPD plug/unplug */ - if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) { - DRM_DEBUG_KMS("unplugged, handling:%d\n", hdata->hpd_handle); - hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, - HDMI_INTC_FLAG_HPD_UNPLUG); - } - if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) { - DRM_DEBUG_KMS("plugged, handling:%d\n", hdata->hpd_handle); - hdmi_reg_writemask(hdata, HDMI_INTC_FLAG, ~0, - HDMI_INTC_FLAG_HPD_PLUG); - } - - if (ctx->drm_dev && hdata->hpd_handle) - queue_work(hdata->wq, &hdata->hotplug_work); - - return IRQ_HANDLED; -} - -static int __devinit hdmi_resources_init(struct hdmi_context *hdata) -{ - struct device *dev = hdata->dev; - struct hdmi_resources *res = &hdata->res; - static char *supply[] = { - "hdmi-en", - "vdd", - "vdd_osc", - "vdd_pll", - }; - int i, ret; - - DRM_DEBUG_KMS("HDMI resource init\n"); - - memset(res, 0, sizeof *res); - - /* get clocks, power */ - res->hdmi = clk_get(dev, "hdmi"); - if (IS_ERR_OR_NULL(res->hdmi)) { - DRM_ERROR("failed to get clock 'hdmi'\n"); - goto fail; - } - res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); - if (IS_ERR_OR_NULL(res->sclk_hdmi)) { - DRM_ERROR("failed to get clock 'sclk_hdmi'\n"); - goto fail; - } - res->sclk_pixel = clk_get(dev, "sclk_pixel"); - if (IS_ERR_OR_NULL(res->sclk_pixel)) { - DRM_ERROR("failed to get clock 'sclk_pixel'\n"); - goto fail; - } - res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy"); - if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) { - DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); - goto fail; - } - res->hdmiphy = clk_get(dev, "hdmiphy"); - if (IS_ERR_OR_NULL(res->hdmiphy)) { - DRM_ERROR("failed to get clock 'hdmiphy'\n"); - goto fail; - } - - clk_set_parent(res->sclk_hdmi, res->sclk_pixel); - - res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * - sizeof res->regul_bulk[0], GFP_KERNEL); - if (!res->regul_bulk) { - DRM_ERROR("failed to get memory for regulators\n"); - goto fail; - } - for (i = 0; i < ARRAY_SIZE(supply); ++i) { - res->regul_bulk[i].supply = supply[i]; - res->regul_bulk[i].consumer = NULL; - } - ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk); - if (ret) { - DRM_ERROR("failed to get regulators\n"); - goto fail; - } - res->regul_count = ARRAY_SIZE(supply); - - return 0; -fail: - DRM_ERROR("HDMI resource init - failed\n"); - return -ENODEV; -} - -static int hdmi_resources_cleanup(struct hdmi_context *hdata) -{ - struct hdmi_resources *res = &hdata->res; - - regulator_bulk_free(res->regul_count, res->regul_bulk); - /* kfree is NULL-safe */ - kfree(res->regul_bulk); - if (!IS_ERR_OR_NULL(res->hdmiphy)) - clk_put(res->hdmiphy); - if (!IS_ERR_OR_NULL(res->sclk_hdmiphy)) - clk_put(res->sclk_hdmiphy); - if (!IS_ERR_OR_NULL(res->sclk_pixel)) - clk_put(res->sclk_pixel); - if (!IS_ERR_OR_NULL(res->sclk_hdmi)) - clk_put(res->sclk_hdmi); - if (!IS_ERR_OR_NULL(res->hdmi)) - clk_put(res->hdmi); - memset(res, 0, sizeof *res); - - return 0; -} - -static void hdmi_resource_poweron(struct hdmi_context *hdata) -{ - struct hdmi_resources *res = &hdata->res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - /* turn HDMI power on */ - regulator_bulk_enable(res->regul_count, res->regul_bulk); - /* power-on hdmi physical interface */ - clk_enable(res->hdmiphy); - /* turn clocks on */ - clk_enable(res->hdmi); - clk_enable(res->sclk_hdmi); - - hdmiphy_conf_reset(hdata); - hdmi_conf_reset(hdata); - hdmi_conf_init(hdata); - hdmi_audio_init(hdata); -} - -static void hdmi_resource_poweroff(struct hdmi_context *hdata) -{ - struct hdmi_resources *res = &hdata->res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - /* turn clocks off */ - clk_disable(res->sclk_hdmi); - clk_disable(res->hdmi); - /* power-off hdmiphy */ - clk_disable(res->hdmiphy); - /* turn HDMI power off */ - regulator_bulk_disable(res->regul_count, res->regul_bulk); -} - -static int hdmi_runtime_suspend(struct device *dev) -{ - struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); - - DRM_DEBUG_KMS("%s\n", __func__); - - hdmi_resource_poweroff(ctx->ctx); - - return 0; -} - -static int hdmi_runtime_resume(struct device *dev) -{ - struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev); - - DRM_DEBUG_KMS("%s\n", __func__); - - hdmi_resource_poweron(ctx->ctx); - - return 0; -} - -static const struct dev_pm_ops hdmi_pm_ops = { - .runtime_suspend = hdmi_runtime_suspend, - .runtime_resume = hdmi_runtime_resume, -}; - -static struct i2c_client *hdmi_ddc, *hdmi_hdmiphy; - -void hdmi_attach_ddc_client(struct i2c_client *ddc) -{ - if (ddc) - hdmi_ddc = ddc; -} - -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) -{ - if (hdmiphy) - hdmi_hdmiphy = hdmiphy; -} - -static int __devinit hdmi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *drm_hdmi_ctx; - struct hdmi_context *hdata; - struct exynos_drm_hdmi_pdata *pdata; - struct resource *res; - int ret; - - DRM_DEBUG_KMS("[%d]\n", __LINE__); - - pdata = pdev->dev.platform_data; - if (!pdata) { - DRM_ERROR("no platform data specified\n"); - return -EINVAL; - } - - drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL); - if (!drm_hdmi_ctx) { - DRM_ERROR("failed to allocate common hdmi context.\n"); - return -ENOMEM; - } - - hdata = kzalloc(sizeof(struct hdmi_context), GFP_KERNEL); - if (!hdata) { - DRM_ERROR("out of memory\n"); - kfree(drm_hdmi_ctx); - return -ENOMEM; - } - - drm_hdmi_ctx->ctx = (void *)hdata; - hdata->parent_ctx = (void *)drm_hdmi_ctx; - - platform_set_drvdata(pdev, drm_hdmi_ctx); - - hdata->is_v13 = pdata->is_v13; - hdata->default_win = pdata->default_win; - hdata->default_timing = &pdata->timing; - hdata->default_bpp = pdata->bpp; - hdata->dev = dev; - - ret = hdmi_resources_init(hdata); - if (ret) { - ret = -EINVAL; - goto err_data; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - DRM_ERROR("failed to find registers\n"); - ret = -ENOENT; - goto err_resource; - } - - hdata->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!hdata->regs_res) { - DRM_ERROR("failed to claim register region\n"); - ret = -ENOENT; - goto err_resource; - } - - hdata->regs = ioremap(res->start, resource_size(res)); - if (!hdata->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -ENXIO; - goto err_req_region; - } - - /* DDC i2c driver */ - if (i2c_add_driver(&ddc_driver)) { - DRM_ERROR("failed to register ddc i2c driver\n"); - ret = -ENOENT; - goto err_iomap; - } - - hdata->ddc_port = hdmi_ddc; - - /* hdmiphy i2c driver */ - if (i2c_add_driver(&hdmiphy_driver)) { - DRM_ERROR("failed to register hdmiphy i2c driver\n"); - ret = -ENOENT; - goto err_ddc; - } - - hdata->hdmiphy_port = hdmi_hdmiphy; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { - DRM_ERROR("get interrupt resource failed.\n"); - ret = -ENXIO; - goto err_hdmiphy; - } - - /* create workqueue and hotplug work */ - hdata->wq = alloc_workqueue("exynos-drm-hdmi", - WQ_UNBOUND | WQ_NON_REENTRANT, 1); - if (hdata->wq == NULL) { - DRM_ERROR("Failed to create workqueue.\n"); - ret = -ENOMEM; - goto err_hdmiphy; - } - INIT_WORK(&hdata->hotplug_work, hdmi_hotplug_func); - - /* register hpd interrupt */ - ret = request_irq(res->start, hdmi_irq_handler, 0, "drm_hdmi", - drm_hdmi_ctx); - if (ret) { - DRM_ERROR("request interrupt failed.\n"); - goto err_workqueue; - } - hdata->irq = res->start; - - /* register specific callbacks to common hdmi. */ - exynos_hdmi_ops_register(&hdmi_ops); - - hdmi_resource_poweron(hdata); - - return 0; - -err_workqueue: - destroy_workqueue(hdata->wq); -err_hdmiphy: - i2c_del_driver(&hdmiphy_driver); -err_ddc: - i2c_del_driver(&ddc_driver); -err_iomap: - iounmap(hdata->regs); -err_req_region: - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); -err_resource: - hdmi_resources_cleanup(hdata); -err_data: - kfree(hdata); - kfree(drm_hdmi_ctx); - return ret; -} - -static int __devexit hdmi_remove(struct platform_device *pdev) -{ - struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); - struct hdmi_context *hdata = ctx->ctx; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - hdmi_resource_poweroff(hdata); - - disable_irq(hdata->irq); - free_irq(hdata->irq, hdata); - - cancel_work_sync(&hdata->hotplug_work); - destroy_workqueue(hdata->wq); - - hdmi_resources_cleanup(hdata); - - iounmap(hdata->regs); - - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); - - /* hdmiphy i2c driver */ - i2c_del_driver(&hdmiphy_driver); - /* DDC i2c driver */ - i2c_del_driver(&ddc_driver); - - kfree(hdata); - - return 0; -} - -struct platform_driver hdmi_driver = { - .probe = hdmi_probe, - .remove = __devexit_p(hdmi_remove), - .driver = { - .name = "exynos4-hdmi", - .owner = THIS_MODULE, - .pm = &hdmi_pm_ops, - }, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.h deleted file mode 100644 index 1c3b6d8f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmi.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * Authors: - * Inki Dae - * Seung-Woo Kim - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _EXYNOS_HDMI_H_ -#define _EXYNOS_HDMI_H_ - -void hdmi_attach_ddc_client(struct i2c_client *ddc); -void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy); - -extern struct i2c_driver hdmiphy_driver; -extern struct i2c_driver ddc_driver; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmiphy.c deleted file mode 100644 index 9fe2995a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_hdmiphy.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim - * Inki Dae - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include "drmP.h" - -#include -#include -#include - -#include "exynos_drm_drv.h" -#include "exynos_hdmi.h" - - -static int hdmiphy_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - hdmi_attach_hdmiphy_client(client); - - dev_info(&client->adapter->dev, "attached s5p_hdmiphy " - "into i2c adapter successfully\n"); - - return 0; -} - -static int hdmiphy_remove(struct i2c_client *client) -{ - dev_info(&client->adapter->dev, "detached s5p_hdmiphy " - "from i2c adapter successfully\n"); - - return 0; -} - -static const struct i2c_device_id hdmiphy_id[] = { - { "s5p_hdmiphy", 0 }, - { }, -}; - -struct i2c_driver hdmiphy_driver = { - .driver = { - .name = "s5p-hdmiphy", - .owner = THIS_MODULE, - }, - .id_table = hdmiphy_id, - .probe = hdmiphy_probe, - .remove = __devexit_p(hdmiphy_remove), - .command = NULL, -}; -EXPORT_SYMBOL(hdmiphy_driver); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_mixer.c b/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_mixer.c deleted file mode 100644 index e15438c0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/exynos_mixer.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Authors: - * Seung-Woo Kim - * Inki Dae - * Joonyoung Shim - * - * Based on drivers/media/video/s5p-tv/mixer_reg.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include "drmP.h" - -#include "regs-mixer.h" -#include "regs-vp.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "exynos_drm_drv.h" -#include "exynos_drm_hdmi.h" - -#define MIXER_WIN_NR 3 -#define MIXER_DEFAULT_WIN 0 - -#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) - -struct hdmi_win_data { - dma_addr_t dma_addr; - void __iomem *vaddr; - dma_addr_t chroma_dma_addr; - void __iomem *chroma_vaddr; - uint32_t pixel_format; - unsigned int bpp; - unsigned int crtc_x; - unsigned int crtc_y; - unsigned int crtc_width; - unsigned int crtc_height; - unsigned int fb_x; - unsigned int fb_y; - unsigned int fb_width; - unsigned int fb_height; - unsigned int mode_width; - unsigned int mode_height; - unsigned int scan_flags; -}; - -struct mixer_resources { - struct device *dev; - int irq; - void __iomem *mixer_regs; - void __iomem *vp_regs; - spinlock_t reg_slock; - struct clk *mixer; - struct clk *vp; - struct clk *sclk_mixer; - struct clk *sclk_hdmi; - struct clk *sclk_dac; -}; - -struct mixer_context { - unsigned int irq; - int pipe; - bool interlace; - - struct mixer_resources mixer_res; - struct hdmi_win_data win_data[MIXER_WIN_NR]; -}; - -static const u8 filter_y_horiz_tap8[] = { - 0, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 0, 0, 0, - 0, 2, 4, 5, 6, 6, 6, 6, - 6, 5, 5, 4, 3, 2, 1, 1, - 0, -6, -12, -16, -18, -20, -21, -20, - -20, -18, -16, -13, -10, -8, -5, -2, - 127, 126, 125, 121, 114, 107, 99, 89, - 79, 68, 57, 46, 35, 25, 16, 8, -}; - -static const u8 filter_y_vert_tap4[] = { - 0, -3, -6, -8, -8, -8, -8, -7, - -6, -5, -4, -3, -2, -1, -1, 0, - 127, 126, 124, 118, 111, 102, 92, 81, - 70, 59, 48, 37, 27, 19, 11, 5, - 0, 5, 11, 19, 27, 37, 48, 59, - 70, 81, 92, 102, 111, 118, 124, 126, - 0, 0, -1, -1, -2, -3, -4, -5, - -6, -7, -8, -8, -8, -8, -6, -3, -}; - -static const u8 filter_cr_horiz_tap4[] = { - 0, -3, -6, -8, -8, -8, -8, -7, - -6, -5, -4, -3, -2, -1, -1, 0, - 127, 126, 124, 118, 111, 102, 92, 81, - 70, 59, 48, 37, 27, 19, 11, 5, -}; - -static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id) -{ - return readl(res->vp_regs + reg_id); -} - -static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id, - u32 val) -{ - writel(val, res->vp_regs + reg_id); -} - -static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id, - u32 val, u32 mask) -{ - u32 old = vp_reg_read(res, reg_id); - - val = (val & mask) | (old & ~mask); - writel(val, res->vp_regs + reg_id); -} - -static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id) -{ - return readl(res->mixer_regs + reg_id); -} - -static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id, - u32 val) -{ - writel(val, res->mixer_regs + reg_id); -} - -static inline void mixer_reg_writemask(struct mixer_resources *res, - u32 reg_id, u32 val, u32 mask) -{ - u32 old = mixer_reg_read(res, reg_id); - - val = (val & mask) | (old & ~mask); - writel(val, res->mixer_regs + reg_id); -} - -static void mixer_regs_dump(struct mixer_context *ctx) -{ -#define DUMPREG(reg_id) \ -do { \ - DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \ -} while (0) - - DUMPREG(MXR_STATUS); - DUMPREG(MXR_CFG); - DUMPREG(MXR_INT_EN); - DUMPREG(MXR_INT_STATUS); - - DUMPREG(MXR_LAYER_CFG); - DUMPREG(MXR_VIDEO_CFG); - - DUMPREG(MXR_GRAPHIC0_CFG); - DUMPREG(MXR_GRAPHIC0_BASE); - DUMPREG(MXR_GRAPHIC0_SPAN); - DUMPREG(MXR_GRAPHIC0_WH); - DUMPREG(MXR_GRAPHIC0_SXY); - DUMPREG(MXR_GRAPHIC0_DXY); - - DUMPREG(MXR_GRAPHIC1_CFG); - DUMPREG(MXR_GRAPHIC1_BASE); - DUMPREG(MXR_GRAPHIC1_SPAN); - DUMPREG(MXR_GRAPHIC1_WH); - DUMPREG(MXR_GRAPHIC1_SXY); - DUMPREG(MXR_GRAPHIC1_DXY); -#undef DUMPREG -} - -static void vp_regs_dump(struct mixer_context *ctx) -{ -#define DUMPREG(reg_id) \ -do { \ - DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \ -} while (0) - - DUMPREG(VP_ENABLE); - DUMPREG(VP_SRESET); - DUMPREG(VP_SHADOW_UPDATE); - DUMPREG(VP_FIELD_ID); - DUMPREG(VP_MODE); - DUMPREG(VP_IMG_SIZE_Y); - DUMPREG(VP_IMG_SIZE_C); - DUMPREG(VP_PER_RATE_CTRL); - DUMPREG(VP_TOP_Y_PTR); - DUMPREG(VP_BOT_Y_PTR); - DUMPREG(VP_TOP_C_PTR); - DUMPREG(VP_BOT_C_PTR); - DUMPREG(VP_ENDIAN_MODE); - DUMPREG(VP_SRC_H_POSITION); - DUMPREG(VP_SRC_V_POSITION); - DUMPREG(VP_SRC_WIDTH); - DUMPREG(VP_SRC_HEIGHT); - DUMPREG(VP_DST_H_POSITION); - DUMPREG(VP_DST_V_POSITION); - DUMPREG(VP_DST_WIDTH); - DUMPREG(VP_DST_HEIGHT); - DUMPREG(VP_H_RATIO); - DUMPREG(VP_V_RATIO); - -#undef DUMPREG -} - -static inline void vp_filter_set(struct mixer_resources *res, - int reg_id, const u8 *data, unsigned int size) -{ - /* assure 4-byte align */ - BUG_ON(size & 3); - for (; size; size -= 4, reg_id += 4, data += 4) { - u32 val = (data[0] << 24) | (data[1] << 16) | - (data[2] << 8) | data[3]; - vp_reg_write(res, reg_id, val); - } -} - -static void vp_default_filter(struct mixer_resources *res) -{ - vp_filter_set(res, VP_POLY8_Y0_LL, - filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); - vp_filter_set(res, VP_POLY4_Y0_LL, - filter_y_vert_tap4, sizeof filter_y_vert_tap4); - vp_filter_set(res, VP_POLY4_C0_LL, - filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); -} - -static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) -{ - struct mixer_resources *res = &ctx->mixer_res; - - /* block update on vsync */ - mixer_reg_writemask(res, MXR_STATUS, enable ? - MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); - - vp_reg_write(res, VP_SHADOW_UPDATE, enable ? - VP_SHADOW_UPDATE_ENABLE : 0); -} - -static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height) -{ - struct mixer_resources *res = &ctx->mixer_res; - u32 val; - - /* choosing between interlace and progressive mode */ - val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE : - MXR_CFG_SCAN_PROGRASSIVE); - - /* choosing between porper HD and SD mode */ - if (height == 480) - val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD; - else if (height == 576) - val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD; - else if (height == 720) - val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; - else if (height == 1080) - val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD; - else - val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; - - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK); -} - -static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) -{ - struct mixer_resources *res = &ctx->mixer_res; - u32 val; - - if (height == 480) { - val = MXR_CFG_RGB601_0_255; - } else if (height == 576) { - val = MXR_CFG_RGB601_0_255; - } else if (height == 720) { - val = MXR_CFG_RGB709_16_235; - mixer_reg_write(res, MXR_CM_COEFF_Y, - (1 << 30) | (94 << 20) | (314 << 10) | - (32 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CB, - (972 << 20) | (851 << 10) | (225 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CR, - (225 << 20) | (820 << 10) | (1004 << 0)); - } else if (height == 1080) { - val = MXR_CFG_RGB709_16_235; - mixer_reg_write(res, MXR_CM_COEFF_Y, - (1 << 30) | (94 << 20) | (314 << 10) | - (32 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CB, - (972 << 20) | (851 << 10) | (225 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CR, - (225 << 20) | (820 << 10) | (1004 << 0)); - } else { - val = MXR_CFG_RGB709_16_235; - mixer_reg_write(res, MXR_CM_COEFF_Y, - (1 << 30) | (94 << 20) | (314 << 10) | - (32 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CB, - (972 << 20) | (851 << 10) | (225 << 0)); - mixer_reg_write(res, MXR_CM_COEFF_CR, - (225 << 20) | (820 << 10) | (1004 << 0)); - } - - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); -} - -static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable) -{ - struct mixer_resources *res = &ctx->mixer_res; - u32 val = enable ? ~0 : 0; - - switch (win) { - case 0: - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); - break; - case 1: - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); - break; - case 2: - vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); - mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE); - break; - } -} - -static void mixer_run(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); - - mixer_regs_dump(ctx); -} - -static void vp_video_buffer(struct mixer_context *ctx, int win) -{ - struct mixer_resources *res = &ctx->mixer_res; - unsigned long flags; - struct hdmi_win_data *win_data; - unsigned int full_width, full_height, width, height; - unsigned int x_ratio, y_ratio; - unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; - unsigned int mode_width, mode_height; - unsigned int buf_num; - dma_addr_t luma_addr[2], chroma_addr[2]; - bool tiled_mode = false; - bool crcb_mode = false; - u32 val; - - win_data = &ctx->win_data[win]; - - switch (win_data->pixel_format) { - case DRM_FORMAT_NV12MT: - tiled_mode = true; - case DRM_FORMAT_NV12M: - crcb_mode = false; - buf_num = 2; - break; - /* TODO: single buffer format NV12, NV21 */ - default: - /* ignore pixel format at disable time */ - if (!win_data->dma_addr) - break; - - DRM_ERROR("pixel format for vp is wrong [%d].\n", - win_data->pixel_format); - return; - } - - full_width = win_data->fb_width; - full_height = win_data->fb_height; - width = win_data->crtc_width; - height = win_data->crtc_height; - mode_width = win_data->mode_width; - mode_height = win_data->mode_height; - - /* scaling feature: (src << 16) / dst */ - x_ratio = (width << 16) / width; - y_ratio = (height << 16) / height; - - src_x_offset = win_data->fb_x; - src_y_offset = win_data->fb_y; - dst_x_offset = win_data->crtc_x; - dst_y_offset = win_data->crtc_y; - - if (buf_num == 2) { - luma_addr[0] = win_data->dma_addr; - chroma_addr[0] = win_data->chroma_dma_addr; - } else { - luma_addr[0] = win_data->dma_addr; - chroma_addr[0] = win_data->dma_addr - + (full_width * full_height); - } - - if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) { - ctx->interlace = true; - if (tiled_mode) { - luma_addr[1] = luma_addr[0] + 0x40; - chroma_addr[1] = chroma_addr[0] + 0x40; - } else { - luma_addr[1] = luma_addr[0] + full_width; - chroma_addr[1] = chroma_addr[0] + full_width; - } - } else { - ctx->interlace = false; - luma_addr[1] = 0; - chroma_addr[1] = 0; - } - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(ctx, false); - - /* interlace or progressive scan mode */ - val = (ctx->interlace ? ~0 : 0); - vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP); - - /* setup format */ - val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12); - val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR); - vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); - - /* setting size of input image */ - vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(full_width) | - VP_IMG_VSIZE(full_height)); - /* chroma height has to reduced by 2 to avoid chroma distorions */ - vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(full_width) | - VP_IMG_VSIZE(full_height / 2)); - - vp_reg_write(res, VP_SRC_WIDTH, width); - vp_reg_write(res, VP_SRC_HEIGHT, height); - vp_reg_write(res, VP_SRC_H_POSITION, - VP_SRC_H_POSITION_VAL(src_x_offset)); - vp_reg_write(res, VP_SRC_V_POSITION, src_y_offset); - - vp_reg_write(res, VP_DST_WIDTH, width); - vp_reg_write(res, VP_DST_H_POSITION, dst_x_offset); - if (ctx->interlace) { - vp_reg_write(res, VP_DST_HEIGHT, height / 2); - vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset / 2); - } else { - vp_reg_write(res, VP_DST_HEIGHT, height); - vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset); - } - - vp_reg_write(res, VP_H_RATIO, x_ratio); - vp_reg_write(res, VP_V_RATIO, y_ratio); - - vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); - - /* set buffer address to vp */ - vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]); - vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]); - vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); - vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); - - mixer_cfg_scan(ctx, mode_height); - mixer_cfg_rgb_fmt(ctx, mode_height); - mixer_cfg_layer(ctx, win, true); - mixer_run(ctx); - - mixer_vsync_set_update(ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); - - vp_regs_dump(ctx); -} - -static void mixer_graph_buffer(struct mixer_context *ctx, int win) -{ - struct mixer_resources *res = &ctx->mixer_res; - unsigned long flags; - struct hdmi_win_data *win_data; - unsigned int full_width, width, height; - unsigned int x_ratio, y_ratio; - unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; - unsigned int mode_width, mode_height; - dma_addr_t dma_addr; - unsigned int fmt; - u32 val; - - win_data = &ctx->win_data[win]; - - #define RGB565 4 - #define ARGB1555 5 - #define ARGB4444 6 - #define ARGB8888 7 - - switch (win_data->bpp) { - case 16: - fmt = ARGB4444; - break; - case 32: - fmt = ARGB8888; - break; - default: - fmt = ARGB8888; - } - - dma_addr = win_data->dma_addr; - full_width = win_data->fb_width; - width = win_data->crtc_width; - height = win_data->crtc_height; - mode_width = win_data->mode_width; - mode_height = win_data->mode_height; - - /* 2x scaling feature */ - x_ratio = 0; - y_ratio = 0; - - src_x_offset = win_data->fb_x; - src_y_offset = win_data->fb_y; - dst_x_offset = win_data->crtc_x; - dst_y_offset = win_data->crtc_y; - - /* converting dma address base and source offset */ - dma_addr = dma_addr - + (src_x_offset * win_data->bpp >> 3) - + (src_y_offset * full_width * win_data->bpp >> 3); - src_x_offset = 0; - src_y_offset = 0; - - if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) - ctx->interlace = true; - else - ctx->interlace = false; - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(ctx, false); - - /* setup format */ - mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), - MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK); - - /* setup geometry */ - mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), full_width); - - val = MXR_GRP_WH_WIDTH(width); - val |= MXR_GRP_WH_HEIGHT(height); - val |= MXR_GRP_WH_H_SCALE(x_ratio); - val |= MXR_GRP_WH_V_SCALE(y_ratio); - mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); - - /* setup offsets in source image */ - val = MXR_GRP_SXY_SX(src_x_offset); - val |= MXR_GRP_SXY_SY(src_y_offset); - mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val); - - /* setup offsets in display image */ - val = MXR_GRP_DXY_DX(dst_x_offset); - val |= MXR_GRP_DXY_DY(dst_y_offset); - mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val); - - /* set buffer address to mixer */ - mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); - - mixer_cfg_scan(ctx, mode_height); - mixer_cfg_rgb_fmt(ctx, mode_height); - mixer_cfg_layer(ctx, win, true); - mixer_run(ctx); - - mixer_vsync_set_update(ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); -} - -static void vp_win_reset(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - int tries = 100; - - vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING); - for (tries = 100; tries; --tries) { - /* waiting until VP_SRESET_PROCESSING is 0 */ - if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING) - break; - mdelay(10); - } - WARN(tries == 0, "failed to reset Video Processor\n"); -} - -static int mixer_enable_vblank(void *ctx, int pipe) -{ - struct mixer_context *mixer_ctx = ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - mixer_ctx->pipe = pipe; - - /* enable vsync interrupt */ - mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC, - MXR_INT_EN_VSYNC); - - return 0; -} - -static void mixer_disable_vblank(void *ctx) -{ - struct mixer_context *mixer_ctx = ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - /* disable vsync interrupt */ - mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); -} - -static void mixer_win_mode_set(void *ctx, - struct exynos_drm_overlay *overlay) -{ - struct mixer_context *mixer_ctx = ctx; - struct hdmi_win_data *win_data; - int win; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - if (!overlay) { - DRM_ERROR("overlay is NULL\n"); - return; - } - - DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n", - overlay->fb_width, overlay->fb_height, - overlay->fb_x, overlay->fb_y, - overlay->crtc_width, overlay->crtc_height, - overlay->crtc_x, overlay->crtc_y); - - win = overlay->zpos; - if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; - - if (win < 0 || win > MIXER_WIN_NR) { - DRM_ERROR("overlay plane[%d] is wrong\n", win); - return; - } - - win_data = &mixer_ctx->win_data[win]; - - win_data->dma_addr = overlay->dma_addr[0]; - win_data->vaddr = overlay->vaddr[0]; - win_data->chroma_dma_addr = overlay->dma_addr[1]; - win_data->chroma_vaddr = overlay->vaddr[1]; - win_data->pixel_format = overlay->pixel_format; - win_data->bpp = overlay->bpp; - - win_data->crtc_x = overlay->crtc_x; - win_data->crtc_y = overlay->crtc_y; - win_data->crtc_width = overlay->crtc_width; - win_data->crtc_height = overlay->crtc_height; - - win_data->fb_x = overlay->fb_x; - win_data->fb_y = overlay->fb_y; - win_data->fb_width = overlay->fb_width; - win_data->fb_height = overlay->fb_height; - - win_data->mode_width = overlay->mode_width; - win_data->mode_height = overlay->mode_height; - - win_data->scan_flags = overlay->scan_flag; -} - -static void mixer_win_commit(void *ctx, int zpos) -{ - struct mixer_context *mixer_ctx = ctx; - int win = zpos; - - DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); - - if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; - - if (win < 0 || win > MIXER_WIN_NR) { - DRM_ERROR("overlay plane[%d] is wrong\n", win); - return; - } - - if (win > 1) - vp_video_buffer(mixer_ctx, win); - else - mixer_graph_buffer(mixer_ctx, win); -} - -static void mixer_win_disable(void *ctx, int zpos) -{ - struct mixer_context *mixer_ctx = ctx; - struct mixer_resources *res = &mixer_ctx->mixer_res; - unsigned long flags; - int win = zpos; - - DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); - - if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; - - if (win < 0 || win > MIXER_WIN_NR) { - DRM_ERROR("overlay plane[%d] is wrong\n", win); - return; - } - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(mixer_ctx, false); - - mixer_cfg_layer(mixer_ctx, win, false); - - mixer_vsync_set_update(mixer_ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); -} - -static struct exynos_mixer_ops mixer_ops = { - /* manager */ - .enable_vblank = mixer_enable_vblank, - .disable_vblank = mixer_disable_vblank, - - /* overlay */ - .win_mode_set = mixer_win_mode_set, - .win_commit = mixer_win_commit, - .win_disable = mixer_win_disable, -}; - -/* for pageflip event */ -static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) -{ - struct exynos_drm_private *dev_priv = drm_dev->dev_private; - struct drm_pending_vblank_event *e, *t; - struct timeval now; - unsigned long flags; - bool is_checked = false; - - spin_lock_irqsave(&drm_dev->event_lock, flags); - - list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list, - base.link) { - /* if event's pipe isn't same as crtc then ignore it. */ - if (crtc != e->pipe) - continue; - - is_checked = true; - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - - list_move_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - if (is_checked) - /* - * call drm_vblank_put only in case that drm_vblank_get was - * called. - */ - if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) - drm_vblank_put(drm_dev, crtc); - - spin_unlock_irqrestore(&drm_dev->event_lock, flags); -} - -static irqreturn_t mixer_irq_handler(int irq, void *arg) -{ - struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; - struct mixer_context *ctx = drm_hdmi_ctx->ctx; - struct mixer_resources *res = &ctx->mixer_res; - u32 val, val_base; - - spin_lock(&res->reg_slock); - - /* read interrupt status for handling and clearing flags for VSYNC */ - val = mixer_reg_read(res, MXR_INT_STATUS); - - /* handling VSYNC */ - if (val & MXR_INT_STATUS_VSYNC) { - /* interlace scan need to check shadow register */ - if (ctx->interlace) { - val_base = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0)); - if (ctx->win_data[0].dma_addr != val_base) - goto out; - - val_base = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1)); - if (ctx->win_data[1].dma_addr != val_base) - goto out; - } - - drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe); - mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe); - } - -out: - /* clear interrupts */ - if (~val & MXR_INT_EN_VSYNC) { - /* vsync interrupt use different bit for read and clear */ - val &= ~MXR_INT_EN_VSYNC; - val |= MXR_INT_CLEAR_VSYNC; - } - mixer_reg_write(res, MXR_INT_STATUS, val); - - spin_unlock(&res->reg_slock); - - return IRQ_HANDLED; -} - -static void mixer_win_reset(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - unsigned long flags; - u32 val; /* value stored to register */ - - spin_lock_irqsave(&res->reg_slock, flags); - mixer_vsync_set_update(ctx, false); - - mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); - - /* set output in RGB888 mode */ - mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK); - - /* 16 beat burst in DMA */ - mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, - MXR_STATUS_BURST_MASK); - - /* setting default layer priority: layer1 > layer0 > video - * because typical usage scenario would be - * layer1 - OSD - * layer0 - framebuffer - * video - video overlay - */ - val = MXR_LAYER_CFG_GRP1_VAL(3); - val |= MXR_LAYER_CFG_GRP0_VAL(2); - val |= MXR_LAYER_CFG_VP_VAL(1); - mixer_reg_write(res, MXR_LAYER_CFG, val); - - /* setting background color */ - mixer_reg_write(res, MXR_BG_COLOR0, 0x008080); - mixer_reg_write(res, MXR_BG_COLOR1, 0x008080); - mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); - - /* setting graphical layers */ - - val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ - val |= MXR_GRP_CFG_WIN_BLEND_EN; - val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ - - /* the same configuration for both layers */ - mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); - - val |= MXR_GRP_CFG_BLEND_PRE_MUL; - val |= MXR_GRP_CFG_PIXEL_BLEND_EN; - mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); - - /* configuration of Video Processor Registers */ - vp_win_reset(ctx); - vp_default_filter(res); - - /* disable all layers */ - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); - mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); - - mixer_vsync_set_update(ctx, true); - spin_unlock_irqrestore(&res->reg_slock, flags); -} - -static void mixer_resource_poweron(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - clk_enable(res->mixer); - clk_enable(res->vp); - clk_enable(res->sclk_mixer); - - mixer_win_reset(ctx); -} - -static void mixer_resource_poweroff(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); - - clk_disable(res->mixer); - clk_disable(res->vp); - clk_disable(res->sclk_mixer); -} - -static int mixer_runtime_resume(struct device *dev) -{ - struct exynos_drm_hdmi_context *ctx = get_mixer_context(dev); - - DRM_DEBUG_KMS("resume - start\n"); - - mixer_resource_poweron(ctx->ctx); - - return 0; -} - -static int mixer_runtime_suspend(struct device *dev) -{ - struct exynos_drm_hdmi_context *ctx = get_mixer_context(dev); - - DRM_DEBUG_KMS("suspend - start\n"); - - mixer_resource_poweroff(ctx->ctx); - - return 0; -} - -static const struct dev_pm_ops mixer_pm_ops = { - .runtime_suspend = mixer_runtime_suspend, - .runtime_resume = mixer_runtime_resume, -}; - -static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, - struct platform_device *pdev) -{ - struct mixer_context *mixer_ctx = ctx->ctx; - struct device *dev = &pdev->dev; - struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; - struct resource *res; - int ret; - - mixer_res->dev = dev; - spin_lock_init(&mixer_res->reg_slock); - - mixer_res->mixer = clk_get(dev, "mixer"); - if (IS_ERR_OR_NULL(mixer_res->mixer)) { - dev_err(dev, "failed to get clock 'mixer'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->vp = clk_get(dev, "vp"); - if (IS_ERR_OR_NULL(mixer_res->vp)) { - dev_err(dev, "failed to get clock 'vp'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer"); - if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) { - dev_err(dev, "failed to get clock 'sclk_mixer'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); - if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) { - dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); - ret = -ENODEV; - goto fail; - } - mixer_res->sclk_dac = clk_get(dev, "sclk_dac"); - if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) { - dev_err(dev, "failed to get clock 'sclk_dac'\n"); - ret = -ENODEV; - goto fail; - } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr"); - if (res == NULL) { - dev_err(dev, "get memory resource failed.\n"); - ret = -ENXIO; - goto fail; - } - - clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi); - - mixer_res->mixer_regs = ioremap(res->start, resource_size(res)); - if (mixer_res->mixer_regs == NULL) { - dev_err(dev, "register mapping failed.\n"); - ret = -ENXIO; - goto fail; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp"); - if (res == NULL) { - dev_err(dev, "get memory resource failed.\n"); - ret = -ENXIO; - goto fail_mixer_regs; - } - - mixer_res->vp_regs = ioremap(res->start, resource_size(res)); - if (mixer_res->vp_regs == NULL) { - dev_err(dev, "register mapping failed.\n"); - ret = -ENXIO; - goto fail_mixer_regs; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq"); - if (res == NULL) { - dev_err(dev, "get interrupt resource failed.\n"); - ret = -ENXIO; - goto fail_vp_regs; - } - - ret = request_irq(res->start, mixer_irq_handler, 0, "drm_mixer", ctx); - if (ret) { - dev_err(dev, "request interrupt failed.\n"); - goto fail_vp_regs; - } - mixer_res->irq = res->start; - - return 0; - -fail_vp_regs: - iounmap(mixer_res->vp_regs); - -fail_mixer_regs: - iounmap(mixer_res->mixer_regs); - -fail: - if (!IS_ERR_OR_NULL(mixer_res->sclk_dac)) - clk_put(mixer_res->sclk_dac); - if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) - clk_put(mixer_res->sclk_hdmi); - if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer)) - clk_put(mixer_res->sclk_mixer); - if (!IS_ERR_OR_NULL(mixer_res->vp)) - clk_put(mixer_res->vp); - if (!IS_ERR_OR_NULL(mixer_res->mixer)) - clk_put(mixer_res->mixer); - mixer_res->dev = NULL; - return ret; -} - -static void mixer_resources_cleanup(struct mixer_context *ctx) -{ - struct mixer_resources *res = &ctx->mixer_res; - - disable_irq(res->irq); - free_irq(res->irq, ctx); - - iounmap(res->vp_regs); - iounmap(res->mixer_regs); -} - -static int __devinit mixer_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *drm_hdmi_ctx; - struct mixer_context *ctx; - int ret; - - dev_info(dev, "probe start\n"); - - drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL); - if (!drm_hdmi_ctx) { - DRM_ERROR("failed to allocate common hdmi context.\n"); - return -ENOMEM; - } - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - DRM_ERROR("failed to alloc mixer context.\n"); - kfree(drm_hdmi_ctx); - return -ENOMEM; - } - - drm_hdmi_ctx->ctx = (void *)ctx; - - platform_set_drvdata(pdev, drm_hdmi_ctx); - - /* acquire resources: regs, irqs, clocks */ - ret = mixer_resources_init(drm_hdmi_ctx, pdev); - if (ret) - goto fail; - - /* register specific callback point to common hdmi. */ - exynos_mixer_ops_register(&mixer_ops); - - mixer_resource_poweron(ctx); - - return 0; - - -fail: - dev_info(dev, "probe failed\n"); - return ret; -} - -static int mixer_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct exynos_drm_hdmi_context *drm_hdmi_ctx = - platform_get_drvdata(pdev); - struct mixer_context *ctx = drm_hdmi_ctx->ctx; - - dev_info(dev, "remove successful\n"); - - mixer_resource_poweroff(ctx); - mixer_resources_cleanup(ctx); - - return 0; -} - -struct platform_driver mixer_driver = { - .driver = { - .name = "s5p-mixer", - .owner = THIS_MODULE, - .pm = &mixer_pm_ops, - }, - .probe = mixer_probe, - .remove = __devexit_p(mixer_remove), -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-hdmi.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-hdmi.h deleted file mode 100644 index 3c04bea8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-hdmi.h +++ /dev/null @@ -1,561 +0,0 @@ -/* - * - * Cloned from drivers/media/video/s5p-tv/regs-hdmi.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * HDMI register header file for Samsung TVOUT driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef SAMSUNG_REGS_HDMI_H -#define SAMSUNG_REGS_HDMI_H - -/* - * Register part -*/ - -/* HDMI Version 1.3 & Common */ -#define HDMI_CTRL_BASE(x) ((x) + 0x00000000) -#define HDMI_CORE_BASE(x) ((x) + 0x00010000) -#define HDMI_I2S_BASE(x) ((x) + 0x00040000) -#define HDMI_TG_BASE(x) ((x) + 0x00050000) - -/* Control registers */ -#define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000) -#define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004) -#define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C) -#define HDMI_V13_PHY_RSTOUT HDMI_CTRL_BASE(0x0014) -#define HDMI_V13_PHY_VPLL HDMI_CTRL_BASE(0x0018) -#define HDMI_V13_PHY_CMU HDMI_CTRL_BASE(0x001C) -#define HDMI_V13_CORE_RSTOUT HDMI_CTRL_BASE(0x0020) - -/* Core registers */ -#define HDMI_CON_0 HDMI_CORE_BASE(0x0000) -#define HDMI_CON_1 HDMI_CORE_BASE(0x0004) -#define HDMI_CON_2 HDMI_CORE_BASE(0x0008) -#define HDMI_SYS_STATUS HDMI_CORE_BASE(0x0010) -#define HDMI_V13_PHY_STATUS HDMI_CORE_BASE(0x0014) -#define HDMI_STATUS_EN HDMI_CORE_BASE(0x0020) -#define HDMI_HPD HDMI_CORE_BASE(0x0030) -#define HDMI_MODE_SEL HDMI_CORE_BASE(0x0040) -#define HDMI_ENC_EN HDMI_CORE_BASE(0x0044) -#define HDMI_V13_BLUE_SCREEN_0 HDMI_CORE_BASE(0x0050) -#define HDMI_V13_BLUE_SCREEN_1 HDMI_CORE_BASE(0x0054) -#define HDMI_V13_BLUE_SCREEN_2 HDMI_CORE_BASE(0x0058) -#define HDMI_H_BLANK_0 HDMI_CORE_BASE(0x00A0) -#define HDMI_H_BLANK_1 HDMI_CORE_BASE(0x00A4) -#define HDMI_V13_V_BLANK_0 HDMI_CORE_BASE(0x00B0) -#define HDMI_V13_V_BLANK_1 HDMI_CORE_BASE(0x00B4) -#define HDMI_V13_V_BLANK_2 HDMI_CORE_BASE(0x00B8) -#define HDMI_V13_H_V_LINE_0 HDMI_CORE_BASE(0x00C0) -#define HDMI_V13_H_V_LINE_1 HDMI_CORE_BASE(0x00C4) -#define HDMI_V13_H_V_LINE_2 HDMI_CORE_BASE(0x00C8) -#define HDMI_VSYNC_POL HDMI_CORE_BASE(0x00E4) -#define HDMI_INT_PRO_MODE HDMI_CORE_BASE(0x00E8) -#define HDMI_V13_V_BLANK_F_0 HDMI_CORE_BASE(0x0110) -#define HDMI_V13_V_BLANK_F_1 HDMI_CORE_BASE(0x0114) -#define HDMI_V13_V_BLANK_F_2 HDMI_CORE_BASE(0x0118) -#define HDMI_V13_H_SYNC_GEN_0 HDMI_CORE_BASE(0x0120) -#define HDMI_V13_H_SYNC_GEN_1 HDMI_CORE_BASE(0x0124) -#define HDMI_V13_H_SYNC_GEN_2 HDMI_CORE_BASE(0x0128) -#define HDMI_V13_V_SYNC_GEN_1_0 HDMI_CORE_BASE(0x0130) -#define HDMI_V13_V_SYNC_GEN_1_1 HDMI_CORE_BASE(0x0134) -#define HDMI_V13_V_SYNC_GEN_1_2 HDMI_CORE_BASE(0x0138) -#define HDMI_V13_V_SYNC_GEN_2_0 HDMI_CORE_BASE(0x0140) -#define HDMI_V13_V_SYNC_GEN_2_1 HDMI_CORE_BASE(0x0144) -#define HDMI_V13_V_SYNC_GEN_2_2 HDMI_CORE_BASE(0x0148) -#define HDMI_V13_V_SYNC_GEN_3_0 HDMI_CORE_BASE(0x0150) -#define HDMI_V13_V_SYNC_GEN_3_1 HDMI_CORE_BASE(0x0154) -#define HDMI_V13_V_SYNC_GEN_3_2 HDMI_CORE_BASE(0x0158) -#define HDMI_V13_ACR_CON HDMI_CORE_BASE(0x0180) -#define HDMI_V13_AVI_CON HDMI_CORE_BASE(0x0300) -#define HDMI_V13_AVI_BYTE(n) HDMI_CORE_BASE(0x0320 + 4 * (n)) -#define HDMI_V13_DC_CONTROL HDMI_CORE_BASE(0x05C0) -#define HDMI_V13_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x05C4) -#define HDMI_V13_HPD_GEN HDMI_CORE_BASE(0x05C8) -#define HDMI_V13_AUI_CON HDMI_CORE_BASE(0x0360) -#define HDMI_V13_SPD_CON HDMI_CORE_BASE(0x0400) - -/* Timing generator registers */ -#define HDMI_TG_CMD HDMI_TG_BASE(0x0000) -#define HDMI_TG_H_FSZ_L HDMI_TG_BASE(0x0018) -#define HDMI_TG_H_FSZ_H HDMI_TG_BASE(0x001C) -#define HDMI_TG_HACT_ST_L HDMI_TG_BASE(0x0020) -#define HDMI_TG_HACT_ST_H HDMI_TG_BASE(0x0024) -#define HDMI_TG_HACT_SZ_L HDMI_TG_BASE(0x0028) -#define HDMI_TG_HACT_SZ_H HDMI_TG_BASE(0x002C) -#define HDMI_TG_V_FSZ_L HDMI_TG_BASE(0x0030) -#define HDMI_TG_V_FSZ_H HDMI_TG_BASE(0x0034) -#define HDMI_TG_VSYNC_L HDMI_TG_BASE(0x0038) -#define HDMI_TG_VSYNC_H HDMI_TG_BASE(0x003C) -#define HDMI_TG_VSYNC2_L HDMI_TG_BASE(0x0040) -#define HDMI_TG_VSYNC2_H HDMI_TG_BASE(0x0044) -#define HDMI_TG_VACT_ST_L HDMI_TG_BASE(0x0048) -#define HDMI_TG_VACT_ST_H HDMI_TG_BASE(0x004C) -#define HDMI_TG_VACT_SZ_L HDMI_TG_BASE(0x0050) -#define HDMI_TG_VACT_SZ_H HDMI_TG_BASE(0x0054) -#define HDMI_TG_FIELD_CHG_L HDMI_TG_BASE(0x0058) -#define HDMI_TG_FIELD_CHG_H HDMI_TG_BASE(0x005C) -#define HDMI_TG_VACT_ST2_L HDMI_TG_BASE(0x0060) -#define HDMI_TG_VACT_ST2_H HDMI_TG_BASE(0x0064) -#define HDMI_TG_VSYNC_TOP_HDMI_L HDMI_TG_BASE(0x0078) -#define HDMI_TG_VSYNC_TOP_HDMI_H HDMI_TG_BASE(0x007C) -#define HDMI_TG_VSYNC_BOT_HDMI_L HDMI_TG_BASE(0x0080) -#define HDMI_TG_VSYNC_BOT_HDMI_H HDMI_TG_BASE(0x0084) -#define HDMI_TG_FIELD_TOP_HDMI_L HDMI_TG_BASE(0x0088) -#define HDMI_TG_FIELD_TOP_HDMI_H HDMI_TG_BASE(0x008C) -#define HDMI_TG_FIELD_BOT_HDMI_L HDMI_TG_BASE(0x0090) -#define HDMI_TG_FIELD_BOT_HDMI_H HDMI_TG_BASE(0x0094) - -/* - * Bit definition part - */ - -/* HDMI_INTC_CON */ -#define HDMI_INTC_EN_GLOBAL (1 << 6) -#define HDMI_INTC_EN_HPD_PLUG (1 << 3) -#define HDMI_INTC_EN_HPD_UNPLUG (1 << 2) - -/* HDMI_INTC_FLAG */ -#define HDMI_INTC_FLAG_HPD_PLUG (1 << 3) -#define HDMI_INTC_FLAG_HPD_UNPLUG (1 << 2) - -/* HDMI_PHY_RSTOUT */ -#define HDMI_PHY_SW_RSTOUT (1 << 0) - -/* HDMI_CORE_RSTOUT */ -#define HDMI_CORE_SW_RSTOUT (1 << 0) - -/* HDMI_CON_0 */ -#define HDMI_BLUE_SCR_EN (1 << 5) -#define HDMI_ASP_EN (1 << 2) -#define HDMI_ASP_DIS (0 << 2) -#define HDMI_ASP_MASK (1 << 2) -#define HDMI_EN (1 << 0) - -/* HDMI_PHY_STATUS */ -#define HDMI_PHY_STATUS_READY (1 << 0) - -/* HDMI_MODE_SEL */ -#define HDMI_MODE_HDMI_EN (1 << 1) -#define HDMI_MODE_DVI_EN (1 << 0) -#define HDMI_DVI_MODE_EN (1) -#define HDMI_DVI_MODE_DIS (0) -#define HDMI_MODE_MASK (3 << 0) - -/* HDMI_TG_CMD */ -#define HDMI_TG_EN (1 << 0) -#define HDMI_FIELD_EN (1 << 1) - - -/* HDMI Version 1.4 */ -/* Control registers */ -/* #define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000) */ -/* #define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004) */ -#define HDMI_HDCP_KEY_LOAD HDMI_CTRL_BASE(0x0008) -/* #define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C) */ -#define HDMI_INTC_CON_1 HDMI_CTRL_BASE(0x0010) -#define HDMI_INTC_FLAG_1 HDMI_CTRL_BASE(0x0014) -#define HDMI_PHY_STATUS_0 HDMI_CTRL_BASE(0x0020) -#define HDMI_PHY_STATUS_CMU HDMI_CTRL_BASE(0x0024) -#define HDMI_PHY_STATUS_PLL HDMI_CTRL_BASE(0x0028) -#define HDMI_PHY_CON_0 HDMI_CTRL_BASE(0x0030) -#define HDMI_HPD_CTRL HDMI_CTRL_BASE(0x0040) -#define HDMI_HPD_ST HDMI_CTRL_BASE(0x0044) -#define HDMI_HPD_TH_X HDMI_CTRL_BASE(0x0050) -#define HDMI_AUDIO_CLKSEL HDMI_CTRL_BASE(0x0070) -#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0074) -#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0078) -#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x007C) -#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0080) - -/* Video related registers */ -#define HDMI_YMAX HDMI_CORE_BASE(0x0060) -#define HDMI_YMIN HDMI_CORE_BASE(0x0064) -#define HDMI_CMAX HDMI_CORE_BASE(0x0068) -#define HDMI_CMIN HDMI_CORE_BASE(0x006C) - -#define HDMI_V2_BLANK_0 HDMI_CORE_BASE(0x00B0) -#define HDMI_V2_BLANK_1 HDMI_CORE_BASE(0x00B4) -#define HDMI_V1_BLANK_0 HDMI_CORE_BASE(0x00B8) -#define HDMI_V1_BLANK_1 HDMI_CORE_BASE(0x00BC) - -#define HDMI_V_LINE_0 HDMI_CORE_BASE(0x00C0) -#define HDMI_V_LINE_1 HDMI_CORE_BASE(0x00C4) -#define HDMI_H_LINE_0 HDMI_CORE_BASE(0x00C8) -#define HDMI_H_LINE_1 HDMI_CORE_BASE(0x00CC) - -#define HDMI_HSYNC_POL HDMI_CORE_BASE(0x00E0) - -#define HDMI_V_BLANK_F0_0 HDMI_CORE_BASE(0x0110) -#define HDMI_V_BLANK_F0_1 HDMI_CORE_BASE(0x0114) -#define HDMI_V_BLANK_F1_0 HDMI_CORE_BASE(0x0118) -#define HDMI_V_BLANK_F1_1 HDMI_CORE_BASE(0x011C) - -#define HDMI_H_SYNC_START_0 HDMI_CORE_BASE(0x0120) -#define HDMI_H_SYNC_START_1 HDMI_CORE_BASE(0x0124) -#define HDMI_H_SYNC_END_0 HDMI_CORE_BASE(0x0128) -#define HDMI_H_SYNC_END_1 HDMI_CORE_BASE(0x012C) - -#define HDMI_V_SYNC_LINE_BEF_2_0 HDMI_CORE_BASE(0x0130) -#define HDMI_V_SYNC_LINE_BEF_2_1 HDMI_CORE_BASE(0x0134) -#define HDMI_V_SYNC_LINE_BEF_1_0 HDMI_CORE_BASE(0x0138) -#define HDMI_V_SYNC_LINE_BEF_1_1 HDMI_CORE_BASE(0x013C) - -#define HDMI_V_SYNC_LINE_AFT_2_0 HDMI_CORE_BASE(0x0140) -#define HDMI_V_SYNC_LINE_AFT_2_1 HDMI_CORE_BASE(0x0144) -#define HDMI_V_SYNC_LINE_AFT_1_0 HDMI_CORE_BASE(0x0148) -#define HDMI_V_SYNC_LINE_AFT_1_1 HDMI_CORE_BASE(0x014C) - -#define HDMI_V_SYNC_LINE_AFT_PXL_2_0 HDMI_CORE_BASE(0x0150) -#define HDMI_V_SYNC_LINE_AFT_PXL_2_1 HDMI_CORE_BASE(0x0154) -#define HDMI_V_SYNC_LINE_AFT_PXL_1_0 HDMI_CORE_BASE(0x0158) -#define HDMI_V_SYNC_LINE_AFT_PXL_1_1 HDMI_CORE_BASE(0x015C) - -#define HDMI_V_BLANK_F2_0 HDMI_CORE_BASE(0x0160) -#define HDMI_V_BLANK_F2_1 HDMI_CORE_BASE(0x0164) -#define HDMI_V_BLANK_F3_0 HDMI_CORE_BASE(0x0168) -#define HDMI_V_BLANK_F3_1 HDMI_CORE_BASE(0x016C) -#define HDMI_V_BLANK_F4_0 HDMI_CORE_BASE(0x0170) -#define HDMI_V_BLANK_F4_1 HDMI_CORE_BASE(0x0174) -#define HDMI_V_BLANK_F5_0 HDMI_CORE_BASE(0x0178) -#define HDMI_V_BLANK_F5_1 HDMI_CORE_BASE(0x017C) - -#define HDMI_V_SYNC_LINE_AFT_3_0 HDMI_CORE_BASE(0x0180) -#define HDMI_V_SYNC_LINE_AFT_3_1 HDMI_CORE_BASE(0x0184) -#define HDMI_V_SYNC_LINE_AFT_4_0 HDMI_CORE_BASE(0x0188) -#define HDMI_V_SYNC_LINE_AFT_4_1 HDMI_CORE_BASE(0x018C) -#define HDMI_V_SYNC_LINE_AFT_5_0 HDMI_CORE_BASE(0x0190) -#define HDMI_V_SYNC_LINE_AFT_5_1 HDMI_CORE_BASE(0x0194) -#define HDMI_V_SYNC_LINE_AFT_6_0 HDMI_CORE_BASE(0x0198) -#define HDMI_V_SYNC_LINE_AFT_6_1 HDMI_CORE_BASE(0x019C) - -#define HDMI_V_SYNC_LINE_AFT_PXL_3_0 HDMI_CORE_BASE(0x01A0) -#define HDMI_V_SYNC_LINE_AFT_PXL_3_1 HDMI_CORE_BASE(0x01A4) -#define HDMI_V_SYNC_LINE_AFT_PXL_4_0 HDMI_CORE_BASE(0x01A8) -#define HDMI_V_SYNC_LINE_AFT_PXL_4_1 HDMI_CORE_BASE(0x01AC) -#define HDMI_V_SYNC_LINE_AFT_PXL_5_0 HDMI_CORE_BASE(0x01B0) -#define HDMI_V_SYNC_LINE_AFT_PXL_5_1 HDMI_CORE_BASE(0x01B4) -#define HDMI_V_SYNC_LINE_AFT_PXL_6_0 HDMI_CORE_BASE(0x01B8) -#define HDMI_V_SYNC_LINE_AFT_PXL_6_1 HDMI_CORE_BASE(0x01BC) - -#define HDMI_VACT_SPACE_1_0 HDMI_CORE_BASE(0x01C0) -#define HDMI_VACT_SPACE_1_1 HDMI_CORE_BASE(0x01C4) -#define HDMI_VACT_SPACE_2_0 HDMI_CORE_BASE(0x01C8) -#define HDMI_VACT_SPACE_2_1 HDMI_CORE_BASE(0x01CC) -#define HDMI_VACT_SPACE_3_0 HDMI_CORE_BASE(0x01D0) -#define HDMI_VACT_SPACE_3_1 HDMI_CORE_BASE(0x01D4) -#define HDMI_VACT_SPACE_4_0 HDMI_CORE_BASE(0x01D8) -#define HDMI_VACT_SPACE_4_1 HDMI_CORE_BASE(0x01DC) -#define HDMI_VACT_SPACE_5_0 HDMI_CORE_BASE(0x01E0) -#define HDMI_VACT_SPACE_5_1 HDMI_CORE_BASE(0x01E4) -#define HDMI_VACT_SPACE_6_0 HDMI_CORE_BASE(0x01E8) -#define HDMI_VACT_SPACE_6_1 HDMI_CORE_BASE(0x01EC) - -#define HDMI_GCP_CON HDMI_CORE_BASE(0x0200) -#define HDMI_GCP_BYTE1 HDMI_CORE_BASE(0x0210) -#define HDMI_GCP_BYTE2 HDMI_CORE_BASE(0x0214) -#define HDMI_GCP_BYTE3 HDMI_CORE_BASE(0x0218) - -/* Audio related registers */ -#define HDMI_ASP_CON HDMI_CORE_BASE(0x0300) -#define HDMI_ASP_SP_FLAT HDMI_CORE_BASE(0x0304) -#define HDMI_ASP_CHCFG0 HDMI_CORE_BASE(0x0310) -#define HDMI_ASP_CHCFG1 HDMI_CORE_BASE(0x0314) -#define HDMI_ASP_CHCFG2 HDMI_CORE_BASE(0x0318) -#define HDMI_ASP_CHCFG3 HDMI_CORE_BASE(0x031C) - -#define HDMI_ACR_CON HDMI_CORE_BASE(0x0400) -#define HDMI_ACR_MCTS0 HDMI_CORE_BASE(0x0410) -#define HDMI_ACR_MCTS1 HDMI_CORE_BASE(0x0414) -#define HDMI_ACR_MCTS2 HDMI_CORE_BASE(0x0418) -#define HDMI_ACR_CTS0 HDMI_CORE_BASE(0x0420) -#define HDMI_ACR_CTS1 HDMI_CORE_BASE(0x0424) -#define HDMI_ACR_CTS2 HDMI_CORE_BASE(0x0428) -#define HDMI_ACR_N0 HDMI_CORE_BASE(0x0430) -#define HDMI_ACR_N1 HDMI_CORE_BASE(0x0434) -#define HDMI_ACR_N2 HDMI_CORE_BASE(0x0438) - -/* Packet related registers */ -#define HDMI_ACP_CON HDMI_CORE_BASE(0x0500) -#define HDMI_ACP_TYPE HDMI_CORE_BASE(0x0514) -#define HDMI_ACP_DATA(n) HDMI_CORE_BASE(0x0520 + 4 * (n)) - -#define HDMI_ISRC_CON HDMI_CORE_BASE(0x0600) -#define HDMI_ISRC1_HEADER1 HDMI_CORE_BASE(0x0614) -#define HDMI_ISRC1_DATA(n) HDMI_CORE_BASE(0x0620 + 4 * (n)) -#define HDMI_ISRC2_DATA(n) HDMI_CORE_BASE(0x06A0 + 4 * (n)) - -#define HDMI_AVI_CON HDMI_CORE_BASE(0x0700) -#define HDMI_AVI_HEADER0 HDMI_CORE_BASE(0x0710) -#define HDMI_AVI_HEADER1 HDMI_CORE_BASE(0x0714) -#define HDMI_AVI_HEADER2 HDMI_CORE_BASE(0x0718) -#define HDMI_AVI_CHECK_SUM HDMI_CORE_BASE(0x071C) -#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0720 + 4 * (n)) - -#define HDMI_AUI_CON HDMI_CORE_BASE(0x0800) -#define HDMI_AUI_HEADER0 HDMI_CORE_BASE(0x0810) -#define HDMI_AUI_HEADER1 HDMI_CORE_BASE(0x0814) -#define HDMI_AUI_HEADER2 HDMI_CORE_BASE(0x0818) -#define HDMI_AUI_CHECK_SUM HDMI_CORE_BASE(0x081C) -#define HDMI_AUI_BYTE(n) HDMI_CORE_BASE(0x0820 + 4 * (n)) - -#define HDMI_MPG_CON HDMI_CORE_BASE(0x0900) -#define HDMI_MPG_CHECK_SUM HDMI_CORE_BASE(0x091C) -#define HDMI_MPG_DATA(n) HDMI_CORE_BASE(0x0920 + 4 * (n)) - -#define HDMI_SPD_CON HDMI_CORE_BASE(0x0A00) -#define HDMI_SPD_HEADER0 HDMI_CORE_BASE(0x0A10) -#define HDMI_SPD_HEADER1 HDMI_CORE_BASE(0x0A14) -#define HDMI_SPD_HEADER2 HDMI_CORE_BASE(0x0A18) -#define HDMI_SPD_DATA(n) HDMI_CORE_BASE(0x0A20 + 4 * (n)) - -#define HDMI_GAMUT_CON HDMI_CORE_BASE(0x0B00) -#define HDMI_GAMUT_HEADER0 HDMI_CORE_BASE(0x0B10) -#define HDMI_GAMUT_HEADER1 HDMI_CORE_BASE(0x0B14) -#define HDMI_GAMUT_HEADER2 HDMI_CORE_BASE(0x0B18) -#define HDMI_GAMUT_METADATA(n) HDMI_CORE_BASE(0x0B20 + 4 * (n)) - -#define HDMI_VSI_CON HDMI_CORE_BASE(0x0C00) -#define HDMI_VSI_HEADER0 HDMI_CORE_BASE(0x0C10) -#define HDMI_VSI_HEADER1 HDMI_CORE_BASE(0x0C14) -#define HDMI_VSI_HEADER2 HDMI_CORE_BASE(0x0C18) -#define HDMI_VSI_DATA(n) HDMI_CORE_BASE(0x0C20 + 4 * (n)) - -#define HDMI_DC_CONTROL HDMI_CORE_BASE(0x0D00) -#define HDMI_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x0D04) - -#define HDMI_AN_SEED_SEL HDMI_CORE_BASE(0x0E48) -#define HDMI_AN_SEED_0 HDMI_CORE_BASE(0x0E58) -#define HDMI_AN_SEED_1 HDMI_CORE_BASE(0x0E5C) -#define HDMI_AN_SEED_2 HDMI_CORE_BASE(0x0E60) -#define HDMI_AN_SEED_3 HDMI_CORE_BASE(0x0E64) - -/* HDCP related registers */ -#define HDMI_HDCP_SHA1(n) HDMI_CORE_BASE(0x7000 + 4 * (n)) -#define HDMI_HDCP_KSV_LIST(n) HDMI_CORE_BASE(0x7050 + 4 * (n)) - -#define HDMI_HDCP_KSV_LIST_CON HDMI_CORE_BASE(0x7064) -#define HDMI_HDCP_SHA_RESULT HDMI_CORE_BASE(0x7070) -#define HDMI_HDCP_CTRL1 HDMI_CORE_BASE(0x7080) -#define HDMI_HDCP_CTRL2 HDMI_CORE_BASE(0x7084) -#define HDMI_HDCP_CHECK_RESULT HDMI_CORE_BASE(0x7090) -#define HDMI_HDCP_BKSV(n) HDMI_CORE_BASE(0x70A0 + 4 * (n)) -#define HDMI_HDCP_AKSV(n) HDMI_CORE_BASE(0x70C0 + 4 * (n)) -#define HDMI_HDCP_AN(n) HDMI_CORE_BASE(0x70E0 + 4 * (n)) - -#define HDMI_HDCP_BCAPS HDMI_CORE_BASE(0x7100) -#define HDMI_HDCP_BSTATUS_0 HDMI_CORE_BASE(0x7110) -#define HDMI_HDCP_BSTATUS_1 HDMI_CORE_BASE(0x7114) -#define HDMI_HDCP_RI_0 HDMI_CORE_BASE(0x7140) -#define HDMI_HDCP_RI_1 HDMI_CORE_BASE(0x7144) -#define HDMI_HDCP_I2C_INT HDMI_CORE_BASE(0x7180) -#define HDMI_HDCP_AN_INT HDMI_CORE_BASE(0x7190) -#define HDMI_HDCP_WDT_INT HDMI_CORE_BASE(0x71A0) -#define HDMI_HDCP_RI_INT HDMI_CORE_BASE(0x71B0) -#define HDMI_HDCP_RI_COMPARE_0 HDMI_CORE_BASE(0x71D0) -#define HDMI_HDCP_RI_COMPARE_1 HDMI_CORE_BASE(0x71D4) -#define HDMI_HDCP_FRAME_COUNT HDMI_CORE_BASE(0x71E0) - -#define HDMI_RGB_ROUND_EN HDMI_CORE_BASE(0xD500) -#define HDMI_VACT_SPACE_R_0 HDMI_CORE_BASE(0xD504) -#define HDMI_VACT_SPACE_R_1 HDMI_CORE_BASE(0xD508) -#define HDMI_VACT_SPACE_G_0 HDMI_CORE_BASE(0xD50C) -#define HDMI_VACT_SPACE_G_1 HDMI_CORE_BASE(0xD510) -#define HDMI_VACT_SPACE_B_0 HDMI_CORE_BASE(0xD514) -#define HDMI_VACT_SPACE_B_1 HDMI_CORE_BASE(0xD518) - -#define HDMI_BLUE_SCREEN_B_0 HDMI_CORE_BASE(0xD520) -#define HDMI_BLUE_SCREEN_B_1 HDMI_CORE_BASE(0xD524) -#define HDMI_BLUE_SCREEN_G_0 HDMI_CORE_BASE(0xD528) -#define HDMI_BLUE_SCREEN_G_1 HDMI_CORE_BASE(0xD52C) -#define HDMI_BLUE_SCREEN_R_0 HDMI_CORE_BASE(0xD530) -#define HDMI_BLUE_SCREEN_R_1 HDMI_CORE_BASE(0xD534) - -/* HDMI I2S register */ -#define HDMI_I2S_CLK_CON HDMI_I2S_BASE(0x000) -#define HDMI_I2S_CON_1 HDMI_I2S_BASE(0x004) -#define HDMI_I2S_CON_2 HDMI_I2S_BASE(0x008) -#define HDMI_I2S_PIN_SEL_0 HDMI_I2S_BASE(0x00c) -#define HDMI_I2S_PIN_SEL_1 HDMI_I2S_BASE(0x010) -#define HDMI_I2S_PIN_SEL_2 HDMI_I2S_BASE(0x014) -#define HDMI_I2S_PIN_SEL_3 HDMI_I2S_BASE(0x018) -#define HDMI_I2S_DSD_CON HDMI_I2S_BASE(0x01c) -#define HDMI_I2S_MUX_CON HDMI_I2S_BASE(0x020) -#define HDMI_I2S_CH_ST_CON HDMI_I2S_BASE(0x024) -#define HDMI_I2S_CH_ST_0 HDMI_I2S_BASE(0x028) -#define HDMI_I2S_CH_ST_1 HDMI_I2S_BASE(0x02c) -#define HDMI_I2S_CH_ST_2 HDMI_I2S_BASE(0x030) -#define HDMI_I2S_CH_ST_3 HDMI_I2S_BASE(0x034) -#define HDMI_I2S_CH_ST_4 HDMI_I2S_BASE(0x038) -#define HDMI_I2S_CH_ST_SH_0 HDMI_I2S_BASE(0x03c) -#define HDMI_I2S_CH_ST_SH_1 HDMI_I2S_BASE(0x040) -#define HDMI_I2S_CH_ST_SH_2 HDMI_I2S_BASE(0x044) -#define HDMI_I2S_CH_ST_SH_3 HDMI_I2S_BASE(0x048) -#define HDMI_I2S_CH_ST_SH_4 HDMI_I2S_BASE(0x04c) -#define HDMI_I2S_MUX_CH HDMI_I2S_BASE(0x054) -#define HDMI_I2S_MUX_CUV HDMI_I2S_BASE(0x058) - -/* I2S bit definition */ - -/* I2S_CLK_CON */ -#define HDMI_I2S_CLK_DIS (0) -#define HDMI_I2S_CLK_EN (1) - -/* I2S_CON_1 */ -#define HDMI_I2S_SCLK_FALLING_EDGE (0 << 1) -#define HDMI_I2S_SCLK_RISING_EDGE (1 << 1) -#define HDMI_I2S_L_CH_LOW_POL (0) -#define HDMI_I2S_L_CH_HIGH_POL (1) - -/* I2S_CON_2 */ -#define HDMI_I2S_MSB_FIRST_MODE (0 << 6) -#define HDMI_I2S_LSB_FIRST_MODE (1 << 6) -#define HDMI_I2S_BIT_CH_32FS (0 << 4) -#define HDMI_I2S_BIT_CH_48FS (1 << 4) -#define HDMI_I2S_BIT_CH_RESERVED (2 << 4) -#define HDMI_I2S_SDATA_16BIT (1 << 2) -#define HDMI_I2S_SDATA_20BIT (2 << 2) -#define HDMI_I2S_SDATA_24BIT (3 << 2) -#define HDMI_I2S_BASIC_FORMAT (0) -#define HDMI_I2S_L_JUST_FORMAT (2) -#define HDMI_I2S_R_JUST_FORMAT (3) -#define HDMI_I2S_CON_2_CLR (~(0xFF)) -#define HDMI_I2S_SET_BIT_CH(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SET_SDATA_BIT(x) (((x) & 0x7) << 2) - -/* I2S_PIN_SEL_0 */ -#define HDMI_I2S_SEL_SCLK(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SEL_LRCK(x) ((x) & 0x7) - -/* I2S_PIN_SEL_1 */ -#define HDMI_I2S_SEL_SDATA1(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7) - -/* I2S_PIN_SEL_2 */ -#define HDMI_I2S_SEL_SDATA3(x) (((x) & 0x7) << 4) -#define HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7) - -/* I2S_PIN_SEL_3 */ -#define HDMI_I2S_SEL_DSD(x) ((x) & 0x7) - -/* I2S_DSD_CON */ -#define HDMI_I2S_DSD_CLK_RI_EDGE (1 << 1) -#define HDMI_I2S_DSD_CLK_FA_EDGE (0 << 1) -#define HDMI_I2S_DSD_ENABLE (1) -#define HDMI_I2S_DSD_DISABLE (0) - -/* I2S_MUX_CON */ -#define HDMI_I2S_NOISE_FILTER_ZERO (0 << 5) -#define HDMI_I2S_NOISE_FILTER_2_STAGE (1 << 5) -#define HDMI_I2S_NOISE_FILTER_3_STAGE (2 << 5) -#define HDMI_I2S_NOISE_FILTER_4_STAGE (3 << 5) -#define HDMI_I2S_NOISE_FILTER_5_STAGE (4 << 5) -#define HDMI_I2S_IN_DISABLE (1 << 4) -#define HDMI_I2S_IN_ENABLE (0 << 4) -#define HDMI_I2S_AUD_SPDIF (0 << 2) -#define HDMI_I2S_AUD_I2S (1 << 2) -#define HDMI_I2S_AUD_DSD (2 << 2) -#define HDMI_I2S_CUV_SPDIF_ENABLE (0 << 1) -#define HDMI_I2S_CUV_I2S_ENABLE (1 << 1) -#define HDMI_I2S_MUX_DISABLE (0) -#define HDMI_I2S_MUX_ENABLE (1) -#define HDMI_I2S_MUX_CON_CLR (~(0xFF)) - -/* I2S_CH_ST_CON */ -#define HDMI_I2S_CH_STATUS_RELOAD (1) -#define HDMI_I2S_CH_ST_CON_CLR (~(1)) - -/* I2S_CH_ST_0 / I2S_CH_ST_SH_0 */ -#define HDMI_I2S_CH_STATUS_MODE_0 (0 << 6) -#define HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH (0 << 3) -#define HDMI_I2S_2AUD_CH_WITH_PREEMPH (1 << 3) -#define HDMI_I2S_DEFAULT_EMPHASIS (0 << 3) -#define HDMI_I2S_COPYRIGHT (0 << 2) -#define HDMI_I2S_NO_COPYRIGHT (1 << 2) -#define HDMI_I2S_LINEAR_PCM (0 << 1) -#define HDMI_I2S_NO_LINEAR_PCM (1 << 1) -#define HDMI_I2S_CONSUMER_FORMAT (0) -#define HDMI_I2S_PROF_FORMAT (1) -#define HDMI_I2S_CH_ST_0_CLR (~(0xFF)) - -/* I2S_CH_ST_1 / I2S_CH_ST_SH_1 */ -#define HDMI_I2S_CD_PLAYER (0x00) -#define HDMI_I2S_DAT_PLAYER (0x03) -#define HDMI_I2S_DCC_PLAYER (0x43) -#define HDMI_I2S_MINI_DISC_PLAYER (0x49) - -/* I2S_CH_ST_2 / I2S_CH_ST_SH_2 */ -#define HDMI_I2S_CHANNEL_NUM_MASK (0xF << 4) -#define HDMI_I2S_SOURCE_NUM_MASK (0xF) -#define HDMI_I2S_SET_CHANNEL_NUM(x) (((x) & (0xF)) << 4) -#define HDMI_I2S_SET_SOURCE_NUM(x) ((x) & (0xF)) - -/* I2S_CH_ST_3 / I2S_CH_ST_SH_3 */ -#define HDMI_I2S_CLK_ACCUR_LEVEL_1 (1 << 4) -#define HDMI_I2S_CLK_ACCUR_LEVEL_2 (0 << 4) -#define HDMI_I2S_CLK_ACCUR_LEVEL_3 (2 << 4) -#define HDMI_I2S_SMP_FREQ_44_1 (0x0) -#define HDMI_I2S_SMP_FREQ_48 (0x2) -#define HDMI_I2S_SMP_FREQ_32 (0x3) -#define HDMI_I2S_SMP_FREQ_96 (0xA) -#define HDMI_I2S_SET_SMP_FREQ(x) ((x) & (0xF)) - -/* I2S_CH_ST_4 / I2S_CH_ST_SH_4 */ -#define HDMI_I2S_ORG_SMP_FREQ_44_1 (0xF << 4) -#define HDMI_I2S_ORG_SMP_FREQ_88_2 (0x7 << 4) -#define HDMI_I2S_ORG_SMP_FREQ_22_05 (0xB << 4) -#define HDMI_I2S_ORG_SMP_FREQ_176_4 (0x3 << 4) -#define HDMI_I2S_WORD_LEN_NOT_DEFINE (0x0 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_20BITS (0x1 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_22BITS (0x2 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_23BITS (0x4 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_24BITS (0x5 << 1) -#define HDMI_I2S_WORD_LEN_MAX24_21BITS (0x6 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_16BITS (0x1 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_18BITS (0x2 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_19BITS (0x4 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_20BITS (0x5 << 1) -#define HDMI_I2S_WORD_LEN_MAX20_17BITS (0x6 << 1) -#define HDMI_I2S_WORD_LEN_MAX_24BITS (1) -#define HDMI_I2S_WORD_LEN_MAX_20BITS (0) - -/* I2S_MUX_CH */ -#define HDMI_I2S_CH3_R_EN (1 << 7) -#define HDMI_I2S_CH3_L_EN (1 << 6) -#define HDMI_I2S_CH3_EN (3 << 6) -#define HDMI_I2S_CH2_R_EN (1 << 5) -#define HDMI_I2S_CH2_L_EN (1 << 4) -#define HDMI_I2S_CH2_EN (3 << 4) -#define HDMI_I2S_CH1_R_EN (1 << 3) -#define HDMI_I2S_CH1_L_EN (1 << 2) -#define HDMI_I2S_CH1_EN (3 << 2) -#define HDMI_I2S_CH0_R_EN (1 << 1) -#define HDMI_I2S_CH0_L_EN (1) -#define HDMI_I2S_CH0_EN (3) -#define HDMI_I2S_CH_ALL_EN (0xFF) -#define HDMI_I2S_MUX_CH_CLR (~HDMI_I2S_CH_ALL_EN) - -/* I2S_MUX_CUV */ -#define HDMI_I2S_CUV_R_EN (1 << 1) -#define HDMI_I2S_CUV_L_EN (1) -#define HDMI_I2S_CUV_RL_EN (0x03) - -/* I2S_CUV_L_R */ -#define HDMI_I2S_CUV_R_DATA_MASK (0x7 << 4) -#define HDMI_I2S_CUV_L_DATA_MASK (0x7) - -/* Timing generator registers */ -/* TG configure/status registers */ -#define HDMI_TG_VACT_ST3_L HDMI_TG_BASE(0x0068) -#define HDMI_TG_VACT_ST3_H HDMI_TG_BASE(0x006c) -#define HDMI_TG_VACT_ST4_L HDMI_TG_BASE(0x0070) -#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) -#define HDMI_TG_3D HDMI_TG_BASE(0x00F0) - -#endif /* SAMSUNG_REGS_HDMI_H */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-mixer.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-mixer.h deleted file mode 100644 index fd2f4d14..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-mixer.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * Cloned from drivers/media/video/s5p-tv/regs-mixer.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Mixer register header file for Samsung Mixer driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ -#ifndef SAMSUNG_REGS_MIXER_H -#define SAMSUNG_REGS_MIXER_H - -/* - * Register part - */ -#define MXR_STATUS 0x0000 -#define MXR_CFG 0x0004 -#define MXR_INT_EN 0x0008 -#define MXR_INT_STATUS 0x000C -#define MXR_LAYER_CFG 0x0010 -#define MXR_VIDEO_CFG 0x0014 -#define MXR_GRAPHIC0_CFG 0x0020 -#define MXR_GRAPHIC0_BASE 0x0024 -#define MXR_GRAPHIC0_SPAN 0x0028 -#define MXR_GRAPHIC0_SXY 0x002C -#define MXR_GRAPHIC0_WH 0x0030 -#define MXR_GRAPHIC0_DXY 0x0034 -#define MXR_GRAPHIC0_BLANK 0x0038 -#define MXR_GRAPHIC1_CFG 0x0040 -#define MXR_GRAPHIC1_BASE 0x0044 -#define MXR_GRAPHIC1_SPAN 0x0048 -#define MXR_GRAPHIC1_SXY 0x004C -#define MXR_GRAPHIC1_WH 0x0050 -#define MXR_GRAPHIC1_DXY 0x0054 -#define MXR_GRAPHIC1_BLANK 0x0058 -#define MXR_BG_CFG 0x0060 -#define MXR_BG_COLOR0 0x0064 -#define MXR_BG_COLOR1 0x0068 -#define MXR_BG_COLOR2 0x006C -#define MXR_CM_COEFF_Y 0x0080 -#define MXR_CM_COEFF_CB 0x0084 -#define MXR_CM_COEFF_CR 0x0088 -#define MXR_GRAPHIC0_BASE_S 0x2024 -#define MXR_GRAPHIC1_BASE_S 0x2044 - -/* for parametrized access to layer registers */ -#define MXR_GRAPHIC_CFG(i) (0x0020 + (i) * 0x20) -#define MXR_GRAPHIC_BASE(i) (0x0024 + (i) * 0x20) -#define MXR_GRAPHIC_SPAN(i) (0x0028 + (i) * 0x20) -#define MXR_GRAPHIC_SXY(i) (0x002C + (i) * 0x20) -#define MXR_GRAPHIC_WH(i) (0x0030 + (i) * 0x20) -#define MXR_GRAPHIC_DXY(i) (0x0034 + (i) * 0x20) -#define MXR_GRAPHIC_BLANK(i) (0x0038 + (i) * 0x20) -#define MXR_GRAPHIC_BASE_S(i) (0x2024 + (i) * 0x20) - -/* - * Bit definition part - */ - -/* generates mask for range of bits */ -#define MXR_MASK(high_bit, low_bit) \ - (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit)) - -#define MXR_MASK_VAL(val, high_bit, low_bit) \ - (((val) << (low_bit)) & MXR_MASK(high_bit, low_bit)) - -/* bits for MXR_STATUS */ -#define MXR_STATUS_16_BURST (1 << 7) -#define MXR_STATUS_BURST_MASK (1 << 7) -#define MXR_STATUS_BIG_ENDIAN (1 << 3) -#define MXR_STATUS_ENDIAN_MASK (1 << 3) -#define MXR_STATUS_SYNC_ENABLE (1 << 2) -#define MXR_STATUS_REG_RUN (1 << 0) - -/* bits for MXR_CFG */ -#define MXR_CFG_RGB601_0_255 (0 << 9) -#define MXR_CFG_RGB601_16_235 (1 << 9) -#define MXR_CFG_RGB709_0_255 (2 << 9) -#define MXR_CFG_RGB709_16_235 (3 << 9) -#define MXR_CFG_RGB_FMT_MASK 0x600 -#define MXR_CFG_OUT_YUV444 (0 << 8) -#define MXR_CFG_OUT_RGB888 (1 << 8) -#define MXR_CFG_OUT_MASK (1 << 8) -#define MXR_CFG_DST_SDO (0 << 7) -#define MXR_CFG_DST_HDMI (1 << 7) -#define MXR_CFG_DST_MASK (1 << 7) -#define MXR_CFG_SCAN_HD_720 (0 << 6) -#define MXR_CFG_SCAN_HD_1080 (1 << 6) -#define MXR_CFG_GRP1_ENABLE (1 << 5) -#define MXR_CFG_GRP0_ENABLE (1 << 4) -#define MXR_CFG_VP_ENABLE (1 << 3) -#define MXR_CFG_SCAN_INTERLACE (0 << 2) -#define MXR_CFG_SCAN_PROGRASSIVE (1 << 2) -#define MXR_CFG_SCAN_NTSC (0 << 1) -#define MXR_CFG_SCAN_PAL (1 << 1) -#define MXR_CFG_SCAN_SD (0 << 0) -#define MXR_CFG_SCAN_HD (1 << 0) -#define MXR_CFG_SCAN_MASK 0x47 - -/* bits for MXR_GRAPHICn_CFG */ -#define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21) -#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20) -#define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17) -#define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16) -#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8) -#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0) -#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0) - -/* bits for MXR_GRAPHICn_WH */ -#define MXR_GRP_WH_H_SCALE(x) MXR_MASK_VAL(x, 28, 28) -#define MXR_GRP_WH_V_SCALE(x) MXR_MASK_VAL(x, 12, 12) -#define MXR_GRP_WH_WIDTH(x) MXR_MASK_VAL(x, 26, 16) -#define MXR_GRP_WH_HEIGHT(x) MXR_MASK_VAL(x, 10, 0) - -/* bits for MXR_GRAPHICn_SXY */ -#define MXR_GRP_SXY_SX(x) MXR_MASK_VAL(x, 26, 16) -#define MXR_GRP_SXY_SY(x) MXR_MASK_VAL(x, 10, 0) - -/* bits for MXR_GRAPHICn_DXY */ -#define MXR_GRP_DXY_DX(x) MXR_MASK_VAL(x, 26, 16) -#define MXR_GRP_DXY_DY(x) MXR_MASK_VAL(x, 10, 0) - -/* bits for MXR_INT_EN */ -#define MXR_INT_EN_VSYNC (1 << 11) -#define MXR_INT_EN_ALL (0x0f << 8) - -/* bit for MXR_INT_STATUS */ -#define MXR_INT_CLEAR_VSYNC (1 << 11) -#define MXR_INT_STATUS_VSYNC (1 << 0) - -/* bit for MXR_LAYER_CFG */ -#define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8) -#define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4) -#define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0) - -#endif /* SAMSUNG_REGS_MIXER_H */ - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-vp.h b/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-vp.h deleted file mode 100644 index 10b737af..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/exynos/regs-vp.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * Cloned from drivers/media/video/s5p-tv/regs-vp.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Video processor register header file for Samsung Mixer driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef SAMSUNG_REGS_VP_H -#define SAMSUNG_REGS_VP_H - -/* - * Register part - */ - -#define VP_ENABLE 0x0000 -#define VP_SRESET 0x0004 -#define VP_SHADOW_UPDATE 0x0008 -#define VP_FIELD_ID 0x000C -#define VP_MODE 0x0010 -#define VP_IMG_SIZE_Y 0x0014 -#define VP_IMG_SIZE_C 0x0018 -#define VP_PER_RATE_CTRL 0x001C -#define VP_TOP_Y_PTR 0x0028 -#define VP_BOT_Y_PTR 0x002C -#define VP_TOP_C_PTR 0x0030 -#define VP_BOT_C_PTR 0x0034 -#define VP_ENDIAN_MODE 0x03CC -#define VP_SRC_H_POSITION 0x0044 -#define VP_SRC_V_POSITION 0x0048 -#define VP_SRC_WIDTH 0x004C -#define VP_SRC_HEIGHT 0x0050 -#define VP_DST_H_POSITION 0x0054 -#define VP_DST_V_POSITION 0x0058 -#define VP_DST_WIDTH 0x005C -#define VP_DST_HEIGHT 0x0060 -#define VP_H_RATIO 0x0064 -#define VP_V_RATIO 0x0068 -#define VP_POLY8_Y0_LL 0x006C -#define VP_POLY4_Y0_LL 0x00EC -#define VP_POLY4_C0_LL 0x012C - -/* - * Bit definition part - */ - -/* generates mask for range of bits */ - -#define VP_MASK(high_bit, low_bit) \ - (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit)) - -#define VP_MASK_VAL(val, high_bit, low_bit) \ - (((val) << (low_bit)) & VP_MASK(high_bit, low_bit)) - - /* VP_ENABLE */ -#define VP_ENABLE_ON (1 << 0) - -/* VP_SRESET */ -#define VP_SRESET_PROCESSING (1 << 0) - -/* VP_SHADOW_UPDATE */ -#define VP_SHADOW_UPDATE_ENABLE (1 << 0) - -/* VP_MODE */ -#define VP_MODE_NV12 (0 << 6) -#define VP_MODE_NV21 (1 << 6) -#define VP_MODE_LINE_SKIP (1 << 5) -#define VP_MODE_MEM_LINEAR (0 << 4) -#define VP_MODE_MEM_TILED (1 << 4) -#define VP_MODE_FMT_MASK (5 << 4) -#define VP_MODE_FIELD_ID_AUTO_TOGGLING (1 << 2) -#define VP_MODE_2D_IPC (1 << 1) - -/* VP_IMG_SIZE_Y */ -/* VP_IMG_SIZE_C */ -#define VP_IMG_HSIZE(x) VP_MASK_VAL(x, 29, 16) -#define VP_IMG_VSIZE(x) VP_MASK_VAL(x, 13, 0) - -/* VP_SRC_H_POSITION */ -#define VP_SRC_H_POSITION_VAL(x) VP_MASK_VAL(x, 14, 4) - -/* VP_ENDIAN_MODE */ -#define VP_ENDIAN_MODE_LITTLE (1 << 0) - -#endif /* SAMSUNG_REGS_VP_H */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/Kconfig b/ANDROID_3.4.5/drivers/gpu/drm/gma500/Kconfig deleted file mode 100644 index 42e665c7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -config DRM_GMA500 - tristate "Intel GMA5/600 KMS Framebuffer" - depends on DRM && PCI && X86 && EXPERIMENTAL - select FB_CFB_COPYAREA - select FB_CFB_FILLRECT - select FB_CFB_IMAGEBLIT - select DRM_KMS_HELPER - select DRM_TTM - help - Say yes for an experimental 2D KMS framebuffer driver for the - Intel GMA500 ('Poulsbo') and other Intel IMG based graphics - devices. - -config DRM_GMA600 - bool "Intel GMA600 support (Experimental)" - depends on DRM_GMA500 - help - Say yes to include support for GMA600 (Intel Moorestown/Oaktrail) - platforms with LVDS ports. MIPI is not currently supported. - -config DRM_GMA3600 - bool "Intel GMA3600/3650 support (Experimental)" - depends on DRM_GMA500 - help - Say yes to include basic support for Intel GMA3600/3650 (Intel - Cedar Trail) platforms. - -config DRM_MEDFIELD - bool "Intel Medfield support (Experimental)" - depends on DRM_GMA500 && X86_INTEL_MID - help - Say yes to include support for the Intel Medfield platform. - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/gma500/Makefile deleted file mode 100644 index 15839829..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# KMS driver for the GMA500 -# -ccflags-y += -Iinclude/drm - -gma500_gfx-y += gem_glue.o \ - accel_2d.o \ - backlight.o \ - framebuffer.o \ - gem.o \ - gtt.o \ - intel_bios.o \ - intel_i2c.o \ - intel_gmbus.o \ - intel_opregion.o \ - mmu.o \ - power.o \ - psb_drv.o \ - psb_intel_display.o \ - psb_intel_lvds.o \ - psb_intel_modes.o \ - psb_intel_sdvo.o \ - psb_lid.o \ - psb_irq.o \ - psb_device.o \ - mid_bios.o - -gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \ - cdv_intel_crt.o \ - cdv_intel_display.o \ - cdv_intel_hdmi.o \ - cdv_intel_lvds.o - -gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \ - oaktrail_crtc.o \ - oaktrail_lvds.o \ - oaktrail_hdmi.o \ - oaktrail_hdmi_i2c.o - -gma500_gfx-$(CONFIG_DRM_MEDFIELD) += mdfld_device.o \ - mdfld_output.o \ - mdfld_intel_display.o \ - mdfld_dsi_output.o \ - mdfld_dsi_dpi.o \ - mdfld_dsi_pkg_sender.o \ - mdfld_tpo_vid.o \ - mdfld_tmd_vid.o \ - tc35876x-dsi-lvds.o - -obj-$(CONFIG_DRM_GMA500) += gma500_gfx.o diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/accel_2d.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/accel_2d.c deleted file mode 100644 index d5ef1a57..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/accel_2d.c +++ /dev/null @@ -1,364 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "psb_drv.h" -#include "psb_reg.h" -#include "framebuffer.h" - -/** - * psb_spank - reset the 2D engine - * @dev_priv: our PSB DRM device - * - * Soft reset the graphics engine and then reload the necessary registers. - * We use this at initialisation time but it will become relevant for - * accelerated X later - */ -void psb_spank(struct drm_psb_private *dev_priv) -{ - PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | - _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET | - _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET | - _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET); - PSB_RSGX32(PSB_CR_SOFT_RESET); - - msleep(1); - - PSB_WSGX32(0, PSB_CR_SOFT_RESET); - wmb(); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT, - PSB_CR_BIF_CTRL); - wmb(); - (void) PSB_RSGX32(PSB_CR_BIF_CTRL); - - msleep(1); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT, - PSB_CR_BIF_CTRL); - (void) PSB_RSGX32(PSB_CR_BIF_CTRL); - PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); -} - -/** - * psb2_2d_wait_available - wait for FIFO room - * @dev_priv: our DRM device - * @size: size (in dwords) of the command we want to issue - * - * Wait until there is room to load the FIFO with our data. If the - * device is not responding then reset it - */ -static int psb_2d_wait_available(struct drm_psb_private *dev_priv, - unsigned size) -{ - uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF); - unsigned long t = jiffies + HZ; - - while (avail < size) { - avail = PSB_RSGX32(PSB_CR_2D_SOCIF); - if (time_after(jiffies, t)) { - psb_spank(dev_priv); - return -EIO; - } - } - return 0; -} - -/** - * psb_2d_submit - submit a 2D command - * @dev_priv: our DRM device - * @cmdbuf: command to issue - * @size: length (in dwords) - * - * Issue one or more 2D commands to the accelerator. This needs to be - * serialized later when we add the GEM interfaces for acceleration - */ -static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, - unsigned size) -{ - int ret = 0; - int i; - unsigned submit_size; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->lock_2d, flags); - while (size > 0) { - submit_size = (size < 0x60) ? size : 0x60; - size -= submit_size; - ret = psb_2d_wait_available(dev_priv, submit_size); - if (ret) - break; - - submit_size <<= 2; - - for (i = 0; i < submit_size; i += 4) - PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i); - - (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); - } - spin_unlock_irqrestore(&dev_priv->lock_2d, flags); - return ret; -} - - -/** - * psb_accel_2d_copy_direction - compute blit order - * @xdir: X direction of move - * @ydir: Y direction of move - * - * Compute the correct order setings to ensure that an overlapping blit - * correctly copies all the pixels. - */ -static u32 psb_accel_2d_copy_direction(int xdir, int ydir) -{ - if (xdir < 0) - return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL : - PSB_2D_COPYORDER_TR2BL; - else - return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR : - PSB_2D_COPYORDER_TL2BR; -} - -/** - * psb_accel_2d_copy - accelerated 2D copy - * @dev_priv: our DRM device - * @src_offset in bytes - * @src_stride in bytes - * @src_format psb 2D format defines - * @dst_offset in bytes - * @dst_stride in bytes - * @dst_format psb 2D format defines - * @src_x offset in pixels - * @src_y offset in pixels - * @dst_x offset in pixels - * @dst_y offset in pixels - * @size_x of the copied area - * @size_y of the copied area - * - * Format and issue a 2D accelerated copy command. - */ -static int psb_accel_2d_copy(struct drm_psb_private *dev_priv, - uint32_t src_offset, uint32_t src_stride, - uint32_t src_format, uint32_t dst_offset, - uint32_t dst_stride, uint32_t dst_format, - uint16_t src_x, uint16_t src_y, - uint16_t dst_x, uint16_t dst_y, - uint16_t size_x, uint16_t size_y) -{ - uint32_t blit_cmd; - uint32_t buffer[10]; - uint32_t *buf; - uint32_t direction; - - buf = buffer; - - direction = - psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y); - - if (direction == PSB_2D_COPYORDER_BR2TL || - direction == PSB_2D_COPYORDER_TR2BL) { - src_x += size_x - 1; - dst_x += size_x - 1; - } - if (direction == PSB_2D_COPYORDER_BR2TL || - direction == PSB_2D_COPYORDER_BL2TR) { - src_y += size_y - 1; - dst_y += size_y - 1; - } - - blit_cmd = - PSB_2D_BLIT_BH | - PSB_2D_ROT_NONE | - PSB_2D_DSTCK_DISABLE | - PSB_2D_SRCCK_DISABLE | - PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction; - - *buf++ = PSB_2D_FENCE_BH; - *buf++ = - PSB_2D_DST_SURF_BH | dst_format | (dst_stride << - PSB_2D_DST_STRIDE_SHIFT); - *buf++ = dst_offset; - *buf++ = - PSB_2D_SRC_SURF_BH | src_format | (src_stride << - PSB_2D_SRC_STRIDE_SHIFT); - *buf++ = src_offset; - *buf++ = - PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) | - (src_y << PSB_2D_SRCOFF_YSTART_SHIFT); - *buf++ = blit_cmd; - *buf++ = - (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y << - PSB_2D_DST_YSTART_SHIFT); - *buf++ = - (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y << - PSB_2D_DST_YSIZE_SHIFT); - *buf++ = PSB_2D_FLUSH_BH; - - return psbfb_2d_submit(dev_priv, buffer, buf - buffer); -} - -/** - * psbfb_copyarea_accel - copyarea acceleration for /dev/fb - * @info: our framebuffer - * @a: copyarea parameters from the framebuffer core - * - * Perform a 2D copy via the accelerator - */ -static void psbfb_copyarea_accel(struct fb_info *info, - const struct fb_copyarea *a) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - struct drm_psb_private *dev_priv = dev->dev_private; - uint32_t offset; - uint32_t stride; - uint32_t src_format; - uint32_t dst_format; - - if (!fb) - return; - - offset = psbfb->gtt->offset; - stride = fb->pitches[0]; - - switch (fb->depth) { - case 8: - src_format = PSB_2D_SRC_332RGB; - dst_format = PSB_2D_DST_332RGB; - break; - case 15: - src_format = PSB_2D_SRC_555RGB; - dst_format = PSB_2D_DST_555RGB; - break; - case 16: - src_format = PSB_2D_SRC_565RGB; - dst_format = PSB_2D_DST_565RGB; - break; - case 24: - case 32: - /* this is wrong but since we don't do blending its okay */ - src_format = PSB_2D_SRC_8888ARGB; - dst_format = PSB_2D_DST_8888ARGB; - break; - default: - /* software fallback */ - cfb_copyarea(info, a); - return; - } - - if (!gma_power_begin(dev, false)) { - cfb_copyarea(info, a); - return; - } - psb_accel_2d_copy(dev_priv, - offset, stride, src_format, - offset, stride, dst_format, - a->sx, a->sy, a->dx, a->dy, a->width, a->height); - gma_power_end(dev); -} - -/** - * psbfb_copyarea - 2D copy interface - * @info: our framebuffer - * @region: region to copy - * - * Copy an area of the framebuffer console either by the accelerator - * or directly using the cfb helpers according to the request - */ -void psbfb_copyarea(struct fb_info *info, - const struct fb_copyarea *region) -{ - if (unlikely(info->state != FBINFO_STATE_RUNNING)) - return; - - /* Avoid the 8 pixel erratum */ - if (region->width == 8 || region->height == 8 || - (info->flags & FBINFO_HWACCEL_DISABLED)) - return cfb_copyarea(info, region); - - psbfb_copyarea_accel(info, region); -} - -/** - * psbfb_sync - synchronize 2D - * @info: our framebuffer - * - * Wait for the 2D engine to quiesce so that we can do CPU - * access to the framebuffer again - */ -int psbfb_sync(struct fb_info *info) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long _end = jiffies + DRM_HZ; - int busy = 0; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->lock_2d, flags); - /* - * First idle the 2D engine. - */ - - if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) && - ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0)) - goto out; - - do { - busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY); - cpu_relax(); - } while (busy && !time_after_eq(jiffies, _end)); - - if (busy) - busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY); - if (busy) - goto out; - - do { - busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & - _PSB_C2B_STATUS_BUSY) != 0); - cpu_relax(); - } while (busy && !time_after_eq(jiffies, _end)); - if (busy) - busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & - _PSB_C2B_STATUS_BUSY) != 0); - -out: - spin_unlock_irqrestore(&dev_priv->lock_2d, flags); - return (busy) ? -EBUSY : 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/backlight.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/backlight.c deleted file mode 100644 index 20793951..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/backlight.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * GMA500 Backlight Interface - * - * Copyright (c) 2009-2011, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Eric Knopp - * - */ - -#include "psb_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_drv.h" -#include "intel_bios.h" -#include "power.h" - -int gma_backlight_init(struct drm_device *dev) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct drm_psb_private *dev_priv = dev->dev_private; - return dev_priv->ops->backlight_init(dev); -#else - return 0; -#endif -} - -void gma_backlight_exit(struct drm_device *dev) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->backlight_device) { - dev_priv->backlight_device->props.brightness = 0; - backlight_update_status(dev_priv->backlight_device); - backlight_device_unregister(dev_priv->backlight_device); - } -#endif -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.c deleted file mode 100644 index a54cc738..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.c +++ /dev/null @@ -1,484 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include "intel_bios.h" -#include "cdv_device.h" - -#define VGA_SR_INDEX 0x3c4 -#define VGA_SR_DATA 0x3c5 - -static void cdv_disable_vga(struct drm_device *dev) -{ - u8 sr1; - u32 vga_reg; - - vga_reg = VGACNTRL; - - outb(1, VGA_SR_INDEX); - sr1 = inb(VGA_SR_DATA); - outb(sr1 | 1<<5, VGA_SR_DATA); - udelay(300); - - REG_WRITE(vga_reg, VGA_DISP_DISABLE); - REG_READ(vga_reg); -} - -static int cdv_output_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - cdv_disable_vga(dev); - - cdv_intel_crt_init(dev, &dev_priv->mode_dev); - cdv_intel_lvds_init(dev, &dev_priv->mode_dev); - - /* These bits indicate HDMI not SDVO on CDV, but we don't yet support - the HDMI interface */ - if (REG_READ(SDVOB) & SDVO_DETECTED) - cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); - if (REG_READ(SDVOC) & SDVO_DETECTED) - cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC); - return 0; -} - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - -/* - * Poulsbo Backlight Interfaces - */ - -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 - -#define PSB_BLC_PWM_PRECISION_FACTOR 10 -#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE -#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 - -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) - -static int cdv_brightness; -static struct backlight_device *cdv_backlight_device; - -static int cdv_get_brightness(struct backlight_device *bd) -{ - /* return locally cached var instead of HW read (due to DPST etc.) */ - /* FIXME: ideally return actual value in case firmware fiddled with - it */ - return cdv_brightness; -} - - -static int cdv_backlight_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long core_clock; - /* u32 bl_max_freq; */ - /* unsigned long value; */ - u16 bl_max_freq; - uint32_t value; - uint32_t blc_pwm_precision_factor; - - /* get bl_max_freq and pol from dev_priv*/ - if (!dev_priv->lvds_bl) { - dev_err(dev->dev, "Has no valid LVDS backlight info\n"); - return -ENOENT; - } - bl_max_freq = dev_priv->lvds_bl->freq; - blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; - - core_clock = dev_priv->core_freq; - - value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; - value *= blc_pwm_precision_factor; - value /= bl_max_freq; - value /= blc_pwm_precision_factor; - - if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || - value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) - return -ERANGE; - else { - /* FIXME */ - } - return 0; -} - -static int cdv_set_brightness(struct backlight_device *bd) -{ - int level = bd->props.brightness; - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - /*cdv_intel_lvds_set_brightness(dev, level); FIXME */ - cdv_brightness = level; - return 0; -} - -static const struct backlight_ops cdv_ops = { - .get_brightness = cdv_get_brightness, - .update_status = cdv_set_brightness, -}; - -static int cdv_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - struct backlight_properties props; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = 100; - props.type = BACKLIGHT_PLATFORM; - - cdv_backlight_device = backlight_device_register("psb-bl", - NULL, (void *)dev, &cdv_ops, &props); - if (IS_ERR(cdv_backlight_device)) - return PTR_ERR(cdv_backlight_device); - - ret = cdv_backlight_setup(dev); - if (ret < 0) { - backlight_device_unregister(cdv_backlight_device); - cdv_backlight_device = NULL; - return ret; - } - cdv_backlight_device->props.brightness = 100; - cdv_backlight_device->props.max_brightness = 100; - backlight_update_status(cdv_backlight_device); - dev_priv->backlight_device = cdv_backlight_device; - return 0; -} - -#endif - -/* - * Provide the Cedarview specific chip logic and low level methods - * for power management - * - * FIXME: we need to implement the apm/ospm base management bits - * for this and the MID devices. - */ - -static inline u32 CDV_MSG_READ32(uint port, uint offset) -{ - int mcr = (0x10<<24) | (port << 16) | (offset << 8); - uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - pci_write_config_dword(pci_root, 0xD0, mcr); - pci_read_config_dword(pci_root, 0xD4, &ret_val); - pci_dev_put(pci_root); - return ret_val; -} - -static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value) -{ - int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - pci_write_config_dword(pci_root, 0xD4, value); - pci_write_config_dword(pci_root, 0xD0, mcr); - pci_dev_put(pci_root); -} - -#define PSB_PM_SSC 0x20 -#define PSB_PM_SSS 0x30 -#define PSB_PWRGT_GFX_ON 0x02 -#define PSB_PWRGT_GFX_OFF 0x01 -#define PSB_PWRGT_GFX_D0 0x00 -#define PSB_PWRGT_GFX_D3 0x03 - -static void cdv_init_pm(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_cnt; - int i; - - dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT, - PSB_APMBA) & 0xFFFF; - dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT, - PSB_OSPMBA) & 0xFFFF; - - /* Power status */ - pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD); - - /* Enable the GPU */ - pwr_cnt &= ~PSB_PWRGT_GFX_MASK; - pwr_cnt |= PSB_PWRGT_GFX_ON; - outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD); - - /* Wait for the GPU power */ - for (i = 0; i < 5; i++) { - u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS); - if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0) - return; - udelay(10); - } - dev_err(dev->dev, "GPU: power management timed out.\n"); -} - -/** - * cdv_save_display_registers - save registers lost on suspend - * @dev: our DRM device - * - * Save the state we need in order to be able to restore the interface - * upon resume from suspend - */ -static int cdv_save_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_save_area *regs = &dev_priv->regs; - struct drm_connector *connector; - - dev_info(dev->dev, "Saving GPU registers.\n"); - - pci_read_config_byte(dev->pdev, 0xF4, ®s->cdv.saveLBB); - - regs->cdv.saveDSPCLK_GATE_D = REG_READ(DSPCLK_GATE_D); - regs->cdv.saveRAMCLK_GATE_D = REG_READ(RAMCLK_GATE_D); - - regs->cdv.saveDSPARB = REG_READ(DSPARB); - regs->cdv.saveDSPFW[0] = REG_READ(DSPFW1); - regs->cdv.saveDSPFW[1] = REG_READ(DSPFW2); - regs->cdv.saveDSPFW[2] = REG_READ(DSPFW3); - regs->cdv.saveDSPFW[3] = REG_READ(DSPFW4); - regs->cdv.saveDSPFW[4] = REG_READ(DSPFW5); - regs->cdv.saveDSPFW[5] = REG_READ(DSPFW6); - - regs->cdv.saveADPA = REG_READ(ADPA); - - regs->cdv.savePP_CONTROL = REG_READ(PP_CONTROL); - regs->cdv.savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS); - regs->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - regs->saveBLC_PWM_CTL2 = REG_READ(BLC_PWM_CTL2); - regs->cdv.saveLVDS = REG_READ(LVDS); - - regs->cdv.savePFIT_CONTROL = REG_READ(PFIT_CONTROL); - - regs->cdv.savePP_ON_DELAYS = REG_READ(PP_ON_DELAYS); - regs->cdv.savePP_OFF_DELAYS = REG_READ(PP_OFF_DELAYS); - regs->cdv.savePP_CYCLE = REG_READ(PP_CYCLE); - - regs->cdv.saveVGACNTRL = REG_READ(VGACNTRL); - - regs->cdv.saveIER = REG_READ(PSB_INT_ENABLE_R); - regs->cdv.saveIMR = REG_READ(PSB_INT_MASK_R); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); - - return 0; -} - -/** - * cdv_restore_display_registers - restore lost register state - * @dev: our DRM device - * - * Restore register state that was lost during suspend and resume. - * - * FIXME: review - */ -static int cdv_restore_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_save_area *regs = &dev_priv->regs; - struct drm_connector *connector; - u32 temp; - - pci_write_config_byte(dev->pdev, 0xF4, regs->cdv.saveLBB); - - REG_WRITE(DSPCLK_GATE_D, regs->cdv.saveDSPCLK_GATE_D); - REG_WRITE(RAMCLK_GATE_D, regs->cdv.saveRAMCLK_GATE_D); - - /* BIOS does below anyway */ - REG_WRITE(DPIO_CFG, 0); - REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N); - - temp = REG_READ(DPLL_A); - if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) { - REG_WRITE(DPLL_A, temp | DPLL_SYNCLOCK_ENABLE); - REG_READ(DPLL_A); - } - - temp = REG_READ(DPLL_B); - if ((temp & DPLL_SYNCLOCK_ENABLE) == 0) { - REG_WRITE(DPLL_B, temp | DPLL_SYNCLOCK_ENABLE); - REG_READ(DPLL_B); - } - - udelay(500); - - REG_WRITE(DSPFW1, regs->cdv.saveDSPFW[0]); - REG_WRITE(DSPFW2, regs->cdv.saveDSPFW[1]); - REG_WRITE(DSPFW3, regs->cdv.saveDSPFW[2]); - REG_WRITE(DSPFW4, regs->cdv.saveDSPFW[3]); - REG_WRITE(DSPFW5, regs->cdv.saveDSPFW[4]); - REG_WRITE(DSPFW6, regs->cdv.saveDSPFW[5]); - - REG_WRITE(DSPARB, regs->cdv.saveDSPARB); - REG_WRITE(ADPA, regs->cdv.saveADPA); - - REG_WRITE(BLC_PWM_CTL2, regs->saveBLC_PWM_CTL2); - REG_WRITE(LVDS, regs->cdv.saveLVDS); - REG_WRITE(PFIT_CONTROL, regs->cdv.savePFIT_CONTROL); - REG_WRITE(PFIT_PGM_RATIOS, regs->cdv.savePFIT_PGM_RATIOS); - REG_WRITE(BLC_PWM_CTL, regs->saveBLC_PWM_CTL); - REG_WRITE(PP_ON_DELAYS, regs->cdv.savePP_ON_DELAYS); - REG_WRITE(PP_OFF_DELAYS, regs->cdv.savePP_OFF_DELAYS); - REG_WRITE(PP_CYCLE, regs->cdv.savePP_CYCLE); - REG_WRITE(PP_CONTROL, regs->cdv.savePP_CONTROL); - - REG_WRITE(VGACNTRL, regs->cdv.saveVGACNTRL); - - REG_WRITE(PSB_INT_ENABLE_R, regs->cdv.saveIER); - REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR); - - /* Fix arbitration bug */ - CDV_MSG_WRITE32(3, 0x30, 0x08027108); - - drm_mode_config_reset(dev); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->funcs->dpms(connector, DRM_MODE_DPMS_ON); - - /* Resume the modeset for every activated CRTC */ - drm_helper_resume_force_mode(dev); - return 0; -} - -static int cdv_power_down(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_cnt, pwr_mask, pwr_sts; - int tries = 5; - - pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD); - pwr_cnt &= ~PSB_PWRGT_GFX_MASK; - pwr_cnt |= PSB_PWRGT_GFX_OFF; - pwr_mask = PSB_PWRGT_GFX_MASK; - - outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD); - - while (tries--) { - pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS); - if ((pwr_sts & pwr_mask) == PSB_PWRGT_GFX_D3) - return 0; - udelay(10); - } - return 0; -} - -static int cdv_power_up(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_cnt, pwr_mask, pwr_sts; - int tries = 5; - - pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD); - pwr_cnt &= ~PSB_PWRGT_GFX_MASK; - pwr_cnt |= PSB_PWRGT_GFX_ON; - pwr_mask = PSB_PWRGT_GFX_MASK; - - outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD); - - while (tries--) { - pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS); - if ((pwr_sts & pwr_mask) == PSB_PWRGT_GFX_D0) - return 0; - udelay(10); - } - return 0; -} - -/* FIXME ? - shared with Poulsbo */ -static void cdv_get_core_freq(struct drm_device *dev) -{ - uint32_t clock; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - struct drm_psb_private *dev_priv = dev->dev_private; - - pci_write_config_dword(pci_root, 0xD0, 0xD0050300); - pci_read_config_dword(pci_root, 0xD4, &clock); - pci_dev_put(pci_root); - - switch (clock & 0x07) { - case 0: - dev_priv->core_freq = 100; - break; - case 1: - dev_priv->core_freq = 133; - break; - case 2: - dev_priv->core_freq = 150; - break; - case 3: - dev_priv->core_freq = 178; - break; - case 4: - dev_priv->core_freq = 200; - break; - case 5: - case 6: - case 7: - dev_priv->core_freq = 266; - default: - dev_priv->core_freq = 0; - } -} - -static int cdv_chip_setup(struct drm_device *dev) -{ - cdv_get_core_freq(dev); - gma_intel_opregion_init(dev); - psb_intel_init_bios(dev); - REG_WRITE(PORT_HOTPLUG_EN, 0); - REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); - return 0; -} - -/* CDV is much like Poulsbo but has MID like SGX offsets and PM */ - -const struct psb_ops cdv_chip_ops = { - .name = "GMA3600/3650", - .accel_2d = 0, - .pipes = 2, - .crtcs = 2, - .sgx_offset = MRST_SGX_OFFSET, - .chip_setup = cdv_chip_setup, - - .crtc_helper = &cdv_intel_helper_funcs, - .crtc_funcs = &cdv_intel_crtc_funcs, - - .output_init = cdv_output_init, - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - .backlight_init = cdv_backlight_init, -#endif - - .init_pm = cdv_init_pm, - .save_regs = cdv_save_display_registers, - .restore_regs = cdv_restore_display_registers, - .power_down = cdv_power_down, - .power_up = cdv_power_up, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.h deleted file mode 100644 index 9561e176..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_device.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs; -extern const struct drm_crtc_funcs cdv_intel_crtc_funcs; -extern void cdv_intel_crt_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void cdv_intel_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, - int reg); -extern struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc); - -static inline void cdv_intel_wait_for_vblank(struct drm_device *dev) -{ - /* Wait for 20ms, i.e. one cycle at 50hz. */ - /* FIXME: msleep ?? */ - mdelay(20); -} - - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_crt.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_crt.c deleted file mode 100644 index a71a6cd9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ - -#include -#include - -#include "intel_bios.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "power.h" -#include "cdv_device.h" -#include - - -static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - u32 temp, reg; - reg = ADPA; - - temp = REG_READ(reg); - temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); - temp &= ~ADPA_DAC_ENABLE; - - switch (mode) { - case DRM_MODE_DPMS_ON: - temp |= ADPA_DAC_ENABLE; - break; - case DRM_MODE_DPMS_STANDBY: - temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE; - break; - case DRM_MODE_DPMS_SUSPEND: - temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE; - break; - case DRM_MODE_DPMS_OFF: - temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; - break; - } - - REG_WRITE(reg, temp); -} - -static int cdv_intel_crt_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_psb_private *dev_priv = connector->dev->dev_private; - int max_clock = 0; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* The lowest clock for CDV is 20000KHz */ - if (mode->clock < 20000) - return MODE_CLOCK_LOW; - - /* The max clock for CDV is 355 instead of 400 */ - max_clock = 355000; - if (mode->clock > max_clock) - return MODE_CLOCK_HIGH; - - if (mode->hdisplay > 1680 || mode->vdisplay > 1050) - return MODE_PANEL; - - /* We assume worst case scenario of 32 bpp here, since we don't know */ - if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > - dev_priv->vram_stolen_size) - return MODE_MEM; - - return MODE_OK; -} - -static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void cdv_intel_crt_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc = encoder->crtc; - struct psb_intel_crtc *psb_intel_crtc = - to_psb_intel_crtc(crtc); - int dpll_md_reg; - u32 adpa, dpll_md; - u32 adpa_reg; - - if (psb_intel_crtc->pipe == 0) - dpll_md_reg = DPLL_A_MD; - else - dpll_md_reg = DPLL_B_MD; - - adpa_reg = ADPA; - - /* - * Disable separate mode multiplier used when cloning SDVO to CRT - * XXX this needs to be adjusted when we really are cloning - */ - { - dpll_md = REG_READ(dpll_md_reg); - REG_WRITE(dpll_md_reg, - dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); - } - - adpa = 0; - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - adpa |= ADPA_HSYNC_ACTIVE_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - adpa |= ADPA_VSYNC_ACTIVE_HIGH; - - if (psb_intel_crtc->pipe == 0) - adpa |= ADPA_PIPE_A_SELECT; - else - adpa |= ADPA_PIPE_B_SELECT; - - REG_WRITE(adpa_reg, adpa); -} - - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. - * - * \return true if CRT is connected. - * \return false if CRT is disconnected. - */ -static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector, - bool force) -{ - struct drm_device *dev = connector->dev; - u32 hotplug_en; - int i, tries = 0, ret = false; - u32 adpa_orig; - - /* disable the DAC when doing the hotplug detection */ - - adpa_orig = REG_READ(ADPA); - - REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE)); - - /* - * On a CDV thep, CRT detect sequence need to be done twice - * to get a reliable result. - */ - tries = 2; - - hotplug_en = REG_READ(PORT_HOTPLUG_EN); - hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK); - hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; - - hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; - hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; - - for (i = 0; i < tries ; i++) { - unsigned long timeout; - /* turn on the FORCE_DETECT */ - REG_WRITE(PORT_HOTPLUG_EN, hotplug_en); - timeout = jiffies + msecs_to_jiffies(1000); - /* wait for FORCE_DETECT to go off */ - do { - if (!(REG_READ(PORT_HOTPLUG_EN) & - CRT_HOTPLUG_FORCE_DETECT)) - break; - msleep(1); - } while (time_after(timeout, jiffies)); - } - - if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != - CRT_HOTPLUG_MONITOR_NONE) - ret = true; - - /* Restore the saved ADPA */ - REG_WRITE(ADPA, adpa_orig); - return ret; -} - -static enum drm_connector_status cdv_intel_crt_detect( - struct drm_connector *connector, bool force) -{ - if (cdv_intel_crt_detect_hotplug(connector, force)) - return connector_status_connected; - else - return connector_status_disconnected; -} - -static void cdv_intel_crt_destroy(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - - psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static int cdv_intel_crt_get_modes(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - return psb_intel_ddc_get_modes(connector, &psb_intel_encoder->ddc_bus->adapter); -} - -static int cdv_intel_crt_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - return 0; -} - -/* - * Routines for controlling stuff on the analog port - */ - -static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = { - .dpms = cdv_intel_crt_dpms, - .mode_fixup = cdv_intel_crt_mode_fixup, - .prepare = psb_intel_encoder_prepare, - .commit = psb_intel_encoder_commit, - .mode_set = cdv_intel_crt_mode_set, -}; - -static const struct drm_connector_funcs cdv_intel_crt_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = cdv_intel_crt_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = cdv_intel_crt_destroy, - .set_property = cdv_intel_crt_set_property, -}; - -static const struct drm_connector_helper_funcs - cdv_intel_crt_connector_helper_funcs = { - .mode_valid = cdv_intel_crt_mode_valid, - .get_modes = cdv_intel_crt_get_modes, - .best_encoder = psb_intel_best_encoder, -}; - -static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = { - .destroy = cdv_intel_crt_enc_destroy, -}; - -void cdv_intel_crt_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - - struct psb_intel_connector *psb_intel_connector; - struct psb_intel_encoder *psb_intel_encoder; - struct drm_connector *connector; - struct drm_encoder *encoder; - - u32 i2c_reg; - - psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); - if (!psb_intel_encoder) - return; - - psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); - if (!psb_intel_connector) - goto failed_connector; - - connector = &psb_intel_connector->base; - drm_connector_init(dev, connector, - &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - - encoder = &psb_intel_encoder->base; - drm_encoder_init(dev, encoder, - &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); - - psb_intel_connector_attach_encoder(psb_intel_connector, - psb_intel_encoder); - - /* Set up the DDC bus. */ - i2c_reg = GPIOA; - /* Remove the following code for CDV */ - /* - if (dev_priv->crt_ddc_bus != 0) - i2c_reg = dev_priv->crt_ddc_bus; - }*/ - psb_intel_encoder->ddc_bus = psb_intel_i2c_create(dev, - i2c_reg, "CRTDDC_A"); - if (!psb_intel_encoder->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - goto failed_ddc; - } - - psb_intel_encoder->type = INTEL_OUTPUT_ANALOG; - /* - psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT); - psb_intel_output->crtc_mask = (1 << 0) | (1 << 1); - */ - connector->interlace_allowed = 0; - connector->doublescan_allowed = 0; - - drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs); - drm_connector_helper_add(connector, - &cdv_intel_crt_connector_helper_funcs); - - drm_sysfs_connector_add(connector); - - return; -failed_ddc: - drm_encoder_cleanup(&psb_intel_encoder->base); - drm_connector_cleanup(&psb_intel_connector->base); - kfree(psb_intel_connector); -failed_connector: - kfree(psb_intel_encoder); - return; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_display.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_display.c deleted file mode 100644 index be845591..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_display.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* - * Copyright © 2006-2011 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - */ - -#include -#include - -#include -#include "framebuffer.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_display.h" -#include "power.h" -#include "cdv_device.h" - - -struct cdv_intel_range_t { - int min, max; -}; - -struct cdv_intel_p2_t { - int dot_limit; - int p2_slow, p2_fast; -}; - -struct cdv_intel_clock_t { - /* given values */ - int n; - int m1, m2; - int p1, p2; - /* derived values */ - int dot; - int vco; - int m; - int p; -}; - -#define INTEL_P2_NUM 2 - -struct cdv_intel_limit_t { - struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1; - struct cdv_intel_p2_t p2; -}; - -#define CDV_LIMIT_SINGLE_LVDS_96 0 -#define CDV_LIMIT_SINGLE_LVDS_100 1 -#define CDV_LIMIT_DAC_HDMI_27 2 -#define CDV_LIMIT_DAC_HDMI_96 3 - -static const struct cdv_intel_limit_t cdv_intel_limits[] = { - { /* CDV_SIGNLE_LVDS_96MHz */ - .dot = {.min = 20000, .max = 115500}, - .vco = {.min = 1800000, .max = 3600000}, - .n = {.min = 2, .max = 6}, - .m = {.min = 60, .max = 160}, - .m1 = {.min = 0, .max = 0}, - .m2 = {.min = 58, .max = 158}, - .p = {.min = 28, .max = 140}, - .p1 = {.min = 2, .max = 10}, - .p2 = {.dot_limit = 200000, - .p2_slow = 14, .p2_fast = 14}, - }, - { /* CDV_SINGLE_LVDS_100MHz */ - .dot = {.min = 20000, .max = 115500}, - .vco = {.min = 1800000, .max = 3600000}, - .n = {.min = 2, .max = 6}, - .m = {.min = 60, .max = 160}, - .m1 = {.min = 0, .max = 0}, - .m2 = {.min = 58, .max = 158}, - .p = {.min = 28, .max = 140}, - .p1 = {.min = 2, .max = 10}, - /* The single-channel range is 25-112Mhz, and dual-channel - * is 80-224Mhz. Prefer single channel as much as possible. - */ - .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14}, - }, - { /* CDV_DAC_HDMI_27MHz */ - .dot = {.min = 20000, .max = 400000}, - .vco = {.min = 1809000, .max = 3564000}, - .n = {.min = 1, .max = 1}, - .m = {.min = 67, .max = 132}, - .m1 = {.min = 0, .max = 0}, - .m2 = {.min = 65, .max = 130}, - .p = {.min = 5, .max = 90}, - .p1 = {.min = 1, .max = 9}, - .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, - }, - { /* CDV_DAC_HDMI_96MHz */ - .dot = {.min = 20000, .max = 400000}, - .vco = {.min = 1800000, .max = 3600000}, - .n = {.min = 2, .max = 6}, - .m = {.min = 60, .max = 160}, - .m1 = {.min = 0, .max = 0}, - .m2 = {.min = 58, .max = 158}, - .p = {.min = 5, .max = 100}, - .p1 = {.min = 1, .max = 10}, - .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, - }, -}; - -#define _wait_for(COND, MS, W) ({ \ - unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ - int ret__ = 0; \ - while (!(COND)) { \ - if (time_after(jiffies, timeout__)) { \ - ret__ = -ETIMEDOUT; \ - break; \ - } \ - if (W && !in_dbg_master()) \ - msleep(W); \ - } \ - ret__; \ -}) - -#define wait_for(COND, MS) _wait_for(COND, MS, 1) - - -static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val) -{ - int ret; - - ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); - if (ret) { - DRM_ERROR("timeout waiting for SB to idle before read\n"); - return ret; - } - - REG_WRITE(SB_ADDR, reg); - REG_WRITE(SB_PCKT, - SET_FIELD(SB_OPCODE_READ, SB_OPCODE) | - SET_FIELD(SB_DEST_DPLL, SB_DEST) | - SET_FIELD(0xf, SB_BYTE_ENABLE)); - - ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); - if (ret) { - DRM_ERROR("timeout waiting for SB to idle after read\n"); - return ret; - } - - *val = REG_READ(SB_DATA); - - return 0; -} - -static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val) -{ - int ret; - static bool dpio_debug = true; - u32 temp; - - if (dpio_debug) { - if (cdv_sb_read(dev, reg, &temp) == 0) - DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp); - DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val); - } - - ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); - if (ret) { - DRM_ERROR("timeout waiting for SB to idle before write\n"); - return ret; - } - - REG_WRITE(SB_ADDR, reg); - REG_WRITE(SB_DATA, val); - REG_WRITE(SB_PCKT, - SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) | - SET_FIELD(SB_DEST_DPLL, SB_DEST) | - SET_FIELD(0xf, SB_BYTE_ENABLE)); - - ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); - if (ret) { - DRM_ERROR("timeout waiting for SB to idle after write\n"); - return ret; - } - - if (dpio_debug) { - if (cdv_sb_read(dev, reg, &temp) == 0) - DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp); - } - - return 0; -} - -/* Reset the DPIO configuration register. The BIOS does this at every - * mode set. - */ -static void cdv_sb_reset(struct drm_device *dev) -{ - - REG_WRITE(DPIO_CFG, 0); - REG_READ(DPIO_CFG); - REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N); -} - -/* Unlike most Intel display engines, on Cedarview the DPLL registers - * are behind this sideband bus. They must be programmed while the - * DPLL reference clock is on in the DPLL control register, but before - * the DPLL is enabled in the DPLL control register. - */ -static int -cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, - struct cdv_intel_clock_t *clock) -{ - struct psb_intel_crtc *psb_crtc = - to_psb_intel_crtc(crtc); - int pipe = psb_crtc->pipe; - u32 m, n_vco, p; - int ret = 0; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - u32 ref_value; - - cdv_sb_reset(dev); - - if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) { - DRM_ERROR("Attempting to set DPLL with refclk disabled\n"); - return -EBUSY; - } - - /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */ - ref_value = 0x68A701; - - cdv_sb_write(dev, SB_REF_SFR(pipe), ref_value); - - /* We don't know what the other fields of these regs are, so - * leave them in place. - */ - ret = cdv_sb_read(dev, SB_M(pipe), &m); - if (ret) - return ret; - m &= ~SB_M_DIVIDER_MASK; - m |= ((clock->m2) << SB_M_DIVIDER_SHIFT); - ret = cdv_sb_write(dev, SB_M(pipe), m); - if (ret) - return ret; - - ret = cdv_sb_read(dev, SB_N_VCO(pipe), &n_vco); - if (ret) - return ret; - - /* Follow the BIOS to program the N_DIVIDER REG */ - n_vco &= 0xFFFF; - n_vco |= 0x107; - n_vco &= ~(SB_N_VCO_SEL_MASK | - SB_N_DIVIDER_MASK | - SB_N_CB_TUNE_MASK); - - n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT); - - if (clock->vco < 2250000) { - n_vco |= (2 << SB_N_CB_TUNE_SHIFT); - n_vco |= (0 << SB_N_VCO_SEL_SHIFT); - } else if (clock->vco < 2750000) { - n_vco |= (1 << SB_N_CB_TUNE_SHIFT); - n_vco |= (1 << SB_N_VCO_SEL_SHIFT); - } else if (clock->vco < 3300000) { - n_vco |= (0 << SB_N_CB_TUNE_SHIFT); - n_vco |= (2 << SB_N_VCO_SEL_SHIFT); - } else { - n_vco |= (0 << SB_N_CB_TUNE_SHIFT); - n_vco |= (3 << SB_N_VCO_SEL_SHIFT); - } - - ret = cdv_sb_write(dev, SB_N_VCO(pipe), n_vco); - if (ret) - return ret; - - ret = cdv_sb_read(dev, SB_P(pipe), &p); - if (ret) - return ret; - p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK); - p |= SET_FIELD(clock->p1, SB_P1_DIVIDER); - switch (clock->p2) { - case 5: - p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER); - break; - case 10: - p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER); - break; - case 14: - p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER); - break; - case 7: - p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER); - break; - default: - DRM_ERROR("Bad P2 clock: %d\n", clock->p2); - return -EINVAL; - } - ret = cdv_sb_write(dev, SB_P(pipe), p); - if (ret) - return ret; - - /* always Program the Lane Register for the Pipe A*/ - if (pipe == 0) { - /* Program the Lane0/1 for HDMI B */ - u32 lane_reg, lane_value; - - lane_reg = PSB_LANE0; - cdv_sb_read(dev, lane_reg, &lane_value); - lane_value &= ~(LANE_PLL_MASK); - lane_value |= LANE_PLL_ENABLE; - cdv_sb_write(dev, lane_reg, lane_value); - - lane_reg = PSB_LANE1; - cdv_sb_read(dev, lane_reg, &lane_value); - lane_value &= ~(LANE_PLL_MASK); - lane_value |= LANE_PLL_ENABLE; - cdv_sb_write(dev, lane_reg, lane_value); - - /* Program the Lane2/3 for HDMI C */ - lane_reg = PSB_LANE2; - cdv_sb_read(dev, lane_reg, &lane_value); - lane_value &= ~(LANE_PLL_MASK); - lane_value |= LANE_PLL_ENABLE; - cdv_sb_write(dev, lane_reg, lane_value); - - lane_reg = PSB_LANE3; - cdv_sb_read(dev, lane_reg, &lane_value); - lane_value &= ~(LANE_PLL_MASK); - lane_value |= LANE_PLL_ENABLE; - cdv_sb_write(dev, lane_reg, lane_value); - } - - return 0; -} - -/* - * Returns whether any encoder on the specified pipe is of the specified type - */ -static bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *l_entry; - - list_for_each_entry(l_entry, &mode_config->connector_list, head) { - if (l_entry->encoder && l_entry->encoder->crtc == crtc) { - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(l_entry); - if (psb_intel_encoder->type == type) - return true; - } - } - return false; -} - -static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc, - int refclk) -{ - const struct cdv_intel_limit_t *limit; - if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - /* - * Now only single-channel LVDS is supported on CDV. If it is - * incorrect, please add the dual-channel LVDS. - */ - if (refclk == 96000) - limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; - else - limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100]; - } else { - if (refclk == 27000) - limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27]; - else - limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96]; - } - return limit; -} - -/* m1 is reserved as 0 in CDV, n is a ring counter */ -static void cdv_intel_clock(struct drm_device *dev, - int refclk, struct cdv_intel_clock_t *clock) -{ - clock->m = clock->m2 + 2; - clock->p = clock->p1 * clock->p2; - clock->vco = (refclk * clock->m) / clock->n; - clock->dot = clock->vco / clock->p; -} - - -#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } -static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc, - const struct cdv_intel_limit_t *limit, - struct cdv_intel_clock_t *clock) -{ - if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) - INTELPllInvalid("p1 out of range\n"); - if (clock->p < limit->p.min || limit->p.max < clock->p) - INTELPllInvalid("p out of range\n"); - /* unnecessary to check the range of m(m1/M2)/n again */ - if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) - INTELPllInvalid("vco out of range\n"); - /* XXX: We may need to be checking "Dot clock" - * depending on the multiplier, connector, etc., - * rather than just a single range. - */ - if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) - INTELPllInvalid("dot out of range\n"); - - return true; -} - -static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target, - int refclk, - struct cdv_intel_clock_t *best_clock) -{ - struct drm_device *dev = crtc->dev; - struct cdv_intel_clock_t clock; - const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk); - int err = target; - - - if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - (REG_READ(LVDS) & LVDS_PORT_EN) != 0) { - /* - * For LVDS, if the panel is on, just rely on its current - * settings for dual-channel. We haven't figured out how to - * reliably set up different single/dual channel state, if we - * even can. - */ - if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset(best_clock, 0, sizeof(*best_clock)); - clock.m1 = 0; - /* m1 is reserved as 0 in CDV, n is a ring counter. - So skip the m1 loop */ - for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) { - for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; - clock.m2++) { - for (clock.p1 = limit->p1.min; - clock.p1 <= limit->p1.max; - clock.p1++) { - int this_err; - - cdv_intel_clock(dev, refclk, &clock); - - if (!cdv_intel_PLL_is_valid(crtc, - limit, &clock)) - continue; - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - } - - return err != target; -} - -static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); - int pipe = psb_intel_crtc->pipe; - unsigned long start, offset; - int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); - int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - u32 dspcntr; - int ret = 0; - - if (!gma_power_begin(dev, true)) - return 0; - - /* no fb bound */ - if (!crtc->fb) { - dev_err(dev->dev, "No FB bound\n"); - goto psb_intel_pipe_cleaner; - } - - - /* We are displaying this buffer, make sure it is actually loaded - into the GTT */ - ret = psb_gtt_pin(psbfb->gtt); - if (ret < 0) - goto psb_intel_pipe_set_base_exit; - start = psbfb->gtt->offset; - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - - REG_WRITE(dspstride, crtc->fb->pitches[0]); - - dspcntr = REG_READ(dspcntr_reg); - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - - switch (crtc->fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (crtc->fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - dev_err(dev->dev, "Unknown color depth\n"); - ret = -EINVAL; - goto psb_intel_pipe_set_base_exit; - } - REG_WRITE(dspcntr_reg, dspcntr); - - dev_dbg(dev->dev, - "Writing base %08lX %08lX %d %d\n", start, offset, x, y); - - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - -psb_intel_pipe_cleaner: - /* If there was a previous display we can now unpin it */ - if (old_fb) - psb_gtt_unpin(to_psb_fb(old_fb)->gtt); - -psb_intel_pipe_set_base_exit: - gma_power_end(dev); - return ret; -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - u32 temp; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - /* Enable the DPLL */ - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - } - - /* Jim Bish - switch plan and pipe per scott */ - /* Enable the plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - } - - udelay(150); - - /* Enable the pipe */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); - - psb_intel_crtc_load_lut(crtc); - - /* Give the overlay scaler a chance to enable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ - break; - case DRM_MODE_DPMS_OFF: - /* Give the overlay scaler a chance to disable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Jim Bish - changed pipe/plane here as well. */ - - /* Wait for vblank for the disable to take effect */ - cdv_intel_wait_for_vblank(dev); - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - REG_READ(pipeconf_reg); - } - - /* Wait for vblank for the disable to take effect. */ - cdv_intel_wait_for_vblank(dev); - - udelay(150); - - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - } - - /* Wait for the clocks to turn off. */ - udelay(150); - break; - } - /*Set FIFO Watermarks*/ - REG_WRITE(DSPARB, 0x3F3E); -} - -static void cdv_intel_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void cdv_intel_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -} - -static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int cdv_intel_panel_fitter_pipe(struct drm_device *dev) -{ - u32 pfit_control; - - pfit_control = REG_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - return (pfit_control >> 29) & 0x3; -} - -static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; - int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; - int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; - int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; - int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; - int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; - int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; - int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk; - struct cdv_intel_clock_t clock; - u32 dpll = 0, dspcntr, pipeconf; - bool ok; - bool is_crt = false, is_lvds = false, is_tv = false; - bool is_hdmi = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - - if (!connector->encoder - || connector->encoder->crtc != crtc) - continue; - - switch (psb_intel_encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; - case INTEL_OUTPUT_HDMI: - is_hdmi = true; - break; - } - } - - refclk = 96000; - - /* Hack selection about ref clk for CRT */ - /* Select 27MHz as the reference clk for HDMI */ - if (is_crt || is_hdmi) - refclk = 27000; - - drm_mode_debug_printmodeline(adjusted_mode); - - ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, - &clock); - if (!ok) { - dev_err(dev->dev, "Couldn't find PLL settings for mode!\n"); - return 0; - } - - dpll = DPLL_VGA_MODE_DIS; - if (is_tv) { - /* XXX: just matching BIOS for now */ -/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - } - dpll |= PLL_REF_INPUT_DREFCLK; - - dpll |= DPLL_SYNCLOCK_ENABLE; - dpll |= DPLL_VGA_MODE_DIS; - if (is_lvds) - dpll |= DPLLB_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - /* dpll |= (2 << 11); */ - - /* setup pipeconf */ - pipeconf = REG_READ(pipeconf_reg); - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr |= DISPPLANE_SEL_PIPE_A; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - dspcntr |= DISPLAY_PLANE_ENABLE; - pipeconf |= PIPEACONF_ENABLE; - - REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); - REG_READ(dpll_reg); - - cdv_dpll_set_clock_cdv(dev, crtc, &clock); - - udelay(150); - - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) { - u32 lvds = REG_READ(LVDS); - - lvds |= - LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | - LVDS_PIPEB_SELECT; - /* Set the B0-B3 data pairs corresponding to - * whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more - * thoroughly into how panels behave in the two modes. - */ - - REG_WRITE(LVDS, lvds); - REG_READ(LVDS); - } - - dpll |= DPLL_VCO_ENABLE; - - /* Disable the panel fitter if it was on our pipe */ - if (cdv_intel_panel_fitter_pipe(dev) == pipe) - REG_WRITE(PFIT_CONTROL, 0); - - DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - drm_mode_debug_printmodeline(mode); - - REG_WRITE(dpll_reg, - (REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); /* 42 usec w/o calibration, 110 with. rounded up. */ - - if (!(REG_READ(dpll_reg) & DPLL_LOCK)) { - dev_err(dev->dev, "Failed to get DPLL lock\n"); - return -EBUSY; - } - - { - int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; - REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); - } - - REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - REG_WRITE(dspsize_reg, - ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(dsppos_reg, 0); - REG_WRITE(pipesrc_reg, - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - - cdv_intel_wait_for_vblank(dev); - - REG_WRITE(dspcntr_reg, dspcntr); - - /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } - - cdv_intel_wait_for_vblank(dev); - - return 0; -} - -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int palreg = PALETTE_A; - int i; - - /* The clocks have to be on to load the palette. */ - if (!crtc->enabled) - return; - - switch (psb_intel_crtc->pipe) { - case 0: - break; - case 1: - palreg = PALETTE_B; - break; - case 2: - palreg = PALETTE_C; - break; - default: - dev_err(dev->dev, "Illegal Pipe Number.\n"); - return; - } - - if (gma_power_begin(dev, false)) { - for (i = 0; i < 256; i++) { - REG_WRITE(palreg + 4 * i, - ((psb_intel_crtc->lut_r[i] + - psb_intel_crtc->lut_adj[i]) << 16) | - ((psb_intel_crtc->lut_g[i] + - psb_intel_crtc->lut_adj[i]) << 8) | - (psb_intel_crtc->lut_b[i] + - psb_intel_crtc->lut_adj[i])); - } - gma_power_end(dev); - } else { - for (i = 0; i < 256; i++) { - dev_priv->regs.psb.save_palette_a[i] = - ((psb_intel_crtc->lut_r[i] + - psb_intel_crtc->lut_adj[i]) << 16) | - ((psb_intel_crtc->lut_g[i] + - psb_intel_crtc->lut_adj[i]) << 8) | - (psb_intel_crtc->lut_b[i] + - psb_intel_crtc->lut_adj[i]); - } - - } -} - -/** - * Save HW states of giving crtc - */ -static void cdv_intel_crtc_save(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - int pipeA = (psb_intel_crtc->pipe == 0); - uint32_t paletteReg; - int i; - - if (!crtc_state) { - dev_dbg(dev->dev, "No CRTC state found\n"); - return; - } - - crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); - crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); - crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); - crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); - crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); - crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); - crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); - crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); - crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); - crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); - crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); - crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); - crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); - - /*NOTE: DSPSIZE DSPPOS only for psb*/ - crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); - crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); - - crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); - - DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - crtc_state->saveDSPCNTR, - crtc_state->savePIPECONF, - crtc_state->savePIPESRC, - crtc_state->saveFP0, - crtc_state->saveFP1, - crtc_state->saveDPLL, - crtc_state->saveHTOTAL, - crtc_state->saveHBLANK, - crtc_state->saveHSYNC, - crtc_state->saveVTOTAL, - crtc_state->saveVBLANK, - crtc_state->saveVSYNC, - crtc_state->saveDSPSTRIDE, - crtc_state->saveDSPSIZE, - crtc_state->saveDSPPOS, - crtc_state->saveDSPBASE - ); - - paletteReg = pipeA ? PALETTE_A : PALETTE_B; - for (i = 0; i < 256; ++i) - crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); -} - -/** - * Restore HW states of giving crtc - */ -static void cdv_intel_crtc_restore(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_psb_private * dev_priv = - (struct drm_psb_private *)dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ - int pipeA = (psb_intel_crtc->pipe == 0); - uint32_t paletteReg; - int i; - - if (!crtc_state) { - dev_dbg(dev->dev, "No crtc state\n"); - return; - } - - DRM_DEBUG( - "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - REG_READ(pipeA ? DSPACNTR : DSPBCNTR), - REG_READ(pipeA ? PIPEACONF : PIPEBCONF), - REG_READ(pipeA ? PIPEASRC : PIPEBSRC), - REG_READ(pipeA ? FPA0 : FPB0), - REG_READ(pipeA ? FPA1 : FPB1), - REG_READ(pipeA ? DPLL_A : DPLL_B), - REG_READ(pipeA ? HTOTAL_A : HTOTAL_B), - REG_READ(pipeA ? HBLANK_A : HBLANK_B), - REG_READ(pipeA ? HSYNC_A : HSYNC_B), - REG_READ(pipeA ? VTOTAL_A : VTOTAL_B), - REG_READ(pipeA ? VBLANK_A : VBLANK_B), - REG_READ(pipeA ? VSYNC_A : VSYNC_B), - REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE), - REG_READ(pipeA ? DSPASIZE : DSPBSIZE), - REG_READ(pipeA ? DSPAPOS : DSPBPOS), - REG_READ(pipeA ? DSPABASE : DSPBBASE) - ); - - DRM_DEBUG( - "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - crtc_state->saveDSPCNTR, - crtc_state->savePIPECONF, - crtc_state->savePIPESRC, - crtc_state->saveFP0, - crtc_state->saveFP1, - crtc_state->saveDPLL, - crtc_state->saveHTOTAL, - crtc_state->saveHBLANK, - crtc_state->saveHSYNC, - crtc_state->saveVTOTAL, - crtc_state->saveVBLANK, - crtc_state->saveVSYNC, - crtc_state->saveDSPSTRIDE, - crtc_state->saveDSPSIZE, - crtc_state->saveDSPPOS, - crtc_state->saveDSPBASE - ); - - - if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { - REG_WRITE(pipeA ? DPLL_A : DPLL_B, - crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); - REG_READ(pipeA ? DPLL_A : DPLL_B); - DRM_DEBUG("write dpll: %x\n", - REG_READ(pipeA ? DPLL_A : DPLL_B)); - udelay(150); - } - - REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); - REG_READ(pipeA ? FPA0 : FPB0); - - REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); - REG_READ(pipeA ? FPA1 : FPB1); - - REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); - REG_READ(pipeA ? DPLL_A : DPLL_B); - udelay(150); - - REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); - REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); - REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); - REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); - REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); - REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); - REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); - - REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); - REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); - - REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); - REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); - REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); - - cdv_intel_wait_for_vblank(dev); - - REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); - REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); - - cdv_intel_wait_for_vblank(dev); - - paletteReg = pipeA ? PALETTE_A : PALETTE_B; - for (i = 0; i < 256; ++i) - REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); -} - -static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, uint32_t height) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; - uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; - uint32_t temp; - size_t addr = 0; - struct gtt_range *gt; - struct drm_gem_object *obj; - int ret; - - /* if we want to turn of the cursor ignore width and height */ - if (!handle) { - /* turn off the cursor */ - temp = CURSOR_MODE_DISABLE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(control, temp); - REG_WRITE(base, 0); - gma_power_end(dev); - } - - /* unpin the old GEM object */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = NULL; - } - - return 0; - } - - /* Currently we only support 64x64 cursors */ - if (width != 64 || height != 64) { - dev_dbg(dev->dev, "we currently only support 64x64 cursors\n"); - return -EINVAL; - } - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) - return -ENOENT; - - if (obj->size < width * height * 4) { - dev_dbg(dev->dev, "buffer is to small\n"); - return -ENOMEM; - } - - gt = container_of(obj, struct gtt_range, gem); - - /* Pin the memory into the GTT */ - ret = psb_gtt_pin(gt); - if (ret) { - dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); - return ret; - } - - addr = gt->offset; /* Or resource.start ??? */ - - psb_intel_crtc->cursor_addr = addr; - - temp = 0; - /* set the pipe for the cursor */ - temp |= (pipe << 28); - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(control, temp); - REG_WRITE(base, addr); - gma_power_end(dev); - } - - /* unpin the old GEM object */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = obj; - } - return 0; -} - -static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - uint32_t temp = 0; - uint32_t adder; - - - if (x < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); - x = -x; - } - if (y < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); - y = -y; - } - - temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); - temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); - - adder = psb_intel_crtc->cursor_addr; - - if (gma_power_begin(dev, false)) { - REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); - REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); - gma_power_end(dev); - } - return 0; -} - -static void cdv_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, uint32_t start, uint32_t size) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int i; - int end = (start + size > 256) ? 256 : start + size; - - for (i = start; i < end; i++) { - psb_intel_crtc->lut_r[i] = red[i] >> 8; - psb_intel_crtc->lut_g[i] = green[i] >> 8; - psb_intel_crtc->lut_b[i] = blue[i] >> 8; - } - - cdv_intel_crtc_load_lut(crtc); -} - -static int cdv_crtc_set_config(struct drm_mode_set *set) -{ - int ret = 0; - struct drm_device *dev = set->crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->rpm_enabled) - return drm_crtc_helper_set_config(set); - - pm_runtime_forbid(&dev->pdev->dev); - - ret = drm_crtc_helper_set_config(set); - - pm_runtime_allow(&dev->pdev->dev); - - return ret; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -/* FIXME: why are we using this, should it be cdv_ in this tree ? */ - -static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/* Returns the clock of the currently programmed mode of the given pipe. */ -static int cdv_intel_crtc_clock_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - u32 dpll; - u32 fp; - struct cdv_intel_clock_t clock; - bool is_lvds; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (gma_power_begin(dev, false)) { - dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = REG_READ((pipe == 0) ? FPA0 : FPB0); - else - fp = REG_READ((pipe == 0) ? FPA1 : FPB1); - is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); - gma_power_end(dev); - } else { - dpll = (pipe == 0) ? - dev_priv->regs.psb.saveDPLL_A : - dev_priv->regs.psb.saveDPLL_B; - - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = (pipe == 0) ? - dev_priv->regs.psb.saveFPA0 : - dev_priv->regs.psb.saveFPB0; - else - fp = (pipe == 0) ? - dev_priv->regs.psb.saveFPA1 : - dev_priv->regs.psb.saveFPB1; - - is_lvds = (pipe == 1) && - (dev_priv->regs.psb.saveLVDS & LVDS_PORT_EN); - } - - clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; - clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; - - if (is_lvds) { - clock.p1 = - ffs((dpll & - DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - if (clock.p1 == 0) { - clock.p1 = 4; - dev_err(dev->dev, "PLL %d\n", dpll); - } - clock.p2 = 14; - - if ((dpll & PLL_REF_INPUT_MASK) == - PLLB_REF_INPUT_SPREADSPECTRUMIN) { - /* XXX: might not be 66MHz */ - i8xx_clock(66000, &clock); - } else - i8xx_clock(48000, &clock); - } else { - if (dpll & PLL_P1_DIVIDE_BY_TWO) - clock.p1 = 2; - else { - clock.p1 = - ((dpll & - DPLL_FPA01_P1_POST_DIV_MASK_I830) >> - DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; - } - if (dpll & PLL_P2_DIVIDE_BY_4) - clock.p2 = 4; - else - clock.p2 = 2; - - i8xx_clock(48000, &clock); - } - - /* XXX: It would be nice to validate the clocks, but we can't reuse - * i830PllIsValid() because it relies on the xf86_config connector - * configuration being accurate, which it isn't necessarily. - */ - - return clock.dot; -} - -/** Returns the currently programmed mode of the given pipe. */ -struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - struct drm_display_mode *mode; - int htot; - int hsync; - int vtot; - int vsync; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (gma_power_begin(dev, false)) { - htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); - hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); - vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); - vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); - gma_power_end(dev); - } else { - htot = (pipe == 0) ? - dev_priv->regs.psb.saveHTOTAL_A : - dev_priv->regs.psb.saveHTOTAL_B; - hsync = (pipe == 0) ? - dev_priv->regs.psb.saveHSYNC_A : - dev_priv->regs.psb.saveHSYNC_B; - vtot = (pipe == 0) ? - dev_priv->regs.psb.saveVTOTAL_A : - dev_priv->regs.psb.saveVTOTAL_B; - vsync = (pipe == 0) ? - dev_priv->regs.psb.saveVSYNC_A : - dev_priv->regs.psb.saveVSYNC_B; - } - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - mode->clock = cdv_intel_crtc_clock_get(dev, crtc); - mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - return mode; -} - -static void cdv_intel_crtc_destroy(struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - - kfree(psb_intel_crtc->crtc_state); - drm_crtc_cleanup(crtc); - kfree(psb_intel_crtc); -} - -const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { - .dpms = cdv_intel_crtc_dpms, - .mode_fixup = cdv_intel_crtc_mode_fixup, - .mode_set = cdv_intel_crtc_mode_set, - .mode_set_base = cdv_intel_pipe_set_base, - .prepare = cdv_intel_crtc_prepare, - .commit = cdv_intel_crtc_commit, -}; - -const struct drm_crtc_funcs cdv_intel_crtc_funcs = { - .save = cdv_intel_crtc_save, - .restore = cdv_intel_crtc_restore, - .cursor_set = cdv_intel_crtc_cursor_set, - .cursor_move = cdv_intel_crtc_cursor_move, - .gamma_set = cdv_intel_crtc_gamma_set, - .set_config = cdv_crtc_set_config, - .destroy = cdv_intel_crtc_destroy, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_hdmi.c deleted file mode 100644 index 8d526955..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright © 2006-2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * - * FIXME: - * We should probably make this generic and share it with Medfield - */ - -#include -#include -#include -#include -#include "psb_intel_drv.h" -#include "psb_drv.h" -#include "psb_intel_reg.h" -#include "cdv_device.h" -#include - -/* hdmi control bits */ -#define HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9) -#define HDMI_BORDER_ENABLE (1 << 7) -#define HDMI_AUDIO_ENABLE (1 << 6) -#define HDMI_VSYNC_ACTIVE_HIGH (1 << 4) -#define HDMI_HSYNC_ACTIVE_HIGH (1 << 3) -/* hdmi-b control bits */ -#define HDMIB_PIPE_B_SELECT (1 << 30) - - -struct mid_intel_hdmi_priv { - u32 hdmi_reg; - u32 save_HDMIB; - bool has_hdmi_sink; - bool has_hdmi_audio; - /* Should set this when detect hotplug */ - bool hdmi_device_connected; - struct mdfld_hdmi_i2c *i2c_bus; - struct i2c_adapter *hdmi_i2c_adapter; /* for control functions */ - struct drm_device *dev; -}; - -static void cdv_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_encoder *psb_intel_encoder = to_psb_intel_encoder(encoder); - struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; - u32 hdmib; - struct drm_crtc *crtc = encoder->crtc; - struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); - - hdmib = (2 << 10); - - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - hdmib |= HDMI_VSYNC_ACTIVE_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - hdmib |= HDMI_HSYNC_ACTIVE_HIGH; - - if (intel_crtc->pipe == 1) - hdmib |= HDMIB_PIPE_B_SELECT; - - if (hdmi_priv->has_hdmi_audio) { - hdmib |= HDMI_AUDIO_ENABLE; - hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC; - } - - REG_WRITE(hdmi_priv->hdmi_reg, hdmib); - REG_READ(hdmi_priv->hdmi_reg); -} - -static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_encoder *psb_intel_encoder = - to_psb_intel_encoder(encoder); - struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; - u32 hdmib; - - hdmib = REG_READ(hdmi_priv->hdmi_reg); - - if (mode != DRM_MODE_DPMS_ON) - REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN); - else - REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN); - REG_READ(hdmi_priv->hdmi_reg); -} - -static void cdv_hdmi_save(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; - - hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg); -} - -static void cdv_hdmi_restore(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; - - REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB); - REG_READ(hdmi_priv->hdmi_reg); -} - -static enum drm_connector_status cdv_hdmi_detect( - struct drm_connector *connector, bool force) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct psb_intel_connector *psb_intel_connector = - to_psb_intel_connector(connector); - struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; - struct edid *edid = NULL; - enum drm_connector_status status = connector_status_disconnected; - - edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter); - - hdmi_priv->has_hdmi_sink = false; - hdmi_priv->has_hdmi_audio = false; - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - hdmi_priv->has_hdmi_sink = - drm_detect_hdmi_monitor(edid); - hdmi_priv->has_hdmi_audio = - drm_detect_monitor_audio(edid); - } - - psb_intel_connector->base.display_info.raw_edid = NULL; - kfree(edid); - } - return status; -} - -static int cdv_hdmi_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct drm_encoder *encoder = connector->encoder; - - if (!strcmp(property->name, "scaling mode") && encoder) { - struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc); - bool centre; - uint64_t curValue; - - if (!crtc) - return -1; - - switch (value) { - case DRM_MODE_SCALE_FULLSCREEN: - break; - case DRM_MODE_SCALE_NO_SCALE: - break; - case DRM_MODE_SCALE_ASPECT: - break; - default: - return -1; - } - - if (drm_connector_property_get_value(connector, - property, &curValue)) - return -1; - - if (curValue == value) - return 0; - - if (drm_connector_property_set_value(connector, - property, value)) - return -1; - - centre = (curValue == DRM_MODE_SCALE_NO_SCALE) || - (value == DRM_MODE_SCALE_NO_SCALE); - - if (crtc->saved_mode.hdisplay != 0 && - crtc->saved_mode.vdisplay != 0) { - if (centre) { - if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode, - encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) - return -1; - } else { - struct drm_encoder_helper_funcs *helpers - = encoder->helper_private; - helpers->mode_set(encoder, &crtc->saved_mode, - &crtc->saved_adjusted_mode); - } - } - } - return 0; -} - -/* - * Return the list of HDMI DDC modes if available. - */ -static int cdv_hdmi_get_modes(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct edid *edid = NULL; - int ret = 0; - - edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter); - if (edid) { - drm_mode_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - } - return ret; -} - -static int cdv_hdmi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_psb_private *dev_priv = connector->dev->dev_private; - - if (mode->clock > 165000) - return MODE_CLOCK_HIGH; - if (mode->clock < 20000) - return MODE_CLOCK_HIGH; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - - /* We assume worst case scenario of 32 bpp here, since we don't know */ - if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > - dev_priv->vram_stolen_size) - return MODE_MEM; - - return MODE_OK; -} - -static void cdv_hdmi_destroy(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - - if (psb_intel_encoder->i2c_bus) - psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = { - .dpms = cdv_hdmi_dpms, - .mode_fixup = cdv_hdmi_mode_fixup, - .prepare = psb_intel_encoder_prepare, - .mode_set = cdv_hdmi_mode_set, - .commit = psb_intel_encoder_commit, -}; - -static const struct drm_connector_helper_funcs - cdv_hdmi_connector_helper_funcs = { - .get_modes = cdv_hdmi_get_modes, - .mode_valid = cdv_hdmi_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -static const struct drm_connector_funcs cdv_hdmi_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = cdv_hdmi_save, - .restore = cdv_hdmi_restore, - .detect = cdv_hdmi_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = cdv_hdmi_set_property, - .destroy = cdv_hdmi_destroy, -}; - -void cdv_hdmi_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev, int reg) -{ - struct psb_intel_encoder *psb_intel_encoder; - struct psb_intel_connector *psb_intel_connector; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct mid_intel_hdmi_priv *hdmi_priv; - int ddc_bus; - - psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), - GFP_KERNEL); - - if (!psb_intel_encoder) - return; - - psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), - GFP_KERNEL); - - if (!psb_intel_connector) - goto err_connector; - - hdmi_priv = kzalloc(sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); - - if (!hdmi_priv) - goto err_priv; - - connector = &psb_intel_connector->base; - encoder = &psb_intel_encoder->base; - drm_connector_init(dev, connector, - &cdv_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_DVID); - - drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_TMDS); - - psb_intel_connector_attach_encoder(psb_intel_connector, - psb_intel_encoder); - psb_intel_encoder->type = INTEL_OUTPUT_HDMI; - hdmi_priv->hdmi_reg = reg; - hdmi_priv->has_hdmi_sink = false; - psb_intel_encoder->dev_priv = hdmi_priv; - - drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs); - drm_connector_helper_add(connector, - &cdv_hdmi_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - - switch (reg) { - case SDVOB: - ddc_bus = GPIOE; - break; - case SDVOC: - ddc_bus = GPIOD; - break; - default: - DRM_ERROR("unknown reg 0x%x for HDMI\n", reg); - goto failed_ddc; - break; - } - - psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev, - ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC"); - - if (!psb_intel_encoder->i2c_bus) { - dev_err(dev->dev, "No ddc adapter available!\n"); - goto failed_ddc; - } - - hdmi_priv->hdmi_i2c_adapter = - &(psb_intel_encoder->i2c_bus->adapter); - hdmi_priv->dev = dev; - drm_sysfs_connector_add(connector); - return; - -failed_ddc: - drm_encoder_cleanup(encoder); - drm_connector_cleanup(connector); -err_priv: - kfree(psb_intel_connector); -err_connector: - kfree(psb_intel_encoder); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_lvds.c deleted file mode 100644 index 8359c1a3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ /dev/null @@ -1,734 +0,0 @@ -/* - * Copyright © 2006-2011 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - * Dave Airlie - * Jesse Barnes - */ - -#include -#include -#include - -#include "intel_bios.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "power.h" -#include -#include "cdv_device.h" - -/** - * LVDS I2C backlight control macros - */ -#define BRIGHTNESS_MAX_LEVEL 100 -#define BRIGHTNESS_MASK 0xFF -#define BLC_I2C_TYPE 0x01 -#define BLC_PWM_TYPT 0x02 - -#define BLC_POLARITY_NORMAL 0 -#define BLC_POLARITY_INVERSE 1 - -#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE) -#define PSB_BLC_MIN_PWM_REG_FREQ (0x2) -#define PSB_BLC_PWM_PRECISION_FACTOR (10) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) - -struct cdv_intel_lvds_priv { - /** - * Saved LVDO output states - */ - uint32_t savePP_ON; - uint32_t savePP_OFF; - uint32_t saveLVDS; - uint32_t savePP_CONTROL; - uint32_t savePP_CYCLE; - uint32_t savePFIT_CONTROL; - uint32_t savePFIT_PGM_RATIOS; - uint32_t saveBLC_PWM_CTL; -}; - -/* - * Returns the maximum level of the backlight duty cycle field. - */ -static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 retval; - - if (gma_power_begin(dev, false)) { - retval = ((REG_READ(BLC_PWM_CTL) & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - gma_power_end(dev); - } else - retval = ((dev_priv->regs.saveBLC_PWM_CTL & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - return retval; -} - -#if 0 -/* - * Set LVDS backlight level by I2C command - */ -static int cdv_lvds_i2c_set_brightness(struct drm_device *dev, - unsigned int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus; - u8 out_buf[2]; - unsigned int blc_i2c_brightness; - - struct i2c_msg msgs[] = { - { - .addr = lvds_i2c_bus->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - } - }; - - blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level * - BRIGHTNESS_MASK / - BRIGHTNESS_MAX_LEVEL); - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness; - - out_buf[0] = dev_priv->lvds_bl->brightnesscmd; - out_buf[1] = (u8)blc_i2c_brightness; - - if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) - return 0; - - DRM_ERROR("I2C transfer error\n"); - return -1; -} - - -static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - u32 max_pwm_blc; - u32 blc_pwm_duty_cycle; - - max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev); - - /*BLC_PWM_CTL Should be initiated while backlight device init*/ - BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); - - blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle; - - blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (blc_pwm_duty_cycle)); - - return 0; -} - -/* - * Set LVDS backlight level either by I2C or PWM - */ -void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->lvds_bl) { - DRM_ERROR("NO LVDS Backlight Info\n"); - return; - } - - if (dev_priv->lvds_bl->type == BLC_I2C_TYPE) - cdv_lvds_i2c_set_brightness(dev, level); - else - cdv_lvds_pwm_set_brightness(dev, level); -} -#endif - -/** - * Sets the backlight level. - * - * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight(). - */ -static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 blc_pwm_ctl; - - if (gma_power_begin(dev, false)) { - blc_pwm_ctl = - REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - REG_WRITE(BLC_PWM_CTL, - (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); - gma_power_end(dev); - } else { - blc_pwm_ctl = dev_priv->regs.saveBLC_PWM_CTL & - ~BACKLIGHT_DUTY_CYCLE_MASK; - dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); - } -} - -/** - * Sets the power state for the panel. - */ -static void cdv_intel_lvds_set_power(struct drm_device *dev, - struct drm_encoder *encoder, bool on) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pp_status; - - if (!gma_power_begin(dev, true)) - return; - - if (on) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - - cdv_intel_lvds_set_backlight(dev, - dev_priv->mode_dev.backlight_duty_cycle); - } else { - cdv_intel_lvds_set_backlight(dev, 0); - - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - } - gma_power_end(dev); -} - -static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - if (mode == DRM_MODE_DPMS_ON) - cdv_intel_lvds_set_power(dev, encoder, true); - else - cdv_intel_lvds_set_power(dev, encoder, false); - /* XXX: We never power down the LVDS pairs. */ -} - -static void cdv_intel_lvds_save(struct drm_connector *connector) -{ -} - -static void cdv_intel_lvds_restore(struct drm_connector *connector) -{ -} - -static int cdv_intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_display_mode *fixed_mode = - dev_priv->mode_dev.panel_fixed_mode; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - - if (fixed_mode) { - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; - } - return MODE_OK; -} - -static bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct drm_encoder *tmp_encoder; - struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode; - - /* Should never happen!! */ - list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, - head) { - if (tmp_encoder != encoder - && tmp_encoder->crtc == encoder->crtc) { - printk(KERN_ERR "Can't enable LVDS and another " - "encoder on the same pipe\n"); - return false; - } - } - - /* - * If we have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - if (panel_fixed_mode != NULL) { - adjusted_mode->hdisplay = panel_fixed_mode->hdisplay; - adjusted_mode->hsync_start = panel_fixed_mode->hsync_start; - adjusted_mode->hsync_end = panel_fixed_mode->hsync_end; - adjusted_mode->htotal = panel_fixed_mode->htotal; - adjusted_mode->vdisplay = panel_fixed_mode->vdisplay; - adjusted_mode->vsync_start = panel_fixed_mode->vsync_start; - adjusted_mode->vsync_end = panel_fixed_mode->vsync_end; - adjusted_mode->vtotal = panel_fixed_mode->vtotal; - adjusted_mode->clock = panel_fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, - CRTC_INTERLACE_HALVE_V); - } - - /* - * XXX: It would be nice to support lower refresh rates on the - * panels to reduce power consumption, and perhaps match the - * user's requested refresh rate. - */ - - return true; -} - -static void cdv_intel_lvds_prepare(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - - if (!gma_power_begin(dev, true)) - return; - - mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - - cdv_intel_lvds_set_power(dev, encoder, false); - - gma_power_end(dev); -} - -static void cdv_intel_lvds_commit(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - - if (mode_dev->backlight_duty_cycle == 0) - mode_dev->backlight_duty_cycle = - cdv_intel_lvds_get_max_backlight(dev); - - cdv_intel_lvds_set_power(dev, encoder, true); -} - -static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pfit_control; - - /* - * The LVDS pin pair will already have been turned on in the - * cdv_intel_crtc_mode_set since it has a large impact on the DPLL - * settings. - */ - - /* - * Enable automatic panel scaling so that non-native modes fill the - * screen. Should be enabled before the pipe is enabled, according to - * register description and PRM. - */ - if (mode->hdisplay != adjusted_mode->hdisplay || - mode->vdisplay != adjusted_mode->vdisplay) - pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | - HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - else - pfit_control = 0; - - if (dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - - REG_WRITE(PFIT_CONTROL, pfit_control); -} - -/** - * Detect the LVDS connection. - * - * This always returns CONNECTOR_STATUS_CONNECTED. - * This connector should only have - * been set up if the LVDS was actually connected anyway. - */ -static enum drm_connector_status cdv_intel_lvds_detect( - struct drm_connector *connector, bool force) -{ - return connector_status_connected; -} - -/** - * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. - */ -static int cdv_intel_lvds_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - int ret; - - ret = psb_intel_ddc_get_modes(connector, &psb_intel_encoder->i2c_bus->adapter); - - if (ret) - return ret; - - /* Didn't get an EDID, so - * Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - connector->display_info.min_vfreq = 0; - connector->display_info.max_vfreq = 200; - connector->display_info.min_hfreq = 0; - connector->display_info.max_hfreq = 200; - if (mode_dev->panel_fixed_mode != NULL) { - struct drm_display_mode *mode = - drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); - drm_mode_probed_add(connector, mode); - return 1; - } - - return 0; -} - -/** - * cdv_intel_lvds_destroy - unregister and free LVDS structures - * @connector: connector to free - * - * Unregister the DDC bus for this connector then free the driver private - * structure. - */ -static void cdv_intel_lvds_destroy(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - - if (psb_intel_encoder->i2c_bus) - psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static int cdv_intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct drm_encoder *encoder = connector->encoder; - - if (!strcmp(property->name, "scaling mode") && encoder) { - struct psb_intel_crtc *crtc = - to_psb_intel_crtc(encoder->crtc); - uint64_t curValue; - - if (!crtc) - return -1; - - switch (value) { - case DRM_MODE_SCALE_FULLSCREEN: - break; - case DRM_MODE_SCALE_NO_SCALE: - break; - case DRM_MODE_SCALE_ASPECT: - break; - default: - return -1; - } - - if (drm_connector_property_get_value(connector, - property, - &curValue)) - return -1; - - if (curValue == value) - return 0; - - if (drm_connector_property_set_value(connector, - property, - value)) - return -1; - - if (crtc->saved_mode.hdisplay != 0 && - crtc->saved_mode.vdisplay != 0) { - if (!drm_crtc_helper_set_mode(encoder->crtc, - &crtc->saved_mode, - encoder->crtc->x, - encoder->crtc->y, - encoder->crtc->fb)) - return -1; - } - } else if (!strcmp(property->name, "backlight") && encoder) { - if (drm_connector_property_set_value(connector, - property, - value)) - return -1; - else { -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct drm_psb_private *dev_priv = - encoder->dev->dev_private; - struct backlight_device *bd = - dev_priv->backlight_device; - bd->props.brightness = value; - backlight_update_status(bd); -#endif - } - } else if (!strcmp(property->name, "DPMS") && encoder) { - struct drm_encoder_helper_funcs *helpers = - encoder->helper_private; - helpers->dpms(encoder, value); - } - return 0; -} - -static const struct drm_encoder_helper_funcs - cdv_intel_lvds_helper_funcs = { - .dpms = cdv_intel_lvds_encoder_dpms, - .mode_fixup = cdv_intel_lvds_mode_fixup, - .prepare = cdv_intel_lvds_prepare, - .mode_set = cdv_intel_lvds_mode_set, - .commit = cdv_intel_lvds_commit, -}; - -static const struct drm_connector_helper_funcs - cdv_intel_lvds_connector_helper_funcs = { - .get_modes = cdv_intel_lvds_get_modes, - .mode_valid = cdv_intel_lvds_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = cdv_intel_lvds_save, - .restore = cdv_intel_lvds_restore, - .detect = cdv_intel_lvds_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = cdv_intel_lvds_set_property, - .destroy = cdv_intel_lvds_destroy, -}; - - -static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { - .destroy = cdv_intel_lvds_enc_destroy, -}; - -/** - * cdv_intel_lvds_init - setup LVDS connectors on this device - * @dev: drm device - * - * Create the connector, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -void cdv_intel_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct psb_intel_encoder *psb_intel_encoder; - struct psb_intel_connector *psb_intel_connector; - struct cdv_intel_lvds_priv *lvds_priv; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct drm_display_mode *scan; - struct drm_crtc *crtc; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 lvds; - int pipe; - - psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), - GFP_KERNEL); - if (!psb_intel_encoder) - return; - - psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), - GFP_KERNEL); - if (!psb_intel_connector) - goto failed_connector; - - lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL); - if (!lvds_priv) - goto failed_lvds_priv; - - psb_intel_encoder->dev_priv = lvds_priv; - - connector = &psb_intel_connector->base; - encoder = &psb_intel_encoder->base; - - - drm_connector_init(dev, connector, - &cdv_intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - - drm_encoder_init(dev, encoder, - &cdv_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS); - - - psb_intel_connector_attach_encoder(psb_intel_connector, - psb_intel_encoder); - psb_intel_encoder->type = INTEL_OUTPUT_LVDS; - - drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs); - drm_connector_helper_add(connector, - &cdv_intel_lvds_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /*Attach connector properties*/ - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, - dev_priv->backlight_property, - BRIGHTNESS_MAX_LEVEL); - - /** - * Set up I2C bus - * FIXME: distroy i2c_bus when exit - */ - psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev, - GPIOB, - "LVDSBLC_B"); - if (!psb_intel_encoder->i2c_bus) { - dev_printk(KERN_ERR, - &dev->pdev->dev, "I2C bus registration failed.\n"); - goto failed_blc_i2c; - } - psb_intel_encoder->i2c_bus->slave_addr = 0x2C; - dev_priv->lvds_i2c_bus = psb_intel_encoder->i2c_bus; - - /* - * LVDS discovery: - * 1) check for EDID on DDC - * 2) check for VBT data - * 3) check to see if LVDS is already on - * if none of the above, no panel - * 4) make sure lid is open - * if closed, act like it's not there for now - */ - - /* Set up the DDC bus. */ - psb_intel_encoder->ddc_bus = psb_intel_i2c_create(dev, - GPIOC, - "LVDSDDC_C"); - if (!psb_intel_encoder->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, - "DDC bus registration " "failed.\n"); - goto failed_ddc; - } - - /* - * Attempt to get the fixed panel mode from DDC. Assume that the - * preferred mode is the right one. - */ - psb_intel_ddc_get_modes(connector, - &psb_intel_encoder->ddc_bus->adapter); - list_for_each_entry(scan, &connector->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) { - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, scan); - goto out; /* FIXME: check for quirks */ - } - } - - /* Failed to get EDID, what about VBT? do we need this?*/ - if (dev_priv->lfp_lvds_vbt_mode) { - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); - if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; /* FIXME: check for quirks */ - } - } - /* - * If we didn't get EDID, try checking if the panel is already turned - * on. If so, assume that whatever is currently programmed is the - * correct mode. - */ - lvds = REG_READ(LVDS); - pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - crtc = psb_intel_get_crtc_from_pipe(dev, pipe); - - if (crtc && (lvds & LVDS_PORT_EN)) { - mode_dev->panel_fixed_mode = - cdv_intel_crtc_mode_get(dev, crtc); - if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; /* FIXME: check for quirks */ - } - } - - /* If we still don't have a mode after all that, give up. */ - if (!mode_dev->panel_fixed_mode) { - DRM_DEBUG - ("Found no modes on the lvds, ignoring the LVDS\n"); - goto failed_find; - } - -out: - drm_sysfs_connector_add(connector); - return; - -failed_find: - printk(KERN_ERR "Failed find\n"); - if (psb_intel_encoder->ddc_bus) - psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus); -failed_ddc: - printk(KERN_ERR "Failed DDC\n"); - if (psb_intel_encoder->i2c_bus) - psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus); -failed_blc_i2c: - printk(KERN_ERR "Failed BLC\n"); - drm_encoder_cleanup(encoder); - drm_connector_cleanup(connector); - kfree(lvds_priv); -failed_lvds_priv: - kfree(psb_intel_connector); -failed_connector: - kfree(psb_intel_encoder); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.c deleted file mode 100644 index 8ea202f1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.c +++ /dev/null @@ -1,800 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "psb_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_drv.h" -#include "framebuffer.h" -#include "gtt.h" - -static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); -static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle); - -static const struct drm_framebuffer_funcs psb_fb_funcs = { - .destroy = psb_user_framebuffer_destroy, - .create_handle = psb_user_framebuffer_create_handle, -}; - -#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) - -static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) -{ - struct psb_fbdev *fbdev = info->par; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - uint32_t v; - - if (!fb) - return -ENOMEM; - - if (regno > 255) - return 1; - - red = CMAP_TOHW(red, info->var.red.length); - blue = CMAP_TOHW(blue, info->var.blue.length); - green = CMAP_TOHW(green, info->var.green.length); - transp = CMAP_TOHW(transp, info->var.transp.length); - - v = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset) | - (transp << info->var.transp.offset); - - if (regno < 16) { - switch (fb->bits_per_pixel) { - case 16: - ((uint32_t *) info->pseudo_palette)[regno] = v; - break; - case 24: - case 32: - ((uint32_t *) info->pseudo_palette)[regno] = v; - break; - } - } - - return 0; -} - -static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - - /* - * We have to poke our nose in here. The core fb code assumes - * panning is part of the hardware that can be invoked before - * the actual fb is mapped. In our case that isn't quite true. - */ - if (psbfb->gtt->npage) { - /* GTT roll shifts in 4K pages, we need to shift the right - number of pages */ - int pages = info->fix.line_length >> 12; - psb_gtt_roll(dev, psbfb->gtt, var->yoffset * pages); - } - return 0; -} - -static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct psb_framebuffer *psbfb = vma->vm_private_data; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - int page_num; - int i; - unsigned long address; - int ret; - unsigned long pfn; - /* FIXME: assumes fb at stolen base which may not be true */ - unsigned long phys_addr = (unsigned long)dev_priv->stolen_base; - - page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT); - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - for (i = 0; i < page_num; i++) { - pfn = (phys_addr >> PAGE_SHIFT); - - ret = vm_insert_mixed(vma, address, pfn); - if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0))) - break; - else if (unlikely(ret != 0)) { - ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; - return ret; - } - address += PAGE_SIZE; - phys_addr += PAGE_SIZE; - } - return VM_FAULT_NOPAGE; -} - -static void psbfb_vm_open(struct vm_area_struct *vma) -{ -} - -static void psbfb_vm_close(struct vm_area_struct *vma) -{ -} - -static struct vm_operations_struct psbfb_vm_ops = { - .fault = psbfb_vm_fault, - .open = psbfb_vm_open, - .close = psbfb_vm_close -}; - -static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = &fbdev->pfb; - - if (vma->vm_pgoff != 0) - return -EINVAL; - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - - if (!psbfb->addr_space) - psbfb->addr_space = vma->vm_file->f_mapping; - /* - * If this is a GEM object then info->screen_base is the virtual - * kernel remapping of the object. FIXME: Review if this is - * suitable for our mmap work - */ - vma->vm_ops = &psbfb_vm_ops; - vma->vm_private_data = (void *)psbfb; - vma->vm_flags |= VM_RESERVED | VM_IO | - VM_MIXEDMAP | VM_DONTEXPAND; - return 0; -} - -static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) -{ - return -ENOTTY; -} - -static struct fb_ops psbfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = psbfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_mmap = psbfb_mmap, - .fb_sync = psbfb_sync, - .fb_ioctl = psbfb_ioctl, -}; - -static struct fb_ops psbfb_roll_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_pan_display = psbfb_pan, - .fb_mmap = psbfb_mmap, - .fb_ioctl = psbfb_ioctl, -}; - -static struct fb_ops psbfb_unaccel_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_blank = drm_fb_helper_blank, - .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_mmap = psbfb_mmap, - .fb_ioctl = psbfb_ioctl, -}; - -/** - * psb_framebuffer_init - initialize a framebuffer - * @dev: our DRM device - * @fb: framebuffer to set up - * @mode_cmd: mode description - * @gt: backing object - * - * Configure and fill in the boilerplate for our frame buffer. Return - * 0 on success or an error code if we fail. - */ -static int psb_framebuffer_init(struct drm_device *dev, - struct psb_framebuffer *fb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct gtt_range *gt) -{ - u32 bpp, depth; - int ret; - - drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); - - if (mode_cmd->pitches[0] & 63) - return -EINVAL; - switch (bpp) { - case 8: - case 16: - case 24: - case 32: - break; - default: - return -EINVAL; - } - ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); - if (ret) { - dev_err(dev->dev, "framebuffer init failed: %d\n", ret); - return ret; - } - drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); - fb->gtt = gt; - return 0; -} - -/** - * psb_framebuffer_create - create a framebuffer backed by gt - * @dev: our DRM device - * @mode_cmd: the description of the requested mode - * @gt: the backing object - * - * Create a framebuffer object backed by the gt, and fill in the - * boilerplate required - * - * TODO: review object references - */ - -static struct drm_framebuffer *psb_framebuffer_create - (struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct gtt_range *gt) -{ - struct psb_framebuffer *fb; - int ret; - - fb = kzalloc(sizeof(*fb), GFP_KERNEL); - if (!fb) - return ERR_PTR(-ENOMEM); - - ret = psb_framebuffer_init(dev, fb, mode_cmd, gt); - if (ret) { - kfree(fb); - return ERR_PTR(ret); - } - return &fb->base; -} - -/** - * psbfb_alloc - allocate frame buffer memory - * @dev: the DRM device - * @aligned_size: space needed - * @force: fall back to GEM buffers if need be - * - * Allocate the frame buffer. In the usual case we get a GTT range that - * is stolen memory backed and life is simple. If there isn't sufficient - * we fail as we don't have the virtual mapping space to really vmap it - * and the kernel console code can't handle non linear framebuffers. - * - * Re-address this as and if the framebuffer layer grows this ability. - */ -static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) -{ - struct gtt_range *backing; - /* Begin by trying to use stolen memory backing */ - backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1); - if (backing) { - if (drm_gem_private_object_init(dev, - &backing->gem, aligned_size) == 0) - return backing; - psb_gtt_free_range(dev, backing); - } - return NULL; -} - -/** - * psbfb_create - create a framebuffer - * @fbdev: the framebuffer device - * @sizes: specification of the layout - * - * Create a framebuffer to the specifications provided - */ -static int psbfb_create(struct psb_fbdev *fbdev, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_device *dev = fbdev->psb_fb_helper.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct fb_info *info; - struct drm_framebuffer *fb; - struct psb_framebuffer *psbfb = &fbdev->pfb; - struct drm_mode_fb_cmd2 mode_cmd; - struct device *device = &dev->pdev->dev; - int size; - int ret; - struct gtt_range *backing; - u32 bpp, depth; - int gtt_roll = 0; - int pitch_lines = 0; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - bpp = sizes->surface_bpp; - depth = sizes->surface_depth; - - /* No 24bit packed */ - if (bpp == 24) - bpp = 32; - - do { - /* - * Acceleration via the GTT requires pitch to be - * power of two aligned. Preferably page but less - * is ok with some fonts - */ - mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096 >> pitch_lines); - - size = mode_cmd.pitches[0] * mode_cmd.height; - size = ALIGN(size, PAGE_SIZE); - - /* Allocate the fb in the GTT with stolen page backing */ - backing = psbfb_alloc(dev, size); - - if (pitch_lines) - pitch_lines *= 2; - else - pitch_lines = 1; - gtt_roll++; - } while (backing == NULL && pitch_lines <= 16); - - /* The final pitch we accepted if we succeeded */ - pitch_lines /= 2; - - if (backing == NULL) { - /* - * We couldn't get the space we wanted, fall back to the - * display engine requirement instead. The HW requires - * the pitch to be 64 byte aligned - */ - - gtt_roll = 0; /* Don't use GTT accelerated scrolling */ - pitch_lines = 64; - - mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64); - - size = mode_cmd.pitches[0] * mode_cmd.height; - size = ALIGN(size, PAGE_SIZE); - - /* Allocate the framebuffer in the GTT with stolen page backing */ - backing = psbfb_alloc(dev, size); - if (backing == NULL) - return -ENOMEM; - } - - mutex_lock(&dev->struct_mutex); - - info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; - goto out_err1; - } - info->par = fbdev; - - mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); - - ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing); - if (ret) - goto out_unref; - - fb = &psbfb->base; - psbfb->fbdev = info; - - fbdev->psb_fb_helper.fb = fb; - fbdev->psb_fb_helper.fbdev = info; - - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); - strcpy(info->fix.id, "psbfb"); - - info->flags = FBINFO_DEFAULT; - if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */ - info->fbops = &psbfb_ops; - else if (gtt_roll) { /* GTT rolling seems best */ - info->fbops = &psbfb_roll_ops; - info->flags |= FBINFO_HWACCEL_YPAN; - } else /* Software */ - info->fbops = &psbfb_unaccel_ops; - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; - } - - info->fix.smem_start = dev->mode_config.fb_base; - info->fix.smem_len = size; - info->fix.ywrapstep = gtt_roll; - info->fix.ypanstep = 0; - - /* Accessed stolen memory directly */ - info->screen_base = (char *)dev_priv->vram_addr + - backing->offset; - info->screen_size = size; - - if (dev_priv->gtt.stolen_size) { - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } - info->apertures->ranges[0].base = dev->mode_config.fb_base; - info->apertures->ranges[0].size = dev_priv->gtt.stolen_size; - } - - drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper, - sizes->fb_width, sizes->fb_height); - - info->fix.mmio_start = pci_resource_start(dev->pdev, 0); - info->fix.mmio_len = pci_resource_len(dev->pdev, 0); - - /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - - dev_info(dev->dev, "allocated %dx%d fb\n", - psbfb->base.width, psbfb->base.height); - - mutex_unlock(&dev->struct_mutex); - return 0; -out_unref: - if (backing->stolen) - psb_gtt_free_range(dev, backing); - else - drm_gem_object_unreference(&backing->gem); -out_err1: - mutex_unlock(&dev->struct_mutex); - psb_gtt_free_range(dev, backing); - return ret; -} - -/** - * psb_user_framebuffer_create - create framebuffer - * @dev: our DRM device - * @filp: client file - * @cmd: mode request - * - * Create a new framebuffer backed by a userspace GEM object - */ -static struct drm_framebuffer *psb_user_framebuffer_create - (struct drm_device *dev, struct drm_file *filp, - struct drm_mode_fb_cmd2 *cmd) -{ - struct gtt_range *r; - struct drm_gem_object *obj; - - /* - * Find the GEM object and thus the gtt range object that is - * to back this space - */ - obj = drm_gem_object_lookup(dev, filp, cmd->handles[0]); - if (obj == NULL) - return ERR_PTR(-ENOENT); - - /* Let the core code do all the work */ - r = container_of(obj, struct gtt_range, gem); - return psb_framebuffer_create(dev, cmd, r); -} - -static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); - - intel_crtc->lut_r[regno] = red >> 8; - intel_crtc->lut_g[regno] = green >> 8; - intel_crtc->lut_b[regno] = blue >> 8; -} - -static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, int regno) -{ - struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); - - *red = intel_crtc->lut_r[regno] << 8; - *green = intel_crtc->lut_g[regno] << 8; - *blue = intel_crtc->lut_b[regno] << 8; -} - -static int psbfb_probe(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper; - int new_fb = 0; - int ret; - - if (!helper->fb) { - ret = psbfb_create(psb_fbdev, sizes); - if (ret) - return ret; - new_fb = 1; - } - return new_fb; -} - -struct drm_fb_helper_funcs psb_fb_helper_funcs = { - .gamma_set = psbfb_gamma_set, - .gamma_get = psbfb_gamma_get, - .fb_probe = psbfb_probe, -}; - -static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) -{ - struct fb_info *info; - struct psb_framebuffer *psbfb = &fbdev->pfb; - - if (fbdev->psb_fb_helper.fbdev) { - info = fbdev->psb_fb_helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } - drm_fb_helper_fini(&fbdev->psb_fb_helper); - drm_framebuffer_cleanup(&psbfb->base); - - if (psbfb->gtt) - drm_gem_object_unreference(&psbfb->gtt->gem); - return 0; -} - -int psb_fbdev_init(struct drm_device *dev) -{ - struct psb_fbdev *fbdev; - struct drm_psb_private *dev_priv = dev->dev_private; - - fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL); - if (!fbdev) { - dev_err(dev->dev, "no memory\n"); - return -ENOMEM; - } - - dev_priv->fbdev = fbdev; - fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs; - - drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs, - INTELFB_CONN_LIMIT); - - drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper); - drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32); - return 0; -} - -static void psb_fbdev_fini(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->fbdev) - return; - - psb_fbdev_destroy(dev, dev_priv->fbdev); - kfree(dev_priv->fbdev); - dev_priv->fbdev = NULL; -} - -static void psbfb_output_poll_changed(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev; - drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper); -} - -/** - * psb_user_framebuffer_create_handle - add hamdle to a framebuffer - * @fb: framebuffer - * @file_priv: our DRM file - * @handle: returned handle - * - * Our framebuffer object is a GTT range which also contains a GEM - * object. We need to turn it into a handle for userspace. GEM will do - * the work for us - */ -static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - return drm_gem_handle_create(file_priv, &r->gem, handle); -} - -/** - * psb_user_framebuffer_destroy - destruct user created fb - * @fb: framebuffer - * - * User framebuffers are backed by GEM objects so all we have to do is - * clean up a bit and drop the reference, GEM will handle the fallout - */ -static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - struct drm_device *dev = fb->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_fbdev *fbdev = dev_priv->fbdev; - struct drm_crtc *crtc; - int reset = 0; - - /* Should never get stolen memory for a user fb */ - WARN_ON(r->stolen); - - /* Check if we are erroneously live */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - if (crtc->fb == fb) - reset = 1; - - if (reset) - /* - * Now force a sane response before we permit the DRM CRTC - * layer to do stupid things like blank the display. Instead - * we reset this framebuffer as if the user had forced a reset. - * We must do this before the cleanup so that the DRM layer - * doesn't get a chance to stick its oar in where it isn't - * wanted. - */ - drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper); - - /* Let DRM do its clean up */ - drm_framebuffer_cleanup(fb); - /* We are no longer using the resource in GEM */ - drm_gem_object_unreference_unlocked(&r->gem); - kfree(fb); -} - -static const struct drm_mode_config_funcs psb_mode_funcs = { - .fb_create = psb_user_framebuffer_create, - .output_poll_changed = psbfb_output_poll_changed, -}; - -static int psb_create_backlight_property(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_property *backlight; - - if (dev_priv->backlight_property) - return 0; - - backlight = drm_property_create_range(dev, 0, "backlight", 0, 100); - - dev_priv->backlight_property = backlight; - - return 0; -} - -static void psb_setup_outputs(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - - drm_mode_create_scaling_mode_property(dev); - psb_create_backlight_property(dev); - - dev_priv->ops->output_init(dev); - - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct drm_encoder *encoder = &psb_intel_encoder->base; - int crtc_mask = 0, clone_mask = 0; - - /* valid crtcs */ - switch (psb_intel_encoder->type) { - case INTEL_OUTPUT_ANALOG: - crtc_mask = (1 << 0); - clone_mask = (1 << INTEL_OUTPUT_ANALOG); - break; - case INTEL_OUTPUT_SDVO: - crtc_mask = ((1 << 0) | (1 << 1)); - clone_mask = (1 << INTEL_OUTPUT_SDVO); - break; - case INTEL_OUTPUT_LVDS: - if (IS_MRST(dev)) - crtc_mask = (1 << 0); - else - crtc_mask = (1 << 1); - clone_mask = (1 << INTEL_OUTPUT_LVDS); - break; - case INTEL_OUTPUT_MIPI: - crtc_mask = (1 << 0); - clone_mask = (1 << INTEL_OUTPUT_MIPI); - break; - case INTEL_OUTPUT_MIPI2: - crtc_mask = (1 << 2); - clone_mask = (1 << INTEL_OUTPUT_MIPI2); - break; - case INTEL_OUTPUT_HDMI: - if (IS_MFLD(dev)) - crtc_mask = (1 << 1); - else - crtc_mask = (1 << 0); - clone_mask = (1 << INTEL_OUTPUT_HDMI); - break; - } - encoder->possible_crtcs = crtc_mask; - encoder->possible_clones = - psb_intel_connector_clones(dev, clone_mask); - } -} - -void psb_modeset_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - int i; - - drm_mode_config_init(dev); - - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - - dev->mode_config.funcs = (void *) &psb_mode_funcs; - - /* set memory base */ - /* Oaktrail and Poulsbo should use BAR 2*/ - pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *) - &(dev->mode_config.fb_base)); - - /* num pipes is 2 for PSB but 1 for Mrst */ - for (i = 0; i < dev_priv->num_pipe; i++) - psb_intel_crtc_init(dev, i, mode_dev); - - dev->mode_config.max_width = 2048; - dev->mode_config.max_height = 2048; - - psb_setup_outputs(dev); -} - -void psb_modeset_cleanup(struct drm_device *dev) -{ - mutex_lock(&dev->struct_mutex); - - drm_kms_helper_poll_fini(dev); - psb_fbdev_fini(dev); - drm_mode_config_cleanup(dev); - - mutex_unlock(&dev->struct_mutex); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.h deleted file mode 100644 index 989558a9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/framebuffer.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2008-2011, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - * - */ - -#ifndef _FRAMEBUFFER_H_ -#define _FRAMEBUFFER_H_ - -#include -#include - -#include "psb_drv.h" - -struct psb_framebuffer { - struct drm_framebuffer base; - struct address_space *addr_space; - struct fb_info *fbdev; - struct gtt_range *gtt; -}; - -struct psb_fbdev { - struct drm_fb_helper psb_fb_helper; - struct psb_framebuffer pfb; -}; - -#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base) - -extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask); - -#endif - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem.c deleted file mode 100644 index 9fbb8686..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * psb GEM interface - * - * Copyright (c) 2011, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Alan Cox - * - * TODO: - * - we need to work out if the MMU is relevant (eg for - * accelerated operations on a GEM object) - */ - -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" - -int psb_gem_init_object(struct drm_gem_object *obj) -{ - return -EINVAL; -} - -void psb_gem_free_object(struct drm_gem_object *obj) -{ - struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); - drm_gem_object_release_wrap(obj); - /* This must occur last as it frees up the memory of the GEM object */ - psb_gtt_free_range(obj->dev, gtt); -} - -int psb_gem_get_aperture(struct drm_device *dev, void *data, - struct drm_file *file) -{ - return -EINVAL; -} - -/** - * psb_gem_dumb_map_gtt - buffer mapping for dumb interface - * @file: our drm client file - * @dev: drm device - * @handle: GEM handle to the object (from dumb_create) - * - * Do the necessary setup to allow the mapping of the frame buffer - * into user memory. We don't have to do much here at the moment. - */ -int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset) -{ - int ret = 0; - struct drm_gem_object *obj; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - mutex_lock(&dev->struct_mutex); - - /* GEM does all our handle to object mapping */ - obj = drm_gem_object_lookup(dev, file, handle); - if (obj == NULL) { - ret = -ENOENT; - goto unlock; - } - /* What validation is needed here ? */ - - /* Make it mmapable */ - if (!obj->map_list.map) { - ret = gem_create_mmap_offset(obj); - if (ret) - goto out; - } - /* GEM should really work out the hash offsets for us */ - *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; -out: - drm_gem_object_unreference(obj); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * psb_gem_create - create a mappable object - * @file: the DRM file of the client - * @dev: our device - * @size: the size requested - * @handlep: returned handle (opaque number) - * - * Create a GEM object, fill in the boilerplate and attach a handle to - * it so that userspace can speak about it. This does the core work - * for the various methods that do/will create GEM objects for things - */ -static int psb_gem_create(struct drm_file *file, - struct drm_device *dev, uint64_t size, uint32_t *handlep) -{ - struct gtt_range *r; - int ret; - u32 handle; - - size = roundup(size, PAGE_SIZE); - - /* Allocate our object - for now a direct gtt range which is not - stolen memory backed */ - r = psb_gtt_alloc_range(dev, size, "gem", 0); - if (r == NULL) { - dev_err(dev->dev, "no memory for %lld byte GEM object\n", size); - return -ENOSPC; - } - /* Initialize the extra goodies GEM needs to do all the hard work */ - if (drm_gem_object_init(dev, &r->gem, size) != 0) { - psb_gtt_free_range(dev, r); - /* GEM doesn't give an error code so use -ENOMEM */ - dev_err(dev->dev, "GEM init failed for %lld\n", size); - return -ENOMEM; - } - /* Give the object a handle so we can carry it more easily */ - ret = drm_gem_handle_create(file, &r->gem, &handle); - if (ret) { - dev_err(dev->dev, "GEM handle failed for %p, %lld\n", - &r->gem, size); - drm_gem_object_release(&r->gem); - psb_gtt_free_range(dev, r); - return ret; - } - /* We have the initial and handle reference but need only one now */ - drm_gem_object_unreference(&r->gem); - *handlep = handle; - return 0; -} - -/** - * psb_gem_dumb_create - create a dumb buffer - * @drm_file: our client file - * @dev: our device - * @args: the requested arguments copied from userspace - * - * Allocate a buffer suitable for use for a frame buffer of the - * form described by user space. Give userspace a handle by which - * to reference it. - */ -int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64); - args->size = args->pitch * args->height; - return psb_gem_create(file, dev, args->size, &args->handle); -} - -/** - * psb_gem_dumb_destroy - destroy a dumb buffer - * @file: client file - * @dev: our DRM device - * @handle: the object handle - * - * Destroy a handle that was created via psb_gem_dumb_create, at least - * we hope it was created that way. i915 seems to assume the caller - * does the checking but that might be worth review ! FIXME - */ -int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle) -{ - /* No special work needed, drop the reference and see what falls out */ - return drm_gem_handle_delete(file, handle); -} - -/** - * psb_gem_fault - pagefault handler for GEM objects - * @vma: the VMA of the GEM object - * @vmf: fault detail - * - * Invoked when a fault occurs on an mmap of a GEM managed area. GEM - * does most of the work for us including the actual map/unmap calls - * but we need to do the actual page work. - * - * This code eventually needs to handle faulting objects in and out - * of the GTT and repacking it when we run out of space. We can put - * that off for now and for our simple uses - * - * The VMA was set up by GEM. In doing so it also ensured that the - * vma->vm_private_data points to the GEM object that is backing this - * mapping. - */ -int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_gem_object *obj; - struct gtt_range *r; - int ret; - unsigned long pfn; - pgoff_t page_offset; - struct drm_device *dev; - struct drm_psb_private *dev_priv; - - obj = vma->vm_private_data; /* GEM object */ - dev = obj->dev; - dev_priv = dev->dev_private; - - r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */ - - /* Make sure we don't parallel update on a fault, nor move or remove - something from beneath our feet */ - mutex_lock(&dev->struct_mutex); - - /* For now the mmap pins the object and it stays pinned. As things - stand that will do us no harm */ - if (r->mmapping == 0) { - ret = psb_gtt_pin(r); - if (ret < 0) { - dev_err(dev->dev, "gma500: pin failed: %d\n", ret); - goto fail; - } - r->mmapping = 1; - } - - /* Page relative to the VMA start - we must calculate this ourselves - because vmf->pgoff is the fake GEM offset */ - page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start) - >> PAGE_SHIFT; - - /* CPU view of the page, don't go via the GART for CPU writes */ - if (r->stolen) - pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT; - else - pfn = page_to_pfn(r->pages[page_offset]); - ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); - -fail: - mutex_unlock(&dev->struct_mutex); - switch (ret) { - case 0: - case -ERESTARTSYS: - case -EINTR: - return VM_FAULT_NOPAGE; - case -ENOMEM: - return VM_FAULT_OOM; - default: - return VM_FAULT_SIGBUS; - } -} - -static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev, - int size, u32 *handle) -{ - struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1); - if (gtt == NULL) - return -ENOMEM; - if (drm_gem_private_object_init(dev, >t->gem, size) != 0) - goto free_gtt; - if (drm_gem_handle_create(file, >t->gem, handle) == 0) - return 0; -free_gtt: - psb_gtt_free_range(dev, gtt); - return -ENOMEM; -} - -/* - * GEM interfaces for our specific client - */ -int psb_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_psb_gem_create *args = data; - int ret; - if (args->flags & GMA_GEM_CREATE_STOLEN) { - ret = psb_gem_create_stolen(file, dev, args->size, - &args->handle); - if (ret == 0) - return 0; - /* Fall throguh */ - args->flags &= ~GMA_GEM_CREATE_STOLEN; - } - return psb_gem_create(file, dev, args->size, &args->handle); -} - -int psb_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_psb_gem_mmap *args = data; - return dev->driver->dumb_map_offset(file, dev, - args->handle, &args->offset); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.c deleted file mode 100644 index 3c17634f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.c +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include -#include -#include "gem_glue.h" - -void drm_gem_object_release_wrap(struct drm_gem_object *obj) -{ - /* Remove the list map if one is present */ - if (obj->map_list.map) { - struct drm_gem_mm *mm = obj->dev->mm_private; - struct drm_map_list *list = &obj->map_list; - drm_ht_remove_item(&mm->offset_hash, &list->hash); - drm_mm_put_block(list->file_offset_node); - kfree(list->map); - list->map = NULL; - } - drm_gem_object_release(obj); -} - -/** - * gem_create_mmap_offset - invent an mmap offset - * @obj: our object - * - * Standard implementation of offset generation for mmap as is - * duplicated in several drivers. This belongs in GEM. - */ -int gem_create_mmap_offset(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; - struct drm_local_map *map; - int ret; - - list = &obj->map_list; - list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); - if (list->map == NULL) - return -ENOMEM; - map = list->map; - map->type = _DRM_GEM; - map->size = obj->size; - map->handle = obj; - - list->file_offset_node = drm_mm_search_free(&mm->offset_manager, - obj->size / PAGE_SIZE, 0, 0); - if (!list->file_offset_node) { - dev_err(dev->dev, "failed to allocate offset for bo %d\n", - obj->name); - ret = -ENOSPC; - goto free_it; - } - list->file_offset_node = drm_mm_get_block(list->file_offset_node, - obj->size / PAGE_SIZE, 0); - if (!list->file_offset_node) { - ret = -ENOMEM; - goto free_it; - } - list->hash.key = list->file_offset_node->start; - ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); - if (ret) { - dev_err(dev->dev, "failed to add to map hash\n"); - goto free_mm; - } - return 0; - -free_mm: - drm_mm_put_block(list->file_offset_node); -free_it: - kfree(list->map); - list->map = NULL; - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.h deleted file mode 100644 index ce5ce30f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gem_glue.h +++ /dev/null @@ -1,2 +0,0 @@ -extern void drm_gem_object_release_wrap(struct drm_gem_object *obj); -extern int gem_create_mmap_offset(struct drm_gem_object *obj); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.c deleted file mode 100644 index c6465b40..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Thomas Hellstrom - * Alan Cox - */ - -#include -#include -#include "psb_drv.h" - - -/* - * GTT resource allocator - manage page mappings in GTT space - */ - -/** - * psb_gtt_mask_pte - generate GTT pte entry - * @pfn: page number to encode - * @type: type of memory in the GTT - * - * Set the GTT entry for the appropriate memory type. - */ -static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) -{ - uint32_t mask = PSB_PTE_VALID; - - if (type & PSB_MMU_CACHED_MEMORY) - mask |= PSB_PTE_CACHED; - if (type & PSB_MMU_RO_MEMORY) - mask |= PSB_PTE_RO; - if (type & PSB_MMU_WO_MEMORY) - mask |= PSB_PTE_WO; - - return (pfn << PAGE_SHIFT) | mask; -} - -/** - * psb_gtt_entry - find the GTT entries for a gtt_range - * @dev: our DRM device - * @r: our GTT range - * - * Given a gtt_range object return the GTT offset of the page table - * entries for this gtt_range - */ -static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long offset; - - offset = r->resource.start - dev_priv->gtt_mem->start; - - return dev_priv->gtt_map + (offset >> PAGE_SHIFT); -} - -/** - * psb_gtt_insert - put an object into the GTT - * @dev: our DRM device - * @r: our GTT range - * - * Take our preallocated GTT range and insert the GEM object into - * the GTT. This is protected via the gtt mutex which the caller - * must hold. - */ -static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) -{ - u32 *gtt_slot, pte; - struct page **pages; - int i; - - if (r->pages == NULL) { - WARN_ON(1); - return -EINVAL; - } - - WARN_ON(r->stolen); /* refcount these maybe ? */ - - gtt_slot = psb_gtt_entry(dev, r); - pages = r->pages; - - /* Make sure changes are visible to the GPU */ - set_pages_array_uc(pages, r->npage); - - /* Write our page entries into the GTT itself */ - for (i = r->roll; i < r->npage; i++) { - pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); - iowrite32(pte, gtt_slot++); - } - for (i = 0; i < r->roll; i++) { - pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); - iowrite32(pte, gtt_slot++); - } - /* Make sure all the entries are set before we return */ - ioread32(gtt_slot - 1); - - return 0; -} - -/** - * psb_gtt_remove - remove an object from the GTT - * @dev: our DRM device - * @r: our GTT range - * - * Remove a preallocated GTT range from the GTT. Overwrite all the - * page table entries with the dummy page. This is protected via the gtt - * mutex which the caller must hold. - */ -static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 *gtt_slot, pte; - int i; - - WARN_ON(r->stolen); - - gtt_slot = psb_gtt_entry(dev, r); - pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0); - - for (i = 0; i < r->npage; i++) - iowrite32(pte, gtt_slot++); - ioread32(gtt_slot - 1); - set_pages_array_wb(r->pages, r->npage); -} - -/** - * psb_gtt_roll - set scrolling position - * @dev: our DRM device - * @r: the gtt mapping we are using - * @roll: roll offset - * - * Roll an existing pinned mapping by moving the pages through the GTT. - * This allows us to implement hardware scrolling on the consoles without - * a 2D engine - */ -void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) -{ - u32 *gtt_slot, pte; - int i; - - if (roll >= r->npage) { - WARN_ON(1); - return; - } - - r->roll = roll; - - /* Not currently in the GTT - no worry we will write the mapping at - the right position when it gets pinned */ - if (!r->stolen && !r->in_gart) - return; - - gtt_slot = psb_gtt_entry(dev, r); - - for (i = r->roll; i < r->npage; i++) { - pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); - iowrite32(pte, gtt_slot++); - } - for (i = 0; i < r->roll; i++) { - pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); - iowrite32(pte, gtt_slot++); - } - ioread32(gtt_slot - 1); -} - -/** - * psb_gtt_attach_pages - attach and pin GEM pages - * @gt: the gtt range - * - * Pin and build an in kernel list of the pages that back our GEM object. - * While we hold this the pages cannot be swapped out. This is protected - * via the gtt mutex which the caller must hold. - */ -static int psb_gtt_attach_pages(struct gtt_range *gt) -{ - struct inode *inode; - struct address_space *mapping; - int i; - struct page *p; - int pages = gt->gem.size / PAGE_SIZE; - - WARN_ON(gt->pages); - - /* This is the shared memory object that backs the GEM resource */ - inode = gt->gem.filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - - gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL); - if (gt->pages == NULL) - return -ENOMEM; - gt->npage = pages; - - for (i = 0; i < pages; i++) { - p = shmem_read_mapping_page(mapping, i); - if (IS_ERR(p)) - goto err; - gt->pages[i] = p; - } - return 0; - -err: - while (i--) - page_cache_release(gt->pages[i]); - kfree(gt->pages); - gt->pages = NULL; - return PTR_ERR(p); -} - -/** - * psb_gtt_detach_pages - attach and pin GEM pages - * @gt: the gtt range - * - * Undo the effect of psb_gtt_attach_pages. At this point the pages - * must have been removed from the GTT as they could now be paged out - * and move bus address. This is protected via the gtt mutex which the - * caller must hold. - */ -static void psb_gtt_detach_pages(struct gtt_range *gt) -{ - int i; - for (i = 0; i < gt->npage; i++) { - /* FIXME: do we need to force dirty */ - set_page_dirty(gt->pages[i]); - page_cache_release(gt->pages[i]); - } - kfree(gt->pages); - gt->pages = NULL; -} - -/** - * psb_gtt_pin - pin pages into the GTT - * @gt: range to pin - * - * Pin a set of pages into the GTT. The pins are refcounted so that - * multiple pins need multiple unpins to undo. - * - * Non GEM backed objects treat this as a no-op as they are always GTT - * backed objects. - */ -int psb_gtt_pin(struct gtt_range *gt) -{ - int ret = 0; - struct drm_device *dev = gt->gem.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->gtt_mutex); - - if (gt->in_gart == 0 && gt->stolen == 0) { - ret = psb_gtt_attach_pages(gt); - if (ret < 0) - goto out; - ret = psb_gtt_insert(dev, gt); - if (ret < 0) { - psb_gtt_detach_pages(gt); - goto out; - } - } - gt->in_gart++; -out: - mutex_unlock(&dev_priv->gtt_mutex); - return ret; -} - -/** - * psb_gtt_unpin - Drop a GTT pin requirement - * @gt: range to pin - * - * Undoes the effect of psb_gtt_pin. On the last drop the GEM object - * will be removed from the GTT which will also drop the page references - * and allow the VM to clean up or page stuff. - * - * Non GEM backed objects treat this as a no-op as they are always GTT - * backed objects. - */ -void psb_gtt_unpin(struct gtt_range *gt) -{ - struct drm_device *dev = gt->gem.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - mutex_lock(&dev_priv->gtt_mutex); - - WARN_ON(!gt->in_gart); - - gt->in_gart--; - if (gt->in_gart == 0 && gt->stolen == 0) { - psb_gtt_remove(dev, gt); - psb_gtt_detach_pages(gt); - } - mutex_unlock(&dev_priv->gtt_mutex); -} - -/* - * GTT resource allocator - allocate and manage GTT address space - */ - -/** - * psb_gtt_alloc_range - allocate GTT address space - * @dev: Our DRM device - * @len: length (bytes) of address space required - * @name: resource name - * @backed: resource should be backed by stolen pages - * - * Ask the kernel core to find us a suitable range of addresses - * to use for a GTT mapping. - * - * Returns a gtt_range structure describing the object, or NULL on - * error. On successful return the resource is both allocated and marked - * as in use. - */ -struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, - const char *name, int backed) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct gtt_range *gt; - struct resource *r = dev_priv->gtt_mem; - int ret; - unsigned long start, end; - - if (backed) { - /* The start of the GTT is the stolen pages */ - start = r->start; - end = r->start + dev_priv->gtt.stolen_size - 1; - } else { - /* The rest we will use for GEM backed objects */ - start = r->start + dev_priv->gtt.stolen_size; - end = r->end; - } - - gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); - if (gt == NULL) - return NULL; - gt->resource.name = name; - gt->stolen = backed; - gt->in_gart = backed; - gt->roll = 0; - /* Ensure this is set for non GEM objects */ - gt->gem.dev = dev; - ret = allocate_resource(dev_priv->gtt_mem, >->resource, - len, start, end, PAGE_SIZE, NULL, NULL); - if (ret == 0) { - gt->offset = gt->resource.start - r->start; - return gt; - } - kfree(gt); - return NULL; -} - -/** - * psb_gtt_free_range - release GTT address space - * @dev: our DRM device - * @gt: a mapping created with psb_gtt_alloc_range - * - * Release a resource that was allocated with psb_gtt_alloc_range. If the - * object has been pinned by mmap users we clean this up here currently. - */ -void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) -{ - /* Undo the mmap pin if we are destroying the object */ - if (gt->mmapping) { - psb_gtt_unpin(gt); - gt->mmapping = 0; - } - WARN_ON(gt->in_gart && !gt->stolen); - release_resource(>->resource); - kfree(gt); -} - -static void psb_gtt_alloc(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - init_rwsem(&dev_priv->gtt.sem); -} - -void psb_gtt_takedown(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - if (dev_priv->gtt_map) { - iounmap(dev_priv->gtt_map); - dev_priv->gtt_map = NULL; - } - if (dev_priv->gtt_initialized) { - pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl); - PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); - (void) PSB_RVDC32(PSB_PGETBL_CTL); - } - if (dev_priv->vram_addr) - iounmap(dev_priv->gtt_map); -} - -int psb_gtt_init(struct drm_device *dev, int resume) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned gtt_pages; - unsigned long stolen_size, vram_stolen_size; - unsigned i, num_pages; - unsigned pfn_base; - uint32_t vram_pages; - uint32_t dvmt_mode = 0; - struct psb_gtt *pg; - - int ret = 0; - uint32_t pte; - - mutex_init(&dev_priv->gtt_mutex); - - psb_gtt_alloc(dev); - pg = &dev_priv->gtt; - - /* Enable the GTT */ - pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl); - pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); - - dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL); - PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); - (void) PSB_RVDC32(PSB_PGETBL_CTL); - - /* The root resource we allocate address space from */ - dev_priv->gtt_initialized = 1; - - pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; - - /* - * The video mmu has a hw bug when accessing 0x0D0000000. - * Make gatt start at 0x0e000,0000. This doesn't actually - * matter for us but may do if the video acceleration ever - * gets opened up. - */ - pg->mmu_gatt_start = 0xE0000000; - - pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); - gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) - >> PAGE_SHIFT; - /* CDV doesn't report this. In which case the system has 64 gtt pages */ - if (pg->gtt_start == 0 || gtt_pages == 0) { - dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n"); - gtt_pages = 64; - pg->gtt_start = dev_priv->pge_ctl; - } - - pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); - pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) - >> PAGE_SHIFT; - dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE]; - - if (pg->gatt_pages == 0 || pg->gatt_start == 0) { - static struct resource fudge; /* Preferably peppermint */ - /* This can occur on CDV systems. Fudge it in this case. - We really don't care what imaginary space is being allocated - at this point */ - dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n"); - pg->gatt_start = 0x40000000; - pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; - /* This is a little confusing but in fact the GTT is providing - a view from the GPU into memory and not vice versa. As such - this is really allocating space that is not the same as the - CPU address space on CDV */ - fudge.start = 0x40000000; - fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1; - fudge.name = "fudge"; - fudge.flags = IORESOURCE_MEM; - dev_priv->gtt_mem = &fudge; - } - - pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base); - vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - - PAGE_SIZE; - - stolen_size = vram_stolen_size; - - printk(KERN_INFO "Stolen memory information\n"); - printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base); - printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", - vram_stolen_size/1024); - dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7; - printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n", - (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode); - - if (resume && (gtt_pages != pg->gtt_pages) && - (stolen_size != pg->stolen_size)) { - dev_err(dev->dev, "GTT resume error.\n"); - ret = -EINVAL; - goto out_err; - } - - pg->gtt_pages = gtt_pages; - pg->stolen_size = stolen_size; - dev_priv->vram_stolen_size = vram_stolen_size; - - /* - * Map the GTT and the stolen memory area - */ - dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, - gtt_pages << PAGE_SHIFT); - if (!dev_priv->gtt_map) { - dev_err(dev->dev, "Failure to map gtt.\n"); - ret = -ENOMEM; - goto out_err; - } - - dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); - if (!dev_priv->vram_addr) { - dev_err(dev->dev, "Failure to map stolen base.\n"); - ret = -ENOMEM; - goto out_err; - } - - /* - * Insert vram stolen pages into the GTT - */ - - pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; - vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; - printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", - num_pages, pfn_base << PAGE_SHIFT, 0); - for (i = 0; i < num_pages; ++i) { - pte = psb_gtt_mask_pte(pfn_base + i, 0); - iowrite32(pte, dev_priv->gtt_map + i); - } - - /* - * Init rest of GTT to the scratch page to avoid accidents or scribbles - */ - - pfn_base = page_to_pfn(dev_priv->scratch_page); - pte = psb_gtt_mask_pte(pfn_base, 0); - for (; i < gtt_pages; ++i) - iowrite32(pte, dev_priv->gtt_map + i); - - (void) ioread32(dev_priv->gtt_map + i - 1); - return 0; - -out_err: - psb_gtt_takedown(dev); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.h deleted file mode 100644 index aa174238..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/gtt.h +++ /dev/null @@ -1,64 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2008, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#ifndef _PSB_GTT_H_ -#define _PSB_GTT_H_ - -#include - -/* This wants cleaning up with respect to the psb_dev and un-needed stuff */ -struct psb_gtt { - uint32_t gatt_start; - uint32_t mmu_gatt_start; - uint32_t gtt_start; - uint32_t gtt_phys_start; - unsigned gtt_pages; - unsigned gatt_pages; - unsigned long stolen_size; - unsigned long vram_stolen_size; - struct rw_semaphore sem; -}; - -/* Exported functions */ -extern int psb_gtt_init(struct drm_device *dev, int resume); -extern void psb_gtt_takedown(struct drm_device *dev); - -/* Each gtt_range describes an allocation in the GTT area */ -struct gtt_range { - struct resource resource; /* Resource for our allocation */ - u32 offset; /* GTT offset of our object */ - struct drm_gem_object gem; /* GEM high level stuff */ - int in_gart; /* Currently in the GART (ref ct) */ - bool stolen; /* Backed from stolen RAM */ - bool mmapping; /* Is mmappable */ - struct page **pages; /* Backing pages if present */ - int npage; /* Number of backing pages */ - int roll; /* Roll applied to the GTT entries */ -}; - -extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, - const char *name, int backed); -extern void psb_gtt_kref_put(struct gtt_range *gt); -extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); -extern int psb_gtt_pin(struct gtt_range *gt); -extern void psb_gtt_unpin(struct gtt_range *gt); -extern void psb_gtt_roll(struct drm_device *dev, - struct gtt_range *gt, int roll); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.c deleted file mode 100644 index d4d0c5b8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2006 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - * - */ -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "intel_bios.h" - - -static void *find_section(struct bdb_header *bdb, int section_id) -{ - u8 *base = (u8 *)bdb; - int index = 0; - u16 total, current_size; - u8 current_id; - - /* skip to first section */ - index += bdb->header_size; - total = bdb->bdb_size; - - /* walk the sections looking for section_id */ - while (index < total) { - current_id = *(base + index); - index++; - current_size = *((u16 *)(base + index)); - index += 2; - if (current_id == section_id) - return base + index; - index += current_size; - } - - return NULL; -} - -static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, - struct lvds_dvo_timing *dvo_timing) -{ - panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) | - dvo_timing->hactive_lo; - panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + - ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo); - panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + - dvo_timing->hsync_pulse_width; - panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + - ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo); - - panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) | - dvo_timing->vactive_lo; - panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + - dvo_timing->vsync_off; - panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + - dvo_timing->vsync_pulse_width; - panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + - ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo); - panel_fixed_mode->clock = dvo_timing->clock * 10; - panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; - - /* Some VBTs have bogus h/vtotal values */ - if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) - panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; - if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) - panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; - - drm_mode_set_name(panel_fixed_mode); -} - -static void parse_backlight_data(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_lvds_backlight *vbt_lvds_bl = NULL; - struct bdb_lvds_backlight *lvds_bl; - u8 p_type = 0; - void *bl_start = NULL; - struct bdb_lvds_options *lvds_opts - = find_section(bdb, BDB_LVDS_OPTIONS); - - dev_priv->lvds_bl = NULL; - - if (lvds_opts) - p_type = lvds_opts->panel_type; - else - return; - - bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT); - vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type; - - lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL); - if (!lvds_bl) { - dev_err(dev_priv->dev->dev, "out of memory for backlight data\n"); - return; - } - memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl)); - dev_priv->lvds_bl = lvds_bl; -} - -/* Try to find integrated panel data */ -static void parse_lfp_panel_data(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_lvds_options *lvds_options; - struct bdb_lvds_lfp_data *lvds_lfp_data; - struct bdb_lvds_lfp_data_entry *entry; - struct lvds_dvo_timing *dvo_timing; - struct drm_display_mode *panel_fixed_mode; - - /* Defaults if we can't find VBT info */ - dev_priv->lvds_dither = 0; - dev_priv->lvds_vbt = 0; - - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); - if (!lvds_options) - return; - - dev_priv->lvds_dither = lvds_options->pixel_dither; - if (lvds_options->panel_type == 0xff) - return; - - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); - if (!lvds_lfp_data) - return; - - - entry = &lvds_lfp_data->data[lvds_options->panel_type]; - dvo_timing = &entry->dvo_timing; - - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), - GFP_KERNEL); - if (panel_fixed_mode == NULL) { - dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n"); - return; - } - - dev_priv->lvds_vbt = 1; - fill_detail_timing_data(panel_fixed_mode, dvo_timing); - - if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) { - dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; - drm_mode_debug_printmodeline(panel_fixed_mode); - } else { - dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n"); - dev_priv->lvds_vbt = 0; - kfree(panel_fixed_mode); - } - return; -} - -/* Try to find sdvo panel data */ -static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_sdvo_lvds_options *sdvo_lvds_options; - struct lvds_dvo_timing *dvo_timing; - struct drm_display_mode *panel_fixed_mode; - - dev_priv->sdvo_lvds_vbt_mode = NULL; - - sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS); - if (!sdvo_lvds_options) - return; - - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS); - if (!dvo_timing) - return; - - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); - - if (!panel_fixed_mode) - return; - - fill_detail_timing_data(panel_fixed_mode, - dvo_timing + sdvo_lvds_options->panel_type); - - dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode; - - return; -} - -static void parse_general_features(struct drm_psb_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_general_features *general; - - /* Set sensible defaults in case we can't find the general block */ - dev_priv->int_tv_support = 1; - dev_priv->int_crt_support = 1; - - general = find_section(bdb, BDB_GENERAL_FEATURES); - if (general) { - dev_priv->int_tv_support = general->int_tv_support; - dev_priv->int_crt_support = general->int_crt_support; - dev_priv->lvds_use_ssc = general->enable_ssc; - - if (dev_priv->lvds_use_ssc) { - dev_priv->lvds_ssc_freq - = general->ssc_freq ? 100 : 96; - } - } -} - -/** - * psb_intel_init_bios - initialize VBIOS settings & find VBT - * @dev: DRM device - * - * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers - * to appropriate values. - * - * VBT existence is a sanity check that is relied on by other i830_bios.c code. - * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may - * feed an updated VBT back through that, compared to what we'll fetch using - * this method of groping around in the BIOS data. - * - * Returns 0 on success, nonzero on failure. - */ -bool psb_intel_init_bios(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct pci_dev *pdev = dev->pdev; - struct vbt_header *vbt = NULL; - struct bdb_header *bdb; - u8 __iomem *bios; - size_t size; - int i; - - bios = pci_map_rom(pdev, &size); - if (!bios) - return -1; - - /* Scour memory looking for the VBT signature */ - for (i = 0; i + 4 < size; i++) { - if (!memcmp(bios + i, "$VBT", 4)) { - vbt = (struct vbt_header *)(bios + i); - break; - } - } - - if (!vbt) { - dev_err(dev->dev, "VBT signature missing\n"); - pci_unmap_rom(pdev, bios); - return -1; - } - - bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); - - /* Grab useful general definitions */ - parse_general_features(dev_priv, bdb); - parse_lfp_panel_data(dev_priv, bdb); - parse_sdvo_panel_data(dev_priv, bdb); - parse_backlight_data(dev_priv, bdb); - - pci_unmap_rom(pdev, bios); - - return 0; -} - -/** - * Destroy and free VBT data - */ -void psb_intel_destroy_bios(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_display_mode *sdvo_lvds_vbt_mode = - dev_priv->sdvo_lvds_vbt_mode; - struct drm_display_mode *lfp_lvds_vbt_mode = - dev_priv->lfp_lvds_vbt_mode; - struct bdb_lvds_backlight *lvds_bl = - dev_priv->lvds_bl; - - /*free sdvo panel mode*/ - if (sdvo_lvds_vbt_mode) { - dev_priv->sdvo_lvds_vbt_mode = NULL; - kfree(sdvo_lvds_vbt_mode); - } - - if (lfp_lvds_vbt_mode) { - dev_priv->lfp_lvds_vbt_mode = NULL; - kfree(lfp_lvds_vbt_mode); - } - - if (lvds_bl) { - dev_priv->lvds_bl = NULL; - kfree(lvds_bl); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.h deleted file mode 100644 index 70f1bf01..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_bios.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (c) 2006 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - * - */ - -#ifndef _I830_BIOS_H_ -#define _I830_BIOS_H_ - -#include - -struct vbt_header { - u8 signature[20]; /**< Always starts with 'VBT$' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 vbt_size; /**< in bytes */ - u8 vbt_checksum; - u8 reserved0; - u32 bdb_offset; /**< from beginning of VBT */ - u32 aim_offset[4]; /**< from beginning of VBT */ -} __attribute__((packed)); - - -struct bdb_header { - u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 bdb_size; /**< in bytes */ -}; - -/* strictly speaking, this is a "skip" block, but it has interesting info */ -struct vbios_data { - u8 type; /* 0 == desktop, 1 == mobile */ - u8 relstage; - u8 chipset; - u8 lvds_present:1; - u8 tv_present:1; - u8 rsvd2:6; /* finish byte */ - u8 rsvd3[4]; - u8 signon[155]; - u8 copyright[61]; - u16 code_segment; - u8 dos_boot_mode; - u8 bandwidth_percent; - u8 rsvd4; /* popup memory size */ - u8 resize_pci_bios; - u8 rsvd5; /* is crt already on ddc2 */ -} __attribute__((packed)); - -/* - * There are several types of BIOS data blocks (BDBs), each block has - * an ID and size in the first 3 bytes (ID in first, size in next 2). - * Known types are listed below. - */ -#define BDB_GENERAL_FEATURES 1 -#define BDB_GENERAL_DEFINITIONS 2 -#define BDB_OLD_TOGGLE_LIST 3 -#define BDB_MODE_SUPPORT_LIST 4 -#define BDB_GENERIC_MODE_TABLE 5 -#define BDB_EXT_MMIO_REGS 6 -#define BDB_SWF_IO 7 -#define BDB_SWF_MMIO 8 -#define BDB_DOT_CLOCK_TABLE 9 -#define BDB_MODE_REMOVAL_TABLE 10 -#define BDB_CHILD_DEVICE_TABLE 11 -#define BDB_DRIVER_FEATURES 12 -#define BDB_DRIVER_PERSISTENCE 13 -#define BDB_EXT_TABLE_PTRS 14 -#define BDB_DOT_CLOCK_OVERRIDE 15 -#define BDB_DISPLAY_SELECT 16 -/* 17 rsvd */ -#define BDB_DRIVER_ROTATION 18 -#define BDB_DISPLAY_REMOVE 19 -#define BDB_OEM_CUSTOM 20 -#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ -#define BDB_SDVO_LVDS_OPTIONS 22 -#define BDB_SDVO_PANEL_DTDS 23 -#define BDB_SDVO_LVDS_PNP_IDS 24 -#define BDB_SDVO_LVDS_POWER_SEQ 25 -#define BDB_TV_OPTIONS 26 -#define BDB_LVDS_OPTIONS 40 -#define BDB_LVDS_LFP_DATA_PTRS 41 -#define BDB_LVDS_LFP_DATA 42 -#define BDB_LVDS_BACKLIGHT 43 -#define BDB_LVDS_POWER 44 -#define BDB_SKIP 254 /* VBIOS private block, ignore */ - -struct bdb_general_features { - /* bits 1 */ - u8 panel_fitting:2; - u8 flexaim:1; - u8 msg_enable:1; - u8 clear_screen:3; - u8 color_flip:1; - - /* bits 2 */ - u8 download_ext_vbt:1; - u8 enable_ssc:1; - u8 ssc_freq:1; - u8 enable_lfp_on_override:1; - u8 disable_ssc_ddt:1; - u8 rsvd8:3; /* finish byte */ - - /* bits 3 */ - u8 disable_smooth_vision:1; - u8 single_dvi:1; - u8 rsvd9:6; /* finish byte */ - - /* bits 4 */ - u8 legacy_monitor_detect; - - /* bits 5 */ - u8 int_crt_support:1; - u8 int_tv_support:1; - u8 rsvd11:6; /* finish byte */ -} __attribute__((packed)); - -struct bdb_general_definitions { - /* DDC GPIO */ - u8 crt_ddc_gmbus_pin; - - /* DPMS bits */ - u8 dpms_acpi:1; - u8 skip_boot_crt_detect:1; - u8 dpms_aim:1; - u8 rsvd1:5; /* finish byte */ - - /* boot device bits */ - u8 boot_display[2]; - u8 child_dev_size; - - /* device info */ - u8 tv_or_lvds_info[33]; - u8 dev1[33]; - u8 dev2[33]; - u8 dev3[33]; - u8 dev4[33]; - /* may be another device block here on some platforms */ -}; - -struct bdb_lvds_options { - u8 panel_type; - u8 rsvd1; - /* LVDS capabilities, stored in a dword */ - u8 pfit_mode:2; - u8 pfit_text_mode_enhanced:1; - u8 pfit_gfx_mode_enhanced:1; - u8 pfit_ratio_auto:1; - u8 pixel_dither:1; - u8 lvds_edid:1; - u8 rsvd2:1; - u8 rsvd4; -} __attribute__((packed)); - -struct bdb_lvds_backlight { - u8 type:2; - u8 pol:1; - u8 gpio:3; - u8 gmbus:2; - u16 freq; - u8 minbrightness; - u8 i2caddr; - u8 brightnesscmd; - /*FIXME: more...*/ -} __attribute__((packed)); - -/* LFP pointer table contains entries to the struct below */ -struct bdb_lvds_lfp_data_ptr { - u16 fp_timing_offset; /* offsets are from start of bdb */ - u8 fp_table_size; - u16 dvo_timing_offset; - u8 dvo_table_size; - u16 panel_pnp_id_offset; - u8 pnp_table_size; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data_ptrs { - u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ - struct bdb_lvds_lfp_data_ptr ptr[16]; -} __attribute__((packed)); - -/* LFP data has 3 blocks per entry */ -struct lvds_fp_timing { - u16 x_res; - u16 y_res; - u32 lvds_reg; - u32 lvds_reg_val; - u32 pp_on_reg; - u32 pp_on_reg_val; - u32 pp_off_reg; - u32 pp_off_reg_val; - u32 pp_cycle_reg; - u32 pp_cycle_reg_val; - u32 pfit_reg; - u32 pfit_reg_val; - u16 terminator; -} __attribute__((packed)); - -struct lvds_dvo_timing { - u16 clock; /**< In 10khz */ - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_off_lo; - u8 hsync_pulse_width; - u8 vsync_pulse_width:4; - u8 vsync_off:4; - u8 rsvd0:6; - u8 hsync_off_hi:2; - u8 h_image; - u8 v_image; - u8 max_hv; - u8 h_border; - u8 v_border; - u8 rsvd1:3; - u8 digital:2; - u8 vsync_positive:1; - u8 hsync_positive:1; - u8 rsvd2:1; -} __attribute__((packed)); - -struct lvds_pnp_id { - u16 mfg_name; - u16 product_code; - u32 serial; - u8 mfg_week; - u8 mfg_year; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data_entry { - struct lvds_fp_timing fp_timing; - struct lvds_dvo_timing dvo_timing; - struct lvds_pnp_id pnp_id; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data { - struct bdb_lvds_lfp_data_entry data[16]; -} __attribute__((packed)); - -struct aimdb_header { - char signature[16]; - char oem_device[20]; - u16 aimdb_version; - u16 aimdb_header_size; - u16 aimdb_size; -} __attribute__((packed)); - -struct aimdb_block { - u8 aimdb_id; - u16 aimdb_size; -} __attribute__((packed)); - -struct vch_panel_data { - u16 fp_timing_offset; - u8 fp_timing_size; - u16 dvo_timing_offset; - u8 dvo_timing_size; - u16 text_fitting_offset; - u8 text_fitting_size; - u16 graphics_fitting_offset; - u8 graphics_fitting_size; -} __attribute__((packed)); - -struct vch_bdb_22 { - struct aimdb_block aimdb_block; - struct vch_panel_data panels[16]; -} __attribute__((packed)); - -struct bdb_sdvo_lvds_options { - u8 panel_backlight; - u8 h40_set_panel_type; - u8 panel_type; - u8 ssc_clk_freq; - u16 als_low_trip; - u16 als_high_trip; - u8 sclalarcoeff_tab_row_num; - u8 sclalarcoeff_tab_row_size; - u8 coefficient[8]; - u8 panel_misc_bits_1; - u8 panel_misc_bits_2; - u8 panel_misc_bits_3; - u8 panel_misc_bits_4; -} __attribute__((packed)); - - -extern bool psb_intel_init_bios(struct drm_device *dev); -extern void psb_intel_destroy_bios(struct drm_device *dev); - -/* - * Driver<->VBIOS interaction occurs through scratch bits in - * GR18 & SWF*. - */ - -/* GR18 bits are set on display switch and hotkey events */ -#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */ -#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */ -#define GR18_HK_NONE (0x0<<3) -#define GR18_HK_LFP_STRETCH (0x1<<3) -#define GR18_HK_TOGGLE_DISP (0x2<<3) -#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */ -#define GR18_HK_POPUP_DISABLED (0x6<<3) -#define GR18_HK_POPUP_ENABLED (0x7<<3) -#define GR18_HK_PFIT (0x8<<3) -#define GR18_HK_APM_CHANGE (0xa<<3) -#define GR18_HK_MULTIPLE (0xc<<3) -#define GR18_USER_INT_EN (1<<2) -#define GR18_A0000_FLUSH_EN (1<<1) -#define GR18_SMM_EN (1<<0) - -/* Set by driver, cleared by VBIOS */ -#define SWF00_YRES_SHIFT 16 -#define SWF00_XRES_SHIFT 0 -#define SWF00_RES_MASK 0xffff - -/* Set by VBIOS at boot time and driver at runtime */ -#define SWF01_TV2_FORMAT_SHIFT 8 -#define SWF01_TV1_FORMAT_SHIFT 0 -#define SWF01_TV_FORMAT_MASK 0xffff - -#define SWF10_VBIOS_BLC_I2C_EN (1<<29) -#define SWF10_GTT_OVERRIDE_EN (1<<28) -#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */ -#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24) -#define SWF10_OLD_TOGGLE 0x0 -#define SWF10_TOGGLE_LIST_1 0x1 -#define SWF10_TOGGLE_LIST_2 0x2 -#define SWF10_TOGGLE_LIST_3 0x3 -#define SWF10_TOGGLE_LIST_4 0x4 -#define SWF10_PANNING_EN (1<<23) -#define SWF10_DRIVER_LOADED (1<<22) -#define SWF10_EXTENDED_DESKTOP (1<<21) -#define SWF10_EXCLUSIVE_MODE (1<<20) -#define SWF10_OVERLAY_EN (1<<19) -#define SWF10_PLANEB_HOLDOFF (1<<18) -#define SWF10_PLANEA_HOLDOFF (1<<17) -#define SWF10_VGA_HOLDOFF (1<<16) -#define SWF10_ACTIVE_DISP_MASK 0xffff -#define SWF10_PIPEB_LFP2 (1<<15) -#define SWF10_PIPEB_EFP2 (1<<14) -#define SWF10_PIPEB_TV2 (1<<13) -#define SWF10_PIPEB_CRT2 (1<<12) -#define SWF10_PIPEB_LFP (1<<11) -#define SWF10_PIPEB_EFP (1<<10) -#define SWF10_PIPEB_TV (1<<9) -#define SWF10_PIPEB_CRT (1<<8) -#define SWF10_PIPEA_LFP2 (1<<7) -#define SWF10_PIPEA_EFP2 (1<<6) -#define SWF10_PIPEA_TV2 (1<<5) -#define SWF10_PIPEA_CRT2 (1<<4) -#define SWF10_PIPEA_LFP (1<<3) -#define SWF10_PIPEA_EFP (1<<2) -#define SWF10_PIPEA_TV (1<<1) -#define SWF10_PIPEA_CRT (1<<0) - -#define SWF11_MEMORY_SIZE_SHIFT 16 -#define SWF11_SV_TEST_EN (1<<15) -#define SWF11_IS_AGP (1<<14) -#define SWF11_DISPLAY_HOLDOFF (1<<13) -#define SWF11_DPMS_REDUCED (1<<12) -#define SWF11_IS_VBE_MODE (1<<11) -#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */ -#define SWF11_DPMS_MASK 0x07 -#define SWF11_DPMS_OFF (1<<2) -#define SWF11_DPMS_SUSPEND (1<<1) -#define SWF11_DPMS_STANDBY (1<<0) -#define SWF11_DPMS_ON 0 - -#define SWF14_GFX_PFIT_EN (1<<31) -#define SWF14_TEXT_PFIT_EN (1<<30) -#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ -#define SWF14_POPUP_EN (1<<28) -#define SWF14_DISPLAY_HOLDOFF (1<<27) -#define SWF14_DISP_DETECT_EN (1<<26) -#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */ -#define SWF14_DRIVER_STATUS (1<<24) -#define SWF14_OS_TYPE_WIN9X (1<<23) -#define SWF14_OS_TYPE_WINNT (1<<22) -/* 21:19 rsvd */ -#define SWF14_PM_TYPE_MASK 0x00070000 -#define SWF14_PM_ACPI_VIDEO (0x4 << 16) -#define SWF14_PM_ACPI (0x3 << 16) -#define SWF14_PM_APM_12 (0x2 << 16) -#define SWF14_PM_APM_11 (0x1 << 16) -#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */ - /* if GR18 indicates a display switch */ -#define SWF14_DS_PIPEB_LFP2_EN (1<<15) -#define SWF14_DS_PIPEB_EFP2_EN (1<<14) -#define SWF14_DS_PIPEB_TV2_EN (1<<13) -#define SWF14_DS_PIPEB_CRT2_EN (1<<12) -#define SWF14_DS_PIPEB_LFP_EN (1<<11) -#define SWF14_DS_PIPEB_EFP_EN (1<<10) -#define SWF14_DS_PIPEB_TV_EN (1<<9) -#define SWF14_DS_PIPEB_CRT_EN (1<<8) -#define SWF14_DS_PIPEA_LFP2_EN (1<<7) -#define SWF14_DS_PIPEA_EFP2_EN (1<<6) -#define SWF14_DS_PIPEA_TV2_EN (1<<5) -#define SWF14_DS_PIPEA_CRT2_EN (1<<4) -#define SWF14_DS_PIPEA_LFP_EN (1<<3) -#define SWF14_DS_PIPEA_EFP_EN (1<<2) -#define SWF14_DS_PIPEA_TV_EN (1<<1) -#define SWF14_DS_PIPEA_CRT_EN (1<<0) - /* if GR18 indicates a panel fitting request */ -#define SWF14_PFIT_EN (1<<0) /* 0 means disable */ - /* if GR18 indicates an APM change request */ -#define SWF14_APM_HIBERNATE 0x4 -#define SWF14_APM_SUSPEND 0x3 -#define SWF14_APM_STANDBY 0x1 -#define SWF14_APM_RESTORE 0x0 - -#endif /* _I830_BIOS_H_ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_gmbus.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_gmbus.c deleted file mode 100644 index 9db90527..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_gmbus.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (c) 2006 Dave Airlie - * Copyright © 2006-2008,2010 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Chris Wilson - */ -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "psb_intel_drv.h" -#include "gma_drm.h" -#include "psb_drv.h" -#include "psb_intel_reg.h" - -#define _wait_for(COND, MS, W) ({ \ - unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ - int ret__ = 0; \ - while (! (COND)) { \ - if (time_after(jiffies, timeout__)) { \ - ret__ = -ETIMEDOUT; \ - break; \ - } \ - if (W && !(in_atomic() || in_dbg_master())) msleep(W); \ - } \ - ret__; \ -}) - -#define wait_for(COND, MS) _wait_for(COND, MS, 1) -#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) - -/* Intel GPIO access functions */ - -#define I2C_RISEFALL_TIME 20 - -static inline struct intel_gmbus * -to_intel_gmbus(struct i2c_adapter *i2c) -{ - return container_of(i2c, struct intel_gmbus, adapter); -} - -struct intel_gpio { - struct i2c_adapter adapter; - struct i2c_algo_bit_data algo; - struct drm_psb_private *dev_priv; - u32 reg; -}; - -void -gma_intel_i2c_reset(struct drm_device *dev) -{ - REG_WRITE(GMBUS0, 0); -} - -static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable) -{ - /* When using bit bashing for I2C, this bit needs to be set to 1 */ - /* FIXME: We are never Pineview, right? - - u32 val; - - if (!IS_PINEVIEW(dev_priv->dev)) - return; - - val = REG_READ(DSPCLK_GATE_D); - if (enable) - val |= DPCUNIT_CLOCK_GATE_DISABLE; - else - val &= ~DPCUNIT_CLOCK_GATE_DISABLE; - REG_WRITE(DSPCLK_GATE_D, val); - - return; - */ -} - -static u32 get_reserved(struct intel_gpio *gpio) -{ - struct drm_psb_private *dev_priv = gpio->dev_priv; - struct drm_device *dev = dev_priv->dev; - u32 reserved = 0; - - /* On most chips, these bits must be preserved in software. */ - reserved = REG_READ(gpio->reg) & - (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - return reserved; -} - -static int get_clock(void *data) -{ - struct intel_gpio *gpio = data; - struct drm_psb_private *dev_priv = gpio->dev_priv; - struct drm_device *dev = dev_priv->dev; - u32 reserved = get_reserved(gpio); - REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); - REG_WRITE(gpio->reg, reserved); - return (REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; -} - -static int get_data(void *data) -{ - struct intel_gpio *gpio = data; - struct drm_psb_private *dev_priv = gpio->dev_priv; - struct drm_device *dev = dev_priv->dev; - u32 reserved = get_reserved(gpio); - REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); - REG_WRITE(gpio->reg, reserved); - return (REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; -} - -static void set_clock(void *data, int state_high) -{ - struct intel_gpio *gpio = data; - struct drm_psb_private *dev_priv = gpio->dev_priv; - struct drm_device *dev = dev_priv->dev; - u32 reserved = get_reserved(gpio); - u32 clock_bits; - - if (state_high) - clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; - else - clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | - GPIO_CLOCK_VAL_MASK; - - REG_WRITE(gpio->reg, reserved | clock_bits); - REG_READ(gpio->reg); /* Posting */ -} - -static void set_data(void *data, int state_high) -{ - struct intel_gpio *gpio = data; - struct drm_psb_private *dev_priv = gpio->dev_priv; - struct drm_device *dev = dev_priv->dev; - u32 reserved = get_reserved(gpio); - u32 data_bits; - - if (state_high) - data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; - else - data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | - GPIO_DATA_VAL_MASK; - - REG_WRITE(gpio->reg, reserved | data_bits); - REG_READ(gpio->reg); -} - -static struct i2c_adapter * -intel_gpio_create(struct drm_psb_private *dev_priv, u32 pin) -{ - static const int map_pin_to_reg[] = { - 0, - GPIOB, - GPIOA, - GPIOC, - GPIOD, - GPIOE, - 0, - GPIOF, - }; - struct intel_gpio *gpio; - - if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) - return NULL; - - gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL); - if (gpio == NULL) - return NULL; - - gpio->reg = map_pin_to_reg[pin]; - gpio->dev_priv = dev_priv; - - snprintf(gpio->adapter.name, sizeof(gpio->adapter.name), - "gma500 GPIO%c", "?BACDE?F"[pin]); - gpio->adapter.owner = THIS_MODULE; - gpio->adapter.algo_data = &gpio->algo; - gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; - gpio->algo.setsda = set_data; - gpio->algo.setscl = set_clock; - gpio->algo.getsda = get_data; - gpio->algo.getscl = get_clock; - gpio->algo.udelay = I2C_RISEFALL_TIME; - gpio->algo.timeout = usecs_to_jiffies(2200); - gpio->algo.data = gpio; - - if (i2c_bit_add_bus(&gpio->adapter)) - goto out_free; - - return &gpio->adapter; - -out_free: - kfree(gpio); - return NULL; -} - -static int -intel_i2c_quirk_xfer(struct drm_psb_private *dev_priv, - struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - struct intel_gpio *gpio = container_of(adapter, - struct intel_gpio, - adapter); - int ret; - - gma_intel_i2c_reset(dev_priv->dev); - - intel_i2c_quirk_set(dev_priv, true); - set_data(gpio, 1); - set_clock(gpio, 1); - udelay(I2C_RISEFALL_TIME); - - ret = adapter->algo->master_xfer(adapter, msgs, num); - - set_data(gpio, 1); - set_clock(gpio, 1); - intel_i2c_quirk_set(dev_priv, false); - - return ret; -} - -static int -gmbus_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - struct intel_gmbus *bus = container_of(adapter, - struct intel_gmbus, - adapter); - struct drm_psb_private *dev_priv = adapter->algo_data; - struct drm_device *dev = dev_priv->dev; - int i, reg_offset; - - if (bus->force_bit) - return intel_i2c_quirk_xfer(dev_priv, - bus->force_bit, msgs, num); - - reg_offset = 0; - - REG_WRITE(GMBUS0 + reg_offset, bus->reg0); - - for (i = 0; i < num; i++) { - u16 len = msgs[i].len; - u8 *buf = msgs[i].buf; - - if (msgs[i].flags & I2C_M_RD) { - REG_WRITE(GMBUS1 + reg_offset, - GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | - (len << GMBUS_BYTE_COUNT_SHIFT) | - (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | - GMBUS_SLAVE_READ | GMBUS_SW_RDY); - REG_READ(GMBUS2+reg_offset); - do { - u32 val, loop = 0; - - if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) - goto timeout; - if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - goto clear_err; - - val = REG_READ(GMBUS3 + reg_offset); - do { - *buf++ = val & 0xff; - val >>= 8; - } while (--len && ++loop < 4); - } while (len); - } else { - u32 val, loop; - - val = loop = 0; - do { - val |= *buf++ << (8 * loop); - } while (--len && ++loop < 4); - - REG_WRITE(GMBUS3 + reg_offset, val); - REG_WRITE(GMBUS1 + reg_offset, - (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | - (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | - (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | - GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); - REG_READ(GMBUS2+reg_offset); - - while (len) { - if (wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) - goto timeout; - if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - goto clear_err; - - val = loop = 0; - do { - val |= *buf++ << (8 * loop); - } while (--len && ++loop < 4); - - REG_WRITE(GMBUS3 + reg_offset, val); - REG_READ(GMBUS2+reg_offset); - } - } - - if (i + 1 < num && wait_for(REG_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) - goto timeout; - if (REG_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - goto clear_err; - } - - goto done; - -clear_err: - /* Toggle the Software Clear Interrupt bit. This has the effect - * of resetting the GMBUS controller and so clearing the - * BUS_ERROR raised by the slave's NAK. - */ - REG_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); - REG_WRITE(GMBUS1 + reg_offset, 0); - -done: - /* Mark the GMBUS interface as disabled. We will re-enable it at the - * start of the next xfer, till then let it sleep. - */ - REG_WRITE(GMBUS0 + reg_offset, 0); - return i; - -timeout: - DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", - bus->reg0 & 0xff, bus->adapter.name); - REG_WRITE(GMBUS0 + reg_offset, 0); - - /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ - bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); - if (!bus->force_bit) - return -ENOMEM; - - return intel_i2c_quirk_xfer(dev_priv, bus->force_bit, msgs, num); -} - -static u32 gmbus_func(struct i2c_adapter *adapter) -{ - struct intel_gmbus *bus = container_of(adapter, - struct intel_gmbus, - adapter); - - if (bus->force_bit) - bus->force_bit->algo->functionality(bus->force_bit); - - return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - /* I2C_FUNC_10BIT_ADDR | */ - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL); -} - -static const struct i2c_algorithm gmbus_algorithm = { - .master_xfer = gmbus_xfer, - .functionality = gmbus_func -}; - -/** - * intel_gmbus_setup - instantiate all Intel i2c GMBuses - * @dev: DRM device - */ -int gma_intel_setup_gmbus(struct drm_device *dev) -{ - static const char *names[GMBUS_NUM_PORTS] = { - "disabled", - "ssc", - "vga", - "panel", - "dpc", - "dpb", - "reserved", - "dpd", - }; - struct drm_psb_private *dev_priv = dev->dev_private; - int ret, i; - - dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus), - GFP_KERNEL); - if (dev_priv->gmbus == NULL) - return -ENOMEM; - - for (i = 0; i < GMBUS_NUM_PORTS; i++) { - struct intel_gmbus *bus = &dev_priv->gmbus[i]; - - bus->adapter.owner = THIS_MODULE; - bus->adapter.class = I2C_CLASS_DDC; - snprintf(bus->adapter.name, - sizeof(bus->adapter.name), - "gma500 gmbus %s", - names[i]); - - bus->adapter.dev.parent = &dev->pdev->dev; - bus->adapter.algo_data = dev_priv; - - bus->adapter.algo = &gmbus_algorithm; - ret = i2c_add_adapter(&bus->adapter); - if (ret) - goto err; - - /* By default use a conservative clock rate */ - bus->reg0 = i | GMBUS_RATE_100KHZ; - - /* XXX force bit banging until GMBUS is fully debugged */ - bus->force_bit = intel_gpio_create(dev_priv, i); - } - - gma_intel_i2c_reset(dev_priv->dev); - - return 0; - -err: - while (--i) { - struct intel_gmbus *bus = &dev_priv->gmbus[i]; - i2c_del_adapter(&bus->adapter); - } - kfree(dev_priv->gmbus); - dev_priv->gmbus = NULL; - return ret; -} - -void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) -{ - struct intel_gmbus *bus = to_intel_gmbus(adapter); - - /* speed: - * 0x0 = 100 KHz - * 0x1 = 50 KHz - * 0x2 = 400 KHz - * 0x3 = 1000 Khz - */ - bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | (speed << 8); -} - -void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) -{ - struct intel_gmbus *bus = to_intel_gmbus(adapter); - - if (force_bit) { - if (bus->force_bit == NULL) { - struct drm_psb_private *dev_priv = adapter->algo_data; - bus->force_bit = intel_gpio_create(dev_priv, - bus->reg0 & 0xff); - } - } else { - if (bus->force_bit) { - i2c_del_adapter(bus->force_bit); - kfree(bus->force_bit); - bus->force_bit = NULL; - } - } -} - -void gma_intel_teardown_gmbus(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int i; - - if (dev_priv->gmbus == NULL) - return; - - for (i = 0; i < GMBUS_NUM_PORTS; i++) { - struct intel_gmbus *bus = &dev_priv->gmbus[i]; - if (bus->force_bit) { - i2c_del_adapter(bus->force_bit); - kfree(bus->force_bit); - } - i2c_del_adapter(&bus->adapter); - } - - kfree(dev_priv->gmbus); - dev_priv->gmbus = NULL; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_i2c.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_i2c.c deleted file mode 100644 index 98a28c20..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_i2c.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - */ -#include -#include -#include - -#include "psb_drv.h" -#include "psb_intel_reg.h" - -/* - * Intel GPIO access functions - */ - -#define I2C_RISEFALL_TIME 20 - -static int get_clock(void *data) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 val; - - val = REG_READ(chan->reg); - return (val & GPIO_CLOCK_VAL_IN) != 0; -} - -static int get_data(void *data) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 val; - - val = REG_READ(chan->reg); - return (val & GPIO_DATA_VAL_IN) != 0; -} - -static void set_clock(void *data, int state_high) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 reserved = 0, clock_bits; - - /* On most chips, these bits must be preserved in software. */ - reserved = - REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - if (state_high) - clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; - else - clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | - GPIO_CLOCK_VAL_MASK; - REG_WRITE(chan->reg, reserved | clock_bits); - udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ -} - -static void set_data(void *data, int state_high) -{ - struct psb_intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - u32 reserved = 0, data_bits; - - /* On most chips, these bits must be preserved in software. */ - reserved = - REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - if (state_high) - data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; - else - data_bits = - GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | - GPIO_DATA_VAL_MASK; - - REG_WRITE(chan->reg, reserved | data_bits); - udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ -} - -/** - * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg - * @dev: DRM device - * @output: driver specific output device - * @reg: GPIO reg to use - * @name: name for this bus - * - * Creates and registers a new i2c bus with the Linux i2c layer, for use - * in output probing and control (e.g. DDC or SDVO control functions). - * - * Possible values for @reg include: - * %GPIOA - * %GPIOB - * %GPIOC - * %GPIOD - * %GPIOE - * %GPIOF - * %GPIOG - * %GPIOH - * see PRM for details on how these different busses are used. - */ -struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, - const u32 reg, const char *name) -{ - struct psb_intel_i2c_chan *chan; - - chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL); - if (!chan) - goto out_free; - - chan->drm_dev = dev; - chan->reg = reg; - snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); - chan->adapter.owner = THIS_MODULE; - chan->adapter.algo_data = &chan->algo; - chan->adapter.dev.parent = &dev->pdev->dev; - chan->algo.setsda = set_data; - chan->algo.setscl = set_clock; - chan->algo.getsda = get_data; - chan->algo.getscl = get_clock; - chan->algo.udelay = 20; - chan->algo.timeout = usecs_to_jiffies(2200); - chan->algo.data = chan; - - i2c_set_adapdata(&chan->adapter, chan); - - if (i2c_bit_add_bus(&chan->adapter)) - goto out_free; - - /* JJJ: raise SCL and SDA? */ - set_data(chan, 1); - set_clock(chan, 1); - udelay(20); - - return chan; - -out_free: - kfree(chan); - return NULL; -} - -/** - * psb_intel_i2c_destroy - unregister and free i2c bus resources - * @output: channel to free - * - * Unregister the adapter from the i2c layer, then free the structure. - */ -void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan) -{ - if (!chan) - return; - - i2c_del_adapter(&chan->adapter); - kfree(chan); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_opregion.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_opregion.c deleted file mode 100644 index d946bc1b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/intel_opregion.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * FIXME: resolve with the i915 version - */ - -#include "psb_drv.h" - -struct opregion_header { - u8 signature[16]; - u32 size; - u32 opregion_ver; - u8 bios_ver[32]; - u8 vbios_ver[16]; - u8 driver_ver[16]; - u32 mboxes; - u8 reserved[164]; -} __packed; - -struct opregion_apci { - /*FIXME: add it later*/ -} __packed; - -struct opregion_swsci { - /*FIXME: add it later*/ -} __packed; - -struct opregion_acpi { - /*FIXME: add it later*/ -} __packed; - -int gma_intel_opregion_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 opregion_phy; - void *base; - u32 *lid_state; - - dev_priv->lid_state = NULL; - - pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy); - if (opregion_phy == 0) - return -ENOTSUPP; - - base = ioremap(opregion_phy, 8*1024); - if (!base) - return -ENOMEM; - - lid_state = base + 0x01ac; - - dev_priv->lid_state = lid_state; - dev_priv->lid_last_state = readl(lid_state); - return 0; -} - -int gma_intel_opregion_exit(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->lid_state) - iounmap(dev_priv->lid_state); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_device.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_device.c deleted file mode 100644 index af656787..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_device.c +++ /dev/null @@ -1,691 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include "psb_drv.h" -#include "mid_bios.h" -#include "mdfld_output.h" -#include "mdfld_dsi_output.h" -#include "tc35876x-dsi-lvds.h" - -#include - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - -#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 -#define BRIGHTNESS_MIN_LEVEL 1 -#define BRIGHTNESS_MAX_LEVEL 100 -#define BRIGHTNESS_MASK 0xFF -#define BLC_POLARITY_NORMAL 0 -#define BLC_POLARITY_INVERSE 1 -#define BLC_ADJUSTMENT_MAX 100 - -#define MDFLD_BLC_PWM_PRECISION_FACTOR 10 -#define MDFLD_BLC_MAX_PWM_REG_FREQ 0xFFFE -#define MDFLD_BLC_MIN_PWM_REG_FREQ 0x2 - -#define MDFLD_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) -#define MDFLD_BACKLIGHT_PWM_CTL_SHIFT (16) - -static struct backlight_device *mdfld_backlight_device; - -int mdfld_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = - (struct drm_device *)bl_get_data(mdfld_backlight_device); - struct drm_psb_private *dev_priv = dev->dev_private; - int level = bd->props.brightness; - - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - - /* Perform value bounds checking */ - if (level < BRIGHTNESS_MIN_LEVEL) - level = BRIGHTNESS_MIN_LEVEL; - - if (gma_power_begin(dev, false)) { - u32 adjusted_level = 0; - - /* - * Adjust the backlight level with the percent in - * dev_priv->blc_adj2 - */ - adjusted_level = level * dev_priv->blc_adj2; - adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX; - dev_priv->brightness_adjusted = adjusted_level; - - if (mdfld_get_panel_type(dev, 0) == TC35876X) { - if (dev_priv->dpi_panel_on[0] || - dev_priv->dpi_panel_on[2]) - tc35876x_brightness_control(dev, - dev_priv->brightness_adjusted); - } else { - if (dev_priv->dpi_panel_on[0]) - mdfld_dsi_brightness_control(dev, 0, - dev_priv->brightness_adjusted); - } - - if (dev_priv->dpi_panel_on[2]) - mdfld_dsi_brightness_control(dev, 2, - dev_priv->brightness_adjusted); - gma_power_end(dev); - } - - /* cache the brightness for later use */ - dev_priv->brightness = level; - return 0; -} - -static int mdfld_get_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = - (struct drm_device *)bl_get_data(mdfld_backlight_device); - struct drm_psb_private *dev_priv = dev->dev_private; - - DRM_DEBUG_DRIVER("brightness = 0x%x \n", dev_priv->brightness); - - /* return locally cached var instead of HW read (due to DPST etc.) */ - return dev_priv->brightness; -} - -static const struct backlight_ops mdfld_ops = { - .get_brightness = mdfld_get_brightness, - .update_status = mdfld_set_brightness, -}; - -static int device_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = (struct drm_psb_private *) - dev->dev_private; - - dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; - dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; - - return 0; -} - -static int mdfld_backlight_init(struct drm_device *dev) -{ - struct backlight_properties props; - int ret = 0; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = BRIGHTNESS_MAX_LEVEL; - props.type = BACKLIGHT_PLATFORM; - mdfld_backlight_device = backlight_device_register("mdfld-bl", - NULL, (void *)dev, &mdfld_ops, &props); - - if (IS_ERR(mdfld_backlight_device)) - return PTR_ERR(mdfld_backlight_device); - - ret = device_backlight_init(dev); - if (ret) - return ret; - - mdfld_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL; - mdfld_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL; - backlight_update_status(mdfld_backlight_device); - return 0; -} -#endif - -struct backlight_device *mdfld_get_backlight_device(void) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - return mdfld_backlight_device; -#else - return NULL; -#endif -} - -/* - * mdfld_save_display_registers - * - * Description: We are going to suspend so save current display - * register state. - * - * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio - */ -static int mdfld_save_display_registers(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct medfield_state *regs = &dev_priv->regs.mdfld; - int i; - - /* register */ - u32 dpll_reg = MRST_DPLL_A; - u32 fp_reg = MRST_FPA0; - u32 pipeconf_reg = PIPEACONF; - u32 htot_reg = HTOTAL_A; - u32 hblank_reg = HBLANK_A; - u32 hsync_reg = HSYNC_A; - u32 vtot_reg = VTOTAL_A; - u32 vblank_reg = VBLANK_A; - u32 vsync_reg = VSYNC_A; - u32 pipesrc_reg = PIPEASRC; - u32 dspstride_reg = DSPASTRIDE; - u32 dsplinoff_reg = DSPALINOFF; - u32 dsptileoff_reg = DSPATILEOFF; - u32 dspsize_reg = DSPASIZE; - u32 dsppos_reg = DSPAPOS; - u32 dspsurf_reg = DSPASURF; - u32 mipi_reg = MIPI; - u32 dspcntr_reg = DSPACNTR; - u32 dspstatus_reg = PIPEASTAT; - u32 palette_reg = PALETTE_A; - - /* pointer to values */ - u32 *dpll_val = ®s->saveDPLL_A; - u32 *fp_val = ®s->saveFPA0; - u32 *pipeconf_val = ®s->savePIPEACONF; - u32 *htot_val = ®s->saveHTOTAL_A; - u32 *hblank_val = ®s->saveHBLANK_A; - u32 *hsync_val = ®s->saveHSYNC_A; - u32 *vtot_val = ®s->saveVTOTAL_A; - u32 *vblank_val = ®s->saveVBLANK_A; - u32 *vsync_val = ®s->saveVSYNC_A; - u32 *pipesrc_val = ®s->savePIPEASRC; - u32 *dspstride_val = ®s->saveDSPASTRIDE; - u32 *dsplinoff_val = ®s->saveDSPALINOFF; - u32 *dsptileoff_val = ®s->saveDSPATILEOFF; - u32 *dspsize_val = ®s->saveDSPASIZE; - u32 *dsppos_val = ®s->saveDSPAPOS; - u32 *dspsurf_val = ®s->saveDSPASURF; - u32 *mipi_val = ®s->saveMIPI; - u32 *dspcntr_val = ®s->saveDSPACNTR; - u32 *dspstatus_val = ®s->saveDSPASTATUS; - u32 *palette_val = regs->save_palette_a; - - switch (pipe) { - case 0: - break; - case 1: - /* regester */ - dpll_reg = MDFLD_DPLL_B; - fp_reg = MDFLD_DPLL_DIV0; - pipeconf_reg = PIPEBCONF; - htot_reg = HTOTAL_B; - hblank_reg = HBLANK_B; - hsync_reg = HSYNC_B; - vtot_reg = VTOTAL_B; - vblank_reg = VBLANK_B; - vsync_reg = VSYNC_B; - pipesrc_reg = PIPEBSRC; - dspstride_reg = DSPBSTRIDE; - dsplinoff_reg = DSPBLINOFF; - dsptileoff_reg = DSPBTILEOFF; - dspsize_reg = DSPBSIZE; - dsppos_reg = DSPBPOS; - dspsurf_reg = DSPBSURF; - dspcntr_reg = DSPBCNTR; - dspstatus_reg = PIPEBSTAT; - palette_reg = PALETTE_B; - - /* values */ - dpll_val = ®s->saveDPLL_B; - fp_val = ®s->saveFPB0; - pipeconf_val = ®s->savePIPEBCONF; - htot_val = ®s->saveHTOTAL_B; - hblank_val = ®s->saveHBLANK_B; - hsync_val = ®s->saveHSYNC_B; - vtot_val = ®s->saveVTOTAL_B; - vblank_val = ®s->saveVBLANK_B; - vsync_val = ®s->saveVSYNC_B; - pipesrc_val = ®s->savePIPEBSRC; - dspstride_val = ®s->saveDSPBSTRIDE; - dsplinoff_val = ®s->saveDSPBLINOFF; - dsptileoff_val = ®s->saveDSPBTILEOFF; - dspsize_val = ®s->saveDSPBSIZE; - dsppos_val = ®s->saveDSPBPOS; - dspsurf_val = ®s->saveDSPBSURF; - dspcntr_val = ®s->saveDSPBCNTR; - dspstatus_val = ®s->saveDSPBSTATUS; - palette_val = regs->save_palette_b; - break; - case 2: - /* register */ - pipeconf_reg = PIPECCONF; - htot_reg = HTOTAL_C; - hblank_reg = HBLANK_C; - hsync_reg = HSYNC_C; - vtot_reg = VTOTAL_C; - vblank_reg = VBLANK_C; - vsync_reg = VSYNC_C; - pipesrc_reg = PIPECSRC; - dspstride_reg = DSPCSTRIDE; - dsplinoff_reg = DSPCLINOFF; - dsptileoff_reg = DSPCTILEOFF; - dspsize_reg = DSPCSIZE; - dsppos_reg = DSPCPOS; - dspsurf_reg = DSPCSURF; - mipi_reg = MIPI_C; - dspcntr_reg = DSPCCNTR; - dspstatus_reg = PIPECSTAT; - palette_reg = PALETTE_C; - - /* pointer to values */ - pipeconf_val = ®s->savePIPECCONF; - htot_val = ®s->saveHTOTAL_C; - hblank_val = ®s->saveHBLANK_C; - hsync_val = ®s->saveHSYNC_C; - vtot_val = ®s->saveVTOTAL_C; - vblank_val = ®s->saveVBLANK_C; - vsync_val = ®s->saveVSYNC_C; - pipesrc_val = ®s->savePIPECSRC; - dspstride_val = ®s->saveDSPCSTRIDE; - dsplinoff_val = ®s->saveDSPCLINOFF; - dsptileoff_val = ®s->saveDSPCTILEOFF; - dspsize_val = ®s->saveDSPCSIZE; - dsppos_val = ®s->saveDSPCPOS; - dspsurf_val = ®s->saveDSPCSURF; - mipi_val = ®s->saveMIPI_C; - dspcntr_val = ®s->saveDSPCCNTR; - dspstatus_val = ®s->saveDSPCSTATUS; - palette_val = regs->save_palette_c; - break; - default: - DRM_ERROR("%s, invalid pipe number.\n", __func__); - return -EINVAL; - } - - /* Pipe & plane A info */ - *dpll_val = PSB_RVDC32(dpll_reg); - *fp_val = PSB_RVDC32(fp_reg); - *pipeconf_val = PSB_RVDC32(pipeconf_reg); - *htot_val = PSB_RVDC32(htot_reg); - *hblank_val = PSB_RVDC32(hblank_reg); - *hsync_val = PSB_RVDC32(hsync_reg); - *vtot_val = PSB_RVDC32(vtot_reg); - *vblank_val = PSB_RVDC32(vblank_reg); - *vsync_val = PSB_RVDC32(vsync_reg); - *pipesrc_val = PSB_RVDC32(pipesrc_reg); - *dspstride_val = PSB_RVDC32(dspstride_reg); - *dsplinoff_val = PSB_RVDC32(dsplinoff_reg); - *dsptileoff_val = PSB_RVDC32(dsptileoff_reg); - *dspsize_val = PSB_RVDC32(dspsize_reg); - *dsppos_val = PSB_RVDC32(dsppos_reg); - *dspsurf_val = PSB_RVDC32(dspsurf_reg); - *dspcntr_val = PSB_RVDC32(dspcntr_reg); - *dspstatus_val = PSB_RVDC32(dspstatus_reg); - - /*save palette (gamma) */ - for (i = 0; i < 256; i++) - palette_val[i] = PSB_RVDC32(palette_reg + (i << 2)); - - if (pipe == 1) { - regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); - regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); - - regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); - regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); - return 0; - } - - *mipi_val = PSB_RVDC32(mipi_reg); - return 0; -} - -/* - * mdfld_restore_display_registers - * - * Description: We are going to resume so restore display register state. - * - * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio - */ -static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) -{ - /* To get panel out of ULPS mode. */ - u32 temp = 0; - u32 device_ready_reg = DEVICE_READY_REG; - struct drm_psb_private *dev_priv = dev->dev_private; - struct mdfld_dsi_config *dsi_config = NULL; - struct medfield_state *regs = &dev_priv->regs.mdfld; - u32 i = 0; - u32 dpll = 0; - u32 timeout = 0; - - /* regester */ - u32 dpll_reg = MRST_DPLL_A; - u32 fp_reg = MRST_FPA0; - u32 pipeconf_reg = PIPEACONF; - u32 htot_reg = HTOTAL_A; - u32 hblank_reg = HBLANK_A; - u32 hsync_reg = HSYNC_A; - u32 vtot_reg = VTOTAL_A; - u32 vblank_reg = VBLANK_A; - u32 vsync_reg = VSYNC_A; - u32 pipesrc_reg = PIPEASRC; - u32 dspstride_reg = DSPASTRIDE; - u32 dsplinoff_reg = DSPALINOFF; - u32 dsptileoff_reg = DSPATILEOFF; - u32 dspsize_reg = DSPASIZE; - u32 dsppos_reg = DSPAPOS; - u32 dspsurf_reg = DSPASURF; - u32 dspstatus_reg = PIPEASTAT; - u32 mipi_reg = MIPI; - u32 dspcntr_reg = DSPACNTR; - u32 palette_reg = PALETTE_A; - - /* values */ - u32 dpll_val = regs->saveDPLL_A & ~DPLL_VCO_ENABLE; - u32 fp_val = regs->saveFPA0; - u32 pipeconf_val = regs->savePIPEACONF; - u32 htot_val = regs->saveHTOTAL_A; - u32 hblank_val = regs->saveHBLANK_A; - u32 hsync_val = regs->saveHSYNC_A; - u32 vtot_val = regs->saveVTOTAL_A; - u32 vblank_val = regs->saveVBLANK_A; - u32 vsync_val = regs->saveVSYNC_A; - u32 pipesrc_val = regs->savePIPEASRC; - u32 dspstride_val = regs->saveDSPASTRIDE; - u32 dsplinoff_val = regs->saveDSPALINOFF; - u32 dsptileoff_val = regs->saveDSPATILEOFF; - u32 dspsize_val = regs->saveDSPASIZE; - u32 dsppos_val = regs->saveDSPAPOS; - u32 dspsurf_val = regs->saveDSPASURF; - u32 dspstatus_val = regs->saveDSPASTATUS; - u32 mipi_val = regs->saveMIPI; - u32 dspcntr_val = regs->saveDSPACNTR; - u32 *palette_val = regs->save_palette_a; - - switch (pipe) { - case 0: - dsi_config = dev_priv->dsi_configs[0]; - break; - case 1: - /* regester */ - dpll_reg = MDFLD_DPLL_B; - fp_reg = MDFLD_DPLL_DIV0; - pipeconf_reg = PIPEBCONF; - htot_reg = HTOTAL_B; - hblank_reg = HBLANK_B; - hsync_reg = HSYNC_B; - vtot_reg = VTOTAL_B; - vblank_reg = VBLANK_B; - vsync_reg = VSYNC_B; - pipesrc_reg = PIPEBSRC; - dspstride_reg = DSPBSTRIDE; - dsplinoff_reg = DSPBLINOFF; - dsptileoff_reg = DSPBTILEOFF; - dspsize_reg = DSPBSIZE; - dsppos_reg = DSPBPOS; - dspsurf_reg = DSPBSURF; - dspcntr_reg = DSPBCNTR; - dspstatus_reg = PIPEBSTAT; - palette_reg = PALETTE_B; - - /* values */ - dpll_val = regs->saveDPLL_B & ~DPLL_VCO_ENABLE; - fp_val = regs->saveFPB0; - pipeconf_val = regs->savePIPEBCONF; - htot_val = regs->saveHTOTAL_B; - hblank_val = regs->saveHBLANK_B; - hsync_val = regs->saveHSYNC_B; - vtot_val = regs->saveVTOTAL_B; - vblank_val = regs->saveVBLANK_B; - vsync_val = regs->saveVSYNC_B; - pipesrc_val = regs->savePIPEBSRC; - dspstride_val = regs->saveDSPBSTRIDE; - dsplinoff_val = regs->saveDSPBLINOFF; - dsptileoff_val = regs->saveDSPBTILEOFF; - dspsize_val = regs->saveDSPBSIZE; - dsppos_val = regs->saveDSPBPOS; - dspsurf_val = regs->saveDSPBSURF; - dspcntr_val = regs->saveDSPBCNTR; - dspstatus_val = regs->saveDSPBSTATUS; - palette_val = regs->save_palette_b; - break; - case 2: - /* regester */ - pipeconf_reg = PIPECCONF; - htot_reg = HTOTAL_C; - hblank_reg = HBLANK_C; - hsync_reg = HSYNC_C; - vtot_reg = VTOTAL_C; - vblank_reg = VBLANK_C; - vsync_reg = VSYNC_C; - pipesrc_reg = PIPECSRC; - dspstride_reg = DSPCSTRIDE; - dsplinoff_reg = DSPCLINOFF; - dsptileoff_reg = DSPCTILEOFF; - dspsize_reg = DSPCSIZE; - dsppos_reg = DSPCPOS; - dspsurf_reg = DSPCSURF; - mipi_reg = MIPI_C; - dspcntr_reg = DSPCCNTR; - dspstatus_reg = PIPECSTAT; - palette_reg = PALETTE_C; - - /* values */ - pipeconf_val = regs->savePIPECCONF; - htot_val = regs->saveHTOTAL_C; - hblank_val = regs->saveHBLANK_C; - hsync_val = regs->saveHSYNC_C; - vtot_val = regs->saveVTOTAL_C; - vblank_val = regs->saveVBLANK_C; - vsync_val = regs->saveVSYNC_C; - pipesrc_val = regs->savePIPECSRC; - dspstride_val = regs->saveDSPCSTRIDE; - dsplinoff_val = regs->saveDSPCLINOFF; - dsptileoff_val = regs->saveDSPCTILEOFF; - dspsize_val = regs->saveDSPCSIZE; - dsppos_val = regs->saveDSPCPOS; - dspsurf_val = regs->saveDSPCSURF; - mipi_val = regs->saveMIPI_C; - dspcntr_val = regs->saveDSPCCNTR; - dspstatus_val = regs->saveDSPCSTATUS; - palette_val = regs->save_palette_c; - - dsi_config = dev_priv->dsi_configs[1]; - break; - default: - DRM_ERROR("%s, invalid pipe number.\n", __func__); - return -EINVAL; - } - - /*make sure VGA plane is off. it initializes to on after reset!*/ - PSB_WVDC32(0x80000000, VGACNTRL); - - if (pipe == 1) { - PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg); - PSB_RVDC32(dpll_reg); - - PSB_WVDC32(fp_val, fp_reg); - } else { - - dpll = PSB_RVDC32(dpll_reg); - - if (!(dpll & DPLL_VCO_ENABLE)) { - - /* When ungating power of DPLL, needs to wait 0.5us - before enable the VCO */ - if (dpll & MDFLD_PWR_GATE_EN) { - dpll &= ~MDFLD_PWR_GATE_EN; - PSB_WVDC32(dpll, dpll_reg); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - } - - PSB_WVDC32(fp_val, fp_reg); - PSB_WVDC32(dpll_val, dpll_reg); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - - dpll_val |= DPLL_VCO_ENABLE; - PSB_WVDC32(dpll_val, dpll_reg); - PSB_RVDC32(dpll_reg); - - /* wait for DSI PLL to lock */ - while (timeout < 20000 && - !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { - udelay(150); - timeout++; - } - - if (timeout == 20000) { - DRM_ERROR("%s, can't lock DSIPLL.\n", - __func__); - return -EINVAL; - } - } - } - /* Restore mode */ - PSB_WVDC32(htot_val, htot_reg); - PSB_WVDC32(hblank_val, hblank_reg); - PSB_WVDC32(hsync_val, hsync_reg); - PSB_WVDC32(vtot_val, vtot_reg); - PSB_WVDC32(vblank_val, vblank_reg); - PSB_WVDC32(vsync_val, vsync_reg); - PSB_WVDC32(pipesrc_val, pipesrc_reg); - PSB_WVDC32(dspstatus_val, dspstatus_reg); - - /*set up the plane*/ - PSB_WVDC32(dspstride_val, dspstride_reg); - PSB_WVDC32(dsplinoff_val, dsplinoff_reg); - PSB_WVDC32(dsptileoff_val, dsptileoff_reg); - PSB_WVDC32(dspsize_val, dspsize_reg); - PSB_WVDC32(dsppos_val, dsppos_reg); - PSB_WVDC32(dspsurf_val, dspsurf_reg); - - if (pipe == 1) { - /* restore palette (gamma) */ - /*DRM_UDELAY(50000); */ - for (i = 0; i < 256; i++) - PSB_WVDC32(palette_val[i], palette_reg + (i << 2)); - - PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL); - PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); - - /*TODO: resume HDMI port */ - - /*TODO: resume pipe*/ - - /*enable the plane*/ - PSB_WVDC32(dspcntr_val & ~DISPLAY_PLANE_ENABLE, dspcntr_reg); - - return 0; - } - - /*set up pipe related registers*/ - PSB_WVDC32(mipi_val, mipi_reg); - - /*setup MIPI adapter + MIPI IP registers*/ - if (dsi_config) - mdfld_dsi_controller_init(dsi_config, pipe); - - if (in_atomic() || in_interrupt()) - mdelay(20); - else - msleep(20); - - /*enable the plane*/ - PSB_WVDC32(dspcntr_val, dspcntr_reg); - - if (in_atomic() || in_interrupt()) - mdelay(20); - else - msleep(20); - - /* LP Hold Release */ - temp = REG_READ(mipi_reg); - temp |= LP_OUTPUT_HOLD_RELEASE; - REG_WRITE(mipi_reg, temp); - mdelay(1); - - - /* Set DSI host to exit from Utra Low Power State */ - temp = REG_READ(device_ready_reg); - temp &= ~ULPS_MASK; - temp |= 0x3; - temp |= EXIT_ULPS_DEV_READY; - REG_WRITE(device_ready_reg, temp); - mdelay(1); - - temp = REG_READ(device_ready_reg); - temp &= ~ULPS_MASK; - temp |= EXITING_ULPS; - REG_WRITE(device_ready_reg, temp); - mdelay(1); - - /*enable the pipe*/ - PSB_WVDC32(pipeconf_val, pipeconf_reg); - - /* restore palette (gamma) */ - /*DRM_UDELAY(50000); */ - for (i = 0; i < 256; i++) - PSB_WVDC32(palette_val[i], palette_reg + (i << 2)); - - return 0; -} - -static int mdfld_save_registers(struct drm_device *dev) -{ - /* mdfld_save_cursor_overlay_registers(dev); */ - mdfld_save_display_registers(dev, 0); - mdfld_save_display_registers(dev, 2); - mdfld_disable_crtc(dev, 0); - mdfld_disable_crtc(dev, 2); - - return 0; -} - -static int mdfld_restore_registers(struct drm_device *dev) -{ - mdfld_restore_display_registers(dev, 2); - mdfld_restore_display_registers(dev, 0); - /* mdfld_restore_cursor_overlay_registers(dev); */ - - return 0; -} - -static int mdfld_power_down(struct drm_device *dev) -{ - /* FIXME */ - return 0; -} - -static int mdfld_power_up(struct drm_device *dev) -{ - /* FIXME */ - return 0; -} - -const struct psb_ops mdfld_chip_ops = { - .name = "mdfld", - .accel_2d = 0, - .pipes = 3, - .crtcs = 3, - .sgx_offset = MRST_SGX_OFFSET, - - .chip_setup = mid_chip_setup, - .crtc_helper = &mdfld_helper_funcs, - .crtc_funcs = &psb_intel_crtc_funcs, - - .output_init = mdfld_output_init, - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - .backlight_init = mdfld_backlight_init, -#endif - - .save_regs = mdfld_save_registers, - .restore_regs = mdfld_restore_registers, - .power_down = mdfld_power_down, - .power_up = mdfld_power_up, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c deleted file mode 100644 index d52358b7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#include "mdfld_dsi_dpi.h" -#include "mdfld_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "psb_drv.h" -#include "tc35876x-dsi-lvds.h" - -static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, - int pipe); - -static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe) -{ - u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && - (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) { - udelay(100); - timeout++; - } - - if (timeout == 20000) - DRM_INFO("MIPI: HS Data FIFO was never cleared!\n"); -} - -static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe) -{ - u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) - & DSI_FIFO_GEN_HS_CTRL_FULL)) { - udelay(100); - timeout++; - } - if (timeout == 20000) - DRM_INFO("MIPI: HS CMD FIFO was never cleared!\n"); -} - -static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe) -{ - u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & - DPI_FIFO_EMPTY) != DPI_FIFO_EMPTY)) { - udelay(100); - timeout++; - } - - if (timeout == 20000) - DRM_ERROR("MIPI: DPI FIFO was never cleared\n"); -} - -static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe) -{ - u32 intr_stat_reg = MIPI_INTR_STAT_REG(pipe); - int timeout = 0; - - udelay(500); - - /* This will time out after approximately 2+ seconds */ - while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) - & DSI_INTR_STATE_SPL_PKG_SENT))) { - udelay(100); - timeout++; - } - - if (timeout == 20000) - DRM_ERROR("MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n"); -} - -/* For TC35876X */ - -static void dsi_set_device_ready_state(struct drm_device *dev, int state, - int pipe) -{ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), !!state, 0, 0); -} - -static void dsi_set_pipe_plane_enable_state(struct drm_device *dev, - int state, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pipeconf_reg = PIPEACONF; - u32 dspcntr_reg = DSPACNTR; - - u32 dspcntr = dev_priv->dspcntr[pipe]; - u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; - - if (pipe) { - pipeconf_reg = PIPECCONF; - dspcntr_reg = DSPCCNTR; - } else - mipi &= (~0x03); - - if (state) { - /*Set up pipe */ - REG_WRITE(pipeconf_reg, BIT(31)); - - if (REG_BIT_WAIT(pipeconf_reg, 1, 30)) - dev_err(&dev->pdev->dev, "%s: Pipe enable timeout\n", - __func__); - - /*Set up display plane */ - REG_WRITE(dspcntr_reg, dspcntr); - } else { - u32 dspbase_reg = pipe ? MDFLD_DSPCBASE : MRST_DSPABASE; - - /* Put DSI lanes to ULPS to disable pipe */ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 2, 2, 1); - REG_READ(MIPI_DEVICE_READY_REG(pipe)); /* posted write? */ - - /* LP Hold */ - REG_FLD_MOD(MIPI_PORT_CONTROL(pipe), 0, 16, 16); - REG_READ(MIPI_PORT_CONTROL(pipe)); /* posted write? */ - - /* Disable display plane */ - REG_FLD_MOD(dspcntr_reg, 0, 31, 31); - - /* Flush the plane changes ??? posted write? */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - - /* Disable PIPE */ - REG_FLD_MOD(pipeconf_reg, 0, 31, 31); - - if (REG_BIT_WAIT(pipeconf_reg, 0, 30)) - dev_err(&dev->pdev->dev, "%s: Pipe disable timeout\n", - __func__); - - if (REG_BIT_WAIT(MIPI_GEN_FIFO_STAT_REG(pipe), 1, 28)) - dev_err(&dev->pdev->dev, "%s: FIFO not empty\n", - __func__); - } -} - -static void mdfld_dsi_configure_down(struct mdfld_dsi_encoder *dsi_encoder, - int pipe) -{ - struct mdfld_dsi_dpi_output *dpi_output = - MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_device *dev = dsi_config->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->dpi_panel_on[pipe]) { - dev_err(dev->dev, "DPI panel is already off\n"); - return; - } - tc35876x_toshiba_bridge_panel_off(dev); - tc35876x_set_bridge_reset_state(dev, 1); - dsi_set_pipe_plane_enable_state(dev, 0, pipe); - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - dsi_set_device_ready_state(dev, 0, pipe); -} - -static void mdfld_dsi_configure_up(struct mdfld_dsi_encoder *dsi_encoder, - int pipe) -{ - struct mdfld_dsi_dpi_output *dpi_output = - MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_device *dev = dsi_config->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (dev_priv->dpi_panel_on[pipe]) { - dev_err(dev->dev, "DPI panel is already on\n"); - return; - } - - /* For resume path sequence */ - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - dsi_set_device_ready_state(dev, 0, pipe); - - dsi_set_device_ready_state(dev, 1, pipe); - tc35876x_set_bridge_reset_state(dev, 0); - tc35876x_configure_lvds_bridge(dev); - mdfld_dsi_dpi_turn_on(dpi_output, pipe); /* Send turn on command */ - dsi_set_pipe_plane_enable_state(dev, 1, pipe); -} -/* End for TC35876X */ - -/* ************************************************************************* *\ - * FUNCTION: mdfld_dsi_tpo_ic_init - * - * DESCRIPTION: This function is called only by mrst_dsi_mode_set and - * restore_display_registers. since this function does not - * acquire the mutex, it is important that the calling function - * does! -\* ************************************************************************* */ -static void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe) -{ - struct drm_device *dev = dsi_config->dev; - u32 dcsChannelNumber = dsi_config->channel_num; - u32 gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe); - u32 gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe); - u32 gen_ctrl_val = GEN_LONG_WRITE; - - DRM_INFO("Enter mrst init TPO MIPI display.\n"); - - gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS; - - /* Flip page order */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00008036); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); - - /* 0xF0 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x005a5af0); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* Write protection key */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x005a5af1); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* 0xFC */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x005a5afc); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* 0xB7 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x770000b7); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000044); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS)); - - /* 0xB6 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000a0ab6); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); - - /* 0xF2 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x081010f2); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x4a070708); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000000c5); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); - - /* 0xF8 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x024003f8); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x01030a04); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x0e020220); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000004); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS)); - - /* 0xE2 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x398fc3e2); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x0000916f); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS)); - - /* 0xB0 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000000b0); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); - - /* 0xF4 */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x240242f4); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x78ee2002); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2a071050); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x507fee10); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x10300710); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS)); - - /* 0xBA */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x19fe07ba); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x101c0a31); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000010); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); - - /* 0xBB */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x28ff07bb); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x24280a31); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000034); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); - - /* 0xFB */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x535d05fb); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1b1a2130); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x221e180e); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x131d2120); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x535d0508); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1c1a2131); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x231f160d); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x111b2220); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x535c2008); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1f1d2433); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2c251a10); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2c34372d); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000023); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); - - /* 0xFA */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x525c0bfa); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1c1c232f); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x2623190e); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x18212625); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x545d0d0e); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1e1d2333); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x26231a10); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x1a222725); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x545d280f); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x21202635); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x31292013); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x31393d33); - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x00000029); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); - - /* Set DM */ - mdfld_wait_for_HS_DATA_FIFO(dev, pipe); - REG_WRITE(gen_data_reg, 0x000100f7); - mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); - REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); -} - -static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count, - int num_lane, int bpp) -{ - return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); -} - -/* - * Calculate the dpi time basing on a given drm mode @mode - * return 0 on success. - * FIXME: I was using proposed mode value for calculation, may need to - * use crtc mode values later - */ -int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, - struct mdfld_dsi_dpi_timing *dpi_timing, - int num_lane, int bpp) -{ - int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive; - int pclk_vsync, pclk_vfp, pclk_vbp; - - pclk_hactive = mode->hdisplay; - pclk_hfp = mode->hsync_start - mode->hdisplay; - pclk_hsync = mode->hsync_end - mode->hsync_start; - pclk_hbp = mode->htotal - mode->hsync_end; - - pclk_vfp = mode->vsync_start - mode->vdisplay; - pclk_vsync = mode->vsync_end - mode->vsync_start; - pclk_vbp = mode->vtotal - mode->vsync_end; - - /* - * byte clock counts were calculated by following formula - * bclock_count = pclk_count * bpp / num_lane / 8 - */ - dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_hsync, num_lane, bpp); - dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_hbp, num_lane, bpp); - dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_hfp, num_lane, bpp); - dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_hactive, num_lane, bpp); - dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_vsync, num_lane, bpp); - dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_vbp, num_lane, bpp); - dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count( - pclk_vfp, num_lane, bpp); - - return 0; -} - -void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, - int pipe) -{ - struct drm_device *dev = dsi_config->dev; - int lane_count = dsi_config->lane_count; - struct mdfld_dsi_dpi_timing dpi_timing; - struct drm_display_mode *mode = dsi_config->mode; - u32 val; - - /*un-ready device*/ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 0, 0, 0); - - /*init dsi adapter before kicking off*/ - REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018); - - /*enable all interrupts*/ - REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff); - - /*set up func_prg*/ - val = lane_count; - val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET; - - switch (dsi_config->bpp) { - case 16: - val |= DSI_DPI_COLOR_FORMAT_RGB565; - break; - case 18: - val |= DSI_DPI_COLOR_FORMAT_RGB666; - break; - case 24: - val |= DSI_DPI_COLOR_FORMAT_RGB888; - break; - default: - DRM_ERROR("unsupported color format, bpp = %d\n", - dsi_config->bpp); - } - REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), val); - - REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe), - (mode->vtotal * mode->htotal * dsi_config->bpp / - (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK); - REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe), - 0xffff & DSI_LP_RX_TIMEOUT_MASK); - - /*max value: 20 clock cycles of txclkesc*/ - REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe), - 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK); - - /*min 21 txclkesc, max: ffffh*/ - REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe), - 0xffff & DSI_RESET_TIMER_MASK); - - REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe), - mode->vdisplay << 16 | mode->hdisplay); - - /*set DPI timing registers*/ - mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, - dsi_config->lane_count, dsi_config->bpp); - - REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe), - dpi_timing.hsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HBP_COUNT_REG(pipe), - dpi_timing.hbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HFP_COUNT_REG(pipe), - dpi_timing.hfp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe), - dpi_timing.hactive_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe), - dpi_timing.vsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VBP_COUNT_REG(pipe), - dpi_timing.vbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VFP_COUNT_REG(pipe), - dpi_timing.vfp_count & DSI_DPI_TIMING_MASK); - - REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x46); - - /*min: 7d0 max: 4e20*/ - REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0x000007d0); - - /*set up video mode*/ - val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE; - REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), val); - - REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000); - - REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004); - - /*TODO: figure out how to setup these registers*/ - if (mdfld_get_panel_type(dev, pipe) == TC35876X) - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008); - else - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150c3408); - - REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14); - - if (mdfld_get_panel_type(dev, pipe) == TC35876X) - tc35876x_set_bridge_reset_state(dev, 0); /*Pull High Reset */ - - /*set device ready*/ - REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 1, 0, 0); -} - -void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe) -{ - struct drm_device *dev = output->dev; - - /* clear special packet sent bit */ - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) - REG_WRITE(MIPI_INTR_STAT_REG(pipe), - DSI_INTR_STATE_SPL_PKG_SENT); - - /*send turn on package*/ - REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_TURN_ON); - - /*wait for SPL_PKG_SENT interrupt*/ - mdfld_wait_for_SPL_PKG_SENT(dev, pipe); - - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) - REG_WRITE(MIPI_INTR_STAT_REG(pipe), - DSI_INTR_STATE_SPL_PKG_SENT); - - output->panel_on = 1; - - /* FIXME the following is disabled to WA the X slow start issue - for TMD panel - if (pipe == 2) - dev_priv->dpi_panel_on2 = true; - else if (pipe == 0) - dev_priv->dpi_panel_on = true; */ -} - -static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, - int pipe) -{ - struct drm_device *dev = output->dev; - - /*if output is on, or mode setting didn't happen, ignore this*/ - if ((!output->panel_on) || output->first_boot) { - output->first_boot = 0; - return; - } - - /* Wait for dpi fifo to empty */ - mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe); - - /* Clear the special packet interrupt bit if set */ - if (REG_READ(MIPI_INTR_STAT_REG(pipe)) & DSI_INTR_STATE_SPL_PKG_SENT) - REG_WRITE(MIPI_INTR_STAT_REG(pipe), - DSI_INTR_STATE_SPL_PKG_SENT); - - if (REG_READ(MIPI_DPI_CONTROL_REG(pipe)) == DSI_DPI_CTRL_HS_SHUTDOWN) - goto shutdown_out; - - REG_WRITE(MIPI_DPI_CONTROL_REG(pipe), DSI_DPI_CTRL_HS_SHUTDOWN); - -shutdown_out: - output->panel_on = 0; - output->first_boot = 0; - - /* FIXME the following is disabled to WA the X slow start issue - for TMD panel - if (pipe == 2) - dev_priv->dpi_panel_on2 = false; - else if (pipe == 0) - dev_priv->dpi_panel_on = false; */ -} - -static void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) -{ - struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); - struct mdfld_dsi_dpi_output *dpi_output = - MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_encoder_get_config(dsi_encoder); - int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); - struct drm_device *dev = dsi_config->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - /*start up display island if it was shutdown*/ - if (!gma_power_begin(dev, true)) - return; - - if (on) { - if (mdfld_get_panel_type(dev, pipe) == TMD_VID) - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - else if (mdfld_get_panel_type(dev, pipe) == TC35876X) - mdfld_dsi_configure_up(dsi_encoder, pipe); - else { - /*enable mipi port*/ - REG_WRITE(MIPI_PORT_CONTROL(pipe), - REG_READ(MIPI_PORT_CONTROL(pipe)) | BIT(31)); - REG_READ(MIPI_PORT_CONTROL(pipe)); - - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - mdfld_dsi_tpo_ic_init(dsi_config, pipe); - } - dev_priv->dpi_panel_on[pipe] = true; - } else { - if (mdfld_get_panel_type(dev, pipe) == TMD_VID) - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - else if (mdfld_get_panel_type(dev, pipe) == TC35876X) - mdfld_dsi_configure_down(dsi_encoder, pipe); - else { - mdfld_dsi_dpi_shut_down(dpi_output, pipe); - - /*disable mipi port*/ - REG_WRITE(MIPI_PORT_CONTROL(pipe), - REG_READ(MIPI_PORT_CONTROL(pipe)) & ~BIT(31)); - REG_READ(MIPI_PORT_CONTROL(pipe)); - } - dev_priv->dpi_panel_on[pipe] = false; - } - gma_power_end(dev); -} - -void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) -{ - mdfld_dsi_dpi_set_power(encoder, mode == DRM_MODE_DPMS_ON); -} - -bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_display_mode *fixed_mode = dsi_config->fixed_mode; - - if (fixed_mode) { - adjusted_mode->hdisplay = fixed_mode->hdisplay; - adjusted_mode->hsync_start = fixed_mode->hsync_start; - adjusted_mode->hsync_end = fixed_mode->hsync_end; - adjusted_mode->htotal = fixed_mode->htotal; - adjusted_mode->vdisplay = fixed_mode->vdisplay; - adjusted_mode->vsync_start = fixed_mode->vsync_start; - adjusted_mode->vsync_end = fixed_mode->vsync_end; - adjusted_mode->vtotal = fixed_mode->vtotal; - adjusted_mode->clock = fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - } - return true; -} - -void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) -{ - mdfld_dsi_dpi_set_power(encoder, false); -} - -void mdfld_dsi_dpi_commit(struct drm_encoder *encoder) -{ - mdfld_dsi_dpi_set_power(encoder, true); -} - -/* For TC35876X */ -/* This functionality was implemented in FW in iCDK */ -/* But removed in DV0 and later. So need to add here. */ -static void mipi_set_properties(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - - REG_WRITE(MIPI_CTRL_REG(pipe), 0x00000018); - REG_WRITE(MIPI_INTR_EN_REG(pipe), 0xffffffff); - REG_WRITE(MIPI_HS_TX_TIMEOUT_REG(pipe), 0xffffff); - REG_WRITE(MIPI_LP_RX_TIMEOUT_REG(pipe), 0xffffff); - REG_WRITE(MIPI_TURN_AROUND_TIMEOUT_REG(pipe), 0x14); - REG_WRITE(MIPI_DEVICE_RESET_TIMER_REG(pipe), 0xff); - REG_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe), 0x25); - REG_WRITE(MIPI_INIT_COUNT_REG(pipe), 0xf0); - REG_WRITE(MIPI_EOT_DISABLE_REG(pipe), 0x00000000); - REG_WRITE(MIPI_LP_BYTECLK_REG(pipe), 0x00000004); - REG_WRITE(MIPI_DBI_BW_CTRL_REG(pipe), 0x00000820); - REG_WRITE(MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe), (0xa << 16) | 0x14); -} - -static void mdfld_mipi_set_video_timing(struct mdfld_dsi_config *dsi_config, - int pipe) -{ - struct drm_device *dev = dsi_config->dev; - struct mdfld_dsi_dpi_timing dpi_timing; - struct drm_display_mode *mode = dsi_config->mode; - - mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, - dsi_config->lane_count, - dsi_config->bpp); - - REG_WRITE(MIPI_DPI_RESOLUTION_REG(pipe), - mode->vdisplay << 16 | mode->hdisplay); - REG_WRITE(MIPI_HSYNC_COUNT_REG(pipe), - dpi_timing.hsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HBP_COUNT_REG(pipe), - dpi_timing.hbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HFP_COUNT_REG(pipe), - dpi_timing.hfp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_HACTIVE_COUNT_REG(pipe), - dpi_timing.hactive_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VSYNC_COUNT_REG(pipe), - dpi_timing.vsync_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VBP_COUNT_REG(pipe), - dpi_timing.vbp_count & DSI_DPI_TIMING_MASK); - REG_WRITE(MIPI_VFP_COUNT_REG(pipe), - dpi_timing.vfp_count & DSI_DPI_TIMING_MASK); -} - -static void mdfld_mipi_config(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - int lane_count = dsi_config->lane_count; - - if (pipe) { - REG_WRITE(MIPI_PORT_CONTROL(0), 0x00000002); - REG_WRITE(MIPI_PORT_CONTROL(2), 0x80000000); - } else { - REG_WRITE(MIPI_PORT_CONTROL(0), 0x80010000); - REG_WRITE(MIPI_PORT_CONTROL(2), 0x00); - } - - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x150A600F); - REG_WRITE(MIPI_VIDEO_MODE_FORMAT_REG(pipe), 0x0000000F); - - /* lane_count = 3 */ - REG_WRITE(MIPI_DSI_FUNC_PRG_REG(pipe), 0x00000200 | lane_count); - - mdfld_mipi_set_video_timing(dsi_config, pipe); -} - -static void mdfld_set_pipe_timing(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct drm_device *dev = dsi_config->dev; - struct drm_display_mode *mode = dsi_config->mode; - - REG_WRITE(HTOTAL_A, ((mode->htotal - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(HBLANK_A, ((mode->htotal - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(HSYNC_A, - ((mode->hsync_end - 1) << 16) | (mode->hsync_start - 1)); - - REG_WRITE(VTOTAL_A, ((mode->vtotal - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(VBLANK_A, ((mode->vtotal - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(VSYNC_A, - ((mode->vsync_end - 1) << 16) | (mode->vsync_start - 1)); - - REG_WRITE(PIPEASRC, - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); -} -/* End for TC35876X */ - -void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); - struct mdfld_dsi_dpi_output *dpi_output = - MDFLD_DSI_DPI_OUTPUT(dsi_encoder); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_encoder_get_config(dsi_encoder); - struct drm_device *dev = dsi_config->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); - - u32 pipeconf_reg = PIPEACONF; - u32 dspcntr_reg = DSPACNTR; - - u32 pipeconf = dev_priv->pipeconf[pipe]; - u32 dspcntr = dev_priv->dspcntr[pipe]; - u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; - - if (pipe) { - pipeconf_reg = PIPECCONF; - dspcntr_reg = DSPCCNTR; - } else { - if (mdfld_get_panel_type(dev, pipe) == TC35876X) - mipi &= (~0x03); /* Use all four lanes */ - else - mipi |= 2; - } - - /*start up display island if it was shutdown*/ - if (!gma_power_begin(dev, true)) - return; - - if (mdfld_get_panel_type(dev, pipe) == TC35876X) { - /* - * The following logic is required to reset the bridge and - * configure. This also starts the DSI clock at 200MHz. - */ - tc35876x_set_bridge_reset_state(dev, 0); /*Pull High Reset */ - tc35876x_toshiba_bridge_panel_on(dev); - udelay(100); - /* Now start the DSI clock */ - REG_WRITE(MRST_DPLL_A, 0x00); - REG_WRITE(MRST_FPA0, 0xC1); - REG_WRITE(MRST_DPLL_A, 0x00800000); - udelay(500); - REG_WRITE(MRST_DPLL_A, 0x80800000); - - if (REG_BIT_WAIT(pipeconf_reg, 1, 29)) - dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n", - __func__); - - REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008); - - mipi_set_properties(dsi_config, pipe); - mdfld_mipi_config(dsi_config, pipe); - mdfld_set_pipe_timing(dsi_config, pipe); - - REG_WRITE(DSPABASE, 0x00); - REG_WRITE(DSPASTRIDE, (mode->hdisplay * 4)); - REG_WRITE(DSPASIZE, - ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - - REG_WRITE(DSPACNTR, 0x98000000); - REG_WRITE(DSPASURF, 0x00); - - REG_WRITE(VGACNTRL, 0x80000000); - REG_WRITE(DEVICE_READY_REG, 0x00000001); - - REG_WRITE(MIPI_PORT_CONTROL(pipe), 0x80810000); - } else { - /*set up mipi port FIXME: do at init time */ - REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi); - } - REG_READ(MIPI_PORT_CONTROL(pipe)); - - if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { - /* NOP */ - } else if (mdfld_get_panel_type(dev, pipe) == TC35876X) { - /* set up DSI controller DPI interface */ - mdfld_dsi_dpi_controller_init(dsi_config, pipe); - - /* Configure MIPI Bridge and Panel */ - tc35876x_configure_lvds_bridge(dev); - dev_priv->dpi_panel_on[pipe] = true; - } else { - /*turn on DPI interface*/ - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - } - - /*set up pipe*/ - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - - /*set up display plane*/ - REG_WRITE(dspcntr_reg, dspcntr); - REG_READ(dspcntr_reg); - - msleep(20); /* FIXME: this should wait for vblank */ - - if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { - /* NOP */ - } else if (mdfld_get_panel_type(dev, pipe) == TC35876X) { - mdfld_dsi_dpi_turn_on(dpi_output, pipe); - } else { - /* init driver ic */ - mdfld_dsi_tpo_ic_init(dsi_config, pipe); - /*init backlight*/ - mdfld_dsi_brightness_init(dsi_config, pipe); - } - - gma_power_end(dev); -} - -/* - * Init DSI DPI encoder. - * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector - * return pointer of newly allocated DPI encoder, NULL on error - */ -struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, - struct mdfld_dsi_connector *dsi_connector, - const struct panel_funcs *p_funcs) -{ - struct mdfld_dsi_dpi_output *dpi_output = NULL; - struct mdfld_dsi_config *dsi_config; - struct drm_connector *connector = NULL; - struct drm_encoder *encoder = NULL; - int pipe; - u32 data; - int ret; - - pipe = dsi_connector->pipe; - - if (mdfld_get_panel_type(dev, pipe) != TC35876X) { - dsi_config = mdfld_dsi_get_config(dsi_connector); - - /* panel hard-reset */ - if (p_funcs->reset) { - ret = p_funcs->reset(pipe); - if (ret) { - DRM_ERROR("Panel %d hard-reset failed\n", pipe); - return NULL; - } - } - - /* panel drvIC init */ - if (p_funcs->drv_ic_init) - p_funcs->drv_ic_init(dsi_config, pipe); - - /* panel power mode detect */ - ret = mdfld_dsi_get_power_mode(dsi_config, &data, false); - if (ret) { - DRM_ERROR("Panel %d get power mode failed\n", pipe); - dsi_connector->status = connector_status_disconnected; - } else { - DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); - dsi_connector->status = connector_status_connected; - } - } - - dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL); - if (!dpi_output) { - DRM_ERROR("No memory\n"); - return NULL; - } - - if (dsi_connector->pipe) - dpi_output->panel_on = 0; - else - dpi_output->panel_on = 0; - - dpi_output->dev = dev; - if (mdfld_get_panel_type(dev, pipe) != TC35876X) - dpi_output->p_funcs = p_funcs; - dpi_output->first_boot = 1; - - /*get fixed mode*/ - dsi_config = mdfld_dsi_get_config(dsi_connector); - - /*create drm encoder object*/ - connector = &dsi_connector->base.base; - encoder = &dpi_output->base.base.base; - drm_encoder_init(dev, - encoder, - p_funcs->encoder_funcs, - DRM_MODE_ENCODER_LVDS); - drm_encoder_helper_add(encoder, - p_funcs->encoder_helper_funcs); - - /*attach to given connector*/ - drm_mode_connector_attach_encoder(connector, encoder); - - /*set possible crtcs and clones*/ - if (dsi_connector->pipe) { - encoder->possible_crtcs = (1 << 2); - encoder->possible_clones = (1 << 1); - } else { - encoder->possible_crtcs = (1 << 0); - encoder->possible_clones = (1 << 0); - } - - dsi_connector->base.encoder = &dpi_output->base.base; - - return &dpi_output->base; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h deleted file mode 100644 index 6f762478..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_dpi.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#ifndef __MDFLD_DSI_DPI_H__ -#define __MDFLD_DSI_DPI_H__ - -#include "mdfld_dsi_output.h" -#include "mdfld_output.h" - -struct mdfld_dsi_dpi_timing { - u16 hsync_count; - u16 hbp_count; - u16 hfp_count; - u16 hactive_count; - u16 vsync_count; - u16 vbp_count; - u16 vfp_count; -}; - -struct mdfld_dsi_dpi_output { - struct mdfld_dsi_encoder base; - struct drm_device *dev; - - int panel_on; - int first_boot; - - const struct panel_funcs *p_funcs; -}; - -#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder)\ - container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base) - -/* Export functions */ -extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, - struct mdfld_dsi_dpi_timing *dpi_timing, - int num_lane, int bpp); -extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, - struct mdfld_dsi_connector *dsi_connector, - const struct panel_funcs *p_funcs); - -/* MDFLD DPI helper functions */ -extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode); -extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder); -extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder); -extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, - int pipe); -extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, - int pipe); -#endif /*__MDFLD_DSI_DPI_H__*/ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.c deleted file mode 100644 index 5675d93b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#include - -#include "mdfld_dsi_output.h" -#include "mdfld_dsi_dpi.h" -#include "mdfld_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "tc35876x-dsi-lvds.h" -#include -#include - -/* get the LABC from command line. */ -static int LABC_control = 1; - -#ifdef MODULE -module_param(LABC_control, int, 0644); -#else - -static int __init parse_LABC_control(char *arg) -{ - /* LABC control can be passed in as a cmdline parameter */ - /* to enable this feature add LABC=1 to cmdline */ - /* to disable this feature add LABC=0 to cmdline */ - if (!arg) - return -EINVAL; - - if (!strcasecmp(arg, "0")) - LABC_control = 0; - else if (!strcasecmp(arg, "1")) - LABC_control = 1; - - return 0; -} -early_param("LABC", parse_LABC_control); -#endif - -/** - * Check and see if the generic control or data buffer is empty and ready. - */ -void mdfld_dsi_gen_fifo_ready(struct drm_device *dev, u32 gen_fifo_stat_reg, - u32 fifo_stat) -{ - u32 GEN_BF_time_out_count; - - /* Check MIPI Adatper command registers */ - for (GEN_BF_time_out_count = 0; - GEN_BF_time_out_count < GEN_FB_TIME_OUT; - GEN_BF_time_out_count++) { - if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat) - break; - udelay(100); - } - - if (GEN_BF_time_out_count == GEN_FB_TIME_OUT) - DRM_ERROR("mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x.\n", - gen_fifo_stat_reg); -} - -/** - * Manage the DSI MIPI keyboard and display brightness. - * FIXME: this is exported to OSPM code. should work out an specific - * display interface to OSPM. - */ - -void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe) -{ - struct mdfld_dsi_pkg_sender *sender = - mdfld_dsi_get_pkg_sender(dsi_config); - struct drm_device *dev = sender->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 gen_ctrl_val; - - if (!sender) { - DRM_ERROR("No sender found\n"); - return; - } - - /* Set default display backlight value to 85% (0xd8)*/ - mdfld_dsi_send_mcs_short(sender, write_display_brightness, 0xd8, 1, - true); - - /* Set minimum brightness setting of CABC function to 20% (0x33)*/ - mdfld_dsi_send_mcs_short(sender, write_cabc_min_bright, 0x33, 1, true); - - /* Enable backlight or/and LABC */ - gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON | - BACKLIGHT_ON; - if (LABC_control == 1) - gen_ctrl_val |= DISPLAY_DIMMING_ON | DISPLAY_BRIGHTNESS_AUTO - | GAMMA_AUTO; - - if (LABC_control == 1) - gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON; - - dev_priv->mipi_ctrl_display = gen_ctrl_val; - - mdfld_dsi_send_mcs_short(sender, write_ctrl_display, (u8)gen_ctrl_val, - 1, true); - - mdfld_dsi_send_mcs_short(sender, write_ctrl_cabc, UI_IMAGE, 1, true); -} - -void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level) -{ - struct mdfld_dsi_pkg_sender *sender; - struct drm_psb_private *dev_priv; - struct mdfld_dsi_config *dsi_config; - u32 gen_ctrl_val = 0; - int p_type = TMD_VID; - - if (!dev || (pipe != 0 && pipe != 2)) { - DRM_ERROR("Invalid parameter\n"); - return; - } - - p_type = mdfld_get_panel_type(dev, 0); - - dev_priv = dev->dev_private; - - if (pipe) - dsi_config = dev_priv->dsi_configs[1]; - else - dsi_config = dev_priv->dsi_configs[0]; - - sender = mdfld_dsi_get_pkg_sender(dsi_config); - - if (!sender) { - DRM_ERROR("No sender found\n"); - return; - } - - gen_ctrl_val = (level * 0xff / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff; - - dev_dbg(sender->dev->dev, "pipe = %d, gen_ctrl_val = %d.\n", - pipe, gen_ctrl_val); - - if (p_type == TMD_VID) { - /* Set display backlight value */ - mdfld_dsi_send_mcs_short(sender, tmd_write_display_brightness, - (u8)gen_ctrl_val, 1, true); - } else { - /* Set display backlight value */ - mdfld_dsi_send_mcs_short(sender, write_display_brightness, - (u8)gen_ctrl_val, 1, true); - - /* Enable backlight control */ - if (level == 0) - gen_ctrl_val = 0; - else - gen_ctrl_val = dev_priv->mipi_ctrl_display; - - mdfld_dsi_send_mcs_short(sender, write_ctrl_display, - (u8)gen_ctrl_val, 1, true); - } -} - -static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config, - u8 dcs, u32 *data, bool hs) -{ - struct mdfld_dsi_pkg_sender *sender - = mdfld_dsi_get_pkg_sender(dsi_config); - - if (!sender || !data) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - return mdfld_dsi_read_mcs(sender, dcs, data, 1, hs); -} - -int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, u32 *mode, - bool hs) -{ - if (!dsi_config || !mode) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, hs); -} - -/* - * NOTE: this function was used by OSPM. - * TODO: will be removed later, should work out display interfaces for OSPM - */ -void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe) -{ - if (!dsi_config || ((pipe != 0) && (pipe != 2))) { - DRM_ERROR("Invalid parameters\n"); - return; - } - - mdfld_dsi_dpi_controller_init(dsi_config, pipe); -} - -static void mdfld_dsi_connector_save(struct drm_connector *connector) -{ -} - -static void mdfld_dsi_connector_restore(struct drm_connector *connector) -{ -} - -/* FIXME: start using the force parameter */ -static enum drm_connector_status -mdfld_dsi_connector_detect(struct drm_connector *connector, bool force) -{ - struct mdfld_dsi_connector *dsi_connector - = mdfld_dsi_connector(connector); - - dsi_connector->status = connector_status_connected; - - return dsi_connector->status; -} - -static int mdfld_dsi_connector_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct drm_encoder *encoder = connector->encoder; - - if (!strcmp(property->name, "scaling mode") && encoder) { - struct psb_intel_crtc *psb_crtc = - to_psb_intel_crtc(encoder->crtc); - bool centerechange; - uint64_t val; - - if (!psb_crtc) - goto set_prop_error; - - switch (value) { - case DRM_MODE_SCALE_FULLSCREEN: - break; - case DRM_MODE_SCALE_NO_SCALE: - break; - case DRM_MODE_SCALE_ASPECT: - break; - default: - goto set_prop_error; - } - - if (drm_connector_property_get_value(connector, property, &val)) - goto set_prop_error; - - if (val == value) - goto set_prop_done; - - if (drm_connector_property_set_value(connector, - property, value)) - goto set_prop_error; - - centerechange = (val == DRM_MODE_SCALE_NO_SCALE) || - (value == DRM_MODE_SCALE_NO_SCALE); - - if (psb_crtc->saved_mode.hdisplay != 0 && - psb_crtc->saved_mode.vdisplay != 0) { - if (centerechange) { - if (!drm_crtc_helper_set_mode(encoder->crtc, - &psb_crtc->saved_mode, - encoder->crtc->x, - encoder->crtc->y, - encoder->crtc->fb)) - goto set_prop_error; - } else { - struct drm_encoder_helper_funcs *funcs = - encoder->helper_private; - funcs->mode_set(encoder, - &psb_crtc->saved_mode, - &psb_crtc->saved_adjusted_mode); - } - } - } else if (!strcmp(property->name, "backlight") && encoder) { - if (drm_connector_property_set_value(connector, property, - value)) - goto set_prop_error; - else { -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct backlight_device *psb_bd; - - psb_bd = mdfld_get_backlight_device(); - if (psb_bd) { - psb_bd->props.brightness = value; - mdfld_set_brightness(psb_bd); - } -#endif - } - } -set_prop_done: - return 0; -set_prop_error: - return -1; -} - -static void mdfld_dsi_connector_destroy(struct drm_connector *connector) -{ - struct mdfld_dsi_connector *dsi_connector = - mdfld_dsi_connector(connector); - struct mdfld_dsi_pkg_sender *sender; - - if (!dsi_connector) - return; - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - sender = dsi_connector->pkg_sender; - mdfld_dsi_pkg_sender_destroy(sender); - kfree(dsi_connector); -} - -static int mdfld_dsi_connector_get_modes(struct drm_connector *connector) -{ - struct mdfld_dsi_connector *dsi_connector = - mdfld_dsi_connector(connector); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_get_config(dsi_connector); - struct drm_display_mode *fixed_mode = dsi_config->fixed_mode; - struct drm_display_mode *dup_mode = NULL; - struct drm_device *dev = connector->dev; - - connector->display_info.min_vfreq = 0; - connector->display_info.max_vfreq = 200; - connector->display_info.min_hfreq = 0; - connector->display_info.max_hfreq = 200; - - if (fixed_mode) { - dev_dbg(dev->dev, "fixed_mode %dx%d\n", - fixed_mode->hdisplay, fixed_mode->vdisplay); - dup_mode = drm_mode_duplicate(dev, fixed_mode); - drm_mode_probed_add(connector, dup_mode); - return 1; - } - DRM_ERROR("Didn't get any modes!\n"); - return 0; -} - -static int mdfld_dsi_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct mdfld_dsi_connector *dsi_connector = - mdfld_dsi_connector(connector); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_get_config(dsi_connector); - struct drm_display_mode *fixed_mode = dsi_config->fixed_mode; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - - /** - * FIXME: current DC has no fitting unit, reject any mode setting - * request - * Will figure out a way to do up-scaling(pannel fitting) later. - **/ - if (fixed_mode) { - if (mode->hdisplay != fixed_mode->hdisplay) - return MODE_PANEL; - - if (mode->vdisplay != fixed_mode->vdisplay) - return MODE_PANEL; - } - - return MODE_OK; -} - -static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) -{ - if (mode == connector->dpms) - return; - - /*first, execute dpms*/ - - drm_helper_connector_dpms(connector, mode); -} - -static struct drm_encoder *mdfld_dsi_connector_best_encoder( - struct drm_connector *connector) -{ - struct mdfld_dsi_connector *dsi_connector = - mdfld_dsi_connector(connector); - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_get_config(dsi_connector); - return &dsi_config->encoder->base.base; -} - -/*DSI connector funcs*/ -static const struct drm_connector_funcs mdfld_dsi_connector_funcs = { - .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms, - .save = mdfld_dsi_connector_save, - .restore = mdfld_dsi_connector_restore, - .detect = mdfld_dsi_connector_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = mdfld_dsi_connector_set_property, - .destroy = mdfld_dsi_connector_destroy, -}; - -/*DSI connector helper funcs*/ -static const struct drm_connector_helper_funcs - mdfld_dsi_connector_helper_funcs = { - .get_modes = mdfld_dsi_connector_get_modes, - .mode_valid = mdfld_dsi_connector_mode_valid, - .best_encoder = mdfld_dsi_connector_best_encoder, -}; - -static int mdfld_dsi_get_default_config(struct drm_device *dev, - struct mdfld_dsi_config *config, int pipe) -{ - if (!dev || !config) { - DRM_ERROR("Invalid parameters"); - return -EINVAL; - } - - config->bpp = 24; - if (mdfld_get_panel_type(dev, pipe) == TC35876X) - config->lane_count = 4; - else - config->lane_count = 2; - config->channel_num = 0; - - if (mdfld_get_panel_type(dev, pipe) == TMD_VID) - config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE; - else if (mdfld_get_panel_type(dev, pipe) == TC35876X) - config->video_mode = - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS; - else - config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE; - - return 0; -} - -int mdfld_dsi_panel_reset(int pipe) -{ - unsigned gpio; - int ret = 0; - - switch (pipe) { - case 0: - gpio = 128; - break; - case 2: - gpio = 34; - break; - default: - DRM_ERROR("Invalid output\n"); - return -EINVAL; - } - - ret = gpio_request(gpio, "gfx"); - if (ret) { - DRM_ERROR("gpio_rqueset failed\n"); - return ret; - } - - ret = gpio_direction_output(gpio, 1); - if (ret) { - DRM_ERROR("gpio_direction_output failed\n"); - goto gpio_error; - } - - gpio_get_value(128); - -gpio_error: - if (gpio_is_valid(gpio)) - gpio_free(gpio); - - return ret; -} - -/* - * MIPI output init - * @dev drm device - * @pipe pipe number. 0 or 2 - * @config - * - * Do the initialization of a MIPI output, including create DRM mode objects - * initialization of DSI output on @pipe - */ -void mdfld_dsi_output_init(struct drm_device *dev, - int pipe, - const struct panel_funcs *p_vid_funcs) -{ - struct mdfld_dsi_config *dsi_config; - struct mdfld_dsi_connector *dsi_connector; - struct drm_connector *connector; - struct mdfld_dsi_encoder *encoder; - struct drm_psb_private *dev_priv = dev->dev_private; - struct panel_info dsi_panel_info; - u32 width_mm, height_mm; - - dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe); - - if (!dev || ((pipe != 0) && (pipe != 2))) { - DRM_ERROR("Invalid parameter\n"); - return; - } - - /*create a new connetor*/ - dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL); - if (!dsi_connector) { - DRM_ERROR("No memory"); - return; - } - - dsi_connector->pipe = pipe; - - dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), - GFP_KERNEL); - if (!dsi_config) { - DRM_ERROR("cannot allocate memory for DSI config\n"); - goto dsi_init_err0; - } - mdfld_dsi_get_default_config(dev, dsi_config, pipe); - - dsi_connector->private = dsi_config; - - dsi_config->changed = 1; - dsi_config->dev = dev; - - dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev); - if (p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info)) - goto dsi_init_err0; - - width_mm = dsi_panel_info.width_mm; - height_mm = dsi_panel_info.height_mm; - - dsi_config->mode = dsi_config->fixed_mode; - dsi_config->connector = dsi_connector; - - if (!dsi_config->fixed_mode) { - DRM_ERROR("No pannel fixed mode was found\n"); - goto dsi_init_err0; - } - - if (pipe && dev_priv->dsi_configs[0]) { - dsi_config->dvr_ic_inited = 0; - dev_priv->dsi_configs[1] = dsi_config; - } else if (pipe == 0) { - dsi_config->dvr_ic_inited = 1; - dev_priv->dsi_configs[0] = dsi_config; - } else { - DRM_ERROR("Trying to init MIPI1 before MIPI0\n"); - goto dsi_init_err0; - } - - - connector = &dsi_connector->base.base; - drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs); - - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->display_info.width_mm = width_mm; - connector->display_info.height_mm = height_mm; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /*attach properties*/ - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, - dev_priv->backlight_property, - MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); - - /*init DSI package sender on this output*/ - if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) { - DRM_ERROR("Package Sender initialization failed on pipe %d\n", - pipe); - goto dsi_init_err0; - } - - encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs); - if (!encoder) { - DRM_ERROR("Create DPI encoder failed\n"); - goto dsi_init_err1; - } - encoder->private = dsi_config; - dsi_config->encoder = encoder; - encoder->base.type = (pipe == 0) ? INTEL_OUTPUT_MIPI : - INTEL_OUTPUT_MIPI2; - drm_sysfs_connector_add(connector); - return; - - /*TODO: add code to destroy outputs on error*/ -dsi_init_err1: - /*destroy sender*/ - mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender); - - drm_connector_cleanup(connector); - - kfree(dsi_config->fixed_mode); - kfree(dsi_config); -dsi_init_err0: - kfree(dsi_connector); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.h deleted file mode 100644 index 36eb0744..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#ifndef __MDFLD_DSI_OUTPUT_H__ -#define __MDFLD_DSI_OUTPUT_H__ - -#include -#include -#include -#include -#include - -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "mdfld_output.h" - -#include - -#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) -#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) -#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end)) -#define FLD_MOD(orig, val, start, end) \ - (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) - -#define REG_FLD_MOD(reg, val, start, end) \ - REG_WRITE(reg, FLD_MOD(REG_READ(reg), val, start, end)) - -static inline int REGISTER_FLD_WAIT(struct drm_device *dev, u32 reg, - u32 val, int start, int end) -{ - int t = 100000; - - while (FLD_GET(REG_READ(reg), start, end) != val) { - if (--t == 0) - return 1; - } - - return 0; -} - -#define REG_FLD_WAIT(reg, val, start, end) \ - REGISTER_FLD_WAIT(dev, reg, val, start, end) - -#define REG_BIT_WAIT(reg, val, bitnum) \ - REGISTER_FLD_WAIT(dev, reg, val, bitnum, bitnum) - -#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 - -#ifdef DEBUG -#define CHECK_PIPE(pipe) ({ \ - const typeof(pipe) __pipe = (pipe); \ - BUG_ON(__pipe != 0 && __pipe != 2); \ - __pipe; }) -#else -#define CHECK_PIPE(pipe) (pipe) -#endif - -/* - * Actual MIPIA->MIPIC reg offset is 0x800, value 0x400 is valid for 0 and 2 - */ -#define REG_OFFSET(pipe) (CHECK_PIPE(pipe) * 0x400) - -/* mdfld DSI controller registers */ -#define MIPI_DEVICE_READY_REG(pipe) (0xb000 + REG_OFFSET(pipe)) -#define MIPI_INTR_STAT_REG(pipe) (0xb004 + REG_OFFSET(pipe)) -#define MIPI_INTR_EN_REG(pipe) (0xb008 + REG_OFFSET(pipe)) -#define MIPI_DSI_FUNC_PRG_REG(pipe) (0xb00c + REG_OFFSET(pipe)) -#define MIPI_HS_TX_TIMEOUT_REG(pipe) (0xb010 + REG_OFFSET(pipe)) -#define MIPI_LP_RX_TIMEOUT_REG(pipe) (0xb014 + REG_OFFSET(pipe)) -#define MIPI_TURN_AROUND_TIMEOUT_REG(pipe) (0xb018 + REG_OFFSET(pipe)) -#define MIPI_DEVICE_RESET_TIMER_REG(pipe) (0xb01c + REG_OFFSET(pipe)) -#define MIPI_DPI_RESOLUTION_REG(pipe) (0xb020 + REG_OFFSET(pipe)) -#define MIPI_DBI_FIFO_THROTTLE_REG(pipe) (0xb024 + REG_OFFSET(pipe)) -#define MIPI_HSYNC_COUNT_REG(pipe) (0xb028 + REG_OFFSET(pipe)) -#define MIPI_HBP_COUNT_REG(pipe) (0xb02c + REG_OFFSET(pipe)) -#define MIPI_HFP_COUNT_REG(pipe) (0xb030 + REG_OFFSET(pipe)) -#define MIPI_HACTIVE_COUNT_REG(pipe) (0xb034 + REG_OFFSET(pipe)) -#define MIPI_VSYNC_COUNT_REG(pipe) (0xb038 + REG_OFFSET(pipe)) -#define MIPI_VBP_COUNT_REG(pipe) (0xb03c + REG_OFFSET(pipe)) -#define MIPI_VFP_COUNT_REG(pipe) (0xb040 + REG_OFFSET(pipe)) -#define MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe) (0xb044 + REG_OFFSET(pipe)) -#define MIPI_DPI_CONTROL_REG(pipe) (0xb048 + REG_OFFSET(pipe)) -#define MIPI_DPI_DATA_REG(pipe) (0xb04c + REG_OFFSET(pipe)) -#define MIPI_INIT_COUNT_REG(pipe) (0xb050 + REG_OFFSET(pipe)) -#define MIPI_MAX_RETURN_PACK_SIZE_REG(pipe) (0xb054 + REG_OFFSET(pipe)) -#define MIPI_VIDEO_MODE_FORMAT_REG(pipe) (0xb058 + REG_OFFSET(pipe)) -#define MIPI_EOT_DISABLE_REG(pipe) (0xb05c + REG_OFFSET(pipe)) -#define MIPI_LP_BYTECLK_REG(pipe) (0xb060 + REG_OFFSET(pipe)) -#define MIPI_LP_GEN_DATA_REG(pipe) (0xb064 + REG_OFFSET(pipe)) -#define MIPI_HS_GEN_DATA_REG(pipe) (0xb068 + REG_OFFSET(pipe)) -#define MIPI_LP_GEN_CTRL_REG(pipe) (0xb06c + REG_OFFSET(pipe)) -#define MIPI_HS_GEN_CTRL_REG(pipe) (0xb070 + REG_OFFSET(pipe)) -#define MIPI_GEN_FIFO_STAT_REG(pipe) (0xb074 + REG_OFFSET(pipe)) -#define MIPI_HS_LS_DBI_ENABLE_REG(pipe) (0xb078 + REG_OFFSET(pipe)) -#define MIPI_DPHY_PARAM_REG(pipe) (0xb080 + REG_OFFSET(pipe)) -#define MIPI_DBI_BW_CTRL_REG(pipe) (0xb084 + REG_OFFSET(pipe)) -#define MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe) (0xb088 + REG_OFFSET(pipe)) - -#define MIPI_CTRL_REG(pipe) (0xb104 + REG_OFFSET(pipe)) -#define MIPI_DATA_ADD_REG(pipe) (0xb108 + REG_OFFSET(pipe)) -#define MIPI_DATA_LEN_REG(pipe) (0xb10c + REG_OFFSET(pipe)) -#define MIPI_CMD_ADD_REG(pipe) (0xb110 + REG_OFFSET(pipe)) -#define MIPI_CMD_LEN_REG(pipe) (0xb114 + REG_OFFSET(pipe)) - -/* non-uniform reg offset */ -#define MIPI_PORT_CONTROL(pipe) (CHECK_PIPE(pipe) ? MIPI_C : MIPI) - -#define DSI_DEVICE_READY (0x1) -#define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1) -#define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1) -#define DSI_POWER_STATE_ULPS_OFFSET (0x1) - - -#define DSI_ONE_DATA_LANE (0x1) -#define DSI_TWO_DATA_LANE (0x2) -#define DSI_THREE_DATA_LANE (0X3) -#define DSI_FOUR_DATA_LANE (0x4) -#define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3) -#define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5) -#define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7) -#define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7) -#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7) -#define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7) -#define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13) - -#define DSI_INTR_STATE_RXSOTERROR BIT(0) - -#define DSI_INTR_STATE_SPL_PKG_SENT BIT(30) -#define DSI_INTR_STATE_TE BIT(31) - -#define DSI_HS_TX_TIMEOUT_MASK (0xffffff) - -#define DSI_LP_RX_TIMEOUT_MASK (0xffffff) - -#define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f) - -#define DSI_RESET_TIMER_MASK (0xffff) - -#define DSI_DBI_FIFO_WM_HALF (0x0) -#define DSI_DBI_FIFO_WM_QUARTER (0x1) -#define DSI_DBI_FIFO_WM_LOW (0x2) - -#define DSI_DPI_TIMING_MASK (0xffff) - -#define DSI_INIT_TIMER_MASK (0xffff) - -#define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff) - -#define DSI_LP_BYTECLK_MASK (0x0ffff) - -#define DSI_HS_CTRL_GEN_SHORT_W0 (0x03) -#define DSI_HS_CTRL_GEN_SHORT_W1 (0x13) -#define DSI_HS_CTRL_GEN_SHORT_W2 (0x23) -#define DSI_HS_CTRL_GEN_R0 (0x04) -#define DSI_HS_CTRL_GEN_R1 (0x14) -#define DSI_HS_CTRL_GEN_R2 (0x24) -#define DSI_HS_CTRL_GEN_LONG_W (0x29) -#define DSI_HS_CTRL_MCS_SHORT_W0 (0x05) -#define DSI_HS_CTRL_MCS_SHORT_W1 (0x15) -#define DSI_HS_CTRL_MCS_R0 (0x06) -#define DSI_HS_CTRL_MCS_LONG_W (0x39) -#define DSI_HS_CTRL_VC_OFFSET (0x06) -#define DSI_HS_CTRL_WC_OFFSET (0x08) - -#define DSI_FIFO_GEN_HS_DATA_FULL BIT(0) -#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY BIT(1) -#define DSI_FIFO_GEN_HS_DATA_EMPTY BIT(2) -#define DSI_FIFO_GEN_LP_DATA_FULL BIT(8) -#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY BIT(9) -#define DSI_FIFO_GEN_LP_DATA_EMPTY BIT(10) -#define DSI_FIFO_GEN_HS_CTRL_FULL BIT(16) -#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY BIT(17) -#define DSI_FIFO_GEN_HS_CTRL_EMPTY BIT(18) -#define DSI_FIFO_GEN_LP_CTRL_FULL BIT(24) -#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY BIT(25) -#define DSI_FIFO_GEN_LP_CTRL_EMPTY BIT(26) -#define DSI_FIFO_DBI_EMPTY BIT(27) -#define DSI_FIFO_DPI_EMPTY BIT(28) - -#define DSI_DBI_HS_LP_SWITCH_MASK (0x1) - -#define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0) -#define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16) - -#define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001) -#define DSI_DPI_CTRL_HS_TURN_ON (0x00000002) - -/*dsi power modes*/ -#define DSI_POWER_MODE_DISPLAY_ON BIT(2) -#define DSI_POWER_MODE_NORMAL_ON BIT(3) -#define DSI_POWER_MODE_SLEEP_OUT BIT(4) -#define DSI_POWER_MODE_PARTIAL_ON BIT(5) -#define DSI_POWER_MODE_IDLE_ON BIT(6) - -enum { - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1, - MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2, - MDFLD_DSI_VIDEO_BURST_MODE = 3, -}; - -#define DSI_DPI_COMPLETE_LAST_LINE BIT(2) -#define DSI_DPI_DISABLE_BTA BIT(3) - -struct mdfld_dsi_connector { - struct psb_intel_connector base; - - int pipe; - void *private; - void *pkg_sender; - - /* Connection status */ - enum drm_connector_status status; -}; - -struct mdfld_dsi_encoder { - struct psb_intel_encoder base; - void *private; -}; - -/* - * DSI config, consists of one DSI connector, two DSI encoders. - * DRM will pick up on DSI encoder basing on differents configs. - */ -struct mdfld_dsi_config { - struct drm_device *dev; - struct drm_display_mode *fixed_mode; - struct drm_display_mode *mode; - - struct mdfld_dsi_connector *connector; - struct mdfld_dsi_encoder *encoder; - - int changed; - - int bpp; - int lane_count; - /*Virtual channel number for this encoder*/ - int channel_num; - /*video mode configure*/ - int video_mode; - - int dvr_ic_inited; -}; - -static inline struct mdfld_dsi_connector *mdfld_dsi_connector( - struct drm_connector *connector) -{ - struct psb_intel_connector *psb_connector; - - psb_connector = to_psb_intel_connector(connector); - - return container_of(psb_connector, struct mdfld_dsi_connector, base); -} - -static inline struct mdfld_dsi_encoder *mdfld_dsi_encoder( - struct drm_encoder *encoder) -{ - struct psb_intel_encoder *psb_encoder; - - psb_encoder = to_psb_intel_encoder(encoder); - - return container_of(psb_encoder, struct mdfld_dsi_encoder, base); -} - -static inline struct mdfld_dsi_config * - mdfld_dsi_get_config(struct mdfld_dsi_connector *connector) -{ - if (!connector) - return NULL; - return (struct mdfld_dsi_config *)connector->private; -} - -static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config) -{ - struct mdfld_dsi_connector *dsi_connector; - - if (!config) - return NULL; - - dsi_connector = config->connector; - - if (!dsi_connector) - return NULL; - - return dsi_connector->pkg_sender; -} - -static inline struct mdfld_dsi_config * - mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder) -{ - if (!encoder) - return NULL; - return (struct mdfld_dsi_config *)encoder->private; -} - -static inline struct mdfld_dsi_connector * - mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder) -{ - struct mdfld_dsi_config *config; - - if (!encoder) - return NULL; - - config = mdfld_dsi_encoder_get_config(encoder); - if (!config) - return NULL; - - return config->connector; -} - -static inline void *mdfld_dsi_encoder_get_pkg_sender( - struct mdfld_dsi_encoder *encoder) -{ - struct mdfld_dsi_config *dsi_config; - - dsi_config = mdfld_dsi_encoder_get_config(encoder); - if (!dsi_config) - return NULL; - - return mdfld_dsi_get_pkg_sender(dsi_config); -} - -static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder) -{ - struct mdfld_dsi_connector *connector; - - if (!encoder) - return -1; - - connector = mdfld_dsi_encoder_get_connector(encoder); - if (!connector) - return -1; - return connector->pipe; -} - -/* Export functions */ -extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev, - u32 gen_fifo_stat_reg, u32 fifo_stat); -extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, - int pipe); -extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, - int level); -extern void mdfld_dsi_output_init(struct drm_device *dev, - int pipe, - const struct panel_funcs *p_vid_funcs); -extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, - int pipe); - -extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, - u32 *mode, bool hs); -extern int mdfld_dsi_panel_reset(int pipe); - -#endif /*__MDFLD_DSI_OUTPUT_H__*/ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c deleted file mode 100644 index baa0e141..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jackie Li - */ - -#include - -#include "mdfld_dsi_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "mdfld_dsi_dpi.h" - -#define MDFLD_DSI_READ_MAX_COUNT 5000 - -enum data_type { - DSI_DT_GENERIC_SHORT_WRITE_0 = 0x03, - DSI_DT_GENERIC_SHORT_WRITE_1 = 0x13, - DSI_DT_GENERIC_SHORT_WRITE_2 = 0x23, - DSI_DT_GENERIC_READ_0 = 0x04, - DSI_DT_GENERIC_READ_1 = 0x14, - DSI_DT_GENERIC_READ_2 = 0x24, - DSI_DT_GENERIC_LONG_WRITE = 0x29, - DSI_DT_DCS_SHORT_WRITE_0 = 0x05, - DSI_DT_DCS_SHORT_WRITE_1 = 0x15, - DSI_DT_DCS_READ = 0x06, - DSI_DT_DCS_LONG_WRITE = 0x39, -}; - -enum { - MDFLD_DSI_PANEL_MODE_SLEEP = 0x1, -}; - -enum { - MDFLD_DSI_PKG_SENDER_FREE = 0x0, - MDFLD_DSI_PKG_SENDER_BUSY = 0x1, -}; - -static const char *const dsi_errors[] = { - "RX SOT Error", - "RX SOT Sync Error", - "RX EOT Sync Error", - "RX Escape Mode Entry Error", - "RX LP TX Sync Error", - "RX HS Receive Timeout Error", - "RX False Control Error", - "RX ECC Single Bit Error", - "RX ECC Multibit Error", - "RX Checksum Error", - "RX DSI Data Type Not Recognised", - "RX DSI VC ID Invalid", - "TX False Control Error", - "TX ECC Single Bit Error", - "TX ECC Multibit Error", - "TX Checksum Error", - "TX DSI Data Type Not Recognised", - "TX DSI VC ID invalid", - "High Contention", - "Low contention", - "DPI FIFO Under run", - "HS TX Timeout", - "LP RX Timeout", - "Turn Around ACK Timeout", - "ACK With No Error", - "RX Invalid TX Length", - "RX Prot Violation", - "HS Generic Write FIFO Full", - "LP Generic Write FIFO Full", - "Generic Read Data Avail" - "Special Packet Sent", - "Tearing Effect", -}; - -static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender, - u32 mask) -{ - struct drm_device *dev = sender->dev; - u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg; - int retry = 0xffff; - - while (retry--) { - if ((mask & REG_READ(gen_fifo_stat_reg)) == mask) - return 0; - udelay(100); - } - DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg)); - return -EIO; -} - -static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) | - BIT(26) | BIT(27) | BIT(28))); -} - -static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26))); -} - -static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender) -{ - return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18))); -} - -static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask) -{ - u32 intr_stat_reg = sender->mipi_intr_stat_reg; - struct drm_device *dev = sender->dev; - - dev_dbg(sender->dev->dev, "Handling error 0x%08x\n", mask); - - switch (mask) { - case BIT(0): - case BIT(1): - case BIT(2): - case BIT(3): - case BIT(4): - case BIT(5): - case BIT(6): - case BIT(7): - case BIT(8): - case BIT(9): - case BIT(10): - case BIT(11): - case BIT(12): - case BIT(13): - dev_dbg(sender->dev->dev, "No Action required\n"); - break; - case BIT(14): - /*wait for all fifo empty*/ - /*wait_for_all_fifos_empty(sender)*/; - break; - case BIT(15): - dev_dbg(sender->dev->dev, "No Action required\n"); - break; - case BIT(16): - break; - case BIT(17): - break; - case BIT(18): - case BIT(19): - dev_dbg(sender->dev->dev, "High/Low contention detected\n"); - /*wait for contention recovery time*/ - /*mdelay(10);*/ - /*wait for all fifo empty*/ - if (0) - wait_for_all_fifos_empty(sender); - break; - case BIT(20): - dev_dbg(sender->dev->dev, "No Action required\n"); - break; - case BIT(21): - /*wait for all fifo empty*/ - /*wait_for_all_fifos_empty(sender);*/ - break; - case BIT(22): - break; - case BIT(23): - case BIT(24): - case BIT(25): - case BIT(26): - case BIT(27): - dev_dbg(sender->dev->dev, "HS Gen fifo full\n"); - REG_WRITE(intr_stat_reg, mask); - wait_for_hs_fifos_empty(sender); - break; - case BIT(28): - dev_dbg(sender->dev->dev, "LP Gen fifo full\n"); - REG_WRITE(intr_stat_reg, mask); - wait_for_lp_fifos_empty(sender); - break; - case BIT(29): - case BIT(30): - case BIT(31): - dev_dbg(sender->dev->dev, "No Action required\n"); - break; - } - - if (mask & REG_READ(intr_stat_reg)) - dev_dbg(sender->dev->dev, - "Cannot clean interrupt 0x%08x\n", mask); - return 0; -} - -static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender) -{ - struct drm_device *dev = sender->dev; - u32 intr_stat_reg = sender->mipi_intr_stat_reg; - u32 mask; - u32 intr_stat; - int i; - int err = 0; - - intr_stat = REG_READ(intr_stat_reg); - - for (i = 0; i < 32; i++) { - mask = (0x00000001UL) << i; - if (intr_stat & mask) { - dev_dbg(sender->dev->dev, "[DSI]: %s\n", dsi_errors[i]); - err = handle_dsi_error(sender, mask); - if (err) - DRM_ERROR("Cannot handle error\n"); - } - } - return err; -} - -static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 cmd, u8 param, bool hs) -{ - struct drm_device *dev = sender->dev; - u32 ctrl_reg; - u32 val; - u8 virtual_channel = 0; - - if (hs) { - ctrl_reg = sender->mipi_hs_gen_ctrl_reg; - - /* FIXME: wait_for_hs_fifos_empty(sender); */ - } else { - ctrl_reg = sender->mipi_lp_gen_ctrl_reg; - - /* FIXME: wait_for_lp_fifos_empty(sender); */ - } - - val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) | - FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0); - - REG_WRITE(ctrl_reg, val); - - return 0; -} - -static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, int len, bool hs) -{ - struct drm_device *dev = sender->dev; - u32 ctrl_reg; - u32 data_reg; - u32 val; - u8 *p; - u8 b1, b2, b3, b4; - u8 virtual_channel = 0; - int i; - - if (hs) { - ctrl_reg = sender->mipi_hs_gen_ctrl_reg; - data_reg = sender->mipi_hs_gen_data_reg; - - /* FIXME: wait_for_hs_fifos_empty(sender); */ - } else { - ctrl_reg = sender->mipi_lp_gen_ctrl_reg; - data_reg = sender->mipi_lp_gen_data_reg; - - /* FIXME: wait_for_lp_fifos_empty(sender); */ - } - - p = data; - for (i = 0; i < len / 4; i++) { - b1 = *p++; - b2 = *p++; - b3 = *p++; - b4 = *p++; - - REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1); - } - - i = len % 4; - if (i) { - b1 = 0; b2 = 0; b3 = 0; - - switch (i) { - case 3: - b1 = *p++; - b2 = *p++; - b3 = *p++; - break; - case 2: - b1 = *p++; - b2 = *p++; - break; - case 1: - b1 = *p++; - break; - } - - REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1); - } - - val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) | - FLD_VAL(data_type, 5, 0); - - REG_WRITE(ctrl_reg, val); - - return 0; -} - -static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len) -{ - u8 cmd; - - switch (data_type) { - case DSI_DT_DCS_SHORT_WRITE_0: - case DSI_DT_DCS_SHORT_WRITE_1: - case DSI_DT_DCS_LONG_WRITE: - cmd = *data; - break; - default: - return 0; - } - - /*this prevents other package sending while doing msleep*/ - sender->status = MDFLD_DSI_PKG_SENDER_BUSY; - - /*wait for 120 milliseconds in case exit_sleep_mode just be sent*/ - if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) { - /*TODO: replace it with msleep later*/ - mdelay(120); - } - - if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) { - /*TODO: replace it with msleep later*/ - mdelay(120); - } - return 0; -} - -static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len) -{ - u8 cmd; - - switch (data_type) { - case DSI_DT_DCS_SHORT_WRITE_0: - case DSI_DT_DCS_SHORT_WRITE_1: - case DSI_DT_DCS_LONG_WRITE: - cmd = *data; - break; - default: - return 0; - } - - /*update panel status*/ - if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) { - sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP; - /*TODO: replace it with msleep later*/ - mdelay(120); - } else if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) { - sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP; - /*TODO: replace it with msleep later*/ - mdelay(120); - } else if (unlikely(cmd == DCS_SOFT_RESET)) { - /*TODO: replace it with msleep later*/ - mdelay(5); - } - - sender->status = MDFLD_DSI_PKG_SENDER_FREE; - - return 0; -} - -static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len, bool hs) -{ - int ret; - - /*handle DSI error*/ - ret = dsi_error_handler(sender); - if (ret) { - DRM_ERROR("Error handling failed\n"); - return -EAGAIN; - } - - /* send pkg */ - if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) { - DRM_ERROR("sender is busy\n"); - return -EAGAIN; - } - - ret = send_pkg_prepare(sender, data_type, data, len); - if (ret) { - DRM_ERROR("send_pkg_prepare error\n"); - return ret; - } - - switch (data_type) { - case DSI_DT_GENERIC_SHORT_WRITE_0: - case DSI_DT_GENERIC_SHORT_WRITE_1: - case DSI_DT_GENERIC_SHORT_WRITE_2: - case DSI_DT_GENERIC_READ_0: - case DSI_DT_GENERIC_READ_1: - case DSI_DT_GENERIC_READ_2: - case DSI_DT_DCS_SHORT_WRITE_0: - case DSI_DT_DCS_SHORT_WRITE_1: - case DSI_DT_DCS_READ: - ret = send_short_pkg(sender, data_type, data[0], data[1], hs); - break; - case DSI_DT_GENERIC_LONG_WRITE: - case DSI_DT_DCS_LONG_WRITE: - ret = send_long_pkg(sender, data_type, data, len, hs); - break; - } - - send_pkg_done(sender, data_type, data, len); - - /*FIXME: should I query complete and fifo empty here?*/ - - return ret; -} - -int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs) -{ - unsigned long flags; - - if (!sender || !data || !len) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, DSI_DT_DCS_LONG_WRITE, data, len, hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u8 param, u8 param_num, bool hs) -{ - u8 data[2]; - unsigned long flags; - u8 data_type; - - if (!sender) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - data[0] = cmd; - - if (param_num) { - data_type = DSI_DT_DCS_SHORT_WRITE_1; - data[1] = param; - } else { - data_type = DSI_DT_DCS_SHORT_WRITE_0; - data[1] = 0; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, data_type, data, sizeof(data), hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0, - u8 param1, u8 param_num, bool hs) -{ - u8 data[2]; - unsigned long flags; - u8 data_type; - - if (!sender || param_num > 2) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - switch (param_num) { - case 0: - data_type = DSI_DT_GENERIC_SHORT_WRITE_0; - data[0] = 0; - data[1] = 0; - break; - case 1: - data_type = DSI_DT_GENERIC_SHORT_WRITE_1; - data[0] = param0; - data[1] = 0; - break; - case 2: - data_type = DSI_DT_GENERIC_SHORT_WRITE_2; - data[0] = param0; - data[1] = param1; - break; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, data_type, data, sizeof(data), hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs) -{ - unsigned long flags; - - if (!sender || !data || !len) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - spin_lock_irqsave(&sender->lock, flags); - send_pkg(sender, DSI_DT_GENERIC_LONG_WRITE, data, len, hs); - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type, - u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs) -{ - unsigned long flags; - struct drm_device *dev = sender->dev; - int i; - u32 gen_data_reg; - int retry = MDFLD_DSI_READ_MAX_COUNT; - - if (!sender || !data_out || !len_out) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - /** - * do reading. - * 0) send out generic read request - * 1) polling read data avail interrupt - * 2) read data - */ - spin_lock_irqsave(&sender->lock, flags); - - REG_WRITE(sender->mipi_intr_stat_reg, BIT(29)); - - if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) - DRM_ERROR("Can NOT clean read data valid interrupt\n"); - - /*send out read request*/ - send_pkg(sender, data_type, data, len, hs); - - /*polling read data avail interrupt*/ - while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) { - udelay(100); - retry--; - } - - if (!retry) { - spin_unlock_irqrestore(&sender->lock, flags); - return -ETIMEDOUT; - } - - REG_WRITE(sender->mipi_intr_stat_reg, BIT(29)); - - /*read data*/ - if (hs) - gen_data_reg = sender->mipi_hs_gen_data_reg; - else - gen_data_reg = sender->mipi_lp_gen_data_reg; - - for (i = 0; i < len_out; i++) - *(data_out + i) = REG_READ(gen_data_reg); - - spin_unlock_irqrestore(&sender->lock, flags); - - return 0; -} - -int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u32 *data, u16 len, bool hs) -{ - if (!sender || !data || !len) { - DRM_ERROR("Invalid parameters\n"); - return -EINVAL; - } - - return __read_panel_data(sender, DSI_DT_DCS_READ, &cmd, 1, - data, len, hs); -} - -int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, - int pipe) -{ - struct mdfld_dsi_pkg_sender *pkg_sender; - struct mdfld_dsi_config *dsi_config = - mdfld_dsi_get_config(dsi_connector); - struct drm_device *dev = dsi_config->dev; - u32 mipi_val = 0; - - if (!dsi_connector) { - DRM_ERROR("Invalid parameter\n"); - return -EINVAL; - } - - pkg_sender = dsi_connector->pkg_sender; - - if (!pkg_sender || IS_ERR(pkg_sender)) { - pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender), - GFP_KERNEL); - if (!pkg_sender) { - DRM_ERROR("Create DSI pkg sender failed\n"); - return -ENOMEM; - } - dsi_connector->pkg_sender = (void *)pkg_sender; - } - - pkg_sender->dev = dev; - pkg_sender->dsi_connector = dsi_connector; - pkg_sender->pipe = pipe; - pkg_sender->pkg_num = 0; - pkg_sender->panel_mode = 0; - pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE; - - /*init regs*/ - if (pipe == 0) { - pkg_sender->dpll_reg = MRST_DPLL_A; - pkg_sender->dspcntr_reg = DSPACNTR; - pkg_sender->pipeconf_reg = PIPEACONF; - pkg_sender->dsplinoff_reg = DSPALINOFF; - pkg_sender->dspsurf_reg = DSPASURF; - pkg_sender->pipestat_reg = PIPEASTAT; - } else if (pipe == 2) { - pkg_sender->dpll_reg = MRST_DPLL_A; - pkg_sender->dspcntr_reg = DSPCCNTR; - pkg_sender->pipeconf_reg = PIPECCONF; - pkg_sender->dsplinoff_reg = DSPCLINOFF; - pkg_sender->dspsurf_reg = DSPCSURF; - pkg_sender->pipestat_reg = PIPECSTAT; - } - - pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe); - pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe); - pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe); - pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe); - pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe); - pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe); - pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe); - pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe); - pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe); - pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe); - - /*init lock*/ - spin_lock_init(&pkg_sender->lock); - - if (mdfld_get_panel_type(dev, pipe) != TC35876X) { - /** - * For video mode, don't enable DPI timing output here, - * will init the DPI timing output during mode setting. - */ - mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; - - if (pipe == 0) - mipi_val |= 0x2; - - REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val); - REG_READ(MIPI_PORT_CONTROL(pipe)); - - /* do dsi controller init */ - mdfld_dsi_controller_init(dsi_config, pipe); - } - - return 0; -} - -void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender) -{ - if (!sender || IS_ERR(sender)) - return; - - /*free*/ - kfree(sender); -} - - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h deleted file mode 100644 index 459cd7ea..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jackie Li - */ -#ifndef __MDFLD_DSI_PKG_SENDER_H__ -#define __MDFLD_DSI_PKG_SENDER_H__ - -#include - -#define MDFLD_MAX_DCS_PARAM 8 - -struct mdfld_dsi_pkg_sender { - struct drm_device *dev; - struct mdfld_dsi_connector *dsi_connector; - u32 status; - u32 panel_mode; - - int pipe; - - spinlock_t lock; - - u32 pkg_num; - - /* Registers */ - u32 dpll_reg; - u32 dspcntr_reg; - u32 pipeconf_reg; - u32 pipestat_reg; - u32 dsplinoff_reg; - u32 dspsurf_reg; - - u32 mipi_intr_stat_reg; - u32 mipi_lp_gen_data_reg; - u32 mipi_hs_gen_data_reg; - u32 mipi_lp_gen_ctrl_reg; - u32 mipi_hs_gen_ctrl_reg; - u32 mipi_gen_fifo_stat_reg; - u32 mipi_data_addr_reg; - u32 mipi_data_len_reg; - u32 mipi_cmd_addr_reg; - u32 mipi_cmd_len_reg; -}; - -/* DCS definitions */ -#define DCS_SOFT_RESET 0x01 -#define DCS_ENTER_SLEEP_MODE 0x10 -#define DCS_EXIT_SLEEP_MODE 0x11 -#define DCS_SET_DISPLAY_OFF 0x28 -#define DCS_SET_DISPLAY_ON 0x29 -#define DCS_SET_COLUMN_ADDRESS 0x2a -#define DCS_SET_PAGE_ADDRESS 0x2b -#define DCS_WRITE_MEM_START 0x2c -#define DCS_SET_TEAR_OFF 0x34 -#define DCS_SET_TEAR_ON 0x35 - -extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, - int pipe); -extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender); -int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u8 param, u8 param_num, bool hs); -int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs); -int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0, - u8 param1, u8 param_num, bool hs); -int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data, - u32 len, bool hs); -/* Read interfaces */ -int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd, - u32 *data, u16 len, bool hs); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_intel_display.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_intel_display.c deleted file mode 100644 index a35a2921..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - */ - -#include -#include - -#include -#include "psb_intel_reg.h" -#include "psb_intel_display.h" -#include "framebuffer.h" -#include "mdfld_output.h" -#include "mdfld_dsi_output.h" - -/* Hardcoded currently */ -static int ksel = KSEL_CRYSTAL_19; - -struct psb_intel_range_t { - int min, max; -}; - -struct mrst_limit_t { - struct psb_intel_range_t dot, m, p1; -}; - -struct mrst_clock_t { - /* derived values */ - int dot; - int m; - int p1; -}; - -#define COUNT_MAX 0x10000000 - -void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) -{ - int count, temp; - u32 pipeconf_reg = PIPEACONF; - - switch (pipe) { - case 0: - break; - case 1: - pipeconf_reg = PIPEBCONF; - break; - case 2: - pipeconf_reg = PIPECCONF; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return; - } - - /* FIXME JLIU7_PO */ - psb_intel_wait_for_vblank(dev); - return; - - /* Wait for for the pipe disable to take effect. */ - for (count = 0; count < COUNT_MAX; count++) { - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_PIPE_STATE) == 0) - break; - } -} - -void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) -{ - int count, temp; - u32 pipeconf_reg = PIPEACONF; - - switch (pipe) { - case 0: - break; - case 1: - pipeconf_reg = PIPEBCONF; - break; - case 2: - pipeconf_reg = PIPECCONF; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return; - } - - /* FIXME JLIU7_PO */ - psb_intel_wait_for_vblank(dev); - return; - - /* Wait for for the pipe enable to take effect. */ - for (count = 0; count < COUNT_MAX; count++) { - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_PIPE_STATE) == 1) - break; - } -} - -static void psb_intel_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void psb_intel_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -} - -static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int psb_intel_panel_fitter_pipe(struct drm_device *dev) -{ - u32 pfit_control; - - pfit_control = REG_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - - /* 965 can place panel fitter on either pipe */ - return (pfit_control >> 29) & 0x3; -} - -static struct drm_device globle_dev; - -void mdfld__intel_plane_set_alpha(int enable) -{ - struct drm_device *dev = &globle_dev; - int dspcntr_reg = DSPACNTR; - u32 dspcntr; - - dspcntr = REG_READ(dspcntr_reg); - - if (enable) { - dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA; - dspcntr |= DISPPLANE_32BPP; - } else { - dspcntr &= ~DISPPLANE_32BPP; - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - } - - REG_WRITE(dspcntr_reg, dspcntr); -} - -static int check_fb(struct drm_framebuffer *fb) -{ - if (!fb) - return 0; - - switch (fb->bits_per_pixel) { - case 8: - case 16: - case 24: - case 32: - return 0; - default: - DRM_ERROR("Unknown color depth\n"); - return -EINVAL; - } -} - -static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); - int pipe = psb_intel_crtc->pipe; - unsigned long start, offset; - int dsplinoff = DSPALINOFF; - int dspsurf = DSPASURF; - int dspstride = DSPASTRIDE; - int dspcntr_reg = DSPACNTR; - u32 dspcntr; - int ret; - - memcpy(&globle_dev, dev, sizeof(struct drm_device)); - - dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe); - - /* no fb bound */ - if (!crtc->fb) { - dev_dbg(dev->dev, "No FB bound\n"); - return 0; - } - - ret = check_fb(crtc->fb); - if (ret) - return ret; - - switch (pipe) { - case 0: - dsplinoff = DSPALINOFF; - break; - case 1: - dsplinoff = DSPBLINOFF; - dspsurf = DSPBSURF; - dspstride = DSPBSTRIDE; - dspcntr_reg = DSPBCNTR; - break; - case 2: - dsplinoff = DSPCLINOFF; - dspsurf = DSPCSURF; - dspstride = DSPCSTRIDE; - dspcntr_reg = DSPCCNTR; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return -EINVAL; - } - - if (!gma_power_begin(dev, true)) - return 0; - - start = psbfb->gtt->offset; - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - - REG_WRITE(dspstride, crtc->fb->pitches[0]); - dspcntr = REG_READ(dspcntr_reg); - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - - switch (crtc->fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (crtc->fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - } - REG_WRITE(dspcntr_reg, dspcntr); - - dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n", - start, offset, x, y); - REG_WRITE(dsplinoff, offset); - REG_READ(dsplinoff); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - - gma_power_end(dev); - - return 0; -} - -/* - * Disable the pipe, plane and pll. - * - */ -void mdfld_disable_crtc(struct drm_device *dev, int pipe) -{ - int dpll_reg = MRST_DPLL_A; - int dspcntr_reg = DSPACNTR; - int dspbase_reg = MRST_DSPABASE; - int pipeconf_reg = PIPEACONF; - u32 temp; - - dev_dbg(dev->dev, "pipe = %d\n", pipe); - - - switch (pipe) { - case 0: - break; - case 1: - dpll_reg = MDFLD_DPLL_B; - dspcntr_reg = DSPBCNTR; - dspbase_reg = DSPBSURF; - pipeconf_reg = PIPEBCONF; - break; - case 2: - dpll_reg = MRST_DPLL_A; - dspcntr_reg = DSPCCNTR; - dspbase_reg = MDFLD_DSPCBASE; - pipeconf_reg = PIPECCONF; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return; - } - - if (pipe != 1) - mdfld_dsi_gen_fifo_ready(dev, MIPI_GEN_FIFO_STAT_REG(pipe), - HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); - - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - /* FIXME_JLIU7 MDFLD_PO revisit */ - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - temp &= ~PIPEACONF_ENABLE; - temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; - REG_WRITE(pipeconf_reg, temp); - REG_READ(pipeconf_reg); - - /* Wait for for the pipe disable to take effect. */ - mdfldWaitForPipeDisable(dev, pipe); - } - - temp = REG_READ(dpll_reg); - if (temp & DPLL_VCO_ENABLE) { - if ((pipe != 1 && - !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) - & PIPEACONF_ENABLE)) || pipe == 1) { - temp &= ~(DPLL_VCO_ENABLE); - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to turn off. */ - /* FIXME_MDFLD PO may need more delay */ - udelay(500); - - if (!(temp & MDFLD_PWR_GATE_EN)) { - /* gating power of DPLL */ - REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(5000); - } - } - } - -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = MRST_DPLL_A; - int dspcntr_reg = DSPACNTR; - int dspbase_reg = MRST_DSPABASE; - int pipeconf_reg = PIPEACONF; - u32 pipestat_reg = PIPEASTAT; - u32 pipeconf = dev_priv->pipeconf[pipe]; - u32 temp; - int timeout = 0; - - dev_dbg(dev->dev, "mode = %d, pipe = %d\n", mode, pipe); - -/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */ -/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */ - - switch (pipe) { - case 0: - break; - case 1: - dpll_reg = DPLL_B; - dspcntr_reg = DSPBCNTR; - dspbase_reg = MRST_DSPBBASE; - pipeconf_reg = PIPEBCONF; - dpll_reg = MDFLD_DPLL_B; - break; - case 2: - dpll_reg = MRST_DPLL_A; - dspcntr_reg = DSPCCNTR; - dspbase_reg = MDFLD_DSPCBASE; - pipeconf_reg = PIPECCONF; - pipestat_reg = PIPECSTAT; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return; - } - - if (!gma_power_begin(dev, true)) - return; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - /* Enable the DPLL */ - temp = REG_READ(dpll_reg); - - if ((temp & DPLL_VCO_ENABLE) == 0) { - /* When ungating power of DPLL, needs to wait 0.5us - before enable the VCO */ - if (temp & MDFLD_PWR_GATE_EN) { - temp &= ~MDFLD_PWR_GATE_EN; - REG_WRITE(dpll_reg, temp); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - } - - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - - /** - * wait for DSI PLL to lock - * NOTE: only need to poll status of pipe 0 and pipe 1, - * since both MIPI pipes share the same PLL. - */ - while ((pipe != 2) && (timeout < 20000) && - !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { - udelay(150); - timeout++; - } - } - - /* Enable the plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - } - - /* Enable the pipe */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) { - REG_WRITE(pipeconf_reg, pipeconf); - - /* Wait for for the pipe enable to take effect. */ - mdfldWaitForPipeEnable(dev, pipe); - } - - /*workaround for sighting 3741701 Random X blank display*/ - /*perform w/a in video mode only on pipe A or C*/ - if (pipe == 0 || pipe == 2) { - REG_WRITE(pipestat_reg, REG_READ(pipestat_reg)); - msleep(100); - if (PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) - dev_dbg(dev->dev, "OK"); - else { - dev_dbg(dev->dev, "STUCK!!!!"); - /*shutdown controller*/ - temp = REG_READ(dspcntr_reg); - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - /*mdfld_dsi_dpi_shut_down(dev, pipe);*/ - REG_WRITE(0xb048, 1); - msleep(100); - temp = REG_READ(pipeconf_reg); - temp &= ~PIPEACONF_ENABLE; - REG_WRITE(pipeconf_reg, temp); - msleep(100); /*wait for pipe disable*/ - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0); - msleep(100); - REG_WRITE(0xb004, REG_READ(0xb004)); - /* try to bring the controller back up again*/ - REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 1); - temp = REG_READ(dspcntr_reg); - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - /*mdfld_dsi_dpi_turn_on(dev, pipe);*/ - REG_WRITE(0xb048, 2); - msleep(100); - temp = REG_READ(pipeconf_reg); - temp |= PIPEACONF_ENABLE; - REG_WRITE(pipeconf_reg, temp); - } - } - - psb_intel_crtc_load_lut(crtc); - - /* Give the overlay scaler a chance to enable - if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ - - break; - case DRM_MODE_DPMS_OFF: - /* Give the overlay scaler a chance to disable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ - if (pipe != 1) - mdfld_dsi_gen_fifo_ready(dev, - MIPI_GEN_FIFO_STAT_REG(pipe), - HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - temp &= ~PIPEACONF_ENABLE; - temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; - REG_WRITE(pipeconf_reg, temp); - REG_READ(pipeconf_reg); - - /* Wait for for the pipe disable to take effect. */ - mdfldWaitForPipeDisable(dev, pipe); - } - - temp = REG_READ(dpll_reg); - if (temp & DPLL_VCO_ENABLE) { - if ((pipe != 1 && !((REG_READ(PIPEACONF) - | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) - || pipe == 1) { - temp &= ~(DPLL_VCO_ENABLE); - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to turn off. */ - /* FIXME_MDFLD PO may need more delay */ - udelay(500); - } - } - break; - } - gma_power_end(dev); -} - - -#define MDFLD_LIMT_DPLL_19 0 -#define MDFLD_LIMT_DPLL_25 1 -#define MDFLD_LIMT_DPLL_83 2 -#define MDFLD_LIMT_DPLL_100 3 -#define MDFLD_LIMT_DSIPLL_19 4 -#define MDFLD_LIMT_DSIPLL_25 5 -#define MDFLD_LIMT_DSIPLL_83 6 -#define MDFLD_LIMT_DSIPLL_100 7 - -#define MDFLD_DOT_MIN 19750 -#define MDFLD_DOT_MAX 120000 -#define MDFLD_DPLL_M_MIN_19 113 -#define MDFLD_DPLL_M_MAX_19 155 -#define MDFLD_DPLL_P1_MIN_19 2 -#define MDFLD_DPLL_P1_MAX_19 10 -#define MDFLD_DPLL_M_MIN_25 101 -#define MDFLD_DPLL_M_MAX_25 130 -#define MDFLD_DPLL_P1_MIN_25 2 -#define MDFLD_DPLL_P1_MAX_25 10 -#define MDFLD_DPLL_M_MIN_83 64 -#define MDFLD_DPLL_M_MAX_83 64 -#define MDFLD_DPLL_P1_MIN_83 2 -#define MDFLD_DPLL_P1_MAX_83 2 -#define MDFLD_DPLL_M_MIN_100 64 -#define MDFLD_DPLL_M_MAX_100 64 -#define MDFLD_DPLL_P1_MIN_100 2 -#define MDFLD_DPLL_P1_MAX_100 2 -#define MDFLD_DSIPLL_M_MIN_19 131 -#define MDFLD_DSIPLL_M_MAX_19 175 -#define MDFLD_DSIPLL_P1_MIN_19 3 -#define MDFLD_DSIPLL_P1_MAX_19 8 -#define MDFLD_DSIPLL_M_MIN_25 97 -#define MDFLD_DSIPLL_M_MAX_25 140 -#define MDFLD_DSIPLL_P1_MIN_25 3 -#define MDFLD_DSIPLL_P1_MAX_25 9 -#define MDFLD_DSIPLL_M_MIN_83 33 -#define MDFLD_DSIPLL_M_MAX_83 92 -#define MDFLD_DSIPLL_P1_MIN_83 2 -#define MDFLD_DSIPLL_P1_MAX_83 3 -#define MDFLD_DSIPLL_M_MIN_100 97 -#define MDFLD_DSIPLL_M_MAX_100 140 -#define MDFLD_DSIPLL_P1_MIN_100 3 -#define MDFLD_DSIPLL_P1_MAX_100 9 - -static const struct mrst_limit_t mdfld_limits[] = { - { /* MDFLD_LIMT_DPLL_19 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19}, - .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19}, - }, - { /* MDFLD_LIMT_DPLL_25 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25}, - .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25}, - }, - { /* MDFLD_LIMT_DPLL_83 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83}, - .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83}, - }, - { /* MDFLD_LIMT_DPLL_100 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100}, - .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100}, - }, - { /* MDFLD_LIMT_DSIPLL_19 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19}, - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19}, - }, - { /* MDFLD_LIMT_DSIPLL_25 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25}, - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25}, - }, - { /* MDFLD_LIMT_DSIPLL_83 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83}, - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83}, - }, - { /* MDFLD_LIMT_DSIPLL_100 */ - .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, - .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100}, - .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100}, - }, -}; - -#define MDFLD_M_MIN 21 -#define MDFLD_M_MAX 180 -static const u32 mdfld_m_converts[] = { -/* M configuration table from 9-bit LFSR table */ - 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */ - 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */ - 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */ - 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */ - 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */ - 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */ - 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */ - 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */ - 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */ - 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */ - 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */ - 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */ - 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */ - 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */ - 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */ - 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */ -}; - -static const struct mrst_limit_t *mdfld_limit(struct drm_crtc *crtc) -{ - const struct mrst_limit_t *limit = NULL; - struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI) - || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) { - if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19]; - else if (ksel == KSEL_BYPASS_25) - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25]; - else if ((ksel == KSEL_BYPASS_83_100) && - (dev_priv->core_freq == 166)) - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83]; - else if ((ksel == KSEL_BYPASS_83_100) && - (dev_priv->core_freq == 100 || - dev_priv->core_freq == 200)) - limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100]; - } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { - if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) - limit = &mdfld_limits[MDFLD_LIMT_DPLL_19]; - else if (ksel == KSEL_BYPASS_25) - limit = &mdfld_limits[MDFLD_LIMT_DPLL_25]; - else if ((ksel == KSEL_BYPASS_83_100) && - (dev_priv->core_freq == 166)) - limit = &mdfld_limits[MDFLD_LIMT_DPLL_83]; - else if ((ksel == KSEL_BYPASS_83_100) && - (dev_priv->core_freq == 100 || - dev_priv->core_freq == 200)) - limit = &mdfld_limits[MDFLD_LIMT_DPLL_100]; - } else { - limit = NULL; - dev_dbg(dev->dev, "mdfld_limit Wrong display type.\n"); - } - - return limit; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ -static void mdfld_clock(int refclk, struct mrst_clock_t *clock) -{ - clock->dot = (refclk * clock->m) / clock->p1; -} - -/** - * Returns a set of divisors for the desired target clock with the given refclk, - * or FALSE. Divisor values are the actual divisors for - */ -static bool -mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk, - struct mrst_clock_t *best_clock) -{ - struct mrst_clock_t clock; - const struct mrst_limit_t *limit = mdfld_limit(crtc); - int err = target; - - memset(best_clock, 0, sizeof(*best_clock)); - - for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { - for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; - clock.p1++) { - int this_err; - - mdfld_clock(refclk, &clock); - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - return err != target; -} - -static int mdfld_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct drm_psb_private *dev_priv = dev->dev_private; - int pipe = psb_intel_crtc->pipe; - int fp_reg = MRST_FPA0; - int dpll_reg = MRST_DPLL_A; - int dspcntr_reg = DSPACNTR; - int pipeconf_reg = PIPEACONF; - int htot_reg = HTOTAL_A; - int hblank_reg = HBLANK_A; - int hsync_reg = HSYNC_A; - int vtot_reg = VTOTAL_A; - int vblank_reg = VBLANK_A; - int vsync_reg = VSYNC_A; - int dspsize_reg = DSPASIZE; - int dsppos_reg = DSPAPOS; - int pipesrc_reg = PIPEASRC; - u32 *pipeconf = &dev_priv->pipeconf[pipe]; - u32 *dspcntr = &dev_priv->dspcntr[pipe]; - int refclk = 0; - int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, - clk_tmp = 0; - struct mrst_clock_t clock; - bool ok; - u32 dpll = 0, fp = 0; - bool is_mipi = false, is_mipi2 = false, is_hdmi = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct psb_intel_encoder *psb_intel_encoder = NULL; - uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; - struct drm_encoder *encoder; - struct drm_connector *connector; - int timeout = 0; - int ret; - - dev_dbg(dev->dev, "pipe = 0x%x\n", pipe); - -#if 0 - if (pipe == 1) { - if (!gma_power_begin(dev, true)) - return 0; - android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode, - x, y, old_fb); - goto mrst_crtc_mode_set_exit; - } -#endif - - switch (pipe) { - case 0: - break; - case 1: - fp_reg = FPB0; - dpll_reg = DPLL_B; - dspcntr_reg = DSPBCNTR; - pipeconf_reg = PIPEBCONF; - htot_reg = HTOTAL_B; - hblank_reg = HBLANK_B; - hsync_reg = HSYNC_B; - vtot_reg = VTOTAL_B; - vblank_reg = VBLANK_B; - vsync_reg = VSYNC_B; - dspsize_reg = DSPBSIZE; - dsppos_reg = DSPBPOS; - pipesrc_reg = PIPEBSRC; - fp_reg = MDFLD_DPLL_DIV0; - dpll_reg = MDFLD_DPLL_B; - break; - case 2: - dpll_reg = MRST_DPLL_A; - dspcntr_reg = DSPCCNTR; - pipeconf_reg = PIPECCONF; - htot_reg = HTOTAL_C; - hblank_reg = HBLANK_C; - hsync_reg = HSYNC_C; - vtot_reg = VTOTAL_C; - vblank_reg = VBLANK_C; - vsync_reg = VSYNC_C; - dspsize_reg = DSPCSIZE; - dsppos_reg = DSPCPOS; - pipesrc_reg = PIPECSRC; - break; - default: - DRM_ERROR("Illegal Pipe Number.\n"); - return 0; - } - - ret = check_fb(crtc->fb); - if (ret) - return ret; - - dev_dbg(dev->dev, "adjusted_hdisplay = %d\n", - adjusted_mode->hdisplay); - dev_dbg(dev->dev, "adjusted_vdisplay = %d\n", - adjusted_mode->vdisplay); - dev_dbg(dev->dev, "adjusted_hsync_start = %d\n", - adjusted_mode->hsync_start); - dev_dbg(dev->dev, "adjusted_hsync_end = %d\n", - adjusted_mode->hsync_end); - dev_dbg(dev->dev, "adjusted_htotal = %d\n", - adjusted_mode->htotal); - dev_dbg(dev->dev, "adjusted_vsync_start = %d\n", - adjusted_mode->vsync_start); - dev_dbg(dev->dev, "adjusted_vsync_end = %d\n", - adjusted_mode->vsync_end); - dev_dbg(dev->dev, "adjusted_vtotal = %d\n", - adjusted_mode->vtotal); - dev_dbg(dev->dev, "adjusted_clock = %d\n", - adjusted_mode->clock); - dev_dbg(dev->dev, "hdisplay = %d\n", - mode->hdisplay); - dev_dbg(dev->dev, "vdisplay = %d\n", - mode->vdisplay); - - if (!gma_power_begin(dev, true)) - return 0; - - memcpy(&psb_intel_crtc->saved_mode, mode, - sizeof(struct drm_display_mode)); - memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, - sizeof(struct drm_display_mode)); - - list_for_each_entry(connector, &mode_config->connector_list, head) { - if (!connector) - continue; - - encoder = connector->encoder; - - if (!encoder) - continue; - - if (encoder->crtc != crtc) - continue; - - psb_intel_encoder = psb_intel_attached_encoder(connector); - - switch (psb_intel_encoder->type) { - case INTEL_OUTPUT_MIPI: - is_mipi = true; - break; - case INTEL_OUTPUT_MIPI2: - is_mipi2 = true; - break; - case INTEL_OUTPUT_HDMI: - is_hdmi = true; - break; - } - } - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Disable the panel fitter if it was on our pipe */ - if (psb_intel_panel_fitter_pipe(dev) == pipe) - REG_WRITE(PFIT_CONTROL, 0); - - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - if (pipe == 1) { - /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 - * (PYR) or 480x854 (TMD), set the sprite width/height and - * souce image size registers with the adjusted mode for - * pipe B. - */ - - /* - * The defined sprite rectangle must always be completely - * contained within the displayable area of the screen image - * (frame buffer). - */ - REG_WRITE(dspsize_reg, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16) - | (min(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1)); - /* Set the CRTC with encoder mode. */ - REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) - | (mode->crtc_vdisplay - 1)); - } else { - REG_WRITE(dspsize_reg, - ((mode->crtc_vdisplay - 1) << 16) | - (mode->crtc_hdisplay - 1)); - REG_WRITE(pipesrc_reg, - ((mode->crtc_hdisplay - 1) << 16) | - (mode->crtc_vdisplay - 1)); - } - - REG_WRITE(dsppos_reg, 0); - - if (psb_intel_encoder) - drm_connector_property_get_value(connector, - dev->mode_config.scaling_mode_property, &scalingType); - - if (scalingType == DRM_MODE_SCALE_NO_SCALE) { - /* Medfield doesn't have register support for centering so we - * need to mess with the h/vblank and h/vsync start and ends - * to get centering - */ - int offsetX = 0, offsetY = 0; - - offsetX = (adjusted_mode->crtc_hdisplay - - mode->crtc_hdisplay) / 2; - offsetY = (adjusted_mode->crtc_vdisplay - - mode->crtc_vdisplay) / 2; - - REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - - offsetX - 1) | - ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - - offsetX - 1) | - ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - - offsetY - 1) | - ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - - offsetY - 1) | - ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); - } else { - REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - } - - /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } - - /* setup pipeconf */ - *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */ - - /* Set up the display plane register */ - *dspcntr = REG_READ(dspcntr_reg); - *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS; - *dspcntr |= DISPLAY_PLANE_ENABLE; - - if (is_mipi2) - goto mrst_crtc_mode_set_exit; - clk = adjusted_mode->clock; - - if (is_hdmi) { - if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) { - refclk = 19200; - - if (is_mipi || is_mipi2) - clk_n = 1, clk_p2 = 8; - else if (is_hdmi) - clk_n = 1, clk_p2 = 10; - } else if (ksel == KSEL_BYPASS_25) { - refclk = 25000; - - if (is_mipi || is_mipi2) - clk_n = 1, clk_p2 = 8; - else if (is_hdmi) - clk_n = 1, clk_p2 = 10; - } else if ((ksel == KSEL_BYPASS_83_100) && - dev_priv->core_freq == 166) { - refclk = 83000; - - if (is_mipi || is_mipi2) - clk_n = 4, clk_p2 = 8; - else if (is_hdmi) - clk_n = 4, clk_p2 = 10; - } else if ((ksel == KSEL_BYPASS_83_100) && - (dev_priv->core_freq == 100 || - dev_priv->core_freq == 200)) { - refclk = 100000; - if (is_mipi || is_mipi2) - clk_n = 4, clk_p2 = 8; - else if (is_hdmi) - clk_n = 4, clk_p2 = 10; - } - - if (is_mipi) - clk_byte = dev_priv->bpp / 8; - else if (is_mipi2) - clk_byte = dev_priv->bpp2 / 8; - - clk_tmp = clk * clk_n * clk_p2 * clk_byte; - - dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d.\n", - clk, clk_n, clk_p2); - dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d.\n", - adjusted_mode->clock, clk_tmp); - - ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock); - - if (!ok) { - DRM_ERROR - ("mdfldFindBestPLL fail in mdfld_crtc_mode_set.\n"); - } else { - m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)]; - - dev_dbg(dev->dev, "dot clock = %d," - "m = %d, p1 = %d, m_conv = %d.\n", - clock.dot, clock.m, - clock.p1, m_conv); - } - - dpll = REG_READ(dpll_reg); - - if (dpll & DPLL_VCO_ENABLE) { - dpll &= ~DPLL_VCO_ENABLE; - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - - /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */ - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - - /* reset M1, N1 & P1 */ - REG_WRITE(fp_reg, 0); - dpll &= ~MDFLD_P1_MASK; - REG_WRITE(dpll_reg, dpll); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - } - - /* When ungating power of DPLL, needs to wait 0.5us before - * enable the VCO */ - if (dpll & MDFLD_PWR_GATE_EN) { - dpll &= ~MDFLD_PWR_GATE_EN; - REG_WRITE(dpll_reg, dpll); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - } - dpll = 0; - -#if 0 /* FIXME revisit later */ - if (ksel == KSEL_CRYSTAL_19 || ksel == KSEL_BYPASS_19 || - ksel == KSEL_BYPASS_25) - dpll &= ~MDFLD_INPUT_REF_SEL; - else if (ksel == KSEL_BYPASS_83_100) - dpll |= MDFLD_INPUT_REF_SEL; -#endif /* FIXME revisit later */ - - if (is_hdmi) - dpll |= MDFLD_VCO_SEL; - - fp = (clk_n / 2) << 16; - fp |= m_conv; - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 2)) << 17; - -#if 0 /* 1080p30 & 720p */ - dpll = 0x00050000; - fp = 0x000001be; -#endif -#if 0 /* 480p */ - dpll = 0x02010000; - fp = 0x000000d2; -#endif - } else { -#if 0 /*DBI_TPO_480x864*/ - dpll = 0x00020000; - fp = 0x00000156; -#endif /* DBI_TPO_480x864 */ /* get from spec. */ - - dpll = 0x00800000; - fp = 0x000000c1; - } - - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll); - /* FIXME_MDFLD PO - change 500 to 1 after PO */ - udelay(500); - - dpll |= DPLL_VCO_ENABLE; - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - - /* wait for DSI PLL to lock */ - while (timeout < 20000 && - !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { - udelay(150); - timeout++; - } - - if (is_mipi) - goto mrst_crtc_mode_set_exit; - - dev_dbg(dev->dev, "is_mipi = 0x%x\n", is_mipi); - - REG_WRITE(pipeconf_reg, *pipeconf); - REG_READ(pipeconf_reg); - - /* Wait for for the pipe enable to take effect. */ - REG_WRITE(dspcntr_reg, *dspcntr); - psb_intel_wait_for_vblank(dev); - -mrst_crtc_mode_set_exit: - - gma_power_end(dev); - - return 0; -} - -const struct drm_crtc_helper_funcs mdfld_helper_funcs = { - .dpms = mdfld_crtc_dpms, - .mode_fixup = psb_intel_crtc_mode_fixup, - .mode_set = mdfld_crtc_mode_set, - .mode_set_base = mdfld__intel_pipe_set_base, - .prepare = psb_intel_crtc_prepare, - .commit = psb_intel_crtc_commit, -}; - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.c deleted file mode 100644 index c95966bb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicensen - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Thomas Eaton - * Scott Rowe -*/ - -#include "mdfld_output.h" -#include "mdfld_dsi_dpi.h" -#include "mdfld_dsi_output.h" - -#include "tc35876x-dsi-lvds.h" - -int mdfld_get_panel_type(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - return dev_priv->mdfld_panel_id; -} - -static void mdfld_init_panel(struct drm_device *dev, int mipi_pipe, - int p_type) -{ - switch (p_type) { - case TPO_VID: - mdfld_dsi_output_init(dev, mipi_pipe, &mdfld_tpo_vid_funcs); - break; - case TC35876X: - tc35876x_init(dev); - mdfld_dsi_output_init(dev, mipi_pipe, &mdfld_tc35876x_funcs); - break; - case TMD_VID: - mdfld_dsi_output_init(dev, mipi_pipe, &mdfld_tmd_vid_funcs); - break; - case HDMI: -/* if (dev_priv->mdfld_hdmi_present) - mdfld_hdmi_init(dev, &dev_priv->mode_dev); */ - break; - } -} - - -int mdfld_output_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - /* FIXME: hardcoded for now */ - dev_priv->mdfld_panel_id = TC35876X; - /* MIPI panel 1 */ - mdfld_init_panel(dev, 0, dev_priv->mdfld_panel_id); - /* HDMI panel */ - mdfld_init_panel(dev, 1, HDMI); - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.h deleted file mode 100644 index ab2b27c0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_output.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicensen - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Thomas Eaton - * Scott Rowe -*/ - -#ifndef MDFLD_OUTPUT_H -#define MDFLD_OUTPUT_H - -#include "psb_drv.h" - -#define TPO_PANEL_WIDTH 84 -#define TPO_PANEL_HEIGHT 46 -#define TMD_PANEL_WIDTH 39 -#define TMD_PANEL_HEIGHT 71 - -struct mdfld_dsi_config; - -enum panel_type { - TPO_VID, - TMD_VID, - HDMI, - TC35876X, -}; - -struct panel_info { - u32 width_mm; - u32 height_mm; - /* Other info */ -}; - -struct panel_funcs { - const struct drm_encoder_funcs *encoder_funcs; - const struct drm_encoder_helper_funcs *encoder_helper_funcs; - struct drm_display_mode * (*get_config_mode)(struct drm_device *); - int (*get_panel_info)(struct drm_device *, int, struct panel_info *); - int (*reset)(int pipe); - void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe); -}; - -int mdfld_output_init(struct drm_device *dev); - -struct backlight_device *mdfld_get_backlight_device(void); -int mdfld_set_brightness(struct backlight_device *bd); - -int mdfld_get_panel_type(struct drm_device *dev, int pipe); - -extern const struct drm_crtc_helper_funcs mdfld_helper_funcs; - -extern const struct panel_funcs mdfld_tmd_vid_funcs; -extern const struct panel_funcs mdfld_tpo_vid_funcs; - -extern void mdfld_disable_crtc(struct drm_device *dev, int pipe); -extern void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe); -extern void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe); -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tmd_vid.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tmd_vid.c deleted file mode 100644 index dc0c6c3d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tmd_vid.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jim Liu - * Jackie Li - * Gideon Eaton - */ - -#include "mdfld_dsi_dpi.h" -#include "mdfld_dsi_pkg_sender.h" - -static struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev) -{ - struct drm_display_mode *mode; - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; - bool use_gct = false; /*Disable GCT for now*/ - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - if (use_gct) { - mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; - mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; - mode->hsync_start = mode->hdisplay + \ - ((ti->hsync_offset_hi << 8) | \ - ti->hsync_offset_lo); - mode->hsync_end = mode->hsync_start + \ - ((ti->hsync_pulse_width_hi << 8) | \ - ti->hsync_pulse_width_lo); - mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ - ti->hblank_lo); - mode->vsync_start = \ - mode->vdisplay + ((ti->vsync_offset_hi << 8) | \ - ti->vsync_offset_lo); - mode->vsync_end = \ - mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ - ti->vsync_pulse_width_lo); - mode->vtotal = mode->vdisplay + \ - ((ti->vblank_hi << 8) | ti->vblank_lo); - mode->clock = ti->pixel_clock * 10; - - dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); - dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); - dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); - dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); - dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); - dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); - dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); - dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); - dev_dbg(dev->dev, "clock is %d\n", mode->clock); - } else { - mode->hdisplay = 480; - mode->vdisplay = 854; - mode->hsync_start = 487; - mode->hsync_end = 490; - mode->htotal = 499; - mode->vsync_start = 861; - mode->vsync_end = 865; - mode->vtotal = 873; - mode->clock = 33264; - } - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - mode->type |= DRM_MODE_TYPE_PREFERRED; - - return mode; -} - -static int tmd_vid_get_panel_info(struct drm_device *dev, - int pipe, - struct panel_info *pi) -{ - if (!dev || !pi) - return -EINVAL; - - pi->width_mm = TMD_PANEL_WIDTH; - pi->height_mm = TMD_PANEL_HEIGHT; - - return 0; -} - -/* ************************************************************************* *\ - * FUNCTION: mdfld_init_TMD_MIPI - * - * DESCRIPTION: This function is called only by mrst_dsi_mode_set and - * restore_display_registers. since this function does not - * acquire the mutex, it is important that the calling function - * does! -\* ************************************************************************* */ - -/* FIXME: make the below data u8 instead of u32; note byte order! */ -static u32 tmd_cmd_mcap_off[] = {0x000000b2}; -static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef}; -static u32 tmd_cmd_set_lane_num[] = {0x006360ef}; -static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef}; -static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef}; -static u32 tmd_cmd_set_mode[] = {0x000000b3}; -static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef}; -static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df}; -static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055}; -static u32 tmd_cmd_set_video_mode[] = {0x00000153}; -/*no auto_bl,need add in furture*/ -static u32 tmd_cmd_enable_backlight[] = {0x00005ab4}; -static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd}; - -static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config, - int pipe) -{ - struct mdfld_dsi_pkg_sender *sender - = mdfld_dsi_get_pkg_sender(dsi_config); - - DRM_INFO("Enter mdfld init TMD MIPI display.\n"); - - if (!sender) { - DRM_ERROR("Cannot get sender\n"); - return; - } - - if (dsi_config->dvr_ic_inited) - return; - - msleep(3); - - /* FIXME: make the below data u8 instead of u32; note byte order! */ - - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_mcap_off, - sizeof(tmd_cmd_mcap_off), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_enable_lane_switch, - sizeof(tmd_cmd_enable_lane_switch), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_lane_num, - sizeof(tmd_cmd_set_lane_num), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_pushing_clock0, - sizeof(tmd_cmd_pushing_clock0), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_pushing_clock1, - sizeof(tmd_cmd_pushing_clock1), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_mode, - sizeof(tmd_cmd_set_mode), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_sync_pulse_mode, - sizeof(tmd_cmd_set_sync_pulse_mode), false); - mdfld_dsi_send_mcs_long(sender, (u8 *) tmd_cmd_set_column, - sizeof(tmd_cmd_set_column), false); - mdfld_dsi_send_mcs_long(sender, (u8 *) tmd_cmd_set_page, - sizeof(tmd_cmd_set_page), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_video_mode, - sizeof(tmd_cmd_set_video_mode), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_enable_backlight, - sizeof(tmd_cmd_enable_backlight), false); - mdfld_dsi_send_gen_long(sender, (u8 *) tmd_cmd_set_backlight_dimming, - sizeof(tmd_cmd_set_backlight_dimming), false); - - dsi_config->dvr_ic_inited = 1; -} - -/*TPO DPI encoder helper funcs*/ -static const struct drm_encoder_helper_funcs - mdfld_tpo_dpi_encoder_helper_funcs = { - .dpms = mdfld_dsi_dpi_dpms, - .mode_fixup = mdfld_dsi_dpi_mode_fixup, - .prepare = mdfld_dsi_dpi_prepare, - .mode_set = mdfld_dsi_dpi_mode_set, - .commit = mdfld_dsi_dpi_commit, -}; - -/*TPO DPI encoder funcs*/ -static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - -const struct panel_funcs mdfld_tmd_vid_funcs = { - .encoder_funcs = &mdfld_tpo_dpi_encoder_funcs, - .encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs, - .get_config_mode = &tmd_vid_get_config_mode, - .get_panel_info = tmd_vid_get_panel_info, - .reset = mdfld_dsi_panel_reset, - .drv_ic_init = mdfld_dsi_tmd_drv_ic_init, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tpo_vid.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tpo_vid.c deleted file mode 100644 index d8d41707..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mdfld_tpo_vid.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * jim liu - * Jackie Li - */ - -#include "mdfld_dsi_dpi.h" - -static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev) -{ - struct drm_display_mode *mode; - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; - bool use_gct = false; - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - if (use_gct) { - mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; - mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; - mode->hsync_start = mode->hdisplay + - ((ti->hsync_offset_hi << 8) | - ti->hsync_offset_lo); - mode->hsync_end = mode->hsync_start + - ((ti->hsync_pulse_width_hi << 8) | - ti->hsync_pulse_width_lo); - mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | - ti->hblank_lo); - mode->vsync_start = - mode->vdisplay + ((ti->vsync_offset_hi << 8) | - ti->vsync_offset_lo); - mode->vsync_end = - mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | - ti->vsync_pulse_width_lo); - mode->vtotal = mode->vdisplay + - ((ti->vblank_hi << 8) | ti->vblank_lo); - mode->clock = ti->pixel_clock * 10; - - dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); - dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); - dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); - dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); - dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); - dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); - dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); - dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); - dev_dbg(dev->dev, "clock is %d\n", mode->clock); - } else { - mode->hdisplay = 864; - mode->vdisplay = 480; - mode->hsync_start = 873; - mode->hsync_end = 876; - mode->htotal = 887; - mode->vsync_start = 487; - mode->vsync_end = 490; - mode->vtotal = 499; - mode->clock = 33264; - } - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - mode->type |= DRM_MODE_TYPE_PREFERRED; - - return mode; -} - -static int tpo_vid_get_panel_info(struct drm_device *dev, - int pipe, - struct panel_info *pi) -{ - if (!dev || !pi) - return -EINVAL; - - pi->width_mm = TPO_PANEL_WIDTH; - pi->height_mm = TPO_PANEL_HEIGHT; - - return 0; -} - -/*TPO DPI encoder helper funcs*/ -static const struct drm_encoder_helper_funcs - mdfld_tpo_dpi_encoder_helper_funcs = { - .dpms = mdfld_dsi_dpi_dpms, - .mode_fixup = mdfld_dsi_dpi_mode_fixup, - .prepare = mdfld_dsi_dpi_prepare, - .mode_set = mdfld_dsi_dpi_mode_set, - .commit = mdfld_dsi_dpi_commit, -}; - -/*TPO DPI encoder funcs*/ -static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - -const struct panel_funcs mdfld_tpo_vid_funcs = { - .encoder_funcs = &mdfld_tpo_dpi_encoder_funcs, - .encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs, - .get_config_mode = &tpo_vid_get_config_mode, - .get_panel_info = tpo_vid_get_panel_info, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.c deleted file mode 100644 index 5eee9ad8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.c +++ /dev/null @@ -1,263 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -/* TODO - * - Split functions by vbt type - * - Make them all take drm_device - * - Check ioremap failures - */ - -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" -#include "mid_bios.h" - -static void mid_get_fuse_settings(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - uint32_t fuse_value = 0; - uint32_t fuse_value_tmp = 0; - -#define FB_REG06 0xD0810600 -#define FB_MIPI_DISABLE (1 << 11) -#define FB_REG09 0xD0810900 -#define FB_REG09 0xD0810900 -#define FB_SKU_MASK 0x7000 -#define FB_SKU_SHIFT 12 -#define FB_SKU_100 0 -#define FB_SKU_100L 1 -#define FB_SKU_83 2 - if (pci_root == NULL) { - WARN_ON(1); - return; - } - - - pci_write_config_dword(pci_root, 0xD0, FB_REG06); - pci_read_config_dword(pci_root, 0xD4, &fuse_value); - - /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */ - if (IS_MRST(dev)) - dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE; - - DRM_INFO("internal display is %s\n", - dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display"); - - /* Prevent runtime suspend at start*/ - if (dev_priv->iLVDS_enable) { - dev_priv->is_lvds_on = true; - dev_priv->is_mipi_on = false; - } else { - dev_priv->is_mipi_on = true; - dev_priv->is_lvds_on = false; - } - - dev_priv->video_device_fuse = fuse_value; - - pci_write_config_dword(pci_root, 0xD0, FB_REG09); - pci_read_config_dword(pci_root, 0xD4, &fuse_value); - - dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value); - fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT; - - dev_priv->fuse_reg_value = fuse_value; - - switch (fuse_value_tmp) { - case FB_SKU_100: - dev_priv->core_freq = 200; - break; - case FB_SKU_100L: - dev_priv->core_freq = 100; - break; - case FB_SKU_83: - dev_priv->core_freq = 166; - break; - default: - dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n", - fuse_value_tmp); - dev_priv->core_freq = 0; - } - dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq); - pci_dev_put(pci_root); -} - -/* - * Get the revison ID, B0:D2:F0;0x08 - */ -static void mid_get_pci_revID(struct drm_psb_private *dev_priv) -{ - uint32_t platform_rev_id = 0; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - if (pci_gfx_root == NULL) { - WARN_ON(1); - return; - } - pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); - dev_priv->platform_rev_id = (uint8_t) platform_rev_id; - pci_dev_put(pci_gfx_root); - dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n", - dev_priv->platform_rev_id); -} - -static void mid_get_vbt_data(struct drm_psb_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct oaktrail_vbt *vbt = &dev_priv->vbt_data; - u32 addr; - u16 new_size; - u8 *vbt_virtual; - u8 bpi; - u8 number_desc = 0; - struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD; - struct gct_r10_timing_info ti; - void *pGCT; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - /* Get the address of the platform config vbt, B0:D2:F0;0xFC */ - pci_read_config_dword(pci_gfx_root, 0xFC, &addr); - pci_dev_put(pci_gfx_root); - - dev_dbg(dev->dev, "drm platform config address is %x\n", addr); - - /* check for platform config address == 0. */ - /* this means fw doesn't support vbt */ - - if (addr == 0) { - vbt->size = 0; - return; - } - - /* get the virtual address of the vbt */ - vbt_virtual = ioremap(addr, sizeof(*vbt)); - if (vbt_virtual == NULL) { - vbt->size = 0; - return; - } - - memcpy(vbt, vbt_virtual, sizeof(*vbt)); - iounmap(vbt_virtual); /* Free virtual address space */ - - /* No matching signature don't process the data */ - if (memcmp(vbt->signature, "$GCT", 4)) { - vbt->size = 0; - return; - } - - dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision); - - switch (vbt->revision) { - case 0: - vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->oaktrail_gct; - bpi = ((struct oaktrail_gct_v1 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct oaktrail_gct_v1 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].DTD, - sizeof(struct oaktrail_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; - break; - case 1: - vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->oaktrail_gct; - bpi = ((struct oaktrail_gct_v2 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct oaktrail_gct_v2 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].DTD, - sizeof(struct oaktrail_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; - break; - case 0x10: - /*header definition changed from rev 01 (v2) to rev 10h. */ - /*so, some values have changed location*/ - new_size = vbt->checksum; /*checksum contains lo size byte*/ - /*LSB of oaktrail_gct contains hi size byte*/ - new_size |= ((0xff & (unsigned int)(long)vbt->oaktrail_gct)) << 8; - - vbt->checksum = vbt->size; /*size contains the checksum*/ - if (new_size > 0xff) - vbt->size = 0xff; /*restrict size to 255*/ - else - vbt->size = new_size; - - /* number of descriptors defined in the GCT */ - number_desc = ((0xff00 & (unsigned int)(long)vbt->oaktrail_gct)) >> 8; - bpi = ((0xff0000 & (unsigned int)(long)vbt->oaktrail_gct)) >> 16; - vbt->oaktrail_gct = ioremap(addr + GCT_R10_HEADER_SIZE, - GCT_R10_DISPLAY_DESC_SIZE * number_desc); - pGCT = vbt->oaktrail_gct; - pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE); - dev_priv->gct_data.bpi = bpi; /*save boot panel id*/ - - /*copy the GCT display timings into a temp structure*/ - memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info)); - - /*now copy the temp struct into the dev_priv->gct_data*/ - dp_ti->pixel_clock = ti.pixel_clock; - dp_ti->hactive_hi = ti.hactive_hi; - dp_ti->hactive_lo = ti.hactive_lo; - dp_ti->hblank_hi = ti.hblank_hi; - dp_ti->hblank_lo = ti.hblank_lo; - dp_ti->hsync_offset_hi = ti.hsync_offset_hi; - dp_ti->hsync_offset_lo = ti.hsync_offset_lo; - dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi; - dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo; - dp_ti->vactive_hi = ti.vactive_hi; - dp_ti->vactive_lo = ti.vactive_lo; - dp_ti->vblank_hi = ti.vblank_hi; - dp_ti->vblank_lo = ti.vblank_lo; - dp_ti->vsync_offset_hi = ti.vsync_offset_hi; - dp_ti->vsync_offset_lo = ti.vsync_offset_lo; - dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi; - dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo; - - /* Move the MIPI_Display_Descriptor data from GCT to dev priv */ - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - *((u8 *)pGCT + 0x0d); - dev_priv->gct_data.Panel_MIPI_Display_Descriptor |= - (*((u8 *)pGCT + 0x0e)) << 8; - break; - default: - dev_err(dev->dev, "Unknown revision of GCT!\n"); - vbt->size = 0; - } -} - -int mid_chip_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - mid_get_fuse_settings(dev); - mid_get_vbt_data(dev_priv); - mid_get_pci_revID(dev_priv); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.h deleted file mode 100644 index 00e7d564..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mid_bios.h +++ /dev/null @@ -1,21 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -extern int mid_chip_setup(struct drm_device *dev); - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mmu.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/mmu.c deleted file mode 100644 index 49bac41b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/mmu.c +++ /dev/null @@ -1,849 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ -#include -#include "psb_drv.h" -#include "psb_reg.h" - -/* - * Code for the SGX MMU: - */ - -/* - * clflush on one processor only: - * clflush should apparently flush the cache line on all processors in an - * SMP system. - */ - -/* - * kmap atomic: - * The usage of the slots must be completely encapsulated within a spinlock, and - * no other functions that may be using the locks for other purposed may be - * called from within the locked region. - * Since the slots are per processor, this will guarantee that we are the only - * user. - */ - -/* - * TODO: Inserting ptes from an interrupt handler: - * This may be desirable for some SGX functionality where the GPU can fault in - * needed pages. For that, we need to make an atomic insert_pages function, that - * may fail. - * If it fails, the caller need to insert the page using a workqueue function, - * but on average it should be fast. - */ - -struct psb_mmu_driver { - /* protects driver- and pd structures. Always take in read mode - * before taking the page table spinlock. - */ - struct rw_semaphore sem; - - /* protects page tables, directory tables and pt tables. - * and pt structures. - */ - spinlock_t lock; - - atomic_t needs_tlbflush; - - uint8_t __iomem *register_map; - struct psb_mmu_pd *default_pd; - /*uint32_t bif_ctrl;*/ - int has_clflush; - int clflush_add; - unsigned long clflush_mask; - - struct drm_psb_private *dev_priv; -}; - -struct psb_mmu_pd; - -struct psb_mmu_pt { - struct psb_mmu_pd *pd; - uint32_t index; - uint32_t count; - struct page *p; - uint32_t *v; -}; - -struct psb_mmu_pd { - struct psb_mmu_driver *driver; - int hw_context; - struct psb_mmu_pt **tables; - struct page *p; - struct page *dummy_pt; - struct page *dummy_page; - uint32_t pd_mask; - uint32_t invalid_pde; - uint32_t invalid_pte; -}; - -static inline uint32_t psb_mmu_pt_index(uint32_t offset) -{ - return (offset >> PSB_PTE_SHIFT) & 0x3FF; -} - -static inline uint32_t psb_mmu_pd_index(uint32_t offset) -{ - return offset >> PSB_PDE_SHIFT; -} - -static inline void psb_clflush(void *addr) -{ - __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory"); -} - -static inline void psb_mmu_clflush(struct psb_mmu_driver *driver, - void *addr) -{ - if (!driver->has_clflush) - return; - - mb(); - psb_clflush(addr); - mb(); -} - -static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page) -{ - uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT; - uint32_t clflush_count = PAGE_SIZE / clflush_add; - int i; - uint8_t *clf; - - clf = kmap_atomic(page); - mb(); - for (i = 0; i < clflush_count; ++i) { - psb_clflush(clf); - clf += clflush_add; - } - mb(); - kunmap_atomic(clf); -} - -static void psb_pages_clflush(struct psb_mmu_driver *driver, - struct page *page[], unsigned long num_pages) -{ - int i; - - if (!driver->has_clflush) - return ; - - for (i = 0; i < num_pages; i++) - psb_page_clflush(driver, *page++); -} - -static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver, - int force) -{ - atomic_set(&driver->needs_tlbflush, 0); -} - -static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force) -{ - down_write(&driver->sem); - psb_mmu_flush_pd_locked(driver, force); - up_write(&driver->sem); -} - -void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot) -{ - if (rc_prot) - down_write(&driver->sem); - if (rc_prot) - up_write(&driver->sem); -} - -void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context) -{ - /*ttm_tt_cache_flush(&pd->p, 1);*/ - psb_pages_clflush(pd->driver, &pd->p, 1); - down_write(&pd->driver->sem); - wmb(); - psb_mmu_flush_pd_locked(pd->driver, 1); - pd->hw_context = hw_context; - up_write(&pd->driver->sem); - -} - -static inline unsigned long psb_pd_addr_end(unsigned long addr, - unsigned long end) -{ - - addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK; - return (addr < end) ? addr : end; -} - -static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type) -{ - uint32_t mask = PSB_PTE_VALID; - - if (type & PSB_MMU_CACHED_MEMORY) - mask |= PSB_PTE_CACHED; - if (type & PSB_MMU_RO_MEMORY) - mask |= PSB_PTE_RO; - if (type & PSB_MMU_WO_MEMORY) - mask |= PSB_PTE_WO; - - return (pfn << PAGE_SHIFT) | mask; -} - -struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, - int trap_pagefaults, int invalid_type) -{ - struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL); - uint32_t *v; - int i; - - if (!pd) - return NULL; - - pd->p = alloc_page(GFP_DMA32); - if (!pd->p) - goto out_err1; - pd->dummy_pt = alloc_page(GFP_DMA32); - if (!pd->dummy_pt) - goto out_err2; - pd->dummy_page = alloc_page(GFP_DMA32); - if (!pd->dummy_page) - goto out_err3; - - if (!trap_pagefaults) { - pd->invalid_pde = - psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt), - invalid_type); - pd->invalid_pte = - psb_mmu_mask_pte(page_to_pfn(pd->dummy_page), - invalid_type); - } else { - pd->invalid_pde = 0; - pd->invalid_pte = 0; - } - - v = kmap(pd->dummy_pt); - for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) - v[i] = pd->invalid_pte; - - kunmap(pd->dummy_pt); - - v = kmap(pd->p); - for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) - v[i] = pd->invalid_pde; - - kunmap(pd->p); - - clear_page(kmap(pd->dummy_page)); - kunmap(pd->dummy_page); - - pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024); - if (!pd->tables) - goto out_err4; - - pd->hw_context = -1; - pd->pd_mask = PSB_PTE_VALID; - pd->driver = driver; - - return pd; - -out_err4: - __free_page(pd->dummy_page); -out_err3: - __free_page(pd->dummy_pt); -out_err2: - __free_page(pd->p); -out_err1: - kfree(pd); - return NULL; -} - -static void psb_mmu_free_pt(struct psb_mmu_pt *pt) -{ - __free_page(pt->p); - kfree(pt); -} - -void psb_mmu_free_pagedir(struct psb_mmu_pd *pd) -{ - struct psb_mmu_driver *driver = pd->driver; - struct psb_mmu_pt *pt; - int i; - - down_write(&driver->sem); - if (pd->hw_context != -1) - psb_mmu_flush_pd_locked(driver, 1); - - /* Should take the spinlock here, but we don't need to do that - since we have the semaphore in write mode. */ - - for (i = 0; i < 1024; ++i) { - pt = pd->tables[i]; - if (pt) - psb_mmu_free_pt(pt); - } - - vfree(pd->tables); - __free_page(pd->dummy_page); - __free_page(pd->dummy_pt); - __free_page(pd->p); - kfree(pd); - up_write(&driver->sem); -} - -static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd) -{ - struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL); - void *v; - uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT; - uint32_t clflush_count = PAGE_SIZE / clflush_add; - spinlock_t *lock = &pd->driver->lock; - uint8_t *clf; - uint32_t *ptes; - int i; - - if (!pt) - return NULL; - - pt->p = alloc_page(GFP_DMA32); - if (!pt->p) { - kfree(pt); - return NULL; - } - - spin_lock(lock); - - v = kmap_atomic(pt->p); - clf = (uint8_t *) v; - ptes = (uint32_t *) v; - for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) - *ptes++ = pd->invalid_pte; - - - if (pd->driver->has_clflush && pd->hw_context != -1) { - mb(); - for (i = 0; i < clflush_count; ++i) { - psb_clflush(clf); - clf += clflush_add; - } - mb(); - } - - kunmap_atomic(v); - spin_unlock(lock); - - pt->count = 0; - pt->pd = pd; - pt->index = 0; - - return pt; -} - -static struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd, - unsigned long addr) -{ - uint32_t index = psb_mmu_pd_index(addr); - struct psb_mmu_pt *pt; - uint32_t *v; - spinlock_t *lock = &pd->driver->lock; - - spin_lock(lock); - pt = pd->tables[index]; - while (!pt) { - spin_unlock(lock); - pt = psb_mmu_alloc_pt(pd); - if (!pt) - return NULL; - spin_lock(lock); - - if (pd->tables[index]) { - spin_unlock(lock); - psb_mmu_free_pt(pt); - spin_lock(lock); - pt = pd->tables[index]; - continue; - } - - v = kmap_atomic(pd->p); - pd->tables[index] = pt; - v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask; - pt->index = index; - kunmap_atomic((void *) v); - - if (pd->hw_context != -1) { - psb_mmu_clflush(pd->driver, (void *) &v[index]); - atomic_set(&pd->driver->needs_tlbflush, 1); - } - } - pt->v = kmap_atomic(pt->p); - return pt; -} - -static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd, - unsigned long addr) -{ - uint32_t index = psb_mmu_pd_index(addr); - struct psb_mmu_pt *pt; - spinlock_t *lock = &pd->driver->lock; - - spin_lock(lock); - pt = pd->tables[index]; - if (!pt) { - spin_unlock(lock); - return NULL; - } - pt->v = kmap_atomic(pt->p); - return pt; -} - -static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt) -{ - struct psb_mmu_pd *pd = pt->pd; - uint32_t *v; - - kunmap_atomic(pt->v); - if (pt->count == 0) { - v = kmap_atomic(pd->p); - v[pt->index] = pd->invalid_pde; - pd->tables[pt->index] = NULL; - - if (pd->hw_context != -1) { - psb_mmu_clflush(pd->driver, - (void *) &v[pt->index]); - atomic_set(&pd->driver->needs_tlbflush, 1); - } - kunmap_atomic(pt->v); - spin_unlock(&pd->driver->lock); - psb_mmu_free_pt(pt); - return; - } - spin_unlock(&pd->driver->lock); -} - -static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt, - unsigned long addr, uint32_t pte) -{ - pt->v[psb_mmu_pt_index(addr)] = pte; -} - -static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt, - unsigned long addr) -{ - pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte; -} - - -void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, - uint32_t mmu_offset, uint32_t gtt_start, - uint32_t gtt_pages) -{ - uint32_t *v; - uint32_t start = psb_mmu_pd_index(mmu_offset); - struct psb_mmu_driver *driver = pd->driver; - int num_pages = gtt_pages; - - down_read(&driver->sem); - spin_lock(&driver->lock); - - v = kmap_atomic(pd->p); - v += start; - - while (gtt_pages--) { - *v++ = gtt_start | pd->pd_mask; - gtt_start += PAGE_SIZE; - } - - /*ttm_tt_cache_flush(&pd->p, num_pages);*/ - psb_pages_clflush(pd->driver, &pd->p, num_pages); - kunmap_atomic(v); - spin_unlock(&driver->lock); - - if (pd->hw_context != -1) - atomic_set(&pd->driver->needs_tlbflush, 1); - - up_read(&pd->driver->sem); - psb_mmu_flush_pd(pd->driver, 0); -} - -struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver) -{ - struct psb_mmu_pd *pd; - - /* down_read(&driver->sem); */ - pd = driver->default_pd; - /* up_read(&driver->sem); */ - - return pd; -} - -void psb_mmu_driver_takedown(struct psb_mmu_driver *driver) -{ - psb_mmu_free_pagedir(driver->default_pd); - kfree(driver); -} - -struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, - int trap_pagefaults, - int invalid_type, - struct drm_psb_private *dev_priv) -{ - struct psb_mmu_driver *driver; - - driver = kmalloc(sizeof(*driver), GFP_KERNEL); - - if (!driver) - return NULL; - driver->dev_priv = dev_priv; - - driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults, - invalid_type); - if (!driver->default_pd) - goto out_err1; - - spin_lock_init(&driver->lock); - init_rwsem(&driver->sem); - down_write(&driver->sem); - driver->register_map = registers; - atomic_set(&driver->needs_tlbflush, 1); - - driver->has_clflush = 0; - - if (boot_cpu_has(X86_FEATURE_CLFLSH)) { - uint32_t tfms, misc, cap0, cap4, clflush_size; - - /* - * clflush size is determined at kernel setup for x86_64 - * but not for i386. We have to do it here. - */ - - cpuid(0x00000001, &tfms, &misc, &cap0, &cap4); - clflush_size = ((misc >> 8) & 0xff) * 8; - driver->has_clflush = 1; - driver->clflush_add = - PAGE_SIZE * clflush_size / sizeof(uint32_t); - driver->clflush_mask = driver->clflush_add - 1; - driver->clflush_mask = ~driver->clflush_mask; - } - - up_write(&driver->sem); - return driver; - -out_err1: - kfree(driver); - return NULL; -} - -static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride) -{ - struct psb_mmu_pt *pt; - uint32_t rows = 1; - uint32_t i; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long add; - unsigned long row_add; - unsigned long clflush_add = pd->driver->clflush_add; - unsigned long clflush_mask = pd->driver->clflush_mask; - - if (!pd->driver->has_clflush) { - /*ttm_tt_cache_flush(&pd->p, num_pages);*/ - psb_pages_clflush(pd->driver, &pd->p, num_pages); - return; - } - - if (hw_tile_stride) - rows = num_pages / desired_tile_stride; - else - desired_tile_stride = num_pages; - - add = desired_tile_stride << PAGE_SHIFT; - row_add = hw_tile_stride << PAGE_SHIFT; - mb(); - for (i = 0; i < rows; ++i) { - - addr = address; - end = addr + add; - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_map_lock(pd, addr); - if (!pt) - continue; - do { - psb_clflush(&pt->v - [psb_mmu_pt_index(addr)]); - } while (addr += - clflush_add, - (addr & clflush_mask) < next); - - psb_mmu_pt_unmap_unlock(pt); - } while (addr = next, next != end); - address += row_add; - } - mb(); -} - -void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, - unsigned long address, uint32_t num_pages) -{ - struct psb_mmu_pt *pt; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long f_address = address; - - down_read(&pd->driver->sem); - - addr = address; - end = addr + (num_pages << PAGE_SHIFT); - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_alloc_map_lock(pd, addr); - if (!pt) - goto out; - do { - psb_mmu_invalidate_pte(pt, addr); - --pt->count; - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - -out: - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1); - - up_read(&pd->driver->sem); - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 0); - - return; -} - -void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address, - uint32_t num_pages, uint32_t desired_tile_stride, - uint32_t hw_tile_stride) -{ - struct psb_mmu_pt *pt; - uint32_t rows = 1; - uint32_t i; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long add; - unsigned long row_add; - unsigned long f_address = address; - - if (hw_tile_stride) - rows = num_pages / desired_tile_stride; - else - desired_tile_stride = num_pages; - - add = desired_tile_stride << PAGE_SHIFT; - row_add = hw_tile_stride << PAGE_SHIFT; - - /* down_read(&pd->driver->sem); */ - - /* Make sure we only need to flush this processor's cache */ - - for (i = 0; i < rows; ++i) { - - addr = address; - end = addr + add; - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_map_lock(pd, addr); - if (!pt) - continue; - do { - psb_mmu_invalidate_pte(pt, addr); - --pt->count; - - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - address += row_add; - } - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, - desired_tile_stride, hw_tile_stride); - - /* up_read(&pd->driver->sem); */ - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 0); -} - -int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn, - unsigned long address, uint32_t num_pages, - int type) -{ - struct psb_mmu_pt *pt; - uint32_t pte; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long f_address = address; - int ret = 0; - - down_read(&pd->driver->sem); - - addr = address; - end = addr + (num_pages << PAGE_SHIFT); - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_alloc_map_lock(pd, addr); - if (!pt) { - ret = -ENOMEM; - goto out; - } - do { - pte = psb_mmu_mask_pte(start_pfn++, type); - psb_mmu_set_pte(pt, addr, pte); - pt->count++; - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - -out: - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1); - - up_read(&pd->driver->sem); - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 1); - - return ret; -} - -int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride, int type) -{ - struct psb_mmu_pt *pt; - uint32_t rows = 1; - uint32_t i; - uint32_t pte; - unsigned long addr; - unsigned long end; - unsigned long next; - unsigned long add; - unsigned long row_add; - unsigned long f_address = address; - int ret = 0; - - if (hw_tile_stride) { - if (num_pages % desired_tile_stride != 0) - return -EINVAL; - rows = num_pages / desired_tile_stride; - } else { - desired_tile_stride = num_pages; - } - - add = desired_tile_stride << PAGE_SHIFT; - row_add = hw_tile_stride << PAGE_SHIFT; - - down_read(&pd->driver->sem); - - for (i = 0; i < rows; ++i) { - - addr = address; - end = addr + add; - - do { - next = psb_pd_addr_end(addr, end); - pt = psb_mmu_pt_alloc_map_lock(pd, addr); - if (!pt) { - ret = -ENOMEM; - goto out; - } - do { - pte = - psb_mmu_mask_pte(page_to_pfn(*pages++), - type); - psb_mmu_set_pte(pt, addr, pte); - pt->count++; - } while (addr += PAGE_SIZE, addr < next); - psb_mmu_pt_unmap_unlock(pt); - - } while (addr = next, next != end); - - address += row_add; - } -out: - if (pd->hw_context != -1) - psb_mmu_flush_ptes(pd, f_address, num_pages, - desired_tile_stride, hw_tile_stride); - - up_read(&pd->driver->sem); - - if (pd->hw_context != -1) - psb_mmu_flush(pd->driver, 1); - - return ret; -} - -int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, - unsigned long *pfn) -{ - int ret; - struct psb_mmu_pt *pt; - uint32_t tmp; - spinlock_t *lock = &pd->driver->lock; - - down_read(&pd->driver->sem); - pt = psb_mmu_pt_map_lock(pd, virtual); - if (!pt) { - uint32_t *v; - - spin_lock(lock); - v = kmap_atomic(pd->p); - tmp = v[psb_mmu_pd_index(virtual)]; - kunmap_atomic(v); - spin_unlock(lock); - - if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) || - !(pd->invalid_pte & PSB_PTE_VALID)) { - ret = -EINVAL; - goto out; - } - ret = 0; - *pfn = pd->invalid_pte >> PAGE_SHIFT; - goto out; - } - tmp = pt->v[psb_mmu_pt_index(virtual)]; - if (!(tmp & PSB_PTE_VALID)) { - ret = -EINVAL; - } else { - ret = 0; - *pfn = tmp >> PAGE_SHIFT; - } - psb_mmu_pt_unmap_unlock(pt); -out: - up_read(&pd->driver->sem); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail.h deleted file mode 100644 index 2da1f368..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail.h +++ /dev/null @@ -1,252 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -/* MID device specific descriptors */ - -struct oaktrail_vbt { - s8 signature[4]; /*4 bytes,"$GCT" */ - u8 revision; - u8 size; - u8 checksum; - void *oaktrail_gct; -} __packed; - -struct oaktrail_timing_info { - u16 pixel_clock; - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_offset_lo; - u8 hsync_pulse_width_lo; - u8 vsync_pulse_width_lo:4; - u8 vsync_offset_lo:4; - u8 vsync_pulse_width_hi:2; - u8 vsync_offset_hi:2; - u8 hsync_pulse_width_hi:2; - u8 hsync_offset_hi:2; - u8 width_mm_lo; - u8 height_mm_lo; - u8 height_mm_hi:4; - u8 width_mm_hi:4; - u8 hborder; - u8 vborder; - u8 unknown0:1; - u8 hsync_positive:1; - u8 vsync_positive:1; - u8 separate_sync:2; - u8 stereo:1; - u8 unknown6:1; - u8 interlaced:1; -} __packed; - -struct gct_r10_timing_info { - u16 pixel_clock; - u32 hactive_lo:8; - u32 hactive_hi:4; - u32 hblank_lo:8; - u32 hblank_hi:4; - u32 hsync_offset_lo:8; - u16 hsync_offset_hi:2; - u16 hsync_pulse_width_lo:8; - u16 hsync_pulse_width_hi:2; - u16 hsync_positive:1; - u16 rsvd_1:3; - u8 vactive_lo:8; - u16 vactive_hi:4; - u16 vblank_lo:8; - u16 vblank_hi:4; - u16 vsync_offset_lo:4; - u16 vsync_offset_hi:2; - u16 vsync_pulse_width_lo:4; - u16 vsync_pulse_width_hi:2; - u16 vsync_positive:1; - u16 rsvd_2:3; -} __packed; - -struct oaktrail_panel_descriptor_v1 { - u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ - /* Register 0x61210 */ - struct oaktrail_timing_info DTD;/*18 bytes, Standard definition */ - u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ - /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ - /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ - u16 Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __packed; - -struct oaktrail_panel_descriptor_v2 { - u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ - /* Register 0x61210 */ - struct oaktrail_timing_info DTD;/*18 bytes, Standard definition */ - u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ - /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ - u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */ - /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ - u16 Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __packed; - -union oaktrail_panel_rx { - struct { - u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ - /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ - u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ - /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ - u16 SupportedVideoTransferMode:2; /*0: Non-burst only */ - /* 1: Burst and non-burst */ - /* 2/3: Reserved */ - u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ - u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ - u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ - u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ - u16 Rsvd:5;/*5 bits,00000b */ - } panelrx; - u16 panel_receiver; -} __packed; - -struct oaktrail_gct_v1 { - union { /*8 bits,Defined as follows: */ - struct { - u8 PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - u8 BootPanelIndex:2; - /* 4 panels to use by default*/ - u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - u8 PanelDescriptor; - }; - struct oaktrail_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ - union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ -} __packed; - -struct oaktrail_gct_v2 { - union { /*8 bits,Defined as follows: */ - struct { - u8 PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - u8 BootPanelIndex:2; - /* 4 panels to use by default*/ - u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - u8 PanelDescriptor; - }; - struct oaktrail_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ - union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ -} __packed; - -struct oaktrail_gct_data { - u8 bpi; /* boot panel index, number of panel used during boot */ - u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ - struct oaktrail_timing_info DTD; /* timing info for the selected panel */ - u32 Panel_Port_Control; - u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/ - u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - u32 PP_Cycle_Delay; - u16 Panel_Backlight_Inverter_Descriptor; - u16 Panel_MIPI_Display_Descriptor; -} __packed; - -#define MODE_SETTING_IN_CRTC 0x1 -#define MODE_SETTING_IN_ENCODER 0x2 -#define MODE_SETTING_ON_GOING 0x3 -#define MODE_SETTING_IN_DSR 0x4 -#define MODE_SETTING_ENCODER_DONE 0x8 - -#define GCT_R10_HEADER_SIZE 16 -#define GCT_R10_DISPLAY_DESC_SIZE 28 - -/* - * Moorestown HDMI interfaces - */ - -struct oaktrail_hdmi_dev { - struct pci_dev *dev; - void __iomem *regs; - unsigned int mmio, mmio_len; - int dpms_mode; - struct hdmi_i2c_dev *i2c_dev; - - /* register state */ - u32 saveDPLL_CTRL; - u32 saveDPLL_DIV_CTRL; - u32 saveDPLL_ADJUST; - u32 saveDPLL_UPDATE; - u32 saveDPLL_CLK_ENABLE; - u32 savePCH_HTOTAL_B; - u32 savePCH_HBLANK_B; - u32 savePCH_HSYNC_B; - u32 savePCH_VTOTAL_B; - u32 savePCH_VBLANK_B; - u32 savePCH_VSYNC_B; - u32 savePCH_PIPEBCONF; - u32 savePCH_PIPEBSRC; -}; - -extern void oaktrail_hdmi_setup(struct drm_device *dev); -extern void oaktrail_hdmi_teardown(struct drm_device *dev); -extern int oaktrail_hdmi_i2c_init(struct pci_dev *dev); -extern void oaktrail_hdmi_i2c_exit(struct pci_dev *dev); -extern void oaktrail_hdmi_save(struct drm_device *dev); -extern void oaktrail_hdmi_restore(struct drm_device *dev); -extern void oaktrail_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_crtc.c deleted file mode 100644 index a39b0d0d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include - -#include -#include "framebuffer.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_display.h" -#include "power.h" - -struct psb_intel_range_t { - int min, max; -}; - -struct oaktrail_limit_t { - struct psb_intel_range_t dot, m, p1; -}; - -struct oaktrail_clock_t { - /* derived values */ - int dot; - int m; - int p1; -}; - -#define MRST_LIMIT_LVDS_100L 0 -#define MRST_LIMIT_LVDS_83 1 -#define MRST_LIMIT_LVDS_100 2 - -#define MRST_DOT_MIN 19750 -#define MRST_DOT_MAX 120000 -#define MRST_M_MIN_100L 20 -#define MRST_M_MIN_100 10 -#define MRST_M_MIN_83 12 -#define MRST_M_MAX_100L 34 -#define MRST_M_MAX_100 17 -#define MRST_M_MAX_83 20 -#define MRST_P1_MIN 2 -#define MRST_P1_MAX_0 7 -#define MRST_P1_MAX_1 8 - -static const struct oaktrail_limit_t oaktrail_limits[] = { - { /* MRST_LIMIT_LVDS_100L */ - .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, - .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L}, - .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, - }, - { /* MRST_LIMIT_LVDS_83L */ - .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, - .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83}, - .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0}, - }, - { /* MRST_LIMIT_LVDS_100 */ - .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX}, - .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100}, - .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1}, - }, -}; - -#define MRST_M_MIN 10 -static const u32 oaktrail_m_converts[] = { - 0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C, - 0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25, - 0x12, 0x09, 0x24, 0x32, 0x39, 0x1c, -}; - -static const struct oaktrail_limit_t *oaktrail_limit(struct drm_crtc *crtc) -{ - const struct oaktrail_limit_t *limit = NULL; - struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) - || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) { - switch (dev_priv->core_freq) { - case 100: - limit = &oaktrail_limits[MRST_LIMIT_LVDS_100L]; - break; - case 166: - limit = &oaktrail_limits[MRST_LIMIT_LVDS_83]; - break; - case 200: - limit = &oaktrail_limits[MRST_LIMIT_LVDS_100]; - break; - } - } else { - limit = NULL; - dev_err(dev->dev, "oaktrail_limit Wrong display type.\n"); - } - - return limit; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ -static void oaktrail_clock(int refclk, struct oaktrail_clock_t *clock) -{ - clock->dot = (refclk * clock->m) / (14 * clock->p1); -} - -static void mrstPrintPll(char *prefix, struct oaktrail_clock_t *clock) -{ - pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n", - prefix, clock->dot, clock->m, clock->p1); -} - -/** - * Returns a set of divisors for the desired target clock with the given refclk, - * or FALSE. Divisor values are the actual divisors for - */ -static bool -mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, - struct oaktrail_clock_t *best_clock) -{ - struct oaktrail_clock_t clock; - const struct oaktrail_limit_t *limit = oaktrail_limit(crtc); - int err = target; - - memset(best_clock, 0, sizeof(*best_clock)); - - for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { - for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; - clock.p1++) { - int this_err; - - oaktrail_clock(refclk, &clock); - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err); - return err != target; -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - u32 temp; - - if (!gma_power_begin(dev, true)) - return; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - /* Enable the DPLL */ - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - } - /* Enable the pipe */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); - /* Enable the plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - } - - psb_intel_crtc_load_lut(crtc); - - /* Give the overlay scaler a chance to enable - if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ - break; - case DRM_MODE_DPMS_OFF: - /* Give the overlay scaler a chance to disable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - REG_READ(pipeconf_reg); - } - /* Wait for for the pipe disable to take effect. */ - psb_intel_wait_for_vblank(dev); - - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - } - - /* Wait for the clocks to turn off. */ - udelay(150); - break; - } - - /*Set FIFO Watermarks*/ - REG_WRITE(DSPARB, 0x3FFF); - REG_WRITE(DSPFW1, 0x3F88080A); - REG_WRITE(DSPFW2, 0x0b060808); - REG_WRITE(DSPFW3, 0x0); - REG_WRITE(DSPFW4, 0x08030404); - REG_WRITE(DSPFW5, 0x04040404); - REG_WRITE(DSPFW6, 0x78); - REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000); - /* Must write Bit 14 of the Chicken Bit Register */ - - gma_power_end(dev); -} - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int oaktrail_panel_fitter_pipe(struct drm_device *dev) -{ - u32 pfit_control; - - pfit_control = REG_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - return (pfit_control >> 29) & 3; -} - -static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct drm_psb_private *dev_priv = dev->dev_private; - int pipe = psb_intel_crtc->pipe; - int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0; - int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; - int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; - int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; - int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; - int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; - int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk = 0; - struct oaktrail_clock_t clock; - u32 dpll = 0, fp = 0, dspcntr, pipeconf; - bool ok, is_sdvo = false; - bool is_lvds = false; - bool is_mipi = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct psb_intel_encoder *psb_intel_encoder = NULL; - uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; - struct drm_connector *connector; - - if (!gma_power_begin(dev, true)) - return 0; - - memcpy(&psb_intel_crtc->saved_mode, - mode, - sizeof(struct drm_display_mode)); - memcpy(&psb_intel_crtc->saved_adjusted_mode, - adjusted_mode, - sizeof(struct drm_display_mode)); - - list_for_each_entry(connector, &mode_config->connector_list, head) { - if (!connector->encoder || connector->encoder->crtc != crtc) - continue; - - psb_intel_encoder = psb_intel_attached_encoder(connector); - - switch (psb_intel_encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - is_sdvo = true; - break; - case INTEL_OUTPUT_MIPI: - is_mipi = true; - break; - } - } - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Disable the panel fitter if it was on our pipe */ - if (oaktrail_panel_fitter_pipe(dev) == pipe) - REG_WRITE(PFIT_CONTROL, 0); - - REG_WRITE(pipesrc_reg, - ((mode->crtc_hdisplay - 1) << 16) | - (mode->crtc_vdisplay - 1)); - - if (psb_intel_encoder) - drm_connector_property_get_value(connector, - dev->mode_config.scaling_mode_property, &scalingType); - - if (scalingType == DRM_MODE_SCALE_NO_SCALE) { - /* Moorestown doesn't have register support for centering so - * we need to mess with the h/vblank and h/vsync start and - * ends to get centering */ - int offsetX = 0, offsetY = 0; - - offsetX = (adjusted_mode->crtc_hdisplay - - mode->crtc_hdisplay) / 2; - offsetY = (adjusted_mode->crtc_vdisplay - - mode->crtc_vdisplay) / 2; - - REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(hblank_reg, - (adjusted_mode->crtc_hblank_start - offsetX - 1) | - ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); - REG_WRITE(hsync_reg, - (adjusted_mode->crtc_hsync_start - offsetX - 1) | - ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); - REG_WRITE(vblank_reg, - (adjusted_mode->crtc_vblank_start - offsetY - 1) | - ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); - REG_WRITE(vsync_reg, - (adjusted_mode->crtc_vsync_start - offsetY - 1) | - ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); - } else { - REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - } - - /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } - - /* setup pipeconf */ - pipeconf = REG_READ(pipeconf_reg); - - /* Set up the display plane register */ - dspcntr = REG_READ(dspcntr_reg); - dspcntr |= DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr |= DISPPLANE_SEL_PIPE_A; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - if (is_mipi) - goto oaktrail_crtc_mode_set_exit; - - refclk = dev_priv->core_freq * 1000; - - dpll = 0; /*BIT16 = 0 for 100MHz reference */ - - ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock); - - if (!ok) { - dev_dbg(dev->dev, "mrstFindBestPLL fail in oaktrail_crtc_mode_set.\n"); - } else { - dev_dbg(dev->dev, "oaktrail_crtc_mode_set pixel clock = %d," - "m = %x, p1 = %x.\n", clock.dot, clock.m, - clock.p1); - } - - fp = oaktrail_m_converts[(clock.m - MRST_M_MIN)] << 8; - - dpll |= DPLL_VGA_MODE_DIS; - - - dpll |= DPLL_VCO_ENABLE; - - if (is_lvds) - dpll |= DPLLA_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - - if (is_sdvo) { - int sdvo_pixel_multiply = - adjusted_mode->clock / mode->clock; - - dpll |= DPLL_DVO_HIGH_SPEED; - dpll |= - (sdvo_pixel_multiply - - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - } - - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 2)) << 17; - - dpll |= DPLL_VCO_ENABLE; - - mrstPrintPll("chosen", &clock); - - if (dpll & DPLL_VCO_ENABLE) { - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Check the DPLLA lock bit PIPEACONF[29] */ - udelay(150); - } - - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - /* write it again -- the BIOS does, after all */ - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - psb_intel_wait_for_vblank(dev); - - REG_WRITE(dspcntr_reg, dspcntr); - psb_intel_wait_for_vblank(dev); - -oaktrail_crtc_mode_set_exit: - gma_power_end(dev); - return 0; -} - -static bool oaktrail_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static int oaktrail_pipe_set_base(struct drm_crtc *crtc, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); - int pipe = psb_intel_crtc->pipe; - unsigned long start, offset; - - int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); - int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - u32 dspcntr; - int ret = 0; - - /* no fb bound */ - if (!crtc->fb) { - dev_dbg(dev->dev, "No FB bound\n"); - return 0; - } - - if (!gma_power_begin(dev, true)) - return 0; - - start = psbfb->gtt->offset; - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - - REG_WRITE(dspstride, crtc->fb->pitches[0]); - - dspcntr = REG_READ(dspcntr_reg); - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - - switch (crtc->fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (crtc->fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - dev_err(dev->dev, "Unknown color depth\n"); - ret = -EINVAL; - goto pipe_set_base_exit; - } - REG_WRITE(dspcntr_reg, dspcntr); - - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - -pipe_set_base_exit: - gma_power_end(dev); - return ret; -} - -static void oaktrail_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void oaktrail_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -} - -const struct drm_crtc_helper_funcs oaktrail_helper_funcs = { - .dpms = oaktrail_crtc_dpms, - .mode_fixup = oaktrail_crtc_mode_fixup, - .mode_set = oaktrail_crtc_mode_set, - .mode_set_base = oaktrail_pipe_set_base, - .prepare = oaktrail_crtc_prepare, - .commit = oaktrail_crtc_commit, -}; - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_device.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_device.c deleted file mode 100644 index 41d1924e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_device.c +++ /dev/null @@ -1,509 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include -#include -#include -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include -#include -#include "mid_bios.h" -#include "intel_bios.h" - -static int oaktrail_output_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->iLVDS_enable) - oaktrail_lvds_init(dev, &dev_priv->mode_dev); - else - dev_err(dev->dev, "DSI is not supported\n"); - if (dev_priv->hdmi_priv) - oaktrail_hdmi_init(dev, &dev_priv->mode_dev); - return 0; -} - -/* - * Provide the low level interfaces for the Moorestown backlight - */ - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - -#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 -#define BLC_ADJUSTMENT_MAX 100 - -static struct backlight_device *oaktrail_backlight_device; -static int oaktrail_brightness; - -static int oaktrail_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(oaktrail_backlight_device); - struct drm_psb_private *dev_priv = dev->dev_private; - int level = bd->props.brightness; - u32 blc_pwm_ctl; - u32 max_pwm_blc; - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - if (gma_power_begin(dev, 0)) { - /* Calculate and set the brightness value */ - max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; - blc_pwm_ctl = level * max_pwm_blc / 100; - - /* Adjust the backlight level with the percent in - * dev_priv->blc_adj1; - */ - blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; - blc_pwm_ctl = blc_pwm_ctl / 100; - - /* Adjust the backlight level with the percent in - * dev_priv->blc_adj2; - */ - blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; - blc_pwm_ctl = blc_pwm_ctl / 100; - - /* force PWM bit on */ - REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); - REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); - gma_power_end(dev); - } - oaktrail_brightness = level; - return 0; -} - -static int oaktrail_get_brightness(struct backlight_device *bd) -{ - /* return locally cached var instead of HW read (due to DPST etc.) */ - /* FIXME: ideally return actual value in case firmware fiddled with - it */ - return oaktrail_brightness; -} - -static int device_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long core_clock; - u16 bl_max_freq; - uint32_t value; - uint32_t blc_pwm_precision_factor; - - dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; - dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; - bl_max_freq = 256; - /* this needs to be set elsewhere */ - blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR; - - core_clock = dev_priv->core_freq; - - value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; - value *= blc_pwm_precision_factor; - value /= bl_max_freq; - value /= blc_pwm_precision_factor; - - if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) - return -ERANGE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); - REG_WRITE(BLC_PWM_CTL, value | (value << 16)); - gma_power_end(dev); - } - return 0; -} - -static const struct backlight_ops oaktrail_ops = { - .get_brightness = oaktrail_get_brightness, - .update_status = oaktrail_set_brightness, -}; - -static int oaktrail_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - struct backlight_properties props; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = 100; - props.type = BACKLIGHT_PLATFORM; - - oaktrail_backlight_device = backlight_device_register("oaktrail-bl", - NULL, (void *)dev, &oaktrail_ops, &props); - - if (IS_ERR(oaktrail_backlight_device)) - return PTR_ERR(oaktrail_backlight_device); - - ret = device_backlight_init(dev); - if (ret < 0) { - backlight_device_unregister(oaktrail_backlight_device); - return ret; - } - oaktrail_backlight_device->props.brightness = 100; - oaktrail_backlight_device->props.max_brightness = 100; - backlight_update_status(oaktrail_backlight_device); - dev_priv->backlight_device = oaktrail_backlight_device; - return 0; -} - -#endif - -/* - * Provide the Moorestown specific chip logic and low level methods - * for power management - */ - -/** - * oaktrail_save_display_registers - save registers lost on suspend - * @dev: our DRM device - * - * Save the state we need in order to be able to restore the interface - * upon resume from suspend - */ -static int oaktrail_save_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_save_area *regs = &dev_priv->regs; - int i; - u32 pp_stat; - - /* Display arbitration control + watermarks */ - regs->psb.saveDSPARB = PSB_RVDC32(DSPARB); - regs->psb.saveDSPFW1 = PSB_RVDC32(DSPFW1); - regs->psb.saveDSPFW2 = PSB_RVDC32(DSPFW2); - regs->psb.saveDSPFW3 = PSB_RVDC32(DSPFW3); - regs->psb.saveDSPFW4 = PSB_RVDC32(DSPFW4); - regs->psb.saveDSPFW5 = PSB_RVDC32(DSPFW5); - regs->psb.saveDSPFW6 = PSB_RVDC32(DSPFW6); - regs->psb.saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); - - /* Pipe & plane A info */ - regs->psb.savePIPEACONF = PSB_RVDC32(PIPEACONF); - regs->psb.savePIPEASRC = PSB_RVDC32(PIPEASRC); - regs->psb.saveFPA0 = PSB_RVDC32(MRST_FPA0); - regs->psb.saveFPA1 = PSB_RVDC32(MRST_FPA1); - regs->psb.saveDPLL_A = PSB_RVDC32(MRST_DPLL_A); - regs->psb.saveHTOTAL_A = PSB_RVDC32(HTOTAL_A); - regs->psb.saveHBLANK_A = PSB_RVDC32(HBLANK_A); - regs->psb.saveHSYNC_A = PSB_RVDC32(HSYNC_A); - regs->psb.saveVTOTAL_A = PSB_RVDC32(VTOTAL_A); - regs->psb.saveVBLANK_A = PSB_RVDC32(VBLANK_A); - regs->psb.saveVSYNC_A = PSB_RVDC32(VSYNC_A); - regs->psb.saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A); - regs->psb.saveDSPACNTR = PSB_RVDC32(DSPACNTR); - regs->psb.saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE); - regs->psb.saveDSPAADDR = PSB_RVDC32(DSPABASE); - regs->psb.saveDSPASURF = PSB_RVDC32(DSPASURF); - regs->psb.saveDSPALINOFF = PSB_RVDC32(DSPALINOFF); - regs->psb.saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF); - - /* Save cursor regs */ - regs->psb.saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR); - regs->psb.saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE); - regs->psb.saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS); - - /* Save palette (gamma) */ - for (i = 0; i < 256; i++) - regs->psb.save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2)); - - if (dev_priv->hdmi_priv) - oaktrail_hdmi_save(dev); - - /* Save performance state */ - regs->psb.savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE); - - /* LVDS state */ - regs->psb.savePP_CONTROL = PSB_RVDC32(PP_CONTROL); - regs->psb.savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); - regs->psb.savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS); - regs->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL); - regs->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2); - regs->psb.saveLVDS = PSB_RVDC32(LVDS); - regs->psb.savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); - regs->psb.savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON); - regs->psb.savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF); - regs->psb.savePP_DIVISOR = PSB_RVDC32(PP_CYCLE); - - /* HW overlay */ - regs->psb.saveOV_OVADD = PSB_RVDC32(OV_OVADD); - regs->psb.saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0); - regs->psb.saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1); - regs->psb.saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2); - regs->psb.saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3); - regs->psb.saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4); - regs->psb.saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5); - - /* DPST registers */ - regs->psb.saveHISTOGRAM_INT_CONTROL_REG = - PSB_RVDC32(HISTOGRAM_INT_CONTROL); - regs->psb.saveHISTOGRAM_LOGIC_CONTROL_REG = - PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); - regs->psb.savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC); - - if (dev_priv->iLVDS_enable) { - /* Shut down the panel */ - PSB_WVDC32(0, PP_CONTROL); - - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x80000000); - - /* Turn off the plane */ - PSB_WVDC32(0x58000000, DSPACNTR); - /* Trigger the plane disable */ - PSB_WVDC32(0, DSPASURF); - - /* Wait ~4 ticks */ - msleep(4); - - /* Turn off pipe */ - PSB_WVDC32(0x0, PIPEACONF); - /* Wait ~8 ticks */ - msleep(8); - - /* Turn off PLLs */ - PSB_WVDC32(0, MRST_DPLL_A); - } - return 0; -} - -/** - * oaktrail_restore_display_registers - restore lost register state - * @dev: our DRM device - * - * Restore register state that was lost during suspend and resume. - */ -static int oaktrail_restore_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_save_area *regs = &dev_priv->regs; - u32 pp_stat; - int i; - - /* Display arbitration + watermarks */ - PSB_WVDC32(regs->psb.saveDSPARB, DSPARB); - PSB_WVDC32(regs->psb.saveDSPFW1, DSPFW1); - PSB_WVDC32(regs->psb.saveDSPFW2, DSPFW2); - PSB_WVDC32(regs->psb.saveDSPFW3, DSPFW3); - PSB_WVDC32(regs->psb.saveDSPFW4, DSPFW4); - PSB_WVDC32(regs->psb.saveDSPFW5, DSPFW5); - PSB_WVDC32(regs->psb.saveDSPFW6, DSPFW6); - PSB_WVDC32(regs->psb.saveCHICKENBIT, DSPCHICKENBIT); - - /* Make sure VGA plane is off. it initializes to on after reset!*/ - PSB_WVDC32(0x80000000, VGACNTRL); - - /* set the plls */ - PSB_WVDC32(regs->psb.saveFPA0, MRST_FPA0); - PSB_WVDC32(regs->psb.saveFPA1, MRST_FPA1); - - /* Actually enable it */ - PSB_WVDC32(regs->psb.saveDPLL_A, MRST_DPLL_A); - DRM_UDELAY(150); - - /* Restore mode */ - PSB_WVDC32(regs->psb.saveHTOTAL_A, HTOTAL_A); - PSB_WVDC32(regs->psb.saveHBLANK_A, HBLANK_A); - PSB_WVDC32(regs->psb.saveHSYNC_A, HSYNC_A); - PSB_WVDC32(regs->psb.saveVTOTAL_A, VTOTAL_A); - PSB_WVDC32(regs->psb.saveVBLANK_A, VBLANK_A); - PSB_WVDC32(regs->psb.saveVSYNC_A, VSYNC_A); - PSB_WVDC32(regs->psb.savePIPEASRC, PIPEASRC); - PSB_WVDC32(regs->psb.saveBCLRPAT_A, BCLRPAT_A); - - /* Restore performance mode*/ - PSB_WVDC32(regs->psb.savePERF_MODE, MRST_PERF_MODE); - - /* Enable the pipe*/ - if (dev_priv->iLVDS_enable) - PSB_WVDC32(regs->psb.savePIPEACONF, PIPEACONF); - - /* Set up the plane*/ - PSB_WVDC32(regs->psb.saveDSPALINOFF, DSPALINOFF); - PSB_WVDC32(regs->psb.saveDSPASTRIDE, DSPASTRIDE); - PSB_WVDC32(regs->psb.saveDSPATILEOFF, DSPATILEOFF); - - /* Enable the plane */ - PSB_WVDC32(regs->psb.saveDSPACNTR, DSPACNTR); - PSB_WVDC32(regs->psb.saveDSPASURF, DSPASURF); - - /* Enable Cursor A */ - PSB_WVDC32(regs->psb.saveDSPACURSOR_CTRL, CURACNTR); - PSB_WVDC32(regs->psb.saveDSPACURSOR_POS, CURAPOS); - PSB_WVDC32(regs->psb.saveDSPACURSOR_BASE, CURABASE); - - /* Restore palette (gamma) */ - for (i = 0; i < 256; i++) - PSB_WVDC32(regs->psb.save_palette_a[i], PALETTE_A + (i << 2)); - - if (dev_priv->hdmi_priv) - oaktrail_hdmi_restore(dev); - - if (dev_priv->iLVDS_enable) { - PSB_WVDC32(regs->saveBLC_PWM_CTL2, BLC_PWM_CTL2); - PSB_WVDC32(regs->psb.saveLVDS, LVDS); /*port 61180h*/ - PSB_WVDC32(regs->psb.savePFIT_CONTROL, PFIT_CONTROL); - PSB_WVDC32(regs->psb.savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); - PSB_WVDC32(regs->psb.savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS); - PSB_WVDC32(regs->saveBLC_PWM_CTL, BLC_PWM_CTL); - PSB_WVDC32(regs->psb.savePP_ON_DELAYS, LVDSPP_ON); - PSB_WVDC32(regs->psb.savePP_OFF_DELAYS, LVDSPP_OFF); - PSB_WVDC32(regs->psb.savePP_DIVISOR, PP_CYCLE); - PSB_WVDC32(regs->psb.savePP_CONTROL, PP_CONTROL); - } - - /* Wait for cycle delay */ - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x08000000); - - /* Wait for panel power up */ - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x10000000); - - /* Restore HW overlay */ - PSB_WVDC32(regs->psb.saveOV_OVADD, OV_OVADD); - PSB_WVDC32(regs->psb.saveOV_OGAMC0, OV_OGAMC0); - PSB_WVDC32(regs->psb.saveOV_OGAMC1, OV_OGAMC1); - PSB_WVDC32(regs->psb.saveOV_OGAMC2, OV_OGAMC2); - PSB_WVDC32(regs->psb.saveOV_OGAMC3, OV_OGAMC3); - PSB_WVDC32(regs->psb.saveOV_OGAMC4, OV_OGAMC4); - PSB_WVDC32(regs->psb.saveOV_OGAMC5, OV_OGAMC5); - - /* DPST registers */ - PSB_WVDC32(regs->psb.saveHISTOGRAM_INT_CONTROL_REG, - HISTOGRAM_INT_CONTROL); - PSB_WVDC32(regs->psb.saveHISTOGRAM_LOGIC_CONTROL_REG, - HISTOGRAM_LOGIC_CONTROL); - PSB_WVDC32(regs->psb.savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC); - - return 0; -} - -/** - * oaktrail_power_down - power down the display island - * @dev: our DRM device - * - * Power down the display interface of our device - */ -static int oaktrail_power_down(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_mask ; - u32 pwr_sts; - - pwr_mask = PSB_PWRGT_DISPLAY_MASK; - outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC); - - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == pwr_mask) - break; - else - udelay(10); - } - return 0; -} - -/* - * oaktrail_power_up - * - * Restore power to the specified island(s) (powergating) - */ -static int oaktrail_power_up(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK; - u32 pwr_sts, pwr_cnt; - - pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); - pwr_cnt &= ~pwr_mask; - outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); - - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == 0) - break; - else - udelay(10); - } - return 0; -} - - -static int oaktrail_chip_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_vbt *vbt = &dev_priv->vbt_data; - int ret; - - ret = mid_chip_setup(dev); - if (ret < 0) - return ret; - if (vbt->size == 0) { - /* Now pull the BIOS data */ - gma_intel_opregion_init(dev); - psb_intel_init_bios(dev); - } - return 0; -} - -static void oaktrail_teardown(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_vbt *vbt = &dev_priv->vbt_data; - - oaktrail_hdmi_teardown(dev); - if (vbt->size == 0) - psb_intel_destroy_bios(dev); -} - -const struct psb_ops oaktrail_chip_ops = { - .name = "Oaktrail", - .accel_2d = 1, - .pipes = 2, - .crtcs = 2, - .sgx_offset = MRST_SGX_OFFSET, - - .chip_setup = oaktrail_chip_setup, - .chip_teardown = oaktrail_teardown, - .crtc_helper = &oaktrail_helper_funcs, - .crtc_funcs = &psb_intel_crtc_funcs, - - .output_init = oaktrail_output_init, - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - .backlight_init = oaktrail_backlight_init, -#endif - - .save_regs = oaktrail_save_display_registers, - .restore_regs = oaktrail_restore_display_registers, - .power_down = oaktrail_power_down, - .power_up = oaktrail_power_up, - - .i2c_bus = 1, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi.c deleted file mode 100644 index f8b367b4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Li Peng - */ - -#include -#include -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_drv.h" - -#define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) -#define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) - -#define HDMI_HCR 0x1000 -#define HCR_ENABLE_HDCP (1 << 5) -#define HCR_ENABLE_AUDIO (1 << 2) -#define HCR_ENABLE_PIXEL (1 << 1) -#define HCR_ENABLE_TMDS (1 << 0) - -#define HDMI_HICR 0x1004 -#define HDMI_HSR 0x1008 -#define HDMI_HISR 0x100C -#define HDMI_DETECT_HDP (1 << 0) - -#define HDMI_VIDEO_REG 0x3000 -#define HDMI_UNIT_EN (1 << 7) -#define HDMI_MODE_OUTPUT (1 << 0) -#define HDMI_HBLANK_A 0x3100 - -#define HDMI_AUDIO_CTRL 0x4000 -#define HDMI_ENABLE_AUDIO (1 << 0) - -#define PCH_HTOTAL_B 0x3100 -#define PCH_HBLANK_B 0x3104 -#define PCH_HSYNC_B 0x3108 -#define PCH_VTOTAL_B 0x310C -#define PCH_VBLANK_B 0x3110 -#define PCH_VSYNC_B 0x3114 -#define PCH_PIPEBSRC 0x311C - -#define PCH_PIPEB_DSL 0x3800 -#define PCH_PIPEB_SLC 0x3804 -#define PCH_PIPEBCONF 0x3808 -#define PCH_PIPEBSTAT 0x3824 - -#define CDVO_DFT 0x5000 -#define CDVO_SLEWRATE 0x5004 -#define CDVO_STRENGTH 0x5008 -#define CDVO_RCOMP 0x500C - -#define DPLL_CTRL 0x6000 -#define DPLL_PDIV_SHIFT 16 -#define DPLL_PDIV_MASK (0xf << 16) -#define DPLL_PWRDN (1 << 4) -#define DPLL_RESET (1 << 3) -#define DPLL_FASTEN (1 << 2) -#define DPLL_ENSTAT (1 << 1) -#define DPLL_DITHEN (1 << 0) - -#define DPLL_DIV_CTRL 0x6004 -#define DPLL_CLKF_MASK 0xffffffc0 -#define DPLL_CLKR_MASK (0x3f) - -#define DPLL_CLK_ENABLE 0x6008 -#define DPLL_EN_DISP (1 << 31) -#define DPLL_SEL_HDMI (1 << 8) -#define DPLL_EN_HDMI (1 << 1) -#define DPLL_EN_VGA (1 << 0) - -#define DPLL_ADJUST 0x600C -#define DPLL_STATUS 0x6010 -#define DPLL_UPDATE 0x6014 -#define DPLL_DFT 0x6020 - -struct intel_range { - int min, max; -}; - -struct oaktrail_hdmi_limit { - struct intel_range vco, np, nr, nf; -}; - -struct oaktrail_hdmi_clock { - int np; - int nr; - int nf; - int dot; -}; - -#define VCO_MIN 320000 -#define VCO_MAX 1650000 -#define NP_MIN 1 -#define NP_MAX 15 -#define NR_MIN 1 -#define NR_MAX 64 -#define NF_MIN 2 -#define NF_MAX 4095 - -static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = { - .vco = { .min = VCO_MIN, .max = VCO_MAX }, - .np = { .min = NP_MIN, .max = NP_MAX }, - .nr = { .min = NR_MIN, .max = NR_MAX }, - .nf = { .min = NF_MIN, .max = NF_MAX }, -}; - -static void oaktrail_hdmi_audio_enable(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - - HDMI_WRITE(HDMI_HCR, 0x67); - HDMI_READ(HDMI_HCR); - - HDMI_WRITE(0x51a8, 0x10); - HDMI_READ(0x51a8); - - HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1); - HDMI_READ(HDMI_AUDIO_CTRL); -} - -static void oaktrail_hdmi_audio_disable(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - - HDMI_WRITE(0x51a8, 0x0); - HDMI_READ(0x51a8); - - HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0); - HDMI_READ(HDMI_AUDIO_CTRL); - - HDMI_WRITE(HDMI_HCR, 0x47); - HDMI_READ(HDMI_HCR); -} - -static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode) -{ - static int dpms_mode = -1; - - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - u32 temp; - - if (dpms_mode == mode) - return; - - if (mode != DRM_MODE_DPMS_ON) - temp = 0x0; - else - temp = 0x99; - - dpms_mode = mode; - HDMI_WRITE(HDMI_VIDEO_REG, temp); -} - -static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_psb_private *dev_priv = connector->dev->dev_private; - if (mode->clock > 165000) - return MODE_CLOCK_HIGH; - if (mode->clock < 20000) - return MODE_CLOCK_LOW; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* We assume worst case scenario of 32 bpp here, since we don't know */ - if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > - dev_priv->vram_stolen_size) - return MODE_MEM; - - return MODE_OK; -} - -static bool oaktrail_hdmi_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static enum drm_connector_status -oaktrail_hdmi_detect(struct drm_connector *connector, bool force) -{ - enum drm_connector_status status; - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - u32 temp; - - temp = HDMI_READ(HDMI_HSR); - DRM_DEBUG_KMS("HDMI_HSR %x\n", temp); - - if ((temp & HDMI_DETECT_HDP) != 0) - status = connector_status_connected; - else - status = connector_status_disconnected; - - return status; -} - -static const unsigned char raw_edid[] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0, - 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78, - 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5, - 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0, - 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35, - 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44, - 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20, - 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d -}; - -static int oaktrail_hdmi_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct i2c_adapter *i2c_adap; - struct edid *edid; - struct drm_display_mode *mode, *t; - int i = 0, ret = 0; - - i2c_adap = i2c_get_adapter(3); - if (i2c_adap == NULL) { - DRM_ERROR("No ddc adapter available!\n"); - edid = (struct edid *)raw_edid; - } else { - edid = (struct edid *)raw_edid; - /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */ - } - - if (edid) { - drm_mode_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - connector->display_info.raw_edid = NULL; - } - - /* - * prune modes that require frame buffer bigger than stolen mem - */ - list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { - if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) { - i++; - drm_mode_remove(connector, mode); - } - } - return ret - i; -} - -static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - - oaktrail_hdmi_audio_enable(dev); - return; -} - -static void oaktrail_hdmi_destroy(struct drm_connector *connector) -{ - return; -} - -static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = { - .dpms = oaktrail_hdmi_dpms, - .mode_fixup = oaktrail_hdmi_mode_fixup, - .prepare = psb_intel_encoder_prepare, - .mode_set = oaktrail_hdmi_mode_set, - .commit = psb_intel_encoder_commit, -}; - -static const struct drm_connector_helper_funcs - oaktrail_hdmi_connector_helper_funcs = { - .get_modes = oaktrail_hdmi_get_modes, - .mode_valid = oaktrail_hdmi_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = oaktrail_hdmi_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = oaktrail_hdmi_destroy, -}; - -static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = { - .destroy = oaktrail_hdmi_enc_destroy, -}; - -void oaktrail_hdmi_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct psb_intel_encoder *psb_intel_encoder; - struct psb_intel_connector *psb_intel_connector; - struct drm_connector *connector; - struct drm_encoder *encoder; - - psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); - if (!psb_intel_encoder) - return; - - psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); - if (!psb_intel_connector) - goto failed_connector; - - connector = &psb_intel_connector->base; - encoder = &psb_intel_encoder->base; - drm_connector_init(dev, connector, - &oaktrail_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_DVID); - - drm_encoder_init(dev, encoder, - &oaktrail_hdmi_enc_funcs, - DRM_MODE_ENCODER_TMDS); - - psb_intel_connector_attach_encoder(psb_intel_connector, - psb_intel_encoder); - - psb_intel_encoder->type = INTEL_OUTPUT_HDMI; - drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs); - drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs); - - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - drm_sysfs_connector_add(connector); - - return; - -failed_connector: - kfree(psb_intel_encoder); -} - -static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) }, - { 0 } -}; - -void oaktrail_hdmi_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct pci_dev *pdev; - struct oaktrail_hdmi_dev *hdmi_dev; - int ret; - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL); - if (!pdev) - return; - - hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL); - if (!hdmi_dev) { - dev_err(dev->dev, "failed to allocate memory\n"); - goto out; - } - - - ret = pci_enable_device(pdev); - if (ret) { - dev_err(dev->dev, "failed to enable hdmi controller\n"); - goto free; - } - - hdmi_dev->mmio = pci_resource_start(pdev, 0); - hdmi_dev->mmio_len = pci_resource_len(pdev, 0); - hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len); - if (!hdmi_dev->regs) { - dev_err(dev->dev, "failed to map hdmi mmio\n"); - goto free; - } - - hdmi_dev->dev = pdev; - pci_set_drvdata(pdev, hdmi_dev); - - /* Initialize i2c controller */ - ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev); - if (ret) - dev_err(dev->dev, "HDMI I2C initialization failed\n"); - - dev_priv->hdmi_priv = hdmi_dev; - oaktrail_hdmi_audio_disable(dev); - return; - -free: - kfree(hdmi_dev); -out: - return; -} - -void oaktrail_hdmi_teardown(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - struct pci_dev *pdev; - - if (hdmi_dev) { - pdev = hdmi_dev->dev; - pci_set_drvdata(pdev, NULL); - oaktrail_hdmi_i2c_exit(pdev); - iounmap(hdmi_dev->regs); - kfree(hdmi_dev); - pci_dev_put(pdev); - } -} - -/* save HDMI register state */ -void oaktrail_hdmi_save(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - struct psb_state *regs = &dev_priv->regs.psb; - int i; - - /* dpll */ - hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL); - hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL); - hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST); - hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE); - hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE); - - /* pipe B */ - regs->savePIPEBCONF = PSB_RVDC32(PIPEBCONF); - regs->savePIPEBSRC = PSB_RVDC32(PIPEBSRC); - regs->saveHTOTAL_B = PSB_RVDC32(HTOTAL_B); - regs->saveHBLANK_B = PSB_RVDC32(HBLANK_B); - regs->saveHSYNC_B = PSB_RVDC32(HSYNC_B); - regs->saveVTOTAL_B = PSB_RVDC32(VTOTAL_B); - regs->saveVBLANK_B = PSB_RVDC32(VBLANK_B); - regs->saveVSYNC_B = PSB_RVDC32(VSYNC_B); - - hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF); - hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC); - hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B); - hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B); - hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B); - hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B); - hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B); - hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B); - - /* plane */ - regs->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR); - regs->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE); - regs->saveDSPBADDR = PSB_RVDC32(DSPBBASE); - regs->saveDSPBSURF = PSB_RVDC32(DSPBSURF); - regs->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF); - regs->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF); - - /* cursor B */ - regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); - regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE); - regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS); - - /* save palette */ - for (i = 0; i < 256; i++) - regs->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2)); -} - -/* restore HDMI register state */ -void oaktrail_hdmi_restore(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; - struct psb_state *regs = &dev_priv->regs.psb; - int i; - - /* dpll */ - PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL); - PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL); - PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST); - PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE); - PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE); - DRM_UDELAY(150); - - /* pipe */ - PSB_WVDC32(regs->savePIPEBSRC, PIPEBSRC); - PSB_WVDC32(regs->saveHTOTAL_B, HTOTAL_B); - PSB_WVDC32(regs->saveHBLANK_B, HBLANK_B); - PSB_WVDC32(regs->saveHSYNC_B, HSYNC_B); - PSB_WVDC32(regs->saveVTOTAL_B, VTOTAL_B); - PSB_WVDC32(regs->saveVBLANK_B, VBLANK_B); - PSB_WVDC32(regs->saveVSYNC_B, VSYNC_B); - - PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC); - PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B); - PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B); - PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B); - PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B); - PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B); - PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B); - - PSB_WVDC32(regs->savePIPEBCONF, PIPEBCONF); - PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF); - - /* plane */ - PSB_WVDC32(regs->saveDSPBLINOFF, DSPBLINOFF); - PSB_WVDC32(regs->saveDSPBSTRIDE, DSPBSTRIDE); - PSB_WVDC32(regs->saveDSPBTILEOFF, DSPBTILEOFF); - PSB_WVDC32(regs->saveDSPBCNTR, DSPBCNTR); - PSB_WVDC32(regs->saveDSPBSURF, DSPBSURF); - - /* cursor B */ - PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR); - PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS); - PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE); - - /* restore palette */ - for (i = 0; i < 256; i++) - PSB_WVDC32(regs->save_palette_b[i], PALETTE_B + (i << 2)); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c deleted file mode 100644 index 5e84fbde..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Li Peng - */ - -#include -#include -#include -#include -#include -#include -#include "psb_drv.h" - -#define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) -#define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) - -#define HDMI_HCR 0x1000 -#define HCR_DETECT_HDP (1 << 6) -#define HCR_ENABLE_HDCP (1 << 5) -#define HCR_ENABLE_AUDIO (1 << 2) -#define HCR_ENABLE_PIXEL (1 << 1) -#define HCR_ENABLE_TMDS (1 << 0) -#define HDMI_HICR 0x1004 -#define HDMI_INTR_I2C_ERROR (1 << 4) -#define HDMI_INTR_I2C_FULL (1 << 3) -#define HDMI_INTR_I2C_DONE (1 << 2) -#define HDMI_INTR_HPD (1 << 0) -#define HDMI_HSR 0x1008 -#define HDMI_HISR 0x100C -#define HDMI_HI2CRDB0 0x1200 -#define HDMI_HI2CHCR 0x1240 -#define HI2C_HDCP_WRITE (0 << 2) -#define HI2C_HDCP_RI_READ (1 << 2) -#define HI2C_HDCP_READ (2 << 2) -#define HI2C_EDID_READ (3 << 2) -#define HI2C_READ_CONTINUE (1 << 1) -#define HI2C_ENABLE_TRANSACTION (1 << 0) - -#define HDMI_ICRH 0x1100 -#define HDMI_HI2CTDR0 0x1244 -#define HDMI_HI2CTDR1 0x1248 - -#define I2C_STAT_INIT 0 -#define I2C_READ_DONE 1 -#define I2C_TRANSACTION_DONE 2 - -struct hdmi_i2c_dev { - struct i2c_adapter *adap; - struct mutex i2c_lock; - struct completion complete; - int status; - struct i2c_msg *msg; - int buf_offset; -}; - -static void hdmi_i2c_irq_enable(struct oaktrail_hdmi_dev *hdmi_dev) -{ - u32 temp; - - temp = HDMI_READ(HDMI_HICR); - temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE); - HDMI_WRITE(HDMI_HICR, temp); - HDMI_READ(HDMI_HICR); -} - -static void hdmi_i2c_irq_disable(struct oaktrail_hdmi_dev *hdmi_dev) -{ - HDMI_WRITE(HDMI_HICR, 0x0); - HDMI_READ(HDMI_HICR); -} - -static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg) -{ - struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap); - struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; - u32 temp; - - i2c_dev->status = I2C_STAT_INIT; - i2c_dev->msg = pmsg; - i2c_dev->buf_offset = 0; - INIT_COMPLETION(i2c_dev->complete); - - /* Enable I2C transaction */ - temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION; - HDMI_WRITE(HDMI_HI2CHCR, temp); - HDMI_READ(HDMI_HI2CHCR); - - while (i2c_dev->status != I2C_TRANSACTION_DONE) - wait_for_completion_interruptible_timeout(&i2c_dev->complete, - 10 * HZ); - - return 0; -} - -static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg) -{ - /* - * XXX: i2c write seems isn't useful for EDID probe, don't do anything - */ - return 0; -} - -static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap, - struct i2c_msg *pmsg, - int num) -{ - struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap); - struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; - int i; - - mutex_lock(&i2c_dev->i2c_lock); - - /* Enable i2c unit */ - HDMI_WRITE(HDMI_ICRH, 0x00008760); - - /* Enable irq */ - hdmi_i2c_irq_enable(hdmi_dev); - for (i = 0; i < num; i++) { - if (pmsg->len && pmsg->buf) { - if (pmsg->flags & I2C_M_RD) - xfer_read(adap, pmsg); - else - xfer_write(adap, pmsg); - } - pmsg++; /* next message */ - } - - /* Disable irq */ - hdmi_i2c_irq_disable(hdmi_dev); - - mutex_unlock(&i2c_dev->i2c_lock); - - return i; -} - -static u32 oaktrail_hdmi_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; -} - -static const struct i2c_algorithm oaktrail_hdmi_i2c_algorithm = { - .master_xfer = oaktrail_hdmi_i2c_access, - .functionality = oaktrail_hdmi_i2c_func, -}; - -static struct i2c_adapter oaktrail_hdmi_i2c_adapter = { - .name = "oaktrail_hdmi_i2c", - .nr = 3, - .owner = THIS_MODULE, - .class = I2C_CLASS_DDC, - .algo = &oaktrail_hdmi_i2c_algorithm, -}; - -static void hdmi_i2c_read(struct oaktrail_hdmi_dev *hdmi_dev) -{ - struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; - struct i2c_msg *msg = i2c_dev->msg; - u8 *buf = msg->buf; - u32 temp; - int i, offset; - - offset = i2c_dev->buf_offset; - for (i = 0; i < 0x10; i++) { - temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4)); - memcpy(buf + (offset + i * 4), &temp, 4); - } - i2c_dev->buf_offset += (0x10 * 4); - - /* clearing read buffer full intr */ - temp = HDMI_READ(HDMI_HISR); - HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL); - HDMI_READ(HDMI_HISR); - - /* continue read transaction */ - temp = HDMI_READ(HDMI_HI2CHCR); - HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE); - HDMI_READ(HDMI_HI2CHCR); - - i2c_dev->status = I2C_READ_DONE; - return; -} - -static void hdmi_i2c_transaction_done(struct oaktrail_hdmi_dev *hdmi_dev) -{ - struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; - u32 temp; - - /* clear transaction done intr */ - temp = HDMI_READ(HDMI_HISR); - HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE); - HDMI_READ(HDMI_HISR); - - - temp = HDMI_READ(HDMI_HI2CHCR); - HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION); - HDMI_READ(HDMI_HI2CHCR); - - i2c_dev->status = I2C_TRANSACTION_DONE; - return; -} - -static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev) -{ - struct oaktrail_hdmi_dev *hdmi_dev = dev; - struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; - u32 stat; - - stat = HDMI_READ(HDMI_HISR); - - if (stat & HDMI_INTR_HPD) { - HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD); - HDMI_READ(HDMI_HISR); - } - - if (stat & HDMI_INTR_I2C_FULL) - hdmi_i2c_read(hdmi_dev); - - if (stat & HDMI_INTR_I2C_DONE) - hdmi_i2c_transaction_done(hdmi_dev); - - complete(&i2c_dev->complete); - - return IRQ_HANDLED; -} - -/* - * choose alternate function 2 of GPIO pin 52, 53, - * which is used by HDMI I2C logic - */ -static void oaktrail_hdmi_i2c_gpio_fix(void) -{ - void *base; - unsigned int gpio_base = 0xff12c000; - int gpio_len = 0x1000; - u32 temp; - - base = ioremap((resource_size_t)gpio_base, gpio_len); - if (base == NULL) { - DRM_ERROR("gpio ioremap fail\n"); - return; - } - - temp = readl(base + 0x44); - DRM_DEBUG_DRIVER("old gpio val %x\n", temp); - writel((temp | 0x00000a00), (base + 0x44)); - temp = readl(base + 0x44); - DRM_DEBUG_DRIVER("new gpio val %x\n", temp); - - iounmap(base); -} - -int oaktrail_hdmi_i2c_init(struct pci_dev *dev) -{ - struct oaktrail_hdmi_dev *hdmi_dev; - struct hdmi_i2c_dev *i2c_dev; - int ret; - - hdmi_dev = pci_get_drvdata(dev); - - i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL); - if (i2c_dev == NULL) { - DRM_ERROR("Can't allocate interface\n"); - ret = -ENOMEM; - goto exit; - } - - i2c_dev->adap = &oaktrail_hdmi_i2c_adapter; - i2c_dev->status = I2C_STAT_INIT; - init_completion(&i2c_dev->complete); - mutex_init(&i2c_dev->i2c_lock); - i2c_set_adapdata(&oaktrail_hdmi_i2c_adapter, hdmi_dev); - hdmi_dev->i2c_dev = i2c_dev; - - /* Enable HDMI I2C function on gpio */ - oaktrail_hdmi_i2c_gpio_fix(); - - /* request irq */ - ret = request_irq(dev->irq, oaktrail_hdmi_i2c_handler, IRQF_SHARED, - oaktrail_hdmi_i2c_adapter.name, hdmi_dev); - if (ret) { - DRM_ERROR("Failed to request IRQ for I2C controller\n"); - goto err; - } - - /* Adapter registration */ - ret = i2c_add_numbered_adapter(&oaktrail_hdmi_i2c_adapter); - return ret; - -err: - kfree(i2c_dev); -exit: - return ret; -} - -void oaktrail_hdmi_i2c_exit(struct pci_dev *dev) -{ - struct oaktrail_hdmi_dev *hdmi_dev; - struct hdmi_i2c_dev *i2c_dev; - - hdmi_dev = pci_get_drvdata(dev); - if (i2c_del_adapter(&oaktrail_hdmi_i2c_adapter)) - DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n"); - - i2c_dev = hdmi_dev->i2c_dev; - kfree(i2c_dev); - free_irq(dev->irq, hdmi_dev); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_lvds.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_lvds.c deleted file mode 100644 index 654f32b2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright © 2006-2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - * Dave Airlie - * Jesse Barnes - */ - -#include -#include -#include - -#include "intel_bios.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "power.h" -#include - -/* The max/min PWM frequency in BPCR[31:17] - */ -/* The smallest number is 1 (not 0) that can fit in the - * 15-bit field of the and then*/ -/* shifts to the left by one bit to get the actual 16-bit - * value that the 15-bits correspond to.*/ -#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF -#define BRIGHTNESS_MAX_LEVEL 100 - -/** - * Sets the power state for the panel. - */ -static void oaktrail_lvds_set_power(struct drm_device *dev, - struct psb_intel_encoder *psb_intel_encoder, - bool on) -{ - u32 pp_status; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!gma_power_begin(dev, true)) - return; - - if (on) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); - dev_priv->is_lvds_on = true; - if (dev_priv->ops->lvds_bl_power) - dev_priv->ops->lvds_bl_power(dev, true); - } else { - if (dev_priv->ops->lvds_bl_power) - dev_priv->ops->lvds_bl_power(dev, false); - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - dev_priv->is_lvds_on = false; - pm_request_idle(&dev->pdev->dev); - } - gma_power_end(dev); -} - -static void oaktrail_lvds_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_encoder *psb_intel_encoder = - to_psb_intel_encoder(encoder); - - if (mode == DRM_MODE_DPMS_ON) - oaktrail_lvds_set_power(dev, psb_intel_encoder, true); - else - oaktrail_lvds_set_power(dev, psb_intel_encoder, false); - - /* XXX: We never power down the LVDS pairs. */ -} - -static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector = NULL; - struct drm_crtc *crtc = encoder->crtc; - u32 lvds_port; - uint64_t v = DRM_MODE_SCALE_FULLSCREEN; - - if (!gma_power_begin(dev, true)) - return; - - /* - * The LVDS pin pair will already have been turned on in the - * psb_intel_crtc_mode_set since it has a large impact on the DPLL - * settings. - */ - lvds_port = (REG_READ(LVDS) & - (~LVDS_PIPEB_SELECT)) | - LVDS_PORT_EN | - LVDS_BORDER_EN; - - /* If the firmware says dither on Moorestown, or the BIOS does - on Oaktrail then enable dithering */ - if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) - lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; - - REG_WRITE(LVDS, lvds_port); - - /* Find the connector we're trying to set up */ - list_for_each_entry(connector, &mode_config->connector_list, head) { - if (!connector->encoder || connector->encoder->crtc != crtc) - continue; - } - - if (!connector) { - DRM_ERROR("Couldn't find connector when setting mode"); - return; - } - - drm_connector_property_get_value( - connector, - dev->mode_config.scaling_mode_property, - &v); - - if (v == DRM_MODE_SCALE_NO_SCALE) - REG_WRITE(PFIT_CONTROL, 0); - else if (v == DRM_MODE_SCALE_ASPECT) { - if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || - (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { - if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == - (mode->hdisplay * adjusted_mode->crtc_vdisplay)) - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - else if ((adjusted_mode->crtc_hdisplay * - mode->vdisplay) > (mode->hdisplay * - adjusted_mode->crtc_vdisplay)) - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | - PFIT_SCALING_MODE_PILLARBOX); - else - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | - PFIT_SCALING_MODE_LETTERBOX); - } else - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ - REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); - - gma_power_end(dev); -} - -static void oaktrail_lvds_prepare(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_encoder *psb_intel_encoder = - to_psb_intel_encoder(encoder); - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - - if (!gma_power_begin(dev, true)) - return; - - mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - oaktrail_lvds_set_power(dev, psb_intel_encoder, false); - gma_power_end(dev); -} - -static u32 oaktrail_lvds_get_max_backlight(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 ret; - - if (gma_power_begin(dev, false)) { - ret = ((REG_READ(BLC_PWM_CTL) & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - gma_power_end(dev); - } else - ret = ((dev_priv->regs.saveBLC_PWM_CTL & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - return ret; -} - -static void oaktrail_lvds_commit(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_encoder *psb_intel_encoder = - to_psb_intel_encoder(encoder); - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - - if (mode_dev->backlight_duty_cycle == 0) - mode_dev->backlight_duty_cycle = - oaktrail_lvds_get_max_backlight(dev); - oaktrail_lvds_set_power(dev, psb_intel_encoder, true); -} - -static const struct drm_encoder_helper_funcs oaktrail_lvds_helper_funcs = { - .dpms = oaktrail_lvds_dpms, - .mode_fixup = psb_intel_lvds_mode_fixup, - .prepare = oaktrail_lvds_prepare, - .mode_set = oaktrail_lvds_mode_set, - .commit = oaktrail_lvds_commit, -}; - -static struct drm_display_mode lvds_configuration_modes[] = { - /* hard coded fixed mode for TPO LTPS LPJ040K001A */ - { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 33264, 800, 836, - 846, 1056, 0, 480, 489, 491, 525, 0, 0) }, - /* hard coded fixed mode for LVDS 800x480 */ - { DRM_MODE("800x480", DRM_MODE_TYPE_DRIVER, 30994, 800, 801, - 802, 1024, 0, 480, 481, 482, 525, 0, 0) }, - /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ - { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072, - 1104, 1184, 0, 600, 603, 604, 608, 0, 0) }, - /* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */ - { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104, - 1136, 1184, 0, 600, 603, 604, 608, 0, 0) }, - /* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */ - { DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124, - 1204, 1312, 0, 600, 607, 610, 621, 0, 0) }, - /* hard coded fixed mode for LVDS 1024x768 */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, 0) }, - /* hard coded fixed mode for LVDS 1366x768 */ - { DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430, - 1558, 1664, 0, 768, 769, 770, 776, 0, 0) }, -}; - -/* Returns the panel fixed mode from configuration. */ - -static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct drm_display_mode *mode = NULL; - struct drm_psb_private *dev_priv = dev->dev_private; - struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; - - mode_dev->panel_fixed_mode = NULL; - - /* Use the firmware provided data on Moorestown */ - if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return; - - mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; - mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; - mode->hsync_start = mode->hdisplay + \ - ((ti->hsync_offset_hi << 8) | \ - ti->hsync_offset_lo); - mode->hsync_end = mode->hsync_start + \ - ((ti->hsync_pulse_width_hi << 8) | \ - ti->hsync_pulse_width_lo); - mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ - ti->hblank_lo); - mode->vsync_start = \ - mode->vdisplay + ((ti->vsync_offset_hi << 4) | \ - ti->vsync_offset_lo); - mode->vsync_end = \ - mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \ - ti->vsync_pulse_width_lo); - mode->vtotal = mode->vdisplay + \ - ((ti->vblank_hi << 8) | ti->vblank_lo); - mode->clock = ti->pixel_clock * 10; -#if 0 - printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay); - printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay); - printk(KERN_INFO "HSS is %d\n", mode->hsync_start); - printk(KERN_INFO "HSE is %d\n", mode->hsync_end); - printk(KERN_INFO "htotal is %d\n", mode->htotal); - printk(KERN_INFO "VSS is %d\n", mode->vsync_start); - printk(KERN_INFO "VSE is %d\n", mode->vsync_end); - printk(KERN_INFO "vtotal is %d\n", mode->vtotal); - printk(KERN_INFO "clock is %d\n", mode->clock); -#endif - mode_dev->panel_fixed_mode = mode; - } - - /* Use the BIOS VBT mode if available */ - if (mode_dev->panel_fixed_mode == NULL && mode_dev->vbt_mode) - mode_dev->panel_fixed_mode = drm_mode_duplicate(dev, - mode_dev->vbt_mode); - - /* Then try the LVDS VBT mode */ - if (mode_dev->panel_fixed_mode == NULL) - if (dev_priv->lfp_lvds_vbt_mode) - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, - dev_priv->lfp_lvds_vbt_mode); - /* Then guess */ - if (mode_dev->panel_fixed_mode == NULL) - mode_dev->panel_fixed_mode - = drm_mode_duplicate(dev, &lvds_configuration_modes[2]); - - drm_mode_set_name(mode_dev->panel_fixed_mode); - drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0); -} - -/** - * oaktrail_lvds_init - setup LVDS connectors on this device - * @dev: drm device - * - * Create the connector, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -void oaktrail_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct psb_intel_encoder *psb_intel_encoder; - struct psb_intel_connector *psb_intel_connector; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct drm_psb_private *dev_priv = dev->dev_private; - struct edid *edid; - struct i2c_adapter *i2c_adap; - struct drm_display_mode *scan; /* *modes, *bios_mode; */ - - psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); - if (!psb_intel_encoder) - return; - - psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); - if (!psb_intel_connector) - goto failed_connector; - - connector = &psb_intel_connector->base; - encoder = &psb_intel_encoder->base; - dev_priv->is_lvds_on = true; - drm_connector_init(dev, connector, - &psb_intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - - drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS); - - psb_intel_connector_attach_encoder(psb_intel_connector, - psb_intel_encoder); - psb_intel_encoder->type = INTEL_OUTPUT_LVDS; - - drm_encoder_helper_add(encoder, &oaktrail_lvds_helper_funcs); - drm_connector_helper_add(connector, - &psb_intel_lvds_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, - dev_priv->backlight_property, - BRIGHTNESS_MAX_LEVEL); - - mode_dev->panel_wants_dither = false; - if (dev_priv->vbt_data.size != 0x00) - mode_dev->panel_wants_dither = (dev_priv->gct_data. - Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); - if (dev_priv->lvds_dither) - mode_dev->panel_wants_dither = 1; - - /* - * LVDS discovery: - * 1) check for EDID on DDC - * 2) check for VBT data - * 3) check to see if LVDS is already on - * if none of the above, no panel - * 4) make sure lid is open - * if closed, act like it's not there for now - */ - - i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus); - if (i2c_adap == NULL) - dev_err(dev->dev, "No ddc adapter available!\n"); - /* - * Attempt to get the fixed panel mode from DDC. Assume that the - * preferred mode is the right one. - */ - if (i2c_adap) { - edid = drm_get_edid(connector, i2c_adap); - if (edid) { - drm_mode_connector_update_edid_property(connector, - edid); - drm_add_edid_modes(connector, edid); - kfree(edid); - } - - list_for_each_entry(scan, &connector->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) { - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, scan); - goto out; /* FIXME: check for quirks */ - } - } - } - /* - * If we didn't get EDID, try geting panel timing - * from configuration data - */ - oaktrail_lvds_get_configuration_mode(dev, mode_dev); - - if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; - goto out; /* FIXME: check for quirks */ - } - - /* If we still don't have a mode after all that, give up. */ - if (!mode_dev->panel_fixed_mode) { - dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); - goto failed_find; - } - -out: - drm_sysfs_connector_add(connector); - return; - -failed_find: - dev_dbg(dev->dev, "No LVDS modes found, disabling.\n"); - if (psb_intel_encoder->ddc_bus) - psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus); - -/* failed_ddc: */ - - drm_encoder_cleanup(encoder); - drm_connector_cleanup(connector); - kfree(psb_intel_connector); -failed_connector: - kfree(psb_intel_encoder); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/power.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/power.c deleted file mode 100644 index 889b8547..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/power.c +++ /dev/null @@ -1,315 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009-2011, Intel Corporation. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Benjamin Defnet - * Rajesh Poornachandran - * Massively reworked - * Alan Cox - */ - -#include "power.h" -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include -#include - -static struct mutex power_mutex; /* Serialize power ops */ -static spinlock_t power_ctrl_lock; /* Serialize power claim */ - -/** - * gma_power_init - initialise power manager - * @dev: our device - * - * Set up for power management tracking of our hardware. - */ -void gma_power_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - /* FIXME: Move APM/OSPM base into relevant device code */ - dev_priv->apm_base = dev_priv->apm_reg & 0xffff; - dev_priv->ospm_base &= 0xffff; - - dev_priv->display_power = true; /* We start active */ - dev_priv->display_count = 0; /* Currently no users */ - dev_priv->suspended = false; /* And not suspended */ - spin_lock_init(&power_ctrl_lock); - mutex_init(&power_mutex); - - if (dev_priv->ops->init_pm) - dev_priv->ops->init_pm(dev); -} - -/** - * gma_power_uninit - end power manager - * @dev: device to end for - * - * Undo the effects of gma_power_init - */ -void gma_power_uninit(struct drm_device *dev) -{ - pm_runtime_disable(&dev->pdev->dev); - pm_runtime_set_suspended(&dev->pdev->dev); -} - -/** - * gma_suspend_display - suspend the display logic - * @dev: our DRM device - * - * Suspend the display logic of the graphics interface - */ -static void gma_suspend_display(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - if (dev_priv->suspended) - return; - dev_priv->ops->save_regs(dev); - dev_priv->ops->power_down(dev); - dev_priv->display_power = false; -} - -/** - * gma_resume_display - resume display side logic - * - * Resume the display hardware restoring state and enabling - * as necessary. - */ -static void gma_resume_display(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - - /* turn on the display power island */ - dev_priv->ops->power_up(dev); - dev_priv->suspended = false; - dev_priv->display_power = true; - - PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); - pci_write_config_word(pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); - dev_priv->ops->restore_regs(dev); -} - -/** - * gma_suspend_pci - suspend PCI side - * @pdev: PCI device - * - * Perform the suspend processing on our PCI device state - */ -static void gma_suspend_pci(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - int bsm, vbt; - - if (dev_priv->suspended) - return; - - pci_save_state(pdev); - pci_read_config_dword(pdev, 0x5C, &bsm); - dev_priv->regs.saveBSM = bsm; - pci_read_config_dword(pdev, 0xFC, &vbt); - dev_priv->regs.saveVBT = vbt; - pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr); - pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data); - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - dev_priv->suspended = true; -} - -/** - * gma_resume_pci - resume helper - * @dev: our PCI device - * - * Perform the resume processing on our PCI device state - rewrite - * register state and re-enable the PCI device - */ -static bool gma_resume_pci(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - - if (!dev_priv->suspended) - return true; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - pci_write_config_dword(pdev, 0x5c, dev_priv->regs.saveBSM); - pci_write_config_dword(pdev, 0xFC, dev_priv->regs.saveVBT); - /* restoring MSI address and data in PCIx space */ - pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr); - pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data); - ret = pci_enable_device(pdev); - - if (ret != 0) - dev_err(&pdev->dev, "pci_enable failed: %d\n", ret); - else - dev_priv->suspended = false; - return !dev_priv->suspended; -} - -/** - * gma_power_suspend - bus callback for suspend - * @pdev: our PCI device - * @state: suspend type - * - * Called back by the PCI layer during a suspend of the system. We - * perform the necessary shut down steps and save enough state that - * we can undo this when resume is called. - */ -int gma_power_suspend(struct device *_dev) -{ - struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev); - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_psb_private *dev_priv = dev->dev_private; - - mutex_lock(&power_mutex); - if (!dev_priv->suspended) { - if (dev_priv->display_count) { - mutex_unlock(&power_mutex); - dev_err(dev->dev, "GPU hardware busy, cannot suspend\n"); - return -EBUSY; - } - psb_irq_uninstall(dev); - gma_suspend_display(dev); - gma_suspend_pci(pdev); - } - mutex_unlock(&power_mutex); - return 0; -} - -/** - * gma_power_resume - resume power - * @pdev: PCI device - * - * Resume the PCI side of the graphics and then the displays - */ -int gma_power_resume(struct device *_dev) -{ - struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev); - struct drm_device *dev = pci_get_drvdata(pdev); - - mutex_lock(&power_mutex); - gma_resume_pci(pdev); - gma_resume_display(pdev); - psb_irq_preinstall(dev); - psb_irq_postinstall(dev); - mutex_unlock(&power_mutex); - return 0; -} - -/** - * gma_power_is_on - returne true if power is on - * @dev: our DRM device - * - * Returns true if the display island power is on at this moment - */ -bool gma_power_is_on(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - return dev_priv->display_power; -} - -/** - * gma_power_begin - begin requiring power - * @dev: our DRM device - * @force_on: true to force power on - * - * Begin an action that requires the display power island is enabled. - * We refcount the islands. - */ -bool gma_power_begin(struct drm_device *dev, bool force_on) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - unsigned long flags; - - spin_lock_irqsave(&power_ctrl_lock, flags); - /* Power already on ? */ - if (dev_priv->display_power) { - dev_priv->display_count++; - pm_runtime_get(&dev->pdev->dev); - spin_unlock_irqrestore(&power_ctrl_lock, flags); - return true; - } - if (force_on == false) - goto out_false; - - /* Ok power up needed */ - ret = gma_resume_pci(dev->pdev); - if (ret == 0) { - psb_irq_preinstall(dev); - psb_irq_postinstall(dev); - pm_runtime_get(&dev->pdev->dev); - dev_priv->display_count++; - spin_unlock_irqrestore(&power_ctrl_lock, flags); - return true; - } -out_false: - spin_unlock_irqrestore(&power_ctrl_lock, flags); - return false; -} - -/** - * gma_power_end - end use of power - * @dev: Our DRM device - * - * Indicate that one of our gma_power_begin() requested periods when - * the diplay island power is needed has completed. - */ -void gma_power_end(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long flags; - spin_lock_irqsave(&power_ctrl_lock, flags); - dev_priv->display_count--; - WARN_ON(dev_priv->display_count < 0); - spin_unlock_irqrestore(&power_ctrl_lock, flags); - pm_runtime_put(&dev->pdev->dev); -} - -int psb_runtime_suspend(struct device *dev) -{ - return gma_power_suspend(dev); -} - -int psb_runtime_resume(struct device *dev) -{ - return gma_power_resume(dev); -} - -int psb_runtime_idle(struct device *dev) -{ - struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev)); - struct drm_psb_private *dev_priv = drmdev->dev_private; - if (dev_priv->display_count) - return 0; - else - return 1; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/power.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/power.h deleted file mode 100644 index 1969d2ec..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/power.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009-2011, Intel Corporation. - * All Rights Reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Benjamin Defnet - * Rajesh Poornachandran - * Massively reworked - * Alan Cox - */ -#ifndef _PSB_POWERMGMT_H_ -#define _PSB_POWERMGMT_H_ - -#include -#include - -void gma_power_init(struct drm_device *dev); -void gma_power_uninit(struct drm_device *dev); - -/* - * The kernel bus power management will call these functions - */ -int gma_power_suspend(struct device *dev); -int gma_power_resume(struct device *dev); - -/* - * These are the functions the driver should use to wrap all hw access - * (i.e. register reads and writes) - */ -bool gma_power_begin(struct drm_device *dev, bool force); -void gma_power_end(struct drm_device *dev); - -/* - * Use this function to do an instantaneous check for if the hw is on. - * Only use this in cases where you know the mutex is already held such - * as in irq install/uninstall and you need to - * prevent a deadlock situation. Otherwise use gma_power_begin(). - */ -bool gma_power_is_on(struct drm_device *dev); - -/* - * GFX-Runtime PM callbacks - */ -int psb_runtime_suspend(struct device *dev); -int psb_runtime_resume(struct device *dev); -int psb_runtime_idle(struct device *dev); - -#endif /*_PSB_POWERMGMT_H_*/ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_device.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_device.c deleted file mode 100644 index 328a1930..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_device.c +++ /dev/null @@ -1,332 +0,0 @@ -/************************************************************************** - * Copyright (c) 2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include "intel_bios.h" - - -static int psb_output_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - psb_intel_lvds_init(dev, &dev_priv->mode_dev); - psb_intel_sdvo_init(dev, SDVOB); - return 0; -} - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - -/* - * Poulsbo Backlight Interfaces - */ - -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 - -#define PSB_BLC_PWM_PRECISION_FACTOR 10 -#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE -#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 - -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) - -static int psb_brightness; -static struct backlight_device *psb_backlight_device; - -static int psb_get_brightness(struct backlight_device *bd) -{ - /* return locally cached var instead of HW read (due to DPST etc.) */ - /* FIXME: ideally return actual value in case firmware fiddled with - it */ - return psb_brightness; -} - - -static int psb_backlight_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long core_clock; - /* u32 bl_max_freq; */ - /* unsigned long value; */ - u16 bl_max_freq; - uint32_t value; - uint32_t blc_pwm_precision_factor; - - /* get bl_max_freq and pol from dev_priv*/ - if (!dev_priv->lvds_bl) { - dev_err(dev->dev, "Has no valid LVDS backlight info\n"); - return -ENOENT; - } - bl_max_freq = dev_priv->lvds_bl->freq; - blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; - - core_clock = dev_priv->core_freq; - - value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; - value *= blc_pwm_precision_factor; - value /= bl_max_freq; - value /= blc_pwm_precision_factor; - - if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || - value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) - return -ERANGE; - else { - value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value)); - } - return 0; -} - -static int psb_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(psb_backlight_device); - int level = bd->props.brightness; - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - psb_intel_lvds_set_brightness(dev, level); - psb_brightness = level; - return 0; -} - -static const struct backlight_ops psb_ops = { - .get_brightness = psb_get_brightness, - .update_status = psb_set_brightness, -}; - -static int psb_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - int ret; - struct backlight_properties props; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = 100; - props.type = BACKLIGHT_PLATFORM; - - psb_backlight_device = backlight_device_register("psb-bl", - NULL, (void *)dev, &psb_ops, &props); - if (IS_ERR(psb_backlight_device)) - return PTR_ERR(psb_backlight_device); - - ret = psb_backlight_setup(dev); - if (ret < 0) { - backlight_device_unregister(psb_backlight_device); - psb_backlight_device = NULL; - return ret; - } - psb_backlight_device->props.brightness = 100; - psb_backlight_device->props.max_brightness = 100; - backlight_update_status(psb_backlight_device); - dev_priv->backlight_device = psb_backlight_device; - return 0; -} - -#endif - -/* - * Provide the Poulsbo specific chip logic and low level methods - * for power management - */ - -static void psb_init_pm(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL); - gating &= ~3; /* Disable 2D clock gating */ - gating |= 1; - PSB_WSGX32(gating, PSB_CR_CLKGATECTL); - PSB_RSGX32(PSB_CR_CLKGATECTL); -} - -/** - * psb_save_display_registers - save registers lost on suspend - * @dev: our DRM device - * - * Save the state we need in order to be able to restore the interface - * upon resume from suspend - */ -static int psb_save_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_connector *connector; - struct psb_state *regs = &dev_priv->regs.psb; - - /* Display arbitration control + watermarks */ - regs->saveDSPARB = PSB_RVDC32(DSPARB); - regs->saveDSPFW1 = PSB_RVDC32(DSPFW1); - regs->saveDSPFW2 = PSB_RVDC32(DSPFW2); - regs->saveDSPFW3 = PSB_RVDC32(DSPFW3); - regs->saveDSPFW4 = PSB_RVDC32(DSPFW4); - regs->saveDSPFW5 = PSB_RVDC32(DSPFW5); - regs->saveDSPFW6 = PSB_RVDC32(DSPFW6); - regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); - - /* Save crtc and output state */ - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (drm_helper_crtc_in_use(crtc)) - crtc->funcs->save(crtc); - } - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->funcs->save) - connector->funcs->save(connector); - - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -/** - * psb_restore_display_registers - restore lost register state - * @dev: our DRM device - * - * Restore register state that was lost during suspend and resume. - */ -static int psb_restore_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_connector *connector; - struct psb_state *regs = &dev_priv->regs.psb; - - /* Display arbitration + watermarks */ - PSB_WVDC32(regs->saveDSPARB, DSPARB); - PSB_WVDC32(regs->saveDSPFW1, DSPFW1); - PSB_WVDC32(regs->saveDSPFW2, DSPFW2); - PSB_WVDC32(regs->saveDSPFW3, DSPFW3); - PSB_WVDC32(regs->saveDSPFW4, DSPFW4); - PSB_WVDC32(regs->saveDSPFW5, DSPFW5); - PSB_WVDC32(regs->saveDSPFW6, DSPFW6); - PSB_WVDC32(regs->saveCHICKENBIT, DSPCHICKENBIT); - - /*make sure VGA plane is off. it initializes to on after reset!*/ - PSB_WVDC32(0x80000000, VGACNTRL); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - if (drm_helper_crtc_in_use(crtc)) - crtc->funcs->restore(crtc); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->funcs->restore) - connector->funcs->restore(connector); - - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -static int psb_power_down(struct drm_device *dev) -{ - return 0; -} - -static int psb_power_up(struct drm_device *dev) -{ - return 0; -} - -static void psb_get_core_freq(struct drm_device *dev) -{ - uint32_t clock; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - struct drm_psb_private *dev_priv = dev->dev_private; - - /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/ - /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/ - - pci_write_config_dword(pci_root, 0xD0, 0xD0050300); - pci_read_config_dword(pci_root, 0xD4, &clock); - pci_dev_put(pci_root); - - switch (clock & 0x07) { - case 0: - dev_priv->core_freq = 100; - break; - case 1: - dev_priv->core_freq = 133; - break; - case 2: - dev_priv->core_freq = 150; - break; - case 3: - dev_priv->core_freq = 178; - break; - case 4: - dev_priv->core_freq = 200; - break; - case 5: - case 6: - case 7: - dev_priv->core_freq = 266; - default: - dev_priv->core_freq = 0; - } -} - -static int psb_chip_setup(struct drm_device *dev) -{ - psb_get_core_freq(dev); - gma_intel_setup_gmbus(dev); - gma_intel_opregion_init(dev); - psb_intel_init_bios(dev); - return 0; -} - -static void psb_chip_teardown(struct drm_device *dev) -{ - gma_intel_teardown_gmbus(dev); -} - -const struct psb_ops psb_chip_ops = { - .name = "Poulsbo", - .accel_2d = 1, - .pipes = 2, - .crtcs = 2, - .sgx_offset = PSB_SGX_OFFSET, - .chip_setup = psb_chip_setup, - .chip_teardown = psb_chip_teardown, - - .crtc_helper = &psb_intel_helper_funcs, - .crtc_funcs = &psb_intel_crtc_funcs, - - .output_init = psb_output_init, - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - .backlight_init = psb_backlight_init, -#endif - - .init_pm = psb_init_pm, - .save_regs = psb_save_display_registers, - .restore_regs = psb_restore_display_registers, - .power_down = psb_power_down, - .power_up = psb_power_up, -}; - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.c deleted file mode 100644 index 09af2ffb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.c +++ /dev/null @@ -1,706 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2011, Intel Corporation. - * All Rights Reserved. - * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#include -#include -#include "gma_drm.h" -#include "psb_drv.h" -#include "framebuffer.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include "intel_bios.h" -#include "mid_bios.h" -#include -#include "power.h" -#include -#include -#include -#include -#include -#include - -static int drm_psb_trap_pagefaults; - -static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); - -MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults"); -module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); - - -static DEFINE_PCI_DEVICE_TABLE(pciidlist) = { - { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, - { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, -#if defined(CONFIG_DRM_GMA600) - { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, - /* Atom E620 */ - { 0x8086, 0x4108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &oaktrail_chip_ops}, -#endif -#if defined(CONFIG_DRM_MEDFIELD) - {0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, - {0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, -#endif -#if defined(CONFIG_DRM_GMA3600) - { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, -#endif - { 0, } -}; -MODULE_DEVICE_TABLE(pci, pciidlist); - -/* - * Standard IOCTLs. - */ - -#define DRM_IOCTL_GMA_ADB \ - DRM_IOWR(DRM_GMA_ADB + DRM_COMMAND_BASE, uint32_t) -#define DRM_IOCTL_GMA_MODE_OPERATION \ - DRM_IOWR(DRM_GMA_MODE_OPERATION + DRM_COMMAND_BASE, \ - struct drm_psb_mode_operation_arg) -#define DRM_IOCTL_GMA_STOLEN_MEMORY \ - DRM_IOWR(DRM_GMA_STOLEN_MEMORY + DRM_COMMAND_BASE, \ - struct drm_psb_stolen_memory_arg) -#define DRM_IOCTL_GMA_GAMMA \ - DRM_IOWR(DRM_GMA_GAMMA + DRM_COMMAND_BASE, \ - struct drm_psb_dpst_lut_arg) -#define DRM_IOCTL_GMA_DPST_BL \ - DRM_IOWR(DRM_GMA_DPST_BL + DRM_COMMAND_BASE, \ - uint32_t) -#define DRM_IOCTL_GMA_GET_PIPE_FROM_CRTC_ID \ - DRM_IOWR(DRM_GMA_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \ - struct drm_psb_get_pipe_from_crtc_id_arg) -#define DRM_IOCTL_GMA_GEM_CREATE \ - DRM_IOWR(DRM_GMA_GEM_CREATE + DRM_COMMAND_BASE, \ - struct drm_psb_gem_create) -#define DRM_IOCTL_GMA_GEM_MMAP \ - DRM_IOWR(DRM_GMA_GEM_MMAP + DRM_COMMAND_BASE, \ - struct drm_psb_gem_mmap) - -static int psb_adb_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_gamma_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -static struct drm_ioctl_desc psb_ioctls[] = { - DRM_IOCTL_DEF_DRV(GMA_ADB, psb_adb_ioctl, DRM_AUTH), - DRM_IOCTL_DEF_DRV(GMA_MODE_OPERATION, psb_mode_operation_ioctl, - DRM_AUTH), - DRM_IOCTL_DEF_DRV(GMA_STOLEN_MEMORY, psb_stolen_memory_ioctl, - DRM_AUTH), - DRM_IOCTL_DEF_DRV(GMA_GAMMA, psb_gamma_ioctl, DRM_AUTH), - DRM_IOCTL_DEF_DRV(GMA_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), - DRM_IOCTL_DEF_DRV(GMA_GET_PIPE_FROM_CRTC_ID, - psb_intel_get_pipe_from_crtc_id, 0), - DRM_IOCTL_DEF_DRV(GMA_GEM_CREATE, psb_gem_create_ioctl, - DRM_UNLOCKED | DRM_AUTH), - DRM_IOCTL_DEF_DRV(GMA_GEM_MMAP, psb_gem_mmap_ioctl, - DRM_UNLOCKED | DRM_AUTH), -}; - -static void psb_lastclose(struct drm_device *dev) -{ - return; -} - -static void psb_do_takedown(struct drm_device *dev) -{ -} - -static int psb_do_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_gtt *pg = &dev_priv->gtt; - - uint32_t stolen_gtt; - - int ret = -ENOMEM; - - if (pg->mmu_gatt_start & 0x0FFFFFFF) { - dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n"); - ret = -EINVAL; - goto out_err; - } - - - stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4; - stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT; - stolen_gtt = - (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages; - - dev_priv->gatt_free_offset = pg->mmu_gatt_start + - (stolen_gtt << PAGE_SHIFT) * 1024; - - if (1 || drm_debug) { - uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID); - uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION); - DRM_INFO("SGX core id = 0x%08x\n", core_id); - DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n", - (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >> - _PSB_CC_REVISION_MAJOR_SHIFT, - (core_rev & _PSB_CC_REVISION_MINOR_MASK) >> - _PSB_CC_REVISION_MINOR_SHIFT); - DRM_INFO - ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n", - (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >> - _PSB_CC_REVISION_MAINTENANCE_SHIFT, - (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >> - _PSB_CC_REVISION_DESIGNER_SHIFT); - } - - - spin_lock_init(&dev_priv->irqmask_lock); - spin_lock_init(&dev_priv->lock_2d); - - PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); - PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); - PSB_RSGX32(PSB_CR_BIF_BANK1); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, - PSB_CR_BIF_CTRL); - psb_spank(dev_priv); - - /* mmu_gatt ?? */ - PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); - return 0; -out_err: - psb_do_takedown(dev); - return ret; -} - -static int psb_driver_unload(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - /* Kill vblank etc here */ - - gma_backlight_exit(dev); - - psb_modeset_cleanup(dev); - - if (dev_priv) { - psb_lid_timer_takedown(dev_priv); - gma_intel_opregion_exit(dev); - - if (dev_priv->ops->chip_teardown) - dev_priv->ops->chip_teardown(dev); - psb_do_takedown(dev); - - - if (dev_priv->pf_pd) { - psb_mmu_free_pagedir(dev_priv->pf_pd); - dev_priv->pf_pd = NULL; - } - if (dev_priv->mmu) { - struct psb_gtt *pg = &dev_priv->gtt; - - down_read(&pg->sem); - psb_mmu_remove_pfn_sequence( - psb_mmu_get_default_pd - (dev_priv->mmu), - pg->mmu_gatt_start, - dev_priv->vram_stolen_size >> PAGE_SHIFT); - up_read(&pg->sem); - psb_mmu_driver_takedown(dev_priv->mmu); - dev_priv->mmu = NULL; - } - psb_gtt_takedown(dev); - if (dev_priv->scratch_page) { - __free_page(dev_priv->scratch_page); - dev_priv->scratch_page = NULL; - } - if (dev_priv->vdc_reg) { - iounmap(dev_priv->vdc_reg); - dev_priv->vdc_reg = NULL; - } - if (dev_priv->sgx_reg) { - iounmap(dev_priv->sgx_reg); - dev_priv->sgx_reg = NULL; - } - - kfree(dev_priv); - dev->dev_private = NULL; - - /*destroy VBT data*/ - psb_intel_destroy_bios(dev); - } - - gma_power_uninit(dev); - - return 0; -} - - -static int psb_driver_load(struct drm_device *dev, unsigned long chipset) -{ - struct drm_psb_private *dev_priv; - unsigned long resource_start; - unsigned long irqflags; - int ret = -ENOMEM; - struct drm_connector *connector; - struct psb_intel_encoder *psb_intel_encoder; - - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev_priv->ops = (struct psb_ops *)chipset; - dev_priv->dev = dev; - dev->dev_private = (void *) dev_priv; - - pci_set_master(dev->pdev); - - if (!IS_PSB(dev)) { - if (pci_enable_msi(dev->pdev)) - dev_warn(dev->dev, "Enabling MSI failed!\n"); - } - - dev_priv->num_pipe = dev_priv->ops->pipes; - - resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); - - dev_priv->vdc_reg = - ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE); - if (!dev_priv->vdc_reg) - goto out_err; - - dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset, - PSB_SGX_SIZE); - if (!dev_priv->sgx_reg) - goto out_err; - - ret = dev_priv->ops->chip_setup(dev); - if (ret) - goto out_err; - - /* Init OSPM support */ - gma_power_init(dev); - - ret = -ENOMEM; - - dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO); - if (!dev_priv->scratch_page) - goto out_err; - - set_pages_uc(dev_priv->scratch_page, 1); - - ret = psb_gtt_init(dev, 0); - if (ret) - goto out_err; - - dev_priv->mmu = psb_mmu_driver_init((void *)0, - drm_psb_trap_pagefaults, 0, - dev_priv); - if (!dev_priv->mmu) - goto out_err; - - dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0); - if (!dev_priv->pf_pd) - goto out_err; - - psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0); - psb_mmu_set_pd_context(dev_priv->pf_pd, 1); - - ret = psb_do_init(dev); - if (ret) - return ret; - - PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); - PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); - -/* igd_opregion_init(&dev_priv->opregion_dev); */ -/* acpi_video_register(); */ - if (dev_priv->lid_state) - psb_lid_timer_init(dev_priv); - - ret = drm_vblank_init(dev, dev_priv->num_pipe); - if (ret) - goto out_err; - - /* - * Install interrupt handlers prior to powering off SGX or else we will - * crash. - */ - dev_priv->vdc_irq_mask = 0; - dev_priv->pipestat[0] = 0; - dev_priv->pipestat[1] = 0; - dev_priv->pipestat[2] = 0; - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); - PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) - drm_irq_install(dev); - - dev->vblank_disable_allowed = 1; - - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - - dev->driver->get_vblank_counter = psb_get_vblank_counter; - - psb_modeset_init(dev); - psb_fbdev_init(dev); - drm_kms_helper_poll_init(dev); - - /* Only add backlight support if we have LVDS output */ - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - psb_intel_encoder = psb_intel_attached_encoder(connector); - - switch (psb_intel_encoder->type) { - case INTEL_OUTPUT_LVDS: - case INTEL_OUTPUT_MIPI: - ret = gma_backlight_init(dev); - break; - } - } - - if (ret) - return ret; -#if 0 - /*enable runtime pm at last*/ - pm_runtime_enable(&dev->pdev->dev); - pm_runtime_set_active(&dev->pdev->dev); -#endif - /*Intel drm driver load is done, continue doing pvr load*/ - return 0; -out_err: - psb_driver_unload(dev); - return ret; -} - -static int psb_driver_device_is_agp(struct drm_device *dev) -{ - return 0; -} - -static inline void get_brightness(struct backlight_device *bd) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - if (bd) { - bd->props.brightness = bd->ops->get_brightness(bd); - backlight_update_status(bd); - } -#endif -} - -static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - uint32_t *arg = data; - - dev_priv->blc_adj2 = *arg; - get_brightness(dev_priv->backlight_device); - return 0; -} - -static int psb_adb_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - uint32_t *arg = data; - - dev_priv->blc_adj1 = *arg; - get_brightness(dev_priv->backlight_device); - return 0; -} - -static int psb_gamma_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_dpst_lut_arg *lut_arg = data; - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct drm_connector *connector; - struct psb_intel_crtc *psb_intel_crtc; - int i = 0; - int32_t obj_id; - - obj_id = lut_arg->output_id; - obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - dev_dbg(dev->dev, "Invalid Connector object.\n"); - return -EINVAL; - } - - connector = obj_to_connector(obj); - crtc = connector->encoder->crtc; - psb_intel_crtc = to_psb_intel_crtc(crtc); - - for (i = 0; i < 256; i++) - psb_intel_crtc->lut_adj[i] = lut_arg->lut[i]; - - psb_intel_crtc_load_lut(crtc); - - return 0; -} - -static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - uint32_t obj_id; - uint16_t op; - struct drm_mode_modeinfo *umode; - struct drm_display_mode *mode = NULL; - struct drm_psb_mode_operation_arg *arg; - struct drm_mode_object *obj; - struct drm_connector *connector; - struct drm_connector_helper_funcs *connector_funcs; - int ret = 0; - int resp = MODE_OK; - - arg = (struct drm_psb_mode_operation_arg *)data; - obj_id = arg->obj_id; - op = arg->operation; - - switch (op) { - case PSB_MODE_OPERATION_MODE_VALID: - umode = &arg->mode; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, obj_id, - DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { - ret = -EINVAL; - goto mode_op_out; - } - - connector = obj_to_connector(obj); - - mode = drm_mode_create(dev); - if (!mode) { - ret = -ENOMEM; - goto mode_op_out; - } - - /* drm_crtc_convert_umode(mode, umode); */ - { - mode->clock = umode->clock; - mode->hdisplay = umode->hdisplay; - mode->hsync_start = umode->hsync_start; - mode->hsync_end = umode->hsync_end; - mode->htotal = umode->htotal; - mode->hskew = umode->hskew; - mode->vdisplay = umode->vdisplay; - mode->vsync_start = umode->vsync_start; - mode->vsync_end = umode->vsync_end; - mode->vtotal = umode->vtotal; - mode->vscan = umode->vscan; - mode->vrefresh = umode->vrefresh; - mode->flags = umode->flags; - mode->type = umode->type; - strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN); - mode->name[DRM_DISPLAY_MODE_LEN-1] = 0; - } - - connector_funcs = (struct drm_connector_helper_funcs *) - connector->helper_private; - - if (connector_funcs->mode_valid) { - resp = connector_funcs->mode_valid(connector, mode); - arg->data = resp; - } - - /*do some clean up work*/ - if (mode) - drm_mode_destroy(dev, mode); -mode_op_out: - mutex_unlock(&dev->mode_config.mutex); - return ret; - - default: - dev_dbg(dev->dev, "Unsupported psb mode operation\n"); - return -EOPNOTSUPP; - } - - return 0; -} - -static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = psb_priv(dev); - struct drm_psb_stolen_memory_arg *arg = data; - - arg->base = dev_priv->stolen_base; - arg->size = dev_priv->vram_stolen_size; - - return 0; -} - -static int psb_driver_open(struct drm_device *dev, struct drm_file *priv) -{ - return 0; -} - -static void psb_driver_close(struct drm_device *dev, struct drm_file *priv) -{ -} - -static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_device *dev = file_priv->minor->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - static unsigned int runtime_allowed; - - if (runtime_allowed == 1 && dev_priv->is_lvds_on) { - runtime_allowed++; - pm_runtime_allow(&dev->pdev->dev); - dev_priv->rpm_enabled = 1; - } - return drm_ioctl(filp, cmd, arg); - /* FIXME: do we need to wrap the other side of this */ -} - - -/* When a client dies: - * - Check for and clean up flipped page state - */ -static void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv) -{ -} - -static void psb_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - drm_put_dev(dev); -} - -static const struct dev_pm_ops psb_pm_ops = { - .resume = gma_power_resume, - .suspend = gma_power_suspend, - .runtime_suspend = psb_runtime_suspend, - .runtime_resume = psb_runtime_resume, - .runtime_idle = psb_runtime_idle, -}; - -static struct vm_operations_struct psb_gem_vm_ops = { - .fault = psb_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static const struct file_operations psb_gem_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = psb_unlocked_ioctl, - .mmap = drm_gem_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, -}; - -static struct drm_driver driver = { - .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \ - DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM , - .load = psb_driver_load, - .unload = psb_driver_unload, - - .ioctls = psb_ioctls, - .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls), - .device_is_agp = psb_driver_device_is_agp, - .irq_preinstall = psb_irq_preinstall, - .irq_postinstall = psb_irq_postinstall, - .irq_uninstall = psb_irq_uninstall, - .irq_handler = psb_irq_handler, - .enable_vblank = psb_enable_vblank, - .disable_vblank = psb_disable_vblank, - .get_vblank_counter = psb_get_vblank_counter, - .lastclose = psb_lastclose, - .open = psb_driver_open, - .preclose = psb_driver_preclose, - .postclose = psb_driver_close, - .reclaim_buffers = drm_core_reclaim_buffers, - - .gem_init_object = psb_gem_init_object, - .gem_free_object = psb_gem_free_object, - .gem_vm_ops = &psb_gem_vm_ops, - .dumb_create = psb_gem_dumb_create, - .dumb_map_offset = psb_gem_dumb_map_gtt, - .dumb_destroy = psb_gem_dumb_destroy, - .fops = &psb_gem_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = PSB_DRM_DRIVER_DATE, - .major = PSB_DRM_DRIVER_MAJOR, - .minor = PSB_DRM_DRIVER_MINOR, - .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL -}; - -static struct pci_driver psb_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = psb_probe, - .remove = psb_remove, - .driver = { - .pm = &psb_pm_ops, - } -}; - -static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - return drm_get_pci_dev(pdev, ent, &driver); -} - -static int __init psb_init(void) -{ - return drm_pci_init(&driver, &psb_pci_driver); -} - -static void __exit psb_exit(void) -{ - drm_pci_exit(&driver, &psb_pci_driver); -} - -late_initcall(psb_init); -module_exit(psb_exit); - -MODULE_AUTHOR("Alan Cox and others"); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.h deleted file mode 100644 index 40ce2c9b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_drv.h +++ /dev/null @@ -1,993 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007-2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - **************************************************************************/ - -#ifndef _PSB_DRV_H_ -#define _PSB_DRV_H_ - -#include - -#include -#include "drm_global.h" -#include "gem_glue.h" -#include "gma_drm.h" -#include "psb_reg.h" -#include "psb_intel_drv.h" -#include "gtt.h" -#include "power.h" -#include "oaktrail.h" - -/* Append new drm mode definition here, align with libdrm definition */ -#define DRM_MODE_SCALE_NO_SCALE 2 - -enum { - CHIP_PSB_8108 = 0, /* Poulsbo */ - CHIP_PSB_8109 = 1, /* Poulsbo */ - CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */ - CHIP_MFLD_0130 = 3, /* Medfield */ -}; - -#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108) -#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) -#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130) - -/* - * Driver definitions - */ - -#define DRIVER_NAME "gma500" -#define DRIVER_DESC "DRM driver for the Intel GMA500" - -#define PSB_DRM_DRIVER_DATE "2011-06-06" -#define PSB_DRM_DRIVER_MAJOR 1 -#define PSB_DRM_DRIVER_MINOR 0 -#define PSB_DRM_DRIVER_PATCHLEVEL 0 - -/* - * Hardware offsets - */ -#define PSB_VDC_OFFSET 0x00000000 -#define PSB_VDC_SIZE 0x000080000 -#define MRST_MMIO_SIZE 0x0000C0000 -#define MDFLD_MMIO_SIZE 0x000100000 -#define PSB_SGX_SIZE 0x8000 -#define PSB_SGX_OFFSET 0x00040000 -#define MRST_SGX_OFFSET 0x00080000 -/* - * PCI resource identifiers - */ -#define PSB_MMIO_RESOURCE 0 -#define PSB_GATT_RESOURCE 2 -#define PSB_GTT_RESOURCE 3 -/* - * PCI configuration - */ -#define PSB_GMCH_CTRL 0x52 -#define PSB_BSM 0x5C -#define _PSB_GMCH_ENABLED 0x4 -#define PSB_PGETBL_CTL 0x2020 -#define _PSB_PGETBL_ENABLED 0x00000001 -#define PSB_SGX_2D_SLAVE_PORT 0x4000 - -/* To get rid of */ -#define PSB_TT_PRIV0_LIMIT (256*1024*1024) -#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT) - -/* - * SGX side MMU definitions (these can probably go) - */ - -/* - * Flags for external memory type field. - */ -#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */ -#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */ -#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */ -/* - * PTE's and PDE's - */ -#define PSB_PDE_MASK 0x003FFFFF -#define PSB_PDE_SHIFT 22 -#define PSB_PTE_SHIFT 12 -/* - * Cache control - */ -#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */ -#define PSB_PTE_WO 0x0002 /* Write only */ -#define PSB_PTE_RO 0x0004 /* Read only */ -#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */ - -/* - * VDC registers and bits - */ -#define PSB_MSVDX_CLOCKGATING 0x2064 -#define PSB_TOPAZ_CLOCKGATING 0x2068 -#define PSB_HWSTAM 0x2098 -#define PSB_INSTPM 0x20C0 -#define PSB_INT_IDENTITY_R 0x20A4 -#define _MDFLD_PIPEC_EVENT_FLAG (1<<2) -#define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) -#define _PSB_DPST_PIPEB_FLAG (1<<4) -#define _MDFLD_PIPEB_EVENT_FLAG (1<<4) -#define _PSB_VSYNC_PIPEB_FLAG (1<<5) -#define _PSB_DPST_PIPEA_FLAG (1<<6) -#define _PSB_PIPEA_EVENT_FLAG (1<<6) -#define _PSB_VSYNC_PIPEA_FLAG (1<<7) -#define _MDFLD_MIPIA_FLAG (1<<16) -#define _MDFLD_MIPIC_FLAG (1<<17) -#define _PSB_IRQ_SGX_FLAG (1<<18) -#define _PSB_IRQ_MSVDX_FLAG (1<<19) -#define _LNC_IRQ_TOPAZ_FLAG (1<<20) - -#define _PSB_PIPE_EVENT_FLAG (_PSB_VSYNC_PIPEA_FLAG | \ - _PSB_VSYNC_PIPEB_FLAG) - -/* This flag includes all the display IRQ bits excepts the vblank irqs. */ -#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ - _MDFLD_PIPEB_EVENT_FLAG | \ - _PSB_PIPEA_EVENT_FLAG | \ - _PSB_VSYNC_PIPEA_FLAG | \ - _MDFLD_MIPIA_FLAG | \ - _MDFLD_MIPIC_FLAG) -#define PSB_INT_IDENTITY_R 0x20A4 -#define PSB_INT_MASK_R 0x20A8 -#define PSB_INT_ENABLE_R 0x20A0 - -#define _PSB_MMU_ER_MASK 0x0001FF00 -#define _PSB_MMU_ER_HOST (1 << 16) -#define GPIOA 0x5010 -#define GPIOB 0x5014 -#define GPIOC 0x5018 -#define GPIOD 0x501c -#define GPIOE 0x5020 -#define GPIOF 0x5024 -#define GPIOG 0x5028 -#define GPIOH 0x502c -#define GPIO_CLOCK_DIR_MASK (1 << 0) -#define GPIO_CLOCK_DIR_IN (0 << 1) -#define GPIO_CLOCK_DIR_OUT (1 << 1) -#define GPIO_CLOCK_VAL_MASK (1 << 2) -#define GPIO_CLOCK_VAL_OUT (1 << 3) -#define GPIO_CLOCK_VAL_IN (1 << 4) -#define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) -#define GPIO_DATA_DIR_MASK (1 << 8) -#define GPIO_DATA_DIR_IN (0 << 9) -#define GPIO_DATA_DIR_OUT (1 << 9) -#define GPIO_DATA_VAL_MASK (1 << 10) -#define GPIO_DATA_VAL_OUT (1 << 11) -#define GPIO_DATA_VAL_IN (1 << 12) -#define GPIO_DATA_PULLUP_DISABLE (1 << 13) - -#define VCLK_DIVISOR_VGA0 0x6000 -#define VCLK_DIVISOR_VGA1 0x6004 -#define VCLK_POST_DIV 0x6010 - -#define PSB_COMM_2D (PSB_ENGINE_2D << 4) -#define PSB_COMM_3D (PSB_ENGINE_3D << 4) -#define PSB_COMM_TA (PSB_ENGINE_TA << 4) -#define PSB_COMM_HP (PSB_ENGINE_HP << 4) -#define PSB_COMM_USER_IRQ (1024 >> 2) -#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1) -#define PSB_COMM_FW (2048 >> 2) - -#define PSB_UIRQ_VISTEST 1 -#define PSB_UIRQ_OOM_REPLY 2 -#define PSB_UIRQ_FIRE_TA_REPLY 3 -#define PSB_UIRQ_FIRE_RASTER_REPLY 4 - -#define PSB_2D_SIZE (256*1024*1024) -#define PSB_MAX_RELOC_PAGES 1024 - -#define PSB_LOW_REG_OFFS 0x0204 -#define PSB_HIGH_REG_OFFS 0x0600 - -#define PSB_NUM_VBLANKS 2 - - -#define PSB_2D_SIZE (256*1024*1024) -#define PSB_MAX_RELOC_PAGES 1024 - -#define PSB_LOW_REG_OFFS 0x0204 -#define PSB_HIGH_REG_OFFS 0x0600 - -#define PSB_NUM_VBLANKS 2 -#define PSB_WATCHDOG_DELAY (DRM_HZ * 2) -#define PSB_LID_DELAY (DRM_HZ / 10) - -#define MDFLD_PNW_B0 0x04 -#define MDFLD_PNW_C0 0x08 - -#define MDFLD_DSR_2D_3D_0 (1 << 0) -#define MDFLD_DSR_2D_3D_2 (1 << 1) -#define MDFLD_DSR_CURSOR_0 (1 << 2) -#define MDFLD_DSR_CURSOR_2 (1 << 3) -#define MDFLD_DSR_OVERLAY_0 (1 << 4) -#define MDFLD_DSR_OVERLAY_2 (1 << 5) -#define MDFLD_DSR_MIPI_CONTROL (1 << 6) -#define MDFLD_DSR_DAMAGE_MASK_0 ((1 << 0) | (1 << 2) | (1 << 4)) -#define MDFLD_DSR_DAMAGE_MASK_2 ((1 << 1) | (1 << 3) | (1 << 5)) -#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) - -#define MDFLD_DSR_RR 45 -#define MDFLD_DPU_ENABLE (1 << 31) -#define MDFLD_DSR_FULLSCREEN (1 << 30) -#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR) - -#define PSB_PWR_STATE_ON 1 -#define PSB_PWR_STATE_OFF 2 - -#define PSB_PMPOLICY_NOPM 0 -#define PSB_PMPOLICY_CLOCKGATING 1 -#define PSB_PMPOLICY_POWERDOWN 2 - -#define PSB_PMSTATE_POWERUP 0 -#define PSB_PMSTATE_CLOCKGATED 1 -#define PSB_PMSTATE_POWERDOWN 2 -#define PSB_PCIx_MSI_ADDR_LOC 0x94 -#define PSB_PCIx_MSI_DATA_LOC 0x98 - -/* Medfield crystal settings */ -#define KSEL_CRYSTAL_19 1 -#define KSEL_BYPASS_19 5 -#define KSEL_BYPASS_25 6 -#define KSEL_BYPASS_83_100 7 - -struct opregion_header; -struct opregion_acpi; -struct opregion_swsci; -struct opregion_asle; - -struct psb_intel_opregion { - struct opregion_header *header; - struct opregion_acpi *acpi; - struct opregion_swsci *swsci; - struct opregion_asle *asle; - int enabled; -}; - -struct sdvo_device_mapping { - u8 initialized; - u8 dvo_port; - u8 slave_addr; - u8 dvo_wiring; - u8 i2c_pin; - u8 i2c_speed; - u8 ddc_pin; -}; - -struct intel_gmbus { - struct i2c_adapter adapter; - struct i2c_adapter *force_bit; - u32 reg0; -}; - -/* - * Register save state. This is used to hold the context when the - * device is powered off. In the case of Oaktrail this can (but does not - * yet) include screen blank. Operations occuring during the save - * update the register cache instead. - */ -struct psb_state { - uint32_t saveDSPACNTR; - uint32_t saveDSPBCNTR; - uint32_t savePIPEACONF; - uint32_t savePIPEBCONF; - uint32_t savePIPEASRC; - uint32_t savePIPEBSRC; - uint32_t saveFPA0; - uint32_t saveFPA1; - uint32_t saveDPLL_A; - uint32_t saveDPLL_A_MD; - uint32_t saveHTOTAL_A; - uint32_t saveHBLANK_A; - uint32_t saveHSYNC_A; - uint32_t saveVTOTAL_A; - uint32_t saveVBLANK_A; - uint32_t saveVSYNC_A; - uint32_t saveDSPASTRIDE; - uint32_t saveDSPASIZE; - uint32_t saveDSPAPOS; - uint32_t saveDSPABASE; - uint32_t saveDSPASURF; - uint32_t saveDSPASTATUS; - uint32_t saveFPB0; - uint32_t saveFPB1; - uint32_t saveDPLL_B; - uint32_t saveDPLL_B_MD; - uint32_t saveHTOTAL_B; - uint32_t saveHBLANK_B; - uint32_t saveHSYNC_B; - uint32_t saveVTOTAL_B; - uint32_t saveVBLANK_B; - uint32_t saveVSYNC_B; - uint32_t saveDSPBSTRIDE; - uint32_t saveDSPBSIZE; - uint32_t saveDSPBPOS; - uint32_t saveDSPBBASE; - uint32_t saveDSPBSURF; - uint32_t saveDSPBSTATUS; - uint32_t saveVCLK_DIVISOR_VGA0; - uint32_t saveVCLK_DIVISOR_VGA1; - uint32_t saveVCLK_POST_DIV; - uint32_t saveVGACNTRL; - uint32_t saveADPA; - uint32_t saveLVDS; - uint32_t saveDVOA; - uint32_t saveDVOB; - uint32_t saveDVOC; - uint32_t savePP_ON; - uint32_t savePP_OFF; - uint32_t savePP_CONTROL; - uint32_t savePP_CYCLE; - uint32_t savePFIT_CONTROL; - uint32_t savePaletteA[256]; - uint32_t savePaletteB[256]; - uint32_t saveCLOCKGATING; - uint32_t saveDSPARB; - uint32_t saveDSPATILEOFF; - uint32_t saveDSPBTILEOFF; - uint32_t saveDSPAADDR; - uint32_t saveDSPBADDR; - uint32_t savePFIT_AUTO_RATIOS; - uint32_t savePFIT_PGM_RATIOS; - uint32_t savePP_ON_DELAYS; - uint32_t savePP_OFF_DELAYS; - uint32_t savePP_DIVISOR; - uint32_t saveBCLRPAT_A; - uint32_t saveBCLRPAT_B; - uint32_t saveDSPALINOFF; - uint32_t saveDSPBLINOFF; - uint32_t savePERF_MODE; - uint32_t saveDSPFW1; - uint32_t saveDSPFW2; - uint32_t saveDSPFW3; - uint32_t saveDSPFW4; - uint32_t saveDSPFW5; - uint32_t saveDSPFW6; - uint32_t saveCHICKENBIT; - uint32_t saveDSPACURSOR_CTRL; - uint32_t saveDSPBCURSOR_CTRL; - uint32_t saveDSPACURSOR_BASE; - uint32_t saveDSPBCURSOR_BASE; - uint32_t saveDSPACURSOR_POS; - uint32_t saveDSPBCURSOR_POS; - uint32_t save_palette_a[256]; - uint32_t save_palette_b[256]; - uint32_t saveOV_OVADD; - uint32_t saveOV_OGAMC0; - uint32_t saveOV_OGAMC1; - uint32_t saveOV_OGAMC2; - uint32_t saveOV_OGAMC3; - uint32_t saveOV_OGAMC4; - uint32_t saveOV_OGAMC5; - uint32_t saveOVC_OVADD; - uint32_t saveOVC_OGAMC0; - uint32_t saveOVC_OGAMC1; - uint32_t saveOVC_OGAMC2; - uint32_t saveOVC_OGAMC3; - uint32_t saveOVC_OGAMC4; - uint32_t saveOVC_OGAMC5; - - /* DPST register save */ - uint32_t saveHISTOGRAM_INT_CONTROL_REG; - uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG; - uint32_t savePWM_CONTROL_LOGIC; -}; - -struct medfield_state { - uint32_t saveDPLL_A; - uint32_t saveFPA0; - uint32_t savePIPEACONF; - uint32_t saveHTOTAL_A; - uint32_t saveHBLANK_A; - uint32_t saveHSYNC_A; - uint32_t saveVTOTAL_A; - uint32_t saveVBLANK_A; - uint32_t saveVSYNC_A; - uint32_t savePIPEASRC; - uint32_t saveDSPASTRIDE; - uint32_t saveDSPALINOFF; - uint32_t saveDSPATILEOFF; - uint32_t saveDSPASIZE; - uint32_t saveDSPAPOS; - uint32_t saveDSPASURF; - uint32_t saveDSPACNTR; - uint32_t saveDSPASTATUS; - uint32_t save_palette_a[256]; - uint32_t saveMIPI; - - uint32_t saveDPLL_B; - uint32_t saveFPB0; - uint32_t savePIPEBCONF; - uint32_t saveHTOTAL_B; - uint32_t saveHBLANK_B; - uint32_t saveHSYNC_B; - uint32_t saveVTOTAL_B; - uint32_t saveVBLANK_B; - uint32_t saveVSYNC_B; - uint32_t savePIPEBSRC; - uint32_t saveDSPBSTRIDE; - uint32_t saveDSPBLINOFF; - uint32_t saveDSPBTILEOFF; - uint32_t saveDSPBSIZE; - uint32_t saveDSPBPOS; - uint32_t saveDSPBSURF; - uint32_t saveDSPBCNTR; - uint32_t saveDSPBSTATUS; - uint32_t save_palette_b[256]; - - uint32_t savePIPECCONF; - uint32_t saveHTOTAL_C; - uint32_t saveHBLANK_C; - uint32_t saveHSYNC_C; - uint32_t saveVTOTAL_C; - uint32_t saveVBLANK_C; - uint32_t saveVSYNC_C; - uint32_t savePIPECSRC; - uint32_t saveDSPCSTRIDE; - uint32_t saveDSPCLINOFF; - uint32_t saveDSPCTILEOFF; - uint32_t saveDSPCSIZE; - uint32_t saveDSPCPOS; - uint32_t saveDSPCSURF; - uint32_t saveDSPCCNTR; - uint32_t saveDSPCSTATUS; - uint32_t save_palette_c[256]; - uint32_t saveMIPI_C; - - uint32_t savePFIT_CONTROL; - uint32_t savePFIT_PGM_RATIOS; - uint32_t saveHDMIPHYMISCCTL; - uint32_t saveHDMIB_CONTROL; -}; - -struct cdv_state { - uint32_t saveDSPCLK_GATE_D; - uint32_t saveRAMCLK_GATE_D; - uint32_t saveDSPARB; - uint32_t saveDSPFW[6]; - uint32_t saveADPA; - uint32_t savePP_CONTROL; - uint32_t savePFIT_PGM_RATIOS; - uint32_t saveLVDS; - uint32_t savePFIT_CONTROL; - uint32_t savePP_ON_DELAYS; - uint32_t savePP_OFF_DELAYS; - uint32_t savePP_CYCLE; - uint32_t saveVGACNTRL; - uint32_t saveIER; - uint32_t saveIMR; - u8 saveLBB; -}; - -struct psb_save_area { - uint32_t saveBSM; - uint32_t saveVBT; - union { - struct psb_state psb; - struct medfield_state mdfld; - struct cdv_state cdv; - }; - uint32_t saveBLC_PWM_CTL2; - uint32_t saveBLC_PWM_CTL; -}; - -struct psb_ops; - -#define PSB_NUM_PIPE 3 - -struct drm_psb_private { - struct drm_device *dev; - const struct psb_ops *ops; - - struct psb_gtt gtt; - - /* GTT Memory manager */ - struct psb_gtt_mm *gtt_mm; - struct page *scratch_page; - u32 *gtt_map; - uint32_t stolen_base; - void *vram_addr; - unsigned long vram_stolen_size; - int gtt_initialized; - u16 gmch_ctrl; /* Saved GTT setup */ - u32 pge_ctl; - - struct mutex gtt_mutex; - struct resource *gtt_mem; /* Our PCI resource */ - - struct psb_mmu_driver *mmu; - struct psb_mmu_pd *pf_pd; - - /* - * Register base - */ - - uint8_t *sgx_reg; - uint8_t *vdc_reg; - uint32_t gatt_free_offset; - - /* - * Fencing / irq. - */ - - uint32_t vdc_irq_mask; - uint32_t pipestat[PSB_NUM_PIPE]; - - spinlock_t irqmask_lock; - - /* - * Power - */ - - bool suspended; - bool display_power; - int display_count; - - /* - * Modesetting - */ - struct psb_intel_mode_device mode_dev; - - struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE]; - struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE]; - uint32_t num_pipe; - - /* - * OSPM info (Power management base) (can go ?) - */ - uint32_t ospm_base; - - /* - * Sizes info - */ - - u32 fuse_reg_value; - u32 video_device_fuse; - - /* PCI revision ID for B0:D2:F0 */ - uint8_t platform_rev_id; - - /* gmbus */ - struct intel_gmbus *gmbus; - - /* Used by SDVO */ - int crt_ddc_pin; - /* FIXME: The mappings should be parsed from bios but for now we can - pretend there are no mappings available */ - struct sdvo_device_mapping sdvo_mappings[2]; - u32 hotplug_supported_mask; - struct drm_property *broadcast_rgb_property; - struct drm_property *force_audio_property; - - /* - * LVDS info - */ - int backlight_duty_cycle; /* restore backlight to this value */ - bool panel_wants_dither; - struct drm_display_mode *panel_fixed_mode; - struct drm_display_mode *lfp_lvds_vbt_mode; - struct drm_display_mode *sdvo_lvds_vbt_mode; - - struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */ - struct psb_intel_i2c_chan *lvds_i2c_bus; /* FIXME: Remove this? */ - - /* Feature bits from the VBIOS */ - unsigned int int_tv_support:1; - unsigned int lvds_dither:1; - unsigned int lvds_vbt:1; - unsigned int int_crt_support:1; - unsigned int lvds_use_ssc:1; - int lvds_ssc_freq; - bool is_lvds_on; - bool is_mipi_on; - u32 mipi_ctrl_display; - - unsigned int core_freq; - uint32_t iLVDS_enable; - - /* Runtime PM state */ - int rpm_enabled; - - /* MID specific */ - struct oaktrail_vbt vbt_data; - struct oaktrail_gct_data gct_data; - - /* Oaktrail HDMI state */ - struct oaktrail_hdmi_dev *hdmi_priv; - - /* - * Register state - */ - - struct psb_save_area regs; - - /* MSI reg save */ - uint32_t msi_addr; - uint32_t msi_data; - - - /* - * LID-Switch - */ - spinlock_t lid_lock; - struct timer_list lid_timer; - struct psb_intel_opregion opregion; - u32 *lid_state; - u32 lid_last_state; - - /* - * Watchdog - */ - - uint32_t apm_reg; - uint16_t apm_base; - - /* - * Used for modifying backlight from - * xrandr -- consider removing and using HAL instead - */ - struct backlight_device *backlight_device; - struct drm_property *backlight_property; - uint32_t blc_adj1; - uint32_t blc_adj2; - - void *fbdev; - - /* 2D acceleration */ - spinlock_t lock_2d; - - /* - * Panel brightness - */ - int brightness; - int brightness_adjusted; - - bool dsr_enable; - u32 dsr_fb_update; - bool dpi_panel_on[3]; - void *dsi_configs[2]; - u32 bpp; - u32 bpp2; - - u32 pipeconf[3]; - u32 dspcntr[3]; - - int mdfld_panel_id; -}; - - -/* - * Operations for each board type - */ - -struct psb_ops { - const char *name; - unsigned int accel_2d:1; - int pipes; /* Number of output pipes */ - int crtcs; /* Number of CRTCs */ - int sgx_offset; /* Base offset of SGX device */ - - /* Sub functions */ - struct drm_crtc_helper_funcs const *crtc_helper; - struct drm_crtc_funcs const *crtc_funcs; - - /* Setup hooks */ - int (*chip_setup)(struct drm_device *dev); - void (*chip_teardown)(struct drm_device *dev); - - /* Display management hooks */ - int (*output_init)(struct drm_device *dev); - /* Power management hooks */ - void (*init_pm)(struct drm_device *dev); - int (*save_regs)(struct drm_device *dev); - int (*restore_regs)(struct drm_device *dev); - int (*power_up)(struct drm_device *dev); - int (*power_down)(struct drm_device *dev); - - void (*lvds_bl_power)(struct drm_device *dev, bool on); -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - /* Backlight */ - int (*backlight_init)(struct drm_device *dev); -#endif - int i2c_bus; /* I2C bus identifier for Moorestown */ -}; - - - -struct psb_mmu_driver; - -extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); -extern int drm_pick_crtcs(struct drm_device *dev); - -static inline struct drm_psb_private *psb_priv(struct drm_device *dev) -{ - return (struct drm_psb_private *) dev->dev_private; -} - -/* - * MMU stuff. - */ - -extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, - int trap_pagefaults, - int invalid_type, - struct drm_psb_private *dev_priv); -extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver); -extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver - *driver); -extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset, - uint32_t gtt_start, uint32_t gtt_pages); -extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, - int trap_pagefaults, - int invalid_type); -extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd); -extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot); -extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, - unsigned long address, - uint32_t num_pages); -extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, - uint32_t start_pfn, - unsigned long address, - uint32_t num_pages, int type); -extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, - unsigned long *pfn); - -/* - * Enable / disable MMU for different requestors. - */ - - -extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context); -extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride, int type); -extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd, - unsigned long address, uint32_t num_pages, - uint32_t desired_tile_stride, - uint32_t hw_tile_stride); -/* - *psb_irq.c - */ - -extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); -extern int psb_irq_enable_dpst(struct drm_device *dev); -extern int psb_irq_disable_dpst(struct drm_device *dev); -extern void psb_irq_preinstall(struct drm_device *dev); -extern int psb_irq_postinstall(struct drm_device *dev); -extern void psb_irq_uninstall(struct drm_device *dev); -extern void psb_irq_turn_on_dpst(struct drm_device *dev); -extern void psb_irq_turn_off_dpst(struct drm_device *dev); - -extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); -extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence); -extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); -extern int psb_enable_vblank(struct drm_device *dev, int crtc); -extern void psb_disable_vblank(struct drm_device *dev, int crtc); -void -psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); - -void -psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); - -extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); - -/* - * intel_opregion.c - */ -extern int gma_intel_opregion_init(struct drm_device *dev); -extern int gma_intel_opregion_exit(struct drm_device *dev); - -/* - * framebuffer.c - */ -extern int psbfb_probed(struct drm_device *dev); -extern int psbfb_remove(struct drm_device *dev, - struct drm_framebuffer *fb); -/* - * accel_2d.c - */ -extern void psbfb_copyarea(struct fb_info *info, - const struct fb_copyarea *region); -extern int psbfb_sync(struct fb_info *info); -extern void psb_spank(struct drm_psb_private *dev_priv); - -/* - * psb_reset.c - */ - -extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); -extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv); -extern void psb_print_pagefault(struct drm_psb_private *dev_priv); - -/* modesetting */ -extern void psb_modeset_init(struct drm_device *dev); -extern void psb_modeset_cleanup(struct drm_device *dev); -extern int psb_fbdev_init(struct drm_device *dev); - -/* backlight.c */ -int gma_backlight_init(struct drm_device *dev); -void gma_backlight_exit(struct drm_device *dev); - -/* oaktrail_crtc.c */ -extern const struct drm_crtc_helper_funcs oaktrail_helper_funcs; - -/* oaktrail_lvds.c */ -extern void oaktrail_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); - -/* psb_intel_display.c */ -extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs; -extern const struct drm_crtc_funcs psb_intel_crtc_funcs; - -/* psb_intel_lvds.c */ -extern const struct drm_connector_helper_funcs - psb_intel_lvds_connector_helper_funcs; -extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; - -/* gem.c */ -extern int psb_gem_init_object(struct drm_gem_object *obj); -extern void psb_gem_free_object(struct drm_gem_object *obj); -extern int psb_gem_get_aperture(struct drm_device *dev, void *data, - struct drm_file *file); -extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args); -extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, - uint32_t handle); -extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset); -extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); -extern int psb_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file); -extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file); - -/* psb_device.c */ -extern const struct psb_ops psb_chip_ops; - -/* oaktrail_device.c */ -extern const struct psb_ops oaktrail_chip_ops; - -/* mdlfd_device.c */ -extern const struct psb_ops mdfld_chip_ops; - -/* cdv_device.c */ -extern const struct psb_ops cdv_chip_ops; - -/* - * Debug print bits setting - */ -#define PSB_D_GENERAL (1 << 0) -#define PSB_D_INIT (1 << 1) -#define PSB_D_IRQ (1 << 2) -#define PSB_D_ENTRY (1 << 3) -/* debug the get H/V BP/FP count */ -#define PSB_D_HV (1 << 4) -#define PSB_D_DBI_BF (1 << 5) -#define PSB_D_PM (1 << 6) -#define PSB_D_RENDER (1 << 7) -#define PSB_D_REG (1 << 8) -#define PSB_D_MSVDX (1 << 9) -#define PSB_D_TOPAZ (1 << 10) - -extern int drm_psb_no_fb; -extern int drm_idle_check_interval; - -/* - * Utilities - */ - -static inline u32 MRST_MSG_READ32(uint port, uint offset) -{ - int mcr = (0xD0<<24) | (port << 16) | (offset << 8); - uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - pci_write_config_dword(pci_root, 0xD0, mcr); - pci_read_config_dword(pci_root, 0xD4, &ret_val); - pci_dev_put(pci_root); - return ret_val; -} -static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value) -{ - int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - pci_write_config_dword(pci_root, 0xD4, value); - pci_write_config_dword(pci_root, 0xD0, mcr); - pci_dev_put(pci_root); -} -static inline u32 MDFLD_MSG_READ32(uint port, uint offset) -{ - int mcr = (0x10<<24) | (port << 16) | (offset << 8); - uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - pci_write_config_dword(pci_root, 0xD0, mcr); - pci_read_config_dword(pci_root, 0xD4, &ret_val); - pci_dev_put(pci_root); - return ret_val; -} -static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value) -{ - int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - pci_write_config_dword(pci_root, 0xD4, value); - pci_write_config_dword(pci_root, 0xD0, mcr); - pci_dev_put(pci_root); -} - -static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - return ioread32(dev_priv->vdc_reg + reg); -} - -#define REG_READ(reg) REGISTER_READ(dev, (reg)) - -static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, - uint32_t val) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - iowrite32((val), dev_priv->vdc_reg + (reg)); -} - -#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) - -static inline void REGISTER_WRITE16(struct drm_device *dev, - uint32_t reg, uint32_t val) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - iowrite16((val), dev_priv->vdc_reg + (reg)); -} - -#define REG_WRITE16(reg, val) REGISTER_WRITE16(dev, (reg), (val)) - -static inline void REGISTER_WRITE8(struct drm_device *dev, - uint32_t reg, uint32_t val) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - iowrite8((val), dev_priv->vdc_reg + (reg)); -} - -#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val)) - -#define PSB_WVDC32(_val, _offs) iowrite32(_val, dev_priv->vdc_reg + (_offs)) -#define PSB_RVDC32(_offs) ioread32(dev_priv->vdc_reg + (_offs)) - -/* #define TRAP_SGX_PM_FAULT 1 */ -#ifdef TRAP_SGX_PM_FAULT -#define PSB_RSGX32(_offs) \ -({ \ - if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ - printk(KERN_ERR \ - "access sgx when it's off!! (READ) %s, %d\n", \ - __FILE__, __LINE__); \ - melay(1000); \ - } \ - ioread32(dev_priv->sgx_reg + (_offs)); \ -}) -#else -#define PSB_RSGX32(_offs) ioread32(dev_priv->sgx_reg + (_offs)) -#endif -#define PSB_WSGX32(_val, _offs) iowrite32(_val, dev_priv->sgx_reg + (_offs)) - -#define MSVDX_REG_DUMP 0 - -#define PSB_WMSVDX32(_val, _offs) iowrite32(_val, dev_priv->msvdx_reg + (_offs)) -#define PSB_RMSVDX32(_offs) ioread32(dev_priv->msvdx_reg + (_offs)) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.c deleted file mode 100644 index 26165584..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.c +++ /dev/null @@ -1,1436 +0,0 @@ -/* - * Copyright © 2006-2011 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - */ - -#include -#include - -#include -#include "framebuffer.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_display.h" -#include "power.h" - -struct psb_intel_clock_t { - /* given values */ - int n; - int m1, m2; - int p1, p2; - /* derived values */ - int dot; - int vco; - int m; - int p; -}; - -struct psb_intel_range_t { - int min, max; -}; - -struct psb_intel_p2_t { - int dot_limit; - int p2_slow, p2_fast; -}; - -#define INTEL_P2_NUM 2 - -struct psb_intel_limit_t { - struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1; - struct psb_intel_p2_t p2; -}; - -#define I8XX_DOT_MIN 25000 -#define I8XX_DOT_MAX 350000 -#define I8XX_VCO_MIN 930000 -#define I8XX_VCO_MAX 1400000 -#define I8XX_N_MIN 3 -#define I8XX_N_MAX 16 -#define I8XX_M_MIN 96 -#define I8XX_M_MAX 140 -#define I8XX_M1_MIN 18 -#define I8XX_M1_MAX 26 -#define I8XX_M2_MIN 6 -#define I8XX_M2_MAX 16 -#define I8XX_P_MIN 4 -#define I8XX_P_MAX 128 -#define I8XX_P1_MIN 2 -#define I8XX_P1_MAX 33 -#define I8XX_P1_LVDS_MIN 1 -#define I8XX_P1_LVDS_MAX 6 -#define I8XX_P2_SLOW 4 -#define I8XX_P2_FAST 2 -#define I8XX_P2_LVDS_SLOW 14 -#define I8XX_P2_LVDS_FAST 14 /* No fast option */ -#define I8XX_P2_SLOW_LIMIT 165000 - -#define I9XX_DOT_MIN 20000 -#define I9XX_DOT_MAX 400000 -#define I9XX_VCO_MIN 1400000 -#define I9XX_VCO_MAX 2800000 -#define I9XX_N_MIN 3 -#define I9XX_N_MAX 8 -#define I9XX_M_MIN 70 -#define I9XX_M_MAX 120 -#define I9XX_M1_MIN 10 -#define I9XX_M1_MAX 20 -#define I9XX_M2_MIN 5 -#define I9XX_M2_MAX 9 -#define I9XX_P_SDVO_DAC_MIN 5 -#define I9XX_P_SDVO_DAC_MAX 80 -#define I9XX_P_LVDS_MIN 7 -#define I9XX_P_LVDS_MAX 98 -#define I9XX_P1_MIN 1 -#define I9XX_P1_MAX 8 -#define I9XX_P2_SDVO_DAC_SLOW 10 -#define I9XX_P2_SDVO_DAC_FAST 5 -#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 -#define I9XX_P2_LVDS_SLOW 14 -#define I9XX_P2_LVDS_FAST 7 -#define I9XX_P2_LVDS_SLOW_LIMIT 112000 - -#define INTEL_LIMIT_I8XX_DVO_DAC 0 -#define INTEL_LIMIT_I8XX_LVDS 1 -#define INTEL_LIMIT_I9XX_SDVO_DAC 2 -#define INTEL_LIMIT_I9XX_LVDS 3 - -static const struct psb_intel_limit_t psb_intel_limits[] = { - { /* INTEL_LIMIT_I8XX_DVO_DAC */ - .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, - .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, - .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, - .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, - .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, - .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, - .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, - .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX}, - .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST}, - }, - { /* INTEL_LIMIT_I8XX_LVDS */ - .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, - .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, - .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, - .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, - .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, - .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, - .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, - .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX}, - .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST}, - }, - { /* INTEL_LIMIT_I9XX_SDVO_DAC */ - .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, - .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, - .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, - .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, - .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, - .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX}, - .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, - .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = - I9XX_P2_SDVO_DAC_FAST}, - }, - { /* INTEL_LIMIT_I9XX_LVDS */ - .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, - .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, - .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, - .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, - .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, - .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX}, - .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, - /* The single-channel range is 25-112Mhz, and dual-channel - * is 80-224Mhz. Prefer single channel as much as possible. - */ - .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST}, - }, -}; - -static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc) -{ - const struct psb_intel_limit_t *limit; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS]; - else - limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; - return limit; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ - -static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -static void psb_intel_clock(struct drm_device *dev, int refclk, - struct psb_intel_clock_t *clock) -{ - return i9xx_clock(refclk, clock); -} - -/** - * Returns whether any output on the specified pipe is of the specified type - */ -bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *l_entry; - - list_for_each_entry(l_entry, &mode_config->connector_list, head) { - if (l_entry->encoder && l_entry->encoder->crtc == crtc) { - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(l_entry); - if (psb_intel_encoder->type == type) - return true; - } - } - return false; -} - -#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } -/** - * Returns whether the given set of divisors are valid for a given refclk with - * the given connectors. - */ - -static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc, - struct psb_intel_clock_t *clock) -{ - const struct psb_intel_limit_t *limit = psb_intel_limit(crtc); - - if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) - INTELPllInvalid("p1 out of range\n"); - if (clock->p < limit->p.min || limit->p.max < clock->p) - INTELPllInvalid("p out of range\n"); - if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) - INTELPllInvalid("m2 out of range\n"); - if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) - INTELPllInvalid("m1 out of range\n"); - if (clock->m1 <= clock->m2) - INTELPllInvalid("m1 <= m2\n"); - if (clock->m < limit->m.min || limit->m.max < clock->m) - INTELPllInvalid("m out of range\n"); - if (clock->n < limit->n.min || limit->n.max < clock->n) - INTELPllInvalid("n out of range\n"); - if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) - INTELPllInvalid("vco out of range\n"); - /* XXX: We may need to be checking "Dot clock" - * depending on the multiplier, connector, etc., - * rather than just a single range. - */ - if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) - INTELPllInvalid("dot out of range\n"); - - return true; -} - -/** - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ -static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target, - int refclk, - struct psb_intel_clock_t *best_clock) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_clock_t clock; - const struct psb_intel_limit_t *limit = psb_intel_limit(crtc); - int err = target; - - if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - (REG_READ(LVDS) & LVDS_PORT_EN) != 0) { - /* - * For LVDS, if the panel is on, just rely on its current - * settings for dual-channel. We haven't figured out how to - * reliably set up different single/dual channel state, if we - * even can. - */ - if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset(best_clock, 0, sizeof(*best_clock)); - - for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; - clock.m1++) { - for (clock.m2 = limit->m2.min; - clock.m2 < clock.m1 && clock.m2 <= limit->m2.max; - clock.m2++) { - for (clock.n = limit->n.min; - clock.n <= limit->n.max; clock.n++) { - for (clock.p1 = limit->p1.min; - clock.p1 <= limit->p1.max; - clock.p1++) { - int this_err; - - psb_intel_clock(dev, refclk, &clock); - - if (!psb_intel_PLL_is_valid - (crtc, &clock)) - continue; - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - } - } - - return err != target; -} - -void psb_intel_wait_for_vblank(struct drm_device *dev) -{ - /* Wait for 20ms, i.e. one cycle at 50hz. */ - mdelay(20); -} - -static int psb_intel_pipe_set_base(struct drm_crtc *crtc, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); - int pipe = psb_intel_crtc->pipe; - unsigned long start, offset; - int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); - int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - u32 dspcntr; - int ret = 0; - - if (!gma_power_begin(dev, true)) - return 0; - - /* no fb bound */ - if (!crtc->fb) { - dev_dbg(dev->dev, "No FB bound\n"); - goto psb_intel_pipe_cleaner; - } - - /* We are displaying this buffer, make sure it is actually loaded - into the GTT */ - ret = psb_gtt_pin(psbfb->gtt); - if (ret < 0) - goto psb_intel_pipe_set_base_exit; - start = psbfb->gtt->offset; - - offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - - REG_WRITE(dspstride, crtc->fb->pitches[0]); - - dspcntr = REG_READ(dspcntr_reg); - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - - switch (crtc->fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (crtc->fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - dev_err(dev->dev, "Unknown color depth\n"); - ret = -EINVAL; - psb_gtt_unpin(psbfb->gtt); - goto psb_intel_pipe_set_base_exit; - } - REG_WRITE(dspcntr_reg, dspcntr); - - - if (0 /* FIXMEAC - check what PSB needs */) { - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - } else { - REG_WRITE(dspbase, start + offset); - REG_READ(dspbase); - } - -psb_intel_pipe_cleaner: - /* If there was a previous display we can now unpin it */ - if (old_fb) - psb_gtt_unpin(to_psb_fb(old_fb)->gtt); - -psb_intel_pipe_set_base_exit: - gma_power_end(dev); - return ret; -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ - /* struct drm_i915_private *dev_priv = dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - u32 temp; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - /* Enable the DPLL */ - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(dpll_reg, temp); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - } - - /* Enable the pipe */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); - - /* Enable the plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(dspcntr_reg, - temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - } - - psb_intel_crtc_load_lut(crtc); - - /* Give the overlay scaler a chance to enable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, true); TODO */ - break; - case DRM_MODE_DPMS_OFF: - /* Give the overlay scaler a chance to disable - * if it's on this pipe */ - /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ - - /* Disable the VGA plane that we never use */ - REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); - - /* Disable display plane */ - temp = REG_READ(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(dspcntr_reg, - temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); - REG_READ(dspbase_reg); - } - - /* Next, disable display pipes */ - temp = REG_READ(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - REG_READ(pipeconf_reg); - } - - /* Wait for vblank for the disable to take effect. */ - psb_intel_wait_for_vblank(dev); - - temp = REG_READ(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - } - - /* Wait for the clocks to turn off. */ - udelay(150); - break; - } - - /*Set FIFO Watermarks*/ - REG_WRITE(DSPARB, 0x3F3E); -} - -static void psb_intel_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void psb_intel_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -} - -void psb_intel_encoder_prepare(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = - encoder->helper_private; - /* lvds has its own version of prepare see psb_intel_lvds_prepare */ - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); -} - -void psb_intel_encoder_commit(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = - encoder->helper_private; - /* lvds has its own version of commit see psb_intel_lvds_commit */ - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); -} - -void psb_intel_encoder_destroy(struct drm_encoder *encoder) -{ - struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); - - drm_encoder_cleanup(encoder); - kfree(intel_encoder); -} - -static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int psb_intel_panel_fitter_pipe(struct drm_device *dev) -{ - u32 pfit_control; - - pfit_control = REG_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - /* Must be on PIPE 1 for PSB */ - return 1; -} - -static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - int pipe = psb_intel_crtc->pipe; - int fp_reg = (pipe == 0) ? FPA0 : FPB0; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; - int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; - int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; - int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; - int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; - int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; - int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; - int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk; - struct psb_intel_clock_t clock; - u32 dpll = 0, fp = 0, dspcntr, pipeconf; - bool ok, is_sdvo = false; - bool is_lvds = false, is_tv = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - /* No scan out no play */ - if (crtc->fb == NULL) { - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - return 0; - } - - list_for_each_entry(connector, &mode_config->connector_list, head) { - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - - if (!connector->encoder - || connector->encoder->crtc != crtc) - continue; - - switch (psb_intel_encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - is_sdvo = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - } - } - - refclk = 96000; - - ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, - &clock); - if (!ok) { - dev_err(dev->dev, "Couldn't find PLL settings for mode!\n"); - return 0; - } - - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - - dpll = DPLL_VGA_MODE_DIS; - if (is_lvds) { - dpll |= DPLLB_MODE_LVDS; - dpll |= DPLL_DVO_HIGH_SPEED; - } else - dpll |= DPLLB_MODE_DAC_SERIAL; - if (is_sdvo) { - int sdvo_pixel_multiply = - adjusted_mode->clock / mode->clock; - dpll |= DPLL_DVO_HIGH_SPEED; - dpll |= - (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - } - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 1)) << 16; - switch (clock.p2) { - case 5: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; - break; - case 7: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; - break; - case 10: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; - break; - case 14: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; - break; - } - - if (is_tv) { - /* XXX: just matching BIOS for now */ -/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - } - dpll |= PLL_REF_INPUT_DREFCLK; - - /* setup pipeconf */ - pipeconf = REG_READ(pipeconf_reg); - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr |= DISPPLANE_SEL_PIPE_A; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - dspcntr |= DISPLAY_PLANE_ENABLE; - pipeconf |= PIPEACONF_ENABLE; - dpll |= DPLL_VCO_ENABLE; - - - /* Disable the panel fitter if it was on our pipe */ - if (psb_intel_panel_fitter_pipe(dev) == pipe) - REG_WRITE(PFIT_CONTROL, 0); - - drm_mode_debug_printmodeline(mode); - - if (dpll & DPLL_VCO_ENABLE) { - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - REG_READ(dpll_reg); - udelay(150); - } - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) { - u32 lvds = REG_READ(LVDS); - - lvds &= ~LVDS_PIPEB_SELECT; - if (pipe == 1) - lvds |= LVDS_PIPEB_SELECT; - - lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - /* Set the B0-B3 data pairs corresponding to - * whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - if (clock.p2 == 7) - lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more - * thoroughly into how panels behave in the two modes. - */ - - REG_WRITE(LVDS, lvds); - REG_READ(LVDS); - } - - REG_WRITE(fp_reg, fp); - REG_WRITE(dpll_reg, dpll); - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - /* write it again -- the BIOS does, after all */ - REG_WRITE(dpll_reg, dpll); - - REG_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - REG_WRITE(dspsize_reg, - ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(dsppos_reg, 0); - REG_WRITE(pipesrc_reg, - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(pipeconf_reg, pipeconf); - REG_READ(pipeconf_reg); - - psb_intel_wait_for_vblank(dev); - - REG_WRITE(dspcntr_reg, dspcntr); - - /* Flush the plane changes */ - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - - psb_intel_wait_for_vblank(dev); - - return 0; -} - -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -void psb_intel_crtc_load_lut(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int palreg = PALETTE_A; - int i; - - /* The clocks have to be on to load the palette. */ - if (!crtc->enabled) - return; - - switch (psb_intel_crtc->pipe) { - case 0: - break; - case 1: - palreg = PALETTE_B; - break; - case 2: - palreg = PALETTE_C; - break; - default: - dev_err(dev->dev, "Illegal Pipe Number.\n"); - return; - } - - if (gma_power_begin(dev, false)) { - for (i = 0; i < 256; i++) { - REG_WRITE(palreg + 4 * i, - ((psb_intel_crtc->lut_r[i] + - psb_intel_crtc->lut_adj[i]) << 16) | - ((psb_intel_crtc->lut_g[i] + - psb_intel_crtc->lut_adj[i]) << 8) | - (psb_intel_crtc->lut_b[i] + - psb_intel_crtc->lut_adj[i])); - } - gma_power_end(dev); - } else { - for (i = 0; i < 256; i++) { - dev_priv->regs.psb.save_palette_a[i] = - ((psb_intel_crtc->lut_r[i] + - psb_intel_crtc->lut_adj[i]) << 16) | - ((psb_intel_crtc->lut_g[i] + - psb_intel_crtc->lut_adj[i]) << 8) | - (psb_intel_crtc->lut_b[i] + - psb_intel_crtc->lut_adj[i]); - } - - } -} - -/** - * Save HW states of giving crtc - */ -static void psb_intel_crtc_save(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - int pipeA = (psb_intel_crtc->pipe == 0); - uint32_t paletteReg; - int i; - - if (!crtc_state) { - dev_err(dev->dev, "No CRTC state found\n"); - return; - } - - crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); - crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); - crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); - crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); - crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); - crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); - crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); - crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); - crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); - crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); - crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); - crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); - crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); - - /*NOTE: DSPSIZE DSPPOS only for psb*/ - crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); - crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); - - crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); - - paletteReg = pipeA ? PALETTE_A : PALETTE_B; - for (i = 0; i < 256; ++i) - crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); -} - -/** - * Restore HW states of giving crtc - */ -static void psb_intel_crtc_restore(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - /* struct drm_psb_private * dev_priv = - (struct drm_psb_private *)dev->dev_private; */ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ - int pipeA = (psb_intel_crtc->pipe == 0); - uint32_t paletteReg; - int i; - - if (!crtc_state) { - dev_err(dev->dev, "No crtc state\n"); - return; - } - - if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { - REG_WRITE(pipeA ? DPLL_A : DPLL_B, - crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); - REG_READ(pipeA ? DPLL_A : DPLL_B); - udelay(150); - } - - REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); - REG_READ(pipeA ? FPA0 : FPB0); - - REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); - REG_READ(pipeA ? FPA1 : FPB1); - - REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); - REG_READ(pipeA ? DPLL_A : DPLL_B); - udelay(150); - - REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); - REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); - REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); - REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); - REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); - REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); - REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); - - REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); - REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); - - REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); - REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); - REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); - - psb_intel_wait_for_vblank(dev); - - REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); - REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); - - psb_intel_wait_for_vblank(dev); - - paletteReg = pipeA ? PALETTE_A : PALETTE_B; - for (i = 0; i < 256; ++i) - REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); -} - -static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, uint32_t height) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; - uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; - uint32_t temp; - size_t addr = 0; - struct gtt_range *gt; - struct drm_gem_object *obj; - int ret; - - /* if we want to turn of the cursor ignore width and height */ - if (!handle) { - /* turn off the cursor */ - temp = CURSOR_MODE_DISABLE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(control, temp); - REG_WRITE(base, 0); - gma_power_end(dev); - } - - /* Unpin the old GEM object */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = NULL; - } - - return 0; - } - - /* Currently we only support 64x64 cursors */ - if (width != 64 || height != 64) { - dev_dbg(dev->dev, "we currently only support 64x64 cursors\n"); - return -EINVAL; - } - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) - return -ENOENT; - - if (obj->size < width * height * 4) { - dev_dbg(dev->dev, "buffer is to small\n"); - return -ENOMEM; - } - - gt = container_of(obj, struct gtt_range, gem); - - /* Pin the memory into the GTT */ - ret = psb_gtt_pin(gt); - if (ret) { - dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); - return ret; - } - - - addr = gt->offset; /* Or resource.start ??? */ - - psb_intel_crtc->cursor_addr = addr; - - temp = 0; - /* set the pipe for the cursor */ - temp |= (pipe << 28); - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - - if (gma_power_begin(dev, false)) { - REG_WRITE(control, temp); - REG_WRITE(base, addr); - gma_power_end(dev); - } - - /* unpin the old bo */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = obj; - } - return 0; -} - -static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct drm_device *dev = crtc->dev; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - uint32_t temp = 0; - uint32_t addr; - - - if (x < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); - x = -x; - } - if (y < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); - y = -y; - } - - temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); - temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); - - addr = psb_intel_crtc->cursor_addr; - - if (gma_power_begin(dev, false)) { - REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); - REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr); - gma_power_end(dev); - } - return 0; -} - -void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, uint32_t type, uint32_t size) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int i; - - if (size != 256) - return; - - for (i = 0; i < 256; i++) { - psb_intel_crtc->lut_r[i] = red[i] >> 8; - psb_intel_crtc->lut_g[i] = green[i] >> 8; - psb_intel_crtc->lut_b[i] = blue[i] >> 8; - } - - psb_intel_crtc_load_lut(crtc); -} - -static int psb_crtc_set_config(struct drm_mode_set *set) -{ - int ret; - struct drm_device *dev = set->crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->rpm_enabled) - return drm_crtc_helper_set_config(set); - - pm_runtime_forbid(&dev->pdev->dev); - ret = drm_crtc_helper_set_config(set); - pm_runtime_allow(&dev->pdev->dev); - return ret; -} - -/* Returns the clock of the currently programmed mode of the given pipe. */ -static int psb_intel_crtc_clock_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - u32 dpll; - u32 fp; - struct psb_intel_clock_t clock; - bool is_lvds; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (gma_power_begin(dev, false)) { - dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = REG_READ((pipe == 0) ? FPA0 : FPB0); - else - fp = REG_READ((pipe == 0) ? FPA1 : FPB1); - is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); - gma_power_end(dev); - } else { - dpll = (pipe == 0) ? - dev_priv->regs.psb.saveDPLL_A : - dev_priv->regs.psb.saveDPLL_B; - - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = (pipe == 0) ? - dev_priv->regs.psb.saveFPA0 : - dev_priv->regs.psb.saveFPB0; - else - fp = (pipe == 0) ? - dev_priv->regs.psb.saveFPA1 : - dev_priv->regs.psb.saveFPB1; - - is_lvds = (pipe == 1) && (dev_priv->regs.psb.saveLVDS & - LVDS_PORT_EN); - } - - clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; - clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; - - if (is_lvds) { - clock.p1 = - ffs((dpll & - DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - clock.p2 = 14; - - if ((dpll & PLL_REF_INPUT_MASK) == - PLLB_REF_INPUT_SPREADSPECTRUMIN) { - /* XXX: might not be 66MHz */ - i8xx_clock(66000, &clock); - } else - i8xx_clock(48000, &clock); - } else { - if (dpll & PLL_P1_DIVIDE_BY_TWO) - clock.p1 = 2; - else { - clock.p1 = - ((dpll & - DPLL_FPA01_P1_POST_DIV_MASK_I830) >> - DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; - } - if (dpll & PLL_P2_DIVIDE_BY_4) - clock.p2 = 4; - else - clock.p2 = 2; - - i8xx_clock(48000, &clock); - } - - /* XXX: It would be nice to validate the clocks, but we can't reuse - * i830PllIsValid() because it relies on the xf86_config connector - * configuration being accurate, which it isn't necessarily. - */ - - return clock.dot; -} - -/** Returns the currently programmed mode of the given pipe. */ -struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - int pipe = psb_intel_crtc->pipe; - struct drm_display_mode *mode; - int htot; - int hsync; - int vtot; - int vsync; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (gma_power_begin(dev, false)) { - htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); - hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); - vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); - vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); - gma_power_end(dev); - } else { - htot = (pipe == 0) ? - dev_priv->regs.psb.saveHTOTAL_A : - dev_priv->regs.psb.saveHTOTAL_B; - hsync = (pipe == 0) ? - dev_priv->regs.psb.saveHSYNC_A : - dev_priv->regs.psb.saveHSYNC_B; - vtot = (pipe == 0) ? - dev_priv->regs.psb.saveVTOTAL_A : - dev_priv->regs.psb.saveVTOTAL_B; - vsync = (pipe == 0) ? - dev_priv->regs.psb.saveVSYNC_A : - dev_priv->regs.psb.saveVSYNC_B; - } - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - mode->clock = psb_intel_crtc_clock_get(dev, crtc); - mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - return mode; -} - -void psb_intel_crtc_destroy(struct drm_crtc *crtc) -{ - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct gtt_range *gt; - - /* Unpin the old GEM object */ - if (psb_intel_crtc->cursor_obj) { - gt = container_of(psb_intel_crtc->cursor_obj, - struct gtt_range, gem); - psb_gtt_unpin(gt); - drm_gem_object_unreference(psb_intel_crtc->cursor_obj); - psb_intel_crtc->cursor_obj = NULL; - } - kfree(psb_intel_crtc->crtc_state); - drm_crtc_cleanup(crtc); - kfree(psb_intel_crtc); -} - -const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { - .dpms = psb_intel_crtc_dpms, - .mode_fixup = psb_intel_crtc_mode_fixup, - .mode_set = psb_intel_crtc_mode_set, - .mode_set_base = psb_intel_pipe_set_base, - .prepare = psb_intel_crtc_prepare, - .commit = psb_intel_crtc_commit, -}; - -const struct drm_crtc_funcs psb_intel_crtc_funcs = { - .save = psb_intel_crtc_save, - .restore = psb_intel_crtc_restore, - .cursor_set = psb_intel_crtc_cursor_set, - .cursor_move = psb_intel_crtc_cursor_move, - .gamma_set = psb_intel_crtc_gamma_set, - .set_config = psb_crtc_set_config, - .destroy = psb_intel_crtc_destroy, -}; - -/* - * Set the default value of cursor control and base register - * to zero. This is a workaround for h/w defect on Oaktrail - */ -static void psb_intel_cursor_init(struct drm_device *dev, int pipe) -{ - u32 control[3] = { CURACNTR, CURBCNTR, CURCCNTR }; - u32 base[3] = { CURABASE, CURBBASE, CURCBASE }; - - REG_WRITE(control[pipe], 0); - REG_WRITE(base[pipe], 0); -} - -void psb_intel_crtc_init(struct drm_device *dev, int pipe, - struct psb_intel_mode_device *mode_dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_crtc *psb_intel_crtc; - int i; - uint16_t *r_base, *g_base, *b_base; - - /* We allocate a extra array of drm_connector pointers - * for fbdev after the crtc */ - psb_intel_crtc = - kzalloc(sizeof(struct psb_intel_crtc) + - (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), - GFP_KERNEL); - if (psb_intel_crtc == NULL) - return; - - psb_intel_crtc->crtc_state = - kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL); - if (!psb_intel_crtc->crtc_state) { - dev_err(dev->dev, "Crtc state error: No memory\n"); - kfree(psb_intel_crtc); - return; - } - - /* Set the CRTC operations from the chip specific data */ - drm_crtc_init(dev, &psb_intel_crtc->base, dev_priv->ops->crtc_funcs); - - drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256); - psb_intel_crtc->pipe = pipe; - psb_intel_crtc->plane = pipe; - - r_base = psb_intel_crtc->base.gamma_store; - g_base = r_base + 256; - b_base = g_base + 256; - for (i = 0; i < 256; i++) { - psb_intel_crtc->lut_r[i] = i; - psb_intel_crtc->lut_g[i] = i; - psb_intel_crtc->lut_b[i] = i; - r_base[i] = i << 8; - g_base[i] = i << 8; - b_base[i] = i << 8; - - psb_intel_crtc->lut_adj[i] = 0; - } - - psb_intel_crtc->mode_dev = mode_dev; - psb_intel_crtc->cursor_addr = 0; - - drm_crtc_helper_add(&psb_intel_crtc->base, - dev_priv->ops->crtc_helper); - - /* Setup the array of drm_connector pointer array */ - psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base; - BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || - dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL); - dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] = - &psb_intel_crtc->base; - dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] = - &psb_intel_crtc->base; - psb_intel_crtc->mode_set.connectors = - (struct drm_connector **) (psb_intel_crtc + 1); - psb_intel_crtc->mode_set.num_connectors = 0; - psb_intel_cursor_init(dev, pipe); -} - -int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data; - struct drm_mode_object *drmmode_obj; - struct psb_intel_crtc *crtc; - - if (!dev_priv) { - dev_err(dev->dev, "called with no initialization\n"); - return -EINVAL; - } - - drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, - DRM_MODE_OBJECT_CRTC); - - if (!drmmode_obj) { - dev_err(dev->dev, "no such CRTC id\n"); - return -EINVAL; - } - - crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj)); - pipe_from_crtc_id->pipe = crtc->pipe; - - return 0; -} - -struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) -{ - struct drm_crtc *crtc = NULL; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - if (psb_intel_crtc->pipe == pipe) - break; - } - return crtc; -} - -int psb_intel_connector_clones(struct drm_device *dev, int type_mask) -{ - int index_mask = 0; - struct drm_connector *connector; - int entry = 0; - - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - if (type_mask & (1 << psb_intel_encoder->type)) - index_mask |= (1 << entry); - entry++; - } - return index_mask; -} - -/* current intel driver doesn't take advantage of encoders - always give back the encoder for the connector -*/ -struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - - return &psb_intel_encoder->base; -} - -void psb_intel_connector_attach_encoder(struct psb_intel_connector *connector, - struct psb_intel_encoder *encoder) -{ - connector->encoder = encoder; - drm_mode_connector_attach_encoder(&connector->base, - &encoder->base); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.h deleted file mode 100644 index 535b49a5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_display.h +++ /dev/null @@ -1,28 +0,0 @@ -/* copyright (c) 2008, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - */ - -#ifndef _INTEL_DISPLAY_H_ -#define _INTEL_DISPLAY_H_ - -bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type); -void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, - u16 *green, u16 *blue, uint32_t type, uint32_t size); -void psb_intel_crtc_destroy(struct drm_crtc *crtc); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_drv.h deleted file mode 100644 index f40535e5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_drv.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2009-2011, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef __INTEL_DRV_H__ -#define __INTEL_DRV_H__ - -#include -#include -#include -#include -#include - -/* - * Display related stuff - */ - -/* store information about an Ixxx DVO */ -/* The i830->i865 use multiple DVOs with multiple i2cs */ -/* the i915, i945 have a single sDVO i2c bus - which is different */ -#define MAX_OUTPUTS 6 -/* maximum connectors per crtcs in the mode set */ -#define INTELFB_CONN_LIMIT 4 - -#define INTEL_I2C_BUS_DVO 1 -#define INTEL_I2C_BUS_SDVO 2 - -/* Intel Pipe Clone Bit */ -#define INTEL_HDMIB_CLONE_BIT 1 -#define INTEL_HDMIC_CLONE_BIT 2 -#define INTEL_HDMID_CLONE_BIT 3 -#define INTEL_HDMIE_CLONE_BIT 4 -#define INTEL_HDMIF_CLONE_BIT 5 -#define INTEL_SDVO_NON_TV_CLONE_BIT 6 -#define INTEL_SDVO_TV_CLONE_BIT 7 -#define INTEL_SDVO_LVDS_CLONE_BIT 8 -#define INTEL_ANALOG_CLONE_BIT 9 -#define INTEL_TV_CLONE_BIT 10 -#define INTEL_DP_B_CLONE_BIT 11 -#define INTEL_DP_C_CLONE_BIT 12 -#define INTEL_DP_D_CLONE_BIT 13 -#define INTEL_LVDS_CLONE_BIT 14 -#define INTEL_DVO_TMDS_CLONE_BIT 15 -#define INTEL_DVO_LVDS_CLONE_BIT 16 -#define INTEL_EDP_CLONE_BIT 17 - -/* these are outputs from the chip - integrated only - * external chips are via DVO or SDVO output */ -#define INTEL_OUTPUT_UNUSED 0 -#define INTEL_OUTPUT_ANALOG 1 -#define INTEL_OUTPUT_DVO 2 -#define INTEL_OUTPUT_SDVO 3 -#define INTEL_OUTPUT_LVDS 4 -#define INTEL_OUTPUT_TVOUT 5 -#define INTEL_OUTPUT_HDMI 6 -#define INTEL_OUTPUT_MIPI 7 -#define INTEL_OUTPUT_MIPI2 8 - -#define INTEL_DVO_CHIP_NONE 0 -#define INTEL_DVO_CHIP_LVDS 1 -#define INTEL_DVO_CHIP_TMDS 2 -#define INTEL_DVO_CHIP_TVOUT 4 - -#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) -#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) - -static inline void -psb_intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, - int multiplier) -{ - mode->clock *= multiplier; - mode->private_flags |= multiplier; -} - -static inline int -psb_intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) -{ - return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) - >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT; -} - - -/* - * Hold information useally put on the device driver privates here, - * since it needs to be shared across multiple of devices drivers privates. - */ -struct psb_intel_mode_device { - - /* - * Abstracted memory manager operations - */ - size_t(*bo_offset) (struct drm_device *dev, void *bo); - - /* - * Cursor (Can go ?) - */ - int cursor_needs_physical; - - /* - * LVDS info - */ - int backlight_duty_cycle; /* restore backlight to this value */ - bool panel_wants_dither; - struct drm_display_mode *panel_fixed_mode; - struct drm_display_mode *panel_fixed_mode2; - struct drm_display_mode *vbt_mode; /* if any */ - - uint32_t saveBLC_PWM_CTL; -}; - -struct psb_intel_i2c_chan { - /* for getting at dev. private (mmio etc.) */ - struct drm_device *drm_dev; - u32 reg; /* GPIO reg */ - struct i2c_adapter adapter; - struct i2c_algo_bit_data algo; - u8 slave_addr; -}; - -struct psb_intel_encoder { - struct drm_encoder base; - int type; - bool needs_tv_clock; - void (*hot_plug)(struct psb_intel_encoder *); - int crtc_mask; - int clone_mask; - void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */ - - /* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's - own set of output privates */ - struct psb_intel_i2c_chan *i2c_bus; - struct psb_intel_i2c_chan *ddc_bus; -}; - -struct psb_intel_connector { - struct drm_connector base; - struct psb_intel_encoder *encoder; -}; - -struct psb_intel_crtc_state { - uint32_t saveDSPCNTR; - uint32_t savePIPECONF; - uint32_t savePIPESRC; - uint32_t saveDPLL; - uint32_t saveFP0; - uint32_t saveFP1; - uint32_t saveHTOTAL; - uint32_t saveHBLANK; - uint32_t saveHSYNC; - uint32_t saveVTOTAL; - uint32_t saveVBLANK; - uint32_t saveVSYNC; - uint32_t saveDSPSTRIDE; - uint32_t saveDSPSIZE; - uint32_t saveDSPPOS; - uint32_t saveDSPBASE; - uint32_t savePalette[256]; -}; - -struct psb_intel_crtc { - struct drm_crtc base; - int pipe; - int plane; - uint32_t cursor_addr; - u8 lut_r[256], lut_g[256], lut_b[256]; - u8 lut_adj[256]; - struct psb_intel_framebuffer *fbdev_fb; - /* a mode_set for fbdev users on this crtc */ - struct drm_mode_set mode_set; - - /* GEM object that holds our cursor */ - struct drm_gem_object *cursor_obj; - - struct drm_display_mode saved_mode; - struct drm_display_mode saved_adjusted_mode; - - struct psb_intel_mode_device *mode_dev; - - /*crtc mode setting flags*/ - u32 mode_flags; - - /* Saved Crtc HW states */ - struct psb_intel_crtc_state *crtc_state; -}; - -#define to_psb_intel_crtc(x) \ - container_of(x, struct psb_intel_crtc, base) -#define to_psb_intel_connector(x) \ - container_of(x, struct psb_intel_connector, base) -#define to_psb_intel_encoder(x) \ - container_of(x, struct psb_intel_encoder, base) -#define to_psb_intel_framebuffer(x) \ - container_of(x, struct psb_intel_framebuffer, base) - -struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, - const u32 reg, const char *name); -void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan); -int psb_intel_ddc_get_modes(struct drm_connector *connector, - struct i2c_adapter *adapter); -extern bool psb_intel_ddc_probe(struct i2c_adapter *adapter); - -extern void psb_intel_crtc_init(struct drm_device *dev, int pipe, - struct psb_intel_mode_device *mode_dev); -extern void psb_intel_crt_init(struct drm_device *dev); -extern bool psb_intel_sdvo_init(struct drm_device *dev, int output_device); -extern void psb_intel_dvo_init(struct drm_device *dev); -extern void psb_intel_tv_init(struct drm_device *dev); -extern void psb_intel_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level); -extern void oaktrail_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void oaktrail_wait_for_INTR_PKT_SENT(struct drm_device *dev); -extern void oaktrail_dsi_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev); -extern void mid_dsi_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev, int dsi_num); - -extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc); -extern void psb_intel_encoder_prepare(struct drm_encoder *encoder); -extern void psb_intel_encoder_commit(struct drm_encoder *encoder); -extern void psb_intel_encoder_destroy(struct drm_encoder *encoder); - -static inline struct psb_intel_encoder *psb_intel_attached_encoder( - struct drm_connector *connector) -{ - return to_psb_intel_connector(connector)->encoder; -} - -extern void psb_intel_connector_attach_encoder( - struct psb_intel_connector *connector, - struct psb_intel_encoder *encoder); - -extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector - *connector); - -extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc); -extern void psb_intel_wait_for_vblank(struct drm_device *dev); -extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, - int pipe); -extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, - int sdvoB); -extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector); -extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, - int enable); -extern int intelfb_probe(struct drm_device *dev); -extern int intelfb_remove(struct drm_device *dev, - struct drm_framebuffer *fb); -extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device - *dev, struct - drm_mode_fb_cmd - *mode_cmd, - void *mm_private); -extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode); -extern int psb_intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value); -extern void psb_intel_lvds_destroy(struct drm_connector *connector); -extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs; - -/* intel_gmbus.c */ -extern void gma_intel_i2c_reset(struct drm_device *dev); -extern int gma_intel_setup_gmbus(struct drm_device *dev); -extern void gma_intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); -extern void gma_intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); -extern void gma_intel_teardown_gmbus(struct drm_device *dev); - -#endif /* __INTEL_DRV_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_lvds.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_lvds.c deleted file mode 100644 index c83f5b5d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ /dev/null @@ -1,867 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Eric Anholt - * Dave Airlie - * Jesse Barnes - */ - -#include -#include - -#include "intel_bios.h" -#include "psb_drv.h" -#include "psb_intel_drv.h" -#include "psb_intel_reg.h" -#include "power.h" -#include - -/* - * LVDS I2C backlight control macros - */ -#define BRIGHTNESS_MAX_LEVEL 100 -#define BRIGHTNESS_MASK 0xFF -#define BLC_I2C_TYPE 0x01 -#define BLC_PWM_TYPT 0x02 - -#define BLC_POLARITY_NORMAL 0 -#define BLC_POLARITY_INVERSE 1 - -#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE) -#define PSB_BLC_MIN_PWM_REG_FREQ (0x2) -#define PSB_BLC_PWM_PRECISION_FACTOR (10) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) - -struct psb_intel_lvds_priv { - /* - * Saved LVDO output states - */ - uint32_t savePP_ON; - uint32_t savePP_OFF; - uint32_t saveLVDS; - uint32_t savePP_CONTROL; - uint32_t savePP_CYCLE; - uint32_t savePFIT_CONTROL; - uint32_t savePFIT_PGM_RATIOS; - uint32_t saveBLC_PWM_CTL; - - struct psb_intel_i2c_chan *i2c_bus; - struct psb_intel_i2c_chan *ddc_bus; -}; - - -/* - * Returns the maximum level of the backlight duty cycle field. - */ -static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 ret; - - if (gma_power_begin(dev, false)) { - ret = REG_READ(BLC_PWM_CTL); - gma_power_end(dev); - } else /* Powered off, use the saved value */ - ret = dev_priv->regs.saveBLC_PWM_CTL; - - /* Top 15bits hold the frequency mask */ - ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT; - - ret *= 2; /* Return a 16bit range as needed for setting */ - if (ret == 0) - dev_err(dev->dev, "BL bug: Reg %08x save %08X\n", - REG_READ(BLC_PWM_CTL), dev_priv->regs.saveBLC_PWM_CTL); - return ret; -} - -/* - * Set LVDS backlight level by I2C command - * - * FIXME: at some point we need to both track this for PM and also - * disable runtime pm on MRST if the brightness is nil (ie blanked) - */ -static int psb_lvds_i2c_set_brightness(struct drm_device *dev, - unsigned int level) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - - struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus; - u8 out_buf[2]; - unsigned int blc_i2c_brightness; - - struct i2c_msg msgs[] = { - { - .addr = lvds_i2c_bus->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - } - }; - - blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level * - BRIGHTNESS_MASK / - BRIGHTNESS_MAX_LEVEL); - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness; - - out_buf[0] = dev_priv->lvds_bl->brightnesscmd; - out_buf[1] = (u8)blc_i2c_brightness; - - if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) { - dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n", - dev_priv->lvds_bl->brightnesscmd, - blc_i2c_brightness); - return 0; - } - - dev_err(dev->dev, "I2C transfer error\n"); - return -1; -} - - -static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - - u32 max_pwm_blc; - u32 blc_pwm_duty_cycle; - - max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); - - /*BLC_PWM_CTL Should be initiated while backlight device init*/ - BUG_ON(max_pwm_blc == 0); - - blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; - - if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) - blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle; - - blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (blc_pwm_duty_cycle)); - - dev_info(dev->dev, "Backlight lvds set brightness %08x\n", - (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (blc_pwm_duty_cycle)); - - return 0; -} - -/* - * Set LVDS backlight level either by I2C or PWM - */ -void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - - dev_dbg(dev->dev, "backlight level is %d\n", level); - - if (!dev_priv->lvds_bl) { - dev_err(dev->dev, "NO LVDS backlight info\n"); - return; - } - - if (dev_priv->lvds_bl->type == BLC_I2C_TYPE) - psb_lvds_i2c_set_brightness(dev, level); - else - psb_lvds_pwm_set_brightness(dev, level); -} - -/* - * Sets the backlight level. - * - * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight(). - */ -static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 blc_pwm_ctl; - - if (gma_power_begin(dev, false)) { - blc_pwm_ctl = REG_READ(BLC_PWM_CTL); - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - REG_WRITE(BLC_PWM_CTL, - (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); - dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); - gma_power_end(dev); - } else { - blc_pwm_ctl = dev_priv->regs.saveBLC_PWM_CTL & - ~BACKLIGHT_DUTY_CYCLE_MASK; - dev_priv->regs.saveBLC_PWM_CTL = (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); - } -} - -/* - * Sets the power state for the panel. - */ -static void psb_intel_lvds_set_power(struct drm_device *dev, bool on) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - u32 pp_status; - - if (!gma_power_begin(dev, true)) { - dev_err(dev->dev, "set power, chip off!\n"); - return; - } - - if (on) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - - psb_intel_lvds_set_backlight(dev, - mode_dev->backlight_duty_cycle); - } else { - psb_intel_lvds_set_backlight(dev, 0); - - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - } - - gma_power_end(dev); -} - -static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - - if (mode == DRM_MODE_DPMS_ON) - psb_intel_lvds_set_power(dev, true); - else - psb_intel_lvds_set_power(dev, false); - - /* XXX: We never power down the LVDS pairs. */ -} - -static void psb_intel_lvds_save(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct psb_intel_lvds_priv *lvds_priv = - (struct psb_intel_lvds_priv *)psb_intel_encoder->dev_priv; - - lvds_priv->savePP_ON = REG_READ(LVDSPP_ON); - lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF); - lvds_priv->saveLVDS = REG_READ(LVDS); - lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL); - lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE); - /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/ - lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL); - lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS); - - /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/ - dev_priv->backlight_duty_cycle = (dev_priv->regs.saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - - /* - * If the light is off at server startup, - * just make it full brightness - */ - if (dev_priv->backlight_duty_cycle == 0) - dev_priv->backlight_duty_cycle = - psb_intel_lvds_get_max_backlight(dev); - - dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", - lvds_priv->savePP_ON, - lvds_priv->savePP_OFF, - lvds_priv->saveLVDS, - lvds_priv->savePP_CONTROL, - lvds_priv->savePP_CYCLE, - lvds_priv->saveBLC_PWM_CTL); -} - -static void psb_intel_lvds_restore(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - u32 pp_status; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct psb_intel_lvds_priv *lvds_priv = - (struct psb_intel_lvds_priv *)psb_intel_encoder->dev_priv; - - dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", - lvds_priv->savePP_ON, - lvds_priv->savePP_OFF, - lvds_priv->saveLVDS, - lvds_priv->savePP_CONTROL, - lvds_priv->savePP_CYCLE, - lvds_priv->saveBLC_PWM_CTL); - - REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL); - REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL); - REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS); - REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON); - REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF); - /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/ - REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE); - REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL); - REG_WRITE(LVDS, lvds_priv->saveLVDS); - - if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | - POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - } else { - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & - ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while (pp_status & PP_ON); - } -} - -int psb_intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_psb_private *dev_priv = connector->dev->dev_private; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct drm_display_mode *fixed_mode = - dev_priv->mode_dev.panel_fixed_mode; - - if (psb_intel_encoder->type == INTEL_OUTPUT_MIPI2) - fixed_mode = dev_priv->mode_dev.panel_fixed_mode2; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* just in case */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - - if (fixed_mode) { - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; - } - return MODE_OK; -} - -bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct psb_intel_crtc *psb_intel_crtc = - to_psb_intel_crtc(encoder->crtc); - struct drm_encoder *tmp_encoder; - struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode; - struct psb_intel_encoder *psb_intel_encoder = - to_psb_intel_encoder(encoder); - - if (psb_intel_encoder->type == INTEL_OUTPUT_MIPI2) - panel_fixed_mode = mode_dev->panel_fixed_mode2; - - /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ - if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { - printk(KERN_ERR "Can't support LVDS on pipe A\n"); - return false; - } - if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) { - printk(KERN_ERR "Must use PIPE A\n"); - return false; - } - /* Should never happen!! */ - list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, - head) { - if (tmp_encoder != encoder - && tmp_encoder->crtc == encoder->crtc) { - printk(KERN_ERR "Can't enable LVDS and another " - "encoder on the same pipe\n"); - return false; - } - } - - /* - * If we have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - if (panel_fixed_mode != NULL) { - adjusted_mode->hdisplay = panel_fixed_mode->hdisplay; - adjusted_mode->hsync_start = panel_fixed_mode->hsync_start; - adjusted_mode->hsync_end = panel_fixed_mode->hsync_end; - adjusted_mode->htotal = panel_fixed_mode->htotal; - adjusted_mode->vdisplay = panel_fixed_mode->vdisplay; - adjusted_mode->vsync_start = panel_fixed_mode->vsync_start; - adjusted_mode->vsync_end = panel_fixed_mode->vsync_end; - adjusted_mode->vtotal = panel_fixed_mode->vtotal; - adjusted_mode->clock = panel_fixed_mode->clock; - drm_mode_set_crtcinfo(adjusted_mode, - CRTC_INTERLACE_HALVE_V); - } - - /* - * XXX: It would be nice to support lower refresh rates on the - * panels to reduce power consumption, and perhaps match the - * user's requested refresh rate. - */ - - return true; -} - -static void psb_intel_lvds_prepare(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - - if (!gma_power_begin(dev, true)) - return; - - mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); - mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - - psb_intel_lvds_set_power(dev, false); - - gma_power_end(dev); -} - -static void psb_intel_lvds_commit(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - - if (mode_dev->backlight_duty_cycle == 0) - mode_dev->backlight_duty_cycle = - psb_intel_lvds_get_max_backlight(dev); - - psb_intel_lvds_set_power(dev, true); -} - -static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pfit_control; - - /* - * The LVDS pin pair will already have been turned on in the - * psb_intel_crtc_mode_set since it has a large impact on the DPLL - * settings. - */ - - /* - * Enable automatic panel scaling so that non-native modes fill the - * screen. Should be enabled before the pipe is enabled, according to - * register description and PRM. - */ - if (mode->hdisplay != adjusted_mode->hdisplay || - mode->vdisplay != adjusted_mode->vdisplay) - pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | - HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - else - pfit_control = 0; - - if (dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - - REG_WRITE(PFIT_CONTROL, pfit_control); -} - -/* - * Detect the LVDS connection. - * - * This always returns CONNECTOR_STATUS_CONNECTED. - * This connector should only have - * been set up if the LVDS was actually connected anyway. - */ -static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector - *connector, bool force) -{ - return connector_status_connected; -} - -/* - * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. - */ -static int psb_intel_lvds_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct psb_intel_lvds_priv *lvds_priv = psb_intel_encoder->dev_priv; - int ret = 0; - - if (!IS_MRST(dev)) - ret = psb_intel_ddc_get_modes(connector, &lvds_priv->i2c_bus->adapter); - - if (ret) - return ret; - - /* Didn't get an EDID, so - * Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - connector->display_info.min_vfreq = 0; - connector->display_info.max_vfreq = 200; - connector->display_info.min_hfreq = 0; - connector->display_info.max_hfreq = 200; - - if (mode_dev->panel_fixed_mode != NULL) { - struct drm_display_mode *mode = - drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); - drm_mode_probed_add(connector, mode); - return 1; - } - - return 0; -} - -/** - * psb_intel_lvds_destroy - unregister and free LVDS structures - * @connector: connector to free - * - * Unregister the DDC bus for this connector then free the driver private - * structure. - */ -void psb_intel_lvds_destroy(struct drm_connector *connector) -{ - struct psb_intel_encoder *psb_intel_encoder = - psb_intel_attached_encoder(connector); - struct psb_intel_lvds_priv *lvds_priv = psb_intel_encoder->dev_priv; - - if (lvds_priv->ddc_bus) - psb_intel_i2c_destroy(lvds_priv->ddc_bus); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -int psb_intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct drm_encoder *encoder = connector->encoder; - - if (!encoder) - return -1; - - if (!strcmp(property->name, "scaling mode")) { - struct psb_intel_crtc *crtc = - to_psb_intel_crtc(encoder->crtc); - uint64_t curval; - - if (!crtc) - goto set_prop_error; - - switch (value) { - case DRM_MODE_SCALE_FULLSCREEN: - break; - case DRM_MODE_SCALE_NO_SCALE: - break; - case DRM_MODE_SCALE_ASPECT: - break; - default: - goto set_prop_error; - } - - if (drm_connector_property_get_value(connector, - property, - &curval)) - goto set_prop_error; - - if (curval == value) - goto set_prop_done; - - if (drm_connector_property_set_value(connector, - property, - value)) - goto set_prop_error; - - if (crtc->saved_mode.hdisplay != 0 && - crtc->saved_mode.vdisplay != 0) { - if (!drm_crtc_helper_set_mode(encoder->crtc, - &crtc->saved_mode, - encoder->crtc->x, - encoder->crtc->y, - encoder->crtc->fb)) - goto set_prop_error; - } - } else if (!strcmp(property->name, "backlight")) { - if (drm_connector_property_set_value(connector, - property, - value)) - goto set_prop_error; - else { -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct drm_psb_private *devp = - encoder->dev->dev_private; - struct backlight_device *bd = devp->backlight_device; - if (bd) { - bd->props.brightness = value; - backlight_update_status(bd); - } -#endif - } - } else if (!strcmp(property->name, "DPMS")) { - struct drm_encoder_helper_funcs *hfuncs - = encoder->helper_private; - hfuncs->dpms(encoder, value); - } - -set_prop_done: - return 0; -set_prop_error: - return -1; -} - -static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = { - .dpms = psb_intel_lvds_encoder_dpms, - .mode_fixup = psb_intel_lvds_mode_fixup, - .prepare = psb_intel_lvds_prepare, - .mode_set = psb_intel_lvds_mode_set, - .commit = psb_intel_lvds_commit, -}; - -const struct drm_connector_helper_funcs - psb_intel_lvds_connector_helper_funcs = { - .get_modes = psb_intel_lvds_get_modes, - .mode_valid = psb_intel_lvds_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -const struct drm_connector_funcs psb_intel_lvds_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = psb_intel_lvds_save, - .restore = psb_intel_lvds_restore, - .detect = psb_intel_lvds_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = psb_intel_lvds_set_property, - .destroy = psb_intel_lvds_destroy, -}; - - -static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); -} - -const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = { - .destroy = psb_intel_lvds_enc_destroy, -}; - - - -/** - * psb_intel_lvds_init - setup LVDS connectors on this device - * @dev: drm device - * - * Create the connector, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -void psb_intel_lvds_init(struct drm_device *dev, - struct psb_intel_mode_device *mode_dev) -{ - struct psb_intel_encoder *psb_intel_encoder; - struct psb_intel_connector *psb_intel_connector; - struct psb_intel_lvds_priv *lvds_priv; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct drm_display_mode *scan; /* *modes, *bios_mode; */ - struct drm_crtc *crtc; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 lvds; - int pipe; - - psb_intel_encoder = - kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL); - if (!psb_intel_encoder) { - dev_err(dev->dev, "psb_intel_encoder allocation error\n"); - return; - } - - psb_intel_connector = - kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL); - if (!psb_intel_connector) { - dev_err(dev->dev, "psb_intel_connector allocation error\n"); - goto failed_encoder; - } - - lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); - if (!lvds_priv) { - dev_err(dev->dev, "LVDS private allocation error\n"); - goto failed_connector; - } - - psb_intel_encoder->dev_priv = lvds_priv; - - connector = &psb_intel_connector->base; - encoder = &psb_intel_encoder->base; - drm_connector_init(dev, connector, - &psb_intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - - drm_encoder_init(dev, encoder, - &psb_intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS); - - psb_intel_connector_attach_encoder(psb_intel_connector, - psb_intel_encoder); - psb_intel_encoder->type = INTEL_OUTPUT_LVDS; - - drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs); - drm_connector_helper_add(connector, - &psb_intel_lvds_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /*Attach connector properties*/ - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - drm_connector_attach_property(connector, - dev_priv->backlight_property, - BRIGHTNESS_MAX_LEVEL); - - /* - * Set up I2C bus - * FIXME: distroy i2c_bus when exit - */ - lvds_priv->i2c_bus = psb_intel_i2c_create(dev, GPIOB, "LVDSBLC_B"); - if (!lvds_priv->i2c_bus) { - dev_printk(KERN_ERR, - &dev->pdev->dev, "I2C bus registration failed.\n"); - goto failed_blc_i2c; - } - lvds_priv->i2c_bus->slave_addr = 0x2C; - dev_priv->lvds_i2c_bus = lvds_priv->i2c_bus; - - /* - * LVDS discovery: - * 1) check for EDID on DDC - * 2) check for VBT data - * 3) check to see if LVDS is already on - * if none of the above, no panel - * 4) make sure lid is open - * if closed, act like it's not there for now - */ - - /* Set up the DDC bus. */ - lvds_priv->ddc_bus = psb_intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); - if (!lvds_priv->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, - "DDC bus registration " "failed.\n"); - goto failed_ddc; - } - - /* - * Attempt to get the fixed panel mode from DDC. Assume that the - * preferred mode is the right one. - */ - psb_intel_ddc_get_modes(connector, &lvds_priv->ddc_bus->adapter); - list_for_each_entry(scan, &connector->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) { - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, scan); - goto out; /* FIXME: check for quirks */ - } - } - - /* Failed to get EDID, what about VBT? do we need this? */ - if (mode_dev->vbt_mode) - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, mode_dev->vbt_mode); - - if (!mode_dev->panel_fixed_mode) - if (dev_priv->lfp_lvds_vbt_mode) - mode_dev->panel_fixed_mode = - drm_mode_duplicate(dev, - dev_priv->lfp_lvds_vbt_mode); - - /* - * If we didn't get EDID, try checking if the panel is already turned - * on. If so, assume that whatever is currently programmed is the - * correct mode. - */ - lvds = REG_READ(LVDS); - pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - crtc = psb_intel_get_crtc_from_pipe(dev, pipe); - - if (crtc && (lvds & LVDS_PORT_EN)) { - mode_dev->panel_fixed_mode = - psb_intel_crtc_mode_get(dev, crtc); - if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; /* FIXME: check for quirks */ - } - } - - /* If we still don't have a mode after all that, give up. */ - if (!mode_dev->panel_fixed_mode) { - dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); - goto failed_find; - } - - /* - * Blacklist machines with BIOSes that list an LVDS panel without - * actually having one. - */ -out: - drm_sysfs_connector_add(connector); - return; - -failed_find: - if (lvds_priv->ddc_bus) - psb_intel_i2c_destroy(lvds_priv->ddc_bus); -failed_ddc: - if (lvds_priv->i2c_bus) - psb_intel_i2c_destroy(lvds_priv->i2c_bus); -failed_blc_i2c: - drm_encoder_cleanup(encoder); - drm_connector_cleanup(connector); -failed_connector: - kfree(psb_intel_connector); -failed_encoder: - kfree(psb_intel_encoder); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_modes.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_modes.c deleted file mode 100644 index 4fca0d6f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_modes.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2007 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authers: Jesse Barnes - */ - -#include -#include -#include -#include "psb_intel_drv.h" - -/** - * psb_intel_ddc_probe - * - */ -bool psb_intel_ddc_probe(struct i2c_adapter *adapter) -{ - u8 out_buf[] = { 0x0, 0x0 }; - u8 buf[2]; - int ret; - struct i2c_msg msgs[] = { - { - .addr = 0x50, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = 0x50, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - ret = i2c_transfer(adapter, msgs, 2); - if (ret == 2) - return true; - - return false; -} - -/** - * psb_intel_ddc_get_modes - get modelist from monitor - * @connector: DRM connector device to use - * - * Fetch the EDID information from @connector using the DDC bus. - */ -int psb_intel_ddc_get_modes(struct drm_connector *connector, - struct i2c_adapter *adapter) -{ - struct edid *edid; - int ret = 0; - - edid = drm_get_edid(connector, adapter); - if (edid) { - drm_mode_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - } - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_reg.h deleted file mode 100644 index e89d3a2e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_reg.h +++ /dev/null @@ -1,1318 +0,0 @@ -/* - * Copyright (c) 2009, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef __PSB_INTEL_REG_H__ -#define __PSB_INTEL_REG_H__ - -/* - * GPIO regs - */ -#define GPIOA 0x5010 -#define GPIOB 0x5014 -#define GPIOC 0x5018 -#define GPIOD 0x501c -#define GPIOE 0x5020 -#define GPIOF 0x5024 -#define GPIOG 0x5028 -#define GPIOH 0x502c -# define GPIO_CLOCK_DIR_MASK (1 << 0) -# define GPIO_CLOCK_DIR_IN (0 << 1) -# define GPIO_CLOCK_DIR_OUT (1 << 1) -# define GPIO_CLOCK_VAL_MASK (1 << 2) -# define GPIO_CLOCK_VAL_OUT (1 << 3) -# define GPIO_CLOCK_VAL_IN (1 << 4) -# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) -# define GPIO_DATA_DIR_MASK (1 << 8) -# define GPIO_DATA_DIR_IN (0 << 9) -# define GPIO_DATA_DIR_OUT (1 << 9) -# define GPIO_DATA_VAL_MASK (1 << 10) -# define GPIO_DATA_VAL_OUT (1 << 11) -# define GPIO_DATA_VAL_IN (1 << 12) -# define GPIO_DATA_PULLUP_DISABLE (1 << 13) - -#define GMBUS0 0x5100 /* clock/port select */ -#define GMBUS_RATE_100KHZ (0<<8) -#define GMBUS_RATE_50KHZ (1<<8) -#define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */ -#define GMBUS_RATE_1MHZ (3<<8) /* reserved on Pineview */ -#define GMBUS_HOLD_EXT (1<<7) /* 300ns hold time, rsvd on Pineview */ -#define GMBUS_PORT_DISABLED 0 -#define GMBUS_PORT_SSC 1 -#define GMBUS_PORT_VGADDC 2 -#define GMBUS_PORT_PANEL 3 -#define GMBUS_PORT_DPC 4 /* HDMIC */ -#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */ - /* 6 reserved */ -#define GMBUS_PORT_DPD 7 /* HDMID */ -#define GMBUS_NUM_PORTS 8 -#define GMBUS1 0x5104 /* command/status */ -#define GMBUS_SW_CLR_INT (1<<31) -#define GMBUS_SW_RDY (1<<30) -#define GMBUS_ENT (1<<29) /* enable timeout */ -#define GMBUS_CYCLE_NONE (0<<25) -#define GMBUS_CYCLE_WAIT (1<<25) -#define GMBUS_CYCLE_INDEX (2<<25) -#define GMBUS_CYCLE_STOP (4<<25) -#define GMBUS_BYTE_COUNT_SHIFT 16 -#define GMBUS_SLAVE_INDEX_SHIFT 8 -#define GMBUS_SLAVE_ADDR_SHIFT 1 -#define GMBUS_SLAVE_READ (1<<0) -#define GMBUS_SLAVE_WRITE (0<<0) -#define GMBUS2 0x5108 /* status */ -#define GMBUS_INUSE (1<<15) -#define GMBUS_HW_WAIT_PHASE (1<<14) -#define GMBUS_STALL_TIMEOUT (1<<13) -#define GMBUS_INT (1<<12) -#define GMBUS_HW_RDY (1<<11) -#define GMBUS_SATOER (1<<10) -#define GMBUS_ACTIVE (1<<9) -#define GMBUS3 0x510c /* data buffer bytes 3-0 */ -#define GMBUS4 0x5110 /* interrupt mask (Pineview+) */ -#define GMBUS_SLAVE_TIMEOUT_EN (1<<4) -#define GMBUS_NAK_EN (1<<3) -#define GMBUS_IDLE_EN (1<<2) -#define GMBUS_HW_WAIT_EN (1<<1) -#define GMBUS_HW_RDY_EN (1<<0) -#define GMBUS5 0x5120 /* byte index */ -#define GMBUS_2BYTE_INDEX_EN (1<<31) - -#define BLC_PWM_CTL 0x61254 -#define BLC_PWM_CTL2 0x61250 -#define BLC_PWM_CTL_C 0x62254 -#define BLC_PWM_CTL2_C 0x62250 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) -/* - * This is the most significant 15 bits of the number of backlight cycles in a - * complete cycle of the modulated backlight control. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) -/* - * This is the number of cycles out of the backlight modulation cycle for which - * the backlight is on. - * - * This field must be no greater than the number of cycles in the complete - * backlight modulation cycle. - */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) - -#define I915_GCFGC 0xf0 -#define I915_LOW_FREQUENCY_ENABLE (1 << 7) -#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define I915_DISPLAY_CLOCK_MASK (7 << 4) - -#define I855_HPLLCC 0xc0 -#define I855_CLOCK_CONTROL_MASK (3 << 0) -#define I855_CLOCK_133_200 (0 << 0) -#define I855_CLOCK_100_200 (1 << 0) -#define I855_CLOCK_100_133 (2 << 0) -#define I855_CLOCK_166_250 (3 << 0) - -/* I830 CRTC registers */ -#define HTOTAL_A 0x60000 -#define HBLANK_A 0x60004 -#define HSYNC_A 0x60008 -#define VTOTAL_A 0x6000c -#define VBLANK_A 0x60010 -#define VSYNC_A 0x60014 -#define PIPEASRC 0x6001c -#define BCLRPAT_A 0x60020 -#define VSYNCSHIFT_A 0x60028 - -#define HTOTAL_B 0x61000 -#define HBLANK_B 0x61004 -#define HSYNC_B 0x61008 -#define VTOTAL_B 0x6100c -#define VBLANK_B 0x61010 -#define VSYNC_B 0x61014 -#define PIPEBSRC 0x6101c -#define BCLRPAT_B 0x61020 -#define VSYNCSHIFT_B 0x61028 - -#define HTOTAL_C 0x62000 -#define HBLANK_C 0x62004 -#define HSYNC_C 0x62008 -#define VTOTAL_C 0x6200c -#define VBLANK_C 0x62010 -#define VSYNC_C 0x62014 -#define PIPECSRC 0x6201c -#define BCLRPAT_C 0x62020 -#define VSYNCSHIFT_C 0x62028 - -#define PP_STATUS 0x61200 -# define PP_ON (1 << 31) -/* - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -#define PP_READY (1 << 30) -#define PP_SEQUENCE_NONE (0 << 28) -#define PP_SEQUENCE_ON (1 << 28) -#define PP_SEQUENCE_OFF (2 << 28) -#define PP_SEQUENCE_MASK 0x30000000 -#define PP_CONTROL 0x61204 -#define POWER_TARGET_ON (1 << 0) - -#define LVDSPP_ON 0x61208 -#define LVDSPP_OFF 0x6120c -#define PP_CYCLE 0x61210 - -#define PP_ON_DELAYS 0x61208 /* Cedartrail */ -#define PP_OFF_DELAYS 0x6120c /* Cedartrail */ - -#define PFIT_CONTROL 0x61230 -#define PFIT_ENABLE (1 << 31) -#define PFIT_PIPE_MASK (3 << 29) -#define PFIT_PIPE_SHIFT 29 -#define PFIT_SCALING_MODE_PILLARBOX (1 << 27) -#define PFIT_SCALING_MODE_LETTERBOX (3 << 26) -#define VERT_INTERP_DISABLE (0 << 10) -#define VERT_INTERP_BILINEAR (1 << 10) -#define VERT_INTERP_MASK (3 << 10) -#define VERT_AUTO_SCALE (1 << 9) -#define HORIZ_INTERP_DISABLE (0 << 6) -#define HORIZ_INTERP_BILINEAR (1 << 6) -#define HORIZ_INTERP_MASK (3 << 6) -#define HORIZ_AUTO_SCALE (1 << 5) -#define PANEL_8TO6_DITHER_ENABLE (1 << 3) - -#define PFIT_PGM_RATIOS 0x61234 -#define PFIT_VERT_SCALE_MASK 0xfff00000 -#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 - -#define PFIT_AUTO_RATIOS 0x61238 - -#define DPLL_A 0x06014 -#define DPLL_B 0x06018 -#define DPLL_VCO_ENABLE (1 << 31) -#define DPLL_DVO_HIGH_SPEED (1 << 30) -#define DPLL_SYNCLOCK_ENABLE (1 << 29) -#define DPLL_VGA_MODE_DIS (1 << 28) -#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -#define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -#define DPLL_MODE_MASK (3 << 26) -#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ -#define DPLL_LOCK (1 << 15) /* CDV */ - -/* - * The i830 generation, in DAC/serial mode, defines p1 as two plus this - * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. - */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/* - * The i830 generation, in LVDS mode, defines P1 as the bit number set within - * this field (only one bit may be set). - */ -#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -#define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required - * in DVO non-gang */ -# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -#define PLL_REF_INPUT_DREFCLK (0 << 13) -#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO - * TVCLKIN */ -#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -#define PLL_REF_INPUT_MASK (3 << 13) -#define PLL_LOAD_PULSE_PHASE_SHIFT 9 -/* - * Parallel to Serial Load Pulse phase selection. - * Selects the phase for the 10X DPLL clock for the PCIe - * digital display port. The range is 4 to 13; 10 or more - * is just a flip delay. The default is 6 - */ -#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -#define DISPLAY_RATE_SELECT_FPA1 (1 << 8) - -/* - * SDVO multiplier for 945G/GM. Not used on 965. - * - * DPLL_MD_UDI_MULTIPLIER_MASK - */ -#define SDVO_MULTIPLIER_MASK 0x000000ff -#define SDVO_MULTIPLIER_SHIFT_HIRES 4 -#define SDVO_MULTIPLIER_SHIFT_VGA 0 - -/* - * PLL_MD - */ -/* Pipe A SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_A_MD 0x0601c -/* Pipe B SDVO/UDI clock multiplier/divider register for G965. */ -#define DPLL_B_MD 0x06020 -/* - * UDI pixel divider, controlling how many pixels are stuffed into a packet. - * - * Value is pixels minus 1. Must be set to 1 pixel for SDVO. - */ -#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -#define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/* - * SDVO/UDI pixel multiplier. - * - * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus - * clock rate is 10 times the DPLL clock. At low resolution/refresh rate - * modes, the bus rate would be below the limits, so SDVO allows for stuffing - * dummy bytes in the datastream at an increased clock rate, with both sides of - * the link knowing how many bytes are fill. - * - * So, for a mode with a dotclock of 65Mhz, we would want to double the clock - * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be - * set to 130Mhz, and the SDVO multiplier set to 2x in this register and - * through an SDVO command. - * - * This register field has values of multiplication factor minus 1, with - * a maximum multiplier of 5 for SDVO. - */ -#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/* - * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. - * This best be set to the default value (3) or the CRT won't work. No, - * I don't entirely understand what this does... - */ -#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 - -#define DPLL_TEST 0x606c -#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -#define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -#define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -#define DPLLB_TEST_N_BYPASS (1 << 19) -#define DPLLB_TEST_M_BYPASS (1 << 18) -#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -#define DPLLA_TEST_N_BYPASS (1 << 3) -#define DPLLA_TEST_M_BYPASS (1 << 2) -#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) - -#define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1 << 31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1 << 30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1 << 30) -#define ADPA_USE_VGA_HVPOLARITY (1 << 15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1 << 11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1 << 10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1 << 4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1 << 3) -#define ADPA_HSYNC_ACTIVE_LOW 0 - -#define FPA0 0x06040 -#define FPA1 0x06044 -#define FPB0 0x06048 -#define FPB1 0x0604c -#define FP_N_DIV_MASK 0x003f0000 -#define FP_N_DIV_SHIFT 16 -#define FP_M1_DIV_MASK 0x00003f00 -#define FP_M1_DIV_SHIFT 8 -#define FP_M2_DIV_MASK 0x0000003f -#define FP_M2_DIV_SHIFT 0 - -#define PORT_HOTPLUG_EN 0x61110 -#define SDVOB_HOTPLUG_INT_EN (1 << 26) -#define SDVOC_HOTPLUG_INT_EN (1 << 25) -#define TV_HOTPLUG_INT_EN (1 << 18) -#define CRT_HOTPLUG_INT_EN (1 << 9) -#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) -/* CDV.. */ -#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8) -#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7) -#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5) -#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4) -#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) -#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) -#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) -#define CRT_HOTPLUG_DETECT_MASK 0x000000F8 - -#define PORT_HOTPLUG_STAT 0x61114 -#define CRT_HOTPLUG_INT_STATUS (1 << 11) -#define TV_HOTPLUG_INT_STATUS (1 << 10) -#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -#define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -#define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -#define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -#define SDVOB_HOTPLUG_INT_STATUS (1 << 6) - -#define SDVOB 0x61140 -#define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) -#define SDVO_COLOR_RANGE_16_235 (1 << 8) -#define SDVO_AUDIO_ENABLE (1 << 6) - -/** - * 915G/GM SDVO pixel multiplier. - * - * Programmed value is multiplier - 1, up to 5x. - * - * DPLL_MD_UDI_MULTIPLIER_MASK - */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) -/* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) -#define SDVOC_PRESERVE_MASK (1 << 17) - -/* - * This register controls the LVDS output enable, pipe selection, and data - * format selection. - * - * All of the clock/data pairs are force powered down by power sequencing. - */ -#define LVDS 0x61180 -/* - * Enables the LVDS port. This bit must be set before DPLLs are enabled, as - * the DPLL semantics change when the LVDS is assigned to that pipe. - */ -#define LVDS_PORT_EN (1 << 31) -/* Selects pipe B for LVDS data. Must be set on pre-965. */ -#define LVDS_PIPEB_SELECT (1 << 30) - -/* Turns on border drawing to allow centered display. */ -#define LVDS_BORDER_EN (1 << 15) - -/* - * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per - * pixel. - */ -#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/* - * Controls the A3 data pair, which contains the additional LSBs for 24 bit - * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be - * on. - */ -#define LVDS_A3_POWER_MASK (3 << 6) -#define LVDS_A3_POWER_DOWN (0 << 6) -#define LVDS_A3_POWER_UP (3 << 6) -/* - * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP - * is set. - */ -#define LVDS_CLKB_POWER_MASK (3 << 4) -#define LVDS_CLKB_POWER_DOWN (0 << 4) -#define LVDS_CLKB_POWER_UP (3 << 4) -/* - * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 - * setting for whether we are in dual-channel mode. The B3 pair will - * additionally only be powered up when LVDS_A3_POWER_UP is set. - */ -#define LVDS_B0B3_POWER_MASK (3 << 2) -#define LVDS_B0B3_POWER_DOWN (0 << 2) -#define LVDS_B0B3_POWER_UP (3 << 2) - -#define PIPEACONF 0x70008 -#define PIPEACONF_ENABLE (1 << 31) -#define PIPEACONF_DISABLE 0 -#define PIPEACONF_DOUBLE_WIDE (1 << 30) -#define PIPECONF_ACTIVE (1 << 30) -#define I965_PIPECONF_ACTIVE (1 << 30) -#define PIPECONF_DSIPLL_LOCK (1 << 29) -#define PIPEACONF_SINGLE_WIDE 0 -#define PIPEACONF_PIPE_UNLOCKED 0 -#define PIPEACONF_DSR (1 << 26) -#define PIPEACONF_PIPE_LOCKED (1 << 25) -#define PIPEACONF_PALETTE 0 -#define PIPECONF_FORCE_BORDER (1 << 25) -#define PIPEACONF_GAMMA (1 << 24) -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) -#define PIPECONF_PLANE_OFF (1 << 19) -#define PIPECONF_CURSOR_OFF (1 << 18) - -#define PIPEBCONF 0x71008 -#define PIPEBCONF_ENABLE (1 << 31) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_DOUBLE_WIDE (1 << 30) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_GAMMA (1 << 24) -#define PIPEBCONF_PALETTE 0 - -#define PIPECCONF 0x72008 - -#define PIPEBGCMAXRED 0x71010 -#define PIPEBGCMAXGREEN 0x71014 -#define PIPEBGCMAXBLUE 0x71018 - -#define PIPEASTAT 0x70024 -#define PIPEBSTAT 0x71024 -#define PIPECSTAT 0x72024 -#define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1) -#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL << 2) -#define PIPE_VBLANK_CLEAR (1 << 1) -#define PIPE_VBLANK_STATUS (1 << 1) -#define PIPE_TE_STATUS (1UL << 6) -#define PIPE_DPST_EVENT_STATUS (1UL << 7) -#define PIPE_VSYNC_CLEAR (1UL << 9) -#define PIPE_VSYNC_STATUS (1UL << 9) -#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL << 10) -#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL << 11) -#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17) -#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18) -#define PIPE_TE_ENABLE (1UL << 22) -#define PIPE_DPST_EVENT_ENABLE (1UL << 23) -#define PIPE_VSYNC_ENABL (1UL << 25) -#define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) -#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27) -#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \ - PIPE_HDMI_AUDIO_BUFFER_DONE) -#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) -#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17)) -#define HISTOGRAM_INT_CONTROL 0x61268 -#define HISTOGRAM_BIN_DATA 0X61264 -#define HISTOGRAM_LOGIC_CONTROL 0x61260 -#define PWM_CONTROL_LOGIC 0x61250 -#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL << 10) -#define HISTOGRAM_INTERRUPT_ENABLE (1UL << 31) -#define HISTOGRAM_LOGIC_ENABLE (1UL << 31) -#define PWM_LOGIC_ENABLE (1UL << 31) -#define PWM_PHASEIN_ENABLE (1UL << 25) -#define PWM_PHASEIN_INT_ENABLE (1UL << 24) -#define PWM_PHASEIN_VB_COUNT 0x00001f00 -#define PWM_PHASEIN_INC 0x0000001f -#define HISTOGRAM_INT_CTRL_CLEAR (1UL << 30) -#define DPST_YUV_LUMA_MODE 0 - -struct dpst_ie_histogram_control { - union { - uint32_t data; - struct { - uint32_t bin_reg_index:7; - uint32_t reserved:4; - uint32_t bin_reg_func_select:1; - uint32_t sync_to_phase_in:1; - uint32_t alt_enhancement_mode:2; - uint32_t reserved1:1; - uint32_t sync_to_phase_in_count:8; - uint32_t histogram_mode_select:1; - uint32_t reserved2:4; - uint32_t ie_pipe_assignment:1; - uint32_t ie_mode_table_enabled:1; - uint32_t ie_histogram_enable:1; - }; - }; -}; - -struct dpst_guardband { - union { - uint32_t data; - struct { - uint32_t guardband:22; - uint32_t guardband_interrupt_delay:8; - uint32_t interrupt_status:1; - uint32_t interrupt_enable:1; - }; - }; -}; - -#define PIPEAFRAMEHIGH 0x70040 -#define PIPEAFRAMEPIXEL 0x70044 -#define PIPEBFRAMEHIGH 0x71040 -#define PIPEBFRAMEPIXEL 0x71044 -#define PIPECFRAMEHIGH 0x72040 -#define PIPECFRAMEPIXEL 0x72044 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 - -#define DSPARB 0x70030 -#define DSPFW1 0x70034 -#define DSPFW2 0x70038 -#define DSPFW3 0x7003c -#define DSPFW4 0x70050 -#define DSPFW5 0x70054 -#define DSPFW6 0x70058 -#define DSPCHICKENBIT 0x70400 -#define DSPACNTR 0x70180 -#define DSPBCNTR 0x71180 -#define DSPCCNTR 0x72180 -#define DISPLAY_PLANE_ENABLE (1 << 31) -#define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1 << 30) -#define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf << 26) -#define DISPPLANE_8BPP (0x2 << 26) -#define DISPPLANE_15_16BPP (0x4 << 26) -#define DISPPLANE_16BPP (0x5 << 26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6 << 26) -#define DISPPLANE_32BPP (0x7 << 26) -#define DISPPLANE_STEREO_ENABLE (1 << 25) -#define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_MASK (1 << 24) -#define DISPPLANE_SEL_PIPE_POS 24 -#define DISPPLANE_SEL_PIPE_A 0 -#define DISPPLANE_SEL_PIPE_B (1 << 24) -#define DISPPLANE_SRC_KEY_ENABLE (1 << 22) -#define DISPPLANE_SRC_KEY_DISABLE 0 -#define DISPPLANE_LINE_DOUBLE (1 << 20) -#define DISPPLANE_NO_LINE_DOUBLE 0 -#define DISPPLANE_STEREO_POLARITY_FIRST 0 -#define DISPPLANE_STEREO_POLARITY_SECOND (1 << 18) -/* plane B only */ -#define DISPPLANE_ALPHA_TRANS_ENABLE (1 << 15) -#define DISPPLANE_ALPHA_TRANS_DISABLE 0 -#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 -#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) -#define DISPPLANE_BOTTOM (4) - -#define DSPABASE 0x70184 -#define DSPALINOFF 0x70184 -#define DSPASTRIDE 0x70188 - -#define DSPBBASE 0x71184 -#define DSPBLINOFF 0X71184 -#define DSPBADDR DSPBBASE -#define DSPBSTRIDE 0x71188 - -#define DSPCBASE 0x72184 -#define DSPCLINOFF 0x72184 -#define DSPCSTRIDE 0x72188 - -#define DSPAKEYVAL 0x70194 -#define DSPAKEYMASK 0x70198 - -#define DSPAPOS 0x7018C /* reserved */ -#define DSPASIZE 0x70190 -#define DSPBPOS 0x7118C -#define DSPBSIZE 0x71190 -#define DSPCPOS 0x7218C -#define DSPCSIZE 0x72190 - -#define DSPASURF 0x7019C -#define DSPATILEOFF 0x701A4 - -#define DSPBSURF 0x7119C -#define DSPBTILEOFF 0x711A4 - -#define DSPCSURF 0x7219C -#define DSPCTILEOFF 0x721A4 -#define DSPCKEYMAXVAL 0x721A0 -#define DSPCKEYMINVAL 0x72194 -#define DSPCKEYMSK 0x72198 - -#define VGACNTRL 0x71400 -#define VGA_DISP_DISABLE (1 << 31) -#define VGA_2X_MODE (1 << 30) -#define VGA_PIPE_B_SELECT (1 << 29) - -/* - * Overlay registers - */ -#define OV_C_OFFSET 0x08000 -#define OV_OVADD 0x30000 -#define OV_DOVASTA 0x30008 -# define OV_PIPE_SELECT ((1 << 6)|(1 << 7)) -# define OV_PIPE_SELECT_POS 6 -# define OV_PIPE_A 0 -# define OV_PIPE_C 1 -#define OV_OGAMC5 0x30010 -#define OV_OGAMC4 0x30014 -#define OV_OGAMC3 0x30018 -#define OV_OGAMC2 0x3001C -#define OV_OGAMC1 0x30020 -#define OV_OGAMC0 0x30024 -#define OVC_OVADD 0x38000 -#define OVC_DOVCSTA 0x38008 -#define OVC_OGAMC5 0x38010 -#define OVC_OGAMC4 0x38014 -#define OVC_OGAMC3 0x38018 -#define OVC_OGAMC2 0x3801C -#define OVC_OGAMC1 0x38020 -#define OVC_OGAMC0 0x38024 - -/* - * Some BIOS scratch area registers. The 845 (and 830?) store the amount - * of video memory available to the BIOS in SWF1. - */ -#define SWF0 0x71410 -#define SWF1 0x71414 -#define SWF2 0x71418 -#define SWF3 0x7141c -#define SWF4 0x71420 -#define SWF5 0x71424 -#define SWF6 0x71428 - -/* - * 855 scratch registers. - */ -#define SWF00 0x70410 -#define SWF01 0x70414 -#define SWF02 0x70418 -#define SWF03 0x7041c -#define SWF04 0x70420 -#define SWF05 0x70424 -#define SWF06 0x70428 - -#define SWF10 SWF0 -#define SWF11 SWF1 -#define SWF12 SWF2 -#define SWF13 SWF3 -#define SWF14 SWF4 -#define SWF15 SWF5 -#define SWF16 SWF6 - -#define SWF30 0x72414 -#define SWF31 0x72418 -#define SWF32 0x7241c - - -/* - * Palette registers - */ -#define PALETTE_A 0x0a000 -#define PALETTE_B 0x0a800 -#define PALETTE_C 0x0ac00 - -/* Cursor A & B regs */ -#define CURACNTR 0x70080 -#define CURSOR_MODE_DISABLE 0x00 -#define CURSOR_MODE_64_32B_AX 0x07 -#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) -#define MCURSOR_GAMMA_ENABLE (1 << 26) -#define CURABASE 0x70084 -#define CURAPOS 0x70088 -#define CURSOR_POS_MASK 0x007FF -#define CURSOR_POS_SIGN 0x8000 -#define CURSOR_X_SHIFT 0 -#define CURSOR_Y_SHIFT 16 -#define CURBCNTR 0x700c0 -#define CURBBASE 0x700c4 -#define CURBPOS 0x700c8 -#define CURCCNTR 0x700e0 -#define CURCBASE 0x700e4 -#define CURCPOS 0x700e8 - -/* - * Interrupt Registers - */ -#define IER 0x020a0 -#define IIR 0x020a4 -#define IMR 0x020a8 -#define ISR 0x020ac - -/* - * MOORESTOWN delta registers - */ -#define MRST_DPLL_A 0x0f014 -#define MDFLD_DPLL_B 0x0f018 -#define MDFLD_INPUT_REF_SEL (1 << 14) -#define MDFLD_VCO_SEL (1 << 16) -#define DPLLA_MODE_LVDS (2 << 26) /* mrst */ -#define MDFLD_PLL_LATCHEN (1 << 28) -#define MDFLD_PWR_GATE_EN (1 << 30) -#define MDFLD_P1_MASK (0x1FF << 17) -#define MRST_FPA0 0x0f040 -#define MRST_FPA1 0x0f044 -#define MDFLD_DPLL_DIV0 0x0f048 -#define MDFLD_DPLL_DIV1 0x0f04c -#define MRST_PERF_MODE 0x020f4 - -/* - * MEDFIELD HDMI registers - */ -#define HDMIPHYMISCCTL 0x61134 -#define HDMI_PHY_POWER_DOWN 0x7f -#define HDMIB_CONTROL 0x61140 -#define HDMIB_PORT_EN (1 << 31) -#define HDMIB_PIPE_B_SELECT (1 << 30) -#define HDMIB_NULL_PACKET (1 << 9) -#define HDMIB_HDCP_PORT (1 << 5) - -/* #define LVDS 0x61180 */ -#define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25) -#define MRST_PANEL_24_DOT_1_FORMAT (1 << 24) -#define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6) - -#define MIPI 0x61190 -#define MIPI_C 0x62190 -#define MIPI_PORT_EN (1 << 31) -/* Turns on border drawing to allow centered display. */ -#define SEL_FLOPPED_HSTX (1 << 23) -#define PASS_FROM_SPHY_TO_AFE (1 << 16) -#define MIPI_BORDER_EN (1 << 15) -#define MIPIA_3LANE_MIPIC_1LANE 0x1 -#define MIPIA_2LANE_MIPIC_2LANE 0x2 -#define TE_TRIGGER_DSI_PROTOCOL (1 << 2) -#define TE_TRIGGER_GPIO_PIN (1 << 3) -#define MIPI_TE_COUNT 0x61194 - -/* #define PP_CONTROL 0x61204 */ -#define POWER_DOWN_ON_RESET (1 << 1) - -/* #define PFIT_CONTROL 0x61230 */ -#define PFIT_PIPE_SELECT (3 << 29) -#define PFIT_PIPE_SELECT_SHIFT (29) - -/* #define BLC_PWM_CTL 0x61254 */ -#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16) -#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16) - -/* #define PIPEACONF 0x70008 */ -#define PIPEACONF_PIPE_STATE (1 << 30) -/* #define DSPACNTR 0x70180 */ - -#define MRST_DSPABASE 0x7019c -#define MRST_DSPBBASE 0x7119c -#define MDFLD_DSPCBASE 0x7219c - -/* - * Moorestown registers. - */ - -/* - * MIPI IP registers - */ -#define MIPIC_REG_OFFSET 0x800 - -#define DEVICE_READY_REG 0xb000 -#define LP_OUTPUT_HOLD (1 << 16) -#define EXIT_ULPS_DEV_READY 0x3 -#define LP_OUTPUT_HOLD_RELEASE 0x810000 -# define ENTERING_ULPS (2 << 1) -# define EXITING_ULPS (1 << 1) -# define ULPS_MASK (3 << 1) -# define BUS_POSSESSION (1 << 3) -#define INTR_STAT_REG 0xb004 -#define RX_SOT_ERROR (1 << 0) -#define RX_SOT_SYNC_ERROR (1 << 1) -#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3) -#define RX_LP_TX_SYNC_ERROR (1 << 4) -#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5) -#define RX_FALSE_CONTROL_ERROR (1 << 6) -#define RX_ECC_SINGLE_BIT_ERROR (1 << 7) -#define RX_ECC_MULTI_BIT_ERROR (1 << 8) -#define RX_CHECKSUM_ERROR (1 << 9) -#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10) -#define RX_DSI_VC_ID_INVALID (1 << 11) -#define TX_FALSE_CONTROL_ERROR (1 << 12) -#define TX_ECC_SINGLE_BIT_ERROR (1 << 13) -#define TX_ECC_MULTI_BIT_ERROR (1 << 14) -#define TX_CHECKSUM_ERROR (1 << 15) -#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16) -#define TX_DSI_VC_ID_INVALID (1 << 17) -#define HIGH_CONTENTION (1 << 18) -#define LOW_CONTENTION (1 << 19) -#define DPI_FIFO_UNDER_RUN (1 << 20) -#define HS_TX_TIMEOUT (1 << 21) -#define LP_RX_TIMEOUT (1 << 22) -#define TURN_AROUND_ACK_TIMEOUT (1 << 23) -#define ACK_WITH_NO_ERROR (1 << 24) -#define HS_GENERIC_WR_FIFO_FULL (1 << 27) -#define LP_GENERIC_WR_FIFO_FULL (1 << 28) -#define SPL_PKT_SENT (1 << 30) -#define INTR_EN_REG 0xb008 -#define DSI_FUNC_PRG_REG 0xb00c -#define DPI_CHANNEL_NUMBER_POS 0x03 -#define DBI_CHANNEL_NUMBER_POS 0x05 -#define FMT_DPI_POS 0x07 -#define FMT_DBI_POS 0x0A -#define DBI_DATA_WIDTH_POS 0x0D - -/* DPI PIXEL FORMATS */ -#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */ -#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */ -#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED - * 666 FORMAT - */ -#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */ -#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */ -#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */ -#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */ -#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */ - -#define DBI_NOT_SUPPORTED 0x00 /* command mode - * is not supported - */ -#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */ -#define DBI_DATA_WIDTH_9BIT 0x02 /* 9 bit data */ -#define DBI_DATA_WIDTH_8BIT 0x03 /* 8 bit data */ -#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */ -#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */ - -#define HS_TX_TIMEOUT_REG 0xb010 -#define LP_RX_TIMEOUT_REG 0xb014 -#define TURN_AROUND_TIMEOUT_REG 0xb018 -#define DEVICE_RESET_REG 0xb01C -#define DPI_RESOLUTION_REG 0xb020 -#define RES_V_POS 0x10 -#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */ -#define HORIZ_SYNC_PAD_COUNT_REG 0xb028 -#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C -#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030 -#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034 -#define VERT_SYNC_PAD_COUNT_REG 0xb038 -#define VERT_BACK_PORCH_COUNT_REG 0xb03c -#define VERT_FRONT_PORCH_COUNT_REG 0xb040 -#define HIGH_LOW_SWITCH_COUNT_REG 0xb044 -#define DPI_CONTROL_REG 0xb048 -#define DPI_SHUT_DOWN (1 << 0) -#define DPI_TURN_ON (1 << 1) -#define DPI_COLOR_MODE_ON (1 << 2) -#define DPI_COLOR_MODE_OFF (1 << 3) -#define DPI_BACK_LIGHT_ON (1 << 4) -#define DPI_BACK_LIGHT_OFF (1 << 5) -#define DPI_LP (1 << 6) -#define DPI_DATA_REG 0xb04c -#define DPI_BACK_LIGHT_ON_DATA 0x07 -#define DPI_BACK_LIGHT_OFF_DATA 0x17 -#define INIT_COUNT_REG 0xb050 -#define MAX_RET_PAK_REG 0xb054 -#define VIDEO_FMT_REG 0xb058 -#define COMPLETE_LAST_PCKT (1 << 2) -#define EOT_DISABLE_REG 0xb05c -#define ENABLE_CLOCK_STOPPING (1 << 1) -#define LP_BYTECLK_REG 0xb060 -#define LP_GEN_DATA_REG 0xb064 -#define HS_GEN_DATA_REG 0xb068 -#define LP_GEN_CTRL_REG 0xb06C -#define HS_GEN_CTRL_REG 0xb070 -#define DCS_CHANNEL_NUMBER_POS 0x6 -#define MCS_COMMANDS_POS 0x8 -#define WORD_COUNTS_POS 0x8 -#define MCS_PARAMETER_POS 0x10 -#define GEN_FIFO_STAT_REG 0xb074 -#define HS_DATA_FIFO_FULL (1 << 0) -#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) -#define HS_DATA_FIFO_EMPTY (1 << 2) -#define LP_DATA_FIFO_FULL (1 << 8) -#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) -#define LP_DATA_FIFO_EMPTY (1 << 10) -#define HS_CTRL_FIFO_FULL (1 << 16) -#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) -#define HS_CTRL_FIFO_EMPTY (1 << 18) -#define LP_CTRL_FIFO_FULL (1 << 24) -#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) -#define LP_CTRL_FIFO_EMPTY (1 << 26) -#define DBI_FIFO_EMPTY (1 << 27) -#define DPI_FIFO_EMPTY (1 << 28) -#define HS_LS_DBI_ENABLE_REG 0xb078 -#define TXCLKESC_REG 0xb07c -#define DPHY_PARAM_REG 0xb080 -#define DBI_BW_CTRL_REG 0xb084 -#define CLK_LANE_SWT_REG 0xb088 - -/* - * MIPI Adapter registers - */ -#define MIPI_CONTROL_REG 0xb104 -#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1)) -#define MIPI_DATA_ADDRESS_REG 0xb108 -#define MIPI_DATA_LENGTH_REG 0xb10C -#define MIPI_COMMAND_ADDRESS_REG 0xb110 -#define MIPI_COMMAND_LENGTH_REG 0xb114 -#define MIPI_READ_DATA_RETURN_REG0 0xb118 -#define MIPI_READ_DATA_RETURN_REG1 0xb11C -#define MIPI_READ_DATA_RETURN_REG2 0xb120 -#define MIPI_READ_DATA_RETURN_REG3 0xb124 -#define MIPI_READ_DATA_RETURN_REG4 0xb128 -#define MIPI_READ_DATA_RETURN_REG5 0xb12C -#define MIPI_READ_DATA_RETURN_REG6 0xb130 -#define MIPI_READ_DATA_RETURN_REG7 0xb134 -#define MIPI_READ_DATA_VALID_REG 0xb138 - -/* DBI COMMANDS */ -#define soft_reset 0x01 -/* - * The display module performs a software reset. - * Registers are written with their SW Reset default values. - */ -#define get_power_mode 0x0a -/* - * The display module returns the current power mode - */ -#define get_address_mode 0x0b -/* - * The display module returns the current status. - */ -#define get_pixel_format 0x0c -/* - * This command gets the pixel format for the RGB image data - * used by the interface. - */ -#define get_display_mode 0x0d -/* - * The display module returns the Display Image Mode status. - */ -#define get_signal_mode 0x0e -/* - * The display module returns the Display Signal Mode. - */ -#define get_diagnostic_result 0x0f -/* - * The display module returns the self-diagnostic results following - * a Sleep Out command. - */ -#define enter_sleep_mode 0x10 -/* - * This command causes the display module to enter the Sleep mode. - * In this mode, all unnecessary blocks inside the display module are - * disabled except interface communication. This is the lowest power - * mode the display module supports. - */ -#define exit_sleep_mode 0x11 -/* - * This command causes the display module to exit Sleep mode. - * All blocks inside the display module are enabled. - */ -#define enter_partial_mode 0x12 -/* - * This command causes the display module to enter the Partial Display - * Mode. The Partial Display Mode window is described by the - * set_partial_area command. - */ -#define enter_normal_mode 0x13 -/* - * This command causes the display module to enter the Normal mode. - * Normal Mode is defined as Partial Display mode and Scroll mode are off - */ -#define exit_invert_mode 0x20 -/* - * This command causes the display module to stop inverting the image - * data on the display device. The frame memory contents remain unchanged. - * No status bits are changed. - */ -#define enter_invert_mode 0x21 -/* - * This command causes the display module to invert the image data only on - * the display device. The frame memory contents remain unchanged. - * No status bits are changed. - */ -#define set_gamma_curve 0x26 -/* - * This command selects the desired gamma curve for the display device. - * Four fixed gamma curves are defined in section DCS spec. - */ -#define set_display_off 0x28 -/* ************************************************************************* *\ -This command causes the display module to stop displaying the image data -on the display device. The frame memory contents remain unchanged. -No status bits are changed. -\* ************************************************************************* */ -#define set_display_on 0x29 -/* ************************************************************************* *\ -This command causes the display module to start displaying the image data -on the display device. The frame memory contents remain unchanged. -No status bits are changed. -\* ************************************************************************* */ -#define set_column_address 0x2a -/* - * This command defines the column extent of the frame memory accessed by - * the hostprocessor with the read_memory_continue and - * write_memory_continue commands. - * No status bits are changed. - */ -#define set_page_addr 0x2b -/* - * This command defines the page extent of the frame memory accessed by - * the host processor with the write_memory_continue and - * read_memory_continue command. - * No status bits are changed. - */ -#define write_mem_start 0x2c -/* - * This command transfers image data from the host processor to the - * display modules frame memory starting at the pixel location specified - * by preceding set_column_address and set_page_address commands. - */ -#define set_partial_area 0x30 -/* - * This command defines the Partial Display mode s display area. - * There are two parameters associated with this command, the first - * defines the Start Row (SR) and the second the End Row (ER). SR and ER - * refer to the Frame Memory Line Pointer. - */ -#define set_scroll_area 0x33 -/* - * This command defines the display modules Vertical Scrolling Area. - */ -#define set_tear_off 0x34 -/* - * This command turns off the display modules Tearing Effect output - * signal on the TE signal line. - */ -#define set_tear_on 0x35 -/* - * This command turns on the display modules Tearing Effect output signal - * on the TE signal line. - */ -#define set_address_mode 0x36 -/* - * This command sets the data order for transfers from the host processor - * to display modules frame memory,bits B[7:5] and B3, and from the - * display modules frame memory to the display device, bits B[2:0] and B4. - */ -#define set_scroll_start 0x37 -/* - * This command sets the start of the vertical scrolling area in the frame - * memory. The vertical scrolling area is fully defined when this command - * is used with the set_scroll_area command The set_scroll_start command - * has one parameter, the Vertical Scroll Pointer. The VSP defines the - * line in the frame memory that is written to the display device as the - * first line of the vertical scroll area. - */ -#define exit_idle_mode 0x38 -/* - * This command causes the display module to exit Idle mode. - */ -#define enter_idle_mode 0x39 -/* - * This command causes the display module to enter Idle Mode. - * In Idle Mode, color expression is reduced. Colors are shown on the - * display device using the MSB of each of the R, G and B color - * components in the frame memory - */ -#define set_pixel_format 0x3a -/* - * This command sets the pixel format for the RGB image data used by the - * interface. - * Bits D[6:4] DPI Pixel Format Definition - * Bits D[2:0] DBI Pixel Format Definition - * Bits D7 and D3 are not used. - */ -#define DCS_PIXEL_FORMAT_3bpp 0x1 -#define DCS_PIXEL_FORMAT_8bpp 0x2 -#define DCS_PIXEL_FORMAT_12bpp 0x3 -#define DCS_PIXEL_FORMAT_16bpp 0x5 -#define DCS_PIXEL_FORMAT_18bpp 0x6 -#define DCS_PIXEL_FORMAT_24bpp 0x7 - -#define write_mem_cont 0x3c - -/* - * This command transfers image data from the host processor to the - * display module's frame memory continuing from the pixel location - * following the previous write_memory_continue or write_memory_start - * command. - */ -#define set_tear_scanline 0x44 -/* - * This command turns on the display modules Tearing Effect output signal - * on the TE signal line when the display module reaches line N. - */ -#define get_scanline 0x45 -/* - * The display module returns the current scanline, N, used to update the - * display device. The total number of scanlines on a display device is - * defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as - * the first line of V Sync and is denoted as Line 0. - * When in Sleep Mode, the value returned by get_scanline is undefined. - */ - -/* MCS or Generic COMMANDS */ -/* MCS/generic data type */ -#define GEN_SHORT_WRITE_0 0x03 /* generic short write, no parameters */ -#define GEN_SHORT_WRITE_1 0x13 /* generic short write, 1 parameters */ -#define GEN_SHORT_WRITE_2 0x23 /* generic short write, 2 parameters */ -#define GEN_READ_0 0x04 /* generic read, no parameters */ -#define GEN_READ_1 0x14 /* generic read, 1 parameters */ -#define GEN_READ_2 0x24 /* generic read, 2 parameters */ -#define GEN_LONG_WRITE 0x29 /* generic long write */ -#define MCS_SHORT_WRITE_0 0x05 /* MCS short write, no parameters */ -#define MCS_SHORT_WRITE_1 0x15 /* MCS short write, 1 parameters */ -#define MCS_READ 0x06 /* MCS read, no parameters */ -#define MCS_LONG_WRITE 0x39 /* MCS long write */ -/* MCS/generic commands */ -/* TPO MCS */ -#define write_display_profile 0x50 -#define write_display_brightness 0x51 -#define write_ctrl_display 0x53 -#define write_ctrl_cabc 0x55 - #define UI_IMAGE 0x01 - #define STILL_IMAGE 0x02 - #define MOVING_IMAGE 0x03 -#define write_hysteresis 0x57 -#define write_gamma_setting 0x58 -#define write_cabc_min_bright 0x5e -#define write_kbbc_profile 0x60 -/* TMD MCS */ -#define tmd_write_display_brightness 0x8c - -/* - * This command is used to control ambient light, panel backlight - * brightness and gamma settings. - */ -#define BRIGHT_CNTL_BLOCK_ON (1 << 5) -#define AMBIENT_LIGHT_SENSE_ON (1 << 4) -#define DISPLAY_DIMMING_ON (1 << 3) -#define BACKLIGHT_ON (1 << 2) -#define DISPLAY_BRIGHTNESS_AUTO (1 << 1) -#define GAMMA_AUTO (1 << 0) - -/* DCS Interface Pixel Formats */ -#define DCS_PIXEL_FORMAT_3BPP 0x1 -#define DCS_PIXEL_FORMAT_8BPP 0x2 -#define DCS_PIXEL_FORMAT_12BPP 0x3 -#define DCS_PIXEL_FORMAT_16BPP 0x5 -#define DCS_PIXEL_FORMAT_18BPP 0x6 -#define DCS_PIXEL_FORMAT_24BPP 0x7 -/* ONE PARAMETER READ DATA */ -#define addr_mode_data 0xfc -#define diag_res_data 0x00 -#define disp_mode_data 0x23 -#define pxl_fmt_data 0x77 -#define pwr_mode_data 0x74 -#define sig_mode_data 0x00 -/* TWO PARAMETERS READ DATA */ -#define scanline_data1 0xff -#define scanline_data2 0xff -#define NON_BURST_MODE_SYNC_PULSE 0x01 /* Non Burst Mode - * with Sync Pulse - */ -#define NON_BURST_MODE_SYNC_EVENTS 0x02 /* Non Burst Mode - * with Sync events - */ -#define BURST_MODE 0x03 /* Burst Mode */ -#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */ - /* Allocate at least - * 0x100 Byte with 32 - * byte alignment - */ -#define DBI_DATA_BUFFER_SIZE 0x120 /* Allocate at least - * 0x100 Byte with 32 - * byte alignment - */ -#define DBI_CB_TIME_OUT 0xFFFF - -#define GEN_FB_TIME_OUT 2000 - -#define SKU_83 0x01 -#define SKU_100 0x02 -#define SKU_100L 0x04 -#define SKU_BYPASS 0x08 - -/* Some handy macros for playing with bitfields. */ -#define PSB_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low)) -#define SET_FIELD(value, field) (((value) << field ## _SHIFT) & field ## _MASK) -#define GET_FIELD(word, field) (((word) & field ## _MASK) >> field ## _SHIFT) - -#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) - -/* PCI config space */ - -#define SB_PCKT 0x02100 /* cedarview */ -# define SB_OPCODE_MASK PSB_MASK(31, 16) -# define SB_OPCODE_SHIFT 16 -# define SB_OPCODE_READ 0 -# define SB_OPCODE_WRITE 1 -# define SB_DEST_MASK PSB_MASK(15, 8) -# define SB_DEST_SHIFT 8 -# define SB_DEST_DPLL 0x88 -# define SB_BYTE_ENABLE_MASK PSB_MASK(7, 4) -# define SB_BYTE_ENABLE_SHIFT 4 -# define SB_BUSY (1 << 0) - -#define DSPCLK_GATE_D 0x6200 -# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* Fixed value on CDV */ -# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) -# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) - -#define RAMCLK_GATE_D 0x6210 - -/* 32-bit value read/written from the DPIO reg. */ -#define SB_DATA 0x02104 /* cedarview */ -/* 32-bit address of the DPIO reg to be read/written. */ -#define SB_ADDR 0x02108 /* cedarview */ -#define DPIO_CFG 0x02110 /* cedarview */ -# define DPIO_MODE_SELECT_1 (1 << 3) -# define DPIO_MODE_SELECT_0 (1 << 2) -# define DPIO_SFR_BYPASS (1 << 1) -/* reset is active low */ -# define DPIO_CMN_RESET_N (1 << 0) - -/* Cedarview sideband registers */ -#define _SB_M_A 0x8008 -#define _SB_M_B 0x8028 -#define SB_M(pipe) _PIPE(pipe, _SB_M_A, _SB_M_B) -# define SB_M_DIVIDER_MASK (0xFF << 24) -# define SB_M_DIVIDER_SHIFT 24 - -#define _SB_N_VCO_A 0x8014 -#define _SB_N_VCO_B 0x8034 -#define SB_N_VCO(pipe) _PIPE(pipe, _SB_N_VCO_A, _SB_N_VCO_B) -#define SB_N_VCO_SEL_MASK PSB_MASK(31, 30) -#define SB_N_VCO_SEL_SHIFT 30 -#define SB_N_DIVIDER_MASK PSB_MASK(29, 26) -#define SB_N_DIVIDER_SHIFT 26 -#define SB_N_CB_TUNE_MASK PSB_MASK(25, 24) -#define SB_N_CB_TUNE_SHIFT 24 - -#define _SB_REF_A 0x8018 -#define _SB_REF_B 0x8038 -#define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B) - -#define _SB_P_A 0x801c -#define _SB_P_B 0x803c -#define SB_P(pipe) _PIPE(pipe, _SB_P_A, _SB_P_B) -#define SB_P2_DIVIDER_MASK PSB_MASK(31, 30) -#define SB_P2_DIVIDER_SHIFT 30 -#define SB_P2_10 0 /* HDMI, DP, DAC */ -#define SB_P2_5 1 /* DAC */ -#define SB_P2_14 2 /* LVDS single */ -#define SB_P2_7 3 /* LVDS double */ -#define SB_P1_DIVIDER_MASK PSB_MASK(15, 12) -#define SB_P1_DIVIDER_SHIFT 12 - -#define PSB_LANE0 0x120 -#define PSB_LANE1 0x220 -#define PSB_LANE2 0x2320 -#define PSB_LANE3 0x2420 - -#define LANE_PLL_MASK (0x7 << 20) -#define LANE_PLL_ENABLE (0x3 << 20) - - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo.c deleted file mode 100644 index 36330cab..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ /dev/null @@ -1,2607 +0,0 @@ -/* - * Copyright 2006 Dave Airlie - * Copyright © 2006-2007 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ -#include -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_edid.h" -#include "psb_intel_drv.h" -#include "gma_drm.h" -#include "psb_drv.h" -#include "psb_intel_sdvo_regs.h" -#include "psb_intel_reg.h" - -#define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) -#define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) -#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) -#define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0) - -#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\ - SDVO_TV_MASK) - -#define IS_TV(c) (c->output_flag & SDVO_TV_MASK) -#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) -#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) -#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) - - -static const char *tv_format_names[] = { - "NTSC_M" , "NTSC_J" , "NTSC_443", - "PAL_B" , "PAL_D" , "PAL_G" , - "PAL_H" , "PAL_I" , "PAL_M" , - "PAL_N" , "PAL_NC" , "PAL_60" , - "SECAM_B" , "SECAM_D" , "SECAM_G" , - "SECAM_K" , "SECAM_K1", "SECAM_L" , - "SECAM_60" -}; - -#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) - -struct psb_intel_sdvo { - struct psb_intel_encoder base; - - struct i2c_adapter *i2c; - u8 slave_addr; - - struct i2c_adapter ddc; - - /* Register for the SDVO device: SDVOB or SDVOC */ - int sdvo_reg; - - /* Active outputs controlled by this SDVO output */ - uint16_t controlled_output; - - /* - * Capabilities of the SDVO device returned by - * i830_sdvo_get_capabilities() - */ - struct psb_intel_sdvo_caps caps; - - /* Pixel clock limitations reported by the SDVO device, in kHz */ - int pixel_clock_min, pixel_clock_max; - - /* - * For multiple function SDVO device, - * this is for current attached outputs. - */ - uint16_t attached_output; - - /** - * This is used to select the color range of RBG outputs in HDMI mode. - * It is only valid when using TMDS encoding and 8 bit per color mode. - */ - uint32_t color_range; - - /** - * This is set if we're going to treat the device as TV-out. - * - * While we have these nice friendly flags for output types that ought - * to decide this for us, the S-Video output on our HDMI+S-Video card - * shows up as RGB1 (VGA). - */ - bool is_tv; - - /* This is for current tv format name */ - int tv_format_index; - - /** - * This is set if we treat the device as HDMI, instead of DVI. - */ - bool is_hdmi; - bool has_hdmi_monitor; - bool has_hdmi_audio; - - /** - * This is set if we detect output of sdvo device as LVDS and - * have a valid fixed mode to use with the panel. - */ - bool is_lvds; - - /** - * This is sdvo fixed pannel mode pointer - */ - struct drm_display_mode *sdvo_lvds_fixed_mode; - - /* DDC bus used by this SDVO encoder */ - uint8_t ddc_bus; - - /* Input timings for adjusted_mode */ - struct psb_intel_sdvo_dtd input_dtd; -}; - -struct psb_intel_sdvo_connector { - struct psb_intel_connector base; - - /* Mark the type of connector */ - uint16_t output_flag; - - int force_audio; - - /* This contains all current supported TV format */ - u8 tv_format_supported[TV_FORMAT_NUM]; - int format_supported_num; - struct drm_property *tv_format; - - /* add the property for the SDVO-TV */ - struct drm_property *left; - struct drm_property *right; - struct drm_property *top; - struct drm_property *bottom; - struct drm_property *hpos; - struct drm_property *vpos; - struct drm_property *contrast; - struct drm_property *saturation; - struct drm_property *hue; - struct drm_property *sharpness; - struct drm_property *flicker_filter; - struct drm_property *flicker_filter_adaptive; - struct drm_property *flicker_filter_2d; - struct drm_property *tv_chroma_filter; - struct drm_property *tv_luma_filter; - struct drm_property *dot_crawl; - - /* add the property for the SDVO-TV/LVDS */ - struct drm_property *brightness; - - /* Add variable to record current setting for the above property */ - u32 left_margin, right_margin, top_margin, bottom_margin; - - /* this is to get the range of margin.*/ - u32 max_hscan, max_vscan; - u32 max_hpos, cur_hpos; - u32 max_vpos, cur_vpos; - u32 cur_brightness, max_brightness; - u32 cur_contrast, max_contrast; - u32 cur_saturation, max_saturation; - u32 cur_hue, max_hue; - u32 cur_sharpness, max_sharpness; - u32 cur_flicker_filter, max_flicker_filter; - u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; - u32 cur_flicker_filter_2d, max_flicker_filter_2d; - u32 cur_tv_chroma_filter, max_tv_chroma_filter; - u32 cur_tv_luma_filter, max_tv_luma_filter; - u32 cur_dot_crawl, max_dot_crawl; -}; - -static struct psb_intel_sdvo *to_psb_intel_sdvo(struct drm_encoder *encoder) -{ - return container_of(encoder, struct psb_intel_sdvo, base.base); -} - -static struct psb_intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) -{ - return container_of(psb_intel_attached_encoder(connector), - struct psb_intel_sdvo, base); -} - -static struct psb_intel_sdvo_connector *to_psb_intel_sdvo_connector(struct drm_connector *connector) -{ - return container_of(to_psb_intel_connector(connector), struct psb_intel_sdvo_connector, base); -} - -static bool -psb_intel_sdvo_output_setup(struct psb_intel_sdvo *psb_intel_sdvo, uint16_t flags); -static bool -psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, - int type); -static bool -psb_intel_sdvo_create_enhance_property(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector); - -/** - * Writes the SDVOB or SDVOC with the given value, but always writes both - * SDVOB and SDVOC to work around apparent hardware issues (according to - * comments in the BIOS). - */ -static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u32 val) -{ - struct drm_device *dev = psb_intel_sdvo->base.base.dev; - u32 bval = val, cval = val; - int i; - - if (psb_intel_sdvo->sdvo_reg == SDVOB) { - cval = REG_READ(SDVOC); - } else { - bval = REG_READ(SDVOB); - } - /* - * Write the registers twice for luck. Sometimes, - * writing them only once doesn't appear to 'stick'. - * The BIOS does this too. Yay, magic - */ - for (i = 0; i < 2; i++) - { - REG_WRITE(SDVOB, bval); - REG_READ(SDVOB); - REG_WRITE(SDVOC, cval); - REG_READ(SDVOC); - } -} - -static bool psb_intel_sdvo_read_byte(struct psb_intel_sdvo *psb_intel_sdvo, u8 addr, u8 *ch) -{ - struct i2c_msg msgs[] = { - { - .addr = psb_intel_sdvo->slave_addr, - .flags = 0, - .len = 1, - .buf = &addr, - }, - { - .addr = psb_intel_sdvo->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = ch, - } - }; - int ret; - - if ((ret = i2c_transfer(psb_intel_sdvo->i2c, msgs, 2)) == 2) - return true; - - DRM_DEBUG_KMS("i2c transfer returned %d\n", ret); - return false; -} - -#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} -/** Mapping of command numbers to names, for debug output */ -static const struct _sdvo_cmd_name { - u8 cmd; - const char *name; -} sdvo_cmd_names[] = { - SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), - - /* Add the op code for SDVO enhancements */ - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), - - /* HDMI op code */ - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), -}; - -#define IS_SDVOB(reg) (reg == SDVOB) -#define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") - -static void psb_intel_sdvo_debug_write(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, - const void *args, int args_len) -{ - int i; - - DRM_DEBUG_KMS("%s: W: %02X ", - SDVO_NAME(psb_intel_sdvo), cmd); - for (i = 0; i < args_len; i++) - DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); - for (; i < 8; i++) - DRM_LOG_KMS(" "); - for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) { - if (cmd == sdvo_cmd_names[i].cmd) { - DRM_LOG_KMS("(%s)", sdvo_cmd_names[i].name); - break; - } - } - if (i == ARRAY_SIZE(sdvo_cmd_names)) - DRM_LOG_KMS("(%02X)", cmd); - DRM_LOG_KMS("\n"); -} - -static const char *cmd_status_names[] = { - "Power on", - "Success", - "Not supported", - "Invalid arg", - "Pending", - "Target not specified", - "Scaling not supported" -}; - -static bool psb_intel_sdvo_write_cmd(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, - const void *args, int args_len) -{ - u8 buf[args_len*2 + 2], status; - struct i2c_msg msgs[args_len + 3]; - int i, ret; - - psb_intel_sdvo_debug_write(psb_intel_sdvo, cmd, args, args_len); - - for (i = 0; i < args_len; i++) { - msgs[i].addr = psb_intel_sdvo->slave_addr; - msgs[i].flags = 0; - msgs[i].len = 2; - msgs[i].buf = buf + 2 *i; - buf[2*i + 0] = SDVO_I2C_ARG_0 - i; - buf[2*i + 1] = ((u8*)args)[i]; - } - msgs[i].addr = psb_intel_sdvo->slave_addr; - msgs[i].flags = 0; - msgs[i].len = 2; - msgs[i].buf = buf + 2*i; - buf[2*i + 0] = SDVO_I2C_OPCODE; - buf[2*i + 1] = cmd; - - /* the following two are to read the response */ - status = SDVO_I2C_CMD_STATUS; - msgs[i+1].addr = psb_intel_sdvo->slave_addr; - msgs[i+1].flags = 0; - msgs[i+1].len = 1; - msgs[i+1].buf = &status; - - msgs[i+2].addr = psb_intel_sdvo->slave_addr; - msgs[i+2].flags = I2C_M_RD; - msgs[i+2].len = 1; - msgs[i+2].buf = &status; - - ret = i2c_transfer(psb_intel_sdvo->i2c, msgs, i+3); - if (ret < 0) { - DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); - return false; - } - if (ret != i+3) { - /* failure in I2C transfer */ - DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); - return false; - } - - return true; -} - -static bool psb_intel_sdvo_read_response(struct psb_intel_sdvo *psb_intel_sdvo, - void *response, int response_len) -{ - u8 retry = 5; - u8 status; - int i; - - DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(psb_intel_sdvo)); - - /* - * The documentation states that all commands will be - * processed within 15µs, and that we need only poll - * the status byte a maximum of 3 times in order for the - * command to be complete. - * - * Check 5 times in case the hardware failed to read the docs. - */ - if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, - SDVO_I2C_CMD_STATUS, - &status)) - goto log_fail; - - while (status == SDVO_CMD_STATUS_PENDING && retry--) { - udelay(15); - if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, - SDVO_I2C_CMD_STATUS, - &status)) - goto log_fail; - } - - if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) - DRM_LOG_KMS("(%s)", cmd_status_names[status]); - else - DRM_LOG_KMS("(??? %d)", status); - - if (status != SDVO_CMD_STATUS_SUCCESS) - goto log_fail; - - /* Read the command response */ - for (i = 0; i < response_len; i++) { - if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, - SDVO_I2C_RETURN_0 + i, - &((u8 *)response)[i])) - goto log_fail; - DRM_LOG_KMS(" %02X", ((u8 *)response)[i]); - } - DRM_LOG_KMS("\n"); - return true; - -log_fail: - DRM_LOG_KMS("... failed\n"); - return false; -} - -static int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) -{ - if (mode->clock >= 100000) - return 1; - else if (mode->clock >= 50000) - return 2; - else - return 4; -} - -static bool psb_intel_sdvo_set_control_bus_switch(struct psb_intel_sdvo *psb_intel_sdvo, - u8 ddc_bus) -{ - /* This must be the immediately preceding write before the i2c xfer */ - return psb_intel_sdvo_write_cmd(psb_intel_sdvo, - SDVO_CMD_SET_CONTROL_BUS_SWITCH, - &ddc_bus, 1); -} - -static bool psb_intel_sdvo_set_value(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, const void *data, int len) -{ - if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, cmd, data, len)) - return false; - - return psb_intel_sdvo_read_response(psb_intel_sdvo, NULL, 0); -} - -static bool -psb_intel_sdvo_get_value(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, void *value, int len) -{ - if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, cmd, NULL, 0)) - return false; - - return psb_intel_sdvo_read_response(psb_intel_sdvo, value, len); -} - -static bool psb_intel_sdvo_set_target_input(struct psb_intel_sdvo *psb_intel_sdvo) -{ - struct psb_intel_sdvo_set_target_input_args targets = {0}; - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_TARGET_INPUT, - &targets, sizeof(targets)); -} - -/** - * Return whether each input is trained. - * - * This function is making an assumption about the layout of the response, - * which should be checked against the docs. - */ -static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_sdvo *psb_intel_sdvo, bool *input_1, bool *input_2) -{ - struct psb_intel_sdvo_get_trained_inputs_response response; - - BUILD_BUG_ON(sizeof(response) != 1); - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, - &response, sizeof(response))) - return false; - - *input_1 = response.input0_trained; - *input_2 = response.input1_trained; - return true; -} - -static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_sdvo *psb_intel_sdvo, - u16 outputs) -{ - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_ACTIVE_OUTPUTS, - &outputs, sizeof(outputs)); -} - -static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_sdvo *psb_intel_sdvo, - int mode) -{ - u8 state = SDVO_ENCODER_STATE_ON; - - switch (mode) { - case DRM_MODE_DPMS_ON: - state = SDVO_ENCODER_STATE_ON; - break; - case DRM_MODE_DPMS_STANDBY: - state = SDVO_ENCODER_STATE_STANDBY; - break; - case DRM_MODE_DPMS_SUSPEND: - state = SDVO_ENCODER_STATE_SUSPEND; - break; - case DRM_MODE_DPMS_OFF: - state = SDVO_ENCODER_STATE_OFF; - break; - } - - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); -} - -static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_sdvo *psb_intel_sdvo, - int *clock_min, - int *clock_max) -{ - struct psb_intel_sdvo_pixel_clock_range clocks; - - BUILD_BUG_ON(sizeof(clocks) != 4); - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, - &clocks, sizeof(clocks))) - return false; - - /* Convert the values from units of 10 kHz to kHz. */ - *clock_min = clocks.min * 10; - *clock_max = clocks.max * 10; - return true; -} - -static bool psb_intel_sdvo_set_target_output(struct psb_intel_sdvo *psb_intel_sdvo, - u16 outputs) -{ - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_TARGET_OUTPUT, - &outputs, sizeof(outputs)); -} - -static bool psb_intel_sdvo_set_timing(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, - struct psb_intel_sdvo_dtd *dtd) -{ - return psb_intel_sdvo_set_value(psb_intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && - psb_intel_sdvo_set_value(psb_intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); -} - -static bool psb_intel_sdvo_set_input_timing(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_dtd *dtd) -{ - return psb_intel_sdvo_set_timing(psb_intel_sdvo, - SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); -} - -static bool psb_intel_sdvo_set_output_timing(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_dtd *dtd) -{ - return psb_intel_sdvo_set_timing(psb_intel_sdvo, - SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); -} - -static bool -psb_intel_sdvo_create_preferred_input_timing(struct psb_intel_sdvo *psb_intel_sdvo, - uint16_t clock, - uint16_t width, - uint16_t height) -{ - struct psb_intel_sdvo_preferred_input_timing_args args; - - memset(&args, 0, sizeof(args)); - args.clock = clock; - args.width = width; - args.height = height; - args.interlace = 0; - - if (psb_intel_sdvo->is_lvds && - (psb_intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || - psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) - args.scaled = 1; - - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, - &args, sizeof(args)); -} - -static bool psb_intel_sdvo_get_preferred_input_timing(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_dtd *dtd) -{ - BUILD_BUG_ON(sizeof(dtd->part1) != 8); - BUILD_BUG_ON(sizeof(dtd->part2) != 8); - return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, - &dtd->part1, sizeof(dtd->part1)) && - psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, - &dtd->part2, sizeof(dtd->part2)); -} - -static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_sdvo *psb_intel_sdvo, u8 val) -{ - return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); -} - -static void psb_intel_sdvo_get_dtd_from_mode(struct psb_intel_sdvo_dtd *dtd, - const struct drm_display_mode *mode) -{ - uint16_t width, height; - uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; - uint16_t h_sync_offset, v_sync_offset; - - width = mode->crtc_hdisplay; - height = mode->crtc_vdisplay; - - /* do some mode translations */ - h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; - h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; - - v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; - v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; - - h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; - v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - - dtd->part1.clock = mode->clock / 10; - dtd->part1.h_active = width & 0xff; - dtd->part1.h_blank = h_blank_len & 0xff; - dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | - ((h_blank_len >> 8) & 0xf); - dtd->part1.v_active = height & 0xff; - dtd->part1.v_blank = v_blank_len & 0xff; - dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | - ((v_blank_len >> 8) & 0xf); - - dtd->part2.h_sync_off = h_sync_offset & 0xff; - dtd->part2.h_sync_width = h_sync_len & 0xff; - dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | - (v_sync_len & 0xf); - dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | - ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | - ((v_sync_len & 0x30) >> 4); - - dtd->part2.dtd_flags = 0x18; - if (mode->flags & DRM_MODE_FLAG_PHSYNC) - dtd->part2.dtd_flags |= 0x2; - if (mode->flags & DRM_MODE_FLAG_PVSYNC) - dtd->part2.dtd_flags |= 0x4; - - dtd->part2.sdvo_flags = 0; - dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; - dtd->part2.reserved = 0; -} - -static void psb_intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, - const struct psb_intel_sdvo_dtd *dtd) -{ - mode->hdisplay = dtd->part1.h_active; - mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; - mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; - mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; - mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; - mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; - mode->htotal = mode->hdisplay + dtd->part1.h_blank; - mode->htotal += (dtd->part1.h_high & 0xf) << 8; - - mode->vdisplay = dtd->part1.v_active; - mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; - mode->vsync_start = mode->vdisplay; - mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; - mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; - mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; - mode->vsync_end = mode->vsync_start + - (dtd->part2.v_sync_off_width & 0xf); - mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; - mode->vtotal = mode->vdisplay + dtd->part1.v_blank; - mode->vtotal += (dtd->part1.v_high & 0xf) << 8; - - mode->clock = dtd->part1.clock * 10; - - mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); - if (dtd->part2.dtd_flags & 0x2) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - if (dtd->part2.dtd_flags & 0x4) - mode->flags |= DRM_MODE_FLAG_PVSYNC; -} - -static bool psb_intel_sdvo_check_supp_encode(struct psb_intel_sdvo *psb_intel_sdvo) -{ - struct psb_intel_sdvo_encode encode; - - BUILD_BUG_ON(sizeof(encode) != 2); - return psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_SUPP_ENCODE, - &encode, sizeof(encode)); -} - -static bool psb_intel_sdvo_set_encode(struct psb_intel_sdvo *psb_intel_sdvo, - uint8_t mode) -{ - return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); -} - -static bool psb_intel_sdvo_set_colorimetry(struct psb_intel_sdvo *psb_intel_sdvo, - uint8_t mode) -{ - return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); -} - -#if 0 -static void psb_intel_sdvo_dump_hdmi_buf(struct psb_intel_sdvo *psb_intel_sdvo) -{ - int i, j; - uint8_t set_buf_index[2]; - uint8_t av_split; - uint8_t buf_size; - uint8_t buf[48]; - uint8_t *pos; - - psb_intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); - - for (i = 0; i <= av_split; i++) { - set_buf_index[0] = i; set_buf_index[1] = 0; - psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2); - psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); - psb_intel_sdvo_read_response(encoder, &buf_size, 1); - - pos = buf; - for (j = 0; j <= buf_size; j += 8) { - psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA, - NULL, 0); - psb_intel_sdvo_read_response(encoder, pos, 8); - pos += 8; - } - } -} -#endif - -static bool psb_intel_sdvo_set_avi_infoframe(struct psb_intel_sdvo *psb_intel_sdvo) -{ - DRM_INFO("HDMI is not supported yet"); - - return false; -#if 0 - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; - uint8_t set_buf_index[2] = { 1, 0 }; - uint64_t *data = (uint64_t *)&avi_if; - unsigned i; - - intel_dip_infoframe_csum(&avi_if); - - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2)) - return false; - - for (i = 0; i < sizeof(avi_if); i += 8) { - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_HBUF_DATA, - data, 8)) - return false; - data++; - } - - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_HBUF_TXRATE, - &tx_rate, 1); -#endif -} - -static bool psb_intel_sdvo_set_tv_format(struct psb_intel_sdvo *psb_intel_sdvo) -{ - struct psb_intel_sdvo_tv_format format; - uint32_t format_map; - - format_map = 1 << psb_intel_sdvo->tv_format_index; - memset(&format, 0, sizeof(format)); - memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); - - BUILD_BUG_ON(sizeof(format) != 6); - return psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_TV_FORMAT, - &format, sizeof(format)); -} - -static bool -psb_intel_sdvo_set_output_timings_from_mode(struct psb_intel_sdvo *psb_intel_sdvo, - struct drm_display_mode *mode) -{ - struct psb_intel_sdvo_dtd output_dtd; - - if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, - psb_intel_sdvo->attached_output)) - return false; - - psb_intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - if (!psb_intel_sdvo_set_output_timing(psb_intel_sdvo, &output_dtd)) - return false; - - return true; -} - -static bool -psb_intel_sdvo_set_input_timings_for_mode(struct psb_intel_sdvo *psb_intel_sdvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* Reset the input timing to the screen. Assume always input 0. */ - if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo)) - return false; - - if (!psb_intel_sdvo_create_preferred_input_timing(psb_intel_sdvo, - mode->clock / 10, - mode->hdisplay, - mode->vdisplay)) - return false; - - if (!psb_intel_sdvo_get_preferred_input_timing(psb_intel_sdvo, - &psb_intel_sdvo->input_dtd)) - return false; - - psb_intel_sdvo_get_mode_from_dtd(adjusted_mode, &psb_intel_sdvo->input_dtd); - - drm_mode_set_crtcinfo(adjusted_mode, 0); - return true; -} - -static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); - int multiplier; - - /* We need to construct preferred input timings based on our - * output timings. To do that, we have to set the output - * timings, even though this isn't really the right place in - * the sequence to do it. Oh well. - */ - if (psb_intel_sdvo->is_tv) { - if (!psb_intel_sdvo_set_output_timings_from_mode(psb_intel_sdvo, mode)) - return false; - - (void) psb_intel_sdvo_set_input_timings_for_mode(psb_intel_sdvo, - mode, - adjusted_mode); - } else if (psb_intel_sdvo->is_lvds) { - if (!psb_intel_sdvo_set_output_timings_from_mode(psb_intel_sdvo, - psb_intel_sdvo->sdvo_lvds_fixed_mode)) - return false; - - (void) psb_intel_sdvo_set_input_timings_for_mode(psb_intel_sdvo, - mode, - adjusted_mode); - } - - /* Make the CRTC code factor in the SDVO pixel multiplier. The - * SDVO device will factor out the multiplier during mode_set. - */ - multiplier = psb_intel_sdvo_get_pixel_multiplier(adjusted_mode); - psb_intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); - - return true; -} - -static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc = encoder->crtc; - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); - u32 sdvox; - struct psb_intel_sdvo_in_out_map in_out; - struct psb_intel_sdvo_dtd input_dtd; - int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode); - int rate; - - if (!mode) - return; - - /* First, set the input mapping for the first input to our controlled - * output. This is only correct if we're a single-input device, in - * which case the first input is the output from the appropriate SDVO - * channel on the motherboard. In a two-input device, the first input - * will be SDVOB and the second SDVOC. - */ - in_out.in0 = psb_intel_sdvo->attached_output; - in_out.in1 = 0; - - psb_intel_sdvo_set_value(psb_intel_sdvo, - SDVO_CMD_SET_IN_OUT_MAP, - &in_out, sizeof(in_out)); - - /* Set the output timings to the screen */ - if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, - psb_intel_sdvo->attached_output)) - return; - - /* We have tried to get input timing in mode_fixup, and filled into - * adjusted_mode. - */ - if (psb_intel_sdvo->is_tv || psb_intel_sdvo->is_lvds) { - input_dtd = psb_intel_sdvo->input_dtd; - } else { - /* Set the output timing to the screen */ - if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, - psb_intel_sdvo->attached_output)) - return; - - psb_intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); - (void) psb_intel_sdvo_set_output_timing(psb_intel_sdvo, &input_dtd); - } - - /* Set the input timing to the screen. Assume always input 0. */ - if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo)) - return; - - if (psb_intel_sdvo->has_hdmi_monitor) { - psb_intel_sdvo_set_encode(psb_intel_sdvo, SDVO_ENCODE_HDMI); - psb_intel_sdvo_set_colorimetry(psb_intel_sdvo, - SDVO_COLORIMETRY_RGB256); - psb_intel_sdvo_set_avi_infoframe(psb_intel_sdvo); - } else - psb_intel_sdvo_set_encode(psb_intel_sdvo, SDVO_ENCODE_DVI); - - if (psb_intel_sdvo->is_tv && - !psb_intel_sdvo_set_tv_format(psb_intel_sdvo)) - return; - - (void) psb_intel_sdvo_set_input_timing(psb_intel_sdvo, &input_dtd); - - switch (pixel_multiplier) { - default: - case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; - case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; - case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; - } - if (!psb_intel_sdvo_set_clock_rate_mult(psb_intel_sdvo, rate)) - return; - - /* Set the SDVO control regs. */ - sdvox = REG_READ(psb_intel_sdvo->sdvo_reg); - switch (psb_intel_sdvo->sdvo_reg) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; - - if (psb_intel_crtc->pipe == 1) - sdvox |= SDVO_PIPE_B_SELECT; - if (psb_intel_sdvo->has_hdmi_audio) - sdvox |= SDVO_AUDIO_ENABLE; - - /* FIXME: Check if this is needed for PSB - sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; - */ - - if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL) - sdvox |= SDVO_STALL_SELECT; - psb_intel_sdvo_write_sdvox(psb_intel_sdvo, sdvox); -} - -static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); - u32 temp; - - switch (mode) { - case DRM_MODE_DPMS_ON: - DRM_DEBUG("DPMS_ON"); - break; - case DRM_MODE_DPMS_OFF: - DRM_DEBUG("DPMS_OFF"); - break; - default: - DRM_DEBUG("DPMS: %d", mode); - } - - if (mode != DRM_MODE_DPMS_ON) { - psb_intel_sdvo_set_active_outputs(psb_intel_sdvo, 0); - if (0) - psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode); - - if (mode == DRM_MODE_DPMS_OFF) { - temp = REG_READ(psb_intel_sdvo->sdvo_reg); - if ((temp & SDVO_ENABLE) != 0) { - psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE); - } - } - } else { - bool input1, input2; - int i; - u8 status; - - temp = REG_READ(psb_intel_sdvo->sdvo_reg); - if ((temp & SDVO_ENABLE) == 0) - psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE); - for (i = 0; i < 2; i++) - psb_intel_wait_for_vblank(dev); - - status = psb_intel_sdvo_get_trained_inputs(psb_intel_sdvo, &input1, &input2); - /* Warn if the device reported failure to sync. - * A lot of SDVO devices fail to notify of sync, but it's - * a given it the status is a success, we succeeded. - */ - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { - DRM_DEBUG_KMS("First %s output reported failure to " - "sync\n", SDVO_NAME(psb_intel_sdvo)); - } - - if (0) - psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode); - psb_intel_sdvo_set_active_outputs(psb_intel_sdvo, psb_intel_sdvo->attached_output); - } - return; -} - -static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_psb_private *dev_priv = connector->dev->dev_private; - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (psb_intel_sdvo->pixel_clock_min > mode->clock) - return MODE_CLOCK_LOW; - - if (psb_intel_sdvo->pixel_clock_max < mode->clock) - return MODE_CLOCK_HIGH; - - if (psb_intel_sdvo->is_lvds) { - if (mode->hdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) - return MODE_PANEL; - - if (mode->vdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) - return MODE_PANEL; - } - - /* We assume worst case scenario of 32 bpp here, since we don't know */ - if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > - dev_priv->vram_stolen_size) - return MODE_MEM; - - return MODE_OK; -} - -static bool psb_intel_sdvo_get_capabilities(struct psb_intel_sdvo *psb_intel_sdvo, struct psb_intel_sdvo_caps *caps) -{ - BUILD_BUG_ON(sizeof(*caps) != 8); - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_DEVICE_CAPS, - caps, sizeof(*caps))) - return false; - - DRM_DEBUG_KMS("SDVO capabilities:\n" - " vendor_id: %d\n" - " device_id: %d\n" - " device_rev_id: %d\n" - " sdvo_version_major: %d\n" - " sdvo_version_minor: %d\n" - " sdvo_inputs_mask: %d\n" - " smooth_scaling: %d\n" - " sharp_scaling: %d\n" - " up_scaling: %d\n" - " down_scaling: %d\n" - " stall_support: %d\n" - " output_flags: %d\n", - caps->vendor_id, - caps->device_id, - caps->device_rev_id, - caps->sdvo_version_major, - caps->sdvo_version_minor, - caps->sdvo_inputs_mask, - caps->smooth_scaling, - caps->sharp_scaling, - caps->up_scaling, - caps->down_scaling, - caps->stall_support, - caps->output_flags); - - return true; -} - -/* No use! */ -#if 0 -struct drm_connector* psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) -{ - struct drm_connector *connector = NULL; - struct psb_intel_sdvo *iout = NULL; - struct psb_intel_sdvo *sdvo; - - /* find the sdvo connector */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_psb_intel_sdvo(connector); - - if (iout->type != INTEL_OUTPUT_SDVO) - continue; - - sdvo = iout->dev_priv; - - if (sdvo->sdvo_reg == SDVOB && sdvoB) - return connector; - - if (sdvo->sdvo_reg == SDVOC && !sdvoB) - return connector; - - } - - return NULL; -} - -int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector) -{ - u8 response[2]; - u8 status; - struct psb_intel_sdvo *psb_intel_sdvo; - DRM_DEBUG_KMS("\n"); - - if (!connector) - return 0; - - psb_intel_sdvo = to_psb_intel_sdvo(connector); - - return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, - &response, 2) && response[0]; -} - -void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on) -{ - u8 response[2]; - u8 status; - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(connector); - - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); - - if (on) { - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); - status = psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); - - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); - } else { - response[0] = 0; - response[1] = 0; - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); - } - - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); -} -#endif - -static bool -psb_intel_sdvo_multifunc_encoder(struct psb_intel_sdvo *psb_intel_sdvo) -{ - /* Is there more than one type of output? */ - int caps = psb_intel_sdvo->caps.output_flags & 0xf; - return caps & -caps; -} - -static struct edid * -psb_intel_sdvo_get_edid(struct drm_connector *connector) -{ - struct psb_intel_sdvo *sdvo = intel_attached_sdvo(connector); - return drm_get_edid(connector, &sdvo->ddc); -} - -/* Mac mini hack -- use the same DDC as the analog connector */ -static struct edid * -psb_intel_sdvo_get_analog_edid(struct drm_connector *connector) -{ - struct drm_psb_private *dev_priv = connector->dev->dev_private; - - return drm_get_edid(connector, - &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); - return NULL; -} - -static enum drm_connector_status -psb_intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) -{ - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - enum drm_connector_status status; - struct edid *edid; - - edid = psb_intel_sdvo_get_edid(connector); - - if (edid == NULL && psb_intel_sdvo_multifunc_encoder(psb_intel_sdvo)) { - u8 ddc, saved_ddc = psb_intel_sdvo->ddc_bus; - - /* - * Don't use the 1 as the argument of DDC bus switch to get - * the EDID. It is used for SDVO SPD ROM. - */ - for (ddc = psb_intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { - psb_intel_sdvo->ddc_bus = ddc; - edid = psb_intel_sdvo_get_edid(connector); - if (edid) - break; - } - /* - * If we found the EDID on the other bus, - * assume that is the correct DDC bus. - */ - if (edid == NULL) - psb_intel_sdvo->ddc_bus = saved_ddc; - } - - /* - * When there is no edid and no monitor is connected with VGA - * port, try to use the CRT ddc to read the EDID for DVI-connector. - */ - if (edid == NULL) - edid = psb_intel_sdvo_get_analog_edid(connector); - - status = connector_status_unknown; - if (edid != NULL) { - /* DDC bus is shared, match EDID to connector type */ - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - if (psb_intel_sdvo->is_hdmi) { - psb_intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); - psb_intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); - } - } else - status = connector_status_disconnected; - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - if (status == connector_status_connected) { - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - if (psb_intel_sdvo_connector->force_audio) - psb_intel_sdvo->has_hdmi_audio = psb_intel_sdvo_connector->force_audio > 0; - } - - return status; -} - -static enum drm_connector_status -psb_intel_sdvo_detect(struct drm_connector *connector, bool force) -{ - uint16_t response; - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - enum drm_connector_status ret; - - if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, - SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) - return connector_status_unknown; - - /* add 30ms delay when the output type might be TV */ - if (psb_intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0)) - mdelay(30); - - if (!psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2)) - return connector_status_unknown; - - DRM_DEBUG_KMS("SDVO response %d %d [%x]\n", - response & 0xff, response >> 8, - psb_intel_sdvo_connector->output_flag); - - if (response == 0) - return connector_status_disconnected; - - psb_intel_sdvo->attached_output = response; - - psb_intel_sdvo->has_hdmi_monitor = false; - psb_intel_sdvo->has_hdmi_audio = false; - - if ((psb_intel_sdvo_connector->output_flag & response) == 0) - ret = connector_status_disconnected; - else if (IS_TMDS(psb_intel_sdvo_connector)) - ret = psb_intel_sdvo_hdmi_sink_detect(connector); - else { - struct edid *edid; - - /* if we have an edid check it matches the connection */ - edid = psb_intel_sdvo_get_edid(connector); - if (edid == NULL) - edid = psb_intel_sdvo_get_analog_edid(connector); - if (edid != NULL) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) - ret = connector_status_disconnected; - else - ret = connector_status_connected; - connector->display_info.raw_edid = NULL; - kfree(edid); - } else - ret = connector_status_connected; - } - - /* May update encoder flag for like clock for SDVO TV, etc.*/ - if (ret == connector_status_connected) { - psb_intel_sdvo->is_tv = false; - psb_intel_sdvo->is_lvds = false; - psb_intel_sdvo->base.needs_tv_clock = false; - - if (response & SDVO_TV_MASK) { - psb_intel_sdvo->is_tv = true; - psb_intel_sdvo->base.needs_tv_clock = true; - } - if (response & SDVO_LVDS_MASK) - psb_intel_sdvo->is_lvds = psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL; - } - - return ret; -} - -static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector) -{ - struct edid *edid; - - /* set the bus switch and get the modes */ - edid = psb_intel_sdvo_get_edid(connector); - - /* - * Mac mini hack. On this device, the DVI-I connector shares one DDC - * link between analog and digital outputs. So, if the regular SDVO - * DDC fails, check to see if the analog output is disconnected, in - * which case we'll look there for the digital DDC data. - */ - if (edid == NULL) - edid = psb_intel_sdvo_get_analog_edid(connector); - - if (edid != NULL) { - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); - bool connector_is_digital = !!IS_TMDS(psb_intel_sdvo_connector); - - if (connector_is_digital == monitor_is_digital) { - drm_mode_connector_update_edid_property(connector, edid); - drm_add_edid_modes(connector, edid); - } - - connector->display_info.raw_edid = NULL; - kfree(edid); - } -} - -/* - * Set of SDVO TV modes. - * Note! This is in reply order (see loop in get_tv_modes). - * XXX: all 60Hz refresh? - */ -static const struct drm_display_mode sdvo_tv_modes[] = { - { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384, - 416, 0, 200, 201, 232, 233, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384, - 416, 0, 240, 241, 272, 273, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464, - 496, 0, 300, 301, 332, 333, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704, - 736, 0, 350, 351, 382, 383, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704, - 736, 0, 400, 401, 432, 433, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704, - 736, 0, 480, 481, 512, 513, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768, - 800, 0, 480, 481, 512, 513, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768, - 800, 0, 576, 577, 608, 609, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784, - 816, 0, 350, 351, 382, 383, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784, - 816, 0, 400, 401, 432, 433, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784, - 816, 0, 480, 481, 512, 513, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784, - 816, 0, 540, 541, 572, 573, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784, - 816, 0, 576, 577, 608, 609, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832, - 864, 0, 576, 577, 608, 609, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864, - 896, 0, 600, 601, 632, 633, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896, - 928, 0, 624, 625, 656, 657, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984, - 1016, 0, 766, 767, 798, 799, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088, - 1120, 0, 768, 769, 800, 801, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344, - 1376, 0, 1024, 1025, 1056, 1057, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -}; - -static void psb_intel_sdvo_get_tv_modes(struct drm_connector *connector) -{ - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - struct psb_intel_sdvo_sdtv_resolution_request tv_res; - uint32_t reply = 0, format_map = 0; - int i; - - /* Read the list of supported input resolutions for the selected TV - * format. - */ - format_map = 1 << psb_intel_sdvo->tv_format_index; - memcpy(&tv_res, &format_map, - min(sizeof(format_map), sizeof(struct psb_intel_sdvo_sdtv_resolution_request))); - - if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, psb_intel_sdvo->attached_output)) - return; - - BUILD_BUG_ON(sizeof(tv_res) != 3); - if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, - SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, - &tv_res, sizeof(tv_res))) - return; - if (!psb_intel_sdvo_read_response(psb_intel_sdvo, &reply, 3)) - return; - - for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) - if (reply & (1 << i)) { - struct drm_display_mode *nmode; - nmode = drm_mode_duplicate(connector->dev, - &sdvo_tv_modes[i]); - if (nmode) - drm_mode_probed_add(connector, nmode); - } -} - -static void psb_intel_sdvo_get_lvds_modes(struct drm_connector *connector) -{ - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - struct drm_psb_private *dev_priv = connector->dev->dev_private; - struct drm_display_mode *newmode; - - /* - * Attempt to get the mode list from DDC. - * Assume that the preferred modes are - * arranged in priority order. - */ - psb_intel_ddc_get_modes(connector, psb_intel_sdvo->i2c); - if (list_empty(&connector->probed_modes) == false) - goto end; - - /* Fetch modes from VBT */ - if (dev_priv->sdvo_lvds_vbt_mode != NULL) { - newmode = drm_mode_duplicate(connector->dev, - dev_priv->sdvo_lvds_vbt_mode); - if (newmode != NULL) { - /* Guarantee the mode is preferred */ - newmode->type = (DRM_MODE_TYPE_PREFERRED | - DRM_MODE_TYPE_DRIVER); - drm_mode_probed_add(connector, newmode); - } - } - -end: - list_for_each_entry(newmode, &connector->probed_modes, head) { - if (newmode->type & DRM_MODE_TYPE_PREFERRED) { - psb_intel_sdvo->sdvo_lvds_fixed_mode = - drm_mode_duplicate(connector->dev, newmode); - - drm_mode_set_crtcinfo(psb_intel_sdvo->sdvo_lvds_fixed_mode, - 0); - - psb_intel_sdvo->is_lvds = true; - break; - } - } - -} - -static int psb_intel_sdvo_get_modes(struct drm_connector *connector) -{ - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - - if (IS_TV(psb_intel_sdvo_connector)) - psb_intel_sdvo_get_tv_modes(connector); - else if (IS_LVDS(psb_intel_sdvo_connector)) - psb_intel_sdvo_get_lvds_modes(connector); - else - psb_intel_sdvo_get_ddc_modes(connector); - - return !list_empty(&connector->probed_modes); -} - -static void -psb_intel_sdvo_destroy_enhance_property(struct drm_connector *connector) -{ - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - struct drm_device *dev = connector->dev; - - if (psb_intel_sdvo_connector->left) - drm_property_destroy(dev, psb_intel_sdvo_connector->left); - if (psb_intel_sdvo_connector->right) - drm_property_destroy(dev, psb_intel_sdvo_connector->right); - if (psb_intel_sdvo_connector->top) - drm_property_destroy(dev, psb_intel_sdvo_connector->top); - if (psb_intel_sdvo_connector->bottom) - drm_property_destroy(dev, psb_intel_sdvo_connector->bottom); - if (psb_intel_sdvo_connector->hpos) - drm_property_destroy(dev, psb_intel_sdvo_connector->hpos); - if (psb_intel_sdvo_connector->vpos) - drm_property_destroy(dev, psb_intel_sdvo_connector->vpos); - if (psb_intel_sdvo_connector->saturation) - drm_property_destroy(dev, psb_intel_sdvo_connector->saturation); - if (psb_intel_sdvo_connector->contrast) - drm_property_destroy(dev, psb_intel_sdvo_connector->contrast); - if (psb_intel_sdvo_connector->hue) - drm_property_destroy(dev, psb_intel_sdvo_connector->hue); - if (psb_intel_sdvo_connector->sharpness) - drm_property_destroy(dev, psb_intel_sdvo_connector->sharpness); - if (psb_intel_sdvo_connector->flicker_filter) - drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter); - if (psb_intel_sdvo_connector->flicker_filter_2d) - drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_2d); - if (psb_intel_sdvo_connector->flicker_filter_adaptive) - drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_adaptive); - if (psb_intel_sdvo_connector->tv_luma_filter) - drm_property_destroy(dev, psb_intel_sdvo_connector->tv_luma_filter); - if (psb_intel_sdvo_connector->tv_chroma_filter) - drm_property_destroy(dev, psb_intel_sdvo_connector->tv_chroma_filter); - if (psb_intel_sdvo_connector->dot_crawl) - drm_property_destroy(dev, psb_intel_sdvo_connector->dot_crawl); - if (psb_intel_sdvo_connector->brightness) - drm_property_destroy(dev, psb_intel_sdvo_connector->brightness); -} - -static void psb_intel_sdvo_destroy(struct drm_connector *connector) -{ - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - - if (psb_intel_sdvo_connector->tv_format) - drm_property_destroy(connector->dev, - psb_intel_sdvo_connector->tv_format); - - psb_intel_sdvo_destroy_enhance_property(connector); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static bool psb_intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) -{ - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - struct edid *edid; - bool has_audio = false; - - if (!psb_intel_sdvo->is_hdmi) - return false; - - edid = psb_intel_sdvo_get_edid(connector); - if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - - return has_audio; -} - -static int -psb_intel_sdvo_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); - struct drm_psb_private *dev_priv = connector->dev->dev_private; - uint16_t temp_value; - uint8_t cmd; - int ret; - - ret = drm_connector_property_set_value(connector, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - int i = val; - bool has_audio; - - if (i == psb_intel_sdvo_connector->force_audio) - return 0; - - psb_intel_sdvo_connector->force_audio = i; - - if (i == 0) - has_audio = psb_intel_sdvo_detect_hdmi_audio(connector); - else - has_audio = i > 0; - - if (has_audio == psb_intel_sdvo->has_hdmi_audio) - return 0; - - psb_intel_sdvo->has_hdmi_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - if (val == !!psb_intel_sdvo->color_range) - return 0; - - psb_intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; - goto done; - } - -#define CHECK_PROPERTY(name, NAME) \ - if (psb_intel_sdvo_connector->name == property) { \ - if (psb_intel_sdvo_connector->cur_##name == temp_value) return 0; \ - if (psb_intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ - cmd = SDVO_CMD_SET_##NAME; \ - psb_intel_sdvo_connector->cur_##name = temp_value; \ - goto set_value; \ - } - - if (property == psb_intel_sdvo_connector->tv_format) { - if (val >= TV_FORMAT_NUM) - return -EINVAL; - - if (psb_intel_sdvo->tv_format_index == - psb_intel_sdvo_connector->tv_format_supported[val]) - return 0; - - psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[val]; - goto done; - } else if (IS_TV_OR_LVDS(psb_intel_sdvo_connector)) { - temp_value = val; - if (psb_intel_sdvo_connector->left == property) { - drm_connector_property_set_value(connector, - psb_intel_sdvo_connector->right, val); - if (psb_intel_sdvo_connector->left_margin == temp_value) - return 0; - - psb_intel_sdvo_connector->left_margin = temp_value; - psb_intel_sdvo_connector->right_margin = temp_value; - temp_value = psb_intel_sdvo_connector->max_hscan - - psb_intel_sdvo_connector->left_margin; - cmd = SDVO_CMD_SET_OVERSCAN_H; - goto set_value; - } else if (psb_intel_sdvo_connector->right == property) { - drm_connector_property_set_value(connector, - psb_intel_sdvo_connector->left, val); - if (psb_intel_sdvo_connector->right_margin == temp_value) - return 0; - - psb_intel_sdvo_connector->left_margin = temp_value; - psb_intel_sdvo_connector->right_margin = temp_value; - temp_value = psb_intel_sdvo_connector->max_hscan - - psb_intel_sdvo_connector->left_margin; - cmd = SDVO_CMD_SET_OVERSCAN_H; - goto set_value; - } else if (psb_intel_sdvo_connector->top == property) { - drm_connector_property_set_value(connector, - psb_intel_sdvo_connector->bottom, val); - if (psb_intel_sdvo_connector->top_margin == temp_value) - return 0; - - psb_intel_sdvo_connector->top_margin = temp_value; - psb_intel_sdvo_connector->bottom_margin = temp_value; - temp_value = psb_intel_sdvo_connector->max_vscan - - psb_intel_sdvo_connector->top_margin; - cmd = SDVO_CMD_SET_OVERSCAN_V; - goto set_value; - } else if (psb_intel_sdvo_connector->bottom == property) { - drm_connector_property_set_value(connector, - psb_intel_sdvo_connector->top, val); - if (psb_intel_sdvo_connector->bottom_margin == temp_value) - return 0; - - psb_intel_sdvo_connector->top_margin = temp_value; - psb_intel_sdvo_connector->bottom_margin = temp_value; - temp_value = psb_intel_sdvo_connector->max_vscan - - psb_intel_sdvo_connector->top_margin; - cmd = SDVO_CMD_SET_OVERSCAN_V; - goto set_value; - } - CHECK_PROPERTY(hpos, HPOS) - CHECK_PROPERTY(vpos, VPOS) - CHECK_PROPERTY(saturation, SATURATION) - CHECK_PROPERTY(contrast, CONTRAST) - CHECK_PROPERTY(hue, HUE) - CHECK_PROPERTY(brightness, BRIGHTNESS) - CHECK_PROPERTY(sharpness, SHARPNESS) - CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) - CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) - CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) - CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) - CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) - CHECK_PROPERTY(dot_crawl, DOT_CRAWL) - } - - return -EINVAL; /* unknown property */ - -set_value: - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, cmd, &temp_value, 2)) - return -EIO; - - -done: - if (psb_intel_sdvo->base.base.crtc) { - struct drm_crtc *crtc = psb_intel_sdvo->base.base.crtc; - drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, - crtc->y, crtc->fb); - } - - return 0; -#undef CHECK_PROPERTY -} - -static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { - .dpms = psb_intel_sdvo_dpms, - .mode_fixup = psb_intel_sdvo_mode_fixup, - .prepare = psb_intel_encoder_prepare, - .mode_set = psb_intel_sdvo_mode_set, - .commit = psb_intel_encoder_commit, -}; - -static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = psb_intel_sdvo_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = psb_intel_sdvo_set_property, - .destroy = psb_intel_sdvo_destroy, -}; - -static const struct drm_connector_helper_funcs psb_intel_sdvo_connector_helper_funcs = { - .get_modes = psb_intel_sdvo_get_modes, - .mode_valid = psb_intel_sdvo_mode_valid, - .best_encoder = psb_intel_best_encoder, -}; - -static void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder) -{ - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); - - if (psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL) - drm_mode_destroy(encoder->dev, - psb_intel_sdvo->sdvo_lvds_fixed_mode); - - i2c_del_adapter(&psb_intel_sdvo->ddc); - psb_intel_encoder_destroy(encoder); -} - -static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = { - .destroy = psb_intel_sdvo_enc_destroy, -}; - -static void -psb_intel_sdvo_guess_ddc_bus(struct psb_intel_sdvo *sdvo) -{ - /* FIXME: At the moment, ddc_bus = 2 is the only thing that works. - * We need to figure out if this is true for all available poulsbo - * hardware, or if we need to fiddle with the guessing code above. - * The problem might go away if we can parse sdvo mappings from bios */ - sdvo->ddc_bus = 2; - -#if 0 - uint16_t mask = 0; - unsigned int num_bits; - - /* Make a mask of outputs less than or equal to our own priority in the - * list. - */ - switch (sdvo->controlled_output) { - case SDVO_OUTPUT_LVDS1: - mask |= SDVO_OUTPUT_LVDS1; - case SDVO_OUTPUT_LVDS0: - mask |= SDVO_OUTPUT_LVDS0; - case SDVO_OUTPUT_TMDS1: - mask |= SDVO_OUTPUT_TMDS1; - case SDVO_OUTPUT_TMDS0: - mask |= SDVO_OUTPUT_TMDS0; - case SDVO_OUTPUT_RGB1: - mask |= SDVO_OUTPUT_RGB1; - case SDVO_OUTPUT_RGB0: - mask |= SDVO_OUTPUT_RGB0; - break; - } - - /* Count bits to find what number we are in the priority list. */ - mask &= sdvo->caps.output_flags; - num_bits = hweight16(mask); - /* If more than 3 outputs, default to DDC bus 3 for now. */ - if (num_bits > 3) - num_bits = 3; - - /* Corresponds to SDVO_CONTROL_BUS_DDCx */ - sdvo->ddc_bus = 1 << num_bits; -#endif -} - -/** - * Choose the appropriate DDC bus for control bus switch command for this - * SDVO output based on the controlled output. - * - * DDC bus number assignment is in a priority order of RGB outputs, then TMDS - * outputs, then LVDS outputs. - */ -static void -psb_intel_sdvo_select_ddc_bus(struct drm_psb_private *dev_priv, - struct psb_intel_sdvo *sdvo, u32 reg) -{ - struct sdvo_device_mapping *mapping; - - if (IS_SDVOB(reg)) - mapping = &(dev_priv->sdvo_mappings[0]); - else - mapping = &(dev_priv->sdvo_mappings[1]); - - if (mapping->initialized) - sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); - else - psb_intel_sdvo_guess_ddc_bus(sdvo); -} - -static void -psb_intel_sdvo_select_i2c_bus(struct drm_psb_private *dev_priv, - struct psb_intel_sdvo *sdvo, u32 reg) -{ - struct sdvo_device_mapping *mapping; - u8 pin, speed; - - if (IS_SDVOB(reg)) - mapping = &dev_priv->sdvo_mappings[0]; - else - mapping = &dev_priv->sdvo_mappings[1]; - - pin = GMBUS_PORT_DPB; - speed = GMBUS_RATE_1MHZ >> 8; - if (mapping->initialized) { - pin = mapping->i2c_pin; - speed = mapping->i2c_speed; - } - - if (pin < GMBUS_NUM_PORTS) { - sdvo->i2c = &dev_priv->gmbus[pin].adapter; - gma_intel_gmbus_set_speed(sdvo->i2c, speed); - gma_intel_gmbus_force_bit(sdvo->i2c, true); - } else - sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; -} - -static bool -psb_intel_sdvo_is_hdmi_connector(struct psb_intel_sdvo *psb_intel_sdvo, int device) -{ - return psb_intel_sdvo_check_supp_encode(psb_intel_sdvo); -} - -static u8 -psb_intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct sdvo_device_mapping *my_mapping, *other_mapping; - - if (IS_SDVOB(sdvo_reg)) { - my_mapping = &dev_priv->sdvo_mappings[0]; - other_mapping = &dev_priv->sdvo_mappings[1]; - } else { - my_mapping = &dev_priv->sdvo_mappings[1]; - other_mapping = &dev_priv->sdvo_mappings[0]; - } - - /* If the BIOS described our SDVO device, take advantage of it. */ - if (my_mapping->slave_addr) - return my_mapping->slave_addr; - - /* If the BIOS only described a different SDVO device, use the - * address that it isn't using. - */ - if (other_mapping->slave_addr) { - if (other_mapping->slave_addr == 0x70) - return 0x72; - else - return 0x70; - } - - /* No SDVO device info is found for another DVO port, - * so use mapping assumption we had before BIOS parsing. - */ - if (IS_SDVOB(sdvo_reg)) - return 0x70; - else - return 0x72; -} - -static void -psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector, - struct psb_intel_sdvo *encoder) -{ - drm_connector_init(encoder->base.base.dev, - &connector->base.base, - &psb_intel_sdvo_connector_funcs, - connector->base.base.connector_type); - - drm_connector_helper_add(&connector->base.base, - &psb_intel_sdvo_connector_helper_funcs); - - connector->base.base.interlace_allowed = 0; - connector->base.base.doublescan_allowed = 0; - connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; - - psb_intel_connector_attach_encoder(&connector->base, &encoder->base); - drm_sysfs_connector_add(&connector->base.base); -} - -static void -psb_intel_sdvo_add_hdmi_properties(struct psb_intel_sdvo_connector *connector) -{ - /* FIXME: We don't support HDMI at the moment - struct drm_device *dev = connector->base.base.dev; - - intel_attach_force_audio_property(&connector->base.base); - if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) - intel_attach_broadcast_rgb_property(&connector->base.base); - */ -} - -static bool -psb_intel_sdvo_dvi_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) -{ - struct drm_encoder *encoder = &psb_intel_sdvo->base.base; - struct drm_connector *connector; - struct psb_intel_connector *intel_connector; - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); - if (!psb_intel_sdvo_connector) - return false; - - if (device == 0) { - psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; - psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; - } else if (device == 1) { - psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; - psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; - } - - intel_connector = &psb_intel_sdvo_connector->base; - connector = &intel_connector->base; - // connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - encoder->encoder_type = DRM_MODE_ENCODER_TMDS; - connector->connector_type = DRM_MODE_CONNECTOR_DVID; - - if (psb_intel_sdvo_is_hdmi_connector(psb_intel_sdvo, device)) { - connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; - psb_intel_sdvo->is_hdmi = true; - } - psb_intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT)); - - psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo); - if (psb_intel_sdvo->is_hdmi) - psb_intel_sdvo_add_hdmi_properties(psb_intel_sdvo_connector); - - return true; -} - -static bool -psb_intel_sdvo_tv_init(struct psb_intel_sdvo *psb_intel_sdvo, int type) -{ - struct drm_encoder *encoder = &psb_intel_sdvo->base.base; - struct drm_connector *connector; - struct psb_intel_connector *intel_connector; - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); - if (!psb_intel_sdvo_connector) - return false; - - intel_connector = &psb_intel_sdvo_connector->base; - connector = &intel_connector->base; - encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; - connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; - - psb_intel_sdvo->controlled_output |= type; - psb_intel_sdvo_connector->output_flag = type; - - psb_intel_sdvo->is_tv = true; - psb_intel_sdvo->base.needs_tv_clock = true; - psb_intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; - - psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo); - - if (!psb_intel_sdvo_tv_create_property(psb_intel_sdvo, psb_intel_sdvo_connector, type)) - goto err; - - if (!psb_intel_sdvo_create_enhance_property(psb_intel_sdvo, psb_intel_sdvo_connector)) - goto err; - - return true; - -err: - psb_intel_sdvo_destroy(connector); - return false; -} - -static bool -psb_intel_sdvo_analog_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) -{ - struct drm_encoder *encoder = &psb_intel_sdvo->base.base; - struct drm_connector *connector; - struct psb_intel_connector *intel_connector; - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); - if (!psb_intel_sdvo_connector) - return false; - - intel_connector = &psb_intel_sdvo_connector->base; - connector = &intel_connector->base; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - encoder->encoder_type = DRM_MODE_ENCODER_DAC; - connector->connector_type = DRM_MODE_CONNECTOR_VGA; - - if (device == 0) { - psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; - psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; - } else if (device == 1) { - psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; - psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; - } - - psb_intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT)); - - psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, - psb_intel_sdvo); - return true; -} - -static bool -psb_intel_sdvo_lvds_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) -{ - struct drm_encoder *encoder = &psb_intel_sdvo->base.base; - struct drm_connector *connector; - struct psb_intel_connector *intel_connector; - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); - if (!psb_intel_sdvo_connector) - return false; - - intel_connector = &psb_intel_sdvo_connector->base; - connector = &intel_connector->base; - encoder->encoder_type = DRM_MODE_ENCODER_LVDS; - connector->connector_type = DRM_MODE_CONNECTOR_LVDS; - - if (device == 0) { - psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; - psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; - } else if (device == 1) { - psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; - psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; - } - - psb_intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | - (1 << INTEL_SDVO_LVDS_CLONE_BIT)); - - psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo); - if (!psb_intel_sdvo_create_enhance_property(psb_intel_sdvo, psb_intel_sdvo_connector)) - goto err; - - return true; - -err: - psb_intel_sdvo_destroy(connector); - return false; -} - -static bool -psb_intel_sdvo_output_setup(struct psb_intel_sdvo *psb_intel_sdvo, uint16_t flags) -{ - psb_intel_sdvo->is_tv = false; - psb_intel_sdvo->base.needs_tv_clock = false; - psb_intel_sdvo->is_lvds = false; - - /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ - - if (flags & SDVO_OUTPUT_TMDS0) - if (!psb_intel_sdvo_dvi_init(psb_intel_sdvo, 0)) - return false; - - if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) - if (!psb_intel_sdvo_dvi_init(psb_intel_sdvo, 1)) - return false; - - /* TV has no XXX1 function block */ - if (flags & SDVO_OUTPUT_SVID0) - if (!psb_intel_sdvo_tv_init(psb_intel_sdvo, SDVO_OUTPUT_SVID0)) - return false; - - if (flags & SDVO_OUTPUT_CVBS0) - if (!psb_intel_sdvo_tv_init(psb_intel_sdvo, SDVO_OUTPUT_CVBS0)) - return false; - - if (flags & SDVO_OUTPUT_RGB0) - if (!psb_intel_sdvo_analog_init(psb_intel_sdvo, 0)) - return false; - - if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) - if (!psb_intel_sdvo_analog_init(psb_intel_sdvo, 1)) - return false; - - if (flags & SDVO_OUTPUT_LVDS0) - if (!psb_intel_sdvo_lvds_init(psb_intel_sdvo, 0)) - return false; - - if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) - if (!psb_intel_sdvo_lvds_init(psb_intel_sdvo, 1)) - return false; - - if ((flags & SDVO_OUTPUT_MASK) == 0) { - unsigned char bytes[2]; - - psb_intel_sdvo->controlled_output = 0; - memcpy(bytes, &psb_intel_sdvo->caps.output_flags, 2); - DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", - SDVO_NAME(psb_intel_sdvo), - bytes[0], bytes[1]); - return false; - } - psb_intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); - - return true; -} - -static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, - int type) -{ - struct drm_device *dev = psb_intel_sdvo->base.base.dev; - struct psb_intel_sdvo_tv_format format; - uint32_t format_map, i; - - if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, type)) - return false; - - BUILD_BUG_ON(sizeof(format) != 6); - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_SUPPORTED_TV_FORMATS, - &format, sizeof(format))) - return false; - - memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); - - if (format_map == 0) - return false; - - psb_intel_sdvo_connector->format_supported_num = 0; - for (i = 0 ; i < TV_FORMAT_NUM; i++) - if (format_map & (1 << i)) - psb_intel_sdvo_connector->tv_format_supported[psb_intel_sdvo_connector->format_supported_num++] = i; - - - psb_intel_sdvo_connector->tv_format = - drm_property_create(dev, DRM_MODE_PROP_ENUM, - "mode", psb_intel_sdvo_connector->format_supported_num); - if (!psb_intel_sdvo_connector->tv_format) - return false; - - for (i = 0; i < psb_intel_sdvo_connector->format_supported_num; i++) - drm_property_add_enum( - psb_intel_sdvo_connector->tv_format, i, - i, tv_format_names[psb_intel_sdvo_connector->tv_format_supported[i]]); - - psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[0]; - drm_connector_attach_property(&psb_intel_sdvo_connector->base.base, - psb_intel_sdvo_connector->tv_format, 0); - return true; - -} - -#define ENHANCEMENT(name, NAME) do { \ - if (enhancements.name) { \ - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ - !psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ - return false; \ - psb_intel_sdvo_connector->max_##name = data_value[0]; \ - psb_intel_sdvo_connector->cur_##name = response; \ - psb_intel_sdvo_connector->name = \ - drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ - if (!psb_intel_sdvo_connector->name) return false; \ - drm_connector_attach_property(connector, \ - psb_intel_sdvo_connector->name, \ - psb_intel_sdvo_connector->cur_##name); \ - DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ - data_value[0], data_value[1], response); \ - } \ -} while(0) - -static bool -psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, - struct psb_intel_sdvo_enhancements_reply enhancements) -{ - struct drm_device *dev = psb_intel_sdvo->base.base.dev; - struct drm_connector *connector = &psb_intel_sdvo_connector->base.base; - uint16_t response, data_value[2]; - - /* when horizontal overscan is supported, Add the left/right property */ - if (enhancements.overscan_h) { - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_MAX_OVERSCAN_H, - &data_value, 4)) - return false; - - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_OVERSCAN_H, - &response, 2)) - return false; - - psb_intel_sdvo_connector->max_hscan = data_value[0]; - psb_intel_sdvo_connector->left_margin = data_value[0] - response; - psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin; - psb_intel_sdvo_connector->left = - drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); - if (!psb_intel_sdvo_connector->left) - return false; - - drm_connector_attach_property(connector, - psb_intel_sdvo_connector->left, - psb_intel_sdvo_connector->left_margin); - - psb_intel_sdvo_connector->right = - drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); - if (!psb_intel_sdvo_connector->right) - return false; - - drm_connector_attach_property(connector, - psb_intel_sdvo_connector->right, - psb_intel_sdvo_connector->right_margin); - DRM_DEBUG_KMS("h_overscan: max %d, " - "default %d, current %d\n", - data_value[0], data_value[1], response); - } - - if (enhancements.overscan_v) { - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_MAX_OVERSCAN_V, - &data_value, 4)) - return false; - - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_OVERSCAN_V, - &response, 2)) - return false; - - psb_intel_sdvo_connector->max_vscan = data_value[0]; - psb_intel_sdvo_connector->top_margin = data_value[0] - response; - psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin; - psb_intel_sdvo_connector->top = - drm_property_create_range(dev, 0, "top_margin", 0, data_value[0]); - if (!psb_intel_sdvo_connector->top) - return false; - - drm_connector_attach_property(connector, - psb_intel_sdvo_connector->top, - psb_intel_sdvo_connector->top_margin); - - psb_intel_sdvo_connector->bottom = - drm_property_create_range(dev, 0, "bottom_margin", 0, data_value[0]); - if (!psb_intel_sdvo_connector->bottom) - return false; - - drm_connector_attach_property(connector, - psb_intel_sdvo_connector->bottom, - psb_intel_sdvo_connector->bottom_margin); - DRM_DEBUG_KMS("v_overscan: max %d, " - "default %d, current %d\n", - data_value[0], data_value[1], response); - } - - ENHANCEMENT(hpos, HPOS); - ENHANCEMENT(vpos, VPOS); - ENHANCEMENT(saturation, SATURATION); - ENHANCEMENT(contrast, CONTRAST); - ENHANCEMENT(hue, HUE); - ENHANCEMENT(sharpness, SHARPNESS); - ENHANCEMENT(brightness, BRIGHTNESS); - ENHANCEMENT(flicker_filter, FLICKER_FILTER); - ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); - ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); - ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); - ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); - - if (enhancements.dot_crawl) { - if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) - return false; - - psb_intel_sdvo_connector->max_dot_crawl = 1; - psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1; - psb_intel_sdvo_connector->dot_crawl = - drm_property_create_range(dev, 0, "dot_crawl", 0, 1); - if (!psb_intel_sdvo_connector->dot_crawl) - return false; - - drm_connector_attach_property(connector, - psb_intel_sdvo_connector->dot_crawl, - psb_intel_sdvo_connector->cur_dot_crawl); - DRM_DEBUG_KMS("dot crawl: current %d\n", response); - } - - return true; -} - -static bool -psb_intel_sdvo_create_enhance_property_lvds(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, - struct psb_intel_sdvo_enhancements_reply enhancements) -{ - struct drm_device *dev = psb_intel_sdvo->base.base.dev; - struct drm_connector *connector = &psb_intel_sdvo_connector->base.base; - uint16_t response, data_value[2]; - - ENHANCEMENT(brightness, BRIGHTNESS); - - return true; -} -#undef ENHANCEMENT - -static bool psb_intel_sdvo_create_enhance_property(struct psb_intel_sdvo *psb_intel_sdvo, - struct psb_intel_sdvo_connector *psb_intel_sdvo_connector) -{ - union { - struct psb_intel_sdvo_enhancements_reply reply; - uint16_t response; - } enhancements; - - BUILD_BUG_ON(sizeof(enhancements) != 2); - - enhancements.response = 0; - psb_intel_sdvo_get_value(psb_intel_sdvo, - SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, - &enhancements, sizeof(enhancements)); - if (enhancements.response == 0) { - DRM_DEBUG_KMS("No enhancement is supported\n"); - return true; - } - - if (IS_TV(psb_intel_sdvo_connector)) - return psb_intel_sdvo_create_enhance_property_tv(psb_intel_sdvo, psb_intel_sdvo_connector, enhancements.reply); - else if(IS_LVDS(psb_intel_sdvo_connector)) - return psb_intel_sdvo_create_enhance_property_lvds(psb_intel_sdvo, psb_intel_sdvo_connector, enhancements.reply); - else - return true; -} - -static int psb_intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - struct psb_intel_sdvo *sdvo = adapter->algo_data; - - if (!psb_intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus)) - return -EIO; - - return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num); -} - -static u32 psb_intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter) -{ - struct psb_intel_sdvo *sdvo = adapter->algo_data; - return sdvo->i2c->algo->functionality(sdvo->i2c); -} - -static const struct i2c_algorithm psb_intel_sdvo_ddc_proxy = { - .master_xfer = psb_intel_sdvo_ddc_proxy_xfer, - .functionality = psb_intel_sdvo_ddc_proxy_func -}; - -static bool -psb_intel_sdvo_init_ddc_proxy(struct psb_intel_sdvo *sdvo, - struct drm_device *dev) -{ - sdvo->ddc.owner = THIS_MODULE; - sdvo->ddc.class = I2C_CLASS_DDC; - snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy"); - sdvo->ddc.dev.parent = &dev->pdev->dev; - sdvo->ddc.algo_data = sdvo; - sdvo->ddc.algo = &psb_intel_sdvo_ddc_proxy; - - return i2c_add_adapter(&sdvo->ddc) == 0; -} - -bool psb_intel_sdvo_init(struct drm_device *dev, int sdvo_reg) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_encoder *psb_intel_encoder; - struct psb_intel_sdvo *psb_intel_sdvo; - int i; - - psb_intel_sdvo = kzalloc(sizeof(struct psb_intel_sdvo), GFP_KERNEL); - if (!psb_intel_sdvo) - return false; - - psb_intel_sdvo->sdvo_reg = sdvo_reg; - psb_intel_sdvo->slave_addr = psb_intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1; - psb_intel_sdvo_select_i2c_bus(dev_priv, psb_intel_sdvo, sdvo_reg); - if (!psb_intel_sdvo_init_ddc_proxy(psb_intel_sdvo, dev)) { - kfree(psb_intel_sdvo); - return false; - } - - /* encoder type will be decided later */ - psb_intel_encoder = &psb_intel_sdvo->base; - psb_intel_encoder->type = INTEL_OUTPUT_SDVO; - drm_encoder_init(dev, &psb_intel_encoder->base, &psb_intel_sdvo_enc_funcs, 0); - - /* Read the regs to test if we can talk to the device */ - for (i = 0; i < 0x40; i++) { - u8 byte; - - if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, i, &byte)) { - DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", - IS_SDVOB(sdvo_reg) ? 'B' : 'C'); - goto err; - } - } - - if (IS_SDVOB(sdvo_reg)) - dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; - else - dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; - - drm_encoder_helper_add(&psb_intel_encoder->base, &psb_intel_sdvo_helper_funcs); - - /* In default case sdvo lvds is false */ - if (!psb_intel_sdvo_get_capabilities(psb_intel_sdvo, &psb_intel_sdvo->caps)) - goto err; - - if (psb_intel_sdvo_output_setup(psb_intel_sdvo, - psb_intel_sdvo->caps.output_flags) != true) { - DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", - IS_SDVOB(sdvo_reg) ? 'B' : 'C'); - goto err; - } - - psb_intel_sdvo_select_ddc_bus(dev_priv, psb_intel_sdvo, sdvo_reg); - - /* Set the input timing to the screen. Assume always input 0. */ - if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo)) - goto err; - - if (!psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_sdvo, - &psb_intel_sdvo->pixel_clock_min, - &psb_intel_sdvo->pixel_clock_max)) - goto err; - - DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " - "clock range %dMHz - %dMHz, " - "input 1: %c, input 2: %c, " - "output 1: %c, output 2: %c\n", - SDVO_NAME(psb_intel_sdvo), - psb_intel_sdvo->caps.vendor_id, psb_intel_sdvo->caps.device_id, - psb_intel_sdvo->caps.device_rev_id, - psb_intel_sdvo->pixel_clock_min / 1000, - psb_intel_sdvo->pixel_clock_max / 1000, - (psb_intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', - (psb_intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', - /* check currently supported outputs */ - psb_intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', - psb_intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); - return true; - -err: - drm_encoder_cleanup(&psb_intel_encoder->base); - i2c_del_adapter(&psb_intel_sdvo->ddc); - kfree(psb_intel_sdvo); - - return false; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h deleted file mode 100644 index 600e7974..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright ? 2006-2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ - -/** - * @file SDVO command definitions and structures. - */ - -#define SDVO_OUTPUT_FIRST (0) -#define SDVO_OUTPUT_TMDS0 (1 << 0) -#define SDVO_OUTPUT_RGB0 (1 << 1) -#define SDVO_OUTPUT_CVBS0 (1 << 2) -#define SDVO_OUTPUT_SVID0 (1 << 3) -#define SDVO_OUTPUT_YPRPB0 (1 << 4) -#define SDVO_OUTPUT_SCART0 (1 << 5) -#define SDVO_OUTPUT_LVDS0 (1 << 6) -#define SDVO_OUTPUT_TMDS1 (1 << 8) -#define SDVO_OUTPUT_RGB1 (1 << 9) -#define SDVO_OUTPUT_CVBS1 (1 << 10) -#define SDVO_OUTPUT_SVID1 (1 << 11) -#define SDVO_OUTPUT_YPRPB1 (1 << 12) -#define SDVO_OUTPUT_SCART1 (1 << 13) -#define SDVO_OUTPUT_LVDS1 (1 << 14) -#define SDVO_OUTPUT_LAST (14) - -struct psb_intel_sdvo_caps { - u8 vendor_id; - u8 device_id; - u8 device_rev_id; - u8 sdvo_version_major; - u8 sdvo_version_minor; - unsigned int sdvo_inputs_mask:2; - unsigned int smooth_scaling:1; - unsigned int sharp_scaling:1; - unsigned int up_scaling:1; - unsigned int down_scaling:1; - unsigned int stall_support:1; - unsigned int pad:1; - u16 output_flags; -} __attribute__((packed)); - -/** This matches the EDID DTD structure, more or less */ -struct psb_intel_sdvo_dtd { - struct { - u16 clock; /**< pixel clock, in 10kHz units */ - u8 h_active; /**< lower 8 bits (pixels) */ - u8 h_blank; /**< lower 8 bits (pixels) */ - u8 h_high; /**< upper 4 bits each h_active, h_blank */ - u8 v_active; /**< lower 8 bits (lines) */ - u8 v_blank; /**< lower 8 bits (lines) */ - u8 v_high; /**< upper 4 bits each v_active, v_blank */ - } part1; - - struct { - u8 h_sync_off; /**< lower 8 bits, from hblank start */ - u8 h_sync_width; /**< lower 8 bits (pixels) */ - /** lower 4 bits each vsync offset, vsync width */ - u8 v_sync_off_width; - /** - * 2 high bits of hsync offset, 2 high bits of hsync width, - * bits 4-5 of vsync offset, and 2 high bits of vsync width. - */ - u8 sync_off_width_high; - u8 dtd_flags; - u8 sdvo_flags; - /** bits 6-7 of vsync offset at bits 6-7 */ - u8 v_sync_off_high; - u8 reserved; - } part2; -} __attribute__((packed)); - -struct psb_intel_sdvo_pixel_clock_range { - u16 min; /**< pixel clock, in 10kHz units */ - u16 max; /**< pixel clock, in 10kHz units */ -} __attribute__((packed)); - -struct psb_intel_sdvo_preferred_input_timing_args { - u16 clock; - u16 width; - u16 height; - u8 interlace:1; - u8 scaled:1; - u8 pad:6; -} __attribute__((packed)); - -/* I2C registers for SDVO */ -#define SDVO_I2C_ARG_0 0x07 -#define SDVO_I2C_ARG_1 0x06 -#define SDVO_I2C_ARG_2 0x05 -#define SDVO_I2C_ARG_3 0x04 -#define SDVO_I2C_ARG_4 0x03 -#define SDVO_I2C_ARG_5 0x02 -#define SDVO_I2C_ARG_6 0x01 -#define SDVO_I2C_ARG_7 0x00 -#define SDVO_I2C_OPCODE 0x08 -#define SDVO_I2C_CMD_STATUS 0x09 -#define SDVO_I2C_RETURN_0 0x0a -#define SDVO_I2C_RETURN_1 0x0b -#define SDVO_I2C_RETURN_2 0x0c -#define SDVO_I2C_RETURN_3 0x0d -#define SDVO_I2C_RETURN_4 0x0e -#define SDVO_I2C_RETURN_5 0x0f -#define SDVO_I2C_RETURN_6 0x10 -#define SDVO_I2C_RETURN_7 0x11 -#define SDVO_I2C_VENDOR_BEGIN 0x20 - -/* Status results */ -#define SDVO_CMD_STATUS_POWER_ON 0x0 -#define SDVO_CMD_STATUS_SUCCESS 0x1 -#define SDVO_CMD_STATUS_NOTSUPP 0x2 -#define SDVO_CMD_STATUS_INVALID_ARG 0x3 -#define SDVO_CMD_STATUS_PENDING 0x4 -#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5 -#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6 - -/* SDVO commands, argument/result registers */ - -#define SDVO_CMD_RESET 0x01 - -/** Returns a struct intel_sdvo_caps */ -#define SDVO_CMD_GET_DEVICE_CAPS 0x02 - -#define SDVO_CMD_GET_FIRMWARE_REV 0x86 -# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0 -# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1 -# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2 - -/** - * Reports which inputs are trained (managed to sync). - * - * Devices must have trained within 2 vsyncs of a mode change. - */ -#define SDVO_CMD_GET_TRAINED_INPUTS 0x03 -struct psb_intel_sdvo_get_trained_inputs_response { - unsigned int input0_trained:1; - unsigned int input1_trained:1; - unsigned int pad:6; -} __attribute__((packed)); - -/** Returns a struct intel_sdvo_output_flags of active outputs. */ -#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 - -/** - * Sets the current set of active outputs. - * - * Takes a struct intel_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP - * on multi-output devices. - */ -#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 - -/** - * Returns the current mapping of SDVO inputs to outputs on the device. - * - * Returns two struct intel_sdvo_output_flags structures. - */ -#define SDVO_CMD_GET_IN_OUT_MAP 0x06 -struct psb_intel_sdvo_in_out_map { - u16 in0, in1; -}; - -/** - * Sets the current mapping of SDVO inputs to outputs on the device. - * - * Takes two struct i380_sdvo_output_flags structures. - */ -#define SDVO_CMD_SET_IN_OUT_MAP 0x07 - -/** - * Returns a struct intel_sdvo_output_flags of attached displays. - */ -#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b - -/** - * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging. - */ -#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c - -/** - * Takes a struct intel_sdvo_output_flags. - */ -#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d - -/** - * Returns a struct intel_sdvo_output_flags of displays with hot plug - * interrupts enabled. - */ -#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e - -#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f -struct intel_sdvo_get_interrupt_event_source_response { - u16 interrupt_status; - unsigned int ambient_light_interrupt:1; - unsigned int hdmi_audio_encrypt_change:1; - unsigned int pad:6; -} __attribute__((packed)); - -/** - * Selects which input is affected by future input commands. - * - * Commands affected include SET_INPUT_TIMINGS_PART[12], - * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12], - * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS. - */ -#define SDVO_CMD_SET_TARGET_INPUT 0x10 -struct psb_intel_sdvo_set_target_input_args { - unsigned int target_1:1; - unsigned int pad:7; -} __attribute__((packed)); - -/** - * Takes a struct intel_sdvo_output_flags of which outputs are targeted by - * future output commands. - * - * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], - * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE. - */ -#define SDVO_CMD_SET_TARGET_OUTPUT 0x11 - -#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12 -#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19 -/* Part 1 */ -# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2 -# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3 -# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4 -# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5 -# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6 -# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7 -/* Part 2 */ -# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0 -# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1 -# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2 -# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4 -# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7) -# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5) -# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3) -# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1) -# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5 -# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7) -# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6) -# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6) -# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4) -# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6 - -/** - * Generates a DTD based on the given width, height, and flags. - * - * This will be supported by any device supporting scaling or interlaced - * modes. - */ -#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0) -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1) - -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c - -/** Returns a struct intel_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d -/** Returns a struct intel_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e - -/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ -#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f - -/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20 -/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21 -# define SDVO_CLOCK_RATE_MULT_1X (1 << 0) -# define SDVO_CLOCK_RATE_MULT_2X (1 << 1) -# define SDVO_CLOCK_RATE_MULT_4X (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 -/** 6 bytes of bit flags for TV formats shared by all TV format functions */ -struct psb_intel_sdvo_tv_format { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:3; -} __attribute__((packed)); - -#define SDVO_CMD_GET_TV_FORMAT 0x28 - -#define SDVO_CMD_SET_TV_FORMAT 0x29 - -/** Returns the resolutiosn that can be used with the given TV format */ -#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 -struct psb_intel_sdvo_sdtv_resolution_request { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int pad:5; -} __attribute__((packed)); - -struct psb_intel_sdvo_sdtv_resolution_reply { - unsigned int res_320x200:1; - unsigned int res_320x240:1; - unsigned int res_400x300:1; - unsigned int res_640x350:1; - unsigned int res_640x400:1; - unsigned int res_640x480:1; - unsigned int res_704x480:1; - unsigned int res_704x576:1; - - unsigned int res_720x350:1; - unsigned int res_720x400:1; - unsigned int res_720x480:1; - unsigned int res_720x540:1; - unsigned int res_720x576:1; - unsigned int res_768x576:1; - unsigned int res_800x600:1; - unsigned int res_832x624:1; - - unsigned int res_920x766:1; - unsigned int res_1024x768:1; - unsigned int res_1280x1024:1; - unsigned int pad:5; -} __attribute__((packed)); - -/* Get supported resolution with squire pixel aspect ratio that can be - scaled for the requested HDTV format */ -#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85 - -struct psb_intel_sdvo_hdtv_resolution_request { - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:6; -} __attribute__((packed)); - -struct psb_intel_sdvo_hdtv_resolution_reply { - unsigned int res_640x480:1; - unsigned int res_800x600:1; - unsigned int res_1024x768:1; - unsigned int res_1280x960:1; - unsigned int res_1400x1050:1; - unsigned int res_1600x1200:1; - unsigned int res_1920x1440:1; - unsigned int res_2048x1536:1; - - unsigned int res_2560x1920:1; - unsigned int res_3200x2400:1; - unsigned int res_3840x2880:1; - unsigned int pad1:5; - - unsigned int res_848x480:1; - unsigned int res_1064x600:1; - unsigned int res_1280x720:1; - unsigned int res_1360x768:1; - unsigned int res_1704x960:1; - unsigned int res_1864x1050:1; - unsigned int res_1920x1080:1; - unsigned int res_2128x1200:1; - - unsigned int res_2560x1400:1; - unsigned int res_2728x1536:1; - unsigned int res_3408x1920:1; - unsigned int res_4264x2400:1; - unsigned int res_5120x2880:1; - unsigned int pad2:3; - - unsigned int res_768x480:1; - unsigned int res_960x600:1; - unsigned int res_1152x720:1; - unsigned int res_1124x768:1; - unsigned int res_1536x960:1; - unsigned int res_1680x1050:1; - unsigned int res_1728x1080:1; - unsigned int res_1920x1200:1; - - unsigned int res_2304x1440:1; - unsigned int res_2456x1536:1; - unsigned int res_3072x1920:1; - unsigned int res_3840x2400:1; - unsigned int res_4608x2880:1; - unsigned int pad3:3; - - unsigned int res_1280x1024:1; - unsigned int pad4:7; - - unsigned int res_1280x768:1; - unsigned int pad5:7; -} __attribute__((packed)); - -/* Get supported power state returns info for encoder and monitor, rely on - last SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a -/* Get power state returns info for encoder and monitor, rely on last - SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_POWER_STATE 0x2b -#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b -#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c -# define SDVO_ENCODER_STATE_ON (1 << 0) -# define SDVO_ENCODER_STATE_STANDBY (1 << 1) -# define SDVO_ENCODER_STATE_SUSPEND (1 << 2) -# define SDVO_ENCODER_STATE_OFF (1 << 3) -# define SDVO_MONITOR_STATE_ON (1 << 4) -# define SDVO_MONITOR_STATE_STANDBY (1 << 5) -# define SDVO_MONITOR_STATE_SUSPEND (1 << 6) -# define SDVO_MONITOR_STATE_OFF (1 << 7) - -#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d -#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e -#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f -/** - * The panel power sequencing parameters are in units of milliseconds. - * The high fields are bits 8:9 of the 10-bit values. - */ -struct psb_sdvo_panel_power_sequencing { - u8 t0; - u8 t1; - u8 t2; - u8 t3; - u8 t4; - - unsigned int t0_high:2; - unsigned int t1_high:2; - unsigned int t2_high:2; - unsigned int t3_high:2; - - unsigned int t4_high:2; - unsigned int pad:6; -} __attribute__((packed)); - -#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30 -struct sdvo_max_backlight_reply { - u8 max_value; - u8 default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31 -#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32 - -#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33 -struct sdvo_get_ambient_light_reply { - u16 trip_low; - u16 trip_high; - u16 value; -} __attribute__((packed)); -#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34 -struct sdvo_set_ambient_light_reply { - u16 trip_low; - u16 trip_high; - unsigned int enable:1; - unsigned int pad:7; -} __attribute__((packed)); - -/* Set display power state */ -#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d -# define SDVO_DISPLAY_STATE_ON (1 << 0) -# define SDVO_DISPLAY_STATE_STANDBY (1 << 1) -# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2) -# define SDVO_DISPLAY_STATE_OFF (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 -struct psb_intel_sdvo_enhancements_reply { - unsigned int flicker_filter:1; - unsigned int flicker_filter_adaptive:1; - unsigned int flicker_filter_2d:1; - unsigned int saturation:1; - unsigned int hue:1; - unsigned int brightness:1; - unsigned int contrast:1; - unsigned int overscan_h:1; - - unsigned int overscan_v:1; - unsigned int hpos:1; - unsigned int vpos:1; - unsigned int sharpness:1; - unsigned int dot_crawl:1; - unsigned int dither:1; - unsigned int tv_chroma_filter:1; - unsigned int tv_luma_filter:1; -} __attribute__((packed)); - -/* Picture enhancement limits below are dependent on the current TV format, - * and thus need to be queried and set after it. - */ -#define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d -#define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b -#define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 -#define SDVO_CMD_GET_MAX_SATURATION 0x55 -#define SDVO_CMD_GET_MAX_HUE 0x58 -#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b -#define SDVO_CMD_GET_MAX_CONTRAST 0x5e -#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 -#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 -#define SDVO_CMD_GET_MAX_HPOS 0x67 -#define SDVO_CMD_GET_MAX_VPOS 0x6a -#define SDVO_CMD_GET_MAX_SHARPNESS 0x6d -#define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 -#define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 -struct psb_intel_sdvo_enhancement_limits_reply { - u16 max_value; - u16 default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f -#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80 -# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0) -# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0) -# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2) -# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2) -# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4) -# define SDVO_LVDS_DUAL_CHANNEL (1 << 4) - -#define SDVO_CMD_GET_FLICKER_FILTER 0x4e -#define SDVO_CMD_SET_FLICKER_FILTER 0x4f -#define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 -#define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 -#define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 -#define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 -#define SDVO_CMD_GET_SATURATION 0x56 -#define SDVO_CMD_SET_SATURATION 0x57 -#define SDVO_CMD_GET_HUE 0x59 -#define SDVO_CMD_SET_HUE 0x5a -#define SDVO_CMD_GET_BRIGHTNESS 0x5c -#define SDVO_CMD_SET_BRIGHTNESS 0x5d -#define SDVO_CMD_GET_CONTRAST 0x5f -#define SDVO_CMD_SET_CONTRAST 0x60 -#define SDVO_CMD_GET_OVERSCAN_H 0x62 -#define SDVO_CMD_SET_OVERSCAN_H 0x63 -#define SDVO_CMD_GET_OVERSCAN_V 0x65 -#define SDVO_CMD_SET_OVERSCAN_V 0x66 -#define SDVO_CMD_GET_HPOS 0x68 -#define SDVO_CMD_SET_HPOS 0x69 -#define SDVO_CMD_GET_VPOS 0x6b -#define SDVO_CMD_SET_VPOS 0x6c -#define SDVO_CMD_GET_SHARPNESS 0x6e -#define SDVO_CMD_SET_SHARPNESS 0x6f -#define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 -#define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 -#define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 -#define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 -struct psb_intel_sdvo_enhancements_arg { - u16 value; -}__attribute__((packed)); - -#define SDVO_CMD_GET_DOT_CRAWL 0x70 -#define SDVO_CMD_SET_DOT_CRAWL 0x71 -# define SDVO_DOT_CRAWL_ON (1 << 0) -# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_GET_DITHER 0x72 -#define SDVO_CMD_SET_DITHER 0x73 -# define SDVO_DITHER_ON (1 << 0) -# define SDVO_DITHER_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a -# define SDVO_CONTROL_BUS_PROM (1 << 0) -# define SDVO_CONTROL_BUS_DDC1 (1 << 1) -# define SDVO_CONTROL_BUS_DDC2 (1 << 2) -# define SDVO_CONTROL_BUS_DDC3 (1 << 3) - -/* HDMI op codes */ -#define SDVO_CMD_GET_SUPP_ENCODE 0x9d -#define SDVO_CMD_GET_ENCODE 0x9e -#define SDVO_CMD_SET_ENCODE 0x9f - #define SDVO_ENCODE_DVI 0x0 - #define SDVO_ENCODE_HDMI 0x1 -#define SDVO_CMD_SET_PIXEL_REPLI 0x8b -#define SDVO_CMD_GET_PIXEL_REPLI 0x8c -#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d -#define SDVO_CMD_SET_COLORIMETRY 0x8e - #define SDVO_COLORIMETRY_RGB256 0x0 - #define SDVO_COLORIMETRY_RGB220 0x1 - #define SDVO_COLORIMETRY_YCrCb422 0x3 - #define SDVO_COLORIMETRY_YCrCb444 0x4 -#define SDVO_CMD_GET_COLORIMETRY 0x8f -#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 -#define SDVO_CMD_SET_AUDIO_STAT 0x91 -#define SDVO_CMD_GET_AUDIO_STAT 0x92 -#define SDVO_CMD_SET_HBUF_INDEX 0x93 -#define SDVO_CMD_GET_HBUF_INDEX 0x94 -#define SDVO_CMD_GET_HBUF_INFO 0x95 -#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 -#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 -#define SDVO_CMD_SET_HBUF_DATA 0x98 -#define SDVO_CMD_GET_HBUF_DATA 0x99 -#define SDVO_CMD_SET_HBUF_TXRATE 0x9a -#define SDVO_CMD_GET_HBUF_TXRATE 0x9b - #define SDVO_HBUF_TX_DISABLED (0 << 6) - #define SDVO_HBUF_TX_ONCE (2 << 6) - #define SDVO_HBUF_TX_VSYNC (3 << 6) -#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c -#define SDVO_NEED_TO_STALL (1 << 7) - -struct psb_intel_sdvo_encode { - u8 dvi_rev; - u8 hdmi_rev; -} __attribute__ ((packed)); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.c deleted file mode 100644 index 18695864..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.c +++ /dev/null @@ -1,622 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - * develop this driver. - * - **************************************************************************/ -/* - */ - -#include -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include "power.h" -#include "psb_irq.h" -#include "mdfld_output.h" - -/* - * inline functions - */ - -static inline u32 -psb_pipestat(int pipe) -{ - if (pipe == 0) - return PIPEASTAT; - if (pipe == 1) - return PIPEBSTAT; - if (pipe == 2) - return PIPECSTAT; - BUG(); -} - -static inline u32 -mid_pipe_event(int pipe) -{ - if (pipe == 0) - return _PSB_PIPEA_EVENT_FLAG; - if (pipe == 1) - return _MDFLD_PIPEB_EVENT_FLAG; - if (pipe == 2) - return _MDFLD_PIPEC_EVENT_FLAG; - BUG(); -} - -static inline u32 -mid_pipe_vsync(int pipe) -{ - if (pipe == 0) - return _PSB_VSYNC_PIPEA_FLAG; - if (pipe == 1) - return _PSB_VSYNC_PIPEB_FLAG; - if (pipe == 2) - return _MDFLD_PIPEC_VBLANK_FLAG; - BUG(); -} - -static inline u32 -mid_pipeconf(int pipe) -{ - if (pipe == 0) - return PIPEACONF; - if (pipe == 1) - return PIPEBCONF; - if (pipe == 2) - return PIPECCONF; - BUG(); -} - -void -psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) -{ - if ((dev_priv->pipestat[pipe] & mask) != mask) { - u32 reg = psb_pipestat(pipe); - dev_priv->pipestat[pipe] |= mask; - /* Enable the interrupt, clear any pending status */ - if (gma_power_begin(dev_priv->dev, false)) { - u32 writeVal = PSB_RVDC32(reg); - writeVal |= (mask | (mask >> 16)); - PSB_WVDC32(writeVal, reg); - (void) PSB_RVDC32(reg); - gma_power_end(dev_priv->dev); - } - } -} - -void -psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) -{ - if ((dev_priv->pipestat[pipe] & mask) != 0) { - u32 reg = psb_pipestat(pipe); - dev_priv->pipestat[pipe] &= ~mask; - if (gma_power_begin(dev_priv->dev, false)) { - u32 writeVal = PSB_RVDC32(reg); - writeVal &= ~mask; - PSB_WVDC32(writeVal, reg); - (void) PSB_RVDC32(reg); - gma_power_end(dev_priv->dev); - } - } -} - -static void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe) -{ - if (gma_power_begin(dev_priv->dev, false)) { - u32 pipe_event = mid_pipe_event(pipe); - dev_priv->vdc_irq_mask |= pipe_event; - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - gma_power_end(dev_priv->dev); - } -} - -static void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) -{ - if (dev_priv->pipestat[pipe] == 0) { - if (gma_power_begin(dev_priv->dev, false)) { - u32 pipe_event = mid_pipe_event(pipe); - dev_priv->vdc_irq_mask &= ~pipe_event; - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - gma_power_end(dev_priv->dev); - } - } -} - -/** - * Display controller interrupt handler for pipe event. - * - */ -static void mid_pipe_event_handler(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - uint32_t pipe_stat_val = 0; - uint32_t pipe_stat_reg = psb_pipestat(pipe); - uint32_t pipe_enable = dev_priv->pipestat[pipe]; - uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; - uint32_t pipe_clear; - uint32_t i = 0; - - spin_lock(&dev_priv->irqmask_lock); - - pipe_stat_val = PSB_RVDC32(pipe_stat_reg); - pipe_stat_val &= pipe_enable | pipe_status; - pipe_stat_val &= pipe_stat_val >> 16; - - spin_unlock(&dev_priv->irqmask_lock); - - /* Clear the 2nd level interrupt status bits - * Sometimes the bits are very sticky so we repeat until they unstick */ - for (i = 0; i < 0xffff; i++) { - PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); - pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status; - - if (pipe_clear == 0) - break; - } - - if (pipe_clear) - dev_err(dev->dev, - "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", - __func__, pipe, PSB_RVDC32(pipe_stat_reg)); - - if (pipe_stat_val & PIPE_VBLANK_STATUS) - drm_handle_vblank(dev, pipe); - - if (pipe_stat_val & PIPE_TE_STATUS) - drm_handle_vblank(dev, pipe); -} - -/* - * Display controller interrupt handler. - */ -static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) -{ - if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) - mid_pipe_event_handler(dev, 0); - - if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG) - mid_pipe_event_handler(dev, 1); -} - -irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - - uint32_t vdc_stat, dsp_int = 0, sgx_int = 0; - int handled = 0; - - spin_lock(&dev_priv->irqmask_lock); - - vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); - - if (vdc_stat & _PSB_PIPE_EVENT_FLAG) - dsp_int = 1; - - /* FIXME: Handle Medfield - if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) - dsp_int = 1; - */ - - if (vdc_stat & _PSB_IRQ_SGX_FLAG) - sgx_int = 1; - - vdc_stat &= dev_priv->vdc_irq_mask; - spin_unlock(&dev_priv->irqmask_lock); - - if (dsp_int && gma_power_is_on(dev)) { - psb_vdc_interrupt(dev, vdc_stat); - handled = 1; - } - - if (sgx_int) { - /* Not expected - we have it masked, shut it up */ - u32 s, s2; - s = PSB_RSGX32(PSB_CR_EVENT_STATUS); - s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); - PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR); - PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2); - /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but - we may as well poll even if we add that ! */ - handled = 1; - } - - PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); - (void) PSB_RVDC32(PSB_INT_IDENTITY_R); - DRM_READMEMORYBARRIER(); - - if (!handled) - return IRQ_NONE; - - return IRQ_HANDLED; -} - -void psb_irq_preinstall(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - if (gma_power_is_on(dev)) - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (dev->vblank_enabled[0]) - dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; - if (dev->vblank_enabled[1]) - dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; - - /* FIXME: Handle Medfield irq mask - if (dev->vblank_enabled[1]) - dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; - if (dev->vblank_enabled[2]) - dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; - */ - - /* This register is safe even if display island is off */ - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -int psb_irq_postinstall(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - /* This register is safe even if display island is off */ - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - - if (dev->vblank_enabled[0]) - psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[1]) - psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[2]) - psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - return 0; -} - -void psb_irq_uninstall(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - - if (dev->vblank_enabled[0]) - psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[1]) - psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank_enabled[2]) - psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - - dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | - _PSB_IRQ_MSVDX_FLAG | - _LNC_IRQ_TOPAZ_FLAG; - - /* These two registers are safe even if display island is off */ - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - - wmb(); - - /* This register is safe even if display island is off */ - PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -void psb_irq_turn_on_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - u32 hist_reg; - u32 pwm_reg; - - if (gma_power_begin(dev, false)) { - PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); - PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); - - PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE - | PWM_PHASEIN_INT_ENABLE, - PWM_CONTROL_LOGIC); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - - psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); - - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); - PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR, - HISTOGRAM_INT_CONTROL); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, - PWM_CONTROL_LOGIC); - - gma_power_end(dev); - } -} - -int psb_irq_enable_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - /* enable DPST */ - mid_enable_pipe_event(dev_priv, 0); - psb_irq_turn_on_dpst(dev); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - return 0; -} - -void psb_irq_turn_off_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - u32 hist_reg; - u32 pwm_reg; - - if (gma_power_begin(dev, false)) { - PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); - - psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); - - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), - PWM_CONTROL_LOGIC); - pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - - gma_power_end(dev); - } -} - -int psb_irq_disable_dpst(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - mid_disable_pipe_event(dev_priv, 0); - psb_irq_turn_off_dpst(dev); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - - return 0; -} - -#ifdef PSB_FIXME -static int psb_vblank_do_wait(struct drm_device *dev, - unsigned int *sequence, atomic_t *counter) -{ - unsigned int cur_vblank; - int ret = 0; - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(counter)) - - *sequence) <= (1 << 23))); - *sequence = cur_vblank; - - return ret; -} -#endif - -/* - * It is used to enable VBLANK interrupt - */ -int psb_enable_vblank(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long irqflags; - uint32_t reg_val = 0; - uint32_t pipeconf_reg = mid_pipeconf(pipe); - - /* Medfield is different - we should perhaps extract out vblank - and blacklight etc ops */ - if (IS_MFLD(dev)) - return mdfld_enable_te(dev, pipe); - - if (gma_power_begin(dev, false)) { - reg_val = REG_READ(pipeconf_reg); - gma_power_end(dev); - } - - if (!(reg_val & PIPEACONF_ENABLE)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - if (pipe == 0) - dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; - else if (pipe == 1) - dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; - - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - - return 0; -} - -/* - * It is used to disable VBLANK interrupt - */ -void psb_disable_vblank(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long irqflags; - - if (IS_MFLD(dev)) - mdfld_disable_te(dev, pipe); - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - if (pipe == 0) - dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG; - else if (pipe == 1) - dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG; - - PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); - PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); - psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -/* - * It is used to enable TE interrupt - */ -int mdfld_enable_te(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - uint32_t reg_val = 0; - uint32_t pipeconf_reg = mid_pipeconf(pipe); - - if (gma_power_begin(dev, false)) { - reg_val = REG_READ(pipeconf_reg); - gma_power_end(dev); - } - - if (!(reg_val & PIPEACONF_ENABLE)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - mid_enable_pipe_event(dev_priv, pipe); - psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - - return 0; -} - -/* - * It is used to disable TE interrupt - */ -void mdfld_disable_te(struct drm_device *dev, int pipe) -{ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - unsigned long irqflags; - - if (!dev_priv->dsr_enable) - return; - - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - - mid_disable_pipe_event(dev_priv, pipe); - psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); - - spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); -} - -/* Called from drm generic code, passed a 'crtc', which - * we use as a pipe index - */ -u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) -{ - uint32_t high_frame = PIPEAFRAMEHIGH; - uint32_t low_frame = PIPEAFRAMEPIXEL; - uint32_t pipeconf_reg = PIPEACONF; - uint32_t reg_val = 0; - uint32_t high1 = 0, high2 = 0, low = 0, count = 0; - - switch (pipe) { - case 0: - break; - case 1: - high_frame = PIPEBFRAMEHIGH; - low_frame = PIPEBFRAMEPIXEL; - pipeconf_reg = PIPEBCONF; - break; - case 2: - high_frame = PIPECFRAMEHIGH; - low_frame = PIPECFRAMEPIXEL; - pipeconf_reg = PIPECCONF; - break; - default: - dev_err(dev->dev, "%s, invalid pipe.\n", __func__); - return 0; - } - - if (!gma_power_begin(dev, false)) - return 0; - - reg_val = REG_READ(pipeconf_reg); - - if (!(reg_val & PIPEACONF_ENABLE)) { - dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n", - pipe); - goto psb_get_vblank_counter_exit; - } - - /* - * High & low register fields aren't synchronized, so make sure - * we get a low value that's stable across two reads of the high - * register. - */ - do { - high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - low = ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> - PIPE_FRAME_LOW_SHIFT); - high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> - PIPE_FRAME_HIGH_SHIFT); - } while (high1 != high2); - - count = (high1 << 8) | low; - -psb_get_vblank_counter_exit: - - gma_power_end(dev); - - return count; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.h deleted file mode 100644 index 603045be..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_irq.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009-2011, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: - * Benjamin Defnet - * Rajesh Poornachandran - * - **************************************************************************/ - -#ifndef _SYSIRQ_H_ -#define _SYSIRQ_H_ - -#include - -bool sysirq_init(struct drm_device *dev); -void sysirq_uninit(struct drm_device *dev); - -void psb_irq_preinstall(struct drm_device *dev); -int psb_irq_postinstall(struct drm_device *dev); -void psb_irq_uninstall(struct drm_device *dev); -irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); - -int psb_irq_enable_dpst(struct drm_device *dev); -int psb_irq_disable_dpst(struct drm_device *dev); -void psb_irq_turn_on_dpst(struct drm_device *dev); -void psb_irq_turn_off_dpst(struct drm_device *dev); -int psb_enable_vblank(struct drm_device *dev, int pipe); -void psb_disable_vblank(struct drm_device *dev, int pipe); -u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); - -int mdfld_enable_te(struct drm_device *dev, int pipe); -void mdfld_disable_te(struct drm_device *dev, int pipe); -#endif /* _SYSIRQ_H_ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_lid.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_lid.c deleted file mode 100644 index b867aabe..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_lid.c +++ /dev/null @@ -1,88 +0,0 @@ -/************************************************************************** - * Copyright (c) 2007, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Thomas Hellstrom - **************************************************************************/ - -#include -#include "psb_drv.h" -#include "psb_reg.h" -#include "psb_intel_reg.h" -#include - -static void psb_lid_timer_func(unsigned long data) -{ - struct drm_psb_private * dev_priv = (struct drm_psb_private *)data; - struct drm_device *dev = (struct drm_device *)dev_priv->dev; - struct timer_list *lid_timer = &dev_priv->lid_timer; - unsigned long irq_flags; - u32 *lid_state = dev_priv->lid_state; - u32 pp_status; - - if (readl(lid_state) == dev_priv->lid_last_state) - goto lid_timer_schedule; - - if ((readl(lid_state)) & 0x01) { - /*lid state is open*/ - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - - /*FIXME: should be backlight level before*/ - psb_intel_lvds_set_brightness(dev, 100); - } else { - psb_intel_lvds_set_brightness(dev, 0); - - REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); - do { - pp_status = REG_READ(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - } - dev_priv->lid_last_state = readl(lid_state); - -lid_timer_schedule: - spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); - if (!timer_pending(lid_timer)) { - lid_timer->expires = jiffies + PSB_LID_DELAY; - add_timer(lid_timer); - } - spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); -} - -void psb_lid_timer_init(struct drm_psb_private *dev_priv) -{ - struct timer_list *lid_timer = &dev_priv->lid_timer; - unsigned long irq_flags; - - spin_lock_init(&dev_priv->lid_lock); - spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); - - init_timer(lid_timer); - - lid_timer->data = (unsigned long)dev_priv; - lid_timer->function = psb_lid_timer_func; - lid_timer->expires = jiffies + PSB_LID_DELAY; - - add_timer(lid_timer); - spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); -} - -void psb_lid_timer_takedown(struct drm_psb_private *dev_priv) -{ - del_timer_sync(&dev_priv->lid_timer); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_reg.h deleted file mode 100644 index b81c7c1e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/psb_reg.h +++ /dev/null @@ -1,582 +0,0 @@ -/************************************************************************** - * - * Copyright (c) (2005-2007) Imagination Technologies Limited. - * Copyright (c) 2007, Intel Corporation. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.. - * - **************************************************************************/ - -#ifndef _PSB_REG_H_ -#define _PSB_REG_H_ - -#define PSB_CR_CLKGATECTL 0x0000 -#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24) -#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20) -#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20) -#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16) -#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16) -#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12) -#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12) -#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8) -#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8) -#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4) -#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4) -#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0) -#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0) -#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0) -#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1) -#define _PSB_C_CLKGATECTL_CLKG_AUTO (2) - -#define PSB_CR_CORE_ID 0x0010 -#define _PSB_CC_ID_ID_SHIFT (16) -#define _PSB_CC_ID_ID_MASK (0xFFFF << 16) -#define _PSB_CC_ID_CONFIG_SHIFT (0) -#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0) - -#define PSB_CR_CORE_REVISION 0x0014 -#define _PSB_CC_REVISION_DESIGNER_SHIFT (24) -#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24) -#define _PSB_CC_REVISION_MAJOR_SHIFT (16) -#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16) -#define _PSB_CC_REVISION_MINOR_SHIFT (8) -#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8) -#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0) -#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0) - -#define PSB_CR_DESIGNER_REV_FIELD1 0x0018 - -#define PSB_CR_SOFT_RESET 0x0080 -#define _PSB_CS_RESET_TSP_RESET (1 << 6) -#define _PSB_CS_RESET_ISP_RESET (1 << 5) -#define _PSB_CS_RESET_USE_RESET (1 << 4) -#define _PSB_CS_RESET_TA_RESET (1 << 3) -#define _PSB_CS_RESET_DPM_RESET (1 << 2) -#define _PSB_CS_RESET_TWOD_RESET (1 << 1) -#define _PSB_CS_RESET_BIF_RESET (1 << 0) - -#define PSB_CR_DESIGNER_REV_FIELD2 0x001C - -#define PSB_CR_EVENT_HOST_ENABLE2 0x0110 - -#define PSB_CR_EVENT_STATUS2 0x0118 - -#define PSB_CR_EVENT_HOST_CLEAR2 0x0114 -#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4) - -#define PSB_CR_EVENT_STATUS 0x012C - -#define PSB_CR_EVENT_HOST_ENABLE 0x0130 - -#define PSB_CR_EVENT_HOST_CLEAR 0x0134 -#define _PSB_CE_MASTER_INTERRUPT (1 << 31) -#define _PSB_CE_TA_DPM_FAULT (1 << 28) -#define _PSB_CE_TWOD_COMPLETE (1 << 27) -#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25) -#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24) -#define _PSB_CE_PIXELBE_END_RENDER (1 << 18) -#define _PSB_CE_SW_EVENT (1 << 14) -#define _PSB_CE_TA_FINISHED (1 << 13) -#define _PSB_CE_TA_TERMINATE (1 << 12) -#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3) -#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2) -#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1) -#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0) - - -#define PSB_USE_OFFSET_MASK 0x0007FFFF -#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1) -#define PSB_CR_USE_CODE_BASE0 0x0A0C -#define PSB_CR_USE_CODE_BASE1 0x0A10 -#define PSB_CR_USE_CODE_BASE2 0x0A14 -#define PSB_CR_USE_CODE_BASE3 0x0A18 -#define PSB_CR_USE_CODE_BASE4 0x0A1C -#define PSB_CR_USE_CODE_BASE5 0x0A20 -#define PSB_CR_USE_CODE_BASE6 0x0A24 -#define PSB_CR_USE_CODE_BASE7 0x0A28 -#define PSB_CR_USE_CODE_BASE8 0x0A2C -#define PSB_CR_USE_CODE_BASE9 0x0A30 -#define PSB_CR_USE_CODE_BASE10 0x0A34 -#define PSB_CR_USE_CODE_BASE11 0x0A38 -#define PSB_CR_USE_CODE_BASE12 0x0A3C -#define PSB_CR_USE_CODE_BASE13 0x0A40 -#define PSB_CR_USE_CODE_BASE14 0x0A44 -#define PSB_CR_USE_CODE_BASE15 0x0A48 -#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2)) -#define _PSB_CUC_BASE_DM_SHIFT (25) -#define _PSB_CUC_BASE_DM_MASK (0x3 << 25) -#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */ -#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7) -#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0) -#define _PSB_CUC_DM_VERTEX (0) -#define _PSB_CUC_DM_PIXEL (1) -#define _PSB_CUC_DM_RESERVED (2) -#define _PSB_CUC_DM_EDM (3) - -#define PSB_CR_PDS_EXEC_BASE 0x0AB8 -#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */ -#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20) - -#define PSB_CR_EVENT_KICKER 0x0AC4 -#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */ - -#define PSB_CR_EVENT_KICK 0x0AC8 -#define _PSB_CE_KICK_NOW (1 << 0) - -#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38 - -#define PSB_CR_BIF_CTRL 0x0C00 -#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4) -#define _PSB_CB_CTRL_INVALDC (1 << 3) -#define _PSB_CB_CTRL_FLUSH (1 << 2) - -#define PSB_CR_BIF_INT_STAT 0x0C04 - -#define PSB_CR_BIF_FAULT 0x0C08 -#define _PSB_CBI_STAT_PF_N_RW (1 << 14) -#define _PSB_CBI_STAT_FAULT_SHIFT (0) -#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0) -#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1) -#define _PSB_CBI_STAT_FAULT_TA (1 << 2) -#define _PSB_CBI_STAT_FAULT_VDM (1 << 3) -#define _PSB_CBI_STAT_FAULT_2D (1 << 4) -#define _PSB_CBI_STAT_FAULT_PBE (1 << 5) -#define _PSB_CBI_STAT_FAULT_TSP (1 << 6) -#define _PSB_CBI_STAT_FAULT_ISP (1 << 7) -#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8) -#define _PSB_CBI_STAT_FAULT_HOST (1 << 9) - -#define PSB_CR_BIF_BANK0 0x0C78 -#define PSB_CR_BIF_BANK1 0x0C7C -#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84 -#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88 -#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC - -#define PSB_CR_2D_SOCIF 0x0E18 -#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0) -#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0) -#define _PSB_C2_SOCIF_EMPTY (0x80 << 0) - -#define PSB_CR_2D_BLIT_STATUS 0x0E04 -#define _PSB_C2B_STATUS_BUSY (1 << 24) -#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0) -#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0) - -/* - * 2D defs. - */ - -/* - * 2D Slave Port Data : Block Header's Object Type - */ - -#define PSB_2D_CLIP_BH (0x00000000) -#define PSB_2D_PAT_BH (0x10000000) -#define PSB_2D_CTRL_BH (0x20000000) -#define PSB_2D_SRC_OFF_BH (0x30000000) -#define PSB_2D_MASK_OFF_BH (0x40000000) -#define PSB_2D_RESERVED1_BH (0x50000000) -#define PSB_2D_RESERVED2_BH (0x60000000) -#define PSB_2D_FENCE_BH (0x70000000) -#define PSB_2D_BLIT_BH (0x80000000) -#define PSB_2D_SRC_SURF_BH (0x90000000) -#define PSB_2D_DST_SURF_BH (0xA0000000) -#define PSB_2D_PAT_SURF_BH (0xB0000000) -#define PSB_2D_SRC_PAL_BH (0xC0000000) -#define PSB_2D_PAT_PAL_BH (0xD0000000) -#define PSB_2D_MASK_SURF_BH (0xE0000000) -#define PSB_2D_FLUSH_BH (0xF0000000) - -/* - * Clip Definition block (PSB_2D_CLIP_BH) - */ -#define PSB_2D_CLIPCOUNT_MAX (1) -#define PSB_2D_CLIPCOUNT_MASK (0x00000000) -#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF) -#define PSB_2D_CLIPCOUNT_SHIFT (0) -/* clip rectangle min & max */ -#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000) -#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF) -#define PSB_2D_CLIP_XMAX_SHIFT (12) -#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF) -#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000) -#define PSB_2D_CLIP_XMIN_SHIFT (0) -/* clip rectangle offset */ -#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000) -#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF) -#define PSB_2D_CLIP_YMAX_SHIFT (12) -#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF) -#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000) -#define PSB_2D_CLIP_YMIN_SHIFT (0) - -/* - * Pattern Control (PSB_2D_PAT_BH) - */ -#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F) -#define PSB_2D_PAT_HEIGHT_SHIFT (0) -#define PSB_2D_PAT_WIDTH_MASK (0x000003E0) -#define PSB_2D_PAT_WIDTH_SHIFT (5) -#define PSB_2D_PAT_YSTART_MASK (0x00007C00) -#define PSB_2D_PAT_YSTART_SHIFT (10) -#define PSB_2D_PAT_XSTART_MASK (0x000F8000) -#define PSB_2D_PAT_XSTART_SHIFT (15) - -/* - * 2D Control block (PSB_2D_CTRL_BH) - */ -/* Present Flags */ -#define PSB_2D_SRCCK_CTRL (0x00000001) -#define PSB_2D_DSTCK_CTRL (0x00000002) -#define PSB_2D_ALPHA_CTRL (0x00000004) -/* Colour Key Colour (SRC/DST)*/ -#define PSB_2D_CK_COL_MASK (0xFFFFFFFF) -#define PSB_2D_CK_COL_CLRMASK (0x00000000) -#define PSB_2D_CK_COL_SHIFT (0) -/* Colour Key Mask (SRC/DST)*/ -#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF) -#define PSB_2D_CK_MASK_CLRMASK (0x00000000) -#define PSB_2D_CK_MASK_SHIFT (0) -/* Alpha Control (Alpha/RGB)*/ -#define PSB_2D_GBLALPHA_MASK (0x000FF000) -#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF) -#define PSB_2D_GBLALPHA_SHIFT (12) -#define PSB_2D_SRCALPHA_OP_MASK (0x00700000) -#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF) -#define PSB_2D_SRCALPHA_OP_SHIFT (20) -#define PSB_2D_SRCALPHA_OP_ONE (0x00000000) -#define PSB_2D_SRCALPHA_OP_SRC (0x00100000) -#define PSB_2D_SRCALPHA_OP_DST (0x00200000) -#define PSB_2D_SRCALPHA_OP_SG (0x00300000) -#define PSB_2D_SRCALPHA_OP_DG (0x00400000) -#define PSB_2D_SRCALPHA_OP_GBL (0x00500000) -#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000) -#define PSB_2D_SRCALPHA_INVERT (0x00800000) -#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF) -#define PSB_2D_DSTALPHA_OP_MASK (0x07000000) -#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF) -#define PSB_2D_DSTALPHA_OP_SHIFT (24) -#define PSB_2D_DSTALPHA_OP_ONE (0x00000000) -#define PSB_2D_DSTALPHA_OP_SRC (0x01000000) -#define PSB_2D_DSTALPHA_OP_DST (0x02000000) -#define PSB_2D_DSTALPHA_OP_SG (0x03000000) -#define PSB_2D_DSTALPHA_OP_DG (0x04000000) -#define PSB_2D_DSTALPHA_OP_GBL (0x05000000) -#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000) -#define PSB_2D_DSTALPHA_INVERT (0x08000000) -#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF) - -#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000) -#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF) -#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000) -#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF) - -/* - *Source Offset (PSB_2D_SRC_OFF_BH) - */ -#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12) -#define PSB_2D_SRCOFF_XSTART_SHIFT (12) -#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF) -#define PSB_2D_SRCOFF_YSTART_SHIFT (0) - -/* - * Mask Offset (PSB_2D_MASK_OFF_BH) - */ -#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12) -#define PSB_2D_MASKOFF_XSTART_SHIFT (12) -#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF) -#define PSB_2D_MASKOFF_YSTART_SHIFT (0) - -/* - * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored - */ - -/* - *Blit Rectangle (PSB_2D_BLIT_BH) - */ - -#define PSB_2D_ROT_MASK (3 << 25) -#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK) -#define PSB_2D_ROT_NONE (0 << 25) -#define PSB_2D_ROT_90DEGS (1 << 25) -#define PSB_2D_ROT_180DEGS (2 << 25) -#define PSB_2D_ROT_270DEGS (3 << 25) - -#define PSB_2D_COPYORDER_MASK (3 << 23) -#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK) -#define PSB_2D_COPYORDER_TL2BR (0 << 23) -#define PSB_2D_COPYORDER_BR2TL (1 << 23) -#define PSB_2D_COPYORDER_TR2BL (2 << 23) -#define PSB_2D_COPYORDER_BL2TR (3 << 23) - -#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF) -#define PSB_2D_DSTCK_DISABLE (0x00000000) -#define PSB_2D_DSTCK_PASS (0x00200000) -#define PSB_2D_DSTCK_REJECT (0x00400000) - -#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF) -#define PSB_2D_SRCCK_DISABLE (0x00000000) -#define PSB_2D_SRCCK_PASS (0x00080000) -#define PSB_2D_SRCCK_REJECT (0x00100000) - -#define PSB_2D_CLIP_ENABLE (0x00040000) - -#define PSB_2D_ALPHA_ENABLE (0x00020000) - -#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF) -#define PSB_2D_PAT_MASK (0x00010000) -#define PSB_2D_USE_PAT (0x00010000) -#define PSB_2D_USE_FILL (0x00000000) -/* - * Tungsten Graphics note on rop codes: If rop A and rop B are - * identical, the mask surface will not be read and need not be - * set up. - */ - -#define PSB_2D_ROP3B_MASK (0x0000FF00) -#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF) -#define PSB_2D_ROP3B_SHIFT (8) -/* rop code A */ -#define PSB_2D_ROP3A_MASK (0x000000FF) -#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00) -#define PSB_2D_ROP3A_SHIFT (0) - -#define PSB_2D_ROP4_MASK (0x0000FFFF) -/* - * DWORD0: (Only pass if Pattern control == Use Fill Colour) - * Fill Colour RGBA8888 - */ -#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF) -#define PSB_2D_FILLCOLOUR_SHIFT (0) -/* - * DWORD1: (Always Present) - * X Start (Dest) - * Y Start (Dest) - */ -#define PSB_2D_DST_XSTART_MASK (0x00FFF000) -#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF) -#define PSB_2D_DST_XSTART_SHIFT (12) -#define PSB_2D_DST_YSTART_MASK (0x00000FFF) -#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000) -#define PSB_2D_DST_YSTART_SHIFT (0) -/* - * DWORD2: (Always Present) - * X Size (Dest) - * Y Size (Dest) - */ -#define PSB_2D_DST_XSIZE_MASK (0x00FFF000) -#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF) -#define PSB_2D_DST_XSIZE_SHIFT (12) -#define PSB_2D_DST_YSIZE_MASK (0x00000FFF) -#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000) -#define PSB_2D_DST_YSIZE_SHIFT (0) - -/* - * Source Surface (PSB_2D_SRC_SURF_BH) - */ -/* - * WORD 0 - */ - -#define PSB_2D_SRC_FORMAT_MASK (0x00078000) -#define PSB_2D_SRC_1_PAL (0x00000000) -#define PSB_2D_SRC_2_PAL (0x00008000) -#define PSB_2D_SRC_4_PAL (0x00010000) -#define PSB_2D_SRC_8_PAL (0x00018000) -#define PSB_2D_SRC_8_ALPHA (0x00020000) -#define PSB_2D_SRC_4_ALPHA (0x00028000) -#define PSB_2D_SRC_332RGB (0x00030000) -#define PSB_2D_SRC_4444ARGB (0x00038000) -#define PSB_2D_SRC_555RGB (0x00040000) -#define PSB_2D_SRC_1555ARGB (0x00048000) -#define PSB_2D_SRC_565RGB (0x00050000) -#define PSB_2D_SRC_0888ARGB (0x00058000) -#define PSB_2D_SRC_8888ARGB (0x00060000) -#define PSB_2D_SRC_8888UYVY (0x00068000) -#define PSB_2D_SRC_RESERVED (0x00070000) -#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000) - - -#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF) -#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_SRC_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003) -#define PSB_2D_SRC_ADDR_SHIFT (2) -#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2) - -/* - * Pattern Surface (PSB_2D_PAT_SURF_BH) - */ -/* - * WORD 0 - */ - -#define PSB_2D_PAT_FORMAT_MASK (0x00078000) -#define PSB_2D_PAT_1_PAL (0x00000000) -#define PSB_2D_PAT_2_PAL (0x00008000) -#define PSB_2D_PAT_4_PAL (0x00010000) -#define PSB_2D_PAT_8_PAL (0x00018000) -#define PSB_2D_PAT_8_ALPHA (0x00020000) -#define PSB_2D_PAT_4_ALPHA (0x00028000) -#define PSB_2D_PAT_332RGB (0x00030000) -#define PSB_2D_PAT_4444ARGB (0x00038000) -#define PSB_2D_PAT_555RGB (0x00040000) -#define PSB_2D_PAT_1555ARGB (0x00048000) -#define PSB_2D_PAT_565RGB (0x00050000) -#define PSB_2D_PAT_0888ARGB (0x00058000) -#define PSB_2D_PAT_8888ARGB (0x00060000) - -#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF) -#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_PAT_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003) -#define PSB_2D_PAT_ADDR_SHIFT (2) -#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2) - -/* - * Destination Surface (PSB_2D_DST_SURF_BH) - */ -/* - * WORD 0 - */ - -#define PSB_2D_DST_FORMAT_MASK (0x00078000) -#define PSB_2D_DST_332RGB (0x00030000) -#define PSB_2D_DST_4444ARGB (0x00038000) -#define PSB_2D_DST_555RGB (0x00040000) -#define PSB_2D_DST_1555ARGB (0x00048000) -#define PSB_2D_DST_565RGB (0x00050000) -#define PSB_2D_DST_0888ARGB (0x00058000) -#define PSB_2D_DST_8888ARGB (0x00060000) -#define PSB_2D_DST_8888AYUV (0x00070000) - -#define PSB_2D_DST_STRIDE_MASK (0x00007FFF) -#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_DST_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_DST_ADDR_CLRMASK (0x00000003) -#define PSB_2D_DST_ADDR_SHIFT (2) -#define PSB_2D_DST_ADDR_ALIGNSHIFT (2) - -/* - * Mask Surface (PSB_2D_MASK_SURF_BH) - */ -/* - * WORD 0 - */ -#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF) -#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_MASK_STRIDE_SHIFT (0) -/* - * WORD 1 - Base Address - */ -#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003) -#define PSB_2D_MASK_ADDR_SHIFT (2) -#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2) - -/* - * Source Palette (PSB_2D_SRC_PAL_BH) - */ - -#define PSB_2D_SRCPAL_ADDR_SHIFT (0) -#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007) -#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8) -#define PSB_2D_SRCPAL_BYTEALIGN (1024) - -/* - * Pattern Palette (PSB_2D_PAT_PAL_BH) - */ - -#define PSB_2D_PATPAL_ADDR_SHIFT (0) -#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007) -#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8) -#define PSB_2D_PATPAL_BYTEALIGN (1024) - -/* - * Rop3 Codes (2 LS bytes) - */ - -#define PSB_2D_ROP3_SRCCOPY (0xCCCC) -#define PSB_2D_ROP3_PATCOPY (0xF0F0) -#define PSB_2D_ROP3_WHITENESS (0xFFFF) -#define PSB_2D_ROP3_BLACKNESS (0x0000) -#define PSB_2D_ROP3_SRC (0xCC) -#define PSB_2D_ROP3_PAT (0xF0) -#define PSB_2D_ROP3_DST (0xAA) - -/* - * Sizes. - */ - -#define PSB_SCENE_HW_COOKIE_SIZE 16 -#define PSB_TA_MEM_HW_COOKIE_SIZE 16 - -/* - * Scene stuff. - */ - -#define PSB_NUM_HW_SCENES 2 - -/* - * Scheduler completion actions. - */ - -#define PSB_RASTER_BLOCK 0 -#define PSB_RASTER 1 -#define PSB_RETURN 2 -#define PSB_TA 3 - -/* Power management */ -#define PSB_PUNIT_PORT 0x04 -#define PSB_OSPMBA 0x78 -#define PSB_APMBA 0x7a -#define PSB_APM_CMD 0x0 -#define PSB_APM_STS 0x04 -#define PSB_PWRGT_VID_ENC_MASK 0x30 -#define PSB_PWRGT_VID_DEC_MASK 0xc -#define PSB_PWRGT_GL3_MASK 0xc0 - -#define PSB_PM_SSC 0x20 -#define PSB_PM_SSS 0x30 -#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ -#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 -#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */ -/* Display SSS register bits are different in A0 vs. B0 */ -#define PSB_PWRGT_GFX_MASK 0x3 -#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 -#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 -#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 -#define PSB_PWRGT_GFX_MASK_B0 0xc3 -#define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 -#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ -#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c b/ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c deleted file mode 100644 index 4a07ab59..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "mdfld_dsi_dpi.h" -#include "mdfld_output.h" -#include "mdfld_dsi_pkg_sender.h" -#include "tc35876x-dsi-lvds.h" -#include -#include -#include -#include - -static struct i2c_client *tc35876x_client; -static struct i2c_client *cmi_lcd_i2c_client; - -#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) -#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) - -/* DSI D-PHY Layer Registers */ -#define D0W_DPHYCONTTX 0x0004 -#define CLW_DPHYCONTRX 0x0020 -#define D0W_DPHYCONTRX 0x0024 -#define D1W_DPHYCONTRX 0x0028 -#define D2W_DPHYCONTRX 0x002C -#define D3W_DPHYCONTRX 0x0030 -#define COM_DPHYCONTRX 0x0038 -#define CLW_CNTRL 0x0040 -#define D0W_CNTRL 0x0044 -#define D1W_CNTRL 0x0048 -#define D2W_CNTRL 0x004C -#define D3W_CNTRL 0x0050 -#define DFTMODE_CNTRL 0x0054 - -/* DSI PPI Layer Registers */ -#define PPI_STARTPPI 0x0104 -#define PPI_BUSYPPI 0x0108 -#define PPI_LINEINITCNT 0x0110 -#define PPI_LPTXTIMECNT 0x0114 -#define PPI_LANEENABLE 0x0134 -#define PPI_TX_RX_TA 0x013C -#define PPI_CLS_ATMR 0x0140 -#define PPI_D0S_ATMR 0x0144 -#define PPI_D1S_ATMR 0x0148 -#define PPI_D2S_ATMR 0x014C -#define PPI_D3S_ATMR 0x0150 -#define PPI_D0S_CLRSIPOCOUNT 0x0164 -#define PPI_D1S_CLRSIPOCOUNT 0x0168 -#define PPI_D2S_CLRSIPOCOUNT 0x016C -#define PPI_D3S_CLRSIPOCOUNT 0x0170 -#define CLS_PRE 0x0180 -#define D0S_PRE 0x0184 -#define D1S_PRE 0x0188 -#define D2S_PRE 0x018C -#define D3S_PRE 0x0190 -#define CLS_PREP 0x01A0 -#define D0S_PREP 0x01A4 -#define D1S_PREP 0x01A8 -#define D2S_PREP 0x01AC -#define D3S_PREP 0x01B0 -#define CLS_ZERO 0x01C0 -#define D0S_ZERO 0x01C4 -#define D1S_ZERO 0x01C8 -#define D2S_ZERO 0x01CC -#define D3S_ZERO 0x01D0 -#define PPI_CLRFLG 0x01E0 -#define PPI_CLRSIPO 0x01E4 -#define HSTIMEOUT 0x01F0 -#define HSTIMEOUTENABLE 0x01F4 - -/* DSI Protocol Layer Registers */ -#define DSI_STARTDSI 0x0204 -#define DSI_BUSYDSI 0x0208 -#define DSI_LANEENABLE 0x0210 -#define DSI_LANESTATUS0 0x0214 -#define DSI_LANESTATUS1 0x0218 -#define DSI_INTSTATUS 0x0220 -#define DSI_INTMASK 0x0224 -#define DSI_INTCLR 0x0228 -#define DSI_LPTXTO 0x0230 - -/* DSI General Registers */ -#define DSIERRCNT 0x0300 - -/* DSI Application Layer Registers */ -#define APLCTRL 0x0400 -#define RDPKTLN 0x0404 - -/* Video Path Registers */ -#define VPCTRL 0x0450 -#define HTIM1 0x0454 -#define HTIM2 0x0458 -#define VTIM1 0x045C -#define VTIM2 0x0460 -#define VFUEN 0x0464 - -/* LVDS Registers */ -#define LVMX0003 0x0480 -#define LVMX0407 0x0484 -#define LVMX0811 0x0488 -#define LVMX1215 0x048C -#define LVMX1619 0x0490 -#define LVMX2023 0x0494 -#define LVMX2427 0x0498 -#define LVCFG 0x049C -#define LVPHY0 0x04A0 -#define LVPHY1 0x04A4 - -/* System Registers */ -#define SYSSTAT 0x0500 -#define SYSRST 0x0504 - -/* GPIO Registers */ -/*#define GPIOC 0x0520*/ -#define GPIOO 0x0524 -#define GPIOI 0x0528 - -/* I2C Registers */ -#define I2CTIMCTRL 0x0540 -#define I2CMADDR 0x0544 -#define WDATAQ 0x0548 -#define RDATAQ 0x054C - -/* Chip/Rev Registers */ -#define IDREG 0x0580 - -/* Debug Registers */ -#define DEBUG00 0x05A0 -#define DEBUG01 0x05A4 - -/* Panel CABC registers */ -#define PANEL_PWM_CONTROL 0x90 -#define PANEL_FREQ_DIVIDER_HI 0x91 -#define PANEL_FREQ_DIVIDER_LO 0x92 -#define PANEL_DUTY_CONTROL 0x93 -#define PANEL_MODIFY_RGB 0x94 -#define PANEL_FRAMERATE_CONTROL 0x96 -#define PANEL_PWM_MIN 0x97 -#define PANEL_PWM_REF 0x98 -#define PANEL_PWM_MAX 0x99 -#define PANEL_ALLOW_DISTORT 0x9A -#define PANEL_BYPASS_PWMI 0x9B - -/* Panel color management registers */ -#define PANEL_CM_ENABLE 0x700 -#define PANEL_CM_HUE 0x701 -#define PANEL_CM_SATURATION 0x702 -#define PANEL_CM_INTENSITY 0x703 -#define PANEL_CM_BRIGHTNESS 0x704 -#define PANEL_CM_CE_ENABLE 0x705 -#define PANEL_CM_PEAK_EN 0x710 -#define PANEL_CM_GAIN 0x711 -#define PANEL_CM_HUETABLE_START 0x730 -#define PANEL_CM_HUETABLE_END 0x747 /* inclusive */ - -/* Input muxing for registers LVMX0003...LVMX2427 */ -enum { - INPUT_R0, /* 0 */ - INPUT_R1, - INPUT_R2, - INPUT_R3, - INPUT_R4, - INPUT_R5, - INPUT_R6, - INPUT_R7, - INPUT_G0, /* 8 */ - INPUT_G1, - INPUT_G2, - INPUT_G3, - INPUT_G4, - INPUT_G5, - INPUT_G6, - INPUT_G7, - INPUT_B0, /* 16 */ - INPUT_B1, - INPUT_B2, - INPUT_B3, - INPUT_B4, - INPUT_B5, - INPUT_B6, - INPUT_B7, - INPUT_HSYNC, /* 24 */ - INPUT_VSYNC, - INPUT_DE, - LOGIC_0, - /* 28...31 undefined */ -}; - -#define INPUT_MUX(lvmx03, lvmx02, lvmx01, lvmx00) \ - (FLD_VAL(lvmx03, 29, 24) | FLD_VAL(lvmx02, 20, 16) | \ - FLD_VAL(lvmx01, 12, 8) | FLD_VAL(lvmx00, 4, 0)) - -/** - * tc35876x_regw - Write DSI-LVDS bridge register using I2C - * @client: struct i2c_client to use - * @reg: register address - * @value: value to write - * - * Returns 0 on success, or a negative error value. - */ -static int tc35876x_regw(struct i2c_client *client, u16 reg, u32 value) -{ - int r; - u8 tx_data[] = { - /* NOTE: Register address big-endian, data little-endian. */ - (reg >> 8) & 0xff, - reg & 0xff, - value & 0xff, - (value >> 8) & 0xff, - (value >> 16) & 0xff, - (value >> 24) & 0xff, - }; - struct i2c_msg msgs[] = { - { - .addr = client->addr, - .flags = 0, - .buf = tx_data, - .len = ARRAY_SIZE(tx_data), - }, - }; - - r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (r < 0) { - dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x error %d\n", - __func__, reg, value, r); - return r; - } - - if (r < ARRAY_SIZE(msgs)) { - dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x msgs %d\n", - __func__, reg, value, r); - return -EAGAIN; - } - - dev_dbg(&client->dev, "%s: reg 0x%04x val 0x%08x\n", - __func__, reg, value); - - return 0; -} - -/** - * tc35876x_regr - Read DSI-LVDS bridge register using I2C - * @client: struct i2c_client to use - * @reg: register address - * @value: pointer for storing the value - * - * Returns 0 on success, or a negative error value. - */ -static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value) -{ - int r; - u8 tx_data[] = { - (reg >> 8) & 0xff, - reg & 0xff, - }; - u8 rx_data[4]; - struct i2c_msg msgs[] = { - { - .addr = client->addr, - .flags = 0, - .buf = tx_data, - .len = ARRAY_SIZE(tx_data), - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .buf = rx_data, - .len = ARRAY_SIZE(rx_data), - }, - }; - - r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (r < 0) { - dev_err(&client->dev, "%s: reg 0x%04x error %d\n", __func__, - reg, r); - return r; - } - - if (r < ARRAY_SIZE(msgs)) { - dev_err(&client->dev, "%s: reg 0x%04x msgs %d\n", __func__, - reg, r); - return -EAGAIN; - } - - *value = rx_data[0] << 24 | rx_data[1] << 16 | - rx_data[2] << 8 | rx_data[3]; - - dev_dbg(&client->dev, "%s: reg 0x%04x value 0x%08x\n", __func__, - reg, *value); - - return 0; -} - -void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state) -{ - struct tc35876x_platform_data *pdata; - - if (WARN(!tc35876x_client, "%s called before probe", __func__)) - return; - - dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state); - - pdata = dev_get_platdata(&tc35876x_client->dev); - - if (pdata->gpio_bridge_reset == -1) - return; - - if (state) { - gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0); - mdelay(10); - } else { - /* Pull MIPI Bridge reset pin to Low */ - gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0); - mdelay(20); - /* Pull MIPI Bridge reset pin to High */ - gpio_set_value_cansleep(pdata->gpio_bridge_reset, 1); - mdelay(40); - } -} - -void tc35876x_configure_lvds_bridge(struct drm_device *dev) -{ - struct i2c_client *i2c = tc35876x_client; - u32 ppi_lptxtimecnt; - u32 txtagocnt; - u32 txtasurecnt; - u32 id; - - if (WARN(!tc35876x_client, "%s called before probe", __func__)) - return; - - dev_dbg(&tc35876x_client->dev, "%s\n", __func__); - - if (!tc35876x_regr(i2c, IDREG, &id)) - dev_info(&tc35876x_client->dev, "tc35876x ID 0x%08x\n", id); - else - dev_err(&tc35876x_client->dev, "Cannot read ID\n"); - - ppi_lptxtimecnt = 4; - txtagocnt = (5 * ppi_lptxtimecnt - 3) / 4; - txtasurecnt = 3 * ppi_lptxtimecnt / 2; - tc35876x_regw(i2c, PPI_TX_RX_TA, FLD_VAL(txtagocnt, 26, 16) | - FLD_VAL(txtasurecnt, 10, 0)); - tc35876x_regw(i2c, PPI_LPTXTIMECNT, FLD_VAL(ppi_lptxtimecnt, 10, 0)); - - tc35876x_regw(i2c, PPI_D0S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); - tc35876x_regw(i2c, PPI_D1S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); - tc35876x_regw(i2c, PPI_D2S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); - tc35876x_regw(i2c, PPI_D3S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); - - /* Enabling MIPI & PPI lanes, Enable 4 lanes */ - tc35876x_regw(i2c, PPI_LANEENABLE, - BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); - tc35876x_regw(i2c, DSI_LANEENABLE, - BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); - tc35876x_regw(i2c, PPI_STARTPPI, BIT(0)); - tc35876x_regw(i2c, DSI_STARTDSI, BIT(0)); - - /* Setting LVDS output frequency */ - tc35876x_regw(i2c, LVPHY0, FLD_VAL(1, 20, 16) | - FLD_VAL(2, 15, 14) | FLD_VAL(6, 4, 0)); /* 0x00048006 */ - - /* Setting video panel control register,0x00000120 VTGen=ON ?!?!? */ - tc35876x_regw(i2c, VPCTRL, BIT(8) | BIT(5)); - - /* Horizontal back porch and horizontal pulse width. 0x00280028 */ - tc35876x_regw(i2c, HTIM1, FLD_VAL(40, 24, 16) | FLD_VAL(40, 8, 0)); - - /* Horizontal front porch and horizontal active video size. 0x00500500*/ - tc35876x_regw(i2c, HTIM2, FLD_VAL(80, 24, 16) | FLD_VAL(1280, 10, 0)); - - /* Vertical back porch and vertical sync pulse width. 0x000e000a */ - tc35876x_regw(i2c, VTIM1, FLD_VAL(14, 23, 16) | FLD_VAL(10, 7, 0)); - - /* Vertical front porch and vertical display size. 0x000e0320 */ - tc35876x_regw(i2c, VTIM2, FLD_VAL(14, 23, 16) | FLD_VAL(800, 10, 0)); - - /* Set above HTIM1, HTIM2, VTIM1, and VTIM2 at next VSYNC. */ - tc35876x_regw(i2c, VFUEN, BIT(0)); - - /* Soft reset LCD controller. */ - tc35876x_regw(i2c, SYSRST, BIT(2)); - - /* LVDS-TX input muxing */ - tc35876x_regw(i2c, LVMX0003, - INPUT_MUX(INPUT_R5, INPUT_R4, INPUT_R3, INPUT_R2)); - tc35876x_regw(i2c, LVMX0407, - INPUT_MUX(INPUT_G2, INPUT_R7, INPUT_R1, INPUT_R6)); - tc35876x_regw(i2c, LVMX0811, - INPUT_MUX(INPUT_G1, INPUT_G0, INPUT_G4, INPUT_G3)); - tc35876x_regw(i2c, LVMX1215, - INPUT_MUX(INPUT_B2, INPUT_G7, INPUT_G6, INPUT_G5)); - tc35876x_regw(i2c, LVMX1619, - INPUT_MUX(INPUT_B4, INPUT_B3, INPUT_B1, INPUT_B0)); - tc35876x_regw(i2c, LVMX2023, - INPUT_MUX(LOGIC_0, INPUT_B7, INPUT_B6, INPUT_B5)); - tc35876x_regw(i2c, LVMX2427, - INPUT_MUX(INPUT_R0, INPUT_DE, INPUT_VSYNC, INPUT_HSYNC)); - - /* Enable LVDS transmitter. */ - tc35876x_regw(i2c, LVCFG, BIT(0)); - - /* Clear notifications. Don't write reserved bits. Was write 0xffffffff - * to 0x0288, must be in error?! */ - tc35876x_regw(i2c, DSI_INTCLR, FLD_MASK(31, 30) | FLD_MASK(22, 0)); -} - -#define GPIOPWMCTRL 0x38F -#define PWM0CLKDIV0 0x62 /* low byte */ -#define PWM0CLKDIV1 0x61 /* high byte */ - -#define SYSTEMCLK 19200000UL /* 19.2 MHz */ -#define PWM_FREQUENCY 9600 /* Hz */ - -/* f = baseclk / (clkdiv + 1) => clkdiv = (baseclk - f) / f */ -static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f) -{ - return (baseclk - f) / f; -} - -static void tc35876x_brightness_init(struct drm_device *dev) -{ - int ret; - u8 pwmctrl; - u16 clkdiv; - - /* Make sure the PWM reference is the 19.2 MHz system clock. Read first - * instead of setting directly to catch potential conflicts between PWM - * users. */ - ret = intel_scu_ipc_ioread8(GPIOPWMCTRL, &pwmctrl); - if (ret || pwmctrl != 0x01) { - if (ret) - dev_err(&dev->pdev->dev, "GPIOPWMCTRL read failed\n"); - else - dev_warn(&dev->pdev->dev, "GPIOPWMCTRL was not set to system clock (pwmctrl = 0x%02x)\n", pwmctrl); - - ret = intel_scu_ipc_iowrite8(GPIOPWMCTRL, 0x01); - if (ret) - dev_err(&dev->pdev->dev, "GPIOPWMCTRL set failed\n"); - } - - clkdiv = calc_clkdiv(SYSTEMCLK, PWM_FREQUENCY); - - ret = intel_scu_ipc_iowrite8(PWM0CLKDIV1, (clkdiv >> 8) & 0xff); - if (!ret) - ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, clkdiv & 0xff); - - if (ret) - dev_err(&dev->pdev->dev, "PWM0CLKDIV set failed\n"); - else - dev_dbg(&dev->pdev->dev, "PWM0CLKDIV set to 0x%04x (%d Hz)\n", - clkdiv, PWM_FREQUENCY); -} - -#define PWM0DUTYCYCLE 0x67 - -void tc35876x_brightness_control(struct drm_device *dev, int level) -{ - int ret; - u8 duty_val; - u8 panel_duty_val; - - level = clamp(level, 0, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); - - /* PWM duty cycle 0x00...0x63 corresponds to 0...99% */ - duty_val = level * 0x63 / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL; - - /* I won't pretend to understand this formula. The panel spec is quite - * bad engrish. - */ - panel_duty_val = (2 * level - 100) * 0xA9 / - MDFLD_DSI_BRIGHTNESS_MAX_LEVEL + 0x56; - - ret = intel_scu_ipc_iowrite8(PWM0DUTYCYCLE, duty_val); - if (ret) - dev_err(&tc35876x_client->dev, "%s: ipc write fail\n", - __func__); - - if (cmi_lcd_i2c_client) { - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, - PANEL_PWM_MAX, panel_duty_val); - if (ret < 0) - dev_err(&cmi_lcd_i2c_client->dev, "%s: i2c write failed\n", - __func__); - } -} - -void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev) -{ - struct tc35876x_platform_data *pdata; - - if (WARN(!tc35876x_client, "%s called before probe", __func__)) - return; - - dev_dbg(&tc35876x_client->dev, "%s\n", __func__); - - pdata = dev_get_platdata(&tc35876x_client->dev); - - if (pdata->gpio_panel_bl_en != -1) - gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 0); - - if (pdata->gpio_panel_vadd != -1) - gpio_set_value_cansleep(pdata->gpio_panel_vadd, 0); -} - -void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) -{ - struct tc35876x_platform_data *pdata; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (WARN(!tc35876x_client, "%s called before probe", __func__)) - return; - - dev_dbg(&tc35876x_client->dev, "%s\n", __func__); - - pdata = dev_get_platdata(&tc35876x_client->dev); - - if (pdata->gpio_panel_vadd != -1) { - gpio_set_value_cansleep(pdata->gpio_panel_vadd, 1); - msleep(260); - } - - if (cmi_lcd_i2c_client) { - int ret; - dev_dbg(&cmi_lcd_i2c_client->dev, "setting TCON\n"); - /* Bit 4 is average_saving. Setting it to 1, the brightness is - * referenced to the average of the frame content. 0 means - * reference to the maximum of frame contents. Bits 3:0 are - * allow_distort. When set to a nonzero value, all color values - * between 255-allow_distort*2 and 255 are mapped to the - * 255-allow_distort*2 value. - */ - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, - PANEL_ALLOW_DISTORT, 0x10); - if (ret < 0) - dev_err(&cmi_lcd_i2c_client->dev, - "i2c write failed (%d)\n", ret); - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, - PANEL_BYPASS_PWMI, 0); - if (ret < 0) - dev_err(&cmi_lcd_i2c_client->dev, - "i2c write failed (%d)\n", ret); - /* Set minimum brightness value - this is tunable */ - ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, - PANEL_PWM_MIN, 0x35); - if (ret < 0) - dev_err(&cmi_lcd_i2c_client->dev, - "i2c write failed (%d)\n", ret); - } - - if (pdata->gpio_panel_bl_en != -1) - gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 1); - - tc35876x_brightness_control(dev, dev_priv->brightness_adjusted); -} - -static struct drm_display_mode *tc35876x_get_config_mode(struct drm_device *dev) -{ - struct drm_display_mode *mode; - - dev_dbg(&dev->pdev->dev, "%s\n", __func__); - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - /* FIXME: do this properly. */ - mode->hdisplay = 1280; - mode->vdisplay = 800; - mode->hsync_start = 1360; - mode->hsync_end = 1400; - mode->htotal = 1440; - mode->vsync_start = 814; - mode->vsync_end = 824; - mode->vtotal = 838; - mode->clock = 33324 << 1; - - dev_info(&dev->pdev->dev, "hdisplay(w) = %d\n", mode->hdisplay); - dev_info(&dev->pdev->dev, "vdisplay(h) = %d\n", mode->vdisplay); - dev_info(&dev->pdev->dev, "HSS = %d\n", mode->hsync_start); - dev_info(&dev->pdev->dev, "HSE = %d\n", mode->hsync_end); - dev_info(&dev->pdev->dev, "htotal = %d\n", mode->htotal); - dev_info(&dev->pdev->dev, "VSS = %d\n", mode->vsync_start); - dev_info(&dev->pdev->dev, "VSE = %d\n", mode->vsync_end); - dev_info(&dev->pdev->dev, "vtotal = %d\n", mode->vtotal); - dev_info(&dev->pdev->dev, "clock = %d\n", mode->clock); - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - mode->type |= DRM_MODE_TYPE_PREFERRED; - - return mode; -} - -/* DV1 Active area 216.96 x 135.6 mm */ -#define DV1_PANEL_WIDTH 217 -#define DV1_PANEL_HEIGHT 136 - -static int tc35876x_get_panel_info(struct drm_device *dev, int pipe, - struct panel_info *pi) -{ - if (!dev || !pi) - return -EINVAL; - - pi->width_mm = DV1_PANEL_WIDTH; - pi->height_mm = DV1_PANEL_HEIGHT; - - return 0; -} - -static int tc35876x_bridge_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct tc35876x_platform_data *pdata; - - dev_info(&client->dev, "%s\n", __func__); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "%s: i2c_check_functionality() failed\n", - __func__); - return -ENODEV; - } - - pdata = dev_get_platdata(&client->dev); - if (!pdata) { - dev_err(&client->dev, "%s: no platform data\n", __func__); - return -ENODEV; - } - - if (pdata->gpio_bridge_reset != -1) { - gpio_request(pdata->gpio_bridge_reset, "tc35876x bridge reset"); - gpio_direction_output(pdata->gpio_bridge_reset, 0); - } - - if (pdata->gpio_panel_bl_en != -1) { - gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en"); - gpio_direction_output(pdata->gpio_panel_bl_en, 0); - } - - if (pdata->gpio_panel_vadd != -1) { - gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd"); - gpio_direction_output(pdata->gpio_panel_vadd, 0); - } - - tc35876x_client = client; - - return 0; -} - -static int tc35876x_bridge_remove(struct i2c_client *client) -{ - struct tc35876x_platform_data *pdata = dev_get_platdata(&client->dev); - - dev_dbg(&client->dev, "%s\n", __func__); - - if (pdata->gpio_bridge_reset != -1) - gpio_free(pdata->gpio_bridge_reset); - - if (pdata->gpio_panel_bl_en != -1) - gpio_free(pdata->gpio_panel_bl_en); - - if (pdata->gpio_panel_vadd != -1) - gpio_free(pdata->gpio_panel_vadd); - - tc35876x_client = NULL; - - return 0; -} - -static const struct i2c_device_id tc35876x_bridge_id[] = { - { "i2c_disp_brig", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tc35876x_bridge_id); - -static struct i2c_driver tc35876x_bridge_i2c_driver = { - .driver = { - .name = "i2c_disp_brig", - }, - .id_table = tc35876x_bridge_id, - .probe = tc35876x_bridge_probe, - .remove = __devexit_p(tc35876x_bridge_remove), -}; - -/* LCD panel I2C */ -static int cmi_lcd_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - dev_info(&client->dev, "%s\n", __func__); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, "%s: i2c_check_functionality() failed\n", - __func__); - return -ENODEV; - } - - cmi_lcd_i2c_client = client; - - return 0; -} - -static int cmi_lcd_i2c_remove(struct i2c_client *client) -{ - dev_dbg(&client->dev, "%s\n", __func__); - - cmi_lcd_i2c_client = NULL; - - return 0; -} - -static const struct i2c_device_id cmi_lcd_i2c_id[] = { - { "cmi-lcd", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, cmi_lcd_i2c_id); - -static struct i2c_driver cmi_lcd_i2c_driver = { - .driver = { - .name = "cmi-lcd", - }, - .id_table = cmi_lcd_i2c_id, - .probe = cmi_lcd_i2c_probe, - .remove = __devexit_p(cmi_lcd_i2c_remove), -}; - -/* HACK to create I2C device while it's not created by platform code */ -#define CMI_LCD_I2C_ADAPTER 2 -#define CMI_LCD_I2C_ADDR 0x60 - -static int cmi_lcd_hack_create_device(void) -{ - struct i2c_adapter *adapter; - struct i2c_client *client; - struct i2c_board_info info = { - .type = "cmi-lcd", - .addr = CMI_LCD_I2C_ADDR, - }; - - pr_debug("%s\n", __func__); - - adapter = i2c_get_adapter(CMI_LCD_I2C_ADAPTER); - if (!adapter) { - pr_err("%s: i2c_get_adapter(%d) failed\n", __func__, - CMI_LCD_I2C_ADAPTER); - return -EINVAL; - } - - client = i2c_new_device(adapter, &info); - if (!client) { - pr_err("%s: i2c_new_device() failed\n", __func__); - i2c_put_adapter(adapter); - return -EINVAL; - } - - return 0; -} - -static const struct drm_encoder_helper_funcs tc35876x_encoder_helper_funcs = { - .dpms = mdfld_dsi_dpi_dpms, - .mode_fixup = mdfld_dsi_dpi_mode_fixup, - .prepare = mdfld_dsi_dpi_prepare, - .mode_set = mdfld_dsi_dpi_mode_set, - .commit = mdfld_dsi_dpi_commit, -}; - -static const struct drm_encoder_funcs tc35876x_encoder_funcs = { - .destroy = drm_encoder_cleanup, -}; - -const struct panel_funcs mdfld_tc35876x_funcs = { - .encoder_funcs = &tc35876x_encoder_funcs, - .encoder_helper_funcs = &tc35876x_encoder_helper_funcs, - .get_config_mode = tc35876x_get_config_mode, - .get_panel_info = tc35876x_get_panel_info, -}; - -void tc35876x_init(struct drm_device *dev) -{ - int r; - - dev_dbg(&dev->pdev->dev, "%s\n", __func__); - - cmi_lcd_hack_create_device(); - - r = i2c_add_driver(&cmi_lcd_i2c_driver); - if (r < 0) - dev_err(&dev->pdev->dev, - "%s: i2c_add_driver() for %s failed (%d)\n", - __func__, cmi_lcd_i2c_driver.driver.name, r); - - r = i2c_add_driver(&tc35876x_bridge_i2c_driver); - if (r < 0) - dev_err(&dev->pdev->dev, - "%s: i2c_add_driver() for %s failed (%d)\n", - __func__, tc35876x_bridge_i2c_driver.driver.name, r); - - tc35876x_brightness_init(dev); -} - -void tc35876x_exit(void) -{ - pr_debug("%s\n", __func__); - - i2c_del_driver(&tc35876x_bridge_i2c_driver); - - if (cmi_lcd_i2c_client) - i2c_del_driver(&cmi_lcd_i2c_driver); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.h b/ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.h deleted file mode 100644 index b14b7f9e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __MDFLD_DSI_LVDS_BRIDGE_H__ -#define __MDFLD_DSI_LVDS_BRIDGE_H__ - -void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state); -void tc35876x_configure_lvds_bridge(struct drm_device *dev); -void tc35876x_brightness_control(struct drm_device *dev, int level); -void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev); -void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev); -void tc35876x_init(struct drm_device *dev); -void tc35876x_exit(void); - -extern const struct panel_funcs mdfld_tc35876x_funcs; - -#endif /*__MDFLD_DSI_LVDS_BRIDGE_H__*/ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i2c/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/i2c/Makefile deleted file mode 100644 index 92862563..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i2c/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -ccflags-y := -Iinclude/drm - -ch7006-y := ch7006_drv.o ch7006_mode.o -obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o - -sil164-y := sil164_drv.o -obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_drv.c deleted file mode 100644 index d3f2e878..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_drv.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include - -#include "ch7006_priv.h" - -/* DRM encoder functions */ - -static void ch7006_encoder_set_config(struct drm_encoder *encoder, - void *params) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - - priv->params = *(struct ch7006_encoder_params *)params; -} - -static void ch7006_encoder_destroy(struct drm_encoder *encoder) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - - drm_property_destroy(encoder->dev, priv->scale_property); - - kfree(priv); - to_encoder_slave(encoder)->slave_priv = NULL; - - drm_i2c_encoder_destroy(encoder); -} - -static void ch7006_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_state *state = &priv->state; - - ch7006_dbg(client, "\n"); - - if (mode == priv->last_dpms) - return; - priv->last_dpms = mode; - - ch7006_setup_power_state(encoder); - - ch7006_load_reg(client, state, CH7006_POWER); -} - -static void ch7006_encoder_save(struct drm_encoder *encoder) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - - ch7006_dbg(client, "\n"); - - ch7006_state_save(client, &priv->saved_state); -} - -static void ch7006_encoder_restore(struct drm_encoder *encoder) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - - ch7006_dbg(client, "\n"); - - ch7006_state_load(client, &priv->saved_state); -} - -static bool ch7006_encoder_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - - /* The ch7006 is painfully picky with the input timings so no - * custom modes for now... */ - - priv->mode = ch7006_lookup_mode(encoder, mode); - - return !!priv->mode; -} - -static int ch7006_encoder_mode_valid(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - if (ch7006_lookup_mode(encoder, mode)) - return MODE_OK; - else - return MODE_BAD; -} - -static void ch7006_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *drm_mode, - struct drm_display_mode *adjusted_mode) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_encoder_params *params = &priv->params; - struct ch7006_state *state = &priv->state; - uint8_t *regs = state->regs; - struct ch7006_mode *mode = priv->mode; - struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; - int start_active; - - ch7006_dbg(client, "\n"); - - regs[CH7006_DISPMODE] = norm->dispmode | mode->dispmode; - regs[CH7006_BWIDTH] = 0; - regs[CH7006_INPUT_FORMAT] = bitf(CH7006_INPUT_FORMAT_FORMAT, - params->input_format); - - regs[CH7006_CLKMODE] = CH7006_CLKMODE_SUBC_LOCK - | bitf(CH7006_CLKMODE_XCM, params->xcm) - | bitf(CH7006_CLKMODE_PCM, params->pcm); - if (params->clock_mode) - regs[CH7006_CLKMODE] |= CH7006_CLKMODE_MASTER; - if (params->clock_edge) - regs[CH7006_CLKMODE] |= CH7006_CLKMODE_POS_EDGE; - - start_active = (drm_mode->htotal & ~0x7) - (drm_mode->hsync_start & ~0x7); - regs[CH7006_POV] = bitf(CH7006_POV_START_ACTIVE_8, start_active); - regs[CH7006_START_ACTIVE] = bitf(CH7006_START_ACTIVE_0, start_active); - - regs[CH7006_INPUT_SYNC] = 0; - if (params->sync_direction) - regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_OUTPUT; - if (params->sync_encoding) - regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_EMBEDDED; - if (drm_mode->flags & DRM_MODE_FLAG_PVSYNC) - regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PVSYNC; - if (drm_mode->flags & DRM_MODE_FLAG_PHSYNC) - regs[CH7006_INPUT_SYNC] |= CH7006_INPUT_SYNC_PHSYNC; - - regs[CH7006_DETECT] = 0; - regs[CH7006_BCLKOUT] = 0; - - regs[CH7006_SUBC_INC3] = 0; - if (params->pout_level) - regs[CH7006_SUBC_INC3] |= CH7006_SUBC_INC3_POUT_3_3V; - - regs[CH7006_SUBC_INC4] = 0; - if (params->active_detect) - regs[CH7006_SUBC_INC4] |= CH7006_SUBC_INC4_DS_INPUT; - - regs[CH7006_PLL_CONTROL] = priv->saved_state.regs[CH7006_PLL_CONTROL]; - - ch7006_setup_levels(encoder); - ch7006_setup_subcarrier(encoder); - ch7006_setup_pll(encoder); - ch7006_setup_power_state(encoder); - ch7006_setup_properties(encoder); - - ch7006_state_load(client, state); -} - -static enum drm_connector_status ch7006_encoder_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_state *state = &priv->state; - int det; - - ch7006_dbg(client, "\n"); - - ch7006_save_reg(client, state, CH7006_DETECT); - ch7006_save_reg(client, state, CH7006_POWER); - ch7006_save_reg(client, state, CH7006_CLKMODE); - - ch7006_write(client, CH7006_POWER, CH7006_POWER_RESET | - bitfs(CH7006_POWER_LEVEL, NORMAL)); - ch7006_write(client, CH7006_CLKMODE, CH7006_CLKMODE_MASTER); - - ch7006_write(client, CH7006_DETECT, CH7006_DETECT_SENSE); - - ch7006_write(client, CH7006_DETECT, 0); - - det = ch7006_read(client, CH7006_DETECT); - - ch7006_load_reg(client, state, CH7006_CLKMODE); - ch7006_load_reg(client, state, CH7006_POWER); - ch7006_load_reg(client, state, CH7006_DETECT); - - if ((det & (CH7006_DETECT_SVIDEO_Y_TEST| - CH7006_DETECT_SVIDEO_C_TEST| - CH7006_DETECT_CVBS_TEST)) == 0) - priv->subconnector = DRM_MODE_SUBCONNECTOR_SCART; - else if ((det & (CH7006_DETECT_SVIDEO_Y_TEST| - CH7006_DETECT_SVIDEO_C_TEST)) == 0) - priv->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; - else if ((det & CH7006_DETECT_CVBS_TEST) == 0) - priv->subconnector = DRM_MODE_SUBCONNECTOR_Composite; - else - priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; - - drm_connector_property_set_value(connector, - encoder->dev->mode_config.tv_subconnector_property, - priv->subconnector); - - return priv->subconnector ? connector_status_connected : - connector_status_disconnected; -} - -static int ch7006_encoder_get_modes(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_mode *mode; - int n = 0; - - for (mode = ch7006_modes; mode->mode.clock; mode++) { - if (~mode->valid_scales & 1<scale || - ~mode->valid_norms & 1<norm) - continue; - - drm_mode_probed_add(connector, - drm_mode_duplicate(encoder->dev, &mode->mode)); - - n++; - } - - return n; -} - -static int ch7006_encoder_create_resources(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct drm_device *dev = encoder->dev; - struct drm_mode_config *conf = &dev->mode_config; - - drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); - - priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2); - - drm_connector_attach_property(connector, conf->tv_select_subconnector_property, - priv->select_subconnector); - drm_connector_attach_property(connector, conf->tv_subconnector_property, - priv->subconnector); - drm_connector_attach_property(connector, conf->tv_left_margin_property, - priv->hmargin); - drm_connector_attach_property(connector, conf->tv_bottom_margin_property, - priv->vmargin); - drm_connector_attach_property(connector, conf->tv_mode_property, - priv->norm); - drm_connector_attach_property(connector, conf->tv_brightness_property, - priv->brightness); - drm_connector_attach_property(connector, conf->tv_contrast_property, - priv->contrast); - drm_connector_attach_property(connector, conf->tv_flicker_reduction_property, - priv->flicker); - drm_connector_attach_property(connector, priv->scale_property, - priv->scale); - - return 0; -} - -static int ch7006_encoder_set_property(struct drm_encoder *encoder, - struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_state *state = &priv->state; - struct drm_mode_config *conf = &encoder->dev->mode_config; - struct drm_crtc *crtc = encoder->crtc; - bool modes_changed = false; - - ch7006_dbg(client, "\n"); - - if (property == conf->tv_select_subconnector_property) { - priv->select_subconnector = val; - - ch7006_setup_power_state(encoder); - - ch7006_load_reg(client, state, CH7006_POWER); - - } else if (property == conf->tv_left_margin_property) { - priv->hmargin = val; - - ch7006_setup_properties(encoder); - - ch7006_load_reg(client, state, CH7006_POV); - ch7006_load_reg(client, state, CH7006_HPOS); - - } else if (property == conf->tv_bottom_margin_property) { - priv->vmargin = val; - - ch7006_setup_properties(encoder); - - ch7006_load_reg(client, state, CH7006_POV); - ch7006_load_reg(client, state, CH7006_VPOS); - - } else if (property == conf->tv_mode_property) { - if (connector->dpms != DRM_MODE_DPMS_OFF) - return -EINVAL; - - priv->norm = val; - - modes_changed = true; - - } else if (property == conf->tv_brightness_property) { - priv->brightness = val; - - ch7006_setup_levels(encoder); - - ch7006_load_reg(client, state, CH7006_BLACK_LEVEL); - - } else if (property == conf->tv_contrast_property) { - priv->contrast = val; - - ch7006_setup_properties(encoder); - - ch7006_load_reg(client, state, CH7006_CONTRAST); - - } else if (property == conf->tv_flicker_reduction_property) { - priv->flicker = val; - - ch7006_setup_properties(encoder); - - ch7006_load_reg(client, state, CH7006_FFILTER); - - } else if (property == priv->scale_property) { - if (connector->dpms != DRM_MODE_DPMS_OFF) - return -EINVAL; - - priv->scale = val; - - modes_changed = true; - - } else { - return -EINVAL; - } - - if (modes_changed) { - drm_helper_probe_single_connector_modes(connector, 0, 0); - - /* Disable the crtc to ensure a full modeset is - * performed whenever it's turned on again. */ - if (crtc) { - struct drm_mode_set modeset = { - .crtc = crtc, - }; - - crtc->funcs->set_config(&modeset); - } - } - - return 0; -} - -static struct drm_encoder_slave_funcs ch7006_encoder_funcs = { - .set_config = ch7006_encoder_set_config, - .destroy = ch7006_encoder_destroy, - .dpms = ch7006_encoder_dpms, - .save = ch7006_encoder_save, - .restore = ch7006_encoder_restore, - .mode_fixup = ch7006_encoder_mode_fixup, - .mode_valid = ch7006_encoder_mode_valid, - .mode_set = ch7006_encoder_mode_set, - .detect = ch7006_encoder_detect, - .get_modes = ch7006_encoder_get_modes, - .create_resources = ch7006_encoder_create_resources, - .set_property = ch7006_encoder_set_property, -}; - - -/* I2C driver functions */ - -static int ch7006_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - uint8_t addr = CH7006_VERSION_ID; - uint8_t val; - int ret; - - ch7006_dbg(client, "\n"); - - ret = i2c_master_send(client, &addr, sizeof(addr)); - if (ret < 0) - goto fail; - - ret = i2c_master_recv(client, &val, sizeof(val)); - if (ret < 0) - goto fail; - - ch7006_info(client, "Detected version ID: %x\n", val); - - /* I don't know what this is for, but otherwise I get no - * signal. - */ - ch7006_write(client, 0x3d, 0x0); - - return 0; - -fail: - ch7006_err(client, "Error %d reading version ID\n", ret); - - return -ENODEV; -} - -static int ch7006_remove(struct i2c_client *client) -{ - ch7006_dbg(client, "\n"); - - return 0; -} - -static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg) -{ - ch7006_dbg(client, "\n"); - - return 0; -} - -static int ch7006_resume(struct i2c_client *client) -{ - ch7006_dbg(client, "\n"); - - ch7006_write(client, 0x3d, 0x0); - - return 0; -} - -static int ch7006_encoder_init(struct i2c_client *client, - struct drm_device *dev, - struct drm_encoder_slave *encoder) -{ - struct ch7006_priv *priv; - int i; - - ch7006_dbg(client, "\n"); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - encoder->slave_priv = priv; - encoder->slave_funcs = &ch7006_encoder_funcs; - - priv->norm = TV_NORM_PAL; - priv->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic; - priv->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; - priv->scale = 1; - priv->contrast = 50; - priv->brightness = 50; - priv->flicker = 50; - priv->hmargin = 50; - priv->vmargin = 50; - priv->last_dpms = -1; - priv->chip_version = ch7006_read(client, CH7006_VERSION_ID); - - if (ch7006_tv_norm) { - for (i = 0; i < NUM_TV_NORMS; i++) { - if (!strcmp(ch7006_tv_norm_names[i], ch7006_tv_norm)) { - priv->norm = i; - break; - } - } - - if (i == NUM_TV_NORMS) - ch7006_err(client, "Invalid TV norm setting \"%s\".\n", - ch7006_tv_norm); - } - - if (ch7006_scale >= 0 && ch7006_scale <= 2) - priv->scale = ch7006_scale; - else - ch7006_err(client, "Invalid scale setting \"%d\".\n", - ch7006_scale); - - return 0; -} - -static struct i2c_device_id ch7006_ids[] = { - { "ch7006", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ch7006_ids); - -static struct drm_i2c_encoder_driver ch7006_driver = { - .i2c_driver = { - .probe = ch7006_probe, - .remove = ch7006_remove, - .suspend = ch7006_suspend, - .resume = ch7006_resume, - - .driver = { - .name = "ch7006", - }, - - .id_table = ch7006_ids, - }, - - .encoder_init = ch7006_encoder_init, -}; - - -/* Module initialization */ - -static int __init ch7006_init(void) -{ - return drm_i2c_encoder_register(THIS_MODULE, &ch7006_driver); -} - -static void __exit ch7006_exit(void) -{ - drm_i2c_encoder_unregister(&ch7006_driver); -} - -int ch7006_debug; -module_param_named(debug, ch7006_debug, int, 0600); -MODULE_PARM_DESC(debug, "Enable debug output."); - -char *ch7006_tv_norm; -module_param_named(tv_norm, ch7006_tv_norm, charp, 0600); -MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" - "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, PAL-60, NTSC-M, NTSC-J.\n" - "\t\tDefault: PAL"); - -int ch7006_scale = 1; -module_param_named(scale, ch7006_scale, int, 0600); -MODULE_PARM_DESC(scale, "Default scale.\n" - "\t\tSupported: 0 -> Select video modes with a higher blanking ratio.\n" - "\t\t\t1 -> Select default video modes.\n" - "\t\t\t2 -> Select video modes with a lower blanking ratio."); - -MODULE_AUTHOR("Francisco Jerez "); -MODULE_DESCRIPTION("Chrontel ch7006 TV encoder driver"); -MODULE_LICENSE("GPL and additional rights"); - -module_init(ch7006_init); -module_exit(ch7006_exit); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_mode.c b/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_mode.c deleted file mode 100644 index c860f24a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_mode.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "ch7006_priv.h" - -char *ch7006_tv_norm_names[] = { - [TV_NORM_PAL] = "PAL", - [TV_NORM_PAL_M] = "PAL-M", - [TV_NORM_PAL_N] = "PAL-N", - [TV_NORM_PAL_NC] = "PAL-Nc", - [TV_NORM_PAL_60] = "PAL-60", - [TV_NORM_NTSC_M] = "NTSC-M", - [TV_NORM_NTSC_J] = "NTSC-J", -}; - -#define NTSC_LIKE_TIMINGS .vrefresh = 60 * fixed1/1.001, \ - .vdisplay = 480, \ - .vtotal = 525, \ - .hvirtual = 660 - -#define PAL_LIKE_TIMINGS .vrefresh = 50 * fixed1, \ - .vdisplay = 576, \ - .vtotal = 625, \ - .hvirtual = 810 - -struct ch7006_tv_norm_info ch7006_tv_norms[] = { - [TV_NORM_NTSC_M] = { - NTSC_LIKE_TIMINGS, - .black_level = 0.339 * fixed1, - .subc_freq = 3579545 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC), - .voffset = 0, - }, - [TV_NORM_NTSC_J] = { - NTSC_LIKE_TIMINGS, - .black_level = 0.286 * fixed1, - .subc_freq = 3579545 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, NTSC_J), - .voffset = 0, - }, - [TV_NORM_PAL] = { - PAL_LIKE_TIMINGS, - .black_level = 0.3 * fixed1, - .subc_freq = 4433618.75 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL), - .voffset = 0, - }, - [TV_NORM_PAL_M] = { - NTSC_LIKE_TIMINGS, - .black_level = 0.339 * fixed1, - .subc_freq = 3575611.433 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M), - .voffset = 16, - }, - - /* The following modes seem to work right but they're - * undocumented */ - - [TV_NORM_PAL_N] = { - PAL_LIKE_TIMINGS, - .black_level = 0.339 * fixed1, - .subc_freq = 4433618.75 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL), - .voffset = 0, - }, - [TV_NORM_PAL_NC] = { - PAL_LIKE_TIMINGS, - .black_level = 0.3 * fixed1, - .subc_freq = 3582056.25 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL), - .voffset = 0, - }, - [TV_NORM_PAL_60] = { - NTSC_LIKE_TIMINGS, - .black_level = 0.3 * fixed1, - .subc_freq = 4433618.75 * fixed1, - .dispmode = bitfs(CH7006_DISPMODE_OUTPUT_STD, PAL_M), - .voffset = 16, - }, -}; - -#define __MODE(f, hd, vd, ht, vt, hsynp, vsynp, \ - subc, scale, scale_mask, norm_mask, e_hd, e_vd) { \ - .mode = { \ - .name = #hd "x" #vd, \ - .status = 0, \ - .type = DRM_MODE_TYPE_DRIVER, \ - .clock = f, \ - .hdisplay = hd, \ - .hsync_start = e_hd + 16, \ - .hsync_end = e_hd + 80, \ - .htotal = ht, \ - .hskew = 0, \ - .vdisplay = vd, \ - .vsync_start = vd + 10, \ - .vsync_end = vd + 26, \ - .vtotal = vt, \ - .vscan = 0, \ - .flags = DRM_MODE_FLAG_##hsynp##HSYNC | \ - DRM_MODE_FLAG_##vsynp##VSYNC, \ - .vrefresh = 0, \ - }, \ - .enc_hdisp = e_hd, \ - .enc_vdisp = e_vd, \ - .subc_coeff = subc * fixed1, \ - .dispmode = bitfs(CH7006_DISPMODE_SCALING_RATIO, scale) | \ - bitfs(CH7006_DISPMODE_INPUT_RES, e_hd##x##e_vd), \ - .valid_scales = scale_mask, \ - .valid_norms = norm_mask \ - } - -#define MODE(f, hd, vd, ht, vt, hsynp, vsynp, \ - subc, scale, scale_mask, norm_mask) \ - __MODE(f, hd, vd, ht, vt, hsynp, vsynp, subc, scale, \ - scale_mask, norm_mask, hd, vd) - -#define NTSC_LIKE (1 << TV_NORM_NTSC_M | 1 << TV_NORM_NTSC_J | \ - 1 << TV_NORM_PAL_M | 1 << TV_NORM_PAL_60) - -#define PAL_LIKE (1 << TV_NORM_PAL | 1 << TV_NORM_PAL_N | 1 << TV_NORM_PAL_NC) - -struct ch7006_mode ch7006_modes[] = { - MODE(21000, 512, 384, 840, 500, N, N, 181.797557582, 5_4, 0x6, PAL_LIKE), - MODE(26250, 512, 384, 840, 625, N, N, 145.438046066, 1_1, 0x1, PAL_LIKE), - MODE(20140, 512, 384, 800, 420, N, N, 213.257083791, 5_4, 0x4, NTSC_LIKE), - MODE(24671, 512, 384, 784, 525, N, N, 174.0874153, 1_1, 0x3, NTSC_LIKE), - MODE(28125, 720, 400, 1125, 500, N, N, 135.742176298, 5_4, 0x6, PAL_LIKE), - MODE(34875, 720, 400, 1116, 625, N, N, 109.469496898, 1_1, 0x1, PAL_LIKE), - MODE(23790, 720, 400, 945, 420, N, N, 160.475642016, 5_4, 0x4, NTSC_LIKE), - MODE(29455, 720, 400, 936, 525, N, N, 129.614941843, 1_1, 0x3, NTSC_LIKE), - MODE(25000, 640, 400, 1000, 500, N, N, 152.709948279, 5_4, 0x6, PAL_LIKE), - MODE(31500, 640, 400, 1008, 625, N, N, 121.198371646, 1_1, 0x1, PAL_LIKE), - MODE(21147, 640, 400, 840, 420, N, N, 180.535097338, 5_4, 0x4, NTSC_LIKE), - MODE(26434, 640, 400, 840, 525, N, N, 144.42807787, 1_1, 0x2, NTSC_LIKE), - MODE(30210, 640, 400, 840, 600, N, N, 126.374568276, 7_8, 0x1, NTSC_LIKE), - MODE(21000, 640, 480, 840, 500, N, N, 181.797557582, 5_4, 0x4, PAL_LIKE), - MODE(26250, 640, 480, 840, 625, N, N, 145.438046066, 1_1, 0x2, PAL_LIKE), - MODE(31500, 640, 480, 840, 750, N, N, 121.198371646, 5_6, 0x1, PAL_LIKE), - MODE(24671, 640, 480, 784, 525, N, N, 174.0874153, 1_1, 0x4, NTSC_LIKE), - MODE(28196, 640, 480, 784, 600, N, N, 152.326488422, 7_8, 0x2, NTSC_LIKE), - MODE(30210, 640, 480, 800, 630, N, N, 142.171389101, 5_6, 0x1, NTSC_LIKE), - __MODE(29500, 720, 576, 944, 625, P, P, 145.592111636, 1_1, 0x7, PAL_LIKE, 800, 600), - MODE(36000, 800, 600, 960, 750, P, P, 119.304647022, 5_6, 0x6, PAL_LIKE), - MODE(39000, 800, 600, 936, 836, P, P, 110.127366499, 3_4, 0x1, PAL_LIKE), - MODE(39273, 800, 600, 1040, 630, P, P, 145.816809399, 5_6, 0x4, NTSC_LIKE), - MODE(43636, 800, 600, 1040, 700, P, P, 131.235128487, 3_4, 0x2, NTSC_LIKE), - MODE(47832, 800, 600, 1064, 750, P, P, 119.723275165, 7_10, 0x1, NTSC_LIKE), - {} -}; - -struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, - struct drm_display_mode *drm_mode) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_mode *mode; - - for (mode = ch7006_modes; mode->mode.clock; mode++) { - - if (~mode->valid_norms & 1<norm) - continue; - - if (mode->mode.hdisplay != drm_mode->hdisplay || - mode->mode.vdisplay != drm_mode->vdisplay || - mode->mode.vtotal != drm_mode->vtotal || - mode->mode.htotal != drm_mode->htotal || - mode->mode.clock != drm_mode->clock) - continue; - - return mode; - } - - return NULL; -} - -/* Some common HW state calculation code */ - -void ch7006_setup_levels(struct drm_encoder *encoder) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - uint8_t *regs = priv->state.regs; - struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; - int gain; - int black_level; - - /* Set DAC_GAIN if the voltage drop between white and black is - * high enough. */ - if (norm->black_level < 339*fixed1/1000) { - gain = 76; - - regs[CH7006_INPUT_FORMAT] |= CH7006_INPUT_FORMAT_DAC_GAIN; - } else { - gain = 71; - - regs[CH7006_INPUT_FORMAT] &= ~CH7006_INPUT_FORMAT_DAC_GAIN; - } - - black_level = round_fixed(norm->black_level*26625)/gain; - - /* Correct it with the specified brightness. */ - black_level = interpolate(90, black_level, 208, priv->brightness); - - regs[CH7006_BLACK_LEVEL] = bitf(CH7006_BLACK_LEVEL_0, black_level); - - ch7006_dbg(client, "black level: %d\n", black_level); -} - -void ch7006_setup_subcarrier(struct drm_encoder *encoder) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_state *state = &priv->state; - struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; - struct ch7006_mode *mode = priv->mode; - uint32_t subc_inc; - - subc_inc = round_fixed((mode->subc_coeff >> 8) - * (norm->subc_freq >> 24)); - - setbitf(state, CH7006_SUBC_INC0, 28, subc_inc); - setbitf(state, CH7006_SUBC_INC1, 24, subc_inc); - setbitf(state, CH7006_SUBC_INC2, 20, subc_inc); - setbitf(state, CH7006_SUBC_INC3, 16, subc_inc); - setbitf(state, CH7006_SUBC_INC4, 12, subc_inc); - setbitf(state, CH7006_SUBC_INC5, 8, subc_inc); - setbitf(state, CH7006_SUBC_INC6, 4, subc_inc); - setbitf(state, CH7006_SUBC_INC7, 0, subc_inc); - - ch7006_dbg(client, "subcarrier inc: %u\n", subc_inc); -} - -void ch7006_setup_pll(struct drm_encoder *encoder) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - uint8_t *regs = priv->state.regs; - struct ch7006_mode *mode = priv->mode; - int n, best_n = 0; - int m, best_m = 0; - int freq, best_freq = 0; - - for (n = 0; n < CH7006_MAXN; n++) { - for (m = 0; m < CH7006_MAXM; m++) { - freq = CH7006_FREQ0*(n+2)/(m+2); - - if (abs(freq - mode->mode.clock) < - abs(best_freq - mode->mode.clock)) { - best_freq = freq; - best_n = n; - best_m = m; - } - } - } - - regs[CH7006_PLLOV] = bitf(CH7006_PLLOV_N_8, best_n) | - bitf(CH7006_PLLOV_M_8, best_m); - - regs[CH7006_PLLM] = bitf(CH7006_PLLM_0, best_m); - regs[CH7006_PLLN] = bitf(CH7006_PLLN_0, best_n); - - if (best_n < 108) - regs[CH7006_PLL_CONTROL] |= CH7006_PLL_CONTROL_CAPACITOR; - else - regs[CH7006_PLL_CONTROL] &= ~CH7006_PLL_CONTROL_CAPACITOR; - - ch7006_dbg(client, "n=%d m=%d f=%d c=%d\n", - best_n, best_m, best_freq, best_n < 108); -} - -void ch7006_setup_power_state(struct drm_encoder *encoder) -{ - struct ch7006_priv *priv = to_ch7006_priv(encoder); - uint8_t *power = &priv->state.regs[CH7006_POWER]; - int subconnector; - - subconnector = priv->select_subconnector ? priv->select_subconnector : - priv->subconnector; - - *power = CH7006_POWER_RESET; - - if (priv->last_dpms == DRM_MODE_DPMS_ON) { - switch (subconnector) { - case DRM_MODE_SUBCONNECTOR_SVIDEO: - *power |= bitfs(CH7006_POWER_LEVEL, CVBS_OFF); - break; - case DRM_MODE_SUBCONNECTOR_Composite: - *power |= bitfs(CH7006_POWER_LEVEL, SVIDEO_OFF); - break; - case DRM_MODE_SUBCONNECTOR_SCART: - *power |= bitfs(CH7006_POWER_LEVEL, NORMAL) | - CH7006_POWER_SCART; - break; - } - - } else { - if (priv->chip_version >= 0x20) - *power |= bitfs(CH7006_POWER_LEVEL, FULL_POWER_OFF); - else - *power |= bitfs(CH7006_POWER_LEVEL, POWER_OFF); - } -} - -void ch7006_setup_properties(struct drm_encoder *encoder) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - struct ch7006_priv *priv = to_ch7006_priv(encoder); - struct ch7006_state *state = &priv->state; - struct ch7006_tv_norm_info *norm = &ch7006_tv_norms[priv->norm]; - struct ch7006_mode *ch_mode = priv->mode; - struct drm_display_mode *mode = &ch_mode->mode; - uint8_t *regs = state->regs; - int flicker, contrast, hpos, vpos; - uint64_t scale, aspect; - - flicker = interpolate(0, 2, 3, priv->flicker); - regs[CH7006_FFILTER] = bitf(CH7006_FFILTER_TEXT, flicker) | - bitf(CH7006_FFILTER_LUMA, flicker) | - bitf(CH7006_FFILTER_CHROMA, 1); - - contrast = interpolate(0, 5, 7, priv->contrast); - regs[CH7006_CONTRAST] = bitf(CH7006_CONTRAST_0, contrast); - - scale = norm->vtotal*fixed1; - do_div(scale, mode->vtotal); - - aspect = ch_mode->enc_hdisp*fixed1; - do_div(aspect, ch_mode->enc_vdisp); - - hpos = round_fixed((norm->hvirtual * aspect - mode->hdisplay * scale) - * priv->hmargin * mode->vtotal) / norm->vtotal / 100 / 4; - - setbitf(state, CH7006_POV, HPOS_8, hpos); - setbitf(state, CH7006_HPOS, 0, hpos); - - vpos = max(0, norm->vdisplay - round_fixed(mode->vdisplay*scale) - + norm->voffset) * priv->vmargin / 100 / 2; - - setbitf(state, CH7006_POV, VPOS_8, vpos); - setbitf(state, CH7006_VPOS, 0, vpos); - - ch7006_dbg(client, "hpos: %d, vpos: %d\n", hpos, vpos); -} - -/* HW access functions */ - -void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val) -{ - uint8_t buf[] = {addr, val}; - int ret; - - ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); - if (ret < 0) - ch7006_err(client, "Error %d writing to subaddress 0x%x\n", - ret, addr); -} - -uint8_t ch7006_read(struct i2c_client *client, uint8_t addr) -{ - uint8_t val; - int ret; - - ret = i2c_master_send(client, &addr, sizeof(addr)); - if (ret < 0) - goto fail; - - ret = i2c_master_recv(client, &val, sizeof(val)); - if (ret < 0) - goto fail; - - return val; - -fail: - ch7006_err(client, "Error %d reading from subaddress 0x%x\n", - ret, addr); - return 0; -} - -void ch7006_state_load(struct i2c_client *client, - struct ch7006_state *state) -{ - ch7006_load_reg(client, state, CH7006_POWER); - - ch7006_load_reg(client, state, CH7006_DISPMODE); - ch7006_load_reg(client, state, CH7006_FFILTER); - ch7006_load_reg(client, state, CH7006_BWIDTH); - ch7006_load_reg(client, state, CH7006_INPUT_FORMAT); - ch7006_load_reg(client, state, CH7006_CLKMODE); - ch7006_load_reg(client, state, CH7006_START_ACTIVE); - ch7006_load_reg(client, state, CH7006_POV); - ch7006_load_reg(client, state, CH7006_BLACK_LEVEL); - ch7006_load_reg(client, state, CH7006_HPOS); - ch7006_load_reg(client, state, CH7006_VPOS); - ch7006_load_reg(client, state, CH7006_INPUT_SYNC); - ch7006_load_reg(client, state, CH7006_DETECT); - ch7006_load_reg(client, state, CH7006_CONTRAST); - ch7006_load_reg(client, state, CH7006_PLLOV); - ch7006_load_reg(client, state, CH7006_PLLM); - ch7006_load_reg(client, state, CH7006_PLLN); - ch7006_load_reg(client, state, CH7006_BCLKOUT); - ch7006_load_reg(client, state, CH7006_SUBC_INC0); - ch7006_load_reg(client, state, CH7006_SUBC_INC1); - ch7006_load_reg(client, state, CH7006_SUBC_INC2); - ch7006_load_reg(client, state, CH7006_SUBC_INC3); - ch7006_load_reg(client, state, CH7006_SUBC_INC4); - ch7006_load_reg(client, state, CH7006_SUBC_INC5); - ch7006_load_reg(client, state, CH7006_SUBC_INC6); - ch7006_load_reg(client, state, CH7006_SUBC_INC7); - ch7006_load_reg(client, state, CH7006_PLL_CONTROL); - ch7006_load_reg(client, state, CH7006_CALC_SUBC_INC0); -} - -void ch7006_state_save(struct i2c_client *client, - struct ch7006_state *state) -{ - ch7006_save_reg(client, state, CH7006_POWER); - - ch7006_save_reg(client, state, CH7006_DISPMODE); - ch7006_save_reg(client, state, CH7006_FFILTER); - ch7006_save_reg(client, state, CH7006_BWIDTH); - ch7006_save_reg(client, state, CH7006_INPUT_FORMAT); - ch7006_save_reg(client, state, CH7006_CLKMODE); - ch7006_save_reg(client, state, CH7006_START_ACTIVE); - ch7006_save_reg(client, state, CH7006_POV); - ch7006_save_reg(client, state, CH7006_BLACK_LEVEL); - ch7006_save_reg(client, state, CH7006_HPOS); - ch7006_save_reg(client, state, CH7006_VPOS); - ch7006_save_reg(client, state, CH7006_INPUT_SYNC); - ch7006_save_reg(client, state, CH7006_DETECT); - ch7006_save_reg(client, state, CH7006_CONTRAST); - ch7006_save_reg(client, state, CH7006_PLLOV); - ch7006_save_reg(client, state, CH7006_PLLM); - ch7006_save_reg(client, state, CH7006_PLLN); - ch7006_save_reg(client, state, CH7006_BCLKOUT); - ch7006_save_reg(client, state, CH7006_SUBC_INC0); - ch7006_save_reg(client, state, CH7006_SUBC_INC1); - ch7006_save_reg(client, state, CH7006_SUBC_INC2); - ch7006_save_reg(client, state, CH7006_SUBC_INC3); - ch7006_save_reg(client, state, CH7006_SUBC_INC4); - ch7006_save_reg(client, state, CH7006_SUBC_INC5); - ch7006_save_reg(client, state, CH7006_SUBC_INC6); - ch7006_save_reg(client, state, CH7006_SUBC_INC7); - ch7006_save_reg(client, state, CH7006_PLL_CONTROL); - ch7006_save_reg(client, state, CH7006_CALC_SUBC_INC0); - - state->regs[CH7006_FFILTER] = (state->regs[CH7006_FFILTER] & 0xf0) | - (state->regs[CH7006_FFILTER] & 0x0c) >> 2 | - (state->regs[CH7006_FFILTER] & 0x03) << 2; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_priv.h b/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_priv.h deleted file mode 100644 index 17667b7d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i2c/ch7006_priv.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __DRM_I2C_CH7006_PRIV_H__ -#define __DRM_I2C_CH7006_PRIV_H__ - -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "drm_encoder_slave.h" -#include "i2c/ch7006.h" - -typedef int64_t fixed; -#define fixed1 (1LL << 32) - -enum ch7006_tv_norm { - TV_NORM_PAL, - TV_NORM_PAL_M, - TV_NORM_PAL_N, - TV_NORM_PAL_NC, - TV_NORM_PAL_60, - TV_NORM_NTSC_M, - TV_NORM_NTSC_J, - NUM_TV_NORMS -}; - -struct ch7006_tv_norm_info { - fixed vrefresh; - int vdisplay; - int vtotal; - int hvirtual; - - fixed subc_freq; - fixed black_level; - - uint32_t dispmode; - int voffset; -}; - -struct ch7006_mode { - struct drm_display_mode mode; - - int enc_hdisp; - int enc_vdisp; - - fixed subc_coeff; - uint32_t dispmode; - - uint32_t valid_scales; - uint32_t valid_norms; -}; - -struct ch7006_state { - uint8_t regs[0x26]; -}; - -struct ch7006_priv { - struct ch7006_encoder_params params; - struct ch7006_mode *mode; - - struct ch7006_state state; - struct ch7006_state saved_state; - - struct drm_property *scale_property; - - int select_subconnector; - int subconnector; - int hmargin; - int vmargin; - enum ch7006_tv_norm norm; - int brightness; - int contrast; - int flicker; - int scale; - - int chip_version; - int last_dpms; -}; - -#define to_ch7006_priv(x) \ - ((struct ch7006_priv *)to_encoder_slave(x)->slave_priv) - -extern int ch7006_debug; -extern char *ch7006_tv_norm; -extern int ch7006_scale; - -extern char *ch7006_tv_norm_names[]; -extern struct ch7006_tv_norm_info ch7006_tv_norms[]; -extern struct ch7006_mode ch7006_modes[]; - -struct ch7006_mode *ch7006_lookup_mode(struct drm_encoder *encoder, - struct drm_display_mode *drm_mode); - -void ch7006_setup_levels(struct drm_encoder *encoder); -void ch7006_setup_subcarrier(struct drm_encoder *encoder); -void ch7006_setup_pll(struct drm_encoder *encoder); -void ch7006_setup_power_state(struct drm_encoder *encoder); -void ch7006_setup_properties(struct drm_encoder *encoder); - -void ch7006_write(struct i2c_client *client, uint8_t addr, uint8_t val); -uint8_t ch7006_read(struct i2c_client *client, uint8_t addr); - -void ch7006_state_load(struct i2c_client *client, - struct ch7006_state *state); -void ch7006_state_save(struct i2c_client *client, - struct ch7006_state *state); - -/* Some helper macros */ - -#define ch7006_dbg(client, format, ...) do { \ - if (ch7006_debug) \ - dev_printk(KERN_DEBUG, &client->dev, \ - "%s: " format, __func__, ## __VA_ARGS__); \ - } while (0) -#define ch7006_info(client, format, ...) \ - dev_info(&client->dev, format, __VA_ARGS__) -#define ch7006_err(client, format, ...) \ - dev_err(&client->dev, format, __VA_ARGS__) - -#define __mask(src, bitfield) \ - (((2 << (1 ? bitfield)) - 1) & ~((1 << (0 ? bitfield)) - 1)) -#define mask(bitfield) __mask(bitfield) - -#define __bitf(src, bitfield, x) \ - (((x) >> (src) << (0 ? bitfield)) & __mask(src, bitfield)) -#define bitf(bitfield, x) __bitf(bitfield, x) -#define bitfs(bitfield, s) __bitf(bitfield, bitfield##_##s) -#define setbitf(state, reg, bitfield, x) \ - state->regs[reg] = (state->regs[reg] & ~mask(reg##_##bitfield)) \ - | bitf(reg##_##bitfield, x) - -#define __unbitf(src, bitfield, x) \ - ((x & __mask(src, bitfield)) >> (0 ? bitfield) << (src)) -#define unbitf(bitfield, x) __unbitf(bitfield, x) - -static inline int interpolate(int y0, int y1, int y2, int x) -{ - return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50; -} - -static inline int32_t round_fixed(fixed x) -{ - return (x + fixed1/2) >> 32; -} - -#define ch7006_load_reg(client, state, reg) ch7006_write(client, reg, state->regs[reg]) -#define ch7006_save_reg(client, state, reg) state->regs[reg] = ch7006_read(client, reg) - -/* Fixed hardware specs */ - -#define CH7006_FREQ0 14318 -#define CH7006_MAXN 650 -#define CH7006_MAXM 315 - -/* Register definitions */ - -#define CH7006_DISPMODE 0x00 -#define CH7006_DISPMODE_INPUT_RES 0, 7:5 -#define CH7006_DISPMODE_INPUT_RES_512x384 0x0 -#define CH7006_DISPMODE_INPUT_RES_720x400 0x1 -#define CH7006_DISPMODE_INPUT_RES_640x400 0x2 -#define CH7006_DISPMODE_INPUT_RES_640x480 0x3 -#define CH7006_DISPMODE_INPUT_RES_800x600 0x4 -#define CH7006_DISPMODE_INPUT_RES_NATIVE 0x5 -#define CH7006_DISPMODE_OUTPUT_STD 0, 4:3 -#define CH7006_DISPMODE_OUTPUT_STD_PAL 0x0 -#define CH7006_DISPMODE_OUTPUT_STD_NTSC 0x1 -#define CH7006_DISPMODE_OUTPUT_STD_PAL_M 0x2 -#define CH7006_DISPMODE_OUTPUT_STD_NTSC_J 0x3 -#define CH7006_DISPMODE_SCALING_RATIO 0, 2:0 -#define CH7006_DISPMODE_SCALING_RATIO_5_4 0x0 -#define CH7006_DISPMODE_SCALING_RATIO_1_1 0x1 -#define CH7006_DISPMODE_SCALING_RATIO_7_8 0x2 -#define CH7006_DISPMODE_SCALING_RATIO_5_6 0x3 -#define CH7006_DISPMODE_SCALING_RATIO_3_4 0x4 -#define CH7006_DISPMODE_SCALING_RATIO_7_10 0x5 - -#define CH7006_FFILTER 0x01 -#define CH7006_FFILTER_TEXT 0, 5:4 -#define CH7006_FFILTER_LUMA 0, 3:2 -#define CH7006_FFILTER_CHROMA 0, 1:0 -#define CH7006_FFILTER_CHROMA_NO_DCRAWL 0x3 - -#define CH7006_BWIDTH 0x03 -#define CH7006_BWIDTH_5L_FFILER (1 << 7) -#define CH7006_BWIDTH_CVBS_NO_CHROMA (1 << 6) -#define CH7006_BWIDTH_CHROMA 0, 5:4 -#define CH7006_BWIDTH_SVIDEO_YPEAK (1 << 3) -#define CH7006_BWIDTH_SVIDEO_LUMA 0, 2:1 -#define CH7006_BWIDTH_CVBS_LUMA 0, 0:0 - -#define CH7006_INPUT_FORMAT 0x04 -#define CH7006_INPUT_FORMAT_DAC_GAIN (1 << 6) -#define CH7006_INPUT_FORMAT_RGB_PASS_THROUGH (1 << 5) -#define CH7006_INPUT_FORMAT_FORMAT 0, 3:0 -#define CH7006_INPUT_FORMAT_FORMAT_RGB16 0x0 -#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m16 0x1 -#define CH7006_INPUT_FORMAT_FORMAT_RGB24m16 0x2 -#define CH7006_INPUT_FORMAT_FORMAT_RGB15 0x3 -#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12C 0x4 -#define CH7006_INPUT_FORMAT_FORMAT_RGB24m12I 0x5 -#define CH7006_INPUT_FORMAT_FORMAT_RGB24m8 0x6 -#define CH7006_INPUT_FORMAT_FORMAT_RGB16m8 0x7 -#define CH7006_INPUT_FORMAT_FORMAT_RGB15m8 0x8 -#define CH7006_INPUT_FORMAT_FORMAT_YCrCb24m8 0x9 - -#define CH7006_CLKMODE 0x06 -#define CH7006_CLKMODE_SUBC_LOCK (1 << 7) -#define CH7006_CLKMODE_MASTER (1 << 6) -#define CH7006_CLKMODE_POS_EDGE (1 << 4) -#define CH7006_CLKMODE_XCM 0, 3:2 -#define CH7006_CLKMODE_PCM 0, 1:0 - -#define CH7006_START_ACTIVE 0x07 -#define CH7006_START_ACTIVE_0 0, 7:0 - -#define CH7006_POV 0x08 -#define CH7006_POV_START_ACTIVE_8 8, 2:2 -#define CH7006_POV_HPOS_8 8, 1:1 -#define CH7006_POV_VPOS_8 8, 0:0 - -#define CH7006_BLACK_LEVEL 0x09 -#define CH7006_BLACK_LEVEL_0 0, 7:0 - -#define CH7006_HPOS 0x0a -#define CH7006_HPOS_0 0, 7:0 - -#define CH7006_VPOS 0x0b -#define CH7006_VPOS_0 0, 7:0 - -#define CH7006_INPUT_SYNC 0x0d -#define CH7006_INPUT_SYNC_EMBEDDED (1 << 3) -#define CH7006_INPUT_SYNC_OUTPUT (1 << 2) -#define CH7006_INPUT_SYNC_PVSYNC (1 << 1) -#define CH7006_INPUT_SYNC_PHSYNC (1 << 0) - -#define CH7006_POWER 0x0e -#define CH7006_POWER_SCART (1 << 4) -#define CH7006_POWER_RESET (1 << 3) -#define CH7006_POWER_LEVEL 0, 2:0 -#define CH7006_POWER_LEVEL_CVBS_OFF 0x0 -#define CH7006_POWER_LEVEL_POWER_OFF 0x1 -#define CH7006_POWER_LEVEL_SVIDEO_OFF 0x2 -#define CH7006_POWER_LEVEL_NORMAL 0x3 -#define CH7006_POWER_LEVEL_FULL_POWER_OFF 0x4 - -#define CH7006_DETECT 0x10 -#define CH7006_DETECT_SVIDEO_Y_TEST (1 << 3) -#define CH7006_DETECT_SVIDEO_C_TEST (1 << 2) -#define CH7006_DETECT_CVBS_TEST (1 << 1) -#define CH7006_DETECT_SENSE (1 << 0) - -#define CH7006_CONTRAST 0x11 -#define CH7006_CONTRAST_0 0, 2:0 - -#define CH7006_PLLOV 0x13 -#define CH7006_PLLOV_N_8 8, 2:1 -#define CH7006_PLLOV_M_8 8, 0:0 - -#define CH7006_PLLM 0x14 -#define CH7006_PLLM_0 0, 7:0 - -#define CH7006_PLLN 0x15 -#define CH7006_PLLN_0 0, 7:0 - -#define CH7006_BCLKOUT 0x17 - -#define CH7006_SUBC_INC0 0x18 -#define CH7006_SUBC_INC0_28 28, 3:0 - -#define CH7006_SUBC_INC1 0x19 -#define CH7006_SUBC_INC1_24 24, 3:0 - -#define CH7006_SUBC_INC2 0x1a -#define CH7006_SUBC_INC2_20 20, 3:0 - -#define CH7006_SUBC_INC3 0x1b -#define CH7006_SUBC_INC3_GPIO1_VAL (1 << 7) -#define CH7006_SUBC_INC3_GPIO0_VAL (1 << 6) -#define CH7006_SUBC_INC3_POUT_3_3V (1 << 5) -#define CH7006_SUBC_INC3_POUT_INV (1 << 4) -#define CH7006_SUBC_INC3_16 16, 3:0 - -#define CH7006_SUBC_INC4 0x1c -#define CH7006_SUBC_INC4_GPIO1_IN (1 << 7) -#define CH7006_SUBC_INC4_GPIO0_IN (1 << 6) -#define CH7006_SUBC_INC4_DS_INPUT (1 << 4) -#define CH7006_SUBC_INC4_12 12, 3:0 - -#define CH7006_SUBC_INC5 0x1d -#define CH7006_SUBC_INC5_8 8, 3:0 - -#define CH7006_SUBC_INC6 0x1e -#define CH7006_SUBC_INC6_4 4, 3:0 - -#define CH7006_SUBC_INC7 0x1f -#define CH7006_SUBC_INC7_0 0, 3:0 - -#define CH7006_PLL_CONTROL 0x20 -#define CH7006_PLL_CONTROL_CPI (1 << 5) -#define CH7006_PLL_CONTROL_CAPACITOR (1 << 4) -#define CH7006_PLL_CONTROL_7STAGES (1 << 3) -#define CH7006_PLL_CONTROL_DIGITAL_5V (1 << 2) -#define CH7006_PLL_CONTROL_ANALOG_5V (1 << 1) -#define CH7006_PLL_CONTROL_MEMORY_5V (1 << 0) - -#define CH7006_CALC_SUBC_INC0 0x21 -#define CH7006_CALC_SUBC_INC0_24 24, 4:3 -#define CH7006_CALC_SUBC_INC0_HYST 0, 2:1 -#define CH7006_CALC_SUBC_INC0_AUTO (1 << 0) - -#define CH7006_CALC_SUBC_INC1 0x22 -#define CH7006_CALC_SUBC_INC1_16 16, 7:0 - -#define CH7006_CALC_SUBC_INC2 0x23 -#define CH7006_CALC_SUBC_INC2_8 8, 7:0 - -#define CH7006_CALC_SUBC_INC3 0x24 -#define CH7006_CALC_SUBC_INC3_0 0, 7:0 - -#define CH7006_VERSION_ID 0x25 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i2c/sil164_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/i2c/sil164_drv.c deleted file mode 100644 index b7d45ab4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i2c/sil164_drv.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (C) 2010 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include - -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "drm_encoder_slave.h" -#include "i2c/sil164.h" - -struct sil164_priv { - struct sil164_encoder_params config; - struct i2c_client *duallink_slave; - - uint8_t saved_state[0x10]; - uint8_t saved_slave_state[0x10]; -}; - -#define to_sil164_priv(x) \ - ((struct sil164_priv *)to_encoder_slave(x)->slave_priv) - -#define sil164_dbg(client, format, ...) do { \ - if (drm_debug & DRM_UT_KMS) \ - dev_printk(KERN_DEBUG, &client->dev, \ - "%s: " format, __func__, ## __VA_ARGS__); \ - } while (0) -#define sil164_info(client, format, ...) \ - dev_info(&client->dev, format, __VA_ARGS__) -#define sil164_err(client, format, ...) \ - dev_err(&client->dev, format, __VA_ARGS__) - -#define SIL164_I2C_ADDR_MASTER 0x38 -#define SIL164_I2C_ADDR_SLAVE 0x39 - -/* HW register definitions */ - -#define SIL164_VENDOR_LO 0x0 -#define SIL164_VENDOR_HI 0x1 -#define SIL164_DEVICE_LO 0x2 -#define SIL164_DEVICE_HI 0x3 -#define SIL164_REVISION 0x4 -#define SIL164_FREQ_MIN 0x6 -#define SIL164_FREQ_MAX 0x7 -#define SIL164_CONTROL0 0x8 -# define SIL164_CONTROL0_POWER_ON 0x01 -# define SIL164_CONTROL0_EDGE_RISING 0x02 -# define SIL164_CONTROL0_INPUT_24BIT 0x04 -# define SIL164_CONTROL0_DUAL_EDGE 0x08 -# define SIL164_CONTROL0_HSYNC_ON 0x10 -# define SIL164_CONTROL0_VSYNC_ON 0x20 -#define SIL164_DETECT 0x9 -# define SIL164_DETECT_INTR_STAT 0x01 -# define SIL164_DETECT_HOTPLUG_STAT 0x02 -# define SIL164_DETECT_RECEIVER_STAT 0x04 -# define SIL164_DETECT_INTR_MODE_RECEIVER 0x00 -# define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08 -# define SIL164_DETECT_OUT_MODE_HIGH 0x00 -# define SIL164_DETECT_OUT_MODE_INTR 0x10 -# define SIL164_DETECT_OUT_MODE_RECEIVER 0x20 -# define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30 -# define SIL164_DETECT_VSWING_STAT 0x80 -#define SIL164_CONTROL1 0xa -# define SIL164_CONTROL1_DESKEW_ENABLE 0x10 -# define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5 -#define SIL164_GPIO 0xb -#define SIL164_CONTROL2 0xc -# define SIL164_CONTROL2_FILTER_ENABLE 0x01 -# define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1 -# define SIL164_CONTROL2_DUALLINK_MASTER 0x40 -# define SIL164_CONTROL2_SYNC_CONT 0x80 -#define SIL164_DUALLINK 0xd -# define SIL164_DUALLINK_ENABLE 0x10 -# define SIL164_DUALLINK_SKEW_SHIFT 5 -#define SIL164_PLLZONE 0xe -# define SIL164_PLLZONE_STAT 0x08 -# define SIL164_PLLZONE_FORCE_ON 0x10 -# define SIL164_PLLZONE_FORCE_HIGH 0x20 - -/* HW access functions */ - -static void -sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val) -{ - uint8_t buf[] = {addr, val}; - int ret; - - ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); - if (ret < 0) - sil164_err(client, "Error %d writing to subaddress 0x%x\n", - ret, addr); -} - -static uint8_t -sil164_read(struct i2c_client *client, uint8_t addr) -{ - uint8_t val; - int ret; - - ret = i2c_master_send(client, &addr, sizeof(addr)); - if (ret < 0) - goto fail; - - ret = i2c_master_recv(client, &val, sizeof(val)); - if (ret < 0) - goto fail; - - return val; - -fail: - sil164_err(client, "Error %d reading from subaddress 0x%x\n", - ret, addr); - return 0; -} - -static void -sil164_save_state(struct i2c_client *client, uint8_t *state) -{ - int i; - - for (i = 0x8; i <= 0xe; i++) - state[i] = sil164_read(client, i); -} - -static void -sil164_restore_state(struct i2c_client *client, uint8_t *state) -{ - int i; - - for (i = 0x8; i <= 0xe; i++) - sil164_write(client, i, state[i]); -} - -static void -sil164_set_power_state(struct i2c_client *client, bool on) -{ - uint8_t control0 = sil164_read(client, SIL164_CONTROL0); - - if (on) - control0 |= SIL164_CONTROL0_POWER_ON; - else - control0 &= ~SIL164_CONTROL0_POWER_ON; - - sil164_write(client, SIL164_CONTROL0, control0); -} - -static void -sil164_init_state(struct i2c_client *client, - struct sil164_encoder_params *config, - bool duallink) -{ - sil164_write(client, SIL164_CONTROL0, - SIL164_CONTROL0_HSYNC_ON | - SIL164_CONTROL0_VSYNC_ON | - (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) | - (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) | - (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0)); - - sil164_write(client, SIL164_DETECT, - SIL164_DETECT_INTR_STAT | - SIL164_DETECT_OUT_MODE_RECEIVER); - - sil164_write(client, SIL164_CONTROL1, - (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) | - (((config->input_skew + 4) & 0x7) - << SIL164_CONTROL1_DESKEW_INCR_SHIFT)); - - sil164_write(client, SIL164_CONTROL2, - SIL164_CONTROL2_SYNC_CONT | - (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) | - (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT)); - - sil164_write(client, SIL164_PLLZONE, 0); - - if (duallink) - sil164_write(client, SIL164_DUALLINK, - SIL164_DUALLINK_ENABLE | - (((config->duallink_skew + 4) & 0x7) - << SIL164_DUALLINK_SKEW_SHIFT)); - else - sil164_write(client, SIL164_DUALLINK, 0); -} - -/* DRM encoder functions */ - -static void -sil164_encoder_set_config(struct drm_encoder *encoder, void *params) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - - priv->config = *(struct sil164_encoder_params *)params; -} - -static void -sil164_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - bool on = (mode == DRM_MODE_DPMS_ON); - bool duallink = (on && encoder->crtc->mode.clock > 165000); - - sil164_set_power_state(drm_i2c_encoder_get_client(encoder), on); - - if (priv->duallink_slave) - sil164_set_power_state(priv->duallink_slave, duallink); -} - -static void -sil164_encoder_save(struct drm_encoder *encoder) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - - sil164_save_state(drm_i2c_encoder_get_client(encoder), - priv->saved_state); - - if (priv->duallink_slave) - sil164_save_state(priv->duallink_slave, - priv->saved_slave_state); -} - -static void -sil164_encoder_restore(struct drm_encoder *encoder) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - - sil164_restore_state(drm_i2c_encoder_get_client(encoder), - priv->saved_state); - - if (priv->duallink_slave) - sil164_restore_state(priv->duallink_slave, - priv->saved_slave_state); -} - -static bool -sil164_encoder_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static int -sil164_encoder_mode_valid(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - - if (mode->clock < 32000) - return MODE_CLOCK_LOW; - - if (mode->clock > 330000 || - (mode->clock > 165000 && !priv->duallink_slave)) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static void -sil164_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - bool duallink = adjusted_mode->clock > 165000; - - sil164_init_state(drm_i2c_encoder_get_client(encoder), - &priv->config, duallink); - - if (priv->duallink_slave) - sil164_init_state(priv->duallink_slave, - &priv->config, duallink); - - sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON); -} - -static enum drm_connector_status -sil164_encoder_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); - - if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT) - return connector_status_connected; - else - return connector_status_disconnected; -} - -static int -sil164_encoder_get_modes(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - return 0; -} - -static int -sil164_encoder_create_resources(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - return 0; -} - -static int -sil164_encoder_set_property(struct drm_encoder *encoder, - struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - return 0; -} - -static void -sil164_encoder_destroy(struct drm_encoder *encoder) -{ - struct sil164_priv *priv = to_sil164_priv(encoder); - - if (priv->duallink_slave) - i2c_unregister_device(priv->duallink_slave); - - kfree(priv); - drm_i2c_encoder_destroy(encoder); -} - -static struct drm_encoder_slave_funcs sil164_encoder_funcs = { - .set_config = sil164_encoder_set_config, - .destroy = sil164_encoder_destroy, - .dpms = sil164_encoder_dpms, - .save = sil164_encoder_save, - .restore = sil164_encoder_restore, - .mode_fixup = sil164_encoder_mode_fixup, - .mode_valid = sil164_encoder_mode_valid, - .mode_set = sil164_encoder_mode_set, - .detect = sil164_encoder_detect, - .get_modes = sil164_encoder_get_modes, - .create_resources = sil164_encoder_create_resources, - .set_property = sil164_encoder_set_property, -}; - -/* I2C driver functions */ - -static int -sil164_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 | - sil164_read(client, SIL164_VENDOR_LO); - int device = sil164_read(client, SIL164_DEVICE_HI) << 8 | - sil164_read(client, SIL164_DEVICE_LO); - int rev = sil164_read(client, SIL164_REVISION); - - if (vendor != 0x1 || device != 0x6) { - sil164_dbg(client, "Unknown device %x:%x.%x\n", - vendor, device, rev); - return -ENODEV; - } - - sil164_info(client, "Detected device %x:%x.%x\n", - vendor, device, rev); - - return 0; -} - -static int -sil164_remove(struct i2c_client *client) -{ - return 0; -} - -static struct i2c_client * -sil164_detect_slave(struct i2c_client *client) -{ - struct i2c_adapter *adap = client->adapter; - struct i2c_msg msg = { - .addr = SIL164_I2C_ADDR_SLAVE, - .len = 0, - }; - const struct i2c_board_info info = { - I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE) - }; - - if (i2c_transfer(adap, &msg, 1) != 1) { - sil164_dbg(adap, "No dual-link slave found."); - return NULL; - } - - return i2c_new_device(adap, &info); -} - -static int -sil164_encoder_init(struct i2c_client *client, - struct drm_device *dev, - struct drm_encoder_slave *encoder) -{ - struct sil164_priv *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - encoder->slave_priv = priv; - encoder->slave_funcs = &sil164_encoder_funcs; - - priv->duallink_slave = sil164_detect_slave(client); - - return 0; -} - -static struct i2c_device_id sil164_ids[] = { - { "sil164", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sil164_ids); - -static struct drm_i2c_encoder_driver sil164_driver = { - .i2c_driver = { - .probe = sil164_probe, - .remove = sil164_remove, - .driver = { - .name = "sil164", - }, - .id_table = sil164_ids, - }, - .encoder_init = sil164_encoder_init, -}; - -/* Module initialization */ - -static int __init -sil164_init(void) -{ - return drm_i2c_encoder_register(THIS_MODULE, &sil164_driver); -} - -static void __exit -sil164_exit(void) -{ - drm_i2c_encoder_unregister(&sil164_driver); -} - -MODULE_AUTHOR("Francisco Jerez "); -MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver"); -MODULE_LICENSE("GPL and additional rights"); - -module_init(sil164_init); -module_exit(sil164_exit); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i810/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/i810/Makefile deleted file mode 100644 index 43844eca..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i810/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -i810-y := i810_drv.o i810_dma.o - -obj-$(CONFIG_DRM_I810) += i810.o diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_dma.c b/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_dma.c deleted file mode 100644 index f920fb5e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_dma.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* i810_dma.c -- DMA support for the i810 -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Rickard E. (Rik) Faith - * Jeff Hartmann - * Keith Whitwell - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i810_drm.h" -#include "i810_drv.h" -#include /* For task queue support */ -#include -#include -#include - -#define I810_BUF_FREE 2 -#define I810_BUF_CLIENT 1 -#define I810_BUF_HARDWARE 0 - -#define I810_BUF_UNMAPPED 0 -#define I810_BUF_MAPPED 1 - -static struct drm_buf *i810_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - int i; - int used; - - /* Linear search might not be the best solution */ - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, - I810_BUF_CLIENT); - if (used == I810_BUF_FREE) - return buf; - } - return NULL; -} - -/* This should only be called if the buffer is not sent to the hardware - * yet, the hardware updates in use for us once its on the ring buffer. - */ - -static int i810_freelist_put(struct drm_device *dev, struct drm_buf *buf) -{ - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - int used; - - /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); - if (used != I810_BUF_CLIENT) { - DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); - return -EINVAL; - } - - return 0; -} - -static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *priv = filp->private_data; - struct drm_device *dev; - drm_i810_private_t *dev_priv; - struct drm_buf *buf; - drm_i810_buf_priv_t *buf_priv; - - dev = priv->minor->dev; - dev_priv = dev->dev_private; - buf = dev_priv->mmap_buffer; - buf_priv = buf->dev_private; - - vma->vm_flags |= (VM_IO | VM_DONTCOPY); - - buf_priv->currently_mapped = I810_BUF_MAPPED; - - if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - return 0; -} - -static const struct file_operations i810_buffer_fops = { - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = i810_mmap_buffers, - .fasync = drm_fasync, - .llseek = noop_llseek, -}; - -static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) -{ - struct drm_device *dev = file_priv->minor->dev; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_private_t *dev_priv = dev->dev_private; - const struct file_operations *old_fops; - int retcode = 0; - - if (buf_priv->currently_mapped == I810_BUF_MAPPED) - return -EINVAL; - - /* This is all entirely broken */ - down_write(¤t->mm->mmap_sem); - old_fops = file_priv->filp->f_op; - file_priv->filp->f_op = &i810_buffer_fops; - dev_priv->mmap_buffer = buf; - buf_priv->virtual = (void *)do_mmap(file_priv->filp, 0, buf->total, - PROT_READ | PROT_WRITE, - MAP_SHARED, buf->bus_address); - dev_priv->mmap_buffer = NULL; - file_priv->filp->f_op = old_fops; - if (IS_ERR(buf_priv->virtual)) { - /* Real error */ - DRM_ERROR("mmap error\n"); - retcode = PTR_ERR(buf_priv->virtual); - buf_priv->virtual = NULL; - } - up_write(¤t->mm->mmap_sem); - - return retcode; -} - -static int i810_unmap_buffer(struct drm_buf *buf) -{ - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - int retcode = 0; - - if (buf_priv->currently_mapped != I810_BUF_MAPPED) - return -EINVAL; - - retcode = vm_munmap((unsigned long)buf_priv->virtual, - (size_t) buf->total); - - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - buf_priv->virtual = NULL; - - return retcode; -} - -static int i810_dma_get_buffer(struct drm_device *dev, drm_i810_dma_t *d, - struct drm_file *file_priv) -{ - struct drm_buf *buf; - drm_i810_buf_priv_t *buf_priv; - int retcode = 0; - - buf = i810_freelist_get(dev); - if (!buf) { - retcode = -ENOMEM; - DRM_DEBUG("retcode=%d\n", retcode); - return retcode; - } - - retcode = i810_map_buffer(buf, file_priv); - if (retcode) { - i810_freelist_put(dev, buf); - DRM_ERROR("mapbuf failed, retcode %d\n", retcode); - return retcode; - } - buf->file_priv = file_priv; - buf_priv = buf->dev_private; - d->granted = 1; - d->request_idx = buf->idx; - d->request_size = buf->total; - d->virtual = buf_priv->virtual; - - return retcode; -} - -static int i810_dma_cleanup(struct drm_device *dev) -{ - struct drm_device_dma *dma = dev->dma; - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - int i; - drm_i810_private_t *dev_priv = - (drm_i810_private_t *) dev->dev_private; - - if (dev_priv->ring.virtual_start) - drm_core_ioremapfree(&dev_priv->ring.map, dev); - if (dev_priv->hw_status_page) { - pci_free_consistent(dev->pdev, PAGE_SIZE, - dev_priv->hw_status_page, - dev_priv->dma_status_page); - } - kfree(dev->dev_private); - dev->dev_private = NULL; - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - if (buf_priv->kernel_virtual && buf->total) - drm_core_ioremapfree(&buf_priv->map, dev); - } - } - return 0; -} - -static int i810_wait_ring(struct drm_device *dev, int n) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - int iters = 0; - unsigned long end; - unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - - end = jiffies + (HZ * 3); - while (ring->space < n) { - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - - if (ring->head != last_head) { - end = jiffies + (HZ * 3); - last_head = ring->head; - } - - iters++; - if (time_before(end, jiffies)) { - DRM_ERROR("space: %d wanted %d\n", ring->space, n); - DRM_ERROR("lockup\n"); - goto out_wait_ring; - } - udelay(1); - } - -out_wait_ring: - return iters; -} - -static void i810_kernel_lost_context(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - - ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; - ring->tail = I810_READ(LP_RING + RING_TAIL); - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; -} - -static int i810_freelist_init(struct drm_device *dev, drm_i810_private_t *dev_priv) -{ - struct drm_device_dma *dma = dev->dma; - int my_idx = 24; - u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx); - int i; - - if (dma->buf_count > 1019) { - /* Not enough space in the status page for the freelist */ - return -EINVAL; - } - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - buf_priv->in_use = hw_status++; - buf_priv->my_use_idx = my_idx; - my_idx += 4; - - *buf_priv->in_use = I810_BUF_FREE; - - buf_priv->map.offset = buf->bus_address; - buf_priv->map.size = buf->total; - buf_priv->map.type = _DRM_AGP; - buf_priv->map.flags = 0; - buf_priv->map.mtrr = 0; - - drm_core_ioremap(&buf_priv->map, dev); - buf_priv->kernel_virtual = buf_priv->map.handle; - - } - return 0; -} - -static int i810_dma_initialize(struct drm_device *dev, - drm_i810_private_t *dev_priv, - drm_i810_init_t *init) -{ - struct drm_map_list *r_list; - memset(dev_priv, 0, sizeof(drm_i810_private_t)); - - list_for_each_entry(r_list, &dev->maplist, head) { - if (r_list->map && - r_list->map->type == _DRM_SHM && - r_list->map->flags & _DRM_CONTAINS_LOCK) { - dev_priv->sarea_map = r_list->map; - break; - } - } - if (!dev_priv->sarea_map) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find sarea!\n"); - return -EINVAL; - } - dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio_map) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find mmio map!\n"); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not find dma buffer map!\n"); - return -EINVAL; - } - - dev_priv->sarea_priv = (drm_i810_sarea_t *) - ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset); - - dev_priv->ring.Start = init->ring_start; - dev_priv->ring.End = init->ring_end; - dev_priv->ring.Size = init->ring_size; - - dev_priv->ring.map.offset = dev->agp->base + init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = _DRM_AGP; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; - - drm_core_ioremap(&dev_priv->ring.map, dev); - - if (dev_priv->ring.map.handle == NULL) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; - - dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - - dev_priv->w = init->w; - dev_priv->h = init->h; - dev_priv->pitch = init->pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->depth_offset = init->depth_offset; - dev_priv->front_offset = init->front_offset; - - dev_priv->overlay_offset = init->overlay_offset; - dev_priv->overlay_physical = init->overlay_physical; - - dev_priv->front_di1 = init->front_offset | init->pitch_bits; - dev_priv->back_di1 = init->back_offset | init->pitch_bits; - dev_priv->zi1 = init->depth_offset | init->pitch_bits; - - /* Program Hardware Status Page */ - dev_priv->hw_status_page = - pci_alloc_consistent(dev->pdev, PAGE_SIZE, - &dev_priv->dma_status_page); - if (!dev_priv->hw_status_page) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); - - I810_WRITE(0x02080, dev_priv->dma_status_page); - DRM_DEBUG("Enabled hardware status page\n"); - - /* Now we need to init our freelist */ - if (i810_freelist_init(dev, dev_priv) != 0) { - dev->dev_private = (void *)dev_priv; - i810_dma_cleanup(dev); - DRM_ERROR("Not enough space in the status page for" - " the freelist\n"); - return -ENOMEM; - } - dev->dev_private = (void *)dev_priv; - - return 0; -} - -static int i810_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv; - drm_i810_init_t *init = data; - int retcode = 0; - - switch (init->func) { - case I810_INIT_DMA_1_4: - DRM_INFO("Using v1.4 init.\n"); - dev_priv = kmalloc(sizeof(drm_i810_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - retcode = i810_dma_initialize(dev, dev_priv, init); - break; - - case I810_CLEANUP_DMA: - DRM_INFO("DMA Cleanup\n"); - retcode = i810_dma_cleanup(dev); - break; - default: - return -EINVAL; - } - - return retcode; -} - -/* Most efficient way to verify state for the i810 is as it is - * emitted. Non-conformant state is silently dropped. - * - * Use 'volatile' & local var tmp to force the emitted values to be - * identical to the verified ones. - */ -static void i810EmitContextVerified(struct drm_device *dev, - volatile unsigned int *code) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I810_CTX_SETUP_SIZE); - - OUT_RING(GFX_OP_COLOR_FACTOR); - OUT_RING(code[I810_CTXREG_CF1]); - - OUT_RING(GFX_OP_STIPPLE); - OUT_RING(code[I810_CTXREG_ST1]); - - for (i = 4; i < I810_CTX_SETUP_SIZE; i++) { - tmp = code[i]; - - if ((tmp & (7 << 29)) == (3 << 29) && - (tmp & (0x1f << 24)) < (0x1d << 24)) { - OUT_RING(tmp); - j++; - } else - printk("constext state dropped!!!\n"); - } - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i810EmitTexVerified(struct drm_device *dev, volatile unsigned int *code) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - int i, j = 0; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I810_TEX_SETUP_SIZE); - - OUT_RING(GFX_OP_MAP_INFO); - OUT_RING(code[I810_TEXREG_MI1]); - OUT_RING(code[I810_TEXREG_MI2]); - OUT_RING(code[I810_TEXREG_MI3]); - - for (i = 4; i < I810_TEX_SETUP_SIZE; i++) { - tmp = code[i]; - - if ((tmp & (7 << 29)) == (3 << 29) && - (tmp & (0x1f << 24)) < (0x1d << 24)) { - OUT_RING(tmp); - j++; - } else - printk("texture state dropped!!!\n"); - } - - if (j & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -/* Need to do some additional checking when setting the dest buffer. - */ -static void i810EmitDestVerified(struct drm_device *dev, - volatile unsigned int *code) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - unsigned int tmp; - RING_LOCALS; - - BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); - - tmp = code[I810_DESTREG_DI1]; - if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { - OUT_RING(CMD_OP_DESTBUFFER_INFO); - OUT_RING(tmp); - } else - DRM_DEBUG("bad di1 %x (allow %x or %x)\n", - tmp, dev_priv->front_di1, dev_priv->back_di1); - - /* invarient: - */ - OUT_RING(CMD_OP_Z_BUFFER_INFO); - OUT_RING(dev_priv->zi1); - - OUT_RING(GFX_OP_DESTBUFFER_VARS); - OUT_RING(code[I810_DESTREG_DV1]); - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(code[I810_DESTREG_DR1]); - OUT_RING(code[I810_DESTREG_DR2]); - OUT_RING(code[I810_DESTREG_DR3]); - OUT_RING(code[I810_DESTREG_DR4]); - OUT_RING(0); - - ADVANCE_LP_RING(); -} - -static void i810EmitState(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG("%x\n", dirty); - - if (dirty & I810_UPLOAD_BUFFERS) { - i810EmitDestVerified(dev, sarea_priv->BufferState); - sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; - } - - if (dirty & I810_UPLOAD_CTX) { - i810EmitContextVerified(dev, sarea_priv->ContextState); - sarea_priv->dirty &= ~I810_UPLOAD_CTX; - } - - if (dirty & I810_UPLOAD_TEX0) { - i810EmitTexVerified(dev, sarea_priv->TexState[0]); - sarea_priv->dirty &= ~I810_UPLOAD_TEX0; - } - - if (dirty & I810_UPLOAD_TEX1) { - i810EmitTexVerified(dev, sarea_priv->TexState[1]); - sarea_priv->dirty &= ~I810_UPLOAD_TEX1; - } -} - -/* need to verify - */ -static void i810_dma_dispatch_clear(struct drm_device *dev, int flags, - unsigned int clear_color, - unsigned int clear_zval) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int pitch = dev_priv->pitch; - int cpp = 2; - int i; - RING_LOCALS; - - if (dev_priv->current_page == 1) { - unsigned int tmp = flags; - - flags &= ~(I810_FRONT | I810_BACK); - if (tmp & I810_FRONT) - flags |= I810_BACK; - if (tmp & I810_BACK) - flags |= I810_FRONT; - } - - i810_kernel_lost_context(dev); - - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; - - for (i = 0; i < nbox; i++, pbox++) { - unsigned int x = pbox->x1; - unsigned int y = pbox->y1; - unsigned int width = (pbox->x2 - x) * cpp; - unsigned int height = pbox->y2 - y; - unsigned int start = y * pitch + x * cpp; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) - continue; - - if (flags & I810_FRONT) { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); - OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); - OUT_RING((height << 16) | width); - OUT_RING(start); - OUT_RING(clear_color); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - if (flags & I810_BACK) { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); - OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); - OUT_RING((height << 16) | width); - OUT_RING(dev_priv->back_offset + start); - OUT_RING(clear_color); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - if (flags & I810_DEPTH) { - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); - OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); - OUT_RING((height << 16) | width); - OUT_RING(dev_priv->depth_offset + start); - OUT_RING(clear_zval); - OUT_RING(0); - ADVANCE_LP_RING(); - } - } -} - -static void i810_dma_dispatch_swap(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int pitch = dev_priv->pitch; - int cpp = 2; - int i; - RING_LOCALS; - - DRM_DEBUG("swapbuffers\n"); - - i810_kernel_lost_context(dev); - - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; - - for (i = 0; i < nbox; i++, pbox++) { - unsigned int w = pbox->x2 - pbox->x1; - unsigned int h = pbox->y2 - pbox->y1; - unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch; - unsigned int start = dst; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) - continue; - - BEGIN_LP_RING(6); - OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); - OUT_RING(pitch | (0xCC << 16)); - OUT_RING((h << 16) | (w * cpp)); - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->front_offset + start); - else - OUT_RING(dev_priv->back_offset + start); - OUT_RING(pitch); - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->back_offset + start); - else - OUT_RING(dev_priv->front_offset + start); - ADVANCE_LP_RING(); - } -} - -static void i810_dma_dispatch_vertex(struct drm_device *dev, - struct drm_buf *buf, int discard, int used) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - struct drm_clip_rect *box = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - int i = 0; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - if (nbox > I810_NR_SAREA_CLIPRECTS) - nbox = I810_NR_SAREA_CLIPRECTS; - - if (used > 4 * 1024) - used = 0; - - if (sarea_priv->dirty) - i810EmitState(dev); - - if (buf_priv->currently_mapped == I810_BUF_MAPPED) { - unsigned int prim = (sarea_priv->vertex_prim & PR_MASK); - - *(u32 *) buf_priv->kernel_virtual = - ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); - - if (used & 4) { - *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0; - used += 4; - } - - i810_unmap_buffer(buf); - } - - if (used) { - do { - if (i < nbox) { - BEGIN_LP_RING(4); - OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | - SC_ENABLE); - OUT_RING(GFX_OP_SCISSOR_INFO); - OUT_RING(box[i].x1 | (box[i].y1 << 16)); - OUT_RING((box[i].x2 - - 1) | ((box[i].y2 - 1) << 16)); - ADVANCE_LP_RING(); - } - - BEGIN_LP_RING(4); - OUT_RING(CMD_OP_BATCH_BUFFER); - OUT_RING(start | BB1_PROTECTED); - OUT_RING(start + used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - - } while (++i < nbox); - } - - if (discard) { - dev_priv->counter++; - - (void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_HARDWARE); - - BEGIN_LP_RING(8); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(buf_priv->my_use_idx); - OUT_RING(I810_BUF_FREE); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - ADVANCE_LP_RING(); - } -} - -static void i810_dma_dispatch_flip(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - int pitch = dev_priv->pitch; - RING_LOCALS; - - DRM_DEBUG("page=%d pfCurrentPage=%d\n", - dev_priv->current_page, - dev_priv->sarea_priv->pf_current_page); - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); - /* On i815 at least ASYNC is buggy */ - /* pitch<<5 is from 11.2.8 p158, - its the pitch / 8 then left shifted 8, - so (pitch >> 3) << 8 */ - OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ ); - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_offset); - dev_priv->current_page = 1; - } else { - OUT_RING(dev_priv->front_offset); - dev_priv->current_page = 0; - } - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(2); - OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP); - OUT_RING(0); - ADVANCE_LP_RING(); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; - -} - -static void i810_dma_quiescent(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(4); - OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - OUT_RING(0); - ADVANCE_LP_RING(); - - i810_wait_ring(dev, dev_priv->ring.Size - 8); -} - -static int i810_flush_queue(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - int i, ret = 0; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - BEGIN_LP_RING(2); - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); - ADVANCE_LP_RING(); - - i810_wait_ring(dev, dev_priv->ring.Size - 8); - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, - I810_BUF_FREE); - - if (used == I810_BUF_HARDWARE) - DRM_DEBUG("reclaimed from HARDWARE\n"); - if (used == I810_BUF_CLIENT) - DRM_DEBUG("still on client\n"); - } - - return ret; -} - -/* Must be called with the lock held */ -static void i810_reclaim_buffers(struct drm_device *dev, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - if (!dma) - return; - if (!dev->dev_private) - return; - if (!dma->buflist) - return; - - i810_flush_queue(dev); - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->file_priv == file_priv && buf_priv) { - int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, - I810_BUF_FREE); - - if (used == I810_BUF_CLIENT) - DRM_DEBUG("reclaimed from client\n"); - if (buf_priv->currently_mapped == I810_BUF_MAPPED) - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - } - } -} - -static int i810_flush_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - LOCK_TEST_WITH_RETURN(dev, file_priv); - - i810_flush_queue(dev); - return 0; -} - -static int i810_dma_vertex(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - drm_i810_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("idx %d used %d discard %d\n", - vertex->idx, vertex->used, vertex->discard); - - if (vertex->idx < 0 || vertex->idx > dma->buf_count) - return -EINVAL; - - i810_dma_dispatch_vertex(dev, - dma->buflist[vertex->idx], - vertex->discard, vertex->used); - - atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]); - atomic_inc(&dev->counts[_DRM_STAT_DMA]); - sarea_priv->last_enqueue = dev_priv->counter - 1; - sarea_priv->last_dispatch = (int)hw_status[5]; - - return 0; -} - -static int i810_clear_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_clear_t *clear = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* GH: Someone's doing nasty things... */ - if (!dev->dev_private) - return -EINVAL; - - i810_dma_dispatch_clear(dev, clear->flags, - clear->clear_color, clear->clear_depth); - return 0; -} - -static int i810_swap_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - i810_dma_dispatch_swap(dev); - return 0; -} - -static int i810_getage(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - - sarea_priv->last_dispatch = (int)hw_status[5]; - return 0; -} - -static int i810_getbuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int retcode = 0; - drm_i810_dma_t *d = data; - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - d->granted = 0; - - retcode = i810_dma_get_buffer(dev, d, file_priv); - - DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", - task_pid_nr(current), retcode, d->granted); - - sarea_priv->last_dispatch = (int)hw_status[5]; - - return retcode; -} - -static int i810_copybuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* Never copy - 2.4.x doesn't need it */ - return 0; -} - -static int i810_docopy(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* Never copy - 2.4.x doesn't need it */ - return 0; -} - -static void i810_dma_dispatch_mc(struct drm_device *dev, struct drm_buf *buf, int used, - unsigned int last_render) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - int u; - RING_LOCALS; - - i810_kernel_lost_context(dev); - - u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); - if (u != I810_BUF_CLIENT) - DRM_DEBUG("MC found buffer that isn't mine!\n"); - - if (used > 4 * 1024) - used = 0; - - sarea_priv->dirty = 0x7f; - - DRM_DEBUG("addr 0x%lx, used 0x%x\n", address, used); - - dev_priv->counter++; - DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG("start : %lx\n", start); - DRM_DEBUG("used : %d\n", used); - DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4); - - if (buf_priv->currently_mapped == I810_BUF_MAPPED) { - if (used & 4) { - *(u32 *) ((char *) buf_priv->virtual + used) = 0; - used += 4; - } - - i810_unmap_buffer(buf); - } - BEGIN_LP_RING(4); - OUT_RING(CMD_OP_BATCH_BUFFER); - OUT_RING(start | BB1_PROTECTED); - OUT_RING(start + used - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - - BEGIN_LP_RING(8); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(buf_priv->my_use_idx); - OUT_RING(I810_BUF_FREE); - OUT_RING(0); - - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(16); - OUT_RING(last_render); - OUT_RING(0); - ADVANCE_LP_RING(); -} - -static int i810_dma_mc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - u32 *hw_status = dev_priv->hw_status_page; - drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) - dev_priv->sarea_priv; - drm_i810_mc_t *mc = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (mc->idx >= dma->buf_count || mc->idx < 0) - return -EINVAL; - - i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used, - mc->last_render); - - atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]); - atomic_inc(&dev->counts[_DRM_STAT_DMA]); - sarea_priv->last_enqueue = dev_priv->counter - 1; - sarea_priv->last_dispatch = (int)hw_status[5]; - - return 0; -} - -static int i810_rstatus(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - - return (int)(((u32 *) (dev_priv->hw_status_page))[4]); -} - -static int i810_ov0_info(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - drm_i810_overlay_t *ov = data; - - ov->offset = dev_priv->overlay_offset; - ov->physical = dev_priv->overlay_physical; - - return 0; -} - -static int i810_fstatus(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - return I810_READ(0x30008); -} - -static int i810_ov0_flip(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Tell the overlay to update */ - I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); - - return 0; -} - -/* Not sure why this isn't set all the time: - */ -static void i810_do_init_pageflip(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; -} - -static int i810_do_cleanup_pageflip(struct drm_device *dev) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - if (dev_priv->current_page != 0) - i810_dma_dispatch_flip(dev); - - dev_priv->page_flipping = 0; - return 0; -} - -static int i810_flip_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i810_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv->page_flipping) - i810_do_init_pageflip(dev); - - i810_dma_dispatch_flip(dev); - return 0; -} - -int i810_driver_load(struct drm_device *dev, unsigned long flags) -{ - /* i810 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - pci_set_master(dev->pdev); - - return 0; -} - -void i810_driver_lastclose(struct drm_device *dev) -{ - i810_dma_cleanup(dev); -} - -void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_i810_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) - i810_do_cleanup_pageflip(dev); - } -} - -void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv) -{ - i810_reclaim_buffers(dev, file_priv); -} - -int i810_driver_dma_quiescent(struct drm_device *dev) -{ - i810_dma_quiescent(dev); - return 0; -} - -struct drm_ioctl_desc i810_ioctls[] = { - DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), -}; - -int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); - -/** - * Determine if the device really is AGP or not. - * - * All Intel graphics chipsets are treated as AGP, even if they are really - * PCI-e. - * - * \param dev The device to be tested. - * - * \returns - * A value of 1 is always retured to indictate every i810 is AGP. - */ -int i810_driver_device_is_agp(struct drm_device *dev) -{ - return 1; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.c deleted file mode 100644 index ec12f7dc..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.c +++ /dev/null @@ -1,103 +0,0 @@ -/* i810_drv.c -- I810 driver -*- linux-c -*- - * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Jeff Hartmann - * Gareth Hughes - */ - -#include - -#include "drmP.h" -#include "drm.h" -#include "i810_drm.h" -#include "i810_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - i810_PCI_IDS -}; - -static const struct file_operations i810_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .llseek = noop_llseek, -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | - DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE, - .dev_priv_size = sizeof(drm_i810_buf_priv_t), - .load = i810_driver_load, - .lastclose = i810_driver_lastclose, - .preclose = i810_driver_preclose, - .device_is_agp = i810_driver_device_is_agp, - .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, - .dma_quiescent = i810_driver_dma_quiescent, - .ioctls = i810_ioctls, - .fops = &i810_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct pci_driver i810_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, -}; - -static int __init i810_init(void) -{ - if (num_possible_cpus() > 1) { - pr_err("drm/i810 does not support SMP\n"); - return -EINVAL; - } - driver.num_ioctls = i810_max_ioctl; - return drm_pci_init(&driver, &i810_pci_driver); -} - -static void __exit i810_exit(void) -{ - drm_pci_exit(&driver, &i810_pci_driver); -} - -module_init(i810_init); -module_exit(i810_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.h deleted file mode 100644 index c9339f48..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i810/i810_drv.h +++ /dev/null @@ -1,245 +0,0 @@ -/* i810_drv.h -- Private header for the Matrox g200/g400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Rickard E. (Rik) Faith - * Jeff Hartmann - * - */ - -#ifndef _I810_DRV_H_ -#define _I810_DRV_H_ - -/* General customization: - */ - -#define DRIVER_AUTHOR "VA Linux Systems Inc." - -#define DRIVER_NAME "i810" -#define DRIVER_DESC "Intel i810" -#define DRIVER_DATE "20030605" - -/* Interface history - * - * 1.1 - XFree86 4.1 - * 1.2 - XvMC interfaces - * - XFree86 4.2 - * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility) - * - Remove requirement for interrupt (leave stubs again) - * 1.3 - Add page flipping. - * 1.4 - fix DRM interface - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 4 -#define DRIVER_PATCHLEVEL 0 - -typedef struct drm_i810_buf_priv { - u32 *in_use; - int my_use_idx; - int currently_mapped; - void *virtual; - void *kernel_virtual; - drm_local_map_t map; -} drm_i810_buf_priv_t; - -typedef struct _drm_i810_ring_buffer { - int tail_mask; - unsigned long Start; - unsigned long End; - unsigned long Size; - u8 *virtual_start; - int head; - int tail; - int space; - drm_local_map_t map; -} drm_i810_ring_buffer_t; - -typedef struct drm_i810_private { - struct drm_local_map *sarea_map; - struct drm_local_map *mmio_map; - - drm_i810_sarea_t *sarea_priv; - drm_i810_ring_buffer_t ring; - - void *hw_status_page; - unsigned long counter; - - dma_addr_t dma_status_page; - - struct drm_buf *mmap_buffer; - - u32 front_di1, back_di1, zi1; - - int back_offset; - int depth_offset; - int overlay_offset; - int overlay_physical; - int w, h; - int pitch; - int back_pitch; - int depth_pitch; - - int do_boxes; - int dma_used; - - int current_page; - int page_flipping; - - wait_queue_head_t irq_queue; - atomic_t irq_received; - atomic_t irq_emitted; - - int front_offset; -} drm_i810_private_t; - - /* i810_dma.c */ -extern int i810_driver_dma_quiescent(struct drm_device *dev); -extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); -extern int i810_driver_load(struct drm_device *, unsigned long flags); -extern void i810_driver_lastclose(struct drm_device *dev); -extern void i810_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv); -extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); -extern int i810_driver_device_is_agp(struct drm_device *dev); - -extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -extern struct drm_ioctl_desc i810_ioctls[]; -extern int i810_max_ioctl; - -#define I810_BASE(reg) ((unsigned long) \ - dev_priv->mmio_map->handle) -#define I810_ADDR(reg) (I810_BASE(reg) + reg) -#define I810_DEREF(reg) (*(__volatile__ int *)I810_ADDR(reg)) -#define I810_READ(reg) I810_DEREF(reg) -#define I810_WRITE(reg, val) do { I810_DEREF(reg) = val; } while (0) -#define I810_DEREF16(reg) (*(__volatile__ u16 *)I810_ADDR(reg)) -#define I810_READ16(reg) I810_DEREF16(reg) -#define I810_WRITE16(reg, val) do { I810_DEREF16(reg) = val; } while (0) - -#define I810_VERBOSE 0 -#define RING_LOCALS unsigned int outring, ringmask; \ - volatile char *virt; - -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \ - if (dev_priv->ring.space < n*4) \ - i810_wait_ring(dev, n*4); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ -} while (0) - -#define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ -} while (0) - -#define OUT_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} while (0) - -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) -#define CMD_REPORT_HEAD (7<<23) -#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) -#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) - -#define INST_PARSER_CLIENT 0x00000000 -#define INST_OP_FLUSH 0x02000000 -#define INST_FLUSH_MAP_CACHE 0x00000001 - -#define BB1_START_ADDR_MASK (~0x7) -#define BB1_PROTECTED (1<<0) -#define BB1_UNPROTECTED (0<<0) -#define BB2_END_ADDR_MASK (~0x7) - -#define I810REG_HWSTAM 0x02098 -#define I810REG_INT_IDENTITY_R 0x020a4 -#define I810REG_INT_MASK_R 0x020a8 -#define I810REG_INT_ENABLE_R 0x020a0 - -#define LP_RING 0x2030 -#define HP_RING 0x2040 -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0x00FFFFF8 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x000FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) - -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) - -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24)) - -#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) -#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) -#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23)) -#define CMD_OP_WAIT_FOR_EVENT ((0x0<<29)|(0x03<<23)) - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define WAIT_FOR_PLANE_A_SCANLINES (1<<1) -#define WAIT_FOR_PLANE_A_FLIP (1<<2) -#define WAIT_FOR_VBLANK (1<<3) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/i915/Makefile deleted file mode 100644 index ce7fc776..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -i915-y := i915_drv.o i915_dma.o i915_irq.o \ - i915_debugfs.o \ - i915_suspend.o \ - i915_gem.o \ - i915_gem_debug.o \ - i915_gem_evict.o \ - i915_gem_execbuffer.o \ - i915_gem_gtt.o \ - i915_gem_tiling.o \ - i915_trace_points.o \ - intel_display.o \ - intel_crt.o \ - intel_lvds.o \ - intel_bios.o \ - intel_dp.o \ - intel_hdmi.o \ - intel_sdvo.o \ - intel_modes.o \ - intel_panel.o \ - intel_i2c.o \ - intel_fb.o \ - intel_tv.o \ - intel_dvo.o \ - intel_ringbuffer.o \ - intel_overlay.o \ - intel_sprite.o \ - intel_opregion.o \ - dvo_ch7xxx.o \ - dvo_ch7017.o \ - dvo_ivch.o \ - dvo_tfp410.o \ - dvo_sil164.o - -i915-$(CONFIG_COMPAT) += i915_ioc32.o - -i915-$(CONFIG_ACPI) += intel_acpi.o - -obj-$(CONFIG_DRM_I915) += i915.o - -CFLAGS_i915_trace_points.o := -I$(src) diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo.h deleted file mode 100644 index 8c2ad014..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright © 2006 Eric Anholt - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -#ifndef _INTEL_DVO_H -#define _INTEL_DVO_H - -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "intel_drv.h" - -struct intel_dvo_device { - const char *name; - int type; - /* DVOA/B/C output register */ - u32 dvo_reg; - /* GPIO register used for i2c bus to control this device */ - u32 gpio; - int slave_addr; - - const struct intel_dvo_dev_ops *dev_ops; - void *dev_priv; - struct i2c_adapter *i2c_bus; -}; - -struct intel_dvo_dev_ops { - /* - * Initialize the device at startup time. - * Returns NULL if the device does not exist. - */ - bool (*init)(struct intel_dvo_device *dvo, - struct i2c_adapter *i2cbus); - - /* - * Called to allow the output a chance to create properties after the - * RandR objects have been created. - */ - void (*create_resources)(struct intel_dvo_device *dvo); - - /* - * Turn on/off output or set intermediate power levels if available. - * - * Unsupported intermediate modes drop to the lower power setting. - * If the mode is DPMSModeOff, the output must be disabled, - * as the DPLL may be disabled afterwards. - */ - void (*dpms)(struct intel_dvo_device *dvo, int mode); - - /* - * Callback for testing a video mode for a given output. - * - * This function should only check for cases where a mode can't - * be supported on the output specifically, and not represent - * generic CRTC limitations. - * - * \return MODE_OK if the mode is valid, or another MODE_* otherwise. - */ - int (*mode_valid)(struct intel_dvo_device *dvo, - struct drm_display_mode *mode); - - /* - * Callback to adjust the mode to be set in the CRTC. - * - * This allows an output to adjust the clock or even the entire set of - * timings, which is used for panels with fixed timings or for - * buses with clock limitations. - */ - bool (*mode_fixup)(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - - /* - * Callback for preparing mode changes on an output - */ - void (*prepare)(struct intel_dvo_device *dvo); - - /* - * Callback for committing mode changes on an output - */ - void (*commit)(struct intel_dvo_device *dvo); - - /* - * Callback for setting up a video mode after fixups have been made. - * - * This is only called while the output is disabled. The dpms callback - * must be all that's necessary for the output, to turn the output on - * after this function is called. - */ - void (*mode_set)(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - - /* - * Probe for a connected output, and return detect_status. - */ - enum drm_connector_status (*detect)(struct intel_dvo_device *dvo); - - /** - * Query the device for the modes it provides. - * - * This function may also update MonInfo, mm_width, and mm_height. - * - * \return singly-linked list of modes or NULL if no modes found. - */ - struct drm_display_mode *(*get_modes)(struct intel_dvo_device *dvo); - - /** - * Clean up driver-specific bits of the output - */ - void (*destroy) (struct intel_dvo_device *dvo); - - /** - * Debugging hook to dump device registers to log file - */ - void (*dump_regs)(struct intel_dvo_device *dvo); -}; - -extern struct intel_dvo_dev_ops sil164_ops; -extern struct intel_dvo_dev_ops ch7xxx_ops; -extern struct intel_dvo_dev_ops ivch_ops; -extern struct intel_dvo_dev_ops tfp410_ops; -extern struct intel_dvo_dev_ops ch7017_ops; - -#endif /* _INTEL_DVO_H */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7017.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7017.c deleted file mode 100644 index 1ca799a1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7017.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright © 2006 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "dvo.h" - -#define CH7017_TV_DISPLAY_MODE 0x00 -#define CH7017_FLICKER_FILTER 0x01 -#define CH7017_VIDEO_BANDWIDTH 0x02 -#define CH7017_TEXT_ENHANCEMENT 0x03 -#define CH7017_START_ACTIVE_VIDEO 0x04 -#define CH7017_HORIZONTAL_POSITION 0x05 -#define CH7017_VERTICAL_POSITION 0x06 -#define CH7017_BLACK_LEVEL 0x07 -#define CH7017_CONTRAST_ENHANCEMENT 0x08 -#define CH7017_TV_PLL 0x09 -#define CH7017_TV_PLL_M 0x0a -#define CH7017_TV_PLL_N 0x0b -#define CH7017_SUB_CARRIER_0 0x0c -#define CH7017_CIV_CONTROL 0x10 -#define CH7017_CIV_0 0x11 -#define CH7017_CHROMA_BOOST 0x14 -#define CH7017_CLOCK_MODE 0x1c -#define CH7017_INPUT_CLOCK 0x1d -#define CH7017_GPIO_CONTROL 0x1e -#define CH7017_INPUT_DATA_FORMAT 0x1f -#define CH7017_CONNECTION_DETECT 0x20 -#define CH7017_DAC_CONTROL 0x21 -#define CH7017_BUFFERED_CLOCK_OUTPUT 0x22 -#define CH7017_DEFEAT_VSYNC 0x47 -#define CH7017_TEST_PATTERN 0x48 - -#define CH7017_POWER_MANAGEMENT 0x49 -/** Enables the TV output path. */ -#define CH7017_TV_EN (1 << 0) -#define CH7017_DAC0_POWER_DOWN (1 << 1) -#define CH7017_DAC1_POWER_DOWN (1 << 2) -#define CH7017_DAC2_POWER_DOWN (1 << 3) -#define CH7017_DAC3_POWER_DOWN (1 << 4) -/** Powers down the TV out block, and DAC0-3 */ -#define CH7017_TV_POWER_DOWN_EN (1 << 5) - -#define CH7017_VERSION_ID 0x4a - -#define CH7017_DEVICE_ID 0x4b -#define CH7017_DEVICE_ID_VALUE 0x1b -#define CH7018_DEVICE_ID_VALUE 0x1a -#define CH7019_DEVICE_ID_VALUE 0x19 - -#define CH7017_XCLK_D2_ADJUST 0x53 -#define CH7017_UP_SCALER_COEFF_0 0x55 -#define CH7017_UP_SCALER_COEFF_1 0x56 -#define CH7017_UP_SCALER_COEFF_2 0x57 -#define CH7017_UP_SCALER_COEFF_3 0x58 -#define CH7017_UP_SCALER_COEFF_4 0x59 -#define CH7017_UP_SCALER_VERTICAL_INC_0 0x5a -#define CH7017_UP_SCALER_VERTICAL_INC_1 0x5b -#define CH7017_GPIO_INVERT 0x5c -#define CH7017_UP_SCALER_HORIZONTAL_INC_0 0x5d -#define CH7017_UP_SCALER_HORIZONTAL_INC_1 0x5e - -#define CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT 0x5f -/**< Low bits of horizontal active pixel input */ - -#define CH7017_ACTIVE_INPUT_LINE_OUTPUT 0x60 -/** High bits of horizontal active pixel input */ -#define CH7017_LVDS_HAP_INPUT_MASK (0x7 << 0) -/** High bits of vertical active line output */ -#define CH7017_LVDS_VAL_HIGH_MASK (0x7 << 3) - -#define CH7017_VERTICAL_ACTIVE_LINE_OUTPUT 0x61 -/**< Low bits of vertical active line output */ - -#define CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT 0x62 -/**< Low bits of horizontal active pixel output */ - -#define CH7017_LVDS_POWER_DOWN 0x63 -/** High bits of horizontal active pixel output */ -#define CH7017_LVDS_HAP_HIGH_MASK (0x7 << 0) -/** Enables the LVDS power down state transition */ -#define CH7017_LVDS_POWER_DOWN_EN (1 << 6) -/** Enables the LVDS upscaler */ -#define CH7017_LVDS_UPSCALER_EN (1 << 7) -#define CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED 0x08 - -#define CH7017_LVDS_ENCODING 0x64 -#define CH7017_LVDS_DITHER_2D (1 << 2) -#define CH7017_LVDS_DITHER_DIS (1 << 3) -#define CH7017_LVDS_DUAL_CHANNEL_EN (1 << 4) -#define CH7017_LVDS_24_BIT (1 << 5) - -#define CH7017_LVDS_ENCODING_2 0x65 - -#define CH7017_LVDS_PLL_CONTROL 0x66 -/** Enables the LVDS panel output path */ -#define CH7017_LVDS_PANEN (1 << 0) -/** Enables the LVDS panel backlight */ -#define CH7017_LVDS_BKLEN (1 << 3) - -#define CH7017_POWER_SEQUENCING_T1 0x67 -#define CH7017_POWER_SEQUENCING_T2 0x68 -#define CH7017_POWER_SEQUENCING_T3 0x69 -#define CH7017_POWER_SEQUENCING_T4 0x6a -#define CH7017_POWER_SEQUENCING_T5 0x6b -#define CH7017_GPIO_DRIVER_TYPE 0x6c -#define CH7017_GPIO_DATA 0x6d -#define CH7017_GPIO_DIRECTION_CONTROL 0x6e - -#define CH7017_LVDS_PLL_FEEDBACK_DIV 0x71 -# define CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT 4 -# define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0 -# define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80 - -#define CH7017_LVDS_PLL_VCO_CONTROL 0x72 -# define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80 -# define CH7017_LVDS_PLL_VCO_SHIFT 4 -# define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0 - -#define CH7017_OUTPUTS_ENABLE 0x73 -# define CH7017_CHARGE_PUMP_LOW 0x0 -# define CH7017_CHARGE_PUMP_HIGH 0x3 -# define CH7017_LVDS_CHANNEL_A (1 << 3) -# define CH7017_LVDS_CHANNEL_B (1 << 4) -# define CH7017_TV_DAC_A (1 << 5) -# define CH7017_TV_DAC_B (1 << 6) -# define CH7017_DDC_SELECT_DC2 (1 << 7) - -#define CH7017_LVDS_OUTPUT_AMPLITUDE 0x74 -#define CH7017_LVDS_PLL_EMI_REDUCTION 0x75 -#define CH7017_LVDS_POWER_DOWN_FLICKER 0x76 - -#define CH7017_LVDS_CONTROL_2 0x78 -# define CH7017_LOOP_FILTER_SHIFT 5 -# define CH7017_PHASE_DETECTOR_SHIFT 0 - -#define CH7017_BANG_LIMIT_CONTROL 0x7f - -struct ch7017_priv { - uint8_t dummy; -}; - -static void ch7017_dump_regs(struct intel_dvo_device *dvo); -static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); - -static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val) -{ - struct i2c_msg msgs[] = { - { - .addr = dvo->slave_addr, - .flags = 0, - .len = 1, - .buf = &addr, - }, - { - .addr = dvo->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = val, - } - }; - return i2c_transfer(dvo->i2c_bus, msgs, 2) == 2; -} - -static bool ch7017_write(struct intel_dvo_device *dvo, u8 addr, u8 val) -{ - uint8_t buf[2] = { addr, val }; - struct i2c_msg msg = { - .addr = dvo->slave_addr, - .flags = 0, - .len = 2, - .buf = buf, - }; - return i2c_transfer(dvo->i2c_bus, &msg, 1) == 1; -} - -/** Probes for a CH7017 on the given bus and slave address. */ -static bool ch7017_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) -{ - struct ch7017_priv *priv; - const char *str; - u8 val; - - priv = kzalloc(sizeof(struct ch7017_priv), GFP_KERNEL); - if (priv == NULL) - return false; - - dvo->i2c_bus = adapter; - dvo->dev_priv = priv; - - if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) - goto fail; - - switch (val) { - case CH7017_DEVICE_ID_VALUE: - str = "ch7017"; - break; - case CH7018_DEVICE_ID_VALUE: - str = "ch7018"; - break; - case CH7019_DEVICE_ID_VALUE: - str = "ch7019"; - break; - default: - DRM_DEBUG_KMS("ch701x not detected, got %d: from %s " - "slave %d.\n", - val, adapter->name, dvo->slave_addr); - goto fail; - } - - DRM_DEBUG_KMS("%s detected on %s, addr %d\n", - str, adapter->name, dvo->slave_addr); - return true; - -fail: - kfree(priv); - return false; -} - -static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) -{ - return connector_status_connected; -} - -static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, - struct drm_display_mode *mode) -{ - if (mode->clock > 160000) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static void ch7017_mode_set(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - uint8_t lvds_pll_feedback_div, lvds_pll_vco_control; - uint8_t outputs_enable, lvds_control_2, lvds_power_down; - uint8_t horizontal_active_pixel_input; - uint8_t horizontal_active_pixel_output, vertical_active_line_output; - uint8_t active_input_line_output; - - DRM_DEBUG_KMS("Registers before mode setting\n"); - ch7017_dump_regs(dvo); - - /* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/ - if (mode->clock < 100000) { - outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW; - lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | - (13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); - lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_VCO_SHIFT) | - (3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); - lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) | - (0 << CH7017_PHASE_DETECTOR_SHIFT); - } else { - outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH; - lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | - (3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); - lvds_pll_feedback_div = 35; - lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) | - (0 << CH7017_PHASE_DETECTOR_SHIFT); - if (1) { /* XXX: dual channel panel detection. Assume yes for now. */ - outputs_enable |= CH7017_LVDS_CHANNEL_B; - lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_VCO_SHIFT) | - (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); - } else { - lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | - (1 << CH7017_LVDS_PLL_VCO_SHIFT) | - (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); - } - } - - horizontal_active_pixel_input = mode->hdisplay & 0x00ff; - - vertical_active_line_output = mode->vdisplay & 0x00ff; - horizontal_active_pixel_output = mode->hdisplay & 0x00ff; - - active_input_line_output = ((mode->hdisplay & 0x0700) >> 8) | - (((mode->vdisplay & 0x0700) >> 8) << 3); - - lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED | - (mode->hdisplay & 0x0700) >> 8; - - ch7017_dpms(dvo, DRM_MODE_DPMS_OFF); - ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, - horizontal_active_pixel_input); - ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT, - horizontal_active_pixel_output); - ch7017_write(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, - vertical_active_line_output); - ch7017_write(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT, - active_input_line_output); - ch7017_write(dvo, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control); - ch7017_write(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div); - ch7017_write(dvo, CH7017_LVDS_CONTROL_2, lvds_control_2); - ch7017_write(dvo, CH7017_OUTPUTS_ENABLE, outputs_enable); - - /* Turn the LVDS back on with new settings. */ - ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down); - - DRM_DEBUG_KMS("Registers after mode setting\n"); - ch7017_dump_regs(dvo); -} - -/* set the CH7017 power state */ -static void ch7017_dpms(struct intel_dvo_device *dvo, int mode) -{ - uint8_t val; - - ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val); - - /* Turn off TV/VGA, and never turn it on since we don't support it. */ - ch7017_write(dvo, CH7017_POWER_MANAGEMENT, - CH7017_DAC0_POWER_DOWN | - CH7017_DAC1_POWER_DOWN | - CH7017_DAC2_POWER_DOWN | - CH7017_DAC3_POWER_DOWN | - CH7017_TV_POWER_DOWN_EN); - - if (mode == DRM_MODE_DPMS_ON) { - /* Turn on the LVDS */ - ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, - val & ~CH7017_LVDS_POWER_DOWN_EN); - } else { - /* Turn off the LVDS */ - ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, - val | CH7017_LVDS_POWER_DOWN_EN); - } - - /* XXX: Should actually wait for update power status somehow */ - msleep(20); -} - -static void ch7017_dump_regs(struct intel_dvo_device *dvo) -{ - uint8_t val; - -#define DUMP(reg) \ -do { \ - ch7017_read(dvo, reg, &val); \ - DRM_DEBUG_KMS(#reg ": %02x\n", val); \ -} while (0) - - DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT); - DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT); - DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT); - DUMP(CH7017_ACTIVE_INPUT_LINE_OUTPUT); - DUMP(CH7017_LVDS_PLL_VCO_CONTROL); - DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV); - DUMP(CH7017_LVDS_CONTROL_2); - DUMP(CH7017_OUTPUTS_ENABLE); - DUMP(CH7017_LVDS_POWER_DOWN); -} - -static void ch7017_destroy(struct intel_dvo_device *dvo) -{ - struct ch7017_priv *priv = dvo->dev_priv; - - if (priv) { - kfree(priv); - dvo->dev_priv = NULL; - } -} - -struct intel_dvo_dev_ops ch7017_ops = { - .init = ch7017_init, - .detect = ch7017_detect, - .mode_valid = ch7017_mode_valid, - .mode_set = ch7017_mode_set, - .dpms = ch7017_dpms, - .dump_regs = ch7017_dump_regs, - .destroy = ch7017_destroy, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7xxx.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7xxx.c deleted file mode 100644 index 4a036600..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - -Copyright © 2006 Dave Airlie - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#include "dvo.h" - -#define CH7xxx_REG_VID 0x4a -#define CH7xxx_REG_DID 0x4b - -#define CH7011_VID 0x83 /* 7010 as well */ -#define CH7009A_VID 0x84 -#define CH7009B_VID 0x85 -#define CH7301_VID 0x95 - -#define CH7xxx_VID 0x84 -#define CH7xxx_DID 0x17 - -#define CH7xxx_NUM_REGS 0x4c - -#define CH7xxx_CM 0x1c -#define CH7xxx_CM_XCM (1<<0) -#define CH7xxx_CM_MCP (1<<2) -#define CH7xxx_INPUT_CLOCK 0x1d -#define CH7xxx_GPIO 0x1e -#define CH7xxx_GPIO_HPIR (1<<3) -#define CH7xxx_IDF 0x1f - -#define CH7xxx_IDF_HSP (1<<3) -#define CH7xxx_IDF_VSP (1<<4) - -#define CH7xxx_CONNECTION_DETECT 0x20 -#define CH7xxx_CDET_DVI (1<<5) - -#define CH7301_DAC_CNTL 0x21 -#define CH7301_HOTPLUG 0x23 -#define CH7xxx_TCTL 0x31 -#define CH7xxx_TVCO 0x32 -#define CH7xxx_TPCP 0x33 -#define CH7xxx_TPD 0x34 -#define CH7xxx_TPVT 0x35 -#define CH7xxx_TLPF 0x36 -#define CH7xxx_TCT 0x37 -#define CH7301_TEST_PATTERN 0x48 - -#define CH7xxx_PM 0x49 -#define CH7xxx_PM_FPD (1<<0) -#define CH7301_PM_DACPD0 (1<<1) -#define CH7301_PM_DACPD1 (1<<2) -#define CH7301_PM_DACPD2 (1<<3) -#define CH7xxx_PM_DVIL (1<<6) -#define CH7xxx_PM_DVIP (1<<7) - -#define CH7301_SYNC_POLARITY 0x56 -#define CH7301_SYNC_RGB_YUV (1<<0) -#define CH7301_SYNC_POL_DVI (1<<5) - -/** @file - * driver for the Chrontel 7xxx DVI chip over DVO. - */ - -static struct ch7xxx_id_struct { - uint8_t vid; - char *name; -} ch7xxx_ids[] = { - { CH7011_VID, "CH7011" }, - { CH7009A_VID, "CH7009A" }, - { CH7009B_VID, "CH7009B" }, - { CH7301_VID, "CH7301" }, -}; - -struct ch7xxx_priv { - bool quiet; -}; - -static char *ch7xxx_get_id(uint8_t vid) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) { - if (ch7xxx_ids[i].vid == vid) - return ch7xxx_ids[i].name; - } - - return NULL; -} - -/** Reads an 8 bit register */ -static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) -{ - struct ch7xxx_priv *ch7xxx = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - u8 out_buf[2]; - u8 in_buf[2]; - - struct i2c_msg msgs[] = { - { - .addr = dvo->slave_addr, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = dvo->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = in_buf, - } - }; - - out_buf[0] = addr; - out_buf[1] = 0; - - if (i2c_transfer(adapter, msgs, 2) == 2) { - *ch = in_buf[0]; - return true; - }; - - if (!ch7xxx->quiet) { - DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", - addr, adapter->name, dvo->slave_addr); - } - return false; -} - -/** Writes an 8 bit register */ -static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) -{ - struct ch7xxx_priv *ch7xxx = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - uint8_t out_buf[2]; - struct i2c_msg msg = { - .addr = dvo->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - }; - - out_buf[0] = addr; - out_buf[1] = ch; - - if (i2c_transfer(adapter, &msg, 1) == 1) - return true; - - if (!ch7xxx->quiet) { - DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", - addr, adapter->name, dvo->slave_addr); - } - - return false; -} - -static bool ch7xxx_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) -{ - /* this will detect the CH7xxx chip on the specified i2c bus */ - struct ch7xxx_priv *ch7xxx; - uint8_t vendor, device; - char *name; - - ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL); - if (ch7xxx == NULL) - return false; - - dvo->i2c_bus = adapter; - dvo->dev_priv = ch7xxx; - ch7xxx->quiet = true; - - if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor)) - goto out; - - name = ch7xxx_get_id(vendor); - if (!name) { - DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s " - "slave %d.\n", - vendor, adapter->name, dvo->slave_addr); - goto out; - } - - - if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device)) - goto out; - - if (device != CH7xxx_DID) { - DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s " - "slave %d.\n", - vendor, adapter->name, dvo->slave_addr); - goto out; - } - - ch7xxx->quiet = false; - DRM_DEBUG_KMS("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", - name, vendor, device); - return true; -out: - kfree(ch7xxx); - return false; -} - -static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo) -{ - uint8_t cdet, orig_pm, pm; - - ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm); - - pm = orig_pm; - pm &= ~CH7xxx_PM_FPD; - pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP; - - ch7xxx_writeb(dvo, CH7xxx_PM, pm); - - ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet); - - ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm); - - if (cdet & CH7xxx_CDET_DVI) - return connector_status_connected; - return connector_status_disconnected; -} - -static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo, - struct drm_display_mode *mode) -{ - if (mode->clock > 165000) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static void ch7xxx_mode_set(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - uint8_t tvco, tpcp, tpd, tlpf, idf; - - if (mode->clock <= 65000) { - tvco = 0x23; - tpcp = 0x08; - tpd = 0x16; - tlpf = 0x60; - } else { - tvco = 0x2d; - tpcp = 0x06; - tpd = 0x26; - tlpf = 0xa0; - } - - ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00); - ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco); - ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp); - ch7xxx_writeb(dvo, CH7xxx_TPD, tpd); - ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30); - ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf); - ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00); - - ch7xxx_readb(dvo, CH7xxx_IDF, &idf); - - idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP); - if (mode->flags & DRM_MODE_FLAG_PHSYNC) - idf |= CH7xxx_IDF_HSP; - - if (mode->flags & DRM_MODE_FLAG_PVSYNC) - idf |= CH7xxx_IDF_HSP; - - ch7xxx_writeb(dvo, CH7xxx_IDF, idf); -} - -/* set the CH7xxx power state */ -static void ch7xxx_dpms(struct intel_dvo_device *dvo, int mode) -{ - if (mode == DRM_MODE_DPMS_ON) - ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP); - else - ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD); -} - -static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) -{ - int i; - - for (i = 0; i < CH7xxx_NUM_REGS; i++) { - uint8_t val; - if ((i % 8) == 0) - DRM_LOG_KMS("\n %02X: ", i); - ch7xxx_readb(dvo, i, &val); - DRM_LOG_KMS("%02X ", val); - } -} - -static void ch7xxx_destroy(struct intel_dvo_device *dvo) -{ - struct ch7xxx_priv *ch7xxx = dvo->dev_priv; - - if (ch7xxx) { - kfree(ch7xxx); - dvo->dev_priv = NULL; - } -} - -struct intel_dvo_dev_ops ch7xxx_ops = { - .init = ch7xxx_init, - .detect = ch7xxx_detect, - .mode_valid = ch7xxx_mode_valid, - .mode_set = ch7xxx_mode_set, - .dpms = ch7xxx_dpms, - .dump_regs = ch7xxx_dump_regs, - .destroy = ch7xxx_destroy, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ivch.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ivch.c deleted file mode 100644 index 04f2893d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_ivch.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright © 2006 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "dvo.h" - -/* - * register definitions for the i82807aa. - * - * Documentation on this chipset can be found in datasheet #29069001 at - * intel.com. - */ - -/* - * VCH Revision & GMBus Base Addr - */ -#define VR00 0x00 -# define VR00_BASE_ADDRESS_MASK 0x007f - -/* - * Functionality Enable - */ -#define VR01 0x01 - -/* - * Enable the panel fitter - */ -# define VR01_PANEL_FIT_ENABLE (1 << 3) -/* - * Enables the LCD display. - * - * This must not be set while VR01_DVO_BYPASS_ENABLE is set. - */ -# define VR01_LCD_ENABLE (1 << 2) -/** Enables the DVO repeater. */ -# define VR01_DVO_BYPASS_ENABLE (1 << 1) -/** Enables the DVO clock */ -# define VR01_DVO_ENABLE (1 << 0) - -/* - * LCD Interface Format - */ -#define VR10 0x10 -/** Enables LVDS output instead of CMOS */ -# define VR10_LVDS_ENABLE (1 << 4) -/** Enables 18-bit LVDS output. */ -# define VR10_INTERFACE_1X18 (0 << 2) -/** Enables 24-bit LVDS or CMOS output */ -# define VR10_INTERFACE_1X24 (1 << 2) -/** Enables 2x18-bit LVDS or CMOS output. */ -# define VR10_INTERFACE_2X18 (2 << 2) -/** Enables 2x24-bit LVDS output */ -# define VR10_INTERFACE_2X24 (3 << 2) - -/* - * VR20 LCD Horizontal Display Size - */ -#define VR20 0x20 - -/* - * LCD Vertical Display Size - */ -#define VR21 0x20 - -/* - * Panel power down status - */ -#define VR30 0x30 -/** Read only bit indicating that the panel is not in a safe poweroff state. */ -# define VR30_PANEL_ON (1 << 15) - -#define VR40 0x40 -# define VR40_STALL_ENABLE (1 << 13) -# define VR40_VERTICAL_INTERP_ENABLE (1 << 12) -# define VR40_ENHANCED_PANEL_FITTING (1 << 11) -# define VR40_HORIZONTAL_INTERP_ENABLE (1 << 10) -# define VR40_AUTO_RATIO_ENABLE (1 << 9) -# define VR40_CLOCK_GATING_ENABLE (1 << 8) - -/* - * Panel Fitting Vertical Ratio - * (((image_height - 1) << 16) / ((panel_height - 1))) >> 2 - */ -#define VR41 0x41 - -/* - * Panel Fitting Horizontal Ratio - * (((image_width - 1) << 16) / ((panel_width - 1))) >> 2 - */ -#define VR42 0x42 - -/* - * Horizontal Image Size - */ -#define VR43 0x43 - -/* VR80 GPIO 0 - */ -#define VR80 0x80 -#define VR81 0x81 -#define VR82 0x82 -#define VR83 0x83 -#define VR84 0x84 -#define VR85 0x85 -#define VR86 0x86 -#define VR87 0x87 - -/* VR88 GPIO 8 - */ -#define VR88 0x88 - -/* Graphics BIOS scratch 0 - */ -#define VR8E 0x8E -# define VR8E_PANEL_TYPE_MASK (0xf << 0) -# define VR8E_PANEL_INTERFACE_CMOS (0 << 4) -# define VR8E_PANEL_INTERFACE_LVDS (1 << 4) -# define VR8E_FORCE_DEFAULT_PANEL (1 << 5) - -/* Graphics BIOS scratch 1 - */ -#define VR8F 0x8F -# define VR8F_VCH_PRESENT (1 << 0) -# define VR8F_DISPLAY_CONN (1 << 1) -# define VR8F_POWER_MASK (0x3c) -# define VR8F_POWER_POS (2) - - -struct ivch_priv { - bool quiet; - - uint16_t width, height; -}; - - -static void ivch_dump_regs(struct intel_dvo_device *dvo); - -/** - * Reads a register on the ivch. - * - * Each of the 256 registers are 16 bits long. - */ -static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) -{ - struct ivch_priv *priv = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - u8 out_buf[1]; - u8 in_buf[2]; - - struct i2c_msg msgs[] = { - { - .addr = dvo->slave_addr, - .flags = I2C_M_RD, - .len = 0, - }, - { - .addr = 0, - .flags = I2C_M_NOSTART, - .len = 1, - .buf = out_buf, - }, - { - .addr = dvo->slave_addr, - .flags = I2C_M_RD | I2C_M_NOSTART, - .len = 2, - .buf = in_buf, - } - }; - - out_buf[0] = addr; - - if (i2c_transfer(adapter, msgs, 3) == 3) { - *data = (in_buf[1] << 8) | in_buf[0]; - return true; - }; - - if (!priv->quiet) { - DRM_DEBUG_KMS("Unable to read register 0x%02x from " - "%s:%02x.\n", - addr, adapter->name, dvo->slave_addr); - } - return false; -} - -/** Writes a 16-bit register on the ivch */ -static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) -{ - struct ivch_priv *priv = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - u8 out_buf[3]; - struct i2c_msg msg = { - .addr = dvo->slave_addr, - .flags = 0, - .len = 3, - .buf = out_buf, - }; - - out_buf[0] = addr; - out_buf[1] = data & 0xff; - out_buf[2] = data >> 8; - - if (i2c_transfer(adapter, &msg, 1) == 1) - return true; - - if (!priv->quiet) { - DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", - addr, adapter->name, dvo->slave_addr); - } - - return false; -} - -/** Probes the given bus and slave address for an ivch */ -static bool ivch_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) -{ - struct ivch_priv *priv; - uint16_t temp; - - priv = kzalloc(sizeof(struct ivch_priv), GFP_KERNEL); - if (priv == NULL) - return false; - - dvo->i2c_bus = adapter; - dvo->dev_priv = priv; - priv->quiet = true; - - if (!ivch_read(dvo, VR00, &temp)) - goto out; - priv->quiet = false; - - /* Since the identification bits are probably zeroes, which doesn't seem - * very unique, check that the value in the base address field matches - * the address it's responding on. - */ - if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) { - DRM_DEBUG_KMS("ivch detect failed due to address mismatch " - "(%d vs %d)\n", - (temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr); - goto out; - } - - ivch_read(dvo, VR20, &priv->width); - ivch_read(dvo, VR21, &priv->height); - - return true; - -out: - kfree(priv); - return false; -} - -static enum drm_connector_status ivch_detect(struct intel_dvo_device *dvo) -{ - return connector_status_connected; -} - -static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo, - struct drm_display_mode *mode) -{ - if (mode->clock > 112000) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -/** Sets the power state of the panel connected to the ivch */ -static void ivch_dpms(struct intel_dvo_device *dvo, int mode) -{ - int i; - uint16_t vr01, vr30, backlight; - - /* Set the new power state of the panel. */ - if (!ivch_read(dvo, VR01, &vr01)) - return; - - if (mode == DRM_MODE_DPMS_ON) - backlight = 1; - else - backlight = 0; - ivch_write(dvo, VR80, backlight); - - if (mode == DRM_MODE_DPMS_ON) - vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE; - else - vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE); - - ivch_write(dvo, VR01, vr01); - - /* Wait for the panel to make its state transition */ - for (i = 0; i < 100; i++) { - if (!ivch_read(dvo, VR30, &vr30)) - break; - - if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DRM_MODE_DPMS_ON)) - break; - udelay(1000); - } - /* wait some more; vch may fail to resync sometimes without this */ - udelay(16 * 1000); -} - -static void ivch_mode_set(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - uint16_t vr40 = 0; - uint16_t vr01; - - vr01 = 0; - vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE | - VR40_HORIZONTAL_INTERP_ENABLE); - - if (mode->hdisplay != adjusted_mode->hdisplay || - mode->vdisplay != adjusted_mode->vdisplay) { - uint16_t x_ratio, y_ratio; - - vr01 |= VR01_PANEL_FIT_ENABLE; - vr40 |= VR40_CLOCK_GATING_ENABLE; - x_ratio = (((mode->hdisplay - 1) << 16) / - (adjusted_mode->hdisplay - 1)) >> 2; - y_ratio = (((mode->vdisplay - 1) << 16) / - (adjusted_mode->vdisplay - 1)) >> 2; - ivch_write(dvo, VR42, x_ratio); - ivch_write(dvo, VR41, y_ratio); - } else { - vr01 &= ~VR01_PANEL_FIT_ENABLE; - vr40 &= ~VR40_CLOCK_GATING_ENABLE; - } - vr40 &= ~VR40_AUTO_RATIO_ENABLE; - - ivch_write(dvo, VR01, vr01); - ivch_write(dvo, VR40, vr40); - - ivch_dump_regs(dvo); -} - -static void ivch_dump_regs(struct intel_dvo_device *dvo) -{ - uint16_t val; - - ivch_read(dvo, VR00, &val); - DRM_LOG_KMS("VR00: 0x%04x\n", val); - ivch_read(dvo, VR01, &val); - DRM_LOG_KMS("VR01: 0x%04x\n", val); - ivch_read(dvo, VR30, &val); - DRM_LOG_KMS("VR30: 0x%04x\n", val); - ivch_read(dvo, VR40, &val); - DRM_LOG_KMS("VR40: 0x%04x\n", val); - - /* GPIO registers */ - ivch_read(dvo, VR80, &val); - DRM_LOG_KMS("VR80: 0x%04x\n", val); - ivch_read(dvo, VR81, &val); - DRM_LOG_KMS("VR81: 0x%04x\n", val); - ivch_read(dvo, VR82, &val); - DRM_LOG_KMS("VR82: 0x%04x\n", val); - ivch_read(dvo, VR83, &val); - DRM_LOG_KMS("VR83: 0x%04x\n", val); - ivch_read(dvo, VR84, &val); - DRM_LOG_KMS("VR84: 0x%04x\n", val); - ivch_read(dvo, VR85, &val); - DRM_LOG_KMS("VR85: 0x%04x\n", val); - ivch_read(dvo, VR86, &val); - DRM_LOG_KMS("VR86: 0x%04x\n", val); - ivch_read(dvo, VR87, &val); - DRM_LOG_KMS("VR87: 0x%04x\n", val); - ivch_read(dvo, VR88, &val); - DRM_LOG_KMS("VR88: 0x%04x\n", val); - - /* Scratch register 0 - AIM Panel type */ - ivch_read(dvo, VR8E, &val); - DRM_LOG_KMS("VR8E: 0x%04x\n", val); - - /* Scratch register 1 - Status register */ - ivch_read(dvo, VR8F, &val); - DRM_LOG_KMS("VR8F: 0x%04x\n", val); -} - -static void ivch_destroy(struct intel_dvo_device *dvo) -{ - struct ivch_priv *priv = dvo->dev_priv; - - if (priv) { - kfree(priv); - dvo->dev_priv = NULL; - } -} - -struct intel_dvo_dev_ops ivch_ops = { - .init = ivch_init, - .dpms = ivch_dpms, - .mode_valid = ivch_mode_valid, - .mode_set = ivch_mode_set, - .detect = ivch_detect, - .dump_regs = ivch_dump_regs, - .destroy = ivch_destroy, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_sil164.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_sil164.c deleted file mode 100644 index a0b13a6f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_sil164.c +++ /dev/null @@ -1,263 +0,0 @@ -/************************************************************************** - -Copyright © 2006 Dave Airlie - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#include "dvo.h" - -#define SIL164_VID 0x0001 -#define SIL164_DID 0x0006 - -#define SIL164_VID_LO 0x00 -#define SIL164_VID_HI 0x01 -#define SIL164_DID_LO 0x02 -#define SIL164_DID_HI 0x03 -#define SIL164_REV 0x04 -#define SIL164_RSVD 0x05 -#define SIL164_FREQ_LO 0x06 -#define SIL164_FREQ_HI 0x07 - -#define SIL164_REG8 0x08 -#define SIL164_8_VEN (1<<5) -#define SIL164_8_HEN (1<<4) -#define SIL164_8_DSEL (1<<3) -#define SIL164_8_BSEL (1<<2) -#define SIL164_8_EDGE (1<<1) -#define SIL164_8_PD (1<<0) - -#define SIL164_REG9 0x09 -#define SIL164_9_VLOW (1<<7) -#define SIL164_9_MSEL_MASK (0x7<<4) -#define SIL164_9_TSEL (1<<3) -#define SIL164_9_RSEN (1<<2) -#define SIL164_9_HTPLG (1<<1) -#define SIL164_9_MDI (1<<0) - -#define SIL164_REGC 0x0c - -struct sil164_priv { - //I2CDevRec d; - bool quiet; -}; - -#define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr)) - -static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) -{ - struct sil164_priv *sil = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - u8 out_buf[2]; - u8 in_buf[2]; - - struct i2c_msg msgs[] = { - { - .addr = dvo->slave_addr, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = dvo->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = in_buf, - } - }; - - out_buf[0] = addr; - out_buf[1] = 0; - - if (i2c_transfer(adapter, msgs, 2) == 2) { - *ch = in_buf[0]; - return true; - }; - - if (!sil->quiet) { - DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", - addr, adapter->name, dvo->slave_addr); - } - return false; -} - -static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) -{ - struct sil164_priv *sil = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - uint8_t out_buf[2]; - struct i2c_msg msg = { - .addr = dvo->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - }; - - out_buf[0] = addr; - out_buf[1] = ch; - - if (i2c_transfer(adapter, &msg, 1) == 1) - return true; - - if (!sil->quiet) { - DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", - addr, adapter->name, dvo->slave_addr); - } - - return false; -} - -/* Silicon Image 164 driver for chip on i2c bus */ -static bool sil164_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) -{ - /* this will detect the SIL164 chip on the specified i2c bus */ - struct sil164_priv *sil; - unsigned char ch; - - sil = kzalloc(sizeof(struct sil164_priv), GFP_KERNEL); - if (sil == NULL) - return false; - - dvo->i2c_bus = adapter; - dvo->dev_priv = sil; - sil->quiet = true; - - if (!sil164_readb(dvo, SIL164_VID_LO, &ch)) - goto out; - - if (ch != (SIL164_VID & 0xff)) { - DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n", - ch, adapter->name, dvo->slave_addr); - goto out; - } - - if (!sil164_readb(dvo, SIL164_DID_LO, &ch)) - goto out; - - if (ch != (SIL164_DID & 0xff)) { - DRM_DEBUG_KMS("sil164 not detected got %d: from %s Slave %d.\n", - ch, adapter->name, dvo->slave_addr); - goto out; - } - sil->quiet = false; - - DRM_DEBUG_KMS("init sil164 dvo controller successfully!\n"); - return true; - -out: - kfree(sil); - return false; -} - -static enum drm_connector_status sil164_detect(struct intel_dvo_device *dvo) -{ - uint8_t reg9; - - sil164_readb(dvo, SIL164_REG9, ®9); - - if (reg9 & SIL164_9_HTPLG) - return connector_status_connected; - else - return connector_status_disconnected; -} - -static enum drm_mode_status sil164_mode_valid(struct intel_dvo_device *dvo, - struct drm_display_mode *mode) -{ - return MODE_OK; -} - -static void sil164_mode_set(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* As long as the basics are set up, since we don't have clock - * dependencies in the mode setup, we can just leave the - * registers alone and everything will work fine. - */ - /* recommended programming sequence from doc */ - /*sil164_writeb(sil, 0x08, 0x30); - sil164_writeb(sil, 0x09, 0x00); - sil164_writeb(sil, 0x0a, 0x90); - sil164_writeb(sil, 0x0c, 0x89); - sil164_writeb(sil, 0x08, 0x31);*/ - /* don't do much */ - return; -} - -/* set the SIL164 power state */ -static void sil164_dpms(struct intel_dvo_device *dvo, int mode) -{ - int ret; - unsigned char ch; - - ret = sil164_readb(dvo, SIL164_REG8, &ch); - if (ret == false) - return; - - if (mode == DRM_MODE_DPMS_ON) - ch |= SIL164_8_PD; - else - ch &= ~SIL164_8_PD; - - sil164_writeb(dvo, SIL164_REG8, ch); - return; -} - -static void sil164_dump_regs(struct intel_dvo_device *dvo) -{ - uint8_t val; - - sil164_readb(dvo, SIL164_FREQ_LO, &val); - DRM_LOG_KMS("SIL164_FREQ_LO: 0x%02x\n", val); - sil164_readb(dvo, SIL164_FREQ_HI, &val); - DRM_LOG_KMS("SIL164_FREQ_HI: 0x%02x\n", val); - sil164_readb(dvo, SIL164_REG8, &val); - DRM_LOG_KMS("SIL164_REG8: 0x%02x\n", val); - sil164_readb(dvo, SIL164_REG9, &val); - DRM_LOG_KMS("SIL164_REG9: 0x%02x\n", val); - sil164_readb(dvo, SIL164_REGC, &val); - DRM_LOG_KMS("SIL164_REGC: 0x%02x\n", val); -} - -static void sil164_destroy(struct intel_dvo_device *dvo) -{ - struct sil164_priv *sil = dvo->dev_priv; - - if (sil) { - kfree(sil); - dvo->dev_priv = NULL; - } -} - -struct intel_dvo_dev_ops sil164_ops = { - .init = sil164_init, - .detect = sil164_detect, - .mode_valid = sil164_mode_valid, - .mode_set = sil164_mode_set, - .dpms = sil164_dpms, - .dump_regs = sil164_dump_regs, - .destroy = sil164_destroy, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_tfp410.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_tfp410.c deleted file mode 100644 index aa2cd3ec..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/dvo_tfp410.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright © 2007 Dave Mueller - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Dave Mueller - * - */ - -#include "dvo.h" - -/* register definitions according to the TFP410 data sheet */ -#define TFP410_VID 0x014C -#define TFP410_DID 0x0410 - -#define TFP410_VID_LO 0x00 -#define TFP410_VID_HI 0x01 -#define TFP410_DID_LO 0x02 -#define TFP410_DID_HI 0x03 -#define TFP410_REV 0x04 - -#define TFP410_CTL_1 0x08 -#define TFP410_CTL_1_TDIS (1<<6) -#define TFP410_CTL_1_VEN (1<<5) -#define TFP410_CTL_1_HEN (1<<4) -#define TFP410_CTL_1_DSEL (1<<3) -#define TFP410_CTL_1_BSEL (1<<2) -#define TFP410_CTL_1_EDGE (1<<1) -#define TFP410_CTL_1_PD (1<<0) - -#define TFP410_CTL_2 0x09 -#define TFP410_CTL_2_VLOW (1<<7) -#define TFP410_CTL_2_MSEL_MASK (0x7<<4) -#define TFP410_CTL_2_MSEL (1<<4) -#define TFP410_CTL_2_TSEL (1<<3) -#define TFP410_CTL_2_RSEN (1<<2) -#define TFP410_CTL_2_HTPLG (1<<1) -#define TFP410_CTL_2_MDI (1<<0) - -#define TFP410_CTL_3 0x0A -#define TFP410_CTL_3_DK_MASK (0x7<<5) -#define TFP410_CTL_3_DK (1<<5) -#define TFP410_CTL_3_DKEN (1<<4) -#define TFP410_CTL_3_CTL_MASK (0x7<<1) -#define TFP410_CTL_3_CTL (1<<1) - -#define TFP410_USERCFG 0x0B - -#define TFP410_DE_DLY 0x32 - -#define TFP410_DE_CTL 0x33 -#define TFP410_DE_CTL_DEGEN (1<<6) -#define TFP410_DE_CTL_VSPOL (1<<5) -#define TFP410_DE_CTL_HSPOL (1<<4) -#define TFP410_DE_CTL_DEDLY8 (1<<0) - -#define TFP410_DE_TOP 0x34 - -#define TFP410_DE_CNT_LO 0x36 -#define TFP410_DE_CNT_HI 0x37 - -#define TFP410_DE_LIN_LO 0x38 -#define TFP410_DE_LIN_HI 0x39 - -#define TFP410_H_RES_LO 0x3A -#define TFP410_H_RES_HI 0x3B - -#define TFP410_V_RES_LO 0x3C -#define TFP410_V_RES_HI 0x3D - -struct tfp410_priv { - bool quiet; -}; - -static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) -{ - struct tfp410_priv *tfp = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - u8 out_buf[2]; - u8 in_buf[2]; - - struct i2c_msg msgs[] = { - { - .addr = dvo->slave_addr, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = dvo->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = in_buf, - } - }; - - out_buf[0] = addr; - out_buf[1] = 0; - - if (i2c_transfer(adapter, msgs, 2) == 2) { - *ch = in_buf[0]; - return true; - }; - - if (!tfp->quiet) { - DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n", - addr, adapter->name, dvo->slave_addr); - } - return false; -} - -static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) -{ - struct tfp410_priv *tfp = dvo->dev_priv; - struct i2c_adapter *adapter = dvo->i2c_bus; - uint8_t out_buf[2]; - struct i2c_msg msg = { - .addr = dvo->slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - }; - - out_buf[0] = addr; - out_buf[1] = ch; - - if (i2c_transfer(adapter, &msg, 1) == 1) - return true; - - if (!tfp->quiet) { - DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n", - addr, adapter->name, dvo->slave_addr); - } - - return false; -} - -static int tfp410_getid(struct intel_dvo_device *dvo, int addr) -{ - uint8_t ch1, ch2; - - if (tfp410_readb(dvo, addr+0, &ch1) && - tfp410_readb(dvo, addr+1, &ch2)) - return ((ch2 << 8) & 0xFF00) | (ch1 & 0x00FF); - - return -1; -} - -/* Ti TFP410 driver for chip on i2c bus */ -static bool tfp410_init(struct intel_dvo_device *dvo, - struct i2c_adapter *adapter) -{ - /* this will detect the tfp410 chip on the specified i2c bus */ - struct tfp410_priv *tfp; - int id; - - tfp = kzalloc(sizeof(struct tfp410_priv), GFP_KERNEL); - if (tfp == NULL) - return false; - - dvo->i2c_bus = adapter; - dvo->dev_priv = tfp; - tfp->quiet = true; - - if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { - DRM_DEBUG_KMS("tfp410 not detected got VID %X: from %s " - "Slave %d.\n", - id, adapter->name, dvo->slave_addr); - goto out; - } - - if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { - DRM_DEBUG_KMS("tfp410 not detected got DID %X: from %s " - "Slave %d.\n", - id, adapter->name, dvo->slave_addr); - goto out; - } - tfp->quiet = false; - return true; -out: - kfree(tfp); - return false; -} - -static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo) -{ - enum drm_connector_status ret = connector_status_disconnected; - uint8_t ctl2; - - if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) { - if (ctl2 & TFP410_CTL_2_RSEN) - ret = connector_status_connected; - else - ret = connector_status_disconnected; - } - - return ret; -} - -static enum drm_mode_status tfp410_mode_valid(struct intel_dvo_device *dvo, - struct drm_display_mode *mode) -{ - return MODE_OK; -} - -static void tfp410_mode_set(struct intel_dvo_device *dvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* As long as the basics are set up, since we don't have clock dependencies - * in the mode setup, we can just leave the registers alone and everything - * will work fine. - */ - /* don't do much */ - return; -} - -/* set the tfp410 power state */ -static void tfp410_dpms(struct intel_dvo_device *dvo, int mode) -{ - uint8_t ctl1; - - if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1)) - return; - - if (mode == DRM_MODE_DPMS_ON) - ctl1 |= TFP410_CTL_1_PD; - else - ctl1 &= ~TFP410_CTL_1_PD; - - tfp410_writeb(dvo, TFP410_CTL_1, ctl1); -} - -static void tfp410_dump_regs(struct intel_dvo_device *dvo) -{ - uint8_t val, val2; - - tfp410_readb(dvo, TFP410_REV, &val); - DRM_LOG_KMS("TFP410_REV: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_CTL_1, &val); - DRM_LOG_KMS("TFP410_CTL1: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_CTL_2, &val); - DRM_LOG_KMS("TFP410_CTL2: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_CTL_3, &val); - DRM_LOG_KMS("TFP410_CTL3: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_USERCFG, &val); - DRM_LOG_KMS("TFP410_USERCFG: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_DE_DLY, &val); - DRM_LOG_KMS("TFP410_DE_DLY: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_DE_CTL, &val); - DRM_LOG_KMS("TFP410_DE_CTL: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_DE_TOP, &val); - DRM_LOG_KMS("TFP410_DE_TOP: 0x%02X\n", val); - tfp410_readb(dvo, TFP410_DE_CNT_LO, &val); - tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2); - DRM_LOG_KMS("TFP410_DE_CNT: 0x%02X%02X\n", val2, val); - tfp410_readb(dvo, TFP410_DE_LIN_LO, &val); - tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2); - DRM_LOG_KMS("TFP410_DE_LIN: 0x%02X%02X\n", val2, val); - tfp410_readb(dvo, TFP410_H_RES_LO, &val); - tfp410_readb(dvo, TFP410_H_RES_HI, &val2); - DRM_LOG_KMS("TFP410_H_RES: 0x%02X%02X\n", val2, val); - tfp410_readb(dvo, TFP410_V_RES_LO, &val); - tfp410_readb(dvo, TFP410_V_RES_HI, &val2); - DRM_LOG_KMS("TFP410_V_RES: 0x%02X%02X\n", val2, val); -} - -static void tfp410_destroy(struct intel_dvo_device *dvo) -{ - struct tfp410_priv *tfp = dvo->dev_priv; - - if (tfp) { - kfree(tfp); - dvo->dev_priv = NULL; - } -} - -struct intel_dvo_dev_ops tfp410_ops = { - .init = tfp410_init, - .detect = tfp410_detect, - .mode_valid = tfp410_mode_valid, - .mode_set = tfp410_mode_set, - .dpms = tfp410_dpms, - .dump_regs = tfp410_dump_regs, - .destroy = tfp410_destroy, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_debugfs.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_debugfs.c deleted file mode 100644 index e6162a16..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_debugfs.c +++ /dev/null @@ -1,1890 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Keith Packard - * - */ - -#include -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "intel_drv.h" -#include "intel_ringbuffer.h" -#include "i915_drm.h" -#include "i915_drv.h" - -#define DRM_I915_RING_DEBUG 1 - - -#if defined(CONFIG_DEBUG_FS) - -enum { - ACTIVE_LIST, - FLUSHING_LIST, - INACTIVE_LIST, - PINNED_LIST, - DEFERRED_FREE_LIST, -}; - -static const char *yesno(int v) -{ - return v ? "yes" : "no"; -} - -static int i915_capabilities(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - const struct intel_device_info *info = INTEL_INFO(dev); - - seq_printf(m, "gen: %d\n", info->gen); - seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev)); -#define B(x) seq_printf(m, #x ": %s\n", yesno(info->x)) - B(is_mobile); - B(is_i85x); - B(is_i915g); - B(is_i945gm); - B(is_g33); - B(need_gfx_hws); - B(is_g4x); - B(is_pineview); - B(is_broadwater); - B(is_crestline); - B(has_fbc); - B(has_pipe_cxsr); - B(has_hotplug); - B(cursor_needs_physical); - B(has_overlay); - B(overlay_needs_physical); - B(supports_tv); - B(has_bsd_ring); - B(has_blt_ring); - B(has_llc); -#undef B - - return 0; -} - -static const char *get_pin_flag(struct drm_i915_gem_object *obj) -{ - if (obj->user_pin_count > 0) - return "P"; - else if (obj->pin_count > 0) - return "p"; - else - return " "; -} - -static const char *get_tiling_flag(struct drm_i915_gem_object *obj) -{ - switch (obj->tiling_mode) { - default: - case I915_TILING_NONE: return " "; - case I915_TILING_X: return "X"; - case I915_TILING_Y: return "Y"; - } -} - -static const char *cache_level_str(int type) -{ - switch (type) { - case I915_CACHE_NONE: return " uncached"; - case I915_CACHE_LLC: return " snooped (LLC)"; - case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)"; - default: return ""; - } -} - -static void -describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) -{ - seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", - &obj->base, - get_pin_flag(obj), - get_tiling_flag(obj), - obj->base.size / 1024, - obj->base.read_domains, - obj->base.write_domain, - obj->last_rendering_seqno, - obj->last_fenced_seqno, - cache_level_str(obj->cache_level), - obj->dirty ? " dirty" : "", - obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); - if (obj->base.name) - seq_printf(m, " (name: %d)", obj->base.name); - if (obj->fence_reg != I915_FENCE_REG_NONE) - seq_printf(m, " (fence: %d)", obj->fence_reg); - if (obj->gtt_space != NULL) - seq_printf(m, " (gtt offset: %08x, size: %08x)", - obj->gtt_offset, (unsigned int)obj->gtt_space->size); - if (obj->pin_mappable || obj->fault_mappable) { - char s[3], *t = s; - if (obj->pin_mappable) - *t++ = 'p'; - if (obj->fault_mappable) - *t++ = 'f'; - *t = '\0'; - seq_printf(m, " (%s mappable)", s); - } - if (obj->ring != NULL) - seq_printf(m, " (%s)", obj->ring->name); -} - -static int i915_gem_object_list_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - uintptr_t list = (uintptr_t) node->info_ent->data; - struct list_head *head; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - size_t total_obj_size, total_gtt_size; - int count, ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - switch (list) { - case ACTIVE_LIST: - seq_printf(m, "Active:\n"); - head = &dev_priv->mm.active_list; - break; - case INACTIVE_LIST: - seq_printf(m, "Inactive:\n"); - head = &dev_priv->mm.inactive_list; - break; - case PINNED_LIST: - seq_printf(m, "Pinned:\n"); - head = &dev_priv->mm.pinned_list; - break; - case FLUSHING_LIST: - seq_printf(m, "Flushing:\n"); - head = &dev_priv->mm.flushing_list; - break; - case DEFERRED_FREE_LIST: - seq_printf(m, "Deferred free:\n"); - head = &dev_priv->mm.deferred_free_list; - break; - default: - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - - total_obj_size = total_gtt_size = count = 0; - list_for_each_entry(obj, head, mm_list) { - seq_printf(m, " "); - describe_obj(m, obj); - seq_printf(m, "\n"); - total_obj_size += obj->base.size; - total_gtt_size += obj->gtt_space->size; - count++; - } - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", - count, total_obj_size, total_gtt_size); - return 0; -} - -#define count_objects(list, member) do { \ - list_for_each_entry(obj, list, member) { \ - size += obj->gtt_space->size; \ - ++count; \ - if (obj->map_and_fenceable) { \ - mappable_size += obj->gtt_space->size; \ - ++mappable_count; \ - } \ - } \ -} while (0) - -static int i915_gem_object_info(struct seq_file *m, void* data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 count, mappable_count; - size_t size, mappable_size; - struct drm_i915_gem_object *obj; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - seq_printf(m, "%u objects, %zu bytes\n", - dev_priv->mm.object_count, - dev_priv->mm.object_memory); - - size = count = mappable_size = mappable_count = 0; - count_objects(&dev_priv->mm.gtt_list, gtt_list); - seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", - count, mappable_count, size, mappable_size); - - size = count = mappable_size = mappable_count = 0; - count_objects(&dev_priv->mm.active_list, mm_list); - count_objects(&dev_priv->mm.flushing_list, mm_list); - seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", - count, mappable_count, size, mappable_size); - - size = count = mappable_size = mappable_count = 0; - count_objects(&dev_priv->mm.pinned_list, mm_list); - seq_printf(m, " %u [%u] pinned objects, %zu [%zu] bytes\n", - count, mappable_count, size, mappable_size); - - size = count = mappable_size = mappable_count = 0; - count_objects(&dev_priv->mm.inactive_list, mm_list); - seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", - count, mappable_count, size, mappable_size); - - size = count = mappable_size = mappable_count = 0; - count_objects(&dev_priv->mm.deferred_free_list, mm_list); - seq_printf(m, " %u [%u] freed objects, %zu [%zu] bytes\n", - count, mappable_count, size, mappable_size); - - size = count = mappable_size = mappable_count = 0; - list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { - if (obj->fault_mappable) { - size += obj->gtt_space->size; - ++count; - } - if (obj->pin_mappable) { - mappable_size += obj->gtt_space->size; - ++mappable_count; - } - } - seq_printf(m, "%u pinned mappable objects, %zu bytes\n", - mappable_count, mappable_size); - seq_printf(m, "%u fault mappable objects, %zu bytes\n", - count, size); - - seq_printf(m, "%zu [%zu] gtt total\n", - dev_priv->mm.gtt_total, dev_priv->mm.mappable_gtt_total); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_gem_gtt_info(struct seq_file *m, void* data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - size_t total_obj_size, total_gtt_size; - int count, ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - total_obj_size = total_gtt_size = count = 0; - list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { - seq_printf(m, " "); - describe_obj(m, obj); - seq_printf(m, "\n"); - total_obj_size += obj->base.size; - total_gtt_size += obj->gtt_space->size; - count++; - } - - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n", - count, total_obj_size, total_gtt_size); - - return 0; -} - - -static int i915_gem_pageflip_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - unsigned long flags; - struct intel_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { - const char pipe = pipe_name(crtc->pipe); - const char plane = plane_name(crtc->plane); - struct intel_unpin_work *work; - - spin_lock_irqsave(&dev->event_lock, flags); - work = crtc->unpin_work; - if (work == NULL) { - seq_printf(m, "No flip due on pipe %c (plane %c)\n", - pipe, plane); - } else { - if (!work->pending) { - seq_printf(m, "Flip queued on pipe %c (plane %c)\n", - pipe, plane); - } else { - seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n", - pipe, plane); - } - if (work->enable_stall_check) - seq_printf(m, "Stall check enabled, "); - else - seq_printf(m, "Stall check waiting for page flip ioctl, "); - seq_printf(m, "%d prepares\n", work->pending); - - if (work->old_fb_obj) { - struct drm_i915_gem_object *obj = work->old_fb_obj; - if (obj) - seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); - } - if (work->pending_flip_obj) { - struct drm_i915_gem_object *obj = work->pending_flip_obj; - if (obj) - seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); - } - } - spin_unlock_irqrestore(&dev->event_lock, flags); - } - - return 0; -} - -static int i915_gem_request_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_request *gem_request; - int ret, count; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - count = 0; - if (!list_empty(&dev_priv->ring[RCS].request_list)) { - seq_printf(m, "Render requests:\n"); - list_for_each_entry(gem_request, - &dev_priv->ring[RCS].request_list, - list) { - seq_printf(m, " %d @ %d\n", - gem_request->seqno, - (int) (jiffies - gem_request->emitted_jiffies)); - } - count++; - } - if (!list_empty(&dev_priv->ring[VCS].request_list)) { - seq_printf(m, "BSD requests:\n"); - list_for_each_entry(gem_request, - &dev_priv->ring[VCS].request_list, - list) { - seq_printf(m, " %d @ %d\n", - gem_request->seqno, - (int) (jiffies - gem_request->emitted_jiffies)); - } - count++; - } - if (!list_empty(&dev_priv->ring[BCS].request_list)) { - seq_printf(m, "BLT requests:\n"); - list_for_each_entry(gem_request, - &dev_priv->ring[BCS].request_list, - list) { - seq_printf(m, " %d @ %d\n", - gem_request->seqno, - (int) (jiffies - gem_request->emitted_jiffies)); - } - count++; - } - mutex_unlock(&dev->struct_mutex); - - if (count == 0) - seq_printf(m, "No requests\n"); - - return 0; -} - -static void i915_ring_seqno_info(struct seq_file *m, - struct intel_ring_buffer *ring) -{ - if (ring->get_seqno) { - seq_printf(m, "Current sequence (%s): %d\n", - ring->name, ring->get_seqno(ring)); - seq_printf(m, "Waiter sequence (%s): %d\n", - ring->name, ring->waiting_seqno); - seq_printf(m, "IRQ sequence (%s): %d\n", - ring->name, ring->irq_seqno); - } -} - -static int i915_gem_seqno_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret, i; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - for (i = 0; i < I915_NUM_RINGS; i++) - i915_ring_seqno_info(m, &dev_priv->ring[i]); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - - -static int i915_interrupt_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret, i, pipe; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - if (!HAS_PCH_SPLIT(dev)) { - seq_printf(m, "Interrupt enable: %08x\n", - I915_READ(IER)); - seq_printf(m, "Interrupt identity: %08x\n", - I915_READ(IIR)); - seq_printf(m, "Interrupt mask: %08x\n", - I915_READ(IMR)); - for_each_pipe(pipe) - seq_printf(m, "Pipe %c stat: %08x\n", - pipe_name(pipe), - I915_READ(PIPESTAT(pipe))); - } else { - seq_printf(m, "North Display Interrupt enable: %08x\n", - I915_READ(DEIER)); - seq_printf(m, "North Display Interrupt identity: %08x\n", - I915_READ(DEIIR)); - seq_printf(m, "North Display Interrupt mask: %08x\n", - I915_READ(DEIMR)); - seq_printf(m, "South Display Interrupt enable: %08x\n", - I915_READ(SDEIER)); - seq_printf(m, "South Display Interrupt identity: %08x\n", - I915_READ(SDEIIR)); - seq_printf(m, "South Display Interrupt mask: %08x\n", - I915_READ(SDEIMR)); - seq_printf(m, "Graphics Interrupt enable: %08x\n", - I915_READ(GTIER)); - seq_printf(m, "Graphics Interrupt identity: %08x\n", - I915_READ(GTIIR)); - seq_printf(m, "Graphics Interrupt mask: %08x\n", - I915_READ(GTIMR)); - } - seq_printf(m, "Interrupts received: %d\n", - atomic_read(&dev_priv->irq_received)); - for (i = 0; i < I915_NUM_RINGS; i++) { - if (IS_GEN6(dev) || IS_GEN7(dev)) { - seq_printf(m, "Graphics Interrupt mask (%s): %08x\n", - dev_priv->ring[i].name, - I915_READ_IMR(&dev_priv->ring[i])); - } - i915_ring_seqno_info(m, &dev_priv->ring[i]); - } - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_gem_fence_regs_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int i, ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); - seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); - for (i = 0; i < dev_priv->num_fence_regs; i++) { - struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj; - - seq_printf(m, "Fenced object[%2d] = ", i); - if (obj == NULL) - seq_printf(m, "unused"); - else - describe_obj(m, obj); - seq_printf(m, "\n"); - } - - mutex_unlock(&dev->struct_mutex); - return 0; -} - -static int i915_hws_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - const volatile u32 __iomem *hws; - int i; - - ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; - hws = (volatile u32 __iomem *)ring->status_page.page_addr; - if (hws == NULL) - return 0; - - for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { - seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", - i * 4, - hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); - } - return 0; -} - -static int i915_ringbuffer_data(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; - if (!ring->obj) { - seq_printf(m, "No ringbuffer setup\n"); - } else { - const u8 __iomem *virt = ring->virtual_start; - uint32_t off; - - for (off = 0; off < ring->size; off += 4) { - uint32_t *ptr = (uint32_t *)(virt + off); - seq_printf(m, "%08x : %08x\n", off, *ptr); - } - } - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_ringbuffer_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - int ret; - - ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; - if (ring->size == 0) - return 0; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - seq_printf(m, "Ring %s:\n", ring->name); - seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); - seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); - seq_printf(m, " Size : %08x\n", ring->size); - seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); - seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); - if (IS_GEN6(dev) || IS_GEN7(dev)) { - seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); - seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); - } - seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); - seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static const char *ring_str(int ring) -{ - switch (ring) { - case RCS: return "render"; - case VCS: return "bsd"; - case BCS: return "blt"; - default: return ""; - } -} - -static const char *pin_flag(int pinned) -{ - if (pinned > 0) - return " P"; - else if (pinned < 0) - return " p"; - else - return ""; -} - -static const char *tiling_flag(int tiling) -{ - switch (tiling) { - default: - case I915_TILING_NONE: return ""; - case I915_TILING_X: return " X"; - case I915_TILING_Y: return " Y"; - } -} - -static const char *dirty_flag(int dirty) -{ - return dirty ? " dirty" : ""; -} - -static const char *purgeable_flag(int purgeable) -{ - return purgeable ? " purgeable" : ""; -} - -static void print_error_buffers(struct seq_file *m, - const char *name, - struct drm_i915_error_buffer *err, - int count) -{ - seq_printf(m, "%s [%d]:\n", name, count); - - while (count--) { - seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s", - err->gtt_offset, - err->size, - err->read_domains, - err->write_domain, - err->seqno, - pin_flag(err->pinned), - tiling_flag(err->tiling), - dirty_flag(err->dirty), - purgeable_flag(err->purgeable), - err->ring != -1 ? " " : "", - ring_str(err->ring), - cache_level_str(err->cache_level)); - - if (err->name) - seq_printf(m, " (name: %d)", err->name); - if (err->fence_reg != I915_FENCE_REG_NONE) - seq_printf(m, " (fence: %d)", err->fence_reg); - - seq_printf(m, "\n"); - err++; - } -} - -static void i915_ring_error_state(struct seq_file *m, - struct drm_device *dev, - struct drm_i915_error_state *error, - unsigned ring) -{ - seq_printf(m, "%s command stream:\n", ring_str(ring)); - seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]); - seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); - seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); - seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); - seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); - seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); - if (ring == RCS && INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); - seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); - } - if (INTEL_INFO(dev)->gen >= 4) - seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); - seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); - if (INTEL_INFO(dev)->gen >= 6) { - seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); - seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); - seq_printf(m, " SYNC_0: 0x%08x\n", - error->semaphore_mboxes[ring][0]); - seq_printf(m, " SYNC_1: 0x%08x\n", - error->semaphore_mboxes[ring][1]); - } - seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); - seq_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); - seq_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); -} - -static int i915_error_state(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_error_state *error; - unsigned long flags; - int i, j, page, offset, elt; - - spin_lock_irqsave(&dev_priv->error_lock, flags); - if (!dev_priv->first_error) { - seq_printf(m, "no error state collected\n"); - goto out; - } - - error = dev_priv->first_error; - - seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, - error->time.tv_usec); - seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); - seq_printf(m, "EIR: 0x%08x\n", error->eir); - seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); - - for (i = 0; i < dev_priv->num_fence_regs; i++) - seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); - - if (INTEL_INFO(dev)->gen >= 6) { - seq_printf(m, "ERROR: 0x%08x\n", error->error); - seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); - } - - i915_ring_error_state(m, dev, error, RCS); - if (HAS_BLT(dev)) - i915_ring_error_state(m, dev, error, BCS); - if (HAS_BSD(dev)) - i915_ring_error_state(m, dev, error, VCS); - - if (error->active_bo) - print_error_buffers(m, "Active", - error->active_bo, - error->active_bo_count); - - if (error->pinned_bo) - print_error_buffers(m, "Pinned", - error->pinned_bo, - error->pinned_bo_count); - - for (i = 0; i < ARRAY_SIZE(error->ring); i++) { - struct drm_i915_error_object *obj; - - if ((obj = error->ring[i].batchbuffer)) { - seq_printf(m, "%s --- gtt_offset = 0x%08x\n", - dev_priv->ring[i].name, - obj->gtt_offset); - offset = 0; - for (page = 0; page < obj->page_count; page++) { - for (elt = 0; elt < PAGE_SIZE/4; elt++) { - seq_printf(m, "%08x : %08x\n", offset, obj->pages[page][elt]); - offset += 4; - } - } - } - - if (error->ring[i].num_requests) { - seq_printf(m, "%s --- %d requests\n", - dev_priv->ring[i].name, - error->ring[i].num_requests); - for (j = 0; j < error->ring[i].num_requests; j++) { - seq_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n", - error->ring[i].requests[j].seqno, - error->ring[i].requests[j].jiffies, - error->ring[i].requests[j].tail); - } - } - - if ((obj = error->ring[i].ringbuffer)) { - seq_printf(m, "%s --- ringbuffer = 0x%08x\n", - dev_priv->ring[i].name, - obj->gtt_offset); - offset = 0; - for (page = 0; page < obj->page_count; page++) { - for (elt = 0; elt < PAGE_SIZE/4; elt++) { - seq_printf(m, "%08x : %08x\n", - offset, - obj->pages[page][elt]); - offset += 4; - } - } - } - } - - if (error->overlay) - intel_overlay_print_error_state(m, error->overlay); - - if (error->display) - intel_display_print_error_state(m, dev, error->display); - -out: - spin_unlock_irqrestore(&dev_priv->error_lock, flags); - - return 0; -} - -static int i915_rstdby_delays(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u16 crstanddelay; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - crstanddelay = I915_READ16(CRSTANDVID); - - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); - - return 0; -} - -static int i915_cur_delayinfo(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - if (IS_GEN5(dev)) { - u16 rgvswctl = I915_READ16(MEMSWCTL); - u16 rgvstat = I915_READ16(MEMSTAT_ILK); - - seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); - seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); - seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> - MEMSTAT_VID_SHIFT); - seq_printf(m, "Current P-state: %d\n", - (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); - } else if (IS_GEN6(dev) || IS_GEN7(dev)) { - u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); - u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); - u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); - u32 rpstat; - u32 rpupei, rpcurup, rpprevup; - u32 rpdownei, rpcurdown, rpprevdown; - int max_freq; - - /* RPSTAT1 is in the GT power well */ - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - gen6_gt_force_wake_get(dev_priv); - - rpstat = I915_READ(GEN6_RPSTAT1); - rpupei = I915_READ(GEN6_RP_CUR_UP_EI); - rpcurup = I915_READ(GEN6_RP_CUR_UP); - rpprevup = I915_READ(GEN6_RP_PREV_UP); - rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI); - rpcurdown = I915_READ(GEN6_RP_CUR_DOWN); - rpprevdown = I915_READ(GEN6_RP_PREV_DOWN); - - gen6_gt_force_wake_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); - seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat); - seq_printf(m, "Render p-state ratio: %d\n", - (gt_perf_status & 0xff00) >> 8); - seq_printf(m, "Render p-state VID: %d\n", - gt_perf_status & 0xff); - seq_printf(m, "Render p-state limit: %d\n", - rp_state_limits & 0xff); - seq_printf(m, "CAGF: %dMHz\n", ((rpstat & GEN6_CAGF_MASK) >> - GEN6_CAGF_SHIFT) * 50); - seq_printf(m, "RP CUR UP EI: %dus\n", rpupei & - GEN6_CURICONT_MASK); - seq_printf(m, "RP CUR UP: %dus\n", rpcurup & - GEN6_CURBSYTAVG_MASK); - seq_printf(m, "RP PREV UP: %dus\n", rpprevup & - GEN6_CURBSYTAVG_MASK); - seq_printf(m, "RP CUR DOWN EI: %dus\n", rpdownei & - GEN6_CURIAVG_MASK); - seq_printf(m, "RP CUR DOWN: %dus\n", rpcurdown & - GEN6_CURBSYTAVG_MASK); - seq_printf(m, "RP PREV DOWN: %dus\n", rpprevdown & - GEN6_CURBSYTAVG_MASK); - - max_freq = (rp_state_cap & 0xff0000) >> 16; - seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", - max_freq * 50); - - max_freq = (rp_state_cap & 0xff00) >> 8; - seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", - max_freq * 50); - - max_freq = rp_state_cap & 0xff; - seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", - max_freq * 50); - } else { - seq_printf(m, "no P-state info available\n"); - } - - return 0; -} - -static int i915_delayfreq_table(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 delayfreq; - int ret, i; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - for (i = 0; i < 16; i++) { - delayfreq = I915_READ(PXVFREQ_BASE + i * 4); - seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq, - (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); - } - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static inline int MAP_TO_MV(int map) -{ - return 1250 - (map * 25); -} - -static int i915_inttoext_table(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 inttoext; - int ret, i; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - for (i = 1; i <= 32; i++) { - inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); - seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); - } - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int ironlake_drpc_info(struct seq_file *m) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 rgvmodectl, rstdbyctl; - u16 crstandvid; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - rgvmodectl = I915_READ(MEMMODECTL); - rstdbyctl = I915_READ(RSTDBYCTL); - crstandvid = I915_READ16(CRSTANDVID); - - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? - "yes" : "no"); - seq_printf(m, "Boost freq: %d\n", - (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >> - MEMMODE_BOOST_FREQ_SHIFT); - seq_printf(m, "HW control enabled: %s\n", - rgvmodectl & MEMMODE_HWIDLE_EN ? "yes" : "no"); - seq_printf(m, "SW control enabled: %s\n", - rgvmodectl & MEMMODE_SWMODE_EN ? "yes" : "no"); - seq_printf(m, "Gated voltage change: %s\n", - rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); - seq_printf(m, "Starting frequency: P%d\n", - (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); - seq_printf(m, "Max P-state: P%d\n", - (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); - seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); - seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f)); - seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); - seq_printf(m, "Render standby enabled: %s\n", - (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); - seq_printf(m, "Current RS state: "); - switch (rstdbyctl & RSX_STATUS_MASK) { - case RSX_STATUS_ON: - seq_printf(m, "on\n"); - break; - case RSX_STATUS_RC1: - seq_printf(m, "RC1\n"); - break; - case RSX_STATUS_RC1E: - seq_printf(m, "RC1E\n"); - break; - case RSX_STATUS_RS1: - seq_printf(m, "RS1\n"); - break; - case RSX_STATUS_RS2: - seq_printf(m, "RS2 (RC6)\n"); - break; - case RSX_STATUS_RS3: - seq_printf(m, "RC3 (RC6+)\n"); - break; - default: - seq_printf(m, "unknown\n"); - break; - } - - return 0; -} - -static int gen6_drpc_info(struct seq_file *m) -{ - - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 rpmodectl1, gt_core_status, rcctl1; - unsigned forcewake_count; - int count=0, ret; - - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - spin_lock_irq(&dev_priv->gt_lock); - forcewake_count = dev_priv->forcewake_count; - spin_unlock_irq(&dev_priv->gt_lock); - - if (forcewake_count) { - seq_printf(m, "RC information inaccurate because somebody " - "holds a forcewake reference \n"); - } else { - /* NB: we cannot use forcewake, else we read the wrong values */ - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) - udelay(10); - seq_printf(m, "RC information accurate: %s\n", yesno(count < 51)); - } - - gt_core_status = readl(dev_priv->regs + GEN6_GT_CORE_STATUS); - trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4); - - rpmodectl1 = I915_READ(GEN6_RP_CONTROL); - rcctl1 = I915_READ(GEN6_RC_CONTROL); - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "Video Turbo Mode: %s\n", - yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO)); - seq_printf(m, "HW control enabled: %s\n", - yesno(rpmodectl1 & GEN6_RP_ENABLE)); - seq_printf(m, "SW control enabled: %s\n", - yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == - GEN6_RP_MEDIA_SW_MODE)); - seq_printf(m, "RC1e Enabled: %s\n", - yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); - seq_printf(m, "RC6 Enabled: %s\n", - yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); - seq_printf(m, "Deep RC6 Enabled: %s\n", - yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE)); - seq_printf(m, "Deepest RC6 Enabled: %s\n", - yesno(rcctl1 & GEN6_RC_CTL_RC6pp_ENABLE)); - seq_printf(m, "Current RC state: "); - switch (gt_core_status & GEN6_RCn_MASK) { - case GEN6_RC0: - if (gt_core_status & GEN6_CORE_CPD_STATE_MASK) - seq_printf(m, "Core Power Down\n"); - else - seq_printf(m, "on\n"); - break; - case GEN6_RC3: - seq_printf(m, "RC3\n"); - break; - case GEN6_RC6: - seq_printf(m, "RC6\n"); - break; - case GEN6_RC7: - seq_printf(m, "RC7\n"); - break; - default: - seq_printf(m, "Unknown\n"); - break; - } - - seq_printf(m, "Core Power Down: %s\n", - yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK)); - return 0; -} - -static int i915_drpc_info(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - - if (IS_GEN6(dev) || IS_GEN7(dev)) - return gen6_drpc_info(m); - else - return ironlake_drpc_info(m); -} - -static int i915_fbc_status(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!I915_HAS_FBC(dev)) { - seq_printf(m, "FBC unsupported on this chipset\n"); - return 0; - } - - if (intel_fbc_enabled(dev)) { - seq_printf(m, "FBC enabled\n"); - } else { - seq_printf(m, "FBC disabled: "); - switch (dev_priv->no_fbc_reason) { - case FBC_NO_OUTPUT: - seq_printf(m, "no outputs"); - break; - case FBC_STOLEN_TOO_SMALL: - seq_printf(m, "not enough stolen memory"); - break; - case FBC_UNSUPPORTED_MODE: - seq_printf(m, "mode not supported"); - break; - case FBC_MODE_TOO_LARGE: - seq_printf(m, "mode too large"); - break; - case FBC_BAD_PLANE: - seq_printf(m, "FBC unsupported on plane"); - break; - case FBC_NOT_TILED: - seq_printf(m, "scanout buffer not tiled"); - break; - case FBC_MULTIPLE_PIPES: - seq_printf(m, "multiple pipes are enabled"); - break; - case FBC_MODULE_PARAM: - seq_printf(m, "disabled per module param (default off)"); - break; - default: - seq_printf(m, "unknown reason"); - } - seq_printf(m, "\n"); - } - return 0; -} - -static int i915_sr_status(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - bool sr_enabled = false; - - if (HAS_PCH_SPLIT(dev)) - sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; - else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) - sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; - else if (IS_I915GM(dev)) - sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; - else if (IS_PINEVIEW(dev)) - sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN; - - seq_printf(m, "self-refresh: %s\n", - sr_enabled ? "enabled" : "disabled"); - - return 0; -} - -static int i915_emon_status(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - unsigned long temp, chipset, gfx; - int ret; - - if (!IS_GEN5(dev)) - return -ENODEV; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - temp = i915_mch_val(dev_priv); - chipset = i915_chipset_val(dev_priv); - gfx = i915_gfx_val(dev_priv); - mutex_unlock(&dev->struct_mutex); - - seq_printf(m, "GMCH temp: %ld\n", temp); - seq_printf(m, "Chipset power: %ld\n", chipset); - seq_printf(m, "GFX power: %ld\n", gfx); - seq_printf(m, "Total power: %ld\n", chipset + gfx); - - return 0; -} - -static int i915_ring_freq_table(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - int gpu_freq, ia_freq; - - if (!(IS_GEN6(dev) || IS_GEN7(dev))) { - seq_printf(m, "unsupported on this chipset\n"); - return 0; - } - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - seq_printf(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\n"); - - for (gpu_freq = dev_priv->min_delay; gpu_freq <= dev_priv->max_delay; - gpu_freq++) { - I915_WRITE(GEN6_PCODE_DATA, gpu_freq); - I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | - GEN6_PCODE_READ_MIN_FREQ_TABLE); - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & - GEN6_PCODE_READY) == 0, 10)) { - DRM_ERROR("pcode read of freq table timed out\n"); - continue; - } - ia_freq = I915_READ(GEN6_PCODE_DATA); - seq_printf(m, "%d\t\t%d\n", gpu_freq * 50, ia_freq * 100); - } - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_gfxec(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_opregion(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - if (opregion->header) - seq_write(m, opregion->header, OPREGION_SIZE); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_gem_framebuffer_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_fbdev *ifbdev; - struct intel_framebuffer *fb; - int ret; - - ret = mutex_lock_interruptible(&dev->mode_config.mutex); - if (ret) - return ret; - - ifbdev = dev_priv->fbdev; - fb = to_intel_framebuffer(ifbdev->helper.fb); - - seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, obj ", - fb->base.width, - fb->base.height, - fb->base.depth, - fb->base.bits_per_pixel); - describe_obj(m, fb->obj); - seq_printf(m, "\n"); - - list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { - if (&fb->base == ifbdev->helper.fb) - continue; - - seq_printf(m, "user size: %d x %d, depth %d, %d bpp, obj ", - fb->base.width, - fb->base.height, - fb->base.depth, - fb->base.bits_per_pixel); - describe_obj(m, fb->obj); - seq_printf(m, "\n"); - } - - mutex_unlock(&dev->mode_config.mutex); - - return 0; -} - -static int i915_context_status(struct seq_file *m, void *unused) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - ret = mutex_lock_interruptible(&dev->mode_config.mutex); - if (ret) - return ret; - - if (dev_priv->pwrctx) { - seq_printf(m, "power context "); - describe_obj(m, dev_priv->pwrctx); - seq_printf(m, "\n"); - } - - if (dev_priv->renderctx) { - seq_printf(m, "render context "); - describe_obj(m, dev_priv->renderctx); - seq_printf(m, "\n"); - } - - mutex_unlock(&dev->mode_config.mutex); - - return 0; -} - -static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned forcewake_count; - - spin_lock_irq(&dev_priv->gt_lock); - forcewake_count = dev_priv->forcewake_count; - spin_unlock_irq(&dev_priv->gt_lock); - - seq_printf(m, "forcewake count = %u\n", forcewake_count); - - return 0; -} - -static const char *swizzle_string(unsigned swizzle) -{ - switch(swizzle) { - case I915_BIT_6_SWIZZLE_NONE: - return "none"; - case I915_BIT_6_SWIZZLE_9: - return "bit9"; - case I915_BIT_6_SWIZZLE_9_10: - return "bit9/bit10"; - case I915_BIT_6_SWIZZLE_9_11: - return "bit9/bit11"; - case I915_BIT_6_SWIZZLE_9_10_11: - return "bit9/bit10/bit11"; - case I915_BIT_6_SWIZZLE_9_17: - return "bit9/bit17"; - case I915_BIT_6_SWIZZLE_9_10_17: - return "bit9/bit10/bit17"; - case I915_BIT_6_SWIZZLE_UNKNOWN: - return "unkown"; - } - - return "bug"; -} - -static int i915_swizzle_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - mutex_lock(&dev->struct_mutex); - seq_printf(m, "bit6 swizzle for X-tiling = %s\n", - swizzle_string(dev_priv->mm.bit_6_swizzle_x)); - seq_printf(m, "bit6 swizzle for Y-tiling = %s\n", - swizzle_string(dev_priv->mm.bit_6_swizzle_y)); - - if (IS_GEN3(dev) || IS_GEN4(dev)) { - seq_printf(m, "DDC = 0x%08x\n", - I915_READ(DCC)); - seq_printf(m, "C0DRB3 = 0x%04x\n", - I915_READ16(C0DRB3)); - seq_printf(m, "C1DRB3 = 0x%04x\n", - I915_READ16(C1DRB3)); - } else if (IS_GEN6(dev) || IS_GEN7(dev)) { - seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", - I915_READ(MAD_DIMM_C0)); - seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", - I915_READ(MAD_DIMM_C1)); - seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n", - I915_READ(MAD_DIMM_C2)); - seq_printf(m, "TILECTL = 0x%08x\n", - I915_READ(TILECTL)); - seq_printf(m, "ARB_MODE = 0x%08x\n", - I915_READ(ARB_MODE)); - seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", - I915_READ(DISP_ARB_CTL)); - } - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static int i915_ppgtt_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - int i, ret; - - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - if (INTEL_INFO(dev)->gen == 6) - seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); - - for (i = 0; i < I915_NUM_RINGS; i++) { - ring = &dev_priv->ring[i]; - - seq_printf(m, "%s\n", ring->name); - if (INTEL_INFO(dev)->gen == 7) - seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring))); - seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring))); - seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring))); - seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring))); - } - if (dev_priv->mm.aliasing_ppgtt) { - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - - seq_printf(m, "aliasing PPGTT:\n"); - seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); - } - seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static ssize_t -i915_wedged_read(struct file *filp, - char __user *ubuf, - size_t max, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - drm_i915_private_t *dev_priv = dev->dev_private; - char buf[80]; - int len; - - len = snprintf(buf, sizeof(buf), - "wedged : %d\n", - atomic_read(&dev_priv->mm.wedged)); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(ubuf, max, ppos, buf, len); -} - -static ssize_t -i915_wedged_write(struct file *filp, - const char __user *ubuf, - size_t cnt, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - char buf[20]; - int val = 1; - - if (cnt > 0) { - if (cnt > sizeof(buf) - 1) - return -EINVAL; - - if (copy_from_user(buf, ubuf, cnt)) - return -EFAULT; - buf[cnt] = 0; - - val = simple_strtoul(buf, NULL, 0); - } - - DRM_INFO("Manually setting wedged to %d\n", val); - i915_handle_error(dev, val); - - return cnt; -} - -static const struct file_operations i915_wedged_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = i915_wedged_read, - .write = i915_wedged_write, - .llseek = default_llseek, -}; - -static ssize_t -i915_max_freq_read(struct file *filp, - char __user *ubuf, - size_t max, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - drm_i915_private_t *dev_priv = dev->dev_private; - char buf[80]; - int len; - - len = snprintf(buf, sizeof(buf), - "max freq: %d\n", dev_priv->max_delay * 50); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(ubuf, max, ppos, buf, len); -} - -static ssize_t -i915_max_freq_write(struct file *filp, - const char __user *ubuf, - size_t cnt, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - struct drm_i915_private *dev_priv = dev->dev_private; - char buf[20]; - int val = 1; - - if (cnt > 0) { - if (cnt > sizeof(buf) - 1) - return -EINVAL; - - if (copy_from_user(buf, ubuf, cnt)) - return -EFAULT; - buf[cnt] = 0; - - val = simple_strtoul(buf, NULL, 0); - } - - DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val); - - /* - * Turbo will still be enabled, but won't go above the set value. - */ - dev_priv->max_delay = val / 50; - - gen6_set_rps(dev, val / 50); - - return cnt; -} - -static const struct file_operations i915_max_freq_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = i915_max_freq_read, - .write = i915_max_freq_write, - .llseek = default_llseek, -}; - -static ssize_t -i915_cache_sharing_read(struct file *filp, - char __user *ubuf, - size_t max, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - drm_i915_private_t *dev_priv = dev->dev_private; - char buf[80]; - u32 snpcr; - int len; - - mutex_lock(&dev_priv->dev->struct_mutex); - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); - mutex_unlock(&dev_priv->dev->struct_mutex); - - len = snprintf(buf, sizeof(buf), - "%d\n", (snpcr & GEN6_MBC_SNPCR_MASK) >> - GEN6_MBC_SNPCR_SHIFT); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(ubuf, max, ppos, buf, len); -} - -static ssize_t -i915_cache_sharing_write(struct file *filp, - const char __user *ubuf, - size_t cnt, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - struct drm_i915_private *dev_priv = dev->dev_private; - char buf[20]; - u32 snpcr; - int val = 1; - - if (cnt > 0) { - if (cnt > sizeof(buf) - 1) - return -EINVAL; - - if (copy_from_user(buf, ubuf, cnt)) - return -EFAULT; - buf[cnt] = 0; - - val = simple_strtoul(buf, NULL, 0); - } - - if (val < 0 || val > 3) - return -EINVAL; - - DRM_DEBUG_DRIVER("Manually setting uncore sharing to %d\n", val); - - /* Update the cache sharing policy here as well */ - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); - snpcr &= ~GEN6_MBC_SNPCR_MASK; - snpcr |= (val << GEN6_MBC_SNPCR_SHIFT); - I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); - - return cnt; -} - -static const struct file_operations i915_cache_sharing_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = i915_cache_sharing_read, - .write = i915_cache_sharing_write, - .llseek = default_llseek, -}; - -/* As the drm_debugfs_init() routines are called before dev->dev_private is - * allocated we need to hook into the minor for release. */ -static int -drm_add_fake_info_node(struct drm_minor *minor, - struct dentry *ent, - const void *key) -{ - struct drm_info_node *node; - - node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); - if (node == NULL) { - debugfs_remove(ent); - return -ENOMEM; - } - - node->minor = minor; - node->dent = ent; - node->info_ent = (void *) key; - - mutex_lock(&minor->debugfs_lock); - list_add(&node->list, &minor->debugfs_list); - mutex_unlock(&minor->debugfs_lock); - - return 0; -} - -static int i915_forcewake_open(struct inode *inode, struct file *file) -{ - struct drm_device *dev = inode->i_private; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - if (INTEL_INFO(dev)->gen < 6) - return 0; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - gen6_gt_force_wake_get(dev_priv); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -int i915_forcewake_release(struct inode *inode, struct file *file) -{ - struct drm_device *dev = inode->i_private; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen < 6) - return 0; - - /* - * It's bad that we can potentially hang userspace if struct_mutex gets - * forever stuck. However, if we cannot acquire this lock it means that - * almost certainly the driver has hung, is not unload-able. Therefore - * hanging here is probably a minor inconvenience not to be seen my - * almost every user. - */ - mutex_lock(&dev->struct_mutex); - gen6_gt_force_wake_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -static const struct file_operations i915_forcewake_fops = { - .owner = THIS_MODULE, - .open = i915_forcewake_open, - .release = i915_forcewake_release, -}; - -static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_forcewake_user", - S_IRUSR, - root, dev, - &i915_forcewake_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); -} - -static int i915_debugfs_create(struct dentry *root, - struct drm_minor *minor, - const char *name, - const struct file_operations *fops) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file(name, - S_IRUGO | S_IWUSR, - root, dev, - fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, fops); -} - -static struct drm_info_list i915_debugfs_list[] = { - {"i915_capabilities", i915_capabilities, 0}, - {"i915_gem_objects", i915_gem_object_info, 0}, - {"i915_gem_gtt", i915_gem_gtt_info, 0}, - {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, - {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, - {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, - {"i915_gem_pinned", i915_gem_object_list_info, 0, (void *) PINNED_LIST}, - {"i915_gem_deferred_free", i915_gem_object_list_info, 0, (void *) DEFERRED_FREE_LIST}, - {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, - {"i915_gem_request", i915_gem_request_info, 0}, - {"i915_gem_seqno", i915_gem_seqno_info, 0}, - {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, - {"i915_gem_interrupt", i915_interrupt_info, 0}, - {"i915_gem_hws", i915_hws_info, 0, (void *)RCS}, - {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS}, - {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS}, - {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RCS}, - {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RCS}, - {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)VCS}, - {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, - {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, - {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, - {"i915_error_state", i915_error_state, 0}, - {"i915_rstdby_delays", i915_rstdby_delays, 0}, - {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, - {"i915_delayfreq_table", i915_delayfreq_table, 0}, - {"i915_inttoext_table", i915_inttoext_table, 0}, - {"i915_drpc_info", i915_drpc_info, 0}, - {"i915_emon_status", i915_emon_status, 0}, - {"i915_ring_freq_table", i915_ring_freq_table, 0}, - {"i915_gfxec", i915_gfxec, 0}, - {"i915_fbc_status", i915_fbc_status, 0}, - {"i915_sr_status", i915_sr_status, 0}, - {"i915_opregion", i915_opregion, 0}, - {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, - {"i915_context_status", i915_context_status, 0}, - {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, - {"i915_swizzle_info", i915_swizzle_info, 0}, - {"i915_ppgtt_info", i915_ppgtt_info, 0}, -}; -#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) - -int i915_debugfs_init(struct drm_minor *minor) -{ - int ret; - - ret = i915_debugfs_create(minor->debugfs_root, minor, - "i915_wedged", - &i915_wedged_fops); - if (ret) - return ret; - - ret = i915_forcewake_create(minor->debugfs_root, minor); - if (ret) - return ret; - - ret = i915_debugfs_create(minor->debugfs_root, minor, - "i915_max_freq", - &i915_max_freq_fops); - if (ret) - return ret; - - ret = i915_debugfs_create(minor->debugfs_root, minor, - "i915_cache_sharing", - &i915_cache_sharing_fops); - if (ret) - return ret; - - return drm_debugfs_create_files(i915_debugfs_list, - I915_DEBUGFS_ENTRIES, - minor->debugfs_root, minor); -} - -void i915_debugfs_cleanup(struct drm_minor *minor) -{ - drm_debugfs_remove_files(i915_debugfs_list, - I915_DEBUGFS_ENTRIES, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops, - 1, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, - 1, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, - 1, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, - 1, minor); -} - -#endif /* CONFIG_DEBUG_FS */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_dma.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_dma.c deleted file mode 100644 index ba60f3c8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_dma.c +++ /dev/null @@ -1,2372 +0,0 @@ -/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_trace.h" -#include "../../../platform/x86/intel_ips.h" -#include -#include -#include -#include -#include -#include -#include -#include - -static void i915_write_hws_pga(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - u32 addr; - - addr = dev_priv->status_page_dmah->busaddr; - if (INTEL_INFO(dev)->gen >= 4) - addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; - I915_WRITE(HWS_PGA, addr); -} - -/** - * Sets up the hardware status page for devices that need a physical address - * in the register. - */ -static int i915_init_phys_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - /* Program Hardware Status Page */ - dev_priv->status_page_dmah = - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); - - if (!dev_priv->status_page_dmah) { - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; - } - - memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, - 0, PAGE_SIZE); - - i915_write_hws_pga(dev); - - DRM_DEBUG_DRIVER("Enabled hardware status page\n"); - return 0; -} - -/** - * Frees the hardware status page, whether it's a physical address or a virtual - * address set up by the X Server. - */ -static void i915_free_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring = LP_RING(dev_priv); - - if (dev_priv->status_page_dmah) { - drm_pci_free(dev, dev_priv->status_page_dmah); - dev_priv->status_page_dmah = NULL; - } - - if (ring->status_page.gfx_addr) { - ring->status_page.gfx_addr = 0; - drm_core_ioremapfree(&dev_priv->hws_map, dev); - } - - /* Need to rewrite hardware status page */ - I915_WRITE(HWS_PGA, 0x1ffff000); -} - -void i915_kernel_lost_context(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv; - struct intel_ring_buffer *ring = LP_RING(dev_priv); - - /* - * We should never lose context on the ring with modesetting - * as we don't expose it to userspace - */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; - ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->size; - - if (!dev->primary->master) - return; - - master_priv = dev->primary->master->driver_priv; - if (ring->head == ring->tail && master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; -} - -static int i915_dma_cleanup(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i; - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - mutex_lock(&dev->struct_mutex); - for (i = 0; i < I915_NUM_RINGS; i++) - intel_cleanup_ring_buffer(&dev_priv->ring[i]); - mutex_unlock(&dev->struct_mutex); - - /* Clear the HWS virtual address at teardown */ - if (I915_NEED_GFX_HWS(dev)) - i915_free_hws(dev); - - return 0; -} - -static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - int ret; - - master_priv->sarea = drm_getsarea(dev); - if (master_priv->sarea) { - master_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); - } else { - DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n"); - } - - if (init->ring_size != 0) { - if (LP_RING(dev_priv)->obj != NULL) { - i915_dma_cleanup(dev); - DRM_ERROR("Client tried to initialize ringbuffer in " - "GEM mode\n"); - return -EINVAL; - } - - ret = intel_render_ring_init_dri(dev, - init->ring_start, - init->ring_size); - if (ret) { - i915_dma_cleanup(dev); - return ret; - } - } - - dev_priv->cpp = init->cpp; - dev_priv->back_offset = init->back_offset; - dev_priv->front_offset = init->front_offset; - dev_priv->current_page = 0; - if (master_priv->sarea_priv) - master_priv->sarea_priv->pf_current_page = 0; - - /* Allow hardware batchbuffers unless told otherwise. - */ - dev_priv->allow_batchbuffer = 1; - - return 0; -} - -static int i915_dma_resume(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - struct intel_ring_buffer *ring = LP_RING(dev_priv); - - DRM_DEBUG_DRIVER("%s\n", __func__); - - if (ring->map.handle == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - /* Program Hardware Status Page */ - if (!ring->status_page.page_addr) { - DRM_ERROR("Can not find hardware status page\n"); - return -EINVAL; - } - DRM_DEBUG_DRIVER("hw status page @ %p\n", - ring->status_page.page_addr); - if (ring->status_page.gfx_addr != 0) - intel_ring_setup_status_page(ring); - else - i915_write_hws_pga(dev); - - DRM_DEBUG_DRIVER("Enabled hardware status page\n"); - - return 0; -} - -static int i915_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_init_t *init = data; - int retcode = 0; - - switch (init->func) { - case I915_INIT_DMA: - retcode = i915_initialize(dev, init); - break; - case I915_CLEANUP_DMA: - retcode = i915_dma_cleanup(dev); - break; - case I915_RESUME_DMA: - retcode = i915_dma_resume(dev); - break; - default: - retcode = -EINVAL; - break; - } - - return retcode; -} - -/* Implement basically the same security restrictions as hardware does - * for MI_BATCH_NON_SECURE. These can be made stricter at any time. - * - * Most of the calculations below involve calculating the size of a - * particular instruction. It's important to get the size right as - * that tells us where the next instruction to check is. Any illegal - * instruction detected will be given a size of zero, which is a - * signal to abort the rest of the buffer. - */ -static int validate_cmd(int cmd) -{ - switch (((cmd >> 29) & 0x7)) { - case 0x0: - switch ((cmd >> 23) & 0x3f) { - case 0x0: - return 1; /* MI_NOOP */ - case 0x4: - return 1; /* MI_FLUSH */ - default: - return 0; /* disallow everything else */ - } - break; - case 0x1: - return 0; /* reserved */ - case 0x2: - return (cmd & 0xff) + 2; /* 2d commands */ - case 0x3: - if (((cmd >> 24) & 0x1f) <= 0x18) - return 1; - - switch ((cmd >> 24) & 0x1f) { - case 0x1c: - return 1; - case 0x1d: - switch ((cmd >> 16) & 0xff) { - case 0x3: - return (cmd & 0x1f) + 2; - case 0x4: - return (cmd & 0xf) + 2; - default: - return (cmd & 0xffff) + 2; - } - case 0x1e: - if (cmd & (1 << 23)) - return (cmd & 0xffff) + 1; - else - return 1; - case 0x1f: - if ((cmd & (1 << 23)) == 0) /* inline vertices */ - return (cmd & 0x1ffff) + 2; - else if (cmd & (1 << 17)) /* indirect random */ - if ((cmd & 0xffff) == 0) - return 0; /* unknown length, too hard */ - else - return (((cmd & 0xffff) + 1) / 2) + 1; - else - return 2; /* indirect sequential */ - default: - return 0; - } - default: - return 0; - } - - return 0; -} - -static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i, ret; - - if ((dwords+1) * sizeof(int) >= LP_RING(dev_priv)->size - 8) - return -EINVAL; - - for (i = 0; i < dwords;) { - int sz = validate_cmd(buffer[i]); - if (sz == 0 || i + sz > dwords) - return -EINVAL; - i += sz; - } - - ret = BEGIN_LP_RING((dwords+1)&~1); - if (ret) - return ret; - - for (i = 0; i < dwords; i++) - OUT_RING(buffer[i]); - if (dwords & 1) - OUT_RING(0); - - ADVANCE_LP_RING(); - - return 0; -} - -int -i915_emit_box(struct drm_device *dev, - struct drm_clip_rect *box, - int DR1, int DR4) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - if (box->y2 <= box->y1 || box->x2 <= box->x1 || - box->y2 <= 0 || box->x2 <= 0) { - DRM_ERROR("Bad box %d,%d..%d,%d\n", - box->x1, box->y1, box->x2, box->y2); - return -EINVAL; - } - - if (INTEL_INFO(dev)->gen >= 4) { - ret = BEGIN_LP_RING(4); - if (ret) - return ret; - - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); - OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); - OUT_RING(DR4); - } else { - ret = BEGIN_LP_RING(6); - if (ret) - return ret; - - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(DR1); - OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); - OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); - OUT_RING(DR4); - OUT_RING(0); - } - ADVANCE_LP_RING(); - - return 0; -} - -/* XXX: Emitting the counter should really be moved to part of the IRQ - * emit. For now, do it in both places: - */ - -static void i915_emit_breadcrumb(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - - dev_priv->counter++; - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->counter = 0; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_enqueue = dev_priv->counter; - - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); - } -} - -static int i915_dispatch_cmdbuffer(struct drm_device * dev, - drm_i915_cmdbuffer_t *cmd, - struct drm_clip_rect *cliprects, - void *cmdbuf) -{ - int nbox = cmd->num_cliprects; - int i = 0, count, ret; - - if (cmd->sz & 0x3) { - DRM_ERROR("alignment"); - return -EINVAL; - } - - i915_kernel_lost_context(dev); - - count = nbox ? nbox : 1; - - for (i = 0; i < count; i++) { - if (i < nbox) { - ret = i915_emit_box(dev, &cliprects[i], - cmd->DR1, cmd->DR4); - if (ret) - return ret; - } - - ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4); - if (ret) - return ret; - } - - i915_emit_breadcrumb(dev); - return 0; -} - -static int i915_dispatch_batchbuffer(struct drm_device * dev, - drm_i915_batchbuffer_t * batch, - struct drm_clip_rect *cliprects) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int nbox = batch->num_cliprects; - int i, count, ret; - - if ((batch->start | batch->used) & 0x7) { - DRM_ERROR("alignment"); - return -EINVAL; - } - - i915_kernel_lost_context(dev); - - count = nbox ? nbox : 1; - for (i = 0; i < count; i++) { - if (i < nbox) { - ret = i915_emit_box(dev, &cliprects[i], - batch->DR1, batch->DR4); - if (ret) - return ret; - } - - if (!IS_I830(dev) && !IS_845G(dev)) { - ret = BEGIN_LP_RING(2); - if (ret) - return ret; - - if (INTEL_INFO(dev)->gen >= 4) { - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); - OUT_RING(batch->start); - } else { - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - } - } else { - ret = BEGIN_LP_RING(4); - if (ret) - return ret; - - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(batch->start | MI_BATCH_NON_SECURE); - OUT_RING(batch->start + batch->used - 4); - OUT_RING(0); - } - ADVANCE_LP_RING(); - } - - - if (IS_G4X(dev) || IS_GEN5(dev)) { - if (BEGIN_LP_RING(2) == 0) { - OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - } - } - - i915_emit_breadcrumb(dev); - return 0; -} - -static int i915_dispatch_flip(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = - dev->primary->master->driver_priv; - int ret; - - if (!master_priv->sarea_priv) - return -EINVAL; - - DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n", - __func__, - dev_priv->current_page, - master_priv->sarea_priv->pf_current_page); - - i915_kernel_lost_context(dev); - - ret = BEGIN_LP_RING(10); - if (ret) - return ret; - - OUT_RING(MI_FLUSH | MI_READ_FLUSH); - OUT_RING(0); - - OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); - OUT_RING(0); - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_offset); - dev_priv->current_page = 1; - } else { - OUT_RING(dev_priv->front_offset); - dev_priv->current_page = 0; - } - OUT_RING(0); - - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); - OUT_RING(0); - - ADVANCE_LP_RING(); - - master_priv->sarea_priv->last_enqueue = dev_priv->counter++; - - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); - } - - master_priv->sarea_priv->pf_current_page = dev_priv->current_page; - return 0; -} - -static int i915_quiescent(struct drm_device *dev) -{ - struct intel_ring_buffer *ring = LP_RING(dev->dev_private); - - i915_kernel_lost_context(dev); - return intel_wait_ring_idle(ring); -} - -static int i915_flush_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - ret = i915_quiescent(dev); - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -static int i915_batchbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) - master_priv->sarea_priv; - drm_i915_batchbuffer_t *batch = data; - int ret; - struct drm_clip_rect *cliprects = NULL; - - if (!dev_priv->allow_batchbuffer) { - DRM_ERROR("Batchbuffer ioctl disabled\n"); - return -EINVAL; - } - - DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n", - batch->start, batch->used, batch->num_cliprects); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (batch->num_cliprects < 0) - return -EINVAL; - - if (batch->num_cliprects) { - cliprects = kcalloc(batch->num_cliprects, - sizeof(struct drm_clip_rect), - GFP_KERNEL); - if (cliprects == NULL) - return -ENOMEM; - - ret = copy_from_user(cliprects, batch->cliprects, - batch->num_cliprects * - sizeof(struct drm_clip_rect)); - if (ret != 0) { - ret = -EFAULT; - goto fail_free; - } - } - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_batchbuffer(dev, batch, cliprects); - mutex_unlock(&dev->struct_mutex); - - if (sarea_priv) - sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - -fail_free: - kfree(cliprects); - - return ret; -} - -static int i915_cmdbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) - master_priv->sarea_priv; - drm_i915_cmdbuffer_t *cmdbuf = data; - struct drm_clip_rect *cliprects = NULL; - void *batch_data; - int ret; - - DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n", - cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (cmdbuf->num_cliprects < 0) - return -EINVAL; - - batch_data = kmalloc(cmdbuf->sz, GFP_KERNEL); - if (batch_data == NULL) - return -ENOMEM; - - ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); - if (ret != 0) { - ret = -EFAULT; - goto fail_batch_free; - } - - if (cmdbuf->num_cliprects) { - cliprects = kcalloc(cmdbuf->num_cliprects, - sizeof(struct drm_clip_rect), GFP_KERNEL); - if (cliprects == NULL) { - ret = -ENOMEM; - goto fail_batch_free; - } - - ret = copy_from_user(cliprects, cmdbuf->cliprects, - cmdbuf->num_cliprects * - sizeof(struct drm_clip_rect)); - if (ret != 0) { - ret = -EFAULT; - goto fail_clip_free; - } - } - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data); - mutex_unlock(&dev->struct_mutex); - if (ret) { - DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); - goto fail_clip_free; - } - - if (sarea_priv) - sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - -fail_clip_free: - kfree(cliprects); -fail_batch_free: - kfree(batch_data); - - return ret; -} - -static int i915_flip_bufs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - DRM_DEBUG_DRIVER("%s\n", __func__); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - ret = i915_dispatch_flip(dev); - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -static int i915_getparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_getparam_t *param = data; - int value; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - switch (param->param) { - case I915_PARAM_IRQ_ACTIVE: - value = dev->pdev->irq ? 1 : 0; - break; - case I915_PARAM_ALLOW_BATCHBUFFER: - value = dev_priv->allow_batchbuffer ? 1 : 0; - break; - case I915_PARAM_LAST_DISPATCH: - value = READ_BREADCRUMB(dev_priv); - break; - case I915_PARAM_CHIPSET_ID: - value = dev->pci_device; - break; - case I915_PARAM_HAS_GEM: - value = dev_priv->has_gem; - break; - case I915_PARAM_NUM_FENCES_AVAIL: - value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; - break; - case I915_PARAM_HAS_OVERLAY: - value = dev_priv->overlay ? 1 : 0; - break; - case I915_PARAM_HAS_PAGEFLIPPING: - value = 1; - break; - case I915_PARAM_HAS_EXECBUF2: - /* depends on GEM */ - value = dev_priv->has_gem; - break; - case I915_PARAM_HAS_BSD: - value = HAS_BSD(dev); - break; - case I915_PARAM_HAS_BLT: - value = HAS_BLT(dev); - break; - case I915_PARAM_HAS_RELAXED_FENCING: - value = 1; - break; - case I915_PARAM_HAS_COHERENT_RINGS: - value = 1; - break; - case I915_PARAM_HAS_EXEC_CONSTANTS: - value = INTEL_INFO(dev)->gen >= 4; - break; - case I915_PARAM_HAS_RELAXED_DELTA: - value = 1; - break; - case I915_PARAM_HAS_GEN7_SOL_RESET: - value = 1; - break; - case I915_PARAM_HAS_LLC: - value = HAS_LLC(dev); - break; - default: - DRM_DEBUG_DRIVER("Unknown parameter %d\n", - param->param); - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("DRM_COPY_TO_USER failed\n"); - return -EFAULT; - } - - return 0; -} - -static int i915_setparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_setparam_t *param = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - switch (param->param) { - case I915_SETPARAM_USE_MI_BATCHBUFFER_START: - break; - case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: - dev_priv->tex_lru_log_granularity = param->value; - break; - case I915_SETPARAM_ALLOW_BATCHBUFFER: - dev_priv->allow_batchbuffer = param->value; - break; - case I915_SETPARAM_NUM_USED_FENCES: - if (param->value > dev_priv->num_fence_regs || - param->value < 0) - return -EINVAL; - /* Userspace can use first N regs */ - dev_priv->fence_reg_start = param->value; - break; - default: - DRM_DEBUG_DRIVER("unknown parameter %d\n", - param->param); - return -EINVAL; - } - - return 0; -} - -static int i915_set_status_page(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_hws_addr_t *hws = data; - struct intel_ring_buffer *ring = LP_RING(dev_priv); - - if (!I915_NEED_GFX_HWS(dev)) - return -EINVAL; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - WARN(1, "tried to set status page when mode setting active\n"); - return 0; - } - - DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); - - ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); - - dev_priv->hws_map.offset = dev->agp->base + hws->addr; - dev_priv->hws_map.size = 4*1024; - dev_priv->hws_map.type = 0; - dev_priv->hws_map.flags = 0; - dev_priv->hws_map.mtrr = 0; - - drm_core_ioremap_wc(&dev_priv->hws_map, dev); - if (dev_priv->hws_map.handle == NULL) { - i915_dma_cleanup(dev); - ring->status_page.gfx_addr = 0; - DRM_ERROR("can not ioremap virtual address for" - " G33 hw status page\n"); - return -ENOMEM; - } - ring->status_page.page_addr = - (void __force __iomem *)dev_priv->hws_map.handle; - memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); - - DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", - ring->status_page.gfx_addr); - DRM_DEBUG_DRIVER("load hws at %p\n", - ring->status_page.page_addr); - return 0; -} - -static int i915_get_bridge_dev(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); - if (!dev_priv->bridge_dev) { - DRM_ERROR("bridge device not found\n"); - return -1; - } - return 0; -} - -#define MCHBAR_I915 0x44 -#define MCHBAR_I965 0x48 -#define MCHBAR_SIZE (4*4096) - -#define DEVEN_REG 0x54 -#define DEVEN_MCHBAR_EN (1 << 28) - -/* Allocate space for the MCH regs if needed, return nonzero on error */ -static int -intel_alloc_mchbar_resource(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - u32 temp_lo, temp_hi = 0; - u64 mchbar_addr; - int ret; - - if (INTEL_INFO(dev)->gen >= 4) - pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); - pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); - mchbar_addr = ((u64)temp_hi << 32) | temp_lo; - - /* If ACPI doesn't have it, assume we need to allocate it ourselves */ -#ifdef CONFIG_PNP - if (mchbar_addr && - pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) - return 0; -#endif - - /* Get some space for it */ - dev_priv->mch_res.name = "i915 MCHBAR"; - dev_priv->mch_res.flags = IORESOURCE_MEM; - ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, - &dev_priv->mch_res, - MCHBAR_SIZE, MCHBAR_SIZE, - PCIBIOS_MIN_MEM, - 0, pcibios_align_resource, - dev_priv->bridge_dev); - if (ret) { - DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); - dev_priv->mch_res.start = 0; - return ret; - } - - if (INTEL_INFO(dev)->gen >= 4) - pci_write_config_dword(dev_priv->bridge_dev, reg + 4, - upper_32_bits(dev_priv->mch_res.start)); - - pci_write_config_dword(dev_priv->bridge_dev, reg, - lower_32_bits(dev_priv->mch_res.start)); - return 0; -} - -/* Setup MCHBAR if possible, return true if we should disable it again */ -static void -intel_setup_mchbar(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - bool enabled; - - dev_priv->mchbar_need_disable = false; - - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - enabled = !!(temp & DEVEN_MCHBAR_EN); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - enabled = temp & 1; - } - - /* If it's already enabled, don't have to do anything */ - if (enabled) - return; - - if (intel_alloc_mchbar_resource(dev)) - return; - - dev_priv->mchbar_need_disable = true; - - /* Space is allocated or reserved, so enable it. */ - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, - temp | DEVEN_MCHBAR_EN); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); - } -} - -static void -intel_teardown_mchbar(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - - if (dev_priv->mchbar_need_disable) { - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - temp &= ~DEVEN_MCHBAR_EN; - pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - temp &= ~1; - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); - } - } - - if (dev_priv->mch_res.start) - release_resource(&dev_priv->mch_res); -} - -#define PTE_ADDRESS_MASK 0xfffff000 -#define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ -#define PTE_MAPPING_TYPE_UNCACHED (0 << 1) -#define PTE_MAPPING_TYPE_DCACHE (1 << 1) /* i830 only */ -#define PTE_MAPPING_TYPE_CACHED (3 << 1) -#define PTE_MAPPING_TYPE_MASK (3 << 1) -#define PTE_VALID (1 << 0) - -/** - * i915_stolen_to_phys - take an offset into stolen memory and turn it into - * a physical one - * @dev: drm device - * @offset: address to translate - * - * Some chip functions require allocations from stolen space and need the - * physical address of the memory in question. - */ -static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct pci_dev *pdev = dev_priv->bridge_dev; - u32 base; - -#if 0 - /* On the machines I have tested the Graphics Base of Stolen Memory - * is unreliable, so compute the base by subtracting the stolen memory - * from the Top of Low Usable DRAM which is where the BIOS places - * the graphics stolen memory. - */ - if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { - /* top 32bits are reserved = 0 */ - pci_read_config_dword(pdev, 0xA4, &base); - } else { - /* XXX presume 8xx is the same as i915 */ - pci_bus_read_config_dword(pdev->bus, 2, 0x5C, &base); - } -#else - if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { - u16 val; - pci_read_config_word(pdev, 0xb0, &val); - base = val >> 4 << 20; - } else { - u8 val; - pci_read_config_byte(pdev, 0x9c, &val); - base = val >> 3 << 27; - } - base -= dev_priv->mm.gtt->stolen_size; -#endif - - return base + offset; -} - -static void i915_warn_stolen(struct drm_device *dev) -{ - DRM_ERROR("not enough stolen space for compressed buffer, disabling\n"); - DRM_ERROR("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n"); -} - -static void i915_setup_compression(struct drm_device *dev, int size) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); - unsigned long cfb_base; - unsigned long ll_base = 0; - - /* Just in case the BIOS is doing something questionable. */ - intel_disable_fbc(dev); - - compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); - if (compressed_fb) - compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); - if (!compressed_fb) - goto err; - - cfb_base = i915_stolen_to_phys(dev, compressed_fb->start); - if (!cfb_base) - goto err_fb; - - if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) { - compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, - 4096, 4096, 0); - if (compressed_llb) - compressed_llb = drm_mm_get_block(compressed_llb, - 4096, 4096); - if (!compressed_llb) - goto err_fb; - - ll_base = i915_stolen_to_phys(dev, compressed_llb->start); - if (!ll_base) - goto err_llb; - } - - dev_priv->cfb_size = size; - - dev_priv->compressed_fb = compressed_fb; - if (HAS_PCH_SPLIT(dev)) - I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); - else if (IS_GM45(dev)) { - I915_WRITE(DPFC_CB_BASE, compressed_fb->start); - } else { - I915_WRITE(FBC_CFB_BASE, cfb_base); - I915_WRITE(FBC_LL_BASE, ll_base); - dev_priv->compressed_llb = compressed_llb; - } - - DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", - cfb_base, ll_base, size >> 20); - return; - -err_llb: - drm_mm_put_block(compressed_llb); -err_fb: - drm_mm_put_block(compressed_fb); -err: - dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; - i915_warn_stolen(dev); -} - -static void i915_cleanup_compression(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - drm_mm_put_block(dev_priv->compressed_fb); - if (dev_priv->compressed_llb) - drm_mm_put_block(dev_priv->compressed_llb); -} - -/* true = enable decode, false = disable decoder */ -static unsigned int i915_vga_set_decode(void *cookie, bool state) -{ - struct drm_device *dev = cookie; - - intel_modeset_vga_set_state(dev, state); - if (state) - return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | - VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; - else - return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; -} - -static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; - if (state == VGA_SWITCHEROO_ON) { - printk(KERN_INFO "i915: switched on\n"); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - /* i915 resume handler doesn't set to D0 */ - pci_set_power_state(dev->pdev, PCI_D0); - i915_resume(dev); - dev->switch_power_state = DRM_SWITCH_POWER_ON; - } else { - printk(KERN_ERR "i915: switched off\n"); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - i915_suspend(dev, pmm); - dev->switch_power_state = DRM_SWITCH_POWER_OFF; - } -} - -static bool i915_switcheroo_can_switch(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - bool can_switch; - - spin_lock(&dev->count_lock); - can_switch = (dev->open_count == 0); - spin_unlock(&dev->count_lock); - return can_switch; -} - -static bool -intel_enable_ppgtt(struct drm_device *dev) -{ - if (i915_enable_ppgtt >= 0) - return i915_enable_ppgtt; - -#ifdef CONFIG_INTEL_IOMMU - /* Disable ppgtt on SNB if VT-d is on. */ - if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) - return false; -#endif - - return true; -} - -static int i915_load_gem_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long prealloc_size, gtt_size, mappable_size; - int ret; - - prealloc_size = dev_priv->mm.gtt->stolen_size; - gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; - mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - - /* Basic memrange allocator for stolen space */ - drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); - - mutex_lock(&dev->struct_mutex); - if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { - /* PPGTT pdes are stolen from global gtt ptes, so shrink the - * aperture accordingly when using aliasing ppgtt. */ - gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; - /* For paranoia keep the guard page in between. */ - gtt_size -= PAGE_SIZE; - - i915_gem_do_init(dev, 0, mappable_size, gtt_size); - - ret = i915_gem_init_aliasing_ppgtt(dev); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - } else { - /* Let GEM Manage all of the aperture. - * - * However, leave one page at the end still bound to the scratch - * page. There are a number of places where the hardware - * apparently prefetches past the end of the object, and we've - * seen multiple hangs with the GPU head pointer stuck in a - * batchbuffer bound at the last page of the aperture. One page - * should be enough to keep any prefetching inside of the - * aperture. - */ - i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); - } - - ret = i915_gem_init_hw(dev); - mutex_unlock(&dev->struct_mutex); - if (ret) { - i915_gem_cleanup_aliasing_ppgtt(dev); - return ret; - } - - /* Try to set up FBC with a reasonable compressed buffer size */ - if (I915_HAS_FBC(dev) && i915_powersave) { - int cfb_size; - - /* Leave 1M for line length buffer & misc. */ - - /* Try to get a 32M buffer... */ - if (prealloc_size > (36*1024*1024)) - cfb_size = 32*1024*1024; - else /* fall back to 7/8 of the stolen space */ - cfb_size = prealloc_size * 7 / 8; - i915_setup_compression(dev, cfb_size); - } - - /* Allow hardware batchbuffers unless told otherwise. */ - dev_priv->allow_batchbuffer = 1; - return 0; -} - -static int i915_load_modeset_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - ret = intel_parse_bios(dev); - if (ret) - DRM_INFO("failed to find VBIOS tables\n"); - - /* If we have > 1 VGA cards, then we need to arbitrate access - * to the common VGA resources. - * - * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), - * then we do not take part in VGA arbitration and the - * vga_client_register() fails with -ENODEV. - */ - ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); - if (ret && ret != -ENODEV) - goto out; - - intel_register_dsm_handler(); - - ret = vga_switcheroo_register_client(dev->pdev, - i915_switcheroo_set_state, - NULL, - i915_switcheroo_can_switch); - if (ret) - goto cleanup_vga_client; - - /* IIR "flip pending" bit means done if this bit is set */ - if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) - dev_priv->flip_pending_is_done = true; - - intel_modeset_init(dev); - - ret = i915_load_gem_init(dev); - if (ret) - goto cleanup_vga_switcheroo; - - intel_modeset_gem_init(dev); - - ret = drm_irq_install(dev); - if (ret) - goto cleanup_gem; - - /* Always safe in the mode setting case. */ - /* FIXME: do pre/post-mode set stuff in core KMS code */ - dev->vblank_disable_allowed = 1; - - ret = intel_fbdev_init(dev); - if (ret) - goto cleanup_irq; - - drm_kms_helper_poll_init(dev); - - /* We're off and running w/KMS */ - dev_priv->mm.suspended = 0; - - return 0; - -cleanup_irq: - drm_irq_uninstall(dev); -cleanup_gem: - mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); - mutex_unlock(&dev->struct_mutex); - i915_gem_cleanup_aliasing_ppgtt(dev); -cleanup_vga_switcheroo: - vga_switcheroo_unregister_client(dev->pdev); -cleanup_vga_client: - vga_client_register(dev->pdev, NULL, NULL, NULL); -out: - return ret; -} - -int i915_master_create(struct drm_device *dev, struct drm_master *master) -{ - struct drm_i915_master_private *master_priv; - - master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); - if (!master_priv) - return -ENOMEM; - - master->driver_priv = master_priv; - return 0; -} - -void i915_master_destroy(struct drm_device *dev, struct drm_master *master) -{ - struct drm_i915_master_private *master_priv = master->driver_priv; - - if (!master_priv) - return; - - kfree(master_priv); - - master->driver_priv = NULL; -} - -static void i915_pineview_get_mem_freq(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - u32 tmp; - - tmp = I915_READ(CLKCFG); - - switch (tmp & CLKCFG_FSB_MASK) { - case CLKCFG_FSB_533: - dev_priv->fsb_freq = 533; /* 133*4 */ - break; - case CLKCFG_FSB_800: - dev_priv->fsb_freq = 800; /* 200*4 */ - break; - case CLKCFG_FSB_667: - dev_priv->fsb_freq = 667; /* 167*4 */ - break; - case CLKCFG_FSB_400: - dev_priv->fsb_freq = 400; /* 100*4 */ - break; - } - - switch (tmp & CLKCFG_MEM_MASK) { - case CLKCFG_MEM_533: - dev_priv->mem_freq = 533; - break; - case CLKCFG_MEM_667: - dev_priv->mem_freq = 667; - break; - case CLKCFG_MEM_800: - dev_priv->mem_freq = 800; - break; - } - - /* detect pineview DDR3 setting */ - tmp = I915_READ(CSHRDDR3CTL); - dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; -} - -static void i915_ironlake_get_mem_freq(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - u16 ddrpll, csipll; - - ddrpll = I915_READ16(DDRMPLL1); - csipll = I915_READ16(CSIPLL0); - - switch (ddrpll & 0xff) { - case 0xc: - dev_priv->mem_freq = 800; - break; - case 0x10: - dev_priv->mem_freq = 1066; - break; - case 0x14: - dev_priv->mem_freq = 1333; - break; - case 0x18: - dev_priv->mem_freq = 1600; - break; - default: - DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n", - ddrpll & 0xff); - dev_priv->mem_freq = 0; - break; - } - - dev_priv->r_t = dev_priv->mem_freq; - - switch (csipll & 0x3ff) { - case 0x00c: - dev_priv->fsb_freq = 3200; - break; - case 0x00e: - dev_priv->fsb_freq = 3733; - break; - case 0x010: - dev_priv->fsb_freq = 4266; - break; - case 0x012: - dev_priv->fsb_freq = 4800; - break; - case 0x014: - dev_priv->fsb_freq = 5333; - break; - case 0x016: - dev_priv->fsb_freq = 5866; - break; - case 0x018: - dev_priv->fsb_freq = 6400; - break; - default: - DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n", - csipll & 0x3ff); - dev_priv->fsb_freq = 0; - break; - } - - if (dev_priv->fsb_freq == 3200) { - dev_priv->c_m = 0; - } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { - dev_priv->c_m = 1; - } else { - dev_priv->c_m = 2; - } -} - -static const struct cparams { - u16 i; - u16 t; - u16 m; - u16 c; -} cparams[] = { - { 1, 1333, 301, 28664 }, - { 1, 1066, 294, 24460 }, - { 1, 800, 294, 25192 }, - { 0, 1333, 276, 27605 }, - { 0, 1066, 276, 27605 }, - { 0, 800, 231, 23784 }, -}; - -unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) -{ - u64 total_count, diff, ret; - u32 count1, count2, count3, m = 0, c = 0; - unsigned long now = jiffies_to_msecs(jiffies), diff1; - int i; - - diff1 = now - dev_priv->last_time1; - - /* Prevent division-by-zero if we are asking too fast. - * Also, we don't get interesting results if we are polling - * faster than once in 10ms, so just return the saved value - * in such cases. - */ - if (diff1 <= 10) - return dev_priv->chipset_power; - - count1 = I915_READ(DMIEC); - count2 = I915_READ(DDREC); - count3 = I915_READ(CSIEC); - - total_count = count1 + count2 + count3; - - /* FIXME: handle per-counter overflow */ - if (total_count < dev_priv->last_count1) { - diff = ~0UL - dev_priv->last_count1; - diff += total_count; - } else { - diff = total_count - dev_priv->last_count1; - } - - for (i = 0; i < ARRAY_SIZE(cparams); i++) { - if (cparams[i].i == dev_priv->c_m && - cparams[i].t == dev_priv->r_t) { - m = cparams[i].m; - c = cparams[i].c; - break; - } - } - - diff = div_u64(diff, diff1); - ret = ((m * diff) + c); - ret = div_u64(ret, 10); - - dev_priv->last_count1 = total_count; - dev_priv->last_time1 = now; - - dev_priv->chipset_power = ret; - - return ret; -} - -unsigned long i915_mch_val(struct drm_i915_private *dev_priv) -{ - unsigned long m, x, b; - u32 tsfs; - - tsfs = I915_READ(TSFS); - - m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT); - x = I915_READ8(TR1); - - b = tsfs & TSFS_INTR_MASK; - - return ((m * x) / 127) - b; -} - -static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) -{ - static const struct v_table { - u16 vd; /* in .1 mil */ - u16 vm; /* in .1 mil */ - } v_table[] = { - { 0, 0, }, - { 375, 0, }, - { 500, 0, }, - { 625, 0, }, - { 750, 0, }, - { 875, 0, }, - { 1000, 0, }, - { 1125, 0, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4125, 3000, }, - { 4250, 3125, }, - { 4375, 3250, }, - { 4500, 3375, }, - { 4625, 3500, }, - { 4750, 3625, }, - { 4875, 3750, }, - { 5000, 3875, }, - { 5125, 4000, }, - { 5250, 4125, }, - { 5375, 4250, }, - { 5500, 4375, }, - { 5625, 4500, }, - { 5750, 4625, }, - { 5875, 4750, }, - { 6000, 4875, }, - { 6125, 5000, }, - { 6250, 5125, }, - { 6375, 5250, }, - { 6500, 5375, }, - { 6625, 5500, }, - { 6750, 5625, }, - { 6875, 5750, }, - { 7000, 5875, }, - { 7125, 6000, }, - { 7250, 6125, }, - { 7375, 6250, }, - { 7500, 6375, }, - { 7625, 6500, }, - { 7750, 6625, }, - { 7875, 6750, }, - { 8000, 6875, }, - { 8125, 7000, }, - { 8250, 7125, }, - { 8375, 7250, }, - { 8500, 7375, }, - { 8625, 7500, }, - { 8750, 7625, }, - { 8875, 7750, }, - { 9000, 7875, }, - { 9125, 8000, }, - { 9250, 8125, }, - { 9375, 8250, }, - { 9500, 8375, }, - { 9625, 8500, }, - { 9750, 8625, }, - { 9875, 8750, }, - { 10000, 8875, }, - { 10125, 9000, }, - { 10250, 9125, }, - { 10375, 9250, }, - { 10500, 9375, }, - { 10625, 9500, }, - { 10750, 9625, }, - { 10875, 9750, }, - { 11000, 9875, }, - { 11125, 10000, }, - { 11250, 10125, }, - { 11375, 10250, }, - { 11500, 10375, }, - { 11625, 10500, }, - { 11750, 10625, }, - { 11875, 10750, }, - { 12000, 10875, }, - { 12125, 11000, }, - { 12250, 11125, }, - { 12375, 11250, }, - { 12500, 11375, }, - { 12625, 11500, }, - { 12750, 11625, }, - { 12875, 11750, }, - { 13000, 11875, }, - { 13125, 12000, }, - { 13250, 12125, }, - { 13375, 12250, }, - { 13500, 12375, }, - { 13625, 12500, }, - { 13750, 12625, }, - { 13875, 12750, }, - { 14000, 12875, }, - { 14125, 13000, }, - { 14250, 13125, }, - { 14375, 13250, }, - { 14500, 13375, }, - { 14625, 13500, }, - { 14750, 13625, }, - { 14875, 13750, }, - { 15000, 13875, }, - { 15125, 14000, }, - { 15250, 14125, }, - { 15375, 14250, }, - { 15500, 14375, }, - { 15625, 14500, }, - { 15750, 14625, }, - { 15875, 14750, }, - { 16000, 14875, }, - { 16125, 15000, }, - }; - if (dev_priv->info->is_mobile) - return v_table[pxvid].vm; - else - return v_table[pxvid].vd; -} - -void i915_update_gfx_val(struct drm_i915_private *dev_priv) -{ - struct timespec now, diff1; - u64 diff; - unsigned long diffms; - u32 count; - - if (dev_priv->info->gen != 5) - return; - - getrawmonotonic(&now); - diff1 = timespec_sub(now, dev_priv->last_time2); - - /* Don't divide by 0 */ - diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000; - if (!diffms) - return; - - count = I915_READ(GFXEC); - - if (count < dev_priv->last_count2) { - diff = ~0UL - dev_priv->last_count2; - diff += count; - } else { - diff = count - dev_priv->last_count2; - } - - dev_priv->last_count2 = count; - dev_priv->last_time2 = now; - - /* More magic constants... */ - diff = diff * 1181; - diff = div_u64(diff, diffms * 10); - dev_priv->gfx_power = diff; -} - -unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) -{ - unsigned long t, corr, state1, corr2, state2; - u32 pxvid, ext_v; - - pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4)); - pxvid = (pxvid >> 24) & 0x7f; - ext_v = pvid_to_extvid(dev_priv, pxvid); - - state1 = ext_v; - - t = i915_mch_val(dev_priv); - - /* Revel in the empirically derived constants */ - - /* Correction factor in 1/100000 units */ - if (t > 80) - corr = ((t * 2349) + 135940); - else if (t >= 50) - corr = ((t * 964) + 29317); - else /* < 50 */ - corr = ((t * 301) + 1004); - - corr = corr * ((150142 * state1) / 10000 - 78642); - corr /= 100000; - corr2 = (corr * dev_priv->corr); - - state2 = (corr2 * state1) / 10000; - state2 /= 100; /* convert to mW */ - - i915_update_gfx_val(dev_priv); - - return dev_priv->gfx_power + state2; -} - -/* Global for IPS driver to get at the current i915 device */ -static struct drm_i915_private *i915_mch_dev; -/* - * Lock protecting IPS related data structures - * - i915_mch_dev - * - dev_priv->max_delay - * - dev_priv->min_delay - * - dev_priv->fmax - * - dev_priv->gpu_busy - */ -static DEFINE_SPINLOCK(mchdev_lock); - -/** - * i915_read_mch_val - return value for IPS use - * - * Calculate and return a value for the IPS driver to use when deciding whether - * we have thermal and power headroom to increase CPU or GPU power budget. - */ -unsigned long i915_read_mch_val(void) -{ - struct drm_i915_private *dev_priv; - unsigned long chipset_val, graphics_val, ret = 0; - - spin_lock(&mchdev_lock); - if (!i915_mch_dev) - goto out_unlock; - dev_priv = i915_mch_dev; - - chipset_val = i915_chipset_val(dev_priv); - graphics_val = i915_gfx_val(dev_priv); - - ret = chipset_val + graphics_val; - -out_unlock: - spin_unlock(&mchdev_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(i915_read_mch_val); - -/** - * i915_gpu_raise - raise GPU frequency limit - * - * Raise the limit; IPS indicates we have thermal headroom. - */ -bool i915_gpu_raise(void) -{ - struct drm_i915_private *dev_priv; - bool ret = true; - - spin_lock(&mchdev_lock); - if (!i915_mch_dev) { - ret = false; - goto out_unlock; - } - dev_priv = i915_mch_dev; - - if (dev_priv->max_delay > dev_priv->fmax) - dev_priv->max_delay--; - -out_unlock: - spin_unlock(&mchdev_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(i915_gpu_raise); - -/** - * i915_gpu_lower - lower GPU frequency limit - * - * IPS indicates we're close to a thermal limit, so throttle back the GPU - * frequency maximum. - */ -bool i915_gpu_lower(void) -{ - struct drm_i915_private *dev_priv; - bool ret = true; - - spin_lock(&mchdev_lock); - if (!i915_mch_dev) { - ret = false; - goto out_unlock; - } - dev_priv = i915_mch_dev; - - if (dev_priv->max_delay < dev_priv->min_delay) - dev_priv->max_delay++; - -out_unlock: - spin_unlock(&mchdev_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(i915_gpu_lower); - -/** - * i915_gpu_busy - indicate GPU business to IPS - * - * Tell the IPS driver whether or not the GPU is busy. - */ -bool i915_gpu_busy(void) -{ - struct drm_i915_private *dev_priv; - bool ret = false; - - spin_lock(&mchdev_lock); - if (!i915_mch_dev) - goto out_unlock; - dev_priv = i915_mch_dev; - - ret = dev_priv->busy; - -out_unlock: - spin_unlock(&mchdev_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(i915_gpu_busy); - -/** - * i915_gpu_turbo_disable - disable graphics turbo - * - * Disable graphics turbo by resetting the max frequency and setting the - * current frequency to the default. - */ -bool i915_gpu_turbo_disable(void) -{ - struct drm_i915_private *dev_priv; - bool ret = true; - - spin_lock(&mchdev_lock); - if (!i915_mch_dev) { - ret = false; - goto out_unlock; - } - dev_priv = i915_mch_dev; - - dev_priv->max_delay = dev_priv->fstart; - - if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart)) - ret = false; - -out_unlock: - spin_unlock(&mchdev_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); - -/** - * Tells the intel_ips driver that the i915 driver is now loaded, if - * IPS got loaded first. - * - * This awkward dance is so that neither module has to depend on the - * other in order for IPS to do the appropriate communication of - * GPU turbo limits to i915. - */ -static void -ips_ping_for_i915_load(void) -{ - void (*link)(void); - - link = symbol_get(ips_link_to_i915_driver); - if (link) { - link(); - symbol_put(ips_link_to_i915_driver); - } -} - -/** - * i915_driver_load - setup chip and create an initial config - * @dev: DRM device - * @flags: startup flags - * - * The driver load routine has to do several things: - * - drive output discovery via intel_modeset_init() - * - initialize the memory manager - * - allocate initial config memory - * - setup the DRM framebuffer with the allocated memory - */ -int i915_driver_load(struct drm_device *dev, unsigned long flags) -{ - struct drm_i915_private *dev_priv; - int ret = 0, mmio_bar; - uint32_t agp_size; - - /* i915 has 4 more counters */ - dev->counters += 4; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - dev->types[9] = _DRM_STAT_DMA; - - dev_priv = kzalloc(sizeof(drm_i915_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev->dev_private = (void *)dev_priv; - dev_priv->dev = dev; - dev_priv->info = (struct intel_device_info *) flags; - - if (i915_get_bridge_dev(dev)) { - ret = -EIO; - goto free_priv; - } - - pci_set_master(dev->pdev); - - /* overlay on gen2 is broken and can't address above 1G */ - if (IS_GEN2(dev)) - dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); - - /* 965GM sometimes incorrectly writes to hardware status page (HWS) - * using 32bit addressing, overwriting memory if HWS is located - * above 4GB. - * - * The documentation also mentions an issue with undefined - * behaviour if any general state is accessed within a page above 4GB, - * which also needs to be handled carefully. - */ - if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) - dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); - - mmio_bar = IS_GEN2(dev) ? 1 : 0; - dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); - if (!dev_priv->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -EIO; - goto put_bridge; - } - - dev_priv->mm.gtt = intel_gtt_get(); - if (!dev_priv->mm.gtt) { - DRM_ERROR("Failed to initialize GTT\n"); - ret = -ENODEV; - goto out_rmmap; - } - - agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - - dev_priv->mm.gtt_mapping = - io_mapping_create_wc(dev->agp->base, agp_size); - if (dev_priv->mm.gtt_mapping == NULL) { - ret = -EIO; - goto out_rmmap; - } - - /* Set up a WC MTRR for non-PAT systems. This is more common than - * one would think, because the kernel disables PAT on first - * generation Core chips because WC PAT gets overridden by a UC - * MTRR if present. Even if a UC MTRR isn't present. - */ - dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, - agp_size, - MTRR_TYPE_WRCOMB, 1); - if (dev_priv->mm.gtt_mtrr < 0) { - DRM_INFO("MTRR allocation failed. Graphics " - "performance may suffer.\n"); - } - - /* The i915 workqueue is primarily used for batched retirement of - * requests (and thus managing bo) once the task has been completed - * by the GPU. i915_gem_retire_requests() is called directly when we - * need high-priority retirement, such as waiting for an explicit - * bo. - * - * It is also used for periodic low-priority events, such as - * idle-timers and recording error state. - * - * All tasks on the workqueue are expected to acquire the dev mutex - * so there is no point in running more than one instance of the - * workqueue at any time: max_active = 1 and NON_REENTRANT. - */ - dev_priv->wq = alloc_workqueue("i915", - WQ_UNBOUND | WQ_NON_REENTRANT, - 1); - if (dev_priv->wq == NULL) { - DRM_ERROR("Failed to create our workqueue.\n"); - ret = -ENOMEM; - goto out_mtrrfree; - } - - /* enable GEM by default */ - dev_priv->has_gem = 1; - - intel_irq_init(dev); - - /* Try to make sure MCHBAR is enabled before poking at it */ - intel_setup_mchbar(dev); - intel_setup_gmbus(dev); - intel_opregion_setup(dev); - - /* Make sure the bios did its job and set up vital registers */ - intel_setup_bios(dev); - - i915_gem_load(dev); - - /* Init HWS */ - if (!I915_NEED_GFX_HWS(dev)) { - ret = i915_init_phys_hws(dev); - if (ret) - goto out_gem_unload; - } - - if (IS_PINEVIEW(dev)) - i915_pineview_get_mem_freq(dev); - else if (IS_GEN5(dev)) - i915_ironlake_get_mem_freq(dev); - - /* On the 945G/GM, the chipset reports the MSI capability on the - * integrated graphics even though the support isn't actually there - * according to the published specs. It doesn't appear to function - * correctly in testing on 945G. - * This may be a side effect of MSI having been made available for PEG - * and the registers being closely associated. - * - * According to chipset errata, on the 965GM, MSI interrupts may - * be lost or delayed, but we use them anyways to avoid - * stuck interrupts on some machines. - */ - if (!IS_I945G(dev) && !IS_I945GM(dev)) - pci_enable_msi(dev->pdev); - - spin_lock_init(&dev_priv->gt_lock); - spin_lock_init(&dev_priv->irq_lock); - spin_lock_init(&dev_priv->error_lock); - spin_lock_init(&dev_priv->rps_lock); - - if (IS_IVYBRIDGE(dev)) - dev_priv->num_pipe = 3; - else if (IS_MOBILE(dev) || !IS_GEN2(dev)) - dev_priv->num_pipe = 2; - else - dev_priv->num_pipe = 1; - - ret = drm_vblank_init(dev, dev_priv->num_pipe); - if (ret) - goto out_gem_unload; - - /* Start out suspended */ - dev_priv->mm.suspended = 1; - - intel_detect_pch(dev); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = i915_load_modeset_init(dev); - if (ret < 0) { - DRM_ERROR("failed to init modeset\n"); - goto out_gem_unload; - } - } - - /* Must be done after probing outputs */ - intel_opregion_init(dev); - acpi_video_register(); - - setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, - (unsigned long) dev); - - if (IS_GEN5(dev)) { - spin_lock(&mchdev_lock); - i915_mch_dev = dev_priv; - dev_priv->mchdev_lock = &mchdev_lock; - spin_unlock(&mchdev_lock); - - ips_ping_for_i915_load(); - } - - return 0; - -out_gem_unload: - if (dev_priv->mm.inactive_shrinker.shrink) - unregister_shrinker(&dev_priv->mm.inactive_shrinker); - - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - intel_teardown_gmbus(dev); - intel_teardown_mchbar(dev); - destroy_workqueue(dev_priv->wq); -out_mtrrfree: - if (dev_priv->mm.gtt_mtrr >= 0) { - mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, - dev->agp->agp_info.aper_size * 1024 * 1024); - dev_priv->mm.gtt_mtrr = -1; - } - io_mapping_free(dev_priv->mm.gtt_mapping); -out_rmmap: - pci_iounmap(dev->pdev, dev_priv->regs); -put_bridge: - pci_dev_put(dev_priv->bridge_dev); -free_priv: - kfree(dev_priv); - return ret; -} - -int i915_driver_unload(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - spin_lock(&mchdev_lock); - i915_mch_dev = NULL; - spin_unlock(&mchdev_lock); - - if (dev_priv->mm.inactive_shrinker.shrink) - unregister_shrinker(&dev_priv->mm.inactive_shrinker); - - mutex_lock(&dev->struct_mutex); - ret = i915_gpu_idle(dev, true); - if (ret) - DRM_ERROR("failed to idle hardware: %d\n", ret); - mutex_unlock(&dev->struct_mutex); - - /* Cancel the retire work handler, which should be idle now. */ - cancel_delayed_work_sync(&dev_priv->mm.retire_work); - - io_mapping_free(dev_priv->mm.gtt_mapping); - if (dev_priv->mm.gtt_mtrr >= 0) { - mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, - dev->agp->agp_info.aper_size * 1024 * 1024); - dev_priv->mm.gtt_mtrr = -1; - } - - acpi_video_unregister(); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - intel_fbdev_fini(dev); - intel_modeset_cleanup(dev); - - /* - * free the memory space allocated for the child device - * config parsed from VBT - */ - if (dev_priv->child_dev && dev_priv->child_dev_num) { - kfree(dev_priv->child_dev); - dev_priv->child_dev = NULL; - dev_priv->child_dev_num = 0; - } - - vga_switcheroo_unregister_client(dev->pdev); - vga_client_register(dev->pdev, NULL, NULL, NULL); - } - - /* Free error state after interrupts are fully disabled. */ - del_timer_sync(&dev_priv->hangcheck_timer); - cancel_work_sync(&dev_priv->error_work); - i915_destroy_error_state(dev); - - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - intel_opregion_fini(dev); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - /* Flush any outstanding unpin_work. */ - flush_workqueue(dev_priv->wq); - - mutex_lock(&dev->struct_mutex); - i915_gem_free_all_phys_object(dev); - i915_gem_cleanup_ringbuffer(dev); - mutex_unlock(&dev->struct_mutex); - i915_gem_cleanup_aliasing_ppgtt(dev); - if (I915_HAS_FBC(dev) && i915_powersave) - i915_cleanup_compression(dev); - drm_mm_takedown(&dev_priv->mm.stolen); - - intel_cleanup_overlay(dev); - - if (!I915_NEED_GFX_HWS(dev)) - i915_free_hws(dev); - } - - if (dev_priv->regs != NULL) - pci_iounmap(dev->pdev, dev_priv->regs); - - intel_teardown_gmbus(dev); - intel_teardown_mchbar(dev); - - destroy_workqueue(dev_priv->wq); - - pci_dev_put(dev_priv->bridge_dev); - kfree(dev->dev_private); - - return 0; -} - -int i915_driver_open(struct drm_device *dev, struct drm_file *file) -{ - struct drm_i915_file_private *file_priv; - - DRM_DEBUG_DRIVER("\n"); - file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); - if (!file_priv) - return -ENOMEM; - - file->driver_priv = file_priv; - - spin_lock_init(&file_priv->mm.lock); - INIT_LIST_HEAD(&file_priv->mm.request_list); - - return 0; -} - -/** - * i915_driver_lastclose - clean up after all DRM clients have exited - * @dev: DRM device - * - * Take care of cleaning up after all DRM clients have exited. In the - * mode setting case, we want to restore the kernel's initial mode (just - * in case the last client left us in a bad state). - * - * Additionally, in the non-mode setting case, we'll tear down the AGP - * and DMA structures, since the kernel won't be using them, and clea - * up any GEM state. - */ -void i915_driver_lastclose(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { - intel_fb_restore_mode(dev); - vga_switcheroo_process_delayed_switch(); - return; - } - - i915_gem_lastclose(dev); - - i915_dma_cleanup(dev); -} - -void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) -{ - i915_gem_release(dev, file_priv); -} - -void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) -{ - struct drm_i915_file_private *file_priv = file->driver_priv; - - kfree(file_priv); -} - -struct drm_ioctl_desc i915_ioctls[] = { - DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), -}; - -int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); - -/** - * Determine if the device really is AGP or not. - * - * All Intel graphics chipsets are treated as AGP, even if they are really - * PCI-e. - * - * \param dev The device to be tested. - * - * \returns - * A value of 1 is always retured to indictate every i9x5 is AGP. - */ -int i915_driver_device_is_agp(struct drm_device * dev) -{ - return 1; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.c deleted file mode 100644 index ae8a64f9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- - */ -/* - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "intel_drv.h" - -#include -#include -#include "drm_crtc_helper.h" - -static int i915_modeset __read_mostly = -1; -module_param_named(modeset, i915_modeset, int, 0400); -MODULE_PARM_DESC(modeset, - "Use kernel modesetting [KMS] (0=DRM_I915_KMS from .config, " - "1=on, -1=force vga console preference [default])"); - -unsigned int i915_fbpercrtc __always_unused = 0; -module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); - -int i915_panel_ignore_lid __read_mostly = 0; -module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600); -MODULE_PARM_DESC(panel_ignore_lid, - "Override lid status (0=autodetect [default], 1=lid open, " - "-1=lid closed)"); - -unsigned int i915_powersave __read_mostly = 1; -module_param_named(powersave, i915_powersave, int, 0600); -MODULE_PARM_DESC(powersave, - "Enable powersavings, fbc, downclocking, etc. (default: true)"); - -int i915_semaphores __read_mostly = -1; -module_param_named(semaphores, i915_semaphores, int, 0600); -MODULE_PARM_DESC(semaphores, - "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); - -int i915_enable_rc6 __read_mostly = -1; -module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); -MODULE_PARM_DESC(i915_enable_rc6, - "Enable power-saving render C-state 6. " - "Different stages can be selected via bitmask values " - "(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). " - "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " - "default: -1 (use per-chip default)"); - -int i915_enable_fbc __read_mostly = -1; -module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); -MODULE_PARM_DESC(i915_enable_fbc, - "Enable frame buffer compression for power savings " - "(default: -1 (use per-chip default))"); - -unsigned int i915_lvds_downclock __read_mostly = 0; -module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); -MODULE_PARM_DESC(lvds_downclock, - "Use panel (LVDS/eDP) downclocking for power savings " - "(default: false)"); - -int i915_panel_use_ssc __read_mostly = -1; -module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); -MODULE_PARM_DESC(lvds_use_ssc, - "Use Spread Spectrum Clock with panels [LVDS/eDP] " - "(default: auto from VBT)"); - -int i915_vbt_sdvo_panel_type __read_mostly = -1; -module_param_named(vbt_sdvo_panel_type, i915_vbt_sdvo_panel_type, int, 0600); -MODULE_PARM_DESC(vbt_sdvo_panel_type, - "Override selection of SDVO panel mode in the VBT " - "(default: auto)"); - -static bool i915_try_reset __read_mostly = true; -module_param_named(reset, i915_try_reset, bool, 0600); -MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)"); - -bool i915_enable_hangcheck __read_mostly = true; -module_param_named(enable_hangcheck, i915_enable_hangcheck, bool, 0644); -MODULE_PARM_DESC(enable_hangcheck, - "Periodically check GPU activity for detecting hangs. " - "WARNING: Disabling this can cause system wide hangs. " - "(default: true)"); - -int i915_enable_ppgtt __read_mostly = -1; -module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); -MODULE_PARM_DESC(i915_enable_ppgtt, - "Enable PPGTT (default: true)"); - -static struct drm_driver driver; -extern int intel_agp_enabled; - -#define INTEL_VGA_DEVICE(id, info) { \ - .class = PCI_BASE_CLASS_DISPLAY << 16, \ - .class_mask = 0xff0000, \ - .vendor = 0x8086, \ - .device = id, \ - .subvendor = PCI_ANY_ID, \ - .subdevice = PCI_ANY_ID, \ - .driver_data = (unsigned long) info } - -static const struct intel_device_info intel_i830_info = { - .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, -}; - -static const struct intel_device_info intel_845g_info = { - .gen = 2, - .has_overlay = 1, .overlay_needs_physical = 1, -}; - -static const struct intel_device_info intel_i85x_info = { - .gen = 2, .is_i85x = 1, .is_mobile = 1, - .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, -}; - -static const struct intel_device_info intel_i865g_info = { - .gen = 2, - .has_overlay = 1, .overlay_needs_physical = 1, -}; - -static const struct intel_device_info intel_i915g_info = { - .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, -}; -static const struct intel_device_info intel_i915gm_info = { - .gen = 3, .is_mobile = 1, - .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .supports_tv = 1, -}; -static const struct intel_device_info intel_i945g_info = { - .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, -}; -static const struct intel_device_info intel_i945gm_info = { - .gen = 3, .is_i945gm = 1, .is_mobile = 1, - .has_hotplug = 1, .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .supports_tv = 1, -}; - -static const struct intel_device_info intel_i965g_info = { - .gen = 4, .is_broadwater = 1, - .has_hotplug = 1, - .has_overlay = 1, -}; - -static const struct intel_device_info intel_i965gm_info = { - .gen = 4, .is_crestline = 1, - .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, - .has_overlay = 1, - .supports_tv = 1, -}; - -static const struct intel_device_info intel_g33_info = { - .gen = 3, .is_g33 = 1, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_overlay = 1, -}; - -static const struct intel_device_info intel_g45_info = { - .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, - .has_pipe_cxsr = 1, .has_hotplug = 1, - .has_bsd_ring = 1, -}; - -static const struct intel_device_info intel_gm45_info = { - .gen = 4, .is_g4x = 1, - .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, - .has_pipe_cxsr = 1, .has_hotplug = 1, - .supports_tv = 1, - .has_bsd_ring = 1, -}; - -static const struct intel_device_info intel_pineview_info = { - .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_overlay = 1, -}; - -static const struct intel_device_info intel_ironlake_d_info = { - .gen = 5, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_bsd_ring = 1, -}; - -static const struct intel_device_info intel_ironlake_m_info = { - .gen = 5, .is_mobile = 1, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 1, - .has_bsd_ring = 1, -}; - -static const struct intel_device_info intel_sandybridge_d_info = { - .gen = 6, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_bsd_ring = 1, - .has_blt_ring = 1, - .has_llc = 1, -}; - -static const struct intel_device_info intel_sandybridge_m_info = { - .gen = 6, .is_mobile = 1, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 1, - .has_bsd_ring = 1, - .has_blt_ring = 1, - .has_llc = 1, -}; - -static const struct intel_device_info intel_ivybridge_d_info = { - .is_ivybridge = 1, .gen = 7, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_bsd_ring = 1, - .has_blt_ring = 1, - .has_llc = 1, -}; - -static const struct intel_device_info intel_ivybridge_m_info = { - .is_ivybridge = 1, .gen = 7, .is_mobile = 1, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ - .has_bsd_ring = 1, - .has_blt_ring = 1, - .has_llc = 1, -}; - -static const struct pci_device_id pciidlist[] = { /* aka */ - INTEL_VGA_DEVICE(0x3577, &intel_i830_info), /* I830_M */ - INTEL_VGA_DEVICE(0x2562, &intel_845g_info), /* 845_G */ - INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), /* I855_GM */ - INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), - INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), /* I865_G */ - INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), /* I915_G */ - INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), /* E7221_G */ - INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info), /* I915_GM */ - INTEL_VGA_DEVICE(0x2772, &intel_i945g_info), /* I945_G */ - INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info), /* I945_GM */ - INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info), /* I945_GME */ - INTEL_VGA_DEVICE(0x2972, &intel_i965g_info), /* I946_GZ */ - INTEL_VGA_DEVICE(0x2982, &intel_i965g_info), /* G35_G */ - INTEL_VGA_DEVICE(0x2992, &intel_i965g_info), /* I965_Q */ - INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info), /* I965_G */ - INTEL_VGA_DEVICE(0x29b2, &intel_g33_info), /* Q35_G */ - INTEL_VGA_DEVICE(0x29c2, &intel_g33_info), /* G33_G */ - INTEL_VGA_DEVICE(0x29d2, &intel_g33_info), /* Q33_G */ - INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info), /* I965_GM */ - INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info), /* I965_GME */ - INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info), /* GM45_G */ - INTEL_VGA_DEVICE(0x2e02, &intel_g45_info), /* IGD_E_G */ - INTEL_VGA_DEVICE(0x2e12, &intel_g45_info), /* Q45_G */ - INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ - INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ - INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ - INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ - INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), - INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), - INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), - INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), - INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), - INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), - INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), - INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), - INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), - INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), - INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), - INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */ - INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */ - INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ - INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ - INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ - INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ - {0, 0, 0} -}; - -#if defined(CONFIG_DRM_I915_KMS) -MODULE_DEVICE_TABLE(pci, pciidlist); -#endif - -#define INTEL_PCH_DEVICE_ID_MASK 0xff00 -#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 -#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 -#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 - -void intel_detect_pch(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct pci_dev *pch; - - /* - * The reason to probe ISA bridge instead of Dev31:Fun0 is to - * make graphics device passthrough work easy for VMM, that only - * need to expose ISA bridge to let driver know the real hardware - * underneath. This is a requirement from virtualization team. - */ - pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); - if (pch) { - if (pch->vendor == PCI_VENDOR_ID_INTEL) { - int id; - id = pch->device & INTEL_PCH_DEVICE_ID_MASK; - - if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { - dev_priv->pch_type = PCH_IBX; - DRM_DEBUG_KMS("Found Ibex Peak PCH\n"); - } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) { - dev_priv->pch_type = PCH_CPT; - DRM_DEBUG_KMS("Found CougarPoint PCH\n"); - } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) { - /* PantherPoint is CPT compatible */ - dev_priv->pch_type = PCH_CPT; - DRM_DEBUG_KMS("Found PatherPoint PCH\n"); - } - } - pci_dev_put(pch); - } -} - -void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) -{ - int count; - - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) - udelay(10); - - I915_WRITE_NOTRACE(FORCEWAKE, 1); - POSTING_READ(FORCEWAKE); - - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) - udelay(10); -} - -void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) -{ - int count; - - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1)) - udelay(10); - - I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1); - POSTING_READ(FORCEWAKE_MT); - - count = 0; - while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0) - udelay(10); -} - -/* - * Generally this is called implicitly by the register read function. However, - * if some sequence requires the GT to not power down then this function should - * be called at the beginning of the sequence followed by a call to - * gen6_gt_force_wake_put() at the end of the sequence. - */ -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) -{ - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (dev_priv->forcewake_count++ == 0) - dev_priv->display.force_wake_get(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); -} - -static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) -{ - u32 gtfifodbg; - gtfifodbg = I915_READ_NOTRACE(GTFIFODBG); - if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK, - "MMIO read or write has been dropped %x\n", gtfifodbg)) - I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK); -} - -void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) -{ - I915_WRITE_NOTRACE(FORCEWAKE, 0); - /* The below doubles as a POSTING_READ */ - gen6_gt_check_fifodbg(dev_priv); -} - -void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) -{ - I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0); - /* The below doubles as a POSTING_READ */ - gen6_gt_check_fifodbg(dev_priv); -} - -/* - * see gen6_gt_force_wake_get() - */ -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) -{ - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (--dev_priv->forcewake_count == 0) - dev_priv->display.force_wake_put(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); -} - -int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) -{ - int ret = 0; - - if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) { - int loop = 500; - u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) { - udelay(10); - fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - } - if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES)) - ++ret; - dev_priv->gt_fifo_count = fifo; - } - dev_priv->gt_fifo_count--; - - return ret; -} - -static int i915_drm_freeze(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - drm_kms_helper_poll_disable(dev); - - pci_save_state(dev->pdev); - - /* If KMS is active, we do the leavevt stuff here */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - int error = i915_gem_idle(dev); - if (error) { - dev_err(&dev->pdev->dev, - "GEM idle failed, resume might fail\n"); - return error; - } - drm_irq_uninstall(dev); - } - - i915_save_state(dev); - - intel_opregion_fini(dev); - - /* Modeset on resume, not lid events */ - dev_priv->modeset_on_lid = 0; - - console_lock(); - intel_fbdev_set_suspend(dev, 1); - console_unlock(); - - return 0; -} - -int i915_suspend(struct drm_device *dev, pm_message_t state) -{ - int error; - - if (!dev || !dev->dev_private) { - DRM_ERROR("dev: %p\n", dev); - DRM_ERROR("DRM not initialized, aborting suspend.\n"); - return -ENODEV; - } - - if (state.event == PM_EVENT_PRETHAW) - return 0; - - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - error = i915_drm_freeze(dev); - if (error) - return error; - - if (state.event == PM_EVENT_SUSPEND) { - /* Shut down the device */ - pci_disable_device(dev->pdev); - pci_set_power_state(dev->pdev, PCI_D3hot); - } - - return 0; -} - -static int i915_drm_thaw(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int error = 0; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - mutex_lock(&dev->struct_mutex); - i915_gem_restore_gtt_mappings(dev); - mutex_unlock(&dev->struct_mutex); - } - - i915_restore_state(dev); - intel_opregion_setup(dev); - - /* KMS EnterVT equivalent */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - mutex_lock(&dev->struct_mutex); - dev_priv->mm.suspended = 0; - - error = i915_gem_init_hw(dev); - mutex_unlock(&dev->struct_mutex); - - if (HAS_PCH_SPLIT(dev)) - ironlake_init_pch_refclk(dev); - - drm_mode_config_reset(dev); - drm_irq_install(dev); - - /* Resume the modeset for every activated CRTC */ - mutex_lock(&dev->mode_config.mutex); - drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); - - if (IS_IRONLAKE_M(dev)) - ironlake_enable_rc6(dev); - } - - intel_opregion_init(dev); - - dev_priv->modeset_on_lid = 0; - - console_lock(); - intel_fbdev_set_suspend(dev, 0); - console_unlock(); - return error; -} - -int i915_resume(struct drm_device *dev) -{ - int ret; - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - if (pci_enable_device(dev->pdev)) - return -EIO; - - pci_set_master(dev->pdev); - - ret = i915_drm_thaw(dev); - if (ret) - return ret; - - drm_kms_helper_poll_enable(dev); - return 0; -} - -static int i8xx_do_reset(struct drm_device *dev, u8 flags) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (IS_I85X(dev)) - return -ENODEV; - - I915_WRITE(D_STATE, I915_READ(D_STATE) | DSTATE_GFX_RESET_I830); - POSTING_READ(D_STATE); - - if (IS_I830(dev) || IS_845G(dev)) { - I915_WRITE(DEBUG_RESET_I830, - DEBUG_RESET_DISPLAY | - DEBUG_RESET_RENDER | - DEBUG_RESET_FULL); - POSTING_READ(DEBUG_RESET_I830); - msleep(1); - - I915_WRITE(DEBUG_RESET_I830, 0); - POSTING_READ(DEBUG_RESET_I830); - } - - msleep(1); - - I915_WRITE(D_STATE, I915_READ(D_STATE) & ~DSTATE_GFX_RESET_I830); - POSTING_READ(D_STATE); - - return 0; -} - -static int i965_reset_complete(struct drm_device *dev) -{ - u8 gdrst; - pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); - return gdrst & 0x1; -} - -static int i965_do_reset(struct drm_device *dev, u8 flags) -{ - u8 gdrst; - - /* - * Set the domains we want to reset (GRDOM/bits 2 and 3) as - * well as the reset bit (GR/bit 0). Setting the GR bit - * triggers the reset; when done, the hardware will clear it. - */ - pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); - pci_write_config_byte(dev->pdev, I965_GDRST, gdrst | flags | 0x1); - - return wait_for(i965_reset_complete(dev), 500); -} - -static int ironlake_do_reset(struct drm_device *dev, u8 flags) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 gdrst = I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR); - I915_WRITE(MCHBAR_MIRROR_BASE + ILK_GDSR, gdrst | flags | 0x1); - return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); -} - -static int gen6_do_reset(struct drm_device *dev, u8 flags) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - unsigned long irqflags; - - /* Hold gt_lock across reset to prevent any register access - * with forcewake not set correctly - */ - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - - /* Reset the chip */ - - /* GEN6_GDRST is not in the gt power well, no need to check - * for fifo space for the write or forcewake the chip for - * the read - */ - I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); - - /* Spin waiting for the device to ack the reset request */ - ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); - - /* If reset with a user forcewake, try to restore, otherwise turn it off */ - if (dev_priv->forcewake_count) - dev_priv->display.force_wake_get(dev_priv); - else - dev_priv->display.force_wake_put(dev_priv); - - /* Restore fifo count */ - dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); - return ret; -} - -/** - * i915_reset - reset chip after a hang - * @dev: drm device to reset - * @flags: reset domains - * - * Reset the chip. Useful if a hang is detected. Returns zero on successful - * reset or otherwise an error code. - * - * Procedure is fairly simple: - * - reset the chip using the reset reg - * - re-init context state - * - re-init hardware status page - * - re-init ring buffer - * - re-init interrupt state - * - re-init display - */ -int i915_reset(struct drm_device *dev, u8 flags) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - /* - * We really should only reset the display subsystem if we actually - * need to - */ - bool need_display = true; - int ret; - - if (!i915_try_reset) - return 0; - - if (!mutex_trylock(&dev->struct_mutex)) - return -EBUSY; - - i915_gem_reset(dev); - - ret = -ENODEV; - if (get_seconds() - dev_priv->last_gpu_reset < 5) { - DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); - } else switch (INTEL_INFO(dev)->gen) { - case 7: - case 6: - ret = gen6_do_reset(dev, flags); - break; - case 5: - ret = ironlake_do_reset(dev, flags); - break; - case 4: - ret = i965_do_reset(dev, flags); - break; - case 2: - ret = i8xx_do_reset(dev, flags); - break; - } - dev_priv->last_gpu_reset = get_seconds(); - if (ret) { - DRM_ERROR("Failed to reset chip.\n"); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - /* Ok, now get things going again... */ - - /* - * Everything depends on having the GTT running, so we need to start - * there. Fortunately we don't need to do this unless we reset the - * chip at a PCI level. - * - * Next we need to restore the context, but we don't use those - * yet either... - * - * Ring buffer needs to be re-initialized in the KMS case, or if X - * was running at the time of the reset (i.e. we weren't VT - * switched away). - */ - if (drm_core_check_feature(dev, DRIVER_MODESET) || - !dev_priv->mm.suspended) { - dev_priv->mm.suspended = 0; - - i915_gem_init_swizzling(dev); - - dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); - if (HAS_BSD(dev)) - dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); - if (HAS_BLT(dev)) - dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); - - i915_gem_init_ppgtt(dev); - - mutex_unlock(&dev->struct_mutex); - drm_irq_uninstall(dev); - drm_mode_config_reset(dev); - drm_irq_install(dev); - mutex_lock(&dev->struct_mutex); - } - - mutex_unlock(&dev->struct_mutex); - - /* - * Perform a full modeset as on later generations, e.g. Ironlake, we may - * need to retrain the display link and cannot just restore the register - * values. - */ - if (need_display) { - mutex_lock(&dev->mode_config.mutex); - drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); - } - - return 0; -} - - -static int __devinit -i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - /* Only bind to function 0 of the device. Early generations - * used function 1 as a placeholder for multi-head. This causes - * us confusion instead, especially on the systems where both - * functions have the same PCI-ID! - */ - if (PCI_FUNC(pdev->devfn)) - return -ENODEV; - - return drm_get_pci_dev(pdev, ent, &driver); -} - -static void -i915_pci_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - drm_put_dev(dev); -} - -static int i915_pm_suspend(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - int error; - - if (!drm_dev || !drm_dev->dev_private) { - dev_err(dev, "DRM not initialized, aborting suspend.\n"); - return -ENODEV; - } - - if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - error = i915_drm_freeze(drm_dev); - if (error) - return error; - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int i915_pm_resume(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - return i915_resume(drm_dev); -} - -static int i915_pm_freeze(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - if (!drm_dev || !drm_dev->dev_private) { - dev_err(dev, "DRM not initialized, aborting suspend.\n"); - return -ENODEV; - } - - return i915_drm_freeze(drm_dev); -} - -static int i915_pm_thaw(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - return i915_drm_thaw(drm_dev); -} - -static int i915_pm_poweroff(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct drm_device *drm_dev = pci_get_drvdata(pdev); - - return i915_drm_freeze(drm_dev); -} - -static const struct dev_pm_ops i915_pm_ops = { - .suspend = i915_pm_suspend, - .resume = i915_pm_resume, - .freeze = i915_pm_freeze, - .thaw = i915_pm_thaw, - .poweroff = i915_pm_poweroff, - .restore = i915_pm_resume, -}; - -static struct vm_operations_struct i915_gem_vm_ops = { - .fault = i915_gem_fault, - .open = drm_gem_vm_open, - .close = drm_gem_vm_close, -}; - -static const struct file_operations i915_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_gem_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, -#ifdef CONFIG_COMPAT - .compat_ioctl = i915_compat_ioctl, -#endif - .llseek = noop_llseek, -}; - -static struct drm_driver driver = { - /* Don't use MTRRs here; the Xserver or userspace app should - * deal with them for Intel hardware. - */ - .driver_features = - DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM, - .load = i915_driver_load, - .unload = i915_driver_unload, - .open = i915_driver_open, - .lastclose = i915_driver_lastclose, - .preclose = i915_driver_preclose, - .postclose = i915_driver_postclose, - - /* Used in place of i915_pm_ops for non-DRIVER_MODESET */ - .suspend = i915_suspend, - .resume = i915_resume, - - .device_is_agp = i915_driver_device_is_agp, - .reclaim_buffers = drm_core_reclaim_buffers, - .master_create = i915_master_create, - .master_destroy = i915_master_destroy, -#if defined(CONFIG_DEBUG_FS) - .debugfs_init = i915_debugfs_init, - .debugfs_cleanup = i915_debugfs_cleanup, -#endif - .gem_init_object = i915_gem_init_object, - .gem_free_object = i915_gem_free_object, - .gem_vm_ops = &i915_gem_vm_ops, - .dumb_create = i915_gem_dumb_create, - .dumb_map_offset = i915_gem_mmap_gtt, - .dumb_destroy = i915_gem_dumb_destroy, - .ioctls = i915_ioctls, - .fops = &i915_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct pci_driver i915_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = i915_pci_probe, - .remove = i915_pci_remove, - .driver.pm = &i915_pm_ops, -}; - -static int __init i915_init(void) -{ - if (!intel_agp_enabled) { - DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); - return -ENODEV; - } - - driver.num_ioctls = i915_max_ioctl; - - /* - * If CONFIG_DRM_I915_KMS is set, default to KMS unless - * explicitly disabled with the module pararmeter. - * - * Otherwise, just follow the parameter (defaulting to off). - * - * Allow optional vga_text_mode_force boot option to override - * the default behavior. - */ -#if defined(CONFIG_DRM_I915_KMS) - if (i915_modeset != 0) - driver.driver_features |= DRIVER_MODESET; -#endif - if (i915_modeset == 1) - driver.driver_features |= DRIVER_MODESET; - -#ifdef CONFIG_VGA_CONSOLE - if (vgacon_text_force() && i915_modeset == -1) - driver.driver_features &= ~DRIVER_MODESET; -#endif - - if (!(driver.driver_features & DRIVER_MODESET)) - driver.get_vblank_timestamp = NULL; - - return drm_pci_init(&driver, &i915_pci_driver); -} - -static void __exit i915_exit(void) -{ - drm_pci_exit(&driver, &i915_pci_driver); -} - -module_init(i915_init); -module_exit(i915_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); - -#define __i915_read(x, y) \ -u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ - u##x val = 0; \ - if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - unsigned long irqflags; \ - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ - if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_get(dev_priv); \ - val = read##y(dev_priv->regs + reg); \ - if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_put(dev_priv); \ - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ - } else { \ - val = read##y(dev_priv->regs + reg); \ - } \ - trace_i915_reg_rw(false, reg, val, sizeof(val)); \ - return val; \ -} - -__i915_read(8, b) -__i915_read(16, w) -__i915_read(32, l) -__i915_read(64, q) -#undef __i915_read - -#define __i915_write(x, y) \ -void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ - u32 __fifo_ret = 0; \ - trace_i915_reg_rw(true, reg, val, sizeof(val)); \ - if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ - } \ - write##y(val, dev_priv->regs + reg); \ - if (unlikely(__fifo_ret)) { \ - gen6_gt_check_fifodbg(dev_priv); \ - } \ -} -__i915_write(8, b) -__i915_write(16, w) -__i915_write(32, l) -__i915_write(64, q) -#undef __i915_write diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.h deleted file mode 100644 index 5fabc6c3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_drv.h +++ /dev/null @@ -1,1497 +0,0 @@ -/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- - */ -/* - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef _I915_DRV_H_ -#define _I915_DRV_H_ - -#include "i915_reg.h" -#include "intel_bios.h" -#include "intel_ringbuffer.h" -#include -#include -#include -#include -#include - -/* General customization: - */ - -#define DRIVER_AUTHOR "Tungsten Graphics, Inc." - -#define DRIVER_NAME "i915" -#define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20080730" - -enum pipe { - PIPE_A = 0, - PIPE_B, - PIPE_C, - I915_MAX_PIPES -}; -#define pipe_name(p) ((p) + 'A') - -enum plane { - PLANE_A = 0, - PLANE_B, - PLANE_C, -}; -#define plane_name(p) ((p) + 'A') - -#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) - -#define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++) - -/* Interface history: - * - * 1.1: Original. - * 1.2: Add Power Management - * 1.3: Add vblank support - * 1.4: Fix cmdbuffer path, add heap destroy - * 1.5: Add vblank pipe configuration - * 1.6: - New ioctl for scheduling buffer swaps on vertical blank - * - Support vertical blank on secondary display pipe - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 6 -#define DRIVER_PATCHLEVEL 0 - -#define WATCH_COHERENCY 0 -#define WATCH_LISTS 0 - -#define I915_GEM_PHYS_CURSOR_0 1 -#define I915_GEM_PHYS_CURSOR_1 2 -#define I915_GEM_PHYS_OVERLAY_REGS 3 -#define I915_MAX_PHYS_OBJECT (I915_GEM_PHYS_OVERLAY_REGS) - -struct drm_i915_gem_phys_object { - int id; - struct page **page_list; - drm_dma_handle_t *handle; - struct drm_i915_gem_object *cur_obj; -}; - -struct mem_block { - struct mem_block *next; - struct mem_block *prev; - int start; - int size; - struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ -}; - -struct opregion_header; -struct opregion_acpi; -struct opregion_swsci; -struct opregion_asle; -struct drm_i915_private; - -struct intel_opregion { - struct opregion_header *header; - struct opregion_acpi *acpi; - struct opregion_swsci *swsci; - struct opregion_asle *asle; - void *vbt; - u32 __iomem *lid_state; -}; -#define OPREGION_SIZE (8*1024) - -struct intel_overlay; -struct intel_overlay_error_state; - -struct drm_i915_master_private { - drm_local_map_t *sarea; - struct _drm_i915_sarea *sarea_priv; -}; -#define I915_FENCE_REG_NONE -1 -#define I915_MAX_NUM_FENCES 16 -/* 16 fences + sign bit for FENCE_REG_NONE */ -#define I915_MAX_NUM_FENCE_BITS 5 - -struct drm_i915_fence_reg { - struct list_head lru_list; - struct drm_i915_gem_object *obj; - uint32_t setup_seqno; - int pin_count; -}; - -struct sdvo_device_mapping { - u8 initialized; - u8 dvo_port; - u8 slave_addr; - u8 dvo_wiring; - u8 i2c_pin; - u8 ddc_pin; -}; - -struct intel_display_error_state; - -struct drm_i915_error_state { - u32 eir; - u32 pgtbl_er; - u32 pipestat[I915_MAX_PIPES]; - u32 tail[I915_NUM_RINGS]; - u32 head[I915_NUM_RINGS]; - u32 ipeir[I915_NUM_RINGS]; - u32 ipehr[I915_NUM_RINGS]; - u32 instdone[I915_NUM_RINGS]; - u32 acthd[I915_NUM_RINGS]; - u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; - /* our own tracking of ring head and tail */ - u32 cpu_ring_head[I915_NUM_RINGS]; - u32 cpu_ring_tail[I915_NUM_RINGS]; - u32 error; /* gen6+ */ - u32 instpm[I915_NUM_RINGS]; - u32 instps[I915_NUM_RINGS]; - u32 instdone1; - u32 seqno[I915_NUM_RINGS]; - u64 bbaddr; - u32 fault_reg[I915_NUM_RINGS]; - u32 done_reg; - u32 faddr[I915_NUM_RINGS]; - u64 fence[I915_MAX_NUM_FENCES]; - struct timeval time; - struct drm_i915_error_ring { - struct drm_i915_error_object { - int page_count; - u32 gtt_offset; - u32 *pages[0]; - } *ringbuffer, *batchbuffer; - struct drm_i915_error_request { - long jiffies; - u32 seqno; - u32 tail; - } *requests; - int num_requests; - } ring[I915_NUM_RINGS]; - struct drm_i915_error_buffer { - u32 size; - u32 name; - u32 seqno; - u32 gtt_offset; - u32 read_domains; - u32 write_domain; - s32 fence_reg:I915_MAX_NUM_FENCE_BITS; - s32 pinned:2; - u32 tiling:2; - u32 dirty:1; - u32 purgeable:1; - s32 ring:4; - u32 cache_level:2; - } *active_bo, *pinned_bo; - u32 active_bo_count, pinned_bo_count; - struct intel_overlay_error_state *overlay; - struct intel_display_error_state *display; -}; - -struct drm_i915_display_funcs { - void (*dpms)(struct drm_crtc *crtc, int mode); - bool (*fbc_enabled)(struct drm_device *dev); - void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); - void (*disable_fbc)(struct drm_device *dev); - int (*get_display_clock_speed)(struct drm_device *dev); - int (*get_fifo_size)(struct drm_device *dev, int plane); - void (*update_wm)(struct drm_device *dev); - void (*update_sprite_wm)(struct drm_device *dev, int pipe, - uint32_t sprite_width, int pixel_size); - int (*crtc_mode_set)(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb); - void (*write_eld)(struct drm_connector *connector, - struct drm_crtc *crtc); - void (*fdi_link_train)(struct drm_crtc *crtc); - void (*init_clock_gating)(struct drm_device *dev); - void (*init_pch_clock_gating)(struct drm_device *dev); - int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj); - int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, - int x, int y); - void (*force_wake_get)(struct drm_i915_private *dev_priv); - void (*force_wake_put)(struct drm_i915_private *dev_priv); - /* clock updates for mode set */ - /* cursor updates */ - /* render clock increase/decrease */ - /* display clock increase/decrease */ - /* pll clock increase/decrease */ -}; - -struct intel_device_info { - u8 gen; - u8 is_mobile:1; - u8 is_i85x:1; - u8 is_i915g:1; - u8 is_i945gm:1; - u8 is_g33:1; - u8 need_gfx_hws:1; - u8 is_g4x:1; - u8 is_pineview:1; - u8 is_broadwater:1; - u8 is_crestline:1; - u8 is_ivybridge:1; - u8 has_fbc:1; - u8 has_pipe_cxsr:1; - u8 has_hotplug:1; - u8 cursor_needs_physical:1; - u8 has_overlay:1; - u8 overlay_needs_physical:1; - u8 supports_tv:1; - u8 has_bsd_ring:1; - u8 has_blt_ring:1; - u8 has_llc:1; -}; - -#define I915_PPGTT_PD_ENTRIES 512 -#define I915_PPGTT_PT_ENTRIES 1024 -struct i915_hw_ppgtt { - unsigned num_pd_entries; - struct page **pt_pages; - uint32_t pd_offset; - dma_addr_t *pt_dma_addr; - dma_addr_t scratch_page_dma_addr; -}; - -enum no_fbc_reason { - FBC_NO_OUTPUT, /* no outputs enabled to compress */ - FBC_STOLEN_TOO_SMALL, /* not enough space to hold compressed buffers */ - FBC_UNSUPPORTED_MODE, /* interlace or doublescanned mode */ - FBC_MODE_TOO_LARGE, /* mode too large for compression */ - FBC_BAD_PLANE, /* fbc not supported on plane */ - FBC_NOT_TILED, /* buffer not tiled */ - FBC_MULTIPLE_PIPES, /* more than one pipe active */ - FBC_MODULE_PARAM, -}; - -enum intel_pch { - PCH_IBX, /* Ibexpeak PCH */ - PCH_CPT, /* Cougarpoint PCH */ -}; - -#define QUIRK_PIPEA_FORCE (1<<0) -#define QUIRK_LVDS_SSC_DISABLE (1<<1) - -struct intel_fbdev; -struct intel_fbc_work; - -struct intel_gmbus { - struct i2c_adapter adapter; - bool force_bit; - bool has_gpio; - u32 reg0; - u32 gpio_reg; - struct i2c_algo_bit_data bit_algo; - struct drm_i915_private *dev_priv; -}; - -typedef struct drm_i915_private { - struct drm_device *dev; - - const struct intel_device_info *info; - - int has_gem; - int relative_constants_mode; - - void __iomem *regs; - /** gt_fifo_count and the subsequent register write are synchronized - * with dev->struct_mutex. */ - unsigned gt_fifo_count; - /** forcewake_count is protected by gt_lock */ - unsigned forcewake_count; - /** gt_lock is also taken in irq contexts. */ - struct spinlock gt_lock; - - struct intel_gmbus *gmbus; - - /** gmbus_mutex protects against concurrent usage of the single hw gmbus - * controller on different i2c buses. */ - struct mutex gmbus_mutex; - - struct pci_dev *bridge_dev; - struct intel_ring_buffer ring[I915_NUM_RINGS]; - uint32_t next_seqno; - - drm_dma_handle_t *status_page_dmah; - uint32_t counter; - drm_local_map_t hws_map; - struct drm_i915_gem_object *pwrctx; - struct drm_i915_gem_object *renderctx; - - struct resource mch_res; - - unsigned int cpp; - int back_offset; - int front_offset; - int current_page; - int page_flipping; - - atomic_t irq_received; - - /* protects the irq masks */ - spinlock_t irq_lock; - /** Cached value of IMR to avoid reads in updating the bitfield */ - u32 pipestat[2]; - u32 irq_mask; - u32 gt_irq_mask; - u32 pch_irq_mask; - - u32 hotplug_supported_mask; - struct work_struct hotplug_work; - - int tex_lru_log_granularity; - int allow_batchbuffer; - unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; - int vblank_pipe; - int num_pipe; - - /* For hangcheck timer */ -#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ - struct timer_list hangcheck_timer; - int hangcheck_count; - uint32_t last_acthd; - uint32_t last_acthd_bsd; - uint32_t last_acthd_blt; - uint32_t last_instdone; - uint32_t last_instdone1; - - unsigned long cfb_size; - unsigned int cfb_fb; - enum plane cfb_plane; - int cfb_y; - struct intel_fbc_work *fbc_work; - - struct intel_opregion opregion; - - /* overlay */ - struct intel_overlay *overlay; - bool sprite_scaling_enabled; - - /* LVDS info */ - int backlight_level; /* restore backlight to this value */ - bool backlight_enabled; - struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ - struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ - - /* Feature bits from the VBIOS */ - unsigned int int_tv_support:1; - unsigned int lvds_dither:1; - unsigned int lvds_vbt:1; - unsigned int int_crt_support:1; - unsigned int lvds_use_ssc:1; - unsigned int display_clock_mode:1; - int lvds_ssc_freq; - struct { - int rate; - int lanes; - int preemphasis; - int vswing; - - bool initialized; - bool support; - int bpp; - struct edp_power_seq pps; - } edp; - bool no_aux_handshake; - - struct notifier_block lid_notifier; - - int crt_ddc_pin; - struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ - int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ - int num_fence_regs; /* 8 on pre-965, 16 otherwise */ - - unsigned int fsb_freq, mem_freq, is_ddr3; - - spinlock_t error_lock; - struct drm_i915_error_state *first_error; - struct work_struct error_work; - struct completion error_completion; - struct workqueue_struct *wq; - - /* Display functions */ - struct drm_i915_display_funcs display; - - /* PCH chipset type */ - enum intel_pch pch_type; - - unsigned long quirks; - - /* Register state */ - bool modeset_on_lid; - u8 saveLBB; - u32 saveDSPACNTR; - u32 saveDSPBCNTR; - u32 saveDSPARB; - u32 saveHWS; - u32 savePIPEACONF; - u32 savePIPEBCONF; - u32 savePIPEASRC; - u32 savePIPEBSRC; - u32 saveFPA0; - u32 saveFPA1; - u32 saveDPLL_A; - u32 saveDPLL_A_MD; - u32 saveHTOTAL_A; - u32 saveHBLANK_A; - u32 saveHSYNC_A; - u32 saveVTOTAL_A; - u32 saveVBLANK_A; - u32 saveVSYNC_A; - u32 saveBCLRPAT_A; - u32 saveTRANSACONF; - u32 saveTRANS_HTOTAL_A; - u32 saveTRANS_HBLANK_A; - u32 saveTRANS_HSYNC_A; - u32 saveTRANS_VTOTAL_A; - u32 saveTRANS_VBLANK_A; - u32 saveTRANS_VSYNC_A; - u32 savePIPEASTAT; - u32 saveDSPASTRIDE; - u32 saveDSPASIZE; - u32 saveDSPAPOS; - u32 saveDSPAADDR; - u32 saveDSPASURF; - u32 saveDSPATILEOFF; - u32 savePFIT_PGM_RATIOS; - u32 saveBLC_HIST_CTL; - u32 saveBLC_PWM_CTL; - u32 saveBLC_PWM_CTL2; - u32 saveBLC_CPU_PWM_CTL; - u32 saveBLC_CPU_PWM_CTL2; - u32 saveFPB0; - u32 saveFPB1; - u32 saveDPLL_B; - u32 saveDPLL_B_MD; - u32 saveHTOTAL_B; - u32 saveHBLANK_B; - u32 saveHSYNC_B; - u32 saveVTOTAL_B; - u32 saveVBLANK_B; - u32 saveVSYNC_B; - u32 saveBCLRPAT_B; - u32 saveTRANSBCONF; - u32 saveTRANS_HTOTAL_B; - u32 saveTRANS_HBLANK_B; - u32 saveTRANS_HSYNC_B; - u32 saveTRANS_VTOTAL_B; - u32 saveTRANS_VBLANK_B; - u32 saveTRANS_VSYNC_B; - u32 savePIPEBSTAT; - u32 saveDSPBSTRIDE; - u32 saveDSPBSIZE; - u32 saveDSPBPOS; - u32 saveDSPBADDR; - u32 saveDSPBSURF; - u32 saveDSPBTILEOFF; - u32 saveVGA0; - u32 saveVGA1; - u32 saveVGA_PD; - u32 saveVGACNTRL; - u32 saveADPA; - u32 saveLVDS; - u32 savePP_ON_DELAYS; - u32 savePP_OFF_DELAYS; - u32 saveDVOA; - u32 saveDVOB; - u32 saveDVOC; - u32 savePP_ON; - u32 savePP_OFF; - u32 savePP_CONTROL; - u32 savePP_DIVISOR; - u32 savePFIT_CONTROL; - u32 save_palette_a[256]; - u32 save_palette_b[256]; - u32 saveDPFC_CB_BASE; - u32 saveFBC_CFB_BASE; - u32 saveFBC_LL_BASE; - u32 saveFBC_CONTROL; - u32 saveFBC_CONTROL2; - u32 saveIER; - u32 saveIIR; - u32 saveIMR; - u32 saveDEIER; - u32 saveDEIMR; - u32 saveGTIER; - u32 saveGTIMR; - u32 saveFDI_RXA_IMR; - u32 saveFDI_RXB_IMR; - u32 saveCACHE_MODE_0; - u32 saveMI_ARB_STATE; - u32 saveSWF0[16]; - u32 saveSWF1[16]; - u32 saveSWF2[3]; - u8 saveMSR; - u8 saveSR[8]; - u8 saveGR[25]; - u8 saveAR_INDEX; - u8 saveAR[21]; - u8 saveDACMASK; - u8 saveCR[37]; - uint64_t saveFENCE[I915_MAX_NUM_FENCES]; - u32 saveCURACNTR; - u32 saveCURAPOS; - u32 saveCURABASE; - u32 saveCURBCNTR; - u32 saveCURBPOS; - u32 saveCURBBASE; - u32 saveCURSIZE; - u32 saveDP_B; - u32 saveDP_C; - u32 saveDP_D; - u32 savePIPEA_GMCH_DATA_M; - u32 savePIPEB_GMCH_DATA_M; - u32 savePIPEA_GMCH_DATA_N; - u32 savePIPEB_GMCH_DATA_N; - u32 savePIPEA_DP_LINK_M; - u32 savePIPEB_DP_LINK_M; - u32 savePIPEA_DP_LINK_N; - u32 savePIPEB_DP_LINK_N; - u32 saveFDI_RXA_CTL; - u32 saveFDI_TXA_CTL; - u32 saveFDI_RXB_CTL; - u32 saveFDI_TXB_CTL; - u32 savePFA_CTL_1; - u32 savePFB_CTL_1; - u32 savePFA_WIN_SZ; - u32 savePFB_WIN_SZ; - u32 savePFA_WIN_POS; - u32 savePFB_WIN_POS; - u32 savePCH_DREF_CONTROL; - u32 saveDISP_ARB_CTL; - u32 savePIPEA_DATA_M1; - u32 savePIPEA_DATA_N1; - u32 savePIPEA_LINK_M1; - u32 savePIPEA_LINK_N1; - u32 savePIPEB_DATA_M1; - u32 savePIPEB_DATA_N1; - u32 savePIPEB_LINK_M1; - u32 savePIPEB_LINK_N1; - u32 saveMCHBAR_RENDER_STANDBY; - u32 savePCH_PORT_HOTPLUG; - - struct { - /** Bridge to intel-gtt-ko */ - const struct intel_gtt *gtt; - /** Memory allocator for GTT stolen memory */ - struct drm_mm stolen; - /** Memory allocator for GTT */ - struct drm_mm gtt_space; - /** List of all objects in gtt_space. Used to restore gtt - * mappings on resume */ - struct list_head gtt_list; - - /** Usable portion of the GTT for GEM */ - unsigned long gtt_start; - unsigned long gtt_mappable_end; - unsigned long gtt_end; - - struct io_mapping *gtt_mapping; - int gtt_mtrr; - - /** PPGTT used for aliasing the PPGTT with the GTT */ - struct i915_hw_ppgtt *aliasing_ppgtt; - - struct shrinker inactive_shrinker; - - /** - * List of objects currently involved in rendering. - * - * Includes buffers having the contents of their GPU caches - * flushed, not necessarily primitives. last_rendering_seqno - * represents when the rendering involved will be completed. - * - * A reference is held on the buffer while on this list. - */ - struct list_head active_list; - - /** - * List of objects which are not in the ringbuffer but which - * still have a write_domain which needs to be flushed before - * unbinding. - * - * last_rendering_seqno is 0 while an object is in this list. - * - * A reference is held on the buffer while on this list. - */ - struct list_head flushing_list; - - /** - * LRU list of objects which are not in the ringbuffer and - * are ready to unbind, but are still in the GTT. - * - * last_rendering_seqno is 0 while an object is in this list. - * - * A reference is not held on the buffer while on this list, - * as merely being GTT-bound shouldn't prevent its being - * freed, and we'll pull it off the list in the free path. - */ - struct list_head inactive_list; - - /** - * LRU list of objects which are not in the ringbuffer but - * are still pinned in the GTT. - */ - struct list_head pinned_list; - - /** LRU list of objects with fence regs on them. */ - struct list_head fence_list; - - /** - * List of objects currently pending being freed. - * - * These objects are no longer in use, but due to a signal - * we were prevented from freeing them at the appointed time. - */ - struct list_head deferred_free_list; - - /** - * We leave the user IRQ off as much as possible, - * but this means that requests will finish and never - * be retired once the system goes idle. Set a timer to - * fire periodically while the ring is running. When it - * fires, go retire requests. - */ - struct delayed_work retire_work; - - /** - * Are we in a non-interruptible section of code like - * modesetting? - */ - bool interruptible; - - /** - * Flag if the X Server, and thus DRM, is not currently in - * control of the device. - * - * This is set between LeaveVT and EnterVT. It needs to be - * replaced with a semaphore. It also needs to be - * transitioned away from for kernel modesetting. - */ - int suspended; - - /** - * Flag if the hardware appears to be wedged. - * - * This is set when attempts to idle the device timeout. - * It prevents command submission from occurring and makes - * every pending request fail - */ - atomic_t wedged; - - /** Bit 6 swizzling required for X tiling */ - uint32_t bit_6_swizzle_x; - /** Bit 6 swizzling required for Y tiling */ - uint32_t bit_6_swizzle_y; - - /* storage for physical objects */ - struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; - - /* accounting, useful for userland debugging */ - size_t gtt_total; - size_t mappable_gtt_total; - size_t object_memory; - u32 object_count; - } mm; - struct sdvo_device_mapping sdvo_mappings[2]; - /* indicate whether the LVDS_BORDER should be enabled or not */ - unsigned int lvds_border_bits; - /* Panel fitter placement and size for Ironlake+ */ - u32 pch_pf_pos, pch_pf_size; - - struct drm_crtc *plane_to_crtc_mapping[3]; - struct drm_crtc *pipe_to_crtc_mapping[3]; - wait_queue_head_t pending_flip_queue; - bool flip_pending_is_done; - - /* Reclocking support */ - bool render_reclock_avail; - bool lvds_downclock_avail; - /* indicates the reduced downclock for LVDS*/ - int lvds_downclock; - struct work_struct idle_work; - struct timer_list idle_timer; - bool busy; - u16 orig_clock; - int child_dev_num; - struct child_device_config *child_dev; - struct drm_connector *int_lvds_connector; - struct drm_connector *int_edp_connector; - - bool mchbar_need_disable; - - struct work_struct rps_work; - spinlock_t rps_lock; - u32 pm_iir; - - u8 cur_delay; - u8 min_delay; - u8 max_delay; - u8 fmax; - u8 fstart; - - u64 last_count1; - unsigned long last_time1; - unsigned long chipset_power; - u64 last_count2; - struct timespec last_time2; - unsigned long gfx_power; - int c_m; - int r_t; - u8 corr; - spinlock_t *mchdev_lock; - - enum no_fbc_reason no_fbc_reason; - - struct drm_mm_node *compressed_fb; - struct drm_mm_node *compressed_llb; - - unsigned long last_gpu_reset; - - /* list of fbdev register on this device */ - struct intel_fbdev *fbdev; - - struct backlight_device *backlight; - - struct drm_property *broadcast_rgb_property; - struct drm_property *force_audio_property; -} drm_i915_private_t; - -enum hdmi_force_audio { - HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ - HDMI_AUDIO_OFF, /* force turn off HDMI audio */ - HDMI_AUDIO_AUTO, /* trust EDID */ - HDMI_AUDIO_ON, /* force turn on HDMI audio */ -}; - -enum i915_cache_level { - I915_CACHE_NONE, - I915_CACHE_LLC, - I915_CACHE_LLC_MLC, /* gen6+ */ -}; - -struct drm_i915_gem_object { - struct drm_gem_object base; - - /** Current space allocated to this object in the GTT, if any. */ - struct drm_mm_node *gtt_space; - struct list_head gtt_list; - - /** This object's place on the active/flushing/inactive lists */ - struct list_head ring_list; - struct list_head mm_list; - /** This object's place on GPU write list */ - struct list_head gpu_write_list; - /** This object's place in the batchbuffer or on the eviction list */ - struct list_head exec_list; - - /** - * This is set if the object is on the active or flushing lists - * (has pending rendering), and is not set if it's on inactive (ready - * to be unbound). - */ - unsigned int active:1; - - /** - * This is set if the object has been written to since last bound - * to the GTT - */ - unsigned int dirty:1; - - /** - * This is set if the object has been written to since the last - * GPU flush. - */ - unsigned int pending_gpu_write:1; - - /** - * Fence register bits (if any) for this object. Will be set - * as needed when mapped into the GTT. - * Protected by dev->struct_mutex. - */ - signed int fence_reg:I915_MAX_NUM_FENCE_BITS; - - /** - * Advice: are the backing pages purgeable? - */ - unsigned int madv:2; - - /** - * Current tiling mode for the object. - */ - unsigned int tiling_mode:2; - unsigned int tiling_changed:1; - - /** How many users have pinned this object in GTT space. The following - * users can each hold at most one reference: pwrite/pread, pin_ioctl - * (via user_pin_count), execbuffer (objects are not allowed multiple - * times for the same batchbuffer), and the framebuffer code. When - * switching/pageflipping, the framebuffer code has at most two buffers - * pinned per crtc. - * - * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 - * bits with absolutely no headroom. So use 4 bits. */ - unsigned int pin_count:4; -#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf - - /** - * Is the object at the current location in the gtt mappable and - * fenceable? Used to avoid costly recalculations. - */ - unsigned int map_and_fenceable:1; - - /** - * Whether the current gtt mapping needs to be mappable (and isn't just - * mappable by accident). Track pin and fault separate for a more - * accurate mappable working set. - */ - unsigned int fault_mappable:1; - unsigned int pin_mappable:1; - - /* - * Is the GPU currently using a fence to access this buffer, - */ - unsigned int pending_fenced_gpu_access:1; - unsigned int fenced_gpu_access:1; - - unsigned int cache_level:2; - - unsigned int has_aliasing_ppgtt_mapping:1; - - struct page **pages; - - /** - * DMAR support - */ - struct scatterlist *sg_list; - int num_sg; - - /** - * Used for performing relocations during execbuffer insertion. - */ - struct hlist_node exec_node; - unsigned long exec_handle; - struct drm_i915_gem_exec_object2 *exec_entry; - - /** - * Current offset of the object in GTT space. - * - * This is the same as gtt_space->start - */ - uint32_t gtt_offset; - - /** Breadcrumb of last rendering to the buffer. */ - uint32_t last_rendering_seqno; - struct intel_ring_buffer *ring; - - /** Breadcrumb of last fenced GPU access to the buffer. */ - uint32_t last_fenced_seqno; - struct intel_ring_buffer *last_fenced_ring; - - /** Current tiling stride for the object, if it's tiled. */ - uint32_t stride; - - /** Record of address bit 17 of each page at last unbind. */ - unsigned long *bit_17; - - - /** - * If present, while GEM_DOMAIN_CPU is in the read domain this array - * flags which individual pages are valid. - */ - uint8_t *page_cpu_valid; - - /** User space pin count and filp owning the pin */ - uint32_t user_pin_count; - struct drm_file *pin_filp; - - /** for phy allocated objects */ - struct drm_i915_gem_phys_object *phys_obj; - - /** - * Number of crtcs where this object is currently the fb, but - * will be page flipped away on the next vblank. When it - * reaches 0, dev_priv->pending_flip_queue will be woken up. - */ - atomic_t pending_flip; -}; - -#define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) - -/** - * Request queue structure. - * - * The request queue allows us to note sequence numbers that have been emitted - * and may be associated with active buffers to be retired. - * - * By keeping this list, we can avoid having to do questionable - * sequence-number comparisons on buffer last_rendering_seqnos, and associate - * an emission time with seqnos for tracking how far ahead of the GPU we are. - */ -struct drm_i915_gem_request { - /** On Which ring this request was generated */ - struct intel_ring_buffer *ring; - - /** GEM sequence number associated with this request. */ - uint32_t seqno; - - /** Postion in the ringbuffer of the end of the request */ - u32 tail; - - /** Time at which this request was emitted, in jiffies. */ - unsigned long emitted_jiffies; - - /** global list entry for this request */ - struct list_head list; - - struct drm_i915_file_private *file_priv; - /** file_priv list entry for this request */ - struct list_head client_list; -}; - -struct drm_i915_file_private { - struct { - struct spinlock lock; - struct list_head request_list; - } mm; -}; - -#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) - -#define IS_I830(dev) ((dev)->pci_device == 0x3577) -#define IS_845G(dev) ((dev)->pci_device == 0x2562) -#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) -#define IS_I865G(dev) ((dev)->pci_device == 0x2572) -#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) -#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) -#define IS_I945G(dev) ((dev)->pci_device == 0x2772) -#define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) -#define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) -#define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) -#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) -#define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) -#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) -#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) -#define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) -#define IS_G33(dev) (INTEL_INFO(dev)->is_g33) -#define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) -#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) -#define IS_IVYBRIDGE(dev) (INTEL_INFO(dev)->is_ivybridge) -#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) - -/* - * The genX designation typically refers to the render engine, so render - * capability related checks should use IS_GEN, while display and other checks - * have their own (e.g. HAS_PCH_SPLIT for ILK+ display, IS_foo for particular - * chips, etc.). - */ -#define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) -#define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) -#define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) -#define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) -#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) -#define IS_GEN7(dev) (INTEL_INFO(dev)->gen == 7) - -#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) -#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) -#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) -#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) - -#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6) - -#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) -#define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) - -/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte - * rows, which changed the alignment requirements and fence programming. - */ -#define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \ - IS_I915GM(dev))) -#define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) -#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev)) -#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_GEN5(dev)) -#define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) -#define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) -#define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) -/* dsparb controlled by hw only */ -#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) - -#define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) -#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) -#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) - -#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) -#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) - -#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) -#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) -#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) - -#include "i915_trace.h" - -/** - * RC6 is a special power stage which allows the GPU to enter an very - * low-voltage mode when idle, using down to 0V while at this stage. This - * stage is entered automatically when the GPU is idle when RC6 support is - * enabled, and as soon as new workload arises GPU wakes up automatically as well. - * - * There are different RC6 modes available in Intel GPU, which differentiate - * among each other with the latency required to enter and leave RC6 and - * voltage consumed by the GPU in different states. - * - * The combination of the following flags define which states GPU is allowed - * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and - * RC6pp is deepest RC6. Their support by hardware varies according to the - * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one - * which brings the most power savings; deeper states save more power, but - * require higher latency to switch to and wake up. - */ -#define INTEL_RC6_ENABLE (1<<0) -#define INTEL_RC6p_ENABLE (1<<1) -#define INTEL_RC6pp_ENABLE (1<<2) - -extern struct drm_ioctl_desc i915_ioctls[]; -extern int i915_max_ioctl; -extern unsigned int i915_fbpercrtc __always_unused; -extern int i915_panel_ignore_lid __read_mostly; -extern unsigned int i915_powersave __read_mostly; -extern int i915_semaphores __read_mostly; -extern unsigned int i915_lvds_downclock __read_mostly; -extern int i915_panel_use_ssc __read_mostly; -extern int i915_vbt_sdvo_panel_type __read_mostly; -extern int i915_enable_rc6 __read_mostly; -extern int i915_enable_fbc __read_mostly; -extern bool i915_enable_hangcheck __read_mostly; -extern int i915_enable_ppgtt __read_mostly; - -extern int i915_suspend(struct drm_device *dev, pm_message_t state); -extern int i915_resume(struct drm_device *dev); -extern int i915_master_create(struct drm_device *dev, struct drm_master *master); -extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); - - /* i915_dma.c */ -extern void i915_kernel_lost_context(struct drm_device * dev); -extern int i915_driver_load(struct drm_device *, unsigned long flags); -extern int i915_driver_unload(struct drm_device *); -extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv); -extern void i915_driver_lastclose(struct drm_device * dev); -extern void i915_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv); -extern void i915_driver_postclose(struct drm_device *dev, - struct drm_file *file_priv); -extern int i915_driver_device_is_agp(struct drm_device * dev); -extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); -extern int i915_emit_box(struct drm_device *dev, - struct drm_clip_rect *box, - int DR1, int DR4); -extern int i915_reset(struct drm_device *dev, u8 flags); -extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); -extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); -extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); -extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); - - -/* i915_irq.c */ -void i915_hangcheck_elapsed(unsigned long data); -void i915_handle_error(struct drm_device *dev, bool wedged); -extern int i915_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern void intel_irq_init(struct drm_device *dev); - -extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_vblank_swap(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -void -i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); - -void -i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); - -void intel_enable_asle(struct drm_device *dev); - -#ifdef CONFIG_DEBUG_FS -extern void i915_destroy_error_state(struct drm_device *dev); -#else -#define i915_destroy_error_state(x) -#endif - - -/* i915_gem.c */ -int i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_execbuffer2(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_madvise_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_set_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_get_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -void i915_gem_load(struct drm_device *dev); -int i915_gem_init_object(struct drm_gem_object *obj); -int __must_check i915_gem_flush_ring(struct intel_ring_buffer *ring, - uint32_t invalidate_domains, - uint32_t flush_domains); -struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, - size_t size); -void i915_gem_free_object(struct drm_gem_object *obj); -int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, - uint32_t alignment, - bool map_and_fenceable); -void i915_gem_object_unpin(struct drm_i915_gem_object *obj); -int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); -void i915_gem_release_mmap(struct drm_i915_gem_object *obj); -void i915_gem_lastclose(struct drm_device *dev); - -int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); -int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj); -void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring, - u32 seqno); - -int i915_gem_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); -int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle, uint64_t *offset); -int i915_gem_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle); -/** - * Returns true if seq1 is later than seq2. - */ -static inline bool -i915_seqno_passed(uint32_t seq1, uint32_t seq2) -{ - return (int32_t)(seq1 - seq2) >= 0; -} - -u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring); - -int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined); -int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); - -static inline void -i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) -{ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - dev_priv->fence_regs[obj->fence_reg].pin_count++; - } -} - -static inline void -i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) -{ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - dev_priv->fence_regs[obj->fence_reg].pin_count--; - } -} - -void i915_gem_retire_requests(struct drm_device *dev); -void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); - -void i915_gem_reset(struct drm_device *dev); -void i915_gem_clflush_object(struct drm_i915_gem_object *obj); -int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain); -int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); -int __must_check i915_gem_init_hw(struct drm_device *dev); -void i915_gem_init_swizzling(struct drm_device *dev); -void i915_gem_init_ppgtt(struct drm_device *dev); -void i915_gem_cleanup_ringbuffer(struct drm_device *dev); -void i915_gem_do_init(struct drm_device *dev, - unsigned long start, - unsigned long mappable_end, - unsigned long end); -int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire); -int __must_check i915_gem_idle(struct drm_device *dev); -int __must_check i915_add_request(struct intel_ring_buffer *ring, - struct drm_file *file, - struct drm_i915_gem_request *request); -int __must_check i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno, - bool do_retire); -int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); -int __must_check -i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, - bool write); -int __must_check -i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, - u32 alignment, - struct intel_ring_buffer *pipelined); -int i915_gem_attach_phys_object(struct drm_device *dev, - struct drm_i915_gem_object *obj, - int id, - int align); -void i915_gem_detach_phys_object(struct drm_device *dev, - struct drm_i915_gem_object *obj); -void i915_gem_free_all_phys_object(struct drm_device *dev); -void i915_gem_release(struct drm_device *dev, struct drm_file *file); - -uint32_t -i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, - uint32_t size, - int tiling_mode); - -int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level); - -/* i915_gem_gtt.c */ -int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); -void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); -void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, - struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level); -void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, - struct drm_i915_gem_object *obj); - -void i915_gem_restore_gtt_mappings(struct drm_device *dev); -int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); -void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level); -void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj); - -/* i915_gem_evict.c */ -int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size, - unsigned alignment, bool mappable); -int __must_check i915_gem_evict_everything(struct drm_device *dev, - bool purgeable_only); -int __must_check i915_gem_evict_inactive(struct drm_device *dev, - bool purgeable_only); - -/* i915_gem_tiling.c */ -void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); -void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); -void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); - -/* i915_gem_debug.c */ -void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, - const char *where, uint32_t mark); -#if WATCH_LISTS -int i915_verify_lists(struct drm_device *dev); -#else -#define i915_verify_lists(dev) 0 -#endif -void i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, - int handle); -void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, - const char *where, uint32_t mark); - -/* i915_debugfs.c */ -int i915_debugfs_init(struct drm_minor *minor); -void i915_debugfs_cleanup(struct drm_minor *minor); - -/* i915_suspend.c */ -extern int i915_save_state(struct drm_device *dev); -extern int i915_restore_state(struct drm_device *dev); - -/* i915_suspend.c */ -extern int i915_save_state(struct drm_device *dev); -extern int i915_restore_state(struct drm_device *dev); - -/* intel_i2c.c */ -extern int intel_setup_gmbus(struct drm_device *dev); -extern void intel_teardown_gmbus(struct drm_device *dev); -extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); -extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); -extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) -{ - return container_of(adapter, struct intel_gmbus, adapter)->force_bit; -} -extern void intel_i2c_reset(struct drm_device *dev); - -/* intel_opregion.c */ -extern int intel_opregion_setup(struct drm_device *dev); -#ifdef CONFIG_ACPI -extern void intel_opregion_init(struct drm_device *dev); -extern void intel_opregion_fini(struct drm_device *dev); -extern void intel_opregion_asle_intr(struct drm_device *dev); -extern void intel_opregion_gse_intr(struct drm_device *dev); -extern void intel_opregion_enable_asle(struct drm_device *dev); -#else -static inline void intel_opregion_init(struct drm_device *dev) { return; } -static inline void intel_opregion_fini(struct drm_device *dev) { return; } -static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; } -static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; } -static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; } -#endif - -/* intel_acpi.c */ -#ifdef CONFIG_ACPI -extern void intel_register_dsm_handler(void); -extern void intel_unregister_dsm_handler(void); -#else -static inline void intel_register_dsm_handler(void) { return; } -static inline void intel_unregister_dsm_handler(void) { return; } -#endif /* CONFIG_ACPI */ - -/* modesetting */ -extern void intel_modeset_init(struct drm_device *dev); -extern void intel_modeset_gem_init(struct drm_device *dev); -extern void intel_modeset_cleanup(struct drm_device *dev); -extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); -extern bool intel_fbc_enabled(struct drm_device *dev); -extern void intel_disable_fbc(struct drm_device *dev); -extern bool ironlake_set_drps(struct drm_device *dev, u8 val); -extern void ironlake_init_pch_refclk(struct drm_device *dev); -extern void ironlake_enable_rc6(struct drm_device *dev); -extern void gen6_set_rps(struct drm_device *dev, u8 val); -extern void intel_detect_pch(struct drm_device *dev); -extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); - -extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); -extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); - -/* overlay */ -#ifdef CONFIG_DEBUG_FS -extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); -extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); - -extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev); -extern void intel_display_print_error_state(struct seq_file *m, - struct drm_device *dev, - struct intel_display_error_state *error); -#endif - -#define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS]) - -#define BEGIN_LP_RING(n) \ - intel_ring_begin(LP_RING(dev_priv), (n)) - -#define OUT_RING(x) \ - intel_ring_emit(LP_RING(dev_priv), x) - -#define ADVANCE_LP_RING() \ - intel_ring_advance(LP_RING(dev_priv)) - -/** - * Lock test for when it's just for synchronization of ring access. - * - * In that case, we don't need to do it when GEM is initialized as nobody else - * has access to the ring. - */ -#define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ - if (LP_RING(dev->dev_private)->obj == NULL) \ - LOCK_TEST_WITH_RETURN(dev, file); \ -} while (0) - -/* On SNB platform, before reading ring registers forcewake bit - * must be set to prevent GT core from power down and stale values being - * returned. - */ -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); -int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); - -/* We give fast paths for the really cool registers */ -#define NEEDS_FORCE_WAKE(dev_priv, reg) \ - (((dev_priv)->info->gen >= 6) && \ - ((reg) < 0x40000) && \ - ((reg) != FORCEWAKE)) - -#define __i915_read(x, y) \ - u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); - -__i915_read(8, b) -__i915_read(16, w) -__i915_read(32, l) -__i915_read(64, q) -#undef __i915_read - -#define __i915_write(x, y) \ - void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val); - -__i915_write(8, b) -__i915_write(16, w) -__i915_write(32, l) -__i915_write(64, q) -#undef __i915_write - -#define I915_READ8(reg) i915_read8(dev_priv, (reg)) -#define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val)) - -#define I915_READ16(reg) i915_read16(dev_priv, (reg)) -#define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val)) -#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) -#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) - -#define I915_READ(reg) i915_read32(dev_priv, (reg)) -#define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val)) -#define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) -#define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) - -#define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val)) -#define I915_READ64(reg) i915_read64(dev_priv, (reg)) - -#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) -#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) - - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem.c deleted file mode 100644 index 0d1e4b7b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem.c +++ /dev/null @@ -1,4276 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_trace.h" -#include "intel_drv.h" -#include -#include -#include -#include - -static __must_check int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj); -static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); -static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); -static __must_check int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, - bool write); -static __must_check int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, - uint64_t offset, - uint64_t size); -static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj); -static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, - unsigned alignment, - bool map_and_fenceable); -static void i915_gem_clear_fence_reg(struct drm_device *dev, - struct drm_i915_fence_reg *reg); -static int i915_gem_phys_pwrite(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file); -static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); - -static int i915_gem_inactive_shrink(struct shrinker *shrinker, - struct shrink_control *sc); -static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); - -/* some bookkeeping */ -static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, - size_t size) -{ - dev_priv->mm.object_count++; - dev_priv->mm.object_memory += size; -} - -static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, - size_t size) -{ - dev_priv->mm.object_count--; - dev_priv->mm.object_memory -= size; -} - -static int -i915_gem_wait_for_error(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct completion *x = &dev_priv->error_completion; - unsigned long flags; - int ret; - - if (!atomic_read(&dev_priv->mm.wedged)) - return 0; - - ret = wait_for_completion_interruptible(x); - if (ret) - return ret; - - if (atomic_read(&dev_priv->mm.wedged)) { - /* GPU is hung, bump the completion count to account for - * the token we just consumed so that we never hit zero and - * end up waiting upon a subsequent completion event that - * will never happen. - */ - spin_lock_irqsave(&x->wait.lock, flags); - x->done++; - spin_unlock_irqrestore(&x->wait.lock, flags); - } - return 0; -} - -int i915_mutex_lock_interruptible(struct drm_device *dev) -{ - int ret; - - ret = i915_gem_wait_for_error(dev); - if (ret) - return ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - WARN_ON(i915_verify_lists(dev)); - return 0; -} - -static inline bool -i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) -{ - return obj->gtt_space && !obj->active && obj->pin_count == 0; -} - -void i915_gem_do_init(struct drm_device *dev, - unsigned long start, - unsigned long mappable_end, - unsigned long end) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - drm_mm_init(&dev_priv->mm.gtt_space, start, end - start); - - dev_priv->mm.gtt_start = start; - dev_priv->mm.gtt_mappable_end = mappable_end; - dev_priv->mm.gtt_end = end; - dev_priv->mm.gtt_total = end - start; - dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start; - - /* Take over this portion of the GTT */ - intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE); -} - -int -i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_init *args = data; - - if (args->gtt_start >= args->gtt_end || - (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) - return -EINVAL; - - mutex_lock(&dev->struct_mutex); - i915_gem_do_init(dev, args->gtt_start, args->gtt_end, args->gtt_end); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -int -i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_get_aperture *args = data; - struct drm_i915_gem_object *obj; - size_t pinned; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - pinned = 0; - mutex_lock(&dev->struct_mutex); - list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) - pinned += obj->gtt_space->size; - mutex_unlock(&dev->struct_mutex); - - args->aper_size = dev_priv->mm.gtt_total; - args->aper_available_size = args->aper_size - pinned; - - return 0; -} - -static int -i915_gem_create(struct drm_file *file, - struct drm_device *dev, - uint64_t size, - uint32_t *handle_p) -{ - struct drm_i915_gem_object *obj; - int ret; - u32 handle; - - size = roundup(size, PAGE_SIZE); - if (size == 0) - return -EINVAL; - - /* Allocate the new object */ - obj = i915_gem_alloc_object(dev, size); - if (obj == NULL) - return -ENOMEM; - - ret = drm_gem_handle_create(file, &obj->base, &handle); - if (ret) { - drm_gem_object_release(&obj->base); - i915_gem_info_remove_obj(dev->dev_private, obj->base.size); - kfree(obj); - return ret; - } - - /* drop reference from allocate - handle holds it now */ - drm_gem_object_unreference(&obj->base); - trace_i915_gem_object_create(obj); - - *handle_p = handle; - return 0; -} - -int -i915_gem_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - /* have to work out size/pitch and return them */ - args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64); - args->size = args->pitch * args->height; - return i915_gem_create(file, dev, - args->size, &args->handle); -} - -int i915_gem_dumb_destroy(struct drm_file *file, - struct drm_device *dev, - uint32_t handle) -{ - return drm_gem_handle_delete(file, handle); -} - -/** - * Creates a new mm object and returns a handle to it. - */ -int -i915_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_create *args = data; - return i915_gem_create(file, dev, - args->size, &args->handle); -} - -static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) -{ - drm_i915_private_t *dev_priv = obj->base.dev->dev_private; - - return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && - obj->tiling_mode != I915_TILING_NONE; -} - -/** - * This is the fast shmem pread path, which attempts to copy_from_user directly - * from the backing pages of the object to the user's address space. On a - * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow(). - */ -static int -i915_gem_shmem_pread_fast(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pread *args, - struct drm_file *file) -{ - struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - ssize_t remain; - loff_t offset; - char __user *user_data; - int page_offset, page_length; - - user_data = (char __user *) (uintptr_t) args->data_ptr; - remain = args->size; - - offset = args->offset; - - while (remain > 0) { - struct page *page; - char *vaddr; - int ret; - - /* Operation in this page - * - * page_offset = offset within page - * page_length = bytes to copy for this page - */ - page_offset = offset_in_page(offset); - page_length = remain; - if ((page_offset + remain) > PAGE_SIZE) - page_length = PAGE_SIZE - page_offset; - - page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); - if (IS_ERR(page)) - return PTR_ERR(page); - - vaddr = kmap_atomic(page); - ret = __copy_to_user_inatomic(user_data, - vaddr + page_offset, - page_length); - kunmap_atomic(vaddr); - - mark_page_accessed(page); - page_cache_release(page); - if (ret) - return -EFAULT; - - remain -= page_length; - user_data += page_length; - offset += page_length; - } - - return 0; -} - -static inline int -__copy_to_user_swizzled(char __user *cpu_vaddr, - const char *gpu_vaddr, int gpu_offset, - int length) -{ - int ret, cpu_offset = 0; - - while (length > 0) { - int cacheline_end = ALIGN(gpu_offset + 1, 64); - int this_length = min(cacheline_end - gpu_offset, length); - int swizzled_gpu_offset = gpu_offset ^ 64; - - ret = __copy_to_user(cpu_vaddr + cpu_offset, - gpu_vaddr + swizzled_gpu_offset, - this_length); - if (ret) - return ret + length; - - cpu_offset += this_length; - gpu_offset += this_length; - length -= this_length; - } - - return 0; -} - -static inline int -__copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, - const char *cpu_vaddr, - int length) -{ - int ret, cpu_offset = 0; - - while (length > 0) { - int cacheline_end = ALIGN(gpu_offset + 1, 64); - int this_length = min(cacheline_end - gpu_offset, length); - int swizzled_gpu_offset = gpu_offset ^ 64; - - ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset, - cpu_vaddr + cpu_offset, - this_length); - if (ret) - return ret + length; - - cpu_offset += this_length; - gpu_offset += this_length; - length -= this_length; - } - - return 0; -} - -/** - * This is the fallback shmem pread path, which allocates temporary storage - * in kernel space to copy_to_user into outside of the struct_mutex, so we - * can copy out of the object's backing pages while holding the struct mutex - * and not take page faults. - */ -static int -i915_gem_shmem_pread_slow(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pread *args, - struct drm_file *file) -{ - struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - char __user *user_data; - ssize_t remain; - loff_t offset; - int shmem_page_offset, page_length, ret; - int obj_do_bit17_swizzling, page_do_bit17_swizzling; - - user_data = (char __user *) (uintptr_t) args->data_ptr; - remain = args->size; - - obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - - offset = args->offset; - - mutex_unlock(&dev->struct_mutex); - - while (remain > 0) { - struct page *page; - char *vaddr; - - /* Operation in this page - * - * shmem_page_offset = offset within page in shmem file - * page_length = bytes to copy for this page - */ - shmem_page_offset = offset_in_page(offset); - page_length = remain; - if ((shmem_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - shmem_page_offset; - - page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - goto out; - } - - page_do_bit17_swizzling = obj_do_bit17_swizzling && - (page_to_phys(page) & (1 << 17)) != 0; - - vaddr = kmap(page); - if (page_do_bit17_swizzling) - ret = __copy_to_user_swizzled(user_data, - vaddr, shmem_page_offset, - page_length); - else - ret = __copy_to_user(user_data, - vaddr + shmem_page_offset, - page_length); - kunmap(page); - - mark_page_accessed(page); - page_cache_release(page); - - if (ret) { - ret = -EFAULT; - goto out; - } - - remain -= page_length; - user_data += page_length; - offset += page_length; - } - -out: - mutex_lock(&dev->struct_mutex); - /* Fixup: Kill any reinstated backing storage pages */ - if (obj->madv == __I915_MADV_PURGED) - i915_gem_object_truncate(obj); - - return ret; -} - -/** - * Reads data from the object referenced by handle. - * - * On error, the contents of *data are undefined. - */ -int -i915_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_pread *args = data; - struct drm_i915_gem_object *obj; - int ret = 0; - - if (args->size == 0) - return 0; - - if (!access_ok(VERIFY_WRITE, - (char __user *)(uintptr_t)args->data_ptr, - args->size)) - return -EFAULT; - - ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr, - args->size); - if (ret) - return -EFAULT; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - /* Bounds check source. */ - if (args->offset > obj->base.size || - args->size > obj->base.size - args->offset) { - ret = -EINVAL; - goto out; - } - - trace_i915_gem_object_pread(obj, args->offset, args->size); - - ret = i915_gem_object_set_cpu_read_domain_range(obj, - args->offset, - args->size); - if (ret) - goto out; - - ret = -EFAULT; - if (!i915_gem_object_needs_bit17_swizzle(obj)) - ret = i915_gem_shmem_pread_fast(dev, obj, args, file); - if (ret == -EFAULT) - ret = i915_gem_shmem_pread_slow(dev, obj, args, file); - -out: - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/* This is the fast write path which cannot handle - * page faults in the source data - */ - -static inline int -fast_user_write(struct io_mapping *mapping, - loff_t page_base, int page_offset, - char __user *user_data, - int length) -{ - char *vaddr_atomic; - unsigned long unwritten; - - vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base); - unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + page_offset, - user_data, length); - io_mapping_unmap_atomic(vaddr_atomic); - return unwritten; -} - -/* Here's the write path which can sleep for - * page faults - */ - -static inline void -slow_kernel_write(struct io_mapping *mapping, - loff_t gtt_base, int gtt_offset, - struct page *user_page, int user_offset, - int length) -{ - char __iomem *dst_vaddr; - char *src_vaddr; - - dst_vaddr = io_mapping_map_wc(mapping, gtt_base); - src_vaddr = kmap(user_page); - - memcpy_toio(dst_vaddr + gtt_offset, - src_vaddr + user_offset, - length); - - kunmap(user_page); - io_mapping_unmap(dst_vaddr); -} - -/** - * This is the fast pwrite path, where we copy the data directly from the - * user into the GTT, uncached. - */ -static int -i915_gem_gtt_pwrite_fast(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - ssize_t remain; - loff_t offset, page_base; - char __user *user_data; - int page_offset, page_length; - - user_data = (char __user *) (uintptr_t) args->data_ptr; - remain = args->size; - - offset = obj->gtt_offset + args->offset; - - while (remain > 0) { - /* Operation in this page - * - * page_base = page offset within aperture - * page_offset = offset within page - * page_length = bytes to copy for this page - */ - page_base = offset & PAGE_MASK; - page_offset = offset_in_page(offset); - page_length = remain; - if ((page_offset + remain) > PAGE_SIZE) - page_length = PAGE_SIZE - page_offset; - - /* If we get a fault while copying data, then (presumably) our - * source page isn't available. Return the error and we'll - * retry in the slow path. - */ - if (fast_user_write(dev_priv->mm.gtt_mapping, page_base, - page_offset, user_data, page_length)) - return -EFAULT; - - remain -= page_length; - user_data += page_length; - offset += page_length; - } - - return 0; -} - -/** - * This is the fallback GTT pwrite path, which uses get_user_pages to pin - * the memory and maps it using kmap_atomic for copying. - * - * This code resulted in x11perf -rgb10text consuming about 10% more CPU - * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit). - */ -static int -i915_gem_gtt_pwrite_slow(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - ssize_t remain; - loff_t gtt_page_base, offset; - loff_t first_data_page, last_data_page, num_pages; - loff_t pinned_pages, i; - struct page **user_pages; - struct mm_struct *mm = current->mm; - int gtt_page_offset, data_page_offset, data_page_index, page_length; - int ret; - uint64_t data_ptr = args->data_ptr; - - remain = args->size; - - /* Pin the user pages containing the data. We can't fault while - * holding the struct mutex, and all of the pwrite implementations - * want to hold it while dereferencing the user data. - */ - first_data_page = data_ptr / PAGE_SIZE; - last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; - num_pages = last_data_page - first_data_page + 1; - - user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); - if (user_pages == NULL) - return -ENOMEM; - - mutex_unlock(&dev->struct_mutex); - down_read(&mm->mmap_sem); - pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, - num_pages, 0, 0, user_pages, NULL); - up_read(&mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - if (pinned_pages < num_pages) { - ret = -EFAULT; - goto out_unpin_pages; - } - - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - goto out_unpin_pages; - - ret = i915_gem_object_put_fence(obj); - if (ret) - goto out_unpin_pages; - - offset = obj->gtt_offset + args->offset; - - while (remain > 0) { - /* Operation in this page - * - * gtt_page_base = page offset within aperture - * gtt_page_offset = offset within page in aperture - * data_page_index = page number in get_user_pages return - * data_page_offset = offset with data_page_index page. - * page_length = bytes to copy for this page - */ - gtt_page_base = offset & PAGE_MASK; - gtt_page_offset = offset_in_page(offset); - data_page_index = data_ptr / PAGE_SIZE - first_data_page; - data_page_offset = offset_in_page(data_ptr); - - page_length = remain; - if ((gtt_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - gtt_page_offset; - if ((data_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - data_page_offset; - - slow_kernel_write(dev_priv->mm.gtt_mapping, - gtt_page_base, gtt_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length); - - remain -= page_length; - offset += page_length; - data_ptr += page_length; - } - -out_unpin_pages: - for (i = 0; i < pinned_pages; i++) - page_cache_release(user_pages[i]); - drm_free_large(user_pages); - - return ret; -} - -/** - * This is the fast shmem pwrite path, which attempts to directly - * copy_from_user into the kmapped pages backing the object. - */ -static int -i915_gem_shmem_pwrite_fast(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file) -{ - struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - ssize_t remain; - loff_t offset; - char __user *user_data; - int page_offset, page_length; - - user_data = (char __user *) (uintptr_t) args->data_ptr; - remain = args->size; - - offset = args->offset; - obj->dirty = 1; - - while (remain > 0) { - struct page *page; - char *vaddr; - int ret; - - /* Operation in this page - * - * page_offset = offset within page - * page_length = bytes to copy for this page - */ - page_offset = offset_in_page(offset); - page_length = remain; - if ((page_offset + remain) > PAGE_SIZE) - page_length = PAGE_SIZE - page_offset; - - page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); - if (IS_ERR(page)) - return PTR_ERR(page); - - vaddr = kmap_atomic(page); - ret = __copy_from_user_inatomic(vaddr + page_offset, - user_data, - page_length); - kunmap_atomic(vaddr); - - set_page_dirty(page); - mark_page_accessed(page); - page_cache_release(page); - - /* If we get a fault while copying data, then (presumably) our - * source page isn't available. Return the error and we'll - * retry in the slow path. - */ - if (ret) - return -EFAULT; - - remain -= page_length; - user_data += page_length; - offset += page_length; - } - - return 0; -} - -/** - * This is the fallback shmem pwrite path, which uses get_user_pages to pin - * the memory and maps it using kmap_atomic for copying. - * - * This avoids taking mmap_sem for faulting on the user's address while the - * struct_mutex is held. - */ -static int -i915_gem_shmem_pwrite_slow(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file) -{ - struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - ssize_t remain; - loff_t offset; - char __user *user_data; - int shmem_page_offset, page_length, ret; - int obj_do_bit17_swizzling, page_do_bit17_swizzling; - - user_data = (char __user *) (uintptr_t) args->data_ptr; - remain = args->size; - - obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - - offset = args->offset; - obj->dirty = 1; - - mutex_unlock(&dev->struct_mutex); - - while (remain > 0) { - struct page *page; - char *vaddr; - - /* Operation in this page - * - * shmem_page_offset = offset within page in shmem file - * page_length = bytes to copy for this page - */ - shmem_page_offset = offset_in_page(offset); - - page_length = remain; - if ((shmem_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - shmem_page_offset; - - page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - goto out; - } - - page_do_bit17_swizzling = obj_do_bit17_swizzling && - (page_to_phys(page) & (1 << 17)) != 0; - - vaddr = kmap(page); - if (page_do_bit17_swizzling) - ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, - user_data, - page_length); - else - ret = __copy_from_user(vaddr + shmem_page_offset, - user_data, - page_length); - kunmap(page); - - set_page_dirty(page); - mark_page_accessed(page); - page_cache_release(page); - - if (ret) { - ret = -EFAULT; - goto out; - } - - remain -= page_length; - user_data += page_length; - offset += page_length; - } - -out: - mutex_lock(&dev->struct_mutex); - /* Fixup: Kill any reinstated backing storage pages */ - if (obj->madv == __I915_MADV_PURGED) - i915_gem_object_truncate(obj); - /* and flush dirty cachelines in case the object isn't in the cpu write - * domain anymore. */ - if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { - i915_gem_clflush_object(obj); - intel_gtt_chipset_flush(); - } - - return ret; -} - -/** - * Writes data to the object referenced by handle. - * - * On error, the contents of the buffer that were to be modified are undefined. - */ -int -i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_pwrite *args = data; - struct drm_i915_gem_object *obj; - int ret; - - if (args->size == 0) - return 0; - - if (!access_ok(VERIFY_READ, - (char __user *)(uintptr_t)args->data_ptr, - args->size)) - return -EFAULT; - - ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr, - args->size); - if (ret) - return -EFAULT; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - /* Bounds check destination. */ - if (args->offset > obj->base.size || - args->size > obj->base.size - args->offset) { - ret = -EINVAL; - goto out; - } - - trace_i915_gem_object_pwrite(obj, args->offset, args->size); - - /* We can only do the GTT pwrite on untiled buffers, as otherwise - * it would end up going through the fenced access, and we'll get - * different detiling behavior between reading and writing. - * pread/pwrite currently are reading and writing from the CPU - * perspective, requiring manual detiling by the client. - */ - if (obj->phys_obj) { - ret = i915_gem_phys_pwrite(dev, obj, args, file); - goto out; - } - - if (obj->gtt_space && - obj->base.write_domain != I915_GEM_DOMAIN_CPU) { - ret = i915_gem_object_pin(obj, 0, true); - if (ret) - goto out; - - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - goto out_unpin; - - ret = i915_gem_object_put_fence(obj); - if (ret) - goto out_unpin; - - ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file); - if (ret == -EFAULT) - ret = i915_gem_gtt_pwrite_slow(dev, obj, args, file); - -out_unpin: - i915_gem_object_unpin(obj); - - if (ret != -EFAULT) - goto out; - /* Fall through to the shmfs paths because the gtt paths might - * fail with non-page-backed user pointers (e.g. gtt mappings - * when moving data between textures). */ - } - - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) - goto out; - - ret = -EFAULT; - if (!i915_gem_object_needs_bit17_swizzle(obj)) - ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); - if (ret == -EFAULT) - ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); - -out: - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Called when user space prepares to use an object with the CPU, either - * through the mmap ioctl's mapping or a GTT mapping. - */ -int -i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_set_domain *args = data; - struct drm_i915_gem_object *obj; - uint32_t read_domains = args->read_domains; - uint32_t write_domain = args->write_domain; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - /* Only handle setting domains to types used by the CPU. */ - if (write_domain & I915_GEM_GPU_DOMAINS) - return -EINVAL; - - if (read_domains & I915_GEM_GPU_DOMAINS) - return -EINVAL; - - /* Having something in the write domain implies it's in the read - * domain, and only that read domain. Enforce that in the request. - */ - if (write_domain != 0 && read_domains != write_domain) - return -EINVAL; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (read_domains & I915_GEM_DOMAIN_GTT) { - ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); - - /* Silently promote "you're not bound, there was nothing to do" - * to success, since the client was just asking us to - * make sure everything was done. - */ - if (ret == -EINVAL) - ret = 0; - } else { - ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); - } - - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Called when user space has done writes to this buffer - */ -int -i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_sw_finish *args = data; - struct drm_i915_gem_object *obj; - int ret = 0; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - /* Pinned buffers may be scanout, so flush the cache */ - if (obj->pin_count) - i915_gem_object_flush_cpu_write_domain(obj); - - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * Maps the contents of an object, returning the address it is mapped - * into. - * - * While the mapping holds a reference on the contents of the object, it doesn't - * imply a ref on the object itself. - */ -int -i915_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_mmap *args = data; - struct drm_gem_object *obj; - unsigned long addr; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - obj = drm_gem_object_lookup(dev, file, args->handle); - if (obj == NULL) - return -ENOENT; - - addr = vm_mmap(obj->filp, 0, args->size, - PROT_READ | PROT_WRITE, MAP_SHARED, - args->offset); - drm_gem_object_unreference_unlocked(obj); - if (IS_ERR((void *)addr)) - return addr; - - args->addr_ptr = (uint64_t) addr; - - return 0; -} - -/** - * i915_gem_fault - fault a page into the GTT - * vma: VMA in question - * vmf: fault info - * - * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped - * from userspace. The fault handler takes care of binding the object to - * the GTT (if needed), allocating and programming a fence register (again, - * only if needed based on whether the old reg is still valid or the object - * is tiled) and inserting a new PTE into the faulting process. - * - * Note that the faulting process may involve evicting existing objects - * from the GTT and/or fence registers to make room. So performance may - * suffer if the GTT working set is large or there are few fence registers - * left. - */ -int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data); - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - pgoff_t page_offset; - unsigned long pfn; - int ret = 0; - bool write = !!(vmf->flags & FAULT_FLAG_WRITE); - - /* We don't use vmf->pgoff since that has the fake offset */ - page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >> - PAGE_SHIFT; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - goto out; - - trace_i915_gem_object_fault(obj, page_offset, true, write); - - /* Now bind it into the GTT if needed */ - if (!obj->map_and_fenceable) { - ret = i915_gem_object_unbind(obj); - if (ret) - goto unlock; - } - if (!obj->gtt_space) { - ret = i915_gem_object_bind_to_gtt(obj, 0, true); - if (ret) - goto unlock; - - ret = i915_gem_object_set_to_gtt_domain(obj, write); - if (ret) - goto unlock; - } - - if (obj->tiling_mode == I915_TILING_NONE) - ret = i915_gem_object_put_fence(obj); - else - ret = i915_gem_object_get_fence(obj, NULL); - if (ret) - goto unlock; - - if (i915_gem_object_is_inactive(obj)) - list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - - obj->fault_mappable = true; - - pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) + - page_offset; - - /* Finally, remap it using the new GTT offset */ - ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); -unlock: - mutex_unlock(&dev->struct_mutex); -out: - switch (ret) { - case -EIO: - case -EAGAIN: - /* Give the error handler a chance to run and move the - * objects off the GPU active list. Next time we service the - * fault, we should be able to transition the page into the - * GTT without touching the GPU (and so avoid further - * EIO/EGAIN). If the GPU is wedged, then there is no issue - * with coherency, just lost writes. - */ - set_need_resched(); - case 0: - case -ERESTARTSYS: - case -EINTR: - return VM_FAULT_NOPAGE; - case -ENOMEM: - return VM_FAULT_OOM; - default: - return VM_FAULT_SIGBUS; - } -} - -/** - * i915_gem_release_mmap - remove physical page mappings - * @obj: obj in question - * - * Preserve the reservation of the mmapping with the DRM core code, but - * relinquish ownership of the pages back to the system. - * - * It is vital that we remove the page mapping if we have mapped a tiled - * object through the GTT and then lose the fence register due to - * resource pressure. Similarly if the object has been moved out of the - * aperture, than pages mapped into userspace must be revoked. Removing the - * mapping will then trigger a page fault on the next user access, allowing - * fixup by i915_gem_fault(). - */ -void -i915_gem_release_mmap(struct drm_i915_gem_object *obj) -{ - if (!obj->fault_mappable) - return; - - if (obj->base.dev->dev_mapping) - unmap_mapping_range(obj->base.dev->dev_mapping, - (loff_t)obj->base.map_list.hash.key<base.size, 1); - - obj->fault_mappable = false; -} - -static uint32_t -i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode) -{ - uint32_t gtt_size; - - if (INTEL_INFO(dev)->gen >= 4 || - tiling_mode == I915_TILING_NONE) - return size; - - /* Previous chips need a power-of-two fence region when tiling */ - if (INTEL_INFO(dev)->gen == 3) - gtt_size = 1024*1024; - else - gtt_size = 512*1024; - - while (gtt_size < size) - gtt_size <<= 1; - - return gtt_size; -} - -/** - * i915_gem_get_gtt_alignment - return required GTT alignment for an object - * @obj: object to check - * - * Return the required GTT alignment for an object, taking into account - * potential fence register mapping. - */ -static uint32_t -i915_gem_get_gtt_alignment(struct drm_device *dev, - uint32_t size, - int tiling_mode) -{ - /* - * Minimum alignment is 4k (GTT page size), but might be greater - * if a fence register is needed for the object. - */ - if (INTEL_INFO(dev)->gen >= 4 || - tiling_mode == I915_TILING_NONE) - return 4096; - - /* - * Previous chips need to be aligned to the size of the smallest - * fence register that can contain the object. - */ - return i915_gem_get_gtt_size(dev, size, tiling_mode); -} - -/** - * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an - * unfenced object - * @dev: the device - * @size: size of the object - * @tiling_mode: tiling mode of the object - * - * Return the required GTT alignment for an object, only taking into account - * unfenced tiled surface requirements. - */ -uint32_t -i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, - uint32_t size, - int tiling_mode) -{ - /* - * Minimum alignment is 4k (GTT page size) for sane hw. - */ - if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || - tiling_mode == I915_TILING_NONE) - return 4096; - - /* Previous hardware however needs to be aligned to a power-of-two - * tile height. The simplest method for determining this is to reuse - * the power-of-tile object size. - */ - return i915_gem_get_gtt_size(dev, size, tiling_mode); -} - -int -i915_gem_mmap_gtt(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int ret; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (obj->base.size > dev_priv->mm.gtt_mappable_end) { - ret = -E2BIG; - goto out; - } - - if (obj->madv != I915_MADV_WILLNEED) { - DRM_ERROR("Attempting to mmap a purgeable buffer\n"); - ret = -EINVAL; - goto out; - } - - if (!obj->base.map_list.map) { - ret = drm_gem_create_mmap_offset(&obj->base); - if (ret) - goto out; - } - - *offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; - -out: - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -/** - * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing - * @dev: DRM device - * @data: GTT mapping ioctl data - * @file: GEM object info - * - * Simply returns the fake offset to userspace so it can mmap it. - * The mmap call will end up in drm_gem_mmap(), which will set things - * up so we can get faults in the handler above. - * - * The fault handler will take care of binding the object into the GTT - * (since it may have been evicted to make room for something), allocating - * a fence register, and mapping the appropriate aperture address into - * userspace. - */ -int -i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_mmap_gtt *args = data; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; - - return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); -} - - -static int -i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, - gfp_t gfpmask) -{ - int page_count, i; - struct address_space *mapping; - struct inode *inode; - struct page *page; - - /* Get the list of pages out of our struct file. They'll be pinned - * at this point until we release them. - */ - page_count = obj->base.size / PAGE_SIZE; - BUG_ON(obj->pages != NULL); - obj->pages = drm_malloc_ab(page_count, sizeof(struct page *)); - if (obj->pages == NULL) - return -ENOMEM; - - inode = obj->base.filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - gfpmask |= mapping_gfp_mask(mapping); - - for (i = 0; i < page_count; i++) { - page = shmem_read_mapping_page_gfp(mapping, i, gfpmask); - if (IS_ERR(page)) - goto err_pages; - - obj->pages[i] = page; - } - - if (i915_gem_object_needs_bit17_swizzle(obj)) - i915_gem_object_do_bit_17_swizzle(obj); - - return 0; - -err_pages: - while (i--) - page_cache_release(obj->pages[i]); - - drm_free_large(obj->pages); - obj->pages = NULL; - return PTR_ERR(page); -} - -static void -i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) -{ - int page_count = obj->base.size / PAGE_SIZE; - int i; - - BUG_ON(obj->madv == __I915_MADV_PURGED); - - if (i915_gem_object_needs_bit17_swizzle(obj)) - i915_gem_object_save_bit_17_swizzle(obj); - - if (obj->madv == I915_MADV_DONTNEED) - obj->dirty = 0; - - for (i = 0; i < page_count; i++) { - if (obj->dirty) - set_page_dirty(obj->pages[i]); - - if (obj->madv == I915_MADV_WILLNEED) - mark_page_accessed(obj->pages[i]); - - page_cache_release(obj->pages[i]); - } - obj->dirty = 0; - - drm_free_large(obj->pages); - obj->pages = NULL; -} - -void -i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring, - u32 seqno) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - BUG_ON(ring == NULL); - obj->ring = ring; - - /* Add a reference if we're newly entering the active list. */ - if (!obj->active) { - drm_gem_object_reference(&obj->base); - obj->active = 1; - } - - /* Move from whatever list we were on to the tail of execution. */ - list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); - list_move_tail(&obj->ring_list, &ring->active_list); - - obj->last_rendering_seqno = seqno; - - if (obj->fenced_gpu_access) { - obj->last_fenced_seqno = seqno; - obj->last_fenced_ring = ring; - - /* Bump MRU to take account of the delayed flush */ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_fence_reg *reg; - - reg = &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, - &dev_priv->mm.fence_list); - } - } -} - -static void -i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) -{ - list_del_init(&obj->ring_list); - obj->last_rendering_seqno = 0; - obj->last_fenced_seqno = 0; -} - -static void -i915_gem_object_move_to_flushing(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - BUG_ON(!obj->active); - list_move_tail(&obj->mm_list, &dev_priv->mm.flushing_list); - - i915_gem_object_move_off_active(obj); -} - -static void -i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (obj->pin_count != 0) - list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); - else - list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - - BUG_ON(!list_empty(&obj->gpu_write_list)); - BUG_ON(!obj->active); - obj->ring = NULL; - obj->last_fenced_ring = NULL; - - i915_gem_object_move_off_active(obj); - obj->fenced_gpu_access = false; - - obj->active = 0; - obj->pending_gpu_write = false; - drm_gem_object_unreference(&obj->base); - - WARN_ON(i915_verify_lists(dev)); -} - -/* Immediately discard the backing storage */ -static void -i915_gem_object_truncate(struct drm_i915_gem_object *obj) -{ - struct inode *inode; - - /* Our goal here is to return as much of the memory as - * is possible back to the system as we are called from OOM. - * To do this we must instruct the shmfs to drop all of its - * backing pages, *now*. - */ - inode = obj->base.filp->f_path.dentry->d_inode; - shmem_truncate_range(inode, 0, (loff_t)-1); - - obj->madv = __I915_MADV_PURGED; -} - -static inline int -i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) -{ - return obj->madv == I915_MADV_DONTNEED; -} - -static void -i915_gem_process_flushing_list(struct intel_ring_buffer *ring, - uint32_t flush_domains) -{ - struct drm_i915_gem_object *obj, *next; - - list_for_each_entry_safe(obj, next, - &ring->gpu_write_list, - gpu_write_list) { - if (obj->base.write_domain & flush_domains) { - uint32_t old_write_domain = obj->base.write_domain; - - obj->base.write_domain = 0; - list_del_init(&obj->gpu_write_list); - i915_gem_object_move_to_active(obj, ring, - i915_gem_next_request_seqno(ring)); - - trace_i915_gem_object_change_domain(obj, - obj->base.read_domains, - old_write_domain); - } - } -} - -static u32 -i915_gem_get_seqno(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - u32 seqno = dev_priv->next_seqno; - - /* reserve 0 for non-seqno */ - if (++dev_priv->next_seqno == 0) - dev_priv->next_seqno = 1; - - return seqno; -} - -u32 -i915_gem_next_request_seqno(struct intel_ring_buffer *ring) -{ - if (ring->outstanding_lazy_request == 0) - ring->outstanding_lazy_request = i915_gem_get_seqno(ring->dev); - - return ring->outstanding_lazy_request; -} - -int -i915_add_request(struct intel_ring_buffer *ring, - struct drm_file *file, - struct drm_i915_gem_request *request) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - uint32_t seqno; - u32 request_ring_position; - int was_empty; - int ret; - - BUG_ON(request == NULL); - seqno = i915_gem_next_request_seqno(ring); - - /* Record the position of the start of the request so that - * should we detect the updated seqno part-way through the - * GPU processing the request, we never over-estimate the - * position of the head. - */ - request_ring_position = intel_ring_get_tail(ring); - - ret = ring->add_request(ring, &seqno); - if (ret) - return ret; - - trace_i915_gem_request_add(ring, seqno); - - request->seqno = seqno; - request->ring = ring; - request->tail = request_ring_position; - request->emitted_jiffies = jiffies; - was_empty = list_empty(&ring->request_list); - list_add_tail(&request->list, &ring->request_list); - - if (file) { - struct drm_i915_file_private *file_priv = file->driver_priv; - - spin_lock(&file_priv->mm.lock); - request->file_priv = file_priv; - list_add_tail(&request->client_list, - &file_priv->mm.request_list); - spin_unlock(&file_priv->mm.lock); - } - - ring->outstanding_lazy_request = 0; - - if (!dev_priv->mm.suspended) { - if (i915_enable_hangcheck) { - mod_timer(&dev_priv->hangcheck_timer, - jiffies + - msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); - } - if (was_empty) - queue_delayed_work(dev_priv->wq, - &dev_priv->mm.retire_work, HZ); - } - return 0; -} - -static inline void -i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) -{ - struct drm_i915_file_private *file_priv = request->file_priv; - - if (!file_priv) - return; - - spin_lock(&file_priv->mm.lock); - if (request->file_priv) { - list_del(&request->client_list); - request->file_priv = NULL; - } - spin_unlock(&file_priv->mm.lock); -} - -static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, - struct intel_ring_buffer *ring) -{ - while (!list_empty(&ring->request_list)) { - struct drm_i915_gem_request *request; - - request = list_first_entry(&ring->request_list, - struct drm_i915_gem_request, - list); - - list_del(&request->list); - i915_gem_request_remove_from_client(request); - kfree(request); - } - - while (!list_empty(&ring->active_list)) { - struct drm_i915_gem_object *obj; - - obj = list_first_entry(&ring->active_list, - struct drm_i915_gem_object, - ring_list); - - obj->base.write_domain = 0; - list_del_init(&obj->gpu_write_list); - i915_gem_object_move_to_inactive(obj); - } -} - -static void i915_gem_reset_fences(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - for (i = 0; i < dev_priv->num_fence_regs; i++) { - struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; - struct drm_i915_gem_object *obj = reg->obj; - - if (!obj) - continue; - - if (obj->tiling_mode) - i915_gem_release_mmap(obj); - - reg->obj->fence_reg = I915_FENCE_REG_NONE; - reg->obj->fenced_gpu_access = false; - reg->obj->last_fenced_seqno = 0; - reg->obj->last_fenced_ring = NULL; - i915_gem_clear_fence_reg(dev, reg); - } -} - -void i915_gem_reset(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int i; - - for (i = 0; i < I915_NUM_RINGS; i++) - i915_gem_reset_ring_lists(dev_priv, &dev_priv->ring[i]); - - /* Remove anything from the flushing lists. The GPU cache is likely - * to be lost on reset along with the data, so simply move the - * lost bo to the inactive list. - */ - while (!list_empty(&dev_priv->mm.flushing_list)) { - obj = list_first_entry(&dev_priv->mm.flushing_list, - struct drm_i915_gem_object, - mm_list); - - obj->base.write_domain = 0; - list_del_init(&obj->gpu_write_list); - i915_gem_object_move_to_inactive(obj); - } - - /* Move everything out of the GPU domains to ensure we do any - * necessary invalidation upon reuse. - */ - list_for_each_entry(obj, - &dev_priv->mm.inactive_list, - mm_list) - { - obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; - } - - /* The fence registers are invalidated so clear them out */ - i915_gem_reset_fences(dev); -} - -/** - * This function clears the request list as sequence numbers are passed. - */ -void -i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) -{ - uint32_t seqno; - int i; - - if (list_empty(&ring->request_list)) - return; - - WARN_ON(i915_verify_lists(ring->dev)); - - seqno = ring->get_seqno(ring); - - for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) - if (seqno >= ring->sync_seqno[i]) - ring->sync_seqno[i] = 0; - - while (!list_empty(&ring->request_list)) { - struct drm_i915_gem_request *request; - - request = list_first_entry(&ring->request_list, - struct drm_i915_gem_request, - list); - - if (!i915_seqno_passed(seqno, request->seqno)) - break; - - trace_i915_gem_request_retire(ring, request->seqno); - /* We know the GPU must have read the request to have - * sent us the seqno + interrupt, so use the position - * of tail of the request to update the last known position - * of the GPU head. - */ - ring->last_retired_head = request->tail; - - list_del(&request->list); - i915_gem_request_remove_from_client(request); - kfree(request); - } - - /* Move any buffers on the active list that are no longer referenced - * by the ringbuffer to the flushing/inactive lists as appropriate. - */ - while (!list_empty(&ring->active_list)) { - struct drm_i915_gem_object *obj; - - obj = list_first_entry(&ring->active_list, - struct drm_i915_gem_object, - ring_list); - - if (!i915_seqno_passed(seqno, obj->last_rendering_seqno)) - break; - - if (obj->base.write_domain != 0) - i915_gem_object_move_to_flushing(obj); - else - i915_gem_object_move_to_inactive(obj); - } - - if (unlikely(ring->trace_irq_seqno && - i915_seqno_passed(seqno, ring->trace_irq_seqno))) { - ring->irq_put(ring); - ring->trace_irq_seqno = 0; - } - - WARN_ON(i915_verify_lists(ring->dev)); -} - -void -i915_gem_retire_requests(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i; - - if (!list_empty(&dev_priv->mm.deferred_free_list)) { - struct drm_i915_gem_object *obj, *next; - - /* We must be careful that during unbind() we do not - * accidentally infinitely recurse into retire requests. - * Currently: - * retire -> free -> unbind -> wait -> retire_ring - */ - list_for_each_entry_safe(obj, next, - &dev_priv->mm.deferred_free_list, - mm_list) - i915_gem_free_object_tail(obj); - } - - for (i = 0; i < I915_NUM_RINGS; i++) - i915_gem_retire_requests_ring(&dev_priv->ring[i]); -} - -static void -i915_gem_retire_work_handler(struct work_struct *work) -{ - drm_i915_private_t *dev_priv; - struct drm_device *dev; - bool idle; - int i; - - dev_priv = container_of(work, drm_i915_private_t, - mm.retire_work.work); - dev = dev_priv->dev; - - /* Come back later if the device is busy... */ - if (!mutex_trylock(&dev->struct_mutex)) { - queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); - return; - } - - i915_gem_retire_requests(dev); - - /* Send a periodic flush down the ring so we don't hold onto GEM - * objects indefinitely. - */ - idle = true; - for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_ring_buffer *ring = &dev_priv->ring[i]; - - if (!list_empty(&ring->gpu_write_list)) { - struct drm_i915_gem_request *request; - int ret; - - ret = i915_gem_flush_ring(ring, - 0, I915_GEM_GPU_DOMAINS); - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (ret || request == NULL || - i915_add_request(ring, NULL, request)) - kfree(request); - } - - idle &= list_empty(&ring->request_list); - } - - if (!dev_priv->mm.suspended && !idle) - queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); - - mutex_unlock(&dev->struct_mutex); -} - -/** - * Waits for a sequence number to be signaled, and cleans up the - * request and object lists appropriately for that event. - */ -int -i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno, - bool do_retire) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - u32 ier; - int ret = 0; - - BUG_ON(seqno == 0); - - if (atomic_read(&dev_priv->mm.wedged)) { - struct completion *x = &dev_priv->error_completion; - bool recovery_complete; - unsigned long flags; - - /* Give the error handler a chance to run. */ - spin_lock_irqsave(&x->wait.lock, flags); - recovery_complete = x->done > 0; - spin_unlock_irqrestore(&x->wait.lock, flags); - - return recovery_complete ? -EIO : -EAGAIN; - } - - if (seqno == ring->outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - ret = i915_add_request(ring, NULL, request); - if (ret) { - kfree(request); - return ret; - } - - seqno = request->seqno; - } - - if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { - if (HAS_PCH_SPLIT(ring->dev)) - ier = I915_READ(DEIER) | I915_READ(GTIER); - else - ier = I915_READ(IER); - if (!ier) { - DRM_ERROR("something (likely vbetool) disabled " - "interrupts, re-enabling\n"); - ring->dev->driver->irq_preinstall(ring->dev); - ring->dev->driver->irq_postinstall(ring->dev); - } - - trace_i915_gem_request_wait_begin(ring, seqno); - - ring->waiting_seqno = seqno; - if (ring->irq_get(ring)) { - if (dev_priv->mm.interruptible) - ret = wait_event_interruptible(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(ring), seqno) - || atomic_read(&dev_priv->mm.wedged)); - else - wait_event(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(ring), seqno) - || atomic_read(&dev_priv->mm.wedged)); - - ring->irq_put(ring); - } else if (wait_for_atomic(i915_seqno_passed(ring->get_seqno(ring), - seqno) || - atomic_read(&dev_priv->mm.wedged), 3000)) - ret = -EBUSY; - ring->waiting_seqno = 0; - - trace_i915_gem_request_wait_end(ring, seqno); - } - if (atomic_read(&dev_priv->mm.wedged)) - ret = -EAGAIN; - - /* Directly dispatch request retiring. While we have the work queue - * to handle this, the waiter on a request often wants an associated - * buffer to have made it to the inactive list, and we would need - * a separate wait queue to handle that. - */ - if (ret == 0 && do_retire) - i915_gem_retire_requests_ring(ring); - - return ret; -} - -/** - * Ensures that all rendering to the object has completed and the object is - * safe to unbind from the GTT or access from the CPU. - */ -int -i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) -{ - int ret; - - /* This function only exists to support waiting for existing rendering, - * not for emitting required flushes. - */ - BUG_ON((obj->base.write_domain & I915_GEM_GPU_DOMAINS) != 0); - - /* If there is rendering queued on the buffer being evicted, wait for - * it. - */ - if (obj->active) { - ret = i915_wait_request(obj->ring, obj->last_rendering_seqno, - true); - if (ret) - return ret; - } - - return 0; -} - -static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) -{ - u32 old_write_domain, old_read_domains; - - /* Act a barrier for all accesses through the GTT */ - mb(); - - /* Force a pagefault for domain tracking on next user access */ - i915_gem_release_mmap(obj); - - if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0) - return; - - old_read_domains = obj->base.read_domains; - old_write_domain = obj->base.write_domain; - - obj->base.read_domains &= ~I915_GEM_DOMAIN_GTT; - obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT; - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - old_write_domain); -} - -/** - * Unbinds an object from the GTT aperture. - */ -int -i915_gem_object_unbind(struct drm_i915_gem_object *obj) -{ - drm_i915_private_t *dev_priv = obj->base.dev->dev_private; - int ret = 0; - - if (obj->gtt_space == NULL) - return 0; - - if (obj->pin_count != 0) { - DRM_ERROR("Attempting to unbind pinned buffer\n"); - return -EINVAL; - } - - ret = i915_gem_object_finish_gpu(obj); - if (ret == -ERESTARTSYS) - return ret; - /* Continue on if we fail due to EIO, the GPU is hung so we - * should be safe and we need to cleanup or else we might - * cause memory corruption through use-after-free. - */ - - i915_gem_object_finish_gtt(obj); - - /* Move the object to the CPU domain to ensure that - * any possible CPU writes while it's not in the GTT - * are flushed when we go to remap it. - */ - if (ret == 0) - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret == -ERESTARTSYS) - return ret; - if (ret) { - /* In the event of a disaster, abandon all caches and - * hope for the best. - */ - i915_gem_clflush_object(obj); - obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; - } - - /* release the fence reg _after_ flushing */ - ret = i915_gem_object_put_fence(obj); - if (ret == -ERESTARTSYS) - return ret; - - trace_i915_gem_object_unbind(obj); - - i915_gem_gtt_unbind_object(obj); - if (obj->has_aliasing_ppgtt_mapping) { - i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); - obj->has_aliasing_ppgtt_mapping = 0; - } - - i915_gem_object_put_pages_gtt(obj); - - list_del_init(&obj->gtt_list); - list_del_init(&obj->mm_list); - /* Avoid an unnecessary call to unbind on rebind. */ - obj->map_and_fenceable = true; - - drm_mm_put_block(obj->gtt_space); - obj->gtt_space = NULL; - obj->gtt_offset = 0; - - if (i915_gem_object_is_purgeable(obj)) - i915_gem_object_truncate(obj); - - return ret; -} - -int -i915_gem_flush_ring(struct intel_ring_buffer *ring, - uint32_t invalidate_domains, - uint32_t flush_domains) -{ - int ret; - - if (((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) == 0) - return 0; - - trace_i915_gem_ring_flush(ring, invalidate_domains, flush_domains); - - ret = ring->flush(ring, invalidate_domains, flush_domains); - if (ret) - return ret; - - if (flush_domains & I915_GEM_GPU_DOMAINS) - i915_gem_process_flushing_list(ring, flush_domains); - - return 0; -} - -static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) -{ - int ret; - - if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) - return 0; - - if (!list_empty(&ring->gpu_write_list)) { - ret = i915_gem_flush_ring(ring, - I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); - if (ret) - return ret; - } - - return i915_wait_request(ring, i915_gem_next_request_seqno(ring), - do_retire); -} - -int i915_gpu_idle(struct drm_device *dev, bool do_retire) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret, i; - - /* Flush everything onto the inactive list. */ - for (i = 0; i < I915_NUM_RINGS; i++) { - ret = i915_ring_idle(&dev_priv->ring[i], do_retire); - if (ret) - return ret; - } - - return 0; -} - -static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 size = obj->gtt_space->size; - int regnum = obj->fence_reg; - uint64_t val; - - val = (uint64_t)((obj->gtt_offset + size - 4096) & - 0xfffff000) << 32; - val |= obj->gtt_offset & 0xfffff000; - val |= (uint64_t)((obj->stride / 128) - 1) << - SANDYBRIDGE_FENCE_PITCH_SHIFT; - - if (obj->tiling_mode == I915_TILING_Y) - val |= 1 << I965_FENCE_TILING_Y_SHIFT; - val |= I965_FENCE_REG_VALID; - - if (pipelined) { - int ret = intel_ring_begin(pipelined, 6); - if (ret) - return ret; - - intel_ring_emit(pipelined, MI_NOOP); - intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); - intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8); - intel_ring_emit(pipelined, (u32)val); - intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8 + 4); - intel_ring_emit(pipelined, (u32)(val >> 32)); - intel_ring_advance(pipelined); - } else - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val); - - return 0; -} - -static int i965_write_fence_reg(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 size = obj->gtt_space->size; - int regnum = obj->fence_reg; - uint64_t val; - - val = (uint64_t)((obj->gtt_offset + size - 4096) & - 0xfffff000) << 32; - val |= obj->gtt_offset & 0xfffff000; - val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; - if (obj->tiling_mode == I915_TILING_Y) - val |= 1 << I965_FENCE_TILING_Y_SHIFT; - val |= I965_FENCE_REG_VALID; - - if (pipelined) { - int ret = intel_ring_begin(pipelined, 6); - if (ret) - return ret; - - intel_ring_emit(pipelined, MI_NOOP); - intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); - intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8); - intel_ring_emit(pipelined, (u32)val); - intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8 + 4); - intel_ring_emit(pipelined, (u32)(val >> 32)); - intel_ring_advance(pipelined); - } else - I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val); - - return 0; -} - -static int i915_write_fence_reg(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 size = obj->gtt_space->size; - u32 fence_reg, val, pitch_val; - int tile_width; - - if (WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) || - (size & -size) != size || - (obj->gtt_offset & (size - 1)), - "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", - obj->gtt_offset, obj->map_and_fenceable, size)) - return -EINVAL; - - if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) - tile_width = 128; - else - tile_width = 512; - - /* Note: pitch better be a power of two tile widths */ - pitch_val = obj->stride / tile_width; - pitch_val = ffs(pitch_val) - 1; - - val = obj->gtt_offset; - if (obj->tiling_mode == I915_TILING_Y) - val |= 1 << I830_FENCE_TILING_Y_SHIFT; - val |= I915_FENCE_SIZE_BITS(size); - val |= pitch_val << I830_FENCE_PITCH_SHIFT; - val |= I830_FENCE_REG_VALID; - - fence_reg = obj->fence_reg; - if (fence_reg < 8) - fence_reg = FENCE_REG_830_0 + fence_reg * 4; - else - fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; - - if (pipelined) { - int ret = intel_ring_begin(pipelined, 4); - if (ret) - return ret; - - intel_ring_emit(pipelined, MI_NOOP); - intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(pipelined, fence_reg); - intel_ring_emit(pipelined, val); - intel_ring_advance(pipelined); - } else - I915_WRITE(fence_reg, val); - - return 0; -} - -static int i830_write_fence_reg(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 size = obj->gtt_space->size; - int regnum = obj->fence_reg; - uint32_t val; - uint32_t pitch_val; - - if (WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) || - (size & -size) != size || - (obj->gtt_offset & (size - 1)), - "object 0x%08x not 512K or pot-size 0x%08x aligned\n", - obj->gtt_offset, size)) - return -EINVAL; - - pitch_val = obj->stride / 128; - pitch_val = ffs(pitch_val) - 1; - - val = obj->gtt_offset; - if (obj->tiling_mode == I915_TILING_Y) - val |= 1 << I830_FENCE_TILING_Y_SHIFT; - val |= I830_FENCE_SIZE_BITS(size); - val |= pitch_val << I830_FENCE_PITCH_SHIFT; - val |= I830_FENCE_REG_VALID; - - if (pipelined) { - int ret = intel_ring_begin(pipelined, 4); - if (ret) - return ret; - - intel_ring_emit(pipelined, MI_NOOP); - intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(pipelined, FENCE_REG_830_0 + regnum*4); - intel_ring_emit(pipelined, val); - intel_ring_advance(pipelined); - } else - I915_WRITE(FENCE_REG_830_0 + regnum * 4, val); - - return 0; -} - -static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno) -{ - return i915_seqno_passed(ring->get_seqno(ring), seqno); -} - -static int -i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - int ret; - - if (obj->fenced_gpu_access) { - if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { - ret = i915_gem_flush_ring(obj->last_fenced_ring, - 0, obj->base.write_domain); - if (ret) - return ret; - } - - obj->fenced_gpu_access = false; - } - - if (obj->last_fenced_seqno && pipelined != obj->last_fenced_ring) { - if (!ring_passed_seqno(obj->last_fenced_ring, - obj->last_fenced_seqno)) { - ret = i915_wait_request(obj->last_fenced_ring, - obj->last_fenced_seqno, - true); - if (ret) - return ret; - } - - obj->last_fenced_seqno = 0; - obj->last_fenced_ring = NULL; - } - - /* Ensure that all CPU reads are completed before installing a fence - * and all writes before removing the fence. - */ - if (obj->base.read_domains & I915_GEM_DOMAIN_GTT) - mb(); - - return 0; -} - -int -i915_gem_object_put_fence(struct drm_i915_gem_object *obj) -{ - int ret; - - if (obj->tiling_mode) - i915_gem_release_mmap(obj); - - ret = i915_gem_object_flush_fence(obj, NULL); - if (ret) - return ret; - - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - - WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count); - i915_gem_clear_fence_reg(obj->base.dev, - &dev_priv->fence_regs[obj->fence_reg]); - - obj->fence_reg = I915_FENCE_REG_NONE; - } - - return 0; -} - -static struct drm_i915_fence_reg * -i915_find_fence_reg(struct drm_device *dev, - struct intel_ring_buffer *pipelined) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_fence_reg *reg, *first, *avail; - int i; - - /* First try to find a free reg */ - avail = NULL; - for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { - reg = &dev_priv->fence_regs[i]; - if (!reg->obj) - return reg; - - if (!reg->pin_count) - avail = reg; - } - - if (avail == NULL) - return NULL; - - /* None available, try to steal one or wait for a user to finish */ - avail = first = NULL; - list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { - if (reg->pin_count) - continue; - - if (first == NULL) - first = reg; - - if (!pipelined || - !reg->obj->last_fenced_ring || - reg->obj->last_fenced_ring == pipelined) { - avail = reg; - break; - } - } - - if (avail == NULL) - avail = first; - - return avail; -} - -/** - * i915_gem_object_get_fence - set up a fence reg for an object - * @obj: object to map through a fence reg - * @pipelined: ring on which to queue the change, or NULL for CPU access - * @interruptible: must we wait uninterruptibly for the register to retire? - * - * When mapping objects through the GTT, userspace wants to be able to write - * to them without having to worry about swizzling if the object is tiled. - * - * This function walks the fence regs looking for a free one for @obj, - * stealing one if it can't find any. - * - * It then sets up the reg based on the object's properties: address, pitch - * and tiling format. - */ -int -i915_gem_object_get_fence(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_fence_reg *reg; - int ret; - - /* XXX disable pipelining. There are bugs. Shocking. */ - pipelined = NULL; - - /* Just update our place in the LRU if our fence is getting reused. */ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - reg = &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, &dev_priv->mm.fence_list); - - if (obj->tiling_changed) { - ret = i915_gem_object_flush_fence(obj, pipelined); - if (ret) - return ret; - - if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) - pipelined = NULL; - - if (pipelined) { - reg->setup_seqno = - i915_gem_next_request_seqno(pipelined); - obj->last_fenced_seqno = reg->setup_seqno; - obj->last_fenced_ring = pipelined; - } - - goto update; - } - - if (!pipelined) { - if (reg->setup_seqno) { - if (!ring_passed_seqno(obj->last_fenced_ring, - reg->setup_seqno)) { - ret = i915_wait_request(obj->last_fenced_ring, - reg->setup_seqno, - true); - if (ret) - return ret; - } - - reg->setup_seqno = 0; - } - } else if (obj->last_fenced_ring && - obj->last_fenced_ring != pipelined) { - ret = i915_gem_object_flush_fence(obj, pipelined); - if (ret) - return ret; - } - - return 0; - } - - reg = i915_find_fence_reg(dev, pipelined); - if (reg == NULL) - return -EDEADLK; - - ret = i915_gem_object_flush_fence(obj, pipelined); - if (ret) - return ret; - - if (reg->obj) { - struct drm_i915_gem_object *old = reg->obj; - - drm_gem_object_reference(&old->base); - - if (old->tiling_mode) - i915_gem_release_mmap(old); - - ret = i915_gem_object_flush_fence(old, pipelined); - if (ret) { - drm_gem_object_unreference(&old->base); - return ret; - } - - if (old->last_fenced_seqno == 0 && obj->last_fenced_seqno == 0) - pipelined = NULL; - - old->fence_reg = I915_FENCE_REG_NONE; - old->last_fenced_ring = pipelined; - old->last_fenced_seqno = - pipelined ? i915_gem_next_request_seqno(pipelined) : 0; - - drm_gem_object_unreference(&old->base); - } else if (obj->last_fenced_seqno == 0) - pipelined = NULL; - - reg->obj = obj; - list_move_tail(®->lru_list, &dev_priv->mm.fence_list); - obj->fence_reg = reg - dev_priv->fence_regs; - obj->last_fenced_ring = pipelined; - - reg->setup_seqno = - pipelined ? i915_gem_next_request_seqno(pipelined) : 0; - obj->last_fenced_seqno = reg->setup_seqno; - -update: - obj->tiling_changed = false; - switch (INTEL_INFO(dev)->gen) { - case 7: - case 6: - ret = sandybridge_write_fence_reg(obj, pipelined); - break; - case 5: - case 4: - ret = i965_write_fence_reg(obj, pipelined); - break; - case 3: - ret = i915_write_fence_reg(obj, pipelined); - break; - case 2: - ret = i830_write_fence_reg(obj, pipelined); - break; - } - - return ret; -} - -/** - * i915_gem_clear_fence_reg - clear out fence register info - * @obj: object to clear - * - * Zeroes out the fence register itself and clears out the associated - * data structures in dev_priv and obj. - */ -static void -i915_gem_clear_fence_reg(struct drm_device *dev, - struct drm_i915_fence_reg *reg) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t fence_reg = reg - dev_priv->fence_regs; - - switch (INTEL_INFO(dev)->gen) { - case 7: - case 6: - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0); - break; - case 5: - case 4: - I915_WRITE64(FENCE_REG_965_0 + fence_reg*8, 0); - break; - case 3: - if (fence_reg >= 8) - fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; - else - case 2: - fence_reg = FENCE_REG_830_0 + fence_reg * 4; - - I915_WRITE(fence_reg, 0); - break; - } - - list_del_init(®->lru_list); - reg->obj = NULL; - reg->setup_seqno = 0; - reg->pin_count = 0; -} - -/** - * Finds free space in the GTT aperture and binds the object there. - */ -static int -i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, - unsigned alignment, - bool map_and_fenceable) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_mm_node *free_space; - gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; - u32 size, fence_size, fence_alignment, unfenced_alignment; - bool mappable, fenceable; - int ret; - - if (obj->madv != I915_MADV_WILLNEED) { - DRM_ERROR("Attempting to bind a purgeable object\n"); - return -EINVAL; - } - - fence_size = i915_gem_get_gtt_size(dev, - obj->base.size, - obj->tiling_mode); - fence_alignment = i915_gem_get_gtt_alignment(dev, - obj->base.size, - obj->tiling_mode); - unfenced_alignment = - i915_gem_get_unfenced_gtt_alignment(dev, - obj->base.size, - obj->tiling_mode); - - if (alignment == 0) - alignment = map_and_fenceable ? fence_alignment : - unfenced_alignment; - if (map_and_fenceable && alignment & (fence_alignment - 1)) { - DRM_ERROR("Invalid object alignment requested %u\n", alignment); - return -EINVAL; - } - - size = map_and_fenceable ? fence_size : obj->base.size; - - /* If the object is bigger than the entire aperture, reject it early - * before evicting everything in a vain attempt to find space. - */ - if (obj->base.size > - (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { - DRM_ERROR("Attempting to bind an object larger than the aperture\n"); - return -E2BIG; - } - - search_free: - if (map_and_fenceable) - free_space = - drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, - size, alignment, 0, - dev_priv->mm.gtt_mappable_end, - 0); - else - free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, - size, alignment, 0); - - if (free_space != NULL) { - if (map_and_fenceable) - obj->gtt_space = - drm_mm_get_block_range_generic(free_space, - size, alignment, 0, - dev_priv->mm.gtt_mappable_end, - 0); - else - obj->gtt_space = - drm_mm_get_block(free_space, size, alignment); - } - if (obj->gtt_space == NULL) { - /* If the gtt is empty and we're still having trouble - * fitting our object in, we're out of memory. - */ - ret = i915_gem_evict_something(dev, size, alignment, - map_and_fenceable); - if (ret) - return ret; - - goto search_free; - } - - ret = i915_gem_object_get_pages_gtt(obj, gfpmask); - if (ret) { - drm_mm_put_block(obj->gtt_space); - obj->gtt_space = NULL; - - if (ret == -ENOMEM) { - /* first try to reclaim some memory by clearing the GTT */ - ret = i915_gem_evict_everything(dev, false); - if (ret) { - /* now try to shrink everyone else */ - if (gfpmask) { - gfpmask = 0; - goto search_free; - } - - return -ENOMEM; - } - - goto search_free; - } - - return ret; - } - - ret = i915_gem_gtt_bind_object(obj); - if (ret) { - i915_gem_object_put_pages_gtt(obj); - drm_mm_put_block(obj->gtt_space); - obj->gtt_space = NULL; - - if (i915_gem_evict_everything(dev, false)) - return ret; - - goto search_free; - } - - list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); - list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - - /* Assert that the object is not currently in any GPU domain. As it - * wasn't in the GTT, there shouldn't be any way it could have been in - * a GPU cache - */ - BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); - BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); - - obj->gtt_offset = obj->gtt_space->start; - - fenceable = - obj->gtt_space->size == fence_size && - (obj->gtt_space->start & (fence_alignment - 1)) == 0; - - mappable = - obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; - - obj->map_and_fenceable = mappable && fenceable; - - trace_i915_gem_object_bind(obj, map_and_fenceable); - return 0; -} - -void -i915_gem_clflush_object(struct drm_i915_gem_object *obj) -{ - /* If we don't have a page list set up, then we're not pinned - * to GPU, and we can ignore the cache flush because it'll happen - * again at bind time. - */ - if (obj->pages == NULL) - return; - - /* If the GPU is snooping the contents of the CPU cache, - * we do not need to manually clear the CPU cache lines. However, - * the caches are only snooped when the render cache is - * flushed/invalidated. As we always have to emit invalidations - * and flushes when moving into and out of the RENDER domain, correct - * snooping behaviour occurs naturally as the result of our domain - * tracking. - */ - if (obj->cache_level != I915_CACHE_NONE) - return; - - trace_i915_gem_object_clflush(obj); - - drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); -} - -/** Flushes any GPU write domain for the object if it's dirty. */ -static int -i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj) -{ - if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) - return 0; - - /* Queue the GPU write cache flushing we need. */ - return i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain); -} - -/** Flushes the GTT write domain for the object if it's dirty. */ -static void -i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) -{ - uint32_t old_write_domain; - - if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) - return; - - /* No actual flushing is required for the GTT write domain. Writes - * to it immediately go to main memory as far as we know, so there's - * no chipset flush. It also doesn't land in render cache. - * - * However, we do have to enforce the order so that all writes through - * the GTT land before any writes to the device, such as updates to - * the GATT itself. - */ - wmb(); - - old_write_domain = obj->base.write_domain; - obj->base.write_domain = 0; - - trace_i915_gem_object_change_domain(obj, - obj->base.read_domains, - old_write_domain); -} - -/** Flushes the CPU write domain for the object if it's dirty. */ -static void -i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) -{ - uint32_t old_write_domain; - - if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) - return; - - i915_gem_clflush_object(obj); - intel_gtt_chipset_flush(); - old_write_domain = obj->base.write_domain; - obj->base.write_domain = 0; - - trace_i915_gem_object_change_domain(obj, - obj->base.read_domains, - old_write_domain); -} - -/** - * Moves a single object to the GTT read, and possibly write domain. - * - * This function returns when the move is complete, including waiting on - * flushes to occur. - */ -int -i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) -{ - uint32_t old_write_domain, old_read_domains; - int ret; - - /* Not valid to be called on unbound objects. */ - if (obj->gtt_space == NULL) - return -EINVAL; - - if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) - return 0; - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret) - return ret; - - if (obj->pending_gpu_write || write) { - ret = i915_gem_object_wait_rendering(obj); - if (ret) - return ret; - } - - i915_gem_object_flush_cpu_write_domain(obj); - - old_write_domain = obj->base.write_domain; - old_read_domains = obj->base.read_domains; - - /* It should now be out of any other write domains, and we can update - * the domain values for our changes. - */ - BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); - obj->base.read_domains |= I915_GEM_DOMAIN_GTT; - if (write) { - obj->base.read_domains = I915_GEM_DOMAIN_GTT; - obj->base.write_domain = I915_GEM_DOMAIN_GTT; - obj->dirty = 1; - } - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - old_write_domain); - - return 0; -} - -int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - if (obj->cache_level == cache_level) - return 0; - - if (obj->pin_count) { - DRM_DEBUG("can not change the cache level of pinned objects\n"); - return -EBUSY; - } - - if (obj->gtt_space) { - ret = i915_gem_object_finish_gpu(obj); - if (ret) - return ret; - - i915_gem_object_finish_gtt(obj); - - /* Before SandyBridge, you could not use tiling or fence - * registers with snooped memory, so relinquish any fences - * currently pointing to our region in the aperture. - */ - if (INTEL_INFO(obj->base.dev)->gen < 6) { - ret = i915_gem_object_put_fence(obj); - if (ret) - return ret; - } - - i915_gem_gtt_rebind_object(obj, cache_level); - if (obj->has_aliasing_ppgtt_mapping) - i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, - obj, cache_level); - } - - if (cache_level == I915_CACHE_NONE) { - u32 old_read_domains, old_write_domain; - - /* If we're coming from LLC cached, then we haven't - * actually been tracking whether the data is in the - * CPU cache or not, since we only allow one bit set - * in obj->write_domain and have been skipping the clflushes. - * Just set it to the CPU cache for now. - */ - WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU); - WARN_ON(obj->base.read_domains & ~I915_GEM_DOMAIN_CPU); - - old_read_domains = obj->base.read_domains; - old_write_domain = obj->base.write_domain; - - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - old_write_domain); - } - - obj->cache_level = cache_level; - return 0; -} - -/* - * Prepare buffer for display plane (scanout, cursors, etc). - * Can be called from an uninterruptible phase (modesetting) and allows - * any flushes to be pipelined (for pageflips). - * - * For the display plane, we want to be in the GTT but out of any write - * domains. So in many ways this looks like set_to_gtt_domain() apart from the - * ability to pipeline the waits, pinning and any additional subtleties - * that may differentiate the display plane from ordinary buffers. - */ -int -i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, - u32 alignment, - struct intel_ring_buffer *pipelined) -{ - u32 old_read_domains, old_write_domain; - int ret; - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret) - return ret; - - if (pipelined != obj->ring) { - ret = i915_gem_object_wait_rendering(obj); - if (ret == -ERESTARTSYS) - return ret; - } - - /* The display engine is not coherent with the LLC cache on gen6. As - * a result, we make sure that the pinning that is about to occur is - * done with uncached PTEs. This is lowest common denominator for all - * chipsets. - * - * However for gen6+, we could do better by using the GFDT bit instead - * of uncaching, which would allow us to flush all the LLC-cached data - * with that bit in the PTE to main memory with just one PIPE_CONTROL. - */ - ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE); - if (ret) - return ret; - - /* As the user may map the buffer once pinned in the display plane - * (e.g. libkms for the bootup splash), we have to ensure that we - * always use map_and_fenceable for all scanout buffers. - */ - ret = i915_gem_object_pin(obj, alignment, true); - if (ret) - return ret; - - i915_gem_object_flush_cpu_write_domain(obj); - - old_write_domain = obj->base.write_domain; - old_read_domains = obj->base.read_domains; - - /* It should now be out of any other write domains, and we can update - * the domain values for our changes. - */ - BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); - obj->base.read_domains |= I915_GEM_DOMAIN_GTT; - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - old_write_domain); - - return 0; -} - -int -i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) -{ - int ret; - - if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) - return 0; - - if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { - ret = i915_gem_flush_ring(obj->ring, 0, obj->base.write_domain); - if (ret) - return ret; - } - - ret = i915_gem_object_wait_rendering(obj); - if (ret) - return ret; - - /* Ensure that we invalidate the GPU's caches and TLBs. */ - obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; - return 0; -} - -/** - * Moves a single object to the CPU read, and possibly write domain. - * - * This function returns when the move is complete, including waiting on - * flushes to occur. - */ -static int -i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) -{ - uint32_t old_write_domain, old_read_domains; - int ret; - - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) - return 0; - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret) - return ret; - - ret = i915_gem_object_wait_rendering(obj); - if (ret) - return ret; - - i915_gem_object_flush_gtt_write_domain(obj); - - /* If we have a partially-valid cache of the object in the CPU, - * finish invalidating it and free the per-page flags. - */ - i915_gem_object_set_to_full_cpu_read_domain(obj); - - old_write_domain = obj->base.write_domain; - old_read_domains = obj->base.read_domains; - - /* Flush the CPU cache if it's still invalid. */ - if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { - i915_gem_clflush_object(obj); - - obj->base.read_domains |= I915_GEM_DOMAIN_CPU; - } - - /* It should now be out of any other write domains, and we can update - * the domain values for our changes. - */ - BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); - - /* If we're writing through the CPU, then the GPU read domains will - * need to be invalidated at next use. - */ - if (write) { - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - } - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - old_write_domain); - - return 0; -} - -/** - * Moves the object from a partially CPU read to a full one. - * - * Note that this only resolves i915_gem_object_set_cpu_read_domain_range(), - * and doesn't handle transitioning from !(read_domains & I915_GEM_DOMAIN_CPU). - */ -static void -i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj) -{ - if (!obj->page_cpu_valid) - return; - - /* If we're partially in the CPU read domain, finish moving it in. - */ - if (obj->base.read_domains & I915_GEM_DOMAIN_CPU) { - int i; - - for (i = 0; i <= (obj->base.size - 1) / PAGE_SIZE; i++) { - if (obj->page_cpu_valid[i]) - continue; - drm_clflush_pages(obj->pages + i, 1); - } - } - - /* Free the page_cpu_valid mappings which are now stale, whether - * or not we've got I915_GEM_DOMAIN_CPU. - */ - kfree(obj->page_cpu_valid); - obj->page_cpu_valid = NULL; -} - -/** - * Set the CPU read domain on a range of the object. - * - * The object ends up with I915_GEM_DOMAIN_CPU in its read flags although it's - * not entirely valid. The page_cpu_valid member of the object flags which - * pages have been flushed, and will be respected by - * i915_gem_object_set_to_cpu_domain() if it's called on to get a valid mapping - * of the whole object. - * - * This function returns when the move is complete, including waiting on - * flushes to occur. - */ -static int -i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, - uint64_t offset, uint64_t size) -{ - uint32_t old_read_domains; - int i, ret; - - if (offset == 0 && size == obj->base.size) - return i915_gem_object_set_to_cpu_domain(obj, 0); - - ret = i915_gem_object_flush_gpu_write_domain(obj); - if (ret) - return ret; - - ret = i915_gem_object_wait_rendering(obj); - if (ret) - return ret; - - i915_gem_object_flush_gtt_write_domain(obj); - - /* If we're already fully in the CPU read domain, we're done. */ - if (obj->page_cpu_valid == NULL && - (obj->base.read_domains & I915_GEM_DOMAIN_CPU) != 0) - return 0; - - /* Otherwise, create/clear the per-page CPU read domain flag if we're - * newly adding I915_GEM_DOMAIN_CPU - */ - if (obj->page_cpu_valid == NULL) { - obj->page_cpu_valid = kzalloc(obj->base.size / PAGE_SIZE, - GFP_KERNEL); - if (obj->page_cpu_valid == NULL) - return -ENOMEM; - } else if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) - memset(obj->page_cpu_valid, 0, obj->base.size / PAGE_SIZE); - - /* Flush the cache on any pages that are still invalid from the CPU's - * perspective. - */ - for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; - i++) { - if (obj->page_cpu_valid[i]) - continue; - - drm_clflush_pages(obj->pages + i, 1); - - obj->page_cpu_valid[i] = 1; - } - - /* It should now be out of any other write domains, and we can update - * the domain values for our changes. - */ - BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); - - old_read_domains = obj->base.read_domains; - obj->base.read_domains |= I915_GEM_DOMAIN_CPU; - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - obj->base.write_domain); - - return 0; -} - -/* Throttle our rendering by waiting until the ring has completed our requests - * emitted over 20 msec ago. - * - * Note that if we were to use the current jiffies each time around the loop, - * we wouldn't escape the function with any frames outstanding if the time to - * render a frame was over 20ms. - * - * This should get us reasonable parallelism between CPU and GPU but also - * relatively low latency when blocking on a particular request to finish. - */ -static int -i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_file_private *file_priv = file->driver_priv; - unsigned long recent_enough = jiffies - msecs_to_jiffies(20); - struct drm_i915_gem_request *request; - struct intel_ring_buffer *ring = NULL; - u32 seqno = 0; - int ret; - - if (atomic_read(&dev_priv->mm.wedged)) - return -EIO; - - spin_lock(&file_priv->mm.lock); - list_for_each_entry(request, &file_priv->mm.request_list, client_list) { - if (time_after_eq(request->emitted_jiffies, recent_enough)) - break; - - ring = request->ring; - seqno = request->seqno; - } - spin_unlock(&file_priv->mm.lock); - - if (seqno == 0) - return 0; - - ret = 0; - if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { - /* And wait for the seqno passing without holding any locks and - * causing extra latency for others. This is safe as the irq - * generation is designed to be run atomically and so is - * lockless. - */ - if (ring->irq_get(ring)) { - ret = wait_event_interruptible(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(ring), seqno) - || atomic_read(&dev_priv->mm.wedged)); - ring->irq_put(ring); - - if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) - ret = -EIO; - } else if (wait_for_atomic(i915_seqno_passed(ring->get_seqno(ring), - seqno) || - atomic_read(&dev_priv->mm.wedged), 3000)) { - ret = -EBUSY; - } - } - - if (ret == 0) - queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); - - return ret; -} - -int -i915_gem_object_pin(struct drm_i915_gem_object *obj, - uint32_t alignment, - bool map_and_fenceable) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); - WARN_ON(i915_verify_lists(dev)); - - if (obj->gtt_space != NULL) { - if ((alignment && obj->gtt_offset & (alignment - 1)) || - (map_and_fenceable && !obj->map_and_fenceable)) { - WARN(obj->pin_count, - "bo is already pinned with incorrect alignment:" - " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," - " obj->map_and_fenceable=%d\n", - obj->gtt_offset, alignment, - map_and_fenceable, - obj->map_and_fenceable); - ret = i915_gem_object_unbind(obj); - if (ret) - return ret; - } - } - - if (obj->gtt_space == NULL) { - ret = i915_gem_object_bind_to_gtt(obj, alignment, - map_and_fenceable); - if (ret) - return ret; - } - - if (obj->pin_count++ == 0) { - if (!obj->active) - list_move_tail(&obj->mm_list, - &dev_priv->mm.pinned_list); - } - obj->pin_mappable |= map_and_fenceable; - - WARN_ON(i915_verify_lists(dev)); - return 0; -} - -void -i915_gem_object_unpin(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - WARN_ON(i915_verify_lists(dev)); - BUG_ON(obj->pin_count == 0); - BUG_ON(obj->gtt_space == NULL); - - if (--obj->pin_count == 0) { - if (!obj->active) - list_move_tail(&obj->mm_list, - &dev_priv->mm.inactive_list); - obj->pin_mappable = false; - } - WARN_ON(i915_verify_lists(dev)); -} - -int -i915_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_pin *args = data; - struct drm_i915_gem_object *obj; - int ret; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (obj->madv != I915_MADV_WILLNEED) { - DRM_ERROR("Attempting to pin a purgeable buffer\n"); - ret = -EINVAL; - goto out; - } - - if (obj->pin_filp != NULL && obj->pin_filp != file) { - DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", - args->handle); - ret = -EINVAL; - goto out; - } - - obj->user_pin_count++; - obj->pin_filp = file; - if (obj->user_pin_count == 1) { - ret = i915_gem_object_pin(obj, args->alignment, true); - if (ret) - goto out; - } - - /* XXX - flush the CPU caches for pinned objects - * as the X server doesn't manage domains yet - */ - i915_gem_object_flush_cpu_write_domain(obj); - args->offset = obj->gtt_offset; -out: - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -int -i915_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_pin *args = data; - struct drm_i915_gem_object *obj; - int ret; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (obj->pin_filp != file) { - DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", - args->handle); - ret = -EINVAL; - goto out; - } - obj->user_pin_count--; - if (obj->user_pin_count == 0) { - obj->pin_filp = NULL; - i915_gem_object_unpin(obj); - } - -out: - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -int -i915_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_busy *args = data; - struct drm_i915_gem_object *obj; - int ret; - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - /* Count all active objects as busy, even if they are currently not used - * by the gpu. Users of this interface expect objects to eventually - * become non-busy without any further actions, therefore emit any - * necessary flushes here. - */ - args->busy = obj->active; - if (args->busy) { - /* Unconditionally flush objects, even when the gpu still uses this - * object. Userspace calling this function indicates that it wants to - * use this buffer rather sooner than later, so issuing the required - * flush earlier is beneficial. - */ - if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) { - ret = i915_gem_flush_ring(obj->ring, - 0, obj->base.write_domain); - } else if (obj->ring->outstanding_lazy_request == - obj->last_rendering_seqno) { - struct drm_i915_gem_request *request; - - /* This ring is not being cleared by active usage, - * so emit a request to do so. - */ - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request) { - ret = i915_add_request(obj->ring, NULL, request); - if (ret) - kfree(request); - } else - ret = -ENOMEM; - } - - /* Update the active list for the hardware's current position. - * Otherwise this only updates on a delayed timer or when irqs - * are actually unmasked, and our working set ends up being - * larger than required. - */ - i915_gem_retire_requests_ring(obj->ring); - - args->busy = obj->active; - } - - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -int -i915_gem_throttle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return i915_gem_ring_throttle(dev, file_priv); -} - -int -i915_gem_madvise_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_gem_madvise *args = data; - struct drm_i915_gem_object *obj; - int ret; - - switch (args->madv) { - case I915_MADV_DONTNEED: - case I915_MADV_WILLNEED: - break; - default: - return -EINVAL; - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - return ret; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle)); - if (&obj->base == NULL) { - ret = -ENOENT; - goto unlock; - } - - if (obj->pin_count) { - ret = -EINVAL; - goto out; - } - - if (obj->madv != __I915_MADV_PURGED) - obj->madv = args->madv; - - /* if the object is no longer bound, discard its backing storage */ - if (i915_gem_object_is_purgeable(obj) && - obj->gtt_space == NULL) - i915_gem_object_truncate(obj); - - args->retained = obj->madv != __I915_MADV_PURGED; - -out: - drm_gem_object_unreference(&obj->base); -unlock: - mutex_unlock(&dev->struct_mutex); - return ret; -} - -struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, - size_t size) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - struct address_space *mapping; - - obj = kzalloc(sizeof(*obj), GFP_KERNEL); - if (obj == NULL) - return NULL; - - if (drm_gem_object_init(dev, &obj->base, size) != 0) { - kfree(obj); - return NULL; - } - - mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); - - i915_gem_info_add_obj(dev_priv, size); - - obj->base.write_domain = I915_GEM_DOMAIN_CPU; - obj->base.read_domains = I915_GEM_DOMAIN_CPU; - - if (HAS_LLC(dev)) { - /* On some devices, we can have the GPU use the LLC (the CPU - * cache) for about a 10% performance improvement - * compared to uncached. Graphics requests other than - * display scanout are coherent with the CPU in - * accessing this cache. This means in this mode we - * don't need to clflush on the CPU side, and on the - * GPU side we only need to flush internal caches to - * get data visible to the CPU. - * - * However, we maintain the display planes as UC, and so - * need to rebind when first used as such. - */ - obj->cache_level = I915_CACHE_LLC; - } else - obj->cache_level = I915_CACHE_NONE; - - obj->base.driver_private = NULL; - obj->fence_reg = I915_FENCE_REG_NONE; - INIT_LIST_HEAD(&obj->mm_list); - INIT_LIST_HEAD(&obj->gtt_list); - INIT_LIST_HEAD(&obj->ring_list); - INIT_LIST_HEAD(&obj->exec_list); - INIT_LIST_HEAD(&obj->gpu_write_list); - obj->madv = I915_MADV_WILLNEED; - /* Avoid an unnecessary call to unbind on the first bind. */ - obj->map_and_fenceable = true; - - return obj; -} - -int i915_gem_init_object(struct drm_gem_object *obj) -{ - BUG(); - - return 0; -} - -static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - ret = i915_gem_object_unbind(obj); - if (ret == -ERESTARTSYS) { - list_move(&obj->mm_list, - &dev_priv->mm.deferred_free_list); - return; - } - - trace_i915_gem_object_destroy(obj); - - if (obj->base.map_list.map) - drm_gem_free_mmap_offset(&obj->base); - - drm_gem_object_release(&obj->base); - i915_gem_info_remove_obj(dev_priv, obj->base.size); - - kfree(obj->page_cpu_valid); - kfree(obj->bit_17); - kfree(obj); -} - -void i915_gem_free_object(struct drm_gem_object *gem_obj) -{ - struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); - struct drm_device *dev = obj->base.dev; - - while (obj->pin_count > 0) - i915_gem_object_unpin(obj); - - if (obj->phys_obj) - i915_gem_detach_phys_object(dev, obj); - - i915_gem_free_object_tail(obj); -} - -int -i915_gem_idle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - mutex_lock(&dev->struct_mutex); - - if (dev_priv->mm.suspended) { - mutex_unlock(&dev->struct_mutex); - return 0; - } - - ret = i915_gpu_idle(dev, true); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - - /* Under UMS, be paranoid and evict. */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = i915_gem_evict_inactive(dev, false); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - } - - i915_gem_reset_fences(dev); - - /* Hack! Don't let anybody do execbuf while we don't control the chip. - * We need to replace this with a semaphore, or something. - * And not confound mm.suspended! - */ - dev_priv->mm.suspended = 1; - del_timer_sync(&dev_priv->hangcheck_timer); - - i915_kernel_lost_context(dev); - i915_gem_cleanup_ringbuffer(dev); - - mutex_unlock(&dev->struct_mutex); - - /* Cancel the retire work handler, which should be idle now. */ - cancel_delayed_work_sync(&dev_priv->mm.retire_work); - - return 0; -} - -void i915_gem_init_swizzling(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen < 5 || - dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) - return; - - I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | - DISP_TILE_SURFACE_SWIZZLING); - - if (IS_GEN5(dev)) - return; - - I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); - if (IS_GEN6(dev)) - I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB)); - else - I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB)); -} - -void i915_gem_init_ppgtt(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t pd_offset; - struct intel_ring_buffer *ring; - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - uint32_t __iomem *pd_addr; - uint32_t pd_entry; - int i; - - if (!dev_priv->mm.aliasing_ppgtt) - return; - - - pd_addr = dev_priv->mm.gtt->gtt + ppgtt->pd_offset/sizeof(uint32_t); - for (i = 0; i < ppgtt->num_pd_entries; i++) { - dma_addr_t pt_addr; - - if (dev_priv->mm.gtt->needs_dmar) - pt_addr = ppgtt->pt_dma_addr[i]; - else - pt_addr = page_to_phys(ppgtt->pt_pages[i]); - - pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); - pd_entry |= GEN6_PDE_VALID; - - writel(pd_entry, pd_addr + i); - } - readl(pd_addr); - - pd_offset = ppgtt->pd_offset; - pd_offset /= 64; /* in cachelines, */ - pd_offset <<= 16; - - if (INTEL_INFO(dev)->gen == 6) { - uint32_t ecochk = I915_READ(GAM_ECOCHK); - I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | - ECOCHK_PPGTT_CACHE64B); - I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); - } else if (INTEL_INFO(dev)->gen >= 7) { - I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); - /* GFX_MODE is per-ring on gen7+ */ - } - - for (i = 0; i < I915_NUM_RINGS; i++) { - ring = &dev_priv->ring[i]; - - if (INTEL_INFO(dev)->gen >= 7) - I915_WRITE(RING_MODE_GEN7(ring), - GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); - - I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); - I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); - } -} - -int -i915_gem_init_hw(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - i915_gem_init_swizzling(dev); - - ret = intel_init_render_ring_buffer(dev); - if (ret) - return ret; - - if (HAS_BSD(dev)) { - ret = intel_init_bsd_ring_buffer(dev); - if (ret) - goto cleanup_render_ring; - } - - if (HAS_BLT(dev)) { - ret = intel_init_blt_ring_buffer(dev); - if (ret) - goto cleanup_bsd_ring; - } - - dev_priv->next_seqno = 1; - - i915_gem_init_ppgtt(dev); - - return 0; - -cleanup_bsd_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); -cleanup_render_ring: - intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); - return ret; -} - -void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i; - - for (i = 0; i < I915_NUM_RINGS; i++) - intel_cleanup_ring_buffer(&dev_priv->ring[i]); -} - -int -i915_gem_entervt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret, i; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - - if (atomic_read(&dev_priv->mm.wedged)) { - DRM_ERROR("Reenabling wedged hardware, good luck\n"); - atomic_set(&dev_priv->mm.wedged, 0); - } - - mutex_lock(&dev->struct_mutex); - dev_priv->mm.suspended = 0; - - ret = i915_gem_init_hw(dev); - if (ret != 0) { - mutex_unlock(&dev->struct_mutex); - return ret; - } - - BUG_ON(!list_empty(&dev_priv->mm.active_list)); - BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); - BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); - for (i = 0; i < I915_NUM_RINGS; i++) { - BUG_ON(!list_empty(&dev_priv->ring[i].active_list)); - BUG_ON(!list_empty(&dev_priv->ring[i].request_list)); - } - mutex_unlock(&dev->struct_mutex); - - ret = drm_irq_install(dev); - if (ret) - goto cleanup_ringbuffer; - - return 0; - -cleanup_ringbuffer: - mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); - dev_priv->mm.suspended = 1; - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -int -i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return 0; - - drm_irq_uninstall(dev); - return i915_gem_idle(dev); -} - -void -i915_gem_lastclose(struct drm_device *dev) -{ - int ret; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - ret = i915_gem_idle(dev); - if (ret) - DRM_ERROR("failed to idle hardware: %d\n", ret); -} - -static void -init_ring_lists(struct intel_ring_buffer *ring) -{ - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - INIT_LIST_HEAD(&ring->gpu_write_list); -} - -void -i915_gem_load(struct drm_device *dev) -{ - int i; - drm_i915_private_t *dev_priv = dev->dev_private; - - INIT_LIST_HEAD(&dev_priv->mm.active_list); - INIT_LIST_HEAD(&dev_priv->mm.flushing_list); - INIT_LIST_HEAD(&dev_priv->mm.inactive_list); - INIT_LIST_HEAD(&dev_priv->mm.pinned_list); - INIT_LIST_HEAD(&dev_priv->mm.fence_list); - INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); - INIT_LIST_HEAD(&dev_priv->mm.gtt_list); - for (i = 0; i < I915_NUM_RINGS; i++) - init_ring_lists(&dev_priv->ring[i]); - for (i = 0; i < I915_MAX_NUM_FENCES; i++) - INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); - INIT_DELAYED_WORK(&dev_priv->mm.retire_work, - i915_gem_retire_work_handler); - init_completion(&dev_priv->error_completion); - - /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ - if (IS_GEN3(dev)) { - u32 tmp = I915_READ(MI_ARB_STATE); - if (!(tmp & MI_ARB_C3_LP_WRITE_ENABLE)) { - /* arb state is a masked write, so set bit + bit in mask */ - tmp = MI_ARB_C3_LP_WRITE_ENABLE | (MI_ARB_C3_LP_WRITE_ENABLE << MI_ARB_MASK_SHIFT); - I915_WRITE(MI_ARB_STATE, tmp); - } - } - - dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; - - /* Old X drivers will take 0-2 for front, back, depth buffers */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - dev_priv->fence_reg_start = 3; - - if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - dev_priv->num_fence_regs = 16; - else - dev_priv->num_fence_regs = 8; - - /* Initialize fence registers to zero */ - for (i = 0; i < dev_priv->num_fence_regs; i++) { - i915_gem_clear_fence_reg(dev, &dev_priv->fence_regs[i]); - } - - i915_gem_detect_bit_6_swizzle(dev); - init_waitqueue_head(&dev_priv->pending_flip_queue); - - dev_priv->mm.interruptible = true; - - dev_priv->mm.inactive_shrinker.shrink = i915_gem_inactive_shrink; - dev_priv->mm.inactive_shrinker.seeks = DEFAULT_SEEKS; - register_shrinker(&dev_priv->mm.inactive_shrinker); -} - -/* - * Create a physically contiguous memory object for this object - * e.g. for cursor + overlay regs - */ -static int i915_gem_init_phys_object(struct drm_device *dev, - int id, int size, int align) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_phys_object *phys_obj; - int ret; - - if (dev_priv->mm.phys_objs[id - 1] || !size) - return 0; - - phys_obj = kzalloc(sizeof(struct drm_i915_gem_phys_object), GFP_KERNEL); - if (!phys_obj) - return -ENOMEM; - - phys_obj->id = id; - - phys_obj->handle = drm_pci_alloc(dev, size, align); - if (!phys_obj->handle) { - ret = -ENOMEM; - goto kfree_obj; - } -#ifdef CONFIG_X86 - set_memory_wc((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); -#endif - - dev_priv->mm.phys_objs[id - 1] = phys_obj; - - return 0; -kfree_obj: - kfree(phys_obj); - return ret; -} - -static void i915_gem_free_phys_object(struct drm_device *dev, int id) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_phys_object *phys_obj; - - if (!dev_priv->mm.phys_objs[id - 1]) - return; - - phys_obj = dev_priv->mm.phys_objs[id - 1]; - if (phys_obj->cur_obj) { - i915_gem_detach_phys_object(dev, phys_obj->cur_obj); - } - -#ifdef CONFIG_X86 - set_memory_wb((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); -#endif - drm_pci_free(dev, phys_obj->handle); - kfree(phys_obj); - dev_priv->mm.phys_objs[id - 1] = NULL; -} - -void i915_gem_free_all_phys_object(struct drm_device *dev) -{ - int i; - - for (i = I915_GEM_PHYS_CURSOR_0; i <= I915_MAX_PHYS_OBJECT; i++) - i915_gem_free_phys_object(dev, i); -} - -void i915_gem_detach_phys_object(struct drm_device *dev, - struct drm_i915_gem_object *obj) -{ - struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - char *vaddr; - int i; - int page_count; - - if (!obj->phys_obj) - return; - vaddr = obj->phys_obj->handle->vaddr; - - page_count = obj->base.size / PAGE_SIZE; - for (i = 0; i < page_count; i++) { - struct page *page = shmem_read_mapping_page(mapping, i); - if (!IS_ERR(page)) { - char *dst = kmap_atomic(page); - memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); - kunmap_atomic(dst); - - drm_clflush_pages(&page, 1); - - set_page_dirty(page); - mark_page_accessed(page); - page_cache_release(page); - } - } - intel_gtt_chipset_flush(); - - obj->phys_obj->cur_obj = NULL; - obj->phys_obj = NULL; -} - -int -i915_gem_attach_phys_object(struct drm_device *dev, - struct drm_i915_gem_object *obj, - int id, - int align) -{ - struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret = 0; - int page_count; - int i; - - if (id > I915_MAX_PHYS_OBJECT) - return -EINVAL; - - if (obj->phys_obj) { - if (obj->phys_obj->id == id) - return 0; - i915_gem_detach_phys_object(dev, obj); - } - - /* create a new object */ - if (!dev_priv->mm.phys_objs[id - 1]) { - ret = i915_gem_init_phys_object(dev, id, - obj->base.size, align); - if (ret) { - DRM_ERROR("failed to init phys object %d size: %zu\n", - id, obj->base.size); - return ret; - } - } - - /* bind to the object */ - obj->phys_obj = dev_priv->mm.phys_objs[id - 1]; - obj->phys_obj->cur_obj = obj; - - page_count = obj->base.size / PAGE_SIZE; - - for (i = 0; i < page_count; i++) { - struct page *page; - char *dst, *src; - - page = shmem_read_mapping_page(mapping, i); - if (IS_ERR(page)) - return PTR_ERR(page); - - src = kmap_atomic(page); - dst = obj->phys_obj->handle->vaddr + (i * PAGE_SIZE); - memcpy(dst, src, PAGE_SIZE); - kunmap_atomic(src); - - mark_page_accessed(page); - page_cache_release(page); - } - - return 0; -} - -static int -i915_gem_phys_pwrite(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) -{ - void *vaddr = obj->phys_obj->handle->vaddr + args->offset; - char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; - - if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { - unsigned long unwritten; - - /* The physical object once assigned is fixed for the lifetime - * of the obj, so we can safely drop the lock and continue - * to access vaddr. - */ - mutex_unlock(&dev->struct_mutex); - unwritten = copy_from_user(vaddr, user_data, args->size); - mutex_lock(&dev->struct_mutex); - if (unwritten) - return -EFAULT; - } - - intel_gtt_chipset_flush(); - return 0; -} - -void i915_gem_release(struct drm_device *dev, struct drm_file *file) -{ - struct drm_i915_file_private *file_priv = file->driver_priv; - - /* Clean up our request list when the client is going away, so that - * later retire_requests won't dereference our soon-to-be-gone - * file_priv. - */ - spin_lock(&file_priv->mm.lock); - while (!list_empty(&file_priv->mm.request_list)) { - struct drm_i915_gem_request *request; - - request = list_first_entry(&file_priv->mm.request_list, - struct drm_i915_gem_request, - client_list); - list_del(&request->client_list); - request->file_priv = NULL; - } - spin_unlock(&file_priv->mm.lock); -} - -static int -i915_gpu_is_active(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int lists_empty; - - lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list); - - return !lists_empty; -} - -static int -i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) -{ - struct drm_i915_private *dev_priv = - container_of(shrinker, - struct drm_i915_private, - mm.inactive_shrinker); - struct drm_device *dev = dev_priv->dev; - struct drm_i915_gem_object *obj, *next; - int nr_to_scan = sc->nr_to_scan; - int cnt; - - if (!mutex_trylock(&dev->struct_mutex)) - return 0; - - /* "fast-path" to count number of available objects */ - if (nr_to_scan == 0) { - cnt = 0; - list_for_each_entry(obj, - &dev_priv->mm.inactive_list, - mm_list) - cnt++; - mutex_unlock(&dev->struct_mutex); - return cnt / 100 * sysctl_vfs_cache_pressure; - } - -rescan: - /* first scan for clean buffers */ - i915_gem_retire_requests(dev); - - list_for_each_entry_safe(obj, next, - &dev_priv->mm.inactive_list, - mm_list) { - if (i915_gem_object_is_purgeable(obj)) { - if (i915_gem_object_unbind(obj) == 0 && - --nr_to_scan == 0) - break; - } - } - - /* second pass, evict/count anything still on the inactive list */ - cnt = 0; - list_for_each_entry_safe(obj, next, - &dev_priv->mm.inactive_list, - mm_list) { - if (nr_to_scan && - i915_gem_object_unbind(obj) == 0) - nr_to_scan--; - else - cnt++; - } - - if (nr_to_scan && i915_gpu_is_active(dev)) { - /* - * We are desperate for pages, so as a last resort, wait - * for the GPU to finish and discard whatever we can. - * This has a dramatic impact to reduce the number of - * OOM-killer events whilst running the GPU aggressively. - */ - if (i915_gpu_idle(dev, true) == 0) - goto rescan; - } - mutex_unlock(&dev->struct_mutex); - return cnt / 100 * sysctl_vfs_cache_pressure; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_debug.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_debug.c deleted file mode 100644 index cc93cac2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_debug.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Keith Packard - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -#if WATCH_LISTS -int -i915_verify_lists(struct drm_device *dev) -{ - static int warned; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int err = 0; - - if (warned) - return 0; - - list_for_each_entry(obj, &dev_priv->render_ring.active_list, list) { - if (obj->base.dev != dev || - !atomic_read(&obj->base.refcount.refcount)) { - DRM_ERROR("freed render active %p\n", obj); - err++; - break; - } else if (!obj->active || - (obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0) { - DRM_ERROR("invalid render active %p (a %d r %x)\n", - obj, - obj->active, - obj->base.read_domains); - err++; - } else if (obj->base.write_domain && list_empty(&obj->gpu_write_list)) { - DRM_ERROR("invalid render active %p (w %x, gwl %d)\n", - obj, - obj->base.write_domain, - !list_empty(&obj->gpu_write_list)); - err++; - } - } - - list_for_each_entry(obj, &dev_priv->mm.flushing_list, list) { - if (obj->base.dev != dev || - !atomic_read(&obj->base.refcount.refcount)) { - DRM_ERROR("freed flushing %p\n", obj); - err++; - break; - } else if (!obj->active || - (obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0 || - list_empty(&obj->gpu_write_list)) { - DRM_ERROR("invalid flushing %p (a %d w %x gwl %d)\n", - obj, - obj->active, - obj->base.write_domain, - !list_empty(&obj->gpu_write_list)); - err++; - } - } - - list_for_each_entry(obj, &dev_priv->mm.gpu_write_list, gpu_write_list) { - if (obj->base.dev != dev || - !atomic_read(&obj->base.refcount.refcount)) { - DRM_ERROR("freed gpu write %p\n", obj); - err++; - break; - } else if (!obj->active || - (obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) { - DRM_ERROR("invalid gpu write %p (a %d w %x)\n", - obj, - obj->active, - obj->base.write_domain); - err++; - } - } - - list_for_each_entry(obj, &dev_priv->mm.inactive_list, list) { - if (obj->base.dev != dev || - !atomic_read(&obj->base.refcount.refcount)) { - DRM_ERROR("freed inactive %p\n", obj); - err++; - break; - } else if (obj->pin_count || obj->active || - (obj->base.write_domain & I915_GEM_GPU_DOMAINS)) { - DRM_ERROR("invalid inactive %p (p %d a %d w %x)\n", - obj, - obj->pin_count, obj->active, - obj->base.write_domain); - err++; - } - } - - list_for_each_entry(obj, &dev_priv->mm.pinned_list, list) { - if (obj->base.dev != dev || - !atomic_read(&obj->base.refcount.refcount)) { - DRM_ERROR("freed pinned %p\n", obj); - err++; - break; - } else if (!obj->pin_count || obj->active || - (obj->base.write_domain & I915_GEM_GPU_DOMAINS)) { - DRM_ERROR("invalid pinned %p (p %d a %d w %x)\n", - obj, - obj->pin_count, obj->active, - obj->base.write_domain); - err++; - } - } - - return warned = err; -} -#endif /* WATCH_INACTIVE */ - -#if WATCH_COHERENCY -void -i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle) -{ - struct drm_device *dev = obj->base.dev; - int page; - uint32_t *gtt_mapping; - uint32_t *backing_map = NULL; - int bad_count = 0; - - DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", - __func__, obj, obj->gtt_offset, handle, - obj->size / 1024); - - gtt_mapping = ioremap(dev->agp->base + obj->gtt_offset, obj->base.size); - if (gtt_mapping == NULL) { - DRM_ERROR("failed to map GTT space\n"); - return; - } - - for (page = 0; page < obj->size / PAGE_SIZE; page++) { - int i; - - backing_map = kmap_atomic(obj->pages[page]); - - if (backing_map == NULL) { - DRM_ERROR("failed to map backing page\n"); - goto out; - } - - for (i = 0; i < PAGE_SIZE / 4; i++) { - uint32_t cpuval = backing_map[i]; - uint32_t gttval = readl(gtt_mapping + - page * 1024 + i); - - if (cpuval != gttval) { - DRM_INFO("incoherent CPU vs GPU at 0x%08x: " - "0x%08x vs 0x%08x\n", - (int)(obj->gtt_offset + - page * PAGE_SIZE + i * 4), - cpuval, gttval); - if (bad_count++ >= 8) { - DRM_INFO("...\n"); - goto out; - } - } - } - kunmap_atomic(backing_map); - backing_map = NULL; - } - - out: - if (backing_map != NULL) - kunmap_atomic(backing_map); - iounmap(gtt_mapping); - - /* give syslog time to catch up */ - msleep(1); - - /* Directly flush the object, since we just loaded values with the CPU - * from the backing pages and we don't want to disturb the cache - * management that we're trying to observe. - */ - - i915_gem_clflush_object(obj); -} -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_evict.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_evict.c deleted file mode 100644 index 21a82710..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_evict.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright © 2008-2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Chris Wilson - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drv.h" -#include "i915_drm.h" -#include "i915_trace.h" - -static bool -mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) -{ - list_add(&obj->exec_list, unwind); - return drm_mm_scan_add_block(obj->gtt_space); -} - -int -i915_gem_evict_something(struct drm_device *dev, int min_size, - unsigned alignment, bool mappable) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct list_head eviction_list, unwind_list; - struct drm_i915_gem_object *obj; - int ret = 0; - - trace_i915_gem_evict(dev, min_size, alignment, mappable); - - /* - * The goal is to evict objects and amalgamate space in LRU order. - * The oldest idle objects reside on the inactive list, which is in - * retirement order. The next objects to retire are those on the (per - * ring) active list that do not have an outstanding flush. Once the - * hardware reports completion (the seqno is updated after the - * batchbuffer has been finished) the clean buffer objects would - * be retired to the inactive list. Any dirty objects would be added - * to the tail of the flushing list. So after processing the clean - * active objects we need to emit a MI_FLUSH to retire the flushing - * list, hence the retirement order of the flushing list is in - * advance of the dirty objects on the active lists. - * - * The retirement sequence is thus: - * 1. Inactive objects (already retired) - * 2. Clean active objects - * 3. Flushing list - * 4. Dirty active objects. - * - * On each list, the oldest objects lie at the HEAD with the freshest - * object on the TAIL. - */ - - INIT_LIST_HEAD(&unwind_list); - if (mappable) - drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size, - alignment, 0, - dev_priv->mm.gtt_mappable_end); - else - drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); - - /* First see if there is a large enough contiguous idle region... */ - list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { - if (mark_free(obj, &unwind_list)) - goto found; - } - - /* Now merge in the soon-to-be-expired objects... */ - list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { - /* Does the object require an outstanding flush? */ - if (obj->base.write_domain || obj->pin_count) - continue; - - if (mark_free(obj, &unwind_list)) - goto found; - } - - /* Finally add anything with a pending flush (in order of retirement) */ - list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) { - if (obj->pin_count) - continue; - - if (mark_free(obj, &unwind_list)) - goto found; - } - list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { - if (!obj->base.write_domain || obj->pin_count) - continue; - - if (mark_free(obj, &unwind_list)) - goto found; - } - - /* Nothing found, clean up and bail out! */ - while (!list_empty(&unwind_list)) { - obj = list_first_entry(&unwind_list, - struct drm_i915_gem_object, - exec_list); - - ret = drm_mm_scan_remove_block(obj->gtt_space); - BUG_ON(ret); - - list_del_init(&obj->exec_list); - } - - /* We expect the caller to unpin, evict all and try again, or give up. - * So calling i915_gem_evict_everything() is unnecessary. - */ - return -ENOSPC; - -found: - /* drm_mm doesn't allow any other other operations while - * scanning, therefore store to be evicted objects on a - * temporary list. */ - INIT_LIST_HEAD(&eviction_list); - while (!list_empty(&unwind_list)) { - obj = list_first_entry(&unwind_list, - struct drm_i915_gem_object, - exec_list); - if (drm_mm_scan_remove_block(obj->gtt_space)) { - list_move(&obj->exec_list, &eviction_list); - drm_gem_object_reference(&obj->base); - continue; - } - list_del_init(&obj->exec_list); - } - - /* Unbinding will emit any required flushes */ - while (!list_empty(&eviction_list)) { - obj = list_first_entry(&eviction_list, - struct drm_i915_gem_object, - exec_list); - if (ret == 0) - ret = i915_gem_object_unbind(obj); - - list_del_init(&obj->exec_list); - drm_gem_object_unreference(&obj->base); - } - - return ret; -} - -int -i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - bool lists_empty; - - lists_empty = (list_empty(&dev_priv->mm.inactive_list) && - list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); - if (lists_empty) - return -ENOSPC; - - trace_i915_gem_evict_everything(dev, purgeable_only); - - /* Flush everything (on to the inactive lists) and evict */ - ret = i915_gpu_idle(dev, true); - if (ret) - return ret; - - BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); - - return i915_gem_evict_inactive(dev, purgeable_only); -} - -/** Unbinds all inactive objects. */ -int -i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj, *next; - - list_for_each_entry_safe(obj, next, - &dev_priv->mm.inactive_list, mm_list) { - if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) { - int ret = i915_gem_object_unbind(obj); - if (ret) - return ret; - } - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_execbuffer.c deleted file mode 100644 index de431942..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ /dev/null @@ -1,1456 +0,0 @@ -/* - * Copyright © 2008,2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Chris Wilson - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_trace.h" -#include "intel_drv.h" -#include - -struct change_domains { - uint32_t invalidate_domains; - uint32_t flush_domains; - uint32_t flush_rings; - uint32_t flips; -}; - -/* - * Set the next domain for the specified object. This - * may not actually perform the necessary flushing/invaliding though, - * as that may want to be batched with other set_domain operations - * - * This is (we hope) the only really tricky part of gem. The goal - * is fairly simple -- track which caches hold bits of the object - * and make sure they remain coherent. A few concrete examples may - * help to explain how it works. For shorthand, we use the notation - * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the - * a pair of read and write domain masks. - * - * Case 1: the batch buffer - * - * 1. Allocated - * 2. Written by CPU - * 3. Mapped to GTT - * 4. Read by GPU - * 5. Unmapped from GTT - * 6. Freed - * - * Let's take these a step at a time - * - * 1. Allocated - * Pages allocated from the kernel may still have - * cache contents, so we set them to (CPU, CPU) always. - * 2. Written by CPU (using pwrite) - * The pwrite function calls set_domain (CPU, CPU) and - * this function does nothing (as nothing changes) - * 3. Mapped by GTT - * This function asserts that the object is not - * currently in any GPU-based read or write domains - * 4. Read by GPU - * i915_gem_execbuffer calls set_domain (COMMAND, 0). - * As write_domain is zero, this function adds in the - * current read domains (CPU+COMMAND, 0). - * flush_domains is set to CPU. - * invalidate_domains is set to COMMAND - * clflush is run to get data out of the CPU caches - * then i915_dev_set_domain calls i915_gem_flush to - * emit an MI_FLUSH and drm_agp_chipset_flush - * 5. Unmapped from GTT - * i915_gem_object_unbind calls set_domain (CPU, CPU) - * flush_domains and invalidate_domains end up both zero - * so no flushing/invalidating happens - * 6. Freed - * yay, done - * - * Case 2: The shared render buffer - * - * 1. Allocated - * 2. Mapped to GTT - * 3. Read/written by GPU - * 4. set_domain to (CPU,CPU) - * 5. Read/written by CPU - * 6. Read/written by GPU - * - * 1. Allocated - * Same as last example, (CPU, CPU) - * 2. Mapped to GTT - * Nothing changes (assertions find that it is not in the GPU) - * 3. Read/written by GPU - * execbuffer calls set_domain (RENDER, RENDER) - * flush_domains gets CPU - * invalidate_domains gets GPU - * clflush (obj) - * MI_FLUSH and drm_agp_chipset_flush - * 4. set_domain (CPU, CPU) - * flush_domains gets GPU - * invalidate_domains gets CPU - * wait_rendering (obj) to make sure all drawing is complete. - * This will include an MI_FLUSH to get the data from GPU - * to memory - * clflush (obj) to invalidate the CPU cache - * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) - * 5. Read/written by CPU - * cache lines are loaded and dirtied - * 6. Read written by GPU - * Same as last GPU access - * - * Case 3: The constant buffer - * - * 1. Allocated - * 2. Written by CPU - * 3. Read by GPU - * 4. Updated (written) by CPU again - * 5. Read by GPU - * - * 1. Allocated - * (CPU, CPU) - * 2. Written by CPU - * (CPU, CPU) - * 3. Read by GPU - * (CPU+RENDER, 0) - * flush_domains = CPU - * invalidate_domains = RENDER - * clflush (obj) - * MI_FLUSH - * drm_agp_chipset_flush - * 4. Updated (written) by CPU again - * (CPU, CPU) - * flush_domains = 0 (no previous write domain) - * invalidate_domains = 0 (no new read domains) - * 5. Read by GPU - * (CPU+RENDER, 0) - * flush_domains = CPU - * invalidate_domains = RENDER - * clflush (obj) - * MI_FLUSH - * drm_agp_chipset_flush - */ -static void -i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring, - struct change_domains *cd) -{ - uint32_t invalidate_domains = 0, flush_domains = 0; - - /* - * If the object isn't moving to a new write domain, - * let the object stay in multiple read domains - */ - if (obj->base.pending_write_domain == 0) - obj->base.pending_read_domains |= obj->base.read_domains; - - /* - * Flush the current write domain if - * the new read domains don't match. Invalidate - * any read domains which differ from the old - * write domain - */ - if (obj->base.write_domain && - (((obj->base.write_domain != obj->base.pending_read_domains || - obj->ring != ring)) || - (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) { - flush_domains |= obj->base.write_domain; - invalidate_domains |= - obj->base.pending_read_domains & ~obj->base.write_domain; - } - /* - * Invalidate any read caches which may have - * stale data. That is, any new read domains. - */ - invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains; - if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) - i915_gem_clflush_object(obj); - - if (obj->base.pending_write_domain) - cd->flips |= atomic_read(&obj->pending_flip); - - /* The actual obj->write_domain will be updated with - * pending_write_domain after we emit the accumulated flush for all - * of our domain changes in execbuffers (which clears objects' - * write_domains). So if we have a current write domain that we - * aren't changing, set pending_write_domain to that. - */ - if (flush_domains == 0 && obj->base.pending_write_domain == 0) - obj->base.pending_write_domain = obj->base.write_domain; - - cd->invalidate_domains |= invalidate_domains; - cd->flush_domains |= flush_domains; - if (flush_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= intel_ring_flag(obj->ring); - if (invalidate_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= intel_ring_flag(ring); -} - -struct eb_objects { - int and; - struct hlist_head buckets[0]; -}; - -static struct eb_objects * -eb_create(int size) -{ - struct eb_objects *eb; - int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; - while (count > size) - count >>= 1; - eb = kzalloc(count*sizeof(struct hlist_head) + - sizeof(struct eb_objects), - GFP_KERNEL); - if (eb == NULL) - return eb; - - eb->and = count - 1; - return eb; -} - -static void -eb_reset(struct eb_objects *eb) -{ - memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); -} - -static void -eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj) -{ - hlist_add_head(&obj->exec_node, - &eb->buckets[obj->exec_handle & eb->and]); -} - -static struct drm_i915_gem_object * -eb_get_object(struct eb_objects *eb, unsigned long handle) -{ - struct hlist_head *head; - struct hlist_node *node; - struct drm_i915_gem_object *obj; - - head = &eb->buckets[handle & eb->and]; - hlist_for_each(node, head) { - obj = hlist_entry(node, struct drm_i915_gem_object, exec_node); - if (obj->exec_handle == handle) - return obj; - } - - return NULL; -} - -static void -eb_destroy(struct eb_objects *eb) -{ - kfree(eb); -} - -static int -i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, - struct eb_objects *eb, - struct drm_i915_gem_relocation_entry *reloc) -{ - struct drm_device *dev = obj->base.dev; - struct drm_gem_object *target_obj; - uint32_t target_offset; - int ret = -EINVAL; - - /* we've already hold a reference to all valid objects */ - target_obj = &eb_get_object(eb, reloc->target_handle)->base; - if (unlikely(target_obj == NULL)) - return -ENOENT; - - target_offset = to_intel_bo(target_obj)->gtt_offset; - - /* The target buffer should have appeared before us in the - * exec_object list, so it should have a GTT space bound by now. - */ - if (unlikely(target_offset == 0)) { - DRM_DEBUG("No GTT space found for object %d\n", - reloc->target_handle); - return ret; - } - - /* Validate that the target is in a valid r/w GPU domain */ - if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { - DRM_DEBUG("reloc with multiple write domains: " - "obj %p target %d offset %d " - "read %08x write %08x", - obj, reloc->target_handle, - (int) reloc->offset, - reloc->read_domains, - reloc->write_domain); - return ret; - } - if (unlikely((reloc->write_domain | reloc->read_domains) - & ~I915_GEM_GPU_DOMAINS)) { - DRM_DEBUG("reloc with read/write non-GPU domains: " - "obj %p target %d offset %d " - "read %08x write %08x", - obj, reloc->target_handle, - (int) reloc->offset, - reloc->read_domains, - reloc->write_domain); - return ret; - } - if (unlikely(reloc->write_domain && target_obj->pending_write_domain && - reloc->write_domain != target_obj->pending_write_domain)) { - DRM_DEBUG("Write domain conflict: " - "obj %p target %d offset %d " - "new %08x old %08x\n", - obj, reloc->target_handle, - (int) reloc->offset, - reloc->write_domain, - target_obj->pending_write_domain); - return ret; - } - - target_obj->pending_read_domains |= reloc->read_domains; - target_obj->pending_write_domain |= reloc->write_domain; - - /* If the relocation already has the right value in it, no - * more work needs to be done. - */ - if (target_offset == reloc->presumed_offset) - return 0; - - /* Check that the relocation address is valid... */ - if (unlikely(reloc->offset > obj->base.size - 4)) { - DRM_DEBUG("Relocation beyond object bounds: " - "obj %p target %d offset %d size %d.\n", - obj, reloc->target_handle, - (int) reloc->offset, - (int) obj->base.size); - return ret; - } - if (unlikely(reloc->offset & 3)) { - DRM_DEBUG("Relocation not 4-byte aligned: " - "obj %p target %d offset %d.\n", - obj, reloc->target_handle, - (int) reloc->offset); - return ret; - } - - reloc->delta += target_offset; - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { - uint32_t page_offset = reloc->offset & ~PAGE_MASK; - char *vaddr; - - vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]); - *(uint32_t *)(vaddr + page_offset) = reloc->delta; - kunmap_atomic(vaddr); - } else { - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t __iomem *reloc_entry; - void __iomem *reloc_page; - - /* We can't wait for rendering with pagefaults disabled */ - if (obj->active && in_atomic()) - return -EFAULT; - - ret = i915_gem_object_set_to_gtt_domain(obj, 1); - if (ret) - return ret; - - /* Map the page containing the relocation we're going to perform. */ - reloc->offset += obj->gtt_offset; - reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - reloc->offset & PAGE_MASK); - reloc_entry = (uint32_t __iomem *) - (reloc_page + (reloc->offset & ~PAGE_MASK)); - iowrite32(reloc->delta, reloc_entry); - io_mapping_unmap_atomic(reloc_page); - } - - /* and update the user's relocation entry */ - reloc->presumed_offset = target_offset; - - return 0; -} - -static int -i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, - struct eb_objects *eb) -{ - struct drm_i915_gem_relocation_entry __user *user_relocs; - struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; - int i, ret; - - user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; - for (i = 0; i < entry->relocation_count; i++) { - struct drm_i915_gem_relocation_entry reloc; - - if (__copy_from_user_inatomic(&reloc, - user_relocs+i, - sizeof(reloc))) - return -EFAULT; - - ret = i915_gem_execbuffer_relocate_entry(obj, eb, &reloc); - if (ret) - return ret; - - if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset, - &reloc.presumed_offset, - sizeof(reloc.presumed_offset))) - return -EFAULT; - } - - return 0; -} - -static int -i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, - struct eb_objects *eb, - struct drm_i915_gem_relocation_entry *relocs) -{ - const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; - int i, ret; - - for (i = 0; i < entry->relocation_count; i++) { - ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i]); - if (ret) - return ret; - } - - return 0; -} - -static int -i915_gem_execbuffer_relocate(struct drm_device *dev, - struct eb_objects *eb, - struct list_head *objects) -{ - struct drm_i915_gem_object *obj; - int ret = 0; - - /* This is the fast path and we cannot handle a pagefault whilst - * holding the struct mutex lest the user pass in the relocations - * contained within a mmaped bo. For in such a case we, the page - * fault handler would call i915_gem_fault() and we would try to - * acquire the struct mutex again. Obviously this is bad and so - * lockdep complains vehemently. - */ - pagefault_disable(); - list_for_each_entry(obj, objects, exec_list) { - ret = i915_gem_execbuffer_relocate_object(obj, eb); - if (ret) - break; - } - pagefault_enable(); - - return ret; -} - -#define __EXEC_OBJECT_HAS_FENCE (1<<31) - -static int -pin_and_fence_object(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring) -{ - struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; - bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; - bool need_fence, need_mappable; - int ret; - - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - need_mappable = - entry->relocation_count ? true : need_fence; - - ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); - if (ret) - return ret; - - if (has_fenced_gpu_access) { - if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { - if (obj->tiling_mode) { - ret = i915_gem_object_get_fence(obj, ring); - if (ret) - goto err_unpin; - - entry->flags |= __EXEC_OBJECT_HAS_FENCE; - i915_gem_object_pin_fence(obj); - } else { - ret = i915_gem_object_put_fence(obj); - if (ret) - goto err_unpin; - } - obj->pending_fenced_gpu_access = true; - } - } - - entry->offset = obj->gtt_offset; - return 0; - -err_unpin: - i915_gem_object_unpin(obj); - return ret; -} - -static int -i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, - struct drm_file *file, - struct list_head *objects) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - struct drm_i915_gem_object *obj; - int ret, retry; - bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; - struct list_head ordered_objects; - - INIT_LIST_HEAD(&ordered_objects); - while (!list_empty(objects)) { - struct drm_i915_gem_exec_object2 *entry; - bool need_fence, need_mappable; - - obj = list_first_entry(objects, - struct drm_i915_gem_object, - exec_list); - entry = obj->exec_entry; - - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - need_mappable = - entry->relocation_count ? true : need_fence; - - if (need_mappable) - list_move(&obj->exec_list, &ordered_objects); - else - list_move_tail(&obj->exec_list, &ordered_objects); - - obj->base.pending_read_domains = 0; - obj->base.pending_write_domain = 0; - } - list_splice(&ordered_objects, objects); - - /* Attempt to pin all of the buffers into the GTT. - * This is done in 3 phases: - * - * 1a. Unbind all objects that do not match the GTT constraints for - * the execbuffer (fenceable, mappable, alignment etc). - * 1b. Increment pin count for already bound objects. - * 2. Bind new objects. - * 3. Decrement pin count. - * - * This avoid unnecessary unbinding of later objects in order to makr - * room for the earlier objects *unless* we need to defragment. - */ - retry = 0; - do { - ret = 0; - - /* Unbind any ill-fitting objects or pin. */ - list_for_each_entry(obj, objects, exec_list) { - struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; - bool need_fence, need_mappable; - - if (!obj->gtt_space) - continue; - - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - need_mappable = - entry->relocation_count ? true : need_fence; - - if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) || - (need_mappable && !obj->map_and_fenceable)) - ret = i915_gem_object_unbind(obj); - else - ret = pin_and_fence_object(obj, ring); - if (ret) - goto err; - } - - /* Bind fresh objects */ - list_for_each_entry(obj, objects, exec_list) { - if (obj->gtt_space) - continue; - - ret = pin_and_fence_object(obj, ring); - if (ret) { - int ret_ignore; - - /* This can potentially raise a harmless - * -EINVAL if we failed to bind in the above - * call. It cannot raise -EINTR since we know - * that the bo is freshly bound and so will - * not need to be flushed or waited upon. - */ - ret_ignore = i915_gem_object_unbind(obj); - (void)ret_ignore; - WARN_ON(obj->gtt_space); - break; - } - } - - /* Decrement pin count for bound objects */ - list_for_each_entry(obj, objects, exec_list) { - struct drm_i915_gem_exec_object2 *entry; - - if (!obj->gtt_space) - continue; - - entry = obj->exec_entry; - if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { - i915_gem_object_unpin_fence(obj); - entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; - } - - i915_gem_object_unpin(obj); - - /* ... and ensure ppgtt mapping exist if needed. */ - if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) { - i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, - obj, obj->cache_level); - - obj->has_aliasing_ppgtt_mapping = 1; - } - } - - if (ret != -ENOSPC || retry > 1) - return ret; - - /* First attempt, just clear anything that is purgeable. - * Second attempt, clear the entire GTT. - */ - ret = i915_gem_evict_everything(ring->dev, retry == 0); - if (ret) - return ret; - - retry++; - } while (1); - -err: - list_for_each_entry_continue_reverse(obj, objects, exec_list) { - struct drm_i915_gem_exec_object2 *entry; - - if (!obj->gtt_space) - continue; - - entry = obj->exec_entry; - if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { - i915_gem_object_unpin_fence(obj); - entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; - } - - i915_gem_object_unpin(obj); - } - - return ret; -} - -static int -i915_gem_execbuffer_relocate_slow(struct drm_device *dev, - struct drm_file *file, - struct intel_ring_buffer *ring, - struct list_head *objects, - struct eb_objects *eb, - struct drm_i915_gem_exec_object2 *exec, - int count) -{ - struct drm_i915_gem_relocation_entry *reloc; - struct drm_i915_gem_object *obj; - int *reloc_offset; - int i, total, ret; - - /* We may process another execbuffer during the unlock... */ - while (!list_empty(objects)) { - obj = list_first_entry(objects, - struct drm_i915_gem_object, - exec_list); - list_del_init(&obj->exec_list); - drm_gem_object_unreference(&obj->base); - } - - mutex_unlock(&dev->struct_mutex); - - total = 0; - for (i = 0; i < count; i++) - total += exec[i].relocation_count; - - reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset)); - reloc = drm_malloc_ab(total, sizeof(*reloc)); - if (reloc == NULL || reloc_offset == NULL) { - drm_free_large(reloc); - drm_free_large(reloc_offset); - mutex_lock(&dev->struct_mutex); - return -ENOMEM; - } - - total = 0; - for (i = 0; i < count; i++) { - struct drm_i915_gem_relocation_entry __user *user_relocs; - - user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr; - - if (copy_from_user(reloc+total, user_relocs, - exec[i].relocation_count * sizeof(*reloc))) { - ret = -EFAULT; - mutex_lock(&dev->struct_mutex); - goto err; - } - - reloc_offset[i] = total; - total += exec[i].relocation_count; - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret) { - mutex_lock(&dev->struct_mutex); - goto err; - } - - /* reacquire the objects */ - eb_reset(eb); - for (i = 0; i < count; i++) { - obj = to_intel_bo(drm_gem_object_lookup(dev, file, - exec[i].handle)); - if (&obj->base == NULL) { - DRM_DEBUG("Invalid object handle %d at index %d\n", - exec[i].handle, i); - ret = -ENOENT; - goto err; - } - - list_add_tail(&obj->exec_list, objects); - obj->exec_handle = exec[i].handle; - obj->exec_entry = &exec[i]; - eb_add_object(eb, obj); - } - - ret = i915_gem_execbuffer_reserve(ring, file, objects); - if (ret) - goto err; - - list_for_each_entry(obj, objects, exec_list) { - int offset = obj->exec_entry - exec; - ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, - reloc + reloc_offset[offset]); - if (ret) - goto err; - } - - /* Leave the user relocations as are, this is the painfully slow path, - * and we want to avoid the complication of dropping the lock whilst - * having buffers reserved in the aperture and so causing spurious - * ENOSPC for random operations. - */ - -err: - drm_free_large(reloc); - drm_free_large(reloc_offset); - return ret; -} - -static int -i915_gem_execbuffer_flush(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains, - uint32_t flush_rings) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int i, ret; - - if (flush_domains & I915_GEM_DOMAIN_CPU) - intel_gtt_chipset_flush(); - - if (flush_domains & I915_GEM_DOMAIN_GTT) - wmb(); - - if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { - for (i = 0; i < I915_NUM_RINGS; i++) - if (flush_rings & (1 << i)) { - ret = i915_gem_flush_ring(&dev_priv->ring[i], - invalidate_domains, - flush_domains); - if (ret) - return ret; - } - } - - return 0; -} - -static bool -intel_enable_semaphores(struct drm_device *dev) -{ - if (INTEL_INFO(dev)->gen < 6) - return 0; - - if (i915_semaphores >= 0) - return i915_semaphores; - - /* Disable semaphores on SNB */ - if (INTEL_INFO(dev)->gen == 6) - return 0; - - return 1; -} - -static int -i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *to) -{ - struct intel_ring_buffer *from = obj->ring; - u32 seqno; - int ret, idx; - - if (from == NULL || to == from) - return 0; - - /* XXX gpu semaphores are implicated in various hard hangs on SNB */ - if (!intel_enable_semaphores(obj->base.dev)) - return i915_gem_object_wait_rendering(obj); - - idx = intel_ring_sync_index(from, to); - - seqno = obj->last_rendering_seqno; - if (seqno <= from->sync_seqno[idx]) - return 0; - - if (seqno == from->outstanding_lazy_request) { - struct drm_i915_gem_request *request; - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - ret = i915_add_request(from, NULL, request); - if (ret) { - kfree(request); - return ret; - } - - seqno = request->seqno; - } - - from->sync_seqno[idx] = seqno; - - return to->sync_to(to, from, seqno - 1); -} - -static int -i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, u32 flips) -{ - u32 plane, flip_mask; - int ret; - - /* Check for any pending flips. As we only maintain a flip queue depth - * of 1, we can simply insert a WAIT for the next display flip prior - * to executing the batch and avoid stalling the CPU. - */ - - for (plane = 0; flips >> plane; plane++) { - if (((flips >> plane) & 1) == 0) - continue; - - if (plane) - flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; - else - flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - } - - return 0; -} - - -static int -i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, - struct list_head *objects) -{ - struct drm_i915_gem_object *obj; - struct change_domains cd; - int ret; - - memset(&cd, 0, sizeof(cd)); - list_for_each_entry(obj, objects, exec_list) - i915_gem_object_set_to_gpu_domain(obj, ring, &cd); - - if (cd.invalidate_domains | cd.flush_domains) { - ret = i915_gem_execbuffer_flush(ring->dev, - cd.invalidate_domains, - cd.flush_domains, - cd.flush_rings); - if (ret) - return ret; - } - - if (cd.flips) { - ret = i915_gem_execbuffer_wait_for_flips(ring, cd.flips); - if (ret) - return ret; - } - - list_for_each_entry(obj, objects, exec_list) { - ret = i915_gem_execbuffer_sync_rings(obj, ring); - if (ret) - return ret; - } - - return 0; -} - -static bool -i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) -{ - return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0; -} - -static int -validate_exec_list(struct drm_i915_gem_exec_object2 *exec, - int count) -{ - int i; - - for (i = 0; i < count; i++) { - char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; - int length; /* limited by fault_in_pages_readable() */ - - /* First check for malicious input causing overflow */ - if (exec[i].relocation_count > - INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) - return -EINVAL; - - length = exec[i].relocation_count * - sizeof(struct drm_i915_gem_relocation_entry); - if (!access_ok(VERIFY_READ, ptr, length)) - return -EFAULT; - - /* we may also need to update the presumed offsets */ - if (!access_ok(VERIFY_WRITE, ptr, length)) - return -EFAULT; - - if (fault_in_pages_readable(ptr, length)) - return -EFAULT; - } - - return 0; -} - -static void -i915_gem_execbuffer_move_to_active(struct list_head *objects, - struct intel_ring_buffer *ring, - u32 seqno) -{ - struct drm_i915_gem_object *obj; - - list_for_each_entry(obj, objects, exec_list) { - u32 old_read = obj->base.read_domains; - u32 old_write = obj->base.write_domain; - - - obj->base.read_domains = obj->base.pending_read_domains; - obj->base.write_domain = obj->base.pending_write_domain; - obj->fenced_gpu_access = obj->pending_fenced_gpu_access; - - i915_gem_object_move_to_active(obj, ring, seqno); - if (obj->base.write_domain) { - obj->dirty = 1; - obj->pending_gpu_write = true; - list_move_tail(&obj->gpu_write_list, - &ring->gpu_write_list); - intel_mark_busy(ring->dev, obj); - } - - trace_i915_gem_object_change_domain(obj, old_read, old_write); - } -} - -static void -i915_gem_execbuffer_retire_commands(struct drm_device *dev, - struct drm_file *file, - struct intel_ring_buffer *ring) -{ - struct drm_i915_gem_request *request; - u32 invalidate; - - /* - * Ensure that the commands in the batch buffer are - * finished before the interrupt fires. - * - * The sampler always gets flushed on i965 (sigh). - */ - invalidate = I915_GEM_DOMAIN_COMMAND; - if (INTEL_INFO(dev)->gen >= 4) - invalidate |= I915_GEM_DOMAIN_SAMPLER; - if (ring->flush(ring, invalidate, 0)) { - i915_gem_next_request_seqno(ring); - return; - } - - /* Add a breadcrumb for the completion of the batch buffer */ - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL || i915_add_request(ring, file, request)) { - i915_gem_next_request_seqno(ring); - kfree(request); - } -} - -static int -i915_reset_gen7_sol_offsets(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int ret, i; - - if (!IS_GEN7(dev) || ring != &dev_priv->ring[RCS]) - return 0; - - ret = intel_ring_begin(ring, 4 * 3); - if (ret) - return ret; - - for (i = 0; i < 4; i++) { - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(ring, GEN7_SO_WRITE_OFFSET(i)); - intel_ring_emit(ring, 0); - } - - intel_ring_advance(ring); - - return 0; -} - -static int -i915_gem_do_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file, - struct drm_i915_gem_execbuffer2 *args, - struct drm_i915_gem_exec_object2 *exec) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct list_head objects; - struct eb_objects *eb; - struct drm_i915_gem_object *batch_obj; - struct drm_clip_rect *cliprects = NULL; - struct intel_ring_buffer *ring; - u32 exec_start, exec_len; - u32 seqno; - u32 mask; - int ret, mode, i; - - if (!i915_gem_check_execbuffer(args)) { - DRM_DEBUG("execbuf with invalid offset/length\n"); - return -EINVAL; - } - - ret = validate_exec_list(exec, args->buffer_count); - if (ret) - return ret; - - switch (args->flags & I915_EXEC_RING_MASK) { - case I915_EXEC_DEFAULT: - case I915_EXEC_RENDER: - ring = &dev_priv->ring[RCS]; - break; - case I915_EXEC_BSD: - if (!HAS_BSD(dev)) { - DRM_DEBUG("execbuf with invalid ring (BSD)\n"); - return -EINVAL; - } - ring = &dev_priv->ring[VCS]; - break; - case I915_EXEC_BLT: - if (!HAS_BLT(dev)) { - DRM_DEBUG("execbuf with invalid ring (BLT)\n"); - return -EINVAL; - } - ring = &dev_priv->ring[BCS]; - break; - default: - DRM_DEBUG("execbuf with unknown ring: %d\n", - (int)(args->flags & I915_EXEC_RING_MASK)); - return -EINVAL; - } - - mode = args->flags & I915_EXEC_CONSTANTS_MASK; - mask = I915_EXEC_CONSTANTS_MASK; - switch (mode) { - case I915_EXEC_CONSTANTS_REL_GENERAL: - case I915_EXEC_CONSTANTS_ABSOLUTE: - case I915_EXEC_CONSTANTS_REL_SURFACE: - if (ring == &dev_priv->ring[RCS] && - mode != dev_priv->relative_constants_mode) { - if (INTEL_INFO(dev)->gen < 4) - return -EINVAL; - - if (INTEL_INFO(dev)->gen > 5 && - mode == I915_EXEC_CONSTANTS_REL_SURFACE) - return -EINVAL; - - /* The HW changed the meaning on this bit on gen6 */ - if (INTEL_INFO(dev)->gen >= 6) - mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; - } - break; - default: - DRM_DEBUG("execbuf with unknown constants: %d\n", mode); - return -EINVAL; - } - - if (args->buffer_count < 1) { - DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); - return -EINVAL; - } - - if (args->num_cliprects != 0) { - if (ring != &dev_priv->ring[RCS]) { - DRM_DEBUG("clip rectangles are only valid with the render ring\n"); - return -EINVAL; - } - - if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { - DRM_DEBUG("execbuf with %u cliprects\n", - args->num_cliprects); - return -EINVAL; - } - cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), - GFP_KERNEL); - if (cliprects == NULL) { - ret = -ENOMEM; - goto pre_mutex_err; - } - - if (copy_from_user(cliprects, - (struct drm_clip_rect __user *)(uintptr_t) - args->cliprects_ptr, - sizeof(*cliprects)*args->num_cliprects)) { - ret = -EFAULT; - goto pre_mutex_err; - } - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - goto pre_mutex_err; - - if (dev_priv->mm.suspended) { - mutex_unlock(&dev->struct_mutex); - ret = -EBUSY; - goto pre_mutex_err; - } - - eb = eb_create(args->buffer_count); - if (eb == NULL) { - mutex_unlock(&dev->struct_mutex); - ret = -ENOMEM; - goto pre_mutex_err; - } - - /* Look up object handles */ - INIT_LIST_HEAD(&objects); - for (i = 0; i < args->buffer_count; i++) { - struct drm_i915_gem_object *obj; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, - exec[i].handle)); - if (&obj->base == NULL) { - DRM_DEBUG("Invalid object handle %d at index %d\n", - exec[i].handle, i); - /* prevent error path from reading uninitialized data */ - ret = -ENOENT; - goto err; - } - - if (!list_empty(&obj->exec_list)) { - DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", - obj, exec[i].handle, i); - ret = -EINVAL; - goto err; - } - - list_add_tail(&obj->exec_list, &objects); - obj->exec_handle = exec[i].handle; - obj->exec_entry = &exec[i]; - eb_add_object(eb, obj); - } - - /* take note of the batch buffer before we might reorder the lists */ - batch_obj = list_entry(objects.prev, - struct drm_i915_gem_object, - exec_list); - - /* Move the objects en-masse into the GTT, evicting if necessary. */ - ret = i915_gem_execbuffer_reserve(ring, file, &objects); - if (ret) - goto err; - - /* The objects are in their final locations, apply the relocations. */ - ret = i915_gem_execbuffer_relocate(dev, eb, &objects); - if (ret) { - if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, - &objects, eb, - exec, - args->buffer_count); - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - } - if (ret) - goto err; - } - - /* Set the pending read domains for the batch buffer to COMMAND */ - if (batch_obj->base.pending_write_domain) { - DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); - ret = -EINVAL; - goto err; - } - batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; - - ret = i915_gem_execbuffer_move_to_gpu(ring, &objects); - if (ret) - goto err; - - seqno = i915_gem_next_request_seqno(ring); - for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) { - if (seqno < ring->sync_seqno[i]) { - /* The GPU can not handle its semaphore value wrapping, - * so every billion or so execbuffers, we need to stall - * the GPU in order to reset the counters. - */ - ret = i915_gpu_idle(dev, true); - if (ret) - goto err; - - BUG_ON(ring->sync_seqno[i]); - } - } - - if (ring == &dev_priv->ring[RCS] && - mode != dev_priv->relative_constants_mode) { - ret = intel_ring_begin(ring, 4); - if (ret) - goto err; - - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(ring, INSTPM); - intel_ring_emit(ring, mask << 16 | mode); - intel_ring_advance(ring); - - dev_priv->relative_constants_mode = mode; - } - - if (args->flags & I915_EXEC_GEN7_SOL_RESET) { - ret = i915_reset_gen7_sol_offsets(dev, ring); - if (ret) - goto err; - } - - trace_i915_gem_ring_dispatch(ring, seqno); - - exec_start = batch_obj->gtt_offset + args->batch_start_offset; - exec_len = args->batch_len; - if (cliprects) { - for (i = 0; i < args->num_cliprects; i++) { - ret = i915_emit_box(dev, &cliprects[i], - args->DR1, args->DR4); - if (ret) - goto err; - - ret = ring->dispatch_execbuffer(ring, - exec_start, exec_len); - if (ret) - goto err; - } - } else { - ret = ring->dispatch_execbuffer(ring, exec_start, exec_len); - if (ret) - goto err; - } - - i915_gem_execbuffer_move_to_active(&objects, ring, seqno); - i915_gem_execbuffer_retire_commands(dev, file, ring); - -err: - eb_destroy(eb); - while (!list_empty(&objects)) { - struct drm_i915_gem_object *obj; - - obj = list_first_entry(&objects, - struct drm_i915_gem_object, - exec_list); - list_del_init(&obj->exec_list); - drm_gem_object_unreference(&obj->base); - } - - mutex_unlock(&dev->struct_mutex); - -pre_mutex_err: - kfree(cliprects); - return ret; -} - -/* - * Legacy execbuffer just creates an exec2 list from the original exec object - * list array and passes it to the real function. - */ -int -i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_execbuffer *args = data; - struct drm_i915_gem_execbuffer2 exec2; - struct drm_i915_gem_exec_object *exec_list = NULL; - struct drm_i915_gem_exec_object2 *exec2_list = NULL; - int ret, i; - - if (args->buffer_count < 1) { - DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); - return -EINVAL; - } - - /* Copy in the exec list from userland */ - exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); - exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); - if (exec_list == NULL || exec2_list == NULL) { - DRM_DEBUG("Failed to allocate exec list for %d buffers\n", - args->buffer_count); - drm_free_large(exec_list); - drm_free_large(exec2_list); - return -ENOMEM; - } - ret = copy_from_user(exec_list, - (struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - sizeof(*exec_list) * args->buffer_count); - if (ret != 0) { - DRM_DEBUG("copy %d exec entries failed %d\n", - args->buffer_count, ret); - drm_free_large(exec_list); - drm_free_large(exec2_list); - return -EFAULT; - } - - for (i = 0; i < args->buffer_count; i++) { - exec2_list[i].handle = exec_list[i].handle; - exec2_list[i].relocation_count = exec_list[i].relocation_count; - exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; - exec2_list[i].alignment = exec_list[i].alignment; - exec2_list[i].offset = exec_list[i].offset; - if (INTEL_INFO(dev)->gen < 4) - exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; - else - exec2_list[i].flags = 0; - } - - exec2.buffers_ptr = args->buffers_ptr; - exec2.buffer_count = args->buffer_count; - exec2.batch_start_offset = args->batch_start_offset; - exec2.batch_len = args->batch_len; - exec2.DR1 = args->DR1; - exec2.DR4 = args->DR4; - exec2.num_cliprects = args->num_cliprects; - exec2.cliprects_ptr = args->cliprects_ptr; - exec2.flags = I915_EXEC_RENDER; - - ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ - for (i = 0; i < args->buffer_count; i++) - exec_list[i].offset = exec2_list[i].offset; - /* ... and back out to userspace */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec_list, - sizeof(*exec_list) * args->buffer_count); - if (ret) { - ret = -EFAULT; - DRM_DEBUG("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); - } - } - - drm_free_large(exec_list); - drm_free_large(exec2_list); - return ret; -} - -int -i915_gem_execbuffer2(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_execbuffer2 *args = data; - struct drm_i915_gem_exec_object2 *exec2_list = NULL; - int ret; - - if (args->buffer_count < 1 || - args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { - DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); - return -EINVAL; - } - - exec2_list = kmalloc(sizeof(*exec2_list)*args->buffer_count, - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); - if (exec2_list == NULL) - exec2_list = drm_malloc_ab(sizeof(*exec2_list), - args->buffer_count); - if (exec2_list == NULL) { - DRM_DEBUG("Failed to allocate exec list for %d buffers\n", - args->buffer_count); - return -ENOMEM; - } - ret = copy_from_user(exec2_list, - (struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - sizeof(*exec2_list) * args->buffer_count); - if (ret != 0) { - DRM_DEBUG("copy %d exec entries failed %d\n", - args->buffer_count, ret); - drm_free_large(exec2_list); - return -EFAULT; - } - - ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec2_list, - sizeof(*exec2_list) * args->buffer_count); - if (ret) { - ret = -EFAULT; - DRM_DEBUG("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); - } - } - - drm_free_large(exec2_list); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_gtt.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_gtt.c deleted file mode 100644 index a135c61f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_gtt.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright © 2010 Daniel Vetter - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_trace.h" -#include "intel_drv.h" - -/* PPGTT support for Sandybdrige/Gen6 and later */ -static void i915_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, - unsigned first_entry, - unsigned num_entries) -{ - uint32_t *pt_vaddr; - uint32_t scratch_pte; - unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; - unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; - unsigned last_pte, i; - - scratch_pte = GEN6_PTE_ADDR_ENCODE(ppgtt->scratch_page_dma_addr); - scratch_pte |= GEN6_PTE_VALID | GEN6_PTE_CACHE_LLC; - - while (num_entries) { - last_pte = first_pte + num_entries; - if (last_pte > I915_PPGTT_PT_ENTRIES) - last_pte = I915_PPGTT_PT_ENTRIES; - - pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); - - for (i = first_pte; i < last_pte; i++) - pt_vaddr[i] = scratch_pte; - - kunmap_atomic(pt_vaddr); - - num_entries -= last_pte - first_pte; - first_pte = 0; - act_pd++; - } -} - -int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_hw_ppgtt *ppgtt; - unsigned first_pd_entry_in_global_pt; - int i; - int ret = -ENOMEM; - - /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 - * entries. For aliasing ppgtt support we just steal them at the end for - * now. */ - first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; - - ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); - if (!ppgtt) - return ret; - - ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; - ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries, - GFP_KERNEL); - if (!ppgtt->pt_pages) - goto err_ppgtt; - - for (i = 0; i < ppgtt->num_pd_entries; i++) { - ppgtt->pt_pages[i] = alloc_page(GFP_KERNEL); - if (!ppgtt->pt_pages[i]) - goto err_pt_alloc; - } - - if (dev_priv->mm.gtt->needs_dmar) { - ppgtt->pt_dma_addr = kzalloc(sizeof(dma_addr_t) - *ppgtt->num_pd_entries, - GFP_KERNEL); - if (!ppgtt->pt_dma_addr) - goto err_pt_alloc; - } - - for (i = 0; i < ppgtt->num_pd_entries; i++) { - dma_addr_t pt_addr; - if (dev_priv->mm.gtt->needs_dmar) { - pt_addr = pci_map_page(dev->pdev, ppgtt->pt_pages[i], - 0, 4096, - PCI_DMA_BIDIRECTIONAL); - - if (pci_dma_mapping_error(dev->pdev, - pt_addr)) { - ret = -EIO; - goto err_pd_pin; - - } - ppgtt->pt_dma_addr[i] = pt_addr; - } else - pt_addr = page_to_phys(ppgtt->pt_pages[i]); - } - - ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; - - i915_ppgtt_clear_range(ppgtt, 0, - ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); - - ppgtt->pd_offset = (first_pd_entry_in_global_pt)*sizeof(uint32_t); - - dev_priv->mm.aliasing_ppgtt = ppgtt; - - return 0; - -err_pd_pin: - if (ppgtt->pt_dma_addr) { - for (i--; i >= 0; i--) - pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], - 4096, PCI_DMA_BIDIRECTIONAL); - } -err_pt_alloc: - kfree(ppgtt->pt_dma_addr); - for (i = 0; i < ppgtt->num_pd_entries; i++) { - if (ppgtt->pt_pages[i]) - __free_page(ppgtt->pt_pages[i]); - } - kfree(ppgtt->pt_pages); -err_ppgtt: - kfree(ppgtt); - - return ret; -} - -void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - int i; - - if (!ppgtt) - return; - - if (ppgtt->pt_dma_addr) { - for (i = 0; i < ppgtt->num_pd_entries; i++) - pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], - 4096, PCI_DMA_BIDIRECTIONAL); - } - - kfree(ppgtt->pt_dma_addr); - for (i = 0; i < ppgtt->num_pd_entries; i++) - __free_page(ppgtt->pt_pages[i]); - kfree(ppgtt->pt_pages); - kfree(ppgtt); -} - -static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt, - struct scatterlist *sg_list, - unsigned sg_len, - unsigned first_entry, - uint32_t pte_flags) -{ - uint32_t *pt_vaddr, pte; - unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; - unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; - unsigned i, j, m, segment_len; - dma_addr_t page_addr; - struct scatterlist *sg; - - /* init sg walking */ - sg = sg_list; - i = 0; - segment_len = sg_dma_len(sg) >> PAGE_SHIFT; - m = 0; - - while (i < sg_len) { - pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); - - for (j = first_pte; j < I915_PPGTT_PT_ENTRIES; j++) { - page_addr = sg_dma_address(sg) + (m << PAGE_SHIFT); - pte = GEN6_PTE_ADDR_ENCODE(page_addr); - pt_vaddr[j] = pte | pte_flags; - - /* grab the next page */ - m++; - if (m == segment_len) { - sg = sg_next(sg); - i++; - if (i == sg_len) - break; - - segment_len = sg_dma_len(sg) >> PAGE_SHIFT; - m = 0; - } - } - - kunmap_atomic(pt_vaddr); - - first_pte = 0; - act_pd++; - } -} - -static void i915_ppgtt_insert_pages(struct i915_hw_ppgtt *ppgtt, - unsigned first_entry, unsigned num_entries, - struct page **pages, uint32_t pte_flags) -{ - uint32_t *pt_vaddr, pte; - unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; - unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; - unsigned last_pte, i; - dma_addr_t page_addr; - - while (num_entries) { - last_pte = first_pte + num_entries; - last_pte = min_t(unsigned, last_pte, I915_PPGTT_PT_ENTRIES); - - pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); - - for (i = first_pte; i < last_pte; i++) { - page_addr = page_to_phys(*pages); - pte = GEN6_PTE_ADDR_ENCODE(page_addr); - pt_vaddr[i] = pte | pte_flags; - - pages++; - } - - kunmap_atomic(pt_vaddr); - - num_entries -= last_pte - first_pte; - first_pte = 0; - act_pd++; - } -} - -void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, - struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t pte_flags = GEN6_PTE_VALID; - - switch (cache_level) { - case I915_CACHE_LLC_MLC: - pte_flags |= GEN6_PTE_CACHE_LLC_MLC; - break; - case I915_CACHE_LLC: - pte_flags |= GEN6_PTE_CACHE_LLC; - break; - case I915_CACHE_NONE: - pte_flags |= GEN6_PTE_UNCACHED; - break; - default: - BUG(); - } - - if (dev_priv->mm.gtt->needs_dmar) { - BUG_ON(!obj->sg_list); - - i915_ppgtt_insert_sg_entries(ppgtt, - obj->sg_list, - obj->num_sg, - obj->gtt_space->start >> PAGE_SHIFT, - pte_flags); - } else - i915_ppgtt_insert_pages(ppgtt, - obj->gtt_space->start >> PAGE_SHIFT, - obj->base.size >> PAGE_SHIFT, - obj->pages, - pte_flags); -} - -void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, - struct drm_i915_gem_object *obj) -{ - i915_ppgtt_clear_range(ppgtt, - obj->gtt_space->start >> PAGE_SHIFT, - obj->base.size >> PAGE_SHIFT); -} - -/* XXX kill agp_type! */ -static unsigned int cache_level_to_agp_type(struct drm_device *dev, - enum i915_cache_level cache_level) -{ - switch (cache_level) { - case I915_CACHE_LLC_MLC: - if (INTEL_INFO(dev)->gen >= 6) - return AGP_USER_CACHED_MEMORY_LLC_MLC; - /* Older chipsets do not have this extra level of CPU - * cacheing, so fallthrough and request the PTE simply - * as cached. - */ - case I915_CACHE_LLC: - return AGP_USER_CACHED_MEMORY; - default: - case I915_CACHE_NONE: - return AGP_USER_MEMORY; - } -} - -static bool do_idling(struct drm_i915_private *dev_priv) -{ - bool ret = dev_priv->mm.interruptible; - - if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { - dev_priv->mm.interruptible = false; - if (i915_gpu_idle(dev_priv->dev, false)) { - DRM_ERROR("Couldn't idle GPU\n"); - /* Wait a bit, in hopes it avoids the hang */ - udelay(10); - } - } - - return ret; -} - -static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) -{ - if (unlikely(dev_priv->mm.gtt->do_idle_maps)) - dev_priv->mm.interruptible = interruptible; -} - -void i915_gem_restore_gtt_mappings(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - - /* First fill our portion of the GTT with scratch pages */ - intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE, - (dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE); - - list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { - i915_gem_clflush_object(obj); - i915_gem_gtt_rebind_object(obj, obj->cache_level); - } - - intel_gtt_chipset_flush(); -} - -int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned int agp_type = cache_level_to_agp_type(dev, obj->cache_level); - int ret; - - if (dev_priv->mm.gtt->needs_dmar) { - ret = intel_gtt_map_memory(obj->pages, - obj->base.size >> PAGE_SHIFT, - &obj->sg_list, - &obj->num_sg); - if (ret != 0) - return ret; - - intel_gtt_insert_sg_entries(obj->sg_list, - obj->num_sg, - obj->gtt_space->start >> PAGE_SHIFT, - agp_type); - } else - intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, - obj->base.size >> PAGE_SHIFT, - obj->pages, - agp_type); - - return 0; -} - -void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, - enum i915_cache_level cache_level) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned int agp_type = cache_level_to_agp_type(dev, cache_level); - - if (dev_priv->mm.gtt->needs_dmar) { - BUG_ON(!obj->sg_list); - - intel_gtt_insert_sg_entries(obj->sg_list, - obj->num_sg, - obj->gtt_space->start >> PAGE_SHIFT, - agp_type); - } else - intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, - obj->base.size >> PAGE_SHIFT, - obj->pages, - agp_type); -} - -void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - bool interruptible; - - interruptible = do_idling(dev_priv); - - intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT, - obj->base.size >> PAGE_SHIFT); - - if (obj->sg_list) { - intel_gtt_unmap_memory(obj->sg_list, obj->num_sg); - obj->sg_list = NULL; - } - - undo_idling(dev_priv, interruptible); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_tiling.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_tiling.c deleted file mode 100644 index 1a930666..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_gem_tiling.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#include "linux/string.h" -#include "linux/bitops.h" -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/** @file i915_gem_tiling.c - * - * Support for managing tiling state of buffer objects. - * - * The idea behind tiling is to increase cache hit rates by rearranging - * pixel data so that a group of pixel accesses are in the same cacheline. - * Performance improvement from doing this on the back/depth buffer are on - * the order of 30%. - * - * Intel architectures make this somewhat more complicated, though, by - * adjustments made to addressing of data when the memory is in interleaved - * mode (matched pairs of DIMMS) to improve memory bandwidth. - * For interleaved memory, the CPU sends every sequential 64 bytes - * to an alternate memory channel so it can get the bandwidth from both. - * - * The GPU also rearranges its accesses for increased bandwidth to interleaved - * memory, and it matches what the CPU does for non-tiled. However, when tiled - * it does it a little differently, since one walks addresses not just in the - * X direction but also Y. So, along with alternating channels when bit - * 6 of the address flips, it also alternates when other bits flip -- Bits 9 - * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines) - * are common to both the 915 and 965-class hardware. - * - * The CPU also sometimes XORs in higher bits as well, to improve - * bandwidth doing strided access like we do so frequently in graphics. This - * is called "Channel XOR Randomization" in the MCH documentation. The result - * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address - * decode. - * - * All of this bit 6 XORing has an effect on our memory management, - * as we need to make sure that the 3d driver can correctly address object - * contents. - * - * If we don't have interleaved memory, all tiling is safe and no swizzling is - * required. - * - * When bit 17 is XORed in, we simply refuse to tile at all. Bit - * 17 is not just a page offset, so as we page an objet out and back in, - * individual pages in it will have different bit 17 addresses, resulting in - * each 64 bytes being swapped with its neighbor! - * - * Otherwise, if interleaved, we have to tell the 3d driver what the address - * swizzling it needs to do is, since it's writing with the CPU to the pages - * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the - * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling - * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order - * to match what the GPU expects. - */ - -/** - * Detects bit 6 swizzling of address lookup between IGD access and CPU - * access through main memory. - */ -void -i915_gem_detect_bit_6_swizzle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; - uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - - if (INTEL_INFO(dev)->gen >= 6) { - uint32_t dimm_c0, dimm_c1; - dimm_c0 = I915_READ(MAD_DIMM_C0); - dimm_c1 = I915_READ(MAD_DIMM_C1); - dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; - dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; - /* Enable swizzling when the channels are populated with - * identically sized dimms. We don't need to check the 3rd - * channel because no cpu with gpu attached ships in that - * configuration. Also, swizzling only makes sense for 2 - * channels anyway. */ - if (dimm_c0 == dimm_c1) { - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; - } else { - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } - } else if (IS_GEN5(dev)) { - /* On Ironlake whatever DRAM config, GPU always do - * same swizzling setup. - */ - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; - } else if (IS_GEN2(dev)) { - /* As far as we know, the 865 doesn't have these bit 6 - * swizzling issues. - */ - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { - uint32_t dcc; - - /* On 9xx chipsets, channel interleave by the CPU is - * determined by DCC. For single-channel, neither the CPU - * nor the GPU do swizzling. For dual channel interleaved, - * the GPU's interleave is bit 9 and 10 for X tiled, and bit - * 9 for Y tiled. The CPU's interleave is independent, and - * can be based on either bit 11 (haven't seen this yet) or - * bit 17 (common). - */ - dcc = I915_READ(DCC); - switch (dcc & DCC_ADDRESSING_MODE_MASK) { - case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: - case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - break; - case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: - if (dcc & DCC_CHANNEL_XOR_DISABLE) { - /* This is the base swizzling by the GPU for - * tiled buffers. - */ - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; - } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { - /* Bit 11 swizzling by the CPU in addition. */ - swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; - swizzle_y = I915_BIT_6_SWIZZLE_9_11; - } else { - /* Bit 17 swizzling by the CPU in addition. */ - swizzle_x = I915_BIT_6_SWIZZLE_9_10_17; - swizzle_y = I915_BIT_6_SWIZZLE_9_17; - } - break; - } - if (dcc == 0xffffffff) { - DRM_ERROR("Couldn't read from MCHBAR. " - "Disabling tiling.\n"); - swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; - swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - } - } else { - /* The 965, G33, and newer, have a very flexible memory - * configuration. It will enable dual-channel mode - * (interleaving) on as much memory as it can, and the GPU - * will additionally sometimes enable different bit 6 - * swizzling for tiled objects from the CPU. - * - * Here's what I found on the G965: - * slot fill memory size swizzling - * 0A 0B 1A 1B 1-ch 2-ch - * 512 0 0 0 512 0 O - * 512 0 512 0 16 1008 X - * 512 0 0 512 16 1008 X - * 0 512 0 512 16 1008 X - * 1024 1024 1024 0 2048 1024 O - * - * We could probably detect this based on either the DRB - * matching, which was the case for the swizzling required in - * the table above, or from the 1-ch value being less than - * the minimum size of a rank. - */ - if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { - swizzle_x = I915_BIT_6_SWIZZLE_NONE; - swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else { - swizzle_x = I915_BIT_6_SWIZZLE_9_10; - swizzle_y = I915_BIT_6_SWIZZLE_9; - } - } - - dev_priv->mm.bit_6_swizzle_x = swizzle_x; - dev_priv->mm.bit_6_swizzle_y = swizzle_y; -} - -/* Check pitch constriants for all chips & tiling formats */ -static bool -i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) -{ - int tile_width; - - /* Linear is always fine */ - if (tiling_mode == I915_TILING_NONE) - return true; - - if (IS_GEN2(dev) || - (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) - tile_width = 128; - else - tile_width = 512; - - /* check maximum stride & object size */ - if (INTEL_INFO(dev)->gen >= 4) { - /* i965 stores the end address of the gtt mapping in the fence - * reg, so dont bother to check the size */ - if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) - return false; - } else { - if (stride > 8192) - return false; - - if (IS_GEN3(dev)) { - if (size > I830_FENCE_MAX_SIZE_VAL << 20) - return false; - } else { - if (size > I830_FENCE_MAX_SIZE_VAL << 19) - return false; - } - } - - /* 965+ just needs multiples of tile width */ - if (INTEL_INFO(dev)->gen >= 4) { - if (stride & (tile_width - 1)) - return false; - return true; - } - - /* Pre-965 needs power of two tile widths */ - if (stride < tile_width) - return false; - - if (stride & (stride - 1)) - return false; - - return true; -} - -/* Is the current GTT allocation valid for the change in tiling? */ -static bool -i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) -{ - u32 size; - - if (tiling_mode == I915_TILING_NONE) - return true; - - if (INTEL_INFO(obj->base.dev)->gen >= 4) - return true; - - if (INTEL_INFO(obj->base.dev)->gen == 3) { - if (obj->gtt_offset & ~I915_FENCE_START_MASK) - return false; - } else { - if (obj->gtt_offset & ~I830_FENCE_START_MASK) - return false; - } - - /* - * Previous chips need to be aligned to the size of the smallest - * fence register that can contain the object. - */ - if (INTEL_INFO(obj->base.dev)->gen == 3) - size = 1024*1024; - else - size = 512*1024; - - while (size < obj->base.size) - size <<= 1; - - if (obj->gtt_space->size != size) - return false; - - if (obj->gtt_offset & (size - 1)) - return false; - - return true; -} - -/** - * Sets the tiling mode of an object, returning the required swizzling of - * bit 6 of addresses in the object. - */ -int -i915_gem_set_tiling(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_set_tiling *args = data; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int ret = 0; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) - return -ENOENT; - - if (!i915_tiling_ok(dev, - args->stride, obj->base.size, args->tiling_mode)) { - drm_gem_object_unreference_unlocked(&obj->base); - return -EINVAL; - } - - if (obj->pin_count) { - drm_gem_object_unreference_unlocked(&obj->base); - return -EBUSY; - } - - if (args->tiling_mode == I915_TILING_NONE) { - args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; - args->stride = 0; - } else { - if (args->tiling_mode == I915_TILING_X) - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; - else - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; - - /* Hide bit 17 swizzling from the user. This prevents old Mesa - * from aborting the application on sw fallbacks to bit 17, - * and we use the pread/pwrite bit17 paths to swizzle for it. - * If there was a user that was relying on the swizzle - * information for drm_intel_bo_map()ed reads/writes this would - * break it, but we don't have any of those. - */ - if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) - args->swizzle_mode = I915_BIT_6_SWIZZLE_9; - if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) - args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; - - /* If we can't handle the swizzling, make it untiled. */ - if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { - args->tiling_mode = I915_TILING_NONE; - args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; - args->stride = 0; - } - } - - mutex_lock(&dev->struct_mutex); - if (args->tiling_mode != obj->tiling_mode || - args->stride != obj->stride) { - /* We need to rebind the object if its current allocation - * no longer meets the alignment restrictions for its new - * tiling mode. Otherwise we can just leave it alone, but - * need to ensure that any fence register is cleared. - */ - i915_gem_release_mmap(obj); - - obj->map_and_fenceable = - obj->gtt_space == NULL || - (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && - i915_gem_object_fence_ok(obj, args->tiling_mode)); - - /* Rebind if we need a change of alignment */ - if (!obj->map_and_fenceable) { - u32 unfenced_alignment = - i915_gem_get_unfenced_gtt_alignment(dev, - obj->base.size, - args->tiling_mode); - if (obj->gtt_offset & (unfenced_alignment - 1)) - ret = i915_gem_object_unbind(obj); - } - - if (ret == 0) { - obj->tiling_changed = true; - obj->tiling_mode = args->tiling_mode; - obj->stride = args->stride; - } - } - /* we have to maintain this existing ABI... */ - args->stride = obj->stride; - args->tiling_mode = obj->tiling_mode; - drm_gem_object_unreference(&obj->base); - mutex_unlock(&dev->struct_mutex); - - return ret; -} - -/** - * Returns the current tiling mode and required bit 6 swizzling for the object. - */ -int -i915_gem_get_tiling(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_get_tiling *args = data; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); - if (&obj->base == NULL) - return -ENOENT; - - mutex_lock(&dev->struct_mutex); - - args->tiling_mode = obj->tiling_mode; - switch (obj->tiling_mode) { - case I915_TILING_X: - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; - break; - case I915_TILING_Y: - args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; - break; - case I915_TILING_NONE: - args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; - break; - default: - DRM_ERROR("unknown tiling mode\n"); - } - - /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ - if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) - args->swizzle_mode = I915_BIT_6_SWIZZLE_9; - if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) - args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; - - drm_gem_object_unreference(&obj->base); - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -/** - * Swap every 64 bytes of this page around, to account for it having a new - * bit 17 of its physical address and therefore being interpreted differently - * by the GPU. - */ -static void -i915_gem_swizzle_page(struct page *page) -{ - char temp[64]; - char *vaddr; - int i; - - vaddr = kmap(page); - - for (i = 0; i < PAGE_SIZE; i += 128) { - memcpy(temp, &vaddr[i], 64); - memcpy(&vaddr[i], &vaddr[i + 64], 64); - memcpy(&vaddr[i + 64], temp, 64); - } - - kunmap(page); -} - -void -i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) -{ - int page_count = obj->base.size >> PAGE_SHIFT; - int i; - - if (obj->bit_17 == NULL) - return; - - for (i = 0; i < page_count; i++) { - char new_bit_17 = page_to_phys(obj->pages[i]) >> 17; - if ((new_bit_17 & 0x1) != - (test_bit(i, obj->bit_17) != 0)) { - i915_gem_swizzle_page(obj->pages[i]); - set_page_dirty(obj->pages[i]); - } - } -} - -void -i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) -{ - int page_count = obj->base.size >> PAGE_SHIFT; - int i; - - if (obj->bit_17 == NULL) { - obj->bit_17 = kmalloc(BITS_TO_LONGS(page_count) * - sizeof(long), GFP_KERNEL); - if (obj->bit_17 == NULL) { - DRM_ERROR("Failed to allocate memory for bit 17 " - "record\n"); - return; - } - } - - for (i = 0; i < page_count; i++) { - if (page_to_phys(obj->pages[i]) & (1 << 17)) - __set_bit(i, obj->bit_17); - else - __clear_bit(i, obj->bit_17); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_ioc32.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_ioc32.c deleted file mode 100644 index 13b02899..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_ioc32.c +++ /dev/null @@ -1,219 +0,0 @@ -/** - * \file i915_ioc32.c - * - * 32-bit ioctl compatibility routines for the i915 DRM. - * - * \author Alan Hourihane - * - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Alan Hourihane 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" - -typedef struct _drm_i915_batchbuffer32 { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ - int num_cliprects; /* mulitpass with multiple cliprects? */ - u32 cliprects; /* pointer to userspace cliprects */ -} drm_i915_batchbuffer32_t; - -static int compat_i915_batchbuffer(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_batchbuffer32_t batchbuffer32; - drm_i915_batchbuffer_t __user *batchbuffer; - - if (copy_from_user - (&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32))) - return -EFAULT; - - batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer)); - if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer)) - || __put_user(batchbuffer32.start, &batchbuffer->start) - || __put_user(batchbuffer32.used, &batchbuffer->used) - || __put_user(batchbuffer32.DR1, &batchbuffer->DR1) - || __put_user(batchbuffer32.DR4, &batchbuffer->DR4) - || __put_user(batchbuffer32.num_cliprects, - &batchbuffer->num_cliprects) - || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects, - &batchbuffer->cliprects)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER, - (unsigned long)batchbuffer); -} - -typedef struct _drm_i915_cmdbuffer32 { - u32 buf; /* pointer to userspace command buffer */ - int sz; /* nr bytes in buf */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ - int num_cliprects; /* mulitpass with multiple cliprects? */ - u32 cliprects; /* pointer to userspace cliprects */ -} drm_i915_cmdbuffer32_t; - -static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_cmdbuffer32_t cmdbuffer32; - drm_i915_cmdbuffer_t __user *cmdbuffer; - - if (copy_from_user - (&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32))) - return -EFAULT; - - cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer)); - if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer)) - || __put_user((int __user *)(unsigned long)cmdbuffer32.buf, - &cmdbuffer->buf) - || __put_user(cmdbuffer32.sz, &cmdbuffer->sz) - || __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1) - || __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4) - || __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects) - || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects, - &cmdbuffer->cliprects)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER, - (unsigned long)cmdbuffer); -} - -typedef struct drm_i915_irq_emit32 { - u32 irq_seq; -} drm_i915_irq_emit32_t; - -static int compat_i915_irq_emit(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_irq_emit32_t req32; - drm_i915_irq_emit_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((int __user *)(unsigned long)req32.irq_seq, - &request->irq_seq)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT, - (unsigned long)request); -} -typedef struct drm_i915_getparam32 { - int param; - u32 value; -} drm_i915_getparam32_t; - -static int compat_i915_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_getparam32_t req32; - drm_i915_getparam_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM, - (unsigned long)request); -} - -typedef struct drm_i915_mem_alloc32 { - int region; - int alignment; - int size; - u32 region_offset; /* offset from start of fb or agp */ -} drm_i915_mem_alloc32_t; - -static int compat_i915_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_mem_alloc32_t req32; - drm_i915_mem_alloc_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.region, &request->region) - || __put_user(req32.alignment, &request->alignment) - || __put_user(req32.size, &request->size) - || __put_user((void __user *)(unsigned long)req32.region_offset, - &request->region_offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_I915_ALLOC, - (unsigned long)request); -} - -drm_ioctl_compat_t *i915_compat_ioctls[] = { - [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, - [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, - [DRM_I915_GETPARAM] = compat_i915_getparam, - [DRM_I915_IRQ_EMIT] = compat_i915_irq_emit, - [DRM_I915_ALLOC] = compat_i915_alloc -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) - fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_irq.c deleted file mode 100644 index 26c67a78..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_irq.c +++ /dev/null @@ -1,2169 +0,0 @@ -/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include -#include -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_trace.h" -#include "intel_drv.h" - -#define MAX_NOPID ((u32)~0) - -/** - * Interrupts that are always left unmasked. - * - * Since pipe events are edge-triggered from the PIPESTAT register to IIR, - * we leave them always unmasked in IMR and then control enabling them through - * PIPESTAT alone. - */ -#define I915_INTERRUPT_ENABLE_FIX \ - (I915_ASLE_INTERRUPT | \ - I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ - I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ - I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | \ - I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | \ - I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) - -/** Interrupts that we mask and unmask at runtime. */ -#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT | I915_BSD_USER_INTERRUPT) - -#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ - PIPE_VBLANK_INTERRUPT_STATUS) - -#define I915_PIPE_VBLANK_ENABLE (PIPE_START_VBLANK_INTERRUPT_ENABLE |\ - PIPE_VBLANK_INTERRUPT_ENABLE) - -#define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \ - DRM_I915_VBLANK_PIPE_B) - -/* For display hotplug interrupt */ -static void -ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - if ((dev_priv->irq_mask & mask) != 0) { - dev_priv->irq_mask &= ~mask; - I915_WRITE(DEIMR, dev_priv->irq_mask); - POSTING_READ(DEIMR); - } -} - -static inline void -ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - if ((dev_priv->irq_mask & mask) != mask) { - dev_priv->irq_mask |= mask; - I915_WRITE(DEIMR, dev_priv->irq_mask); - POSTING_READ(DEIMR); - } -} - -void -i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) -{ - if ((dev_priv->pipestat[pipe] & mask) != mask) { - u32 reg = PIPESTAT(pipe); - - dev_priv->pipestat[pipe] |= mask; - /* Enable the interrupt, clear any pending status */ - I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16)); - POSTING_READ(reg); - } -} - -void -i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) -{ - if ((dev_priv->pipestat[pipe] & mask) != 0) { - u32 reg = PIPESTAT(pipe); - - dev_priv->pipestat[pipe] &= ~mask; - I915_WRITE(reg, dev_priv->pipestat[pipe]); - POSTING_READ(reg); - } -} - -/** - * intel_enable_asle - enable ASLE interrupt for OpRegion - */ -void intel_enable_asle(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - - if (HAS_PCH_SPLIT(dev)) - ironlake_enable_display_irq(dev_priv, DE_GSE); - else { - i915_enable_pipestat(dev_priv, 1, - PIPE_LEGACY_BLC_EVENT_ENABLE); - if (INTEL_INFO(dev)->gen >= 4) - i915_enable_pipestat(dev_priv, 0, - PIPE_LEGACY_BLC_EVENT_ENABLE); - } - - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -/** - * i915_pipe_enabled - check if a pipe is enabled - * @dev: DRM device - * @pipe: pipe to check - * - * Reading certain registers when the pipe is disabled can hang the chip. - * Use this routine to make sure the PLL is running and the pipe is active - * before reading such registers if unsure. - */ -static int -i915_pipe_enabled(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE; -} - -/* Called from drm generic code, passed a 'crtc', which - * we use as a pipe index - */ -static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long high_frame; - unsigned long low_frame; - u32 high1, high2, low; - - if (!i915_pipe_enabled(dev, pipe)) { - DRM_DEBUG_DRIVER("trying to get vblank count for disabled " - "pipe %c\n", pipe_name(pipe)); - return 0; - } - - high_frame = PIPEFRAME(pipe); - low_frame = PIPEFRAMEPIXEL(pipe); - - /* - * High & low register fields aren't synchronized, so make sure - * we get a low value that's stable across two reads of the high - * register. - */ - do { - high1 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK; - low = I915_READ(low_frame) & PIPE_FRAME_LOW_MASK; - high2 = I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK; - } while (high1 != high2); - - high1 >>= PIPE_FRAME_HIGH_SHIFT; - low >>= PIPE_FRAME_LOW_SHIFT; - return (high1 << 8) | low; -} - -static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int reg = PIPE_FRMCOUNT_GM45(pipe); - - if (!i915_pipe_enabled(dev, pipe)) { - DRM_DEBUG_DRIVER("trying to get vblank count for disabled " - "pipe %c\n", pipe_name(pipe)); - return 0; - } - - return I915_READ(reg); -} - -static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, - int *vpos, int *hpos) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 vbl = 0, position = 0; - int vbl_start, vbl_end, htotal, vtotal; - bool in_vbl = true; - int ret = 0; - - if (!i915_pipe_enabled(dev, pipe)) { - DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " - "pipe %c\n", pipe_name(pipe)); - return 0; - } - - /* Get vtotal. */ - vtotal = 1 + ((I915_READ(VTOTAL(pipe)) >> 16) & 0x1fff); - - if (INTEL_INFO(dev)->gen >= 4) { - /* No obvious pixelcount register. Only query vertical - * scanout position from Display scan line register. - */ - position = I915_READ(PIPEDSL(pipe)); - - /* Decode into vertical scanout position. Don't have - * horizontal scanout position. - */ - *vpos = position & 0x1fff; - *hpos = 0; - } else { - /* Have access to pixelcount since start of frame. - * We can split this into vertical and horizontal - * scanout position. - */ - position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT; - - htotal = 1 + ((I915_READ(HTOTAL(pipe)) >> 16) & 0x1fff); - *vpos = position / htotal; - *hpos = position - (*vpos * htotal); - } - - /* Query vblank area. */ - vbl = I915_READ(VBLANK(pipe)); - - /* Test position against vblank region. */ - vbl_start = vbl & 0x1fff; - vbl_end = (vbl >> 16) & 0x1fff; - - if ((*vpos < vbl_start) || (*vpos > vbl_end)) - in_vbl = false; - - /* Inside "upper part" of vblank area? Apply corrective offset: */ - if (in_vbl && (*vpos >= vbl_start)) - *vpos = *vpos - vtotal; - - /* Readouts valid? */ - if (vbl > 0) - ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; - - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_INVBL; - - return ret; -} - -static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, - int *max_error, - struct timeval *vblank_time, - unsigned flags) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - - if (pipe < 0 || pipe >= dev_priv->num_pipe) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; - } - - /* Get drm_crtc to timestamp: */ - crtc = intel_get_crtc_for_pipe(dev, pipe); - if (crtc == NULL) { - DRM_ERROR("Invalid crtc %d\n", pipe); - return -EINVAL; - } - - if (!crtc->enabled) { - DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); - return -EBUSY; - } - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, - vblank_time, flags, - crtc); -} - -/* - * Handle hotplug events outside the interrupt handler proper. - */ -static void i915_hotplug_work_func(struct work_struct *work) -{ - drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, - hotplug_work); - struct drm_device *dev = dev_priv->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - - mutex_lock(&mode_config->mutex); - DRM_DEBUG_KMS("running encoder hotplug functions\n"); - - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) - if (encoder->hot_plug) - encoder->hot_plug(encoder); - - mutex_unlock(&mode_config->mutex); - - /* Just fire off a uevent and let userspace tell us what to do */ - drm_helper_hpd_irq_event(dev); -} - -static void i915_handle_rps_change(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - u32 busy_up, busy_down, max_avg, min_avg; - u8 new_delay = dev_priv->cur_delay; - - I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); - busy_up = I915_READ(RCPREVBSYTUPAVG); - busy_down = I915_READ(RCPREVBSYTDNAVG); - max_avg = I915_READ(RCBMAXAVG); - min_avg = I915_READ(RCBMINAVG); - - /* Handle RCS change request from hw */ - if (busy_up > max_avg) { - if (dev_priv->cur_delay != dev_priv->max_delay) - new_delay = dev_priv->cur_delay - 1; - if (new_delay < dev_priv->max_delay) - new_delay = dev_priv->max_delay; - } else if (busy_down < min_avg) { - if (dev_priv->cur_delay != dev_priv->min_delay) - new_delay = dev_priv->cur_delay + 1; - if (new_delay > dev_priv->min_delay) - new_delay = dev_priv->min_delay; - } - - if (ironlake_set_drps(dev, new_delay)) - dev_priv->cur_delay = new_delay; - - return; -} - -static void notify_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 seqno; - - if (ring->obj == NULL) - return; - - seqno = ring->get_seqno(ring); - trace_i915_gem_request_complete(ring, seqno); - - ring->irq_seqno = seqno; - wake_up_all(&ring->irq_queue); - if (i915_enable_hangcheck) { - dev_priv->hangcheck_count = 0; - mod_timer(&dev_priv->hangcheck_timer, - jiffies + - msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); - } -} - -static void gen6_pm_rps_work(struct work_struct *work) -{ - drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, - rps_work); - u8 new_delay = dev_priv->cur_delay; - u32 pm_iir, pm_imr; - - spin_lock_irq(&dev_priv->rps_lock); - pm_iir = dev_priv->pm_iir; - dev_priv->pm_iir = 0; - pm_imr = I915_READ(GEN6_PMIMR); - I915_WRITE(GEN6_PMIMR, 0); - spin_unlock_irq(&dev_priv->rps_lock); - - if (!pm_iir) - return; - - mutex_lock(&dev_priv->dev->struct_mutex); - if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { - if (dev_priv->cur_delay != dev_priv->max_delay) - new_delay = dev_priv->cur_delay + 1; - if (new_delay > dev_priv->max_delay) - new_delay = dev_priv->max_delay; - } else if (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) { - gen6_gt_force_wake_get(dev_priv); - if (dev_priv->cur_delay != dev_priv->min_delay) - new_delay = dev_priv->cur_delay - 1; - if (new_delay < dev_priv->min_delay) { - new_delay = dev_priv->min_delay; - I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, - I915_READ(GEN6_RP_INTERRUPT_LIMITS) | - ((new_delay << 16) & 0x3f0000)); - } else { - /* Make sure we continue to get down interrupts - * until we hit the minimum frequency */ - I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, - I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000); - } - gen6_gt_force_wake_put(dev_priv); - } - - gen6_set_rps(dev_priv->dev, new_delay); - dev_priv->cur_delay = new_delay; - - /* - * rps_lock not held here because clearing is non-destructive. There is - * an *extremely* unlikely race with gen6_rps_enable() that is prevented - * by holding struct_mutex for the duration of the write. - */ - mutex_unlock(&dev_priv->dev->struct_mutex); -} - -static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, - u32 pm_iir) -{ - unsigned long flags; - - /* - * IIR bits should never already be set because IMR should - * prevent an interrupt from being shown in IIR. The warning - * displays a case where we've unsafely cleared - * dev_priv->pm_iir. Although missing an interrupt of the same - * type is not a problem, it displays a problem in the logic. - * - * The mask bit in IMR is cleared by rps_work. - */ - - spin_lock_irqsave(&dev_priv->rps_lock, flags); - dev_priv->pm_iir |= pm_iir; - I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); - POSTING_READ(GEN6_PMIMR); - spin_unlock_irqrestore(&dev_priv->rps_lock, flags); - - queue_work(dev_priv->wq, &dev_priv->rps_work); -} - -static void pch_irq_handler(struct drm_device *dev, u32 pch_iir) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe; - - if (pch_iir & SDE_AUDIO_POWER_MASK) - DRM_DEBUG_DRIVER("PCH audio power change on port %d\n", - (pch_iir & SDE_AUDIO_POWER_MASK) >> - SDE_AUDIO_POWER_SHIFT); - - if (pch_iir & SDE_GMBUS) - DRM_DEBUG_DRIVER("PCH GMBUS interrupt\n"); - - if (pch_iir & SDE_AUDIO_HDCP_MASK) - DRM_DEBUG_DRIVER("PCH HDCP audio interrupt\n"); - - if (pch_iir & SDE_AUDIO_TRANS_MASK) - DRM_DEBUG_DRIVER("PCH transcoder audio interrupt\n"); - - if (pch_iir & SDE_POISON) - DRM_ERROR("PCH poison interrupt\n"); - - if (pch_iir & SDE_FDI_MASK) - for_each_pipe(pipe) - DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", - pipe_name(pipe), - I915_READ(FDI_RX_IIR(pipe))); - - if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) - DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n"); - - if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR)) - DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); - - if (pch_iir & SDE_TRANSB_FIFO_UNDER) - DRM_DEBUG_DRIVER("PCH transcoder B underrun interrupt\n"); - if (pch_iir & SDE_TRANSA_FIFO_UNDER) - DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); -} - -static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret = IRQ_NONE; - u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; - struct drm_i915_master_private *master_priv; - - atomic_inc(&dev_priv->irq_received); - - /* disable master interrupt before clearing iir */ - de_ier = I915_READ(DEIER); - I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); - POSTING_READ(DEIER); - - de_iir = I915_READ(DEIIR); - gt_iir = I915_READ(GTIIR); - pch_iir = I915_READ(SDEIIR); - pm_iir = I915_READ(GEN6_PMIIR); - - if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && pm_iir == 0) - goto done; - - ret = IRQ_HANDLED; - - if (dev->primary->master) { - master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } - - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, &dev_priv->ring[RCS]); - if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS]); - if (gt_iir & GT_BLT_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); - - if (de_iir & DE_GSE_IVB) - intel_opregion_gse_intr(dev); - - if (de_iir & DE_PLANEA_FLIP_DONE_IVB) { - intel_prepare_page_flip(dev, 0); - intel_finish_page_flip_plane(dev, 0); - } - - if (de_iir & DE_PLANEB_FLIP_DONE_IVB) { - intel_prepare_page_flip(dev, 1); - intel_finish_page_flip_plane(dev, 1); - } - - if (de_iir & DE_PIPEA_VBLANK_IVB) - drm_handle_vblank(dev, 0); - - if (de_iir & DE_PIPEB_VBLANK_IVB) - drm_handle_vblank(dev, 1); - - /* check event from PCH */ - if (de_iir & DE_PCH_EVENT_IVB) { - if (pch_iir & SDE_HOTPLUG_MASK_CPT) - queue_work(dev_priv->wq, &dev_priv->hotplug_work); - pch_irq_handler(dev, pch_iir); - } - - if (pm_iir & GEN6_PM_DEFERRED_EVENTS) - gen6_queue_rps_work(dev_priv, pm_iir); - - /* should clear PCH hotplug event before clear CPU irq */ - I915_WRITE(SDEIIR, pch_iir); - I915_WRITE(GTIIR, gt_iir); - I915_WRITE(DEIIR, de_iir); - I915_WRITE(GEN6_PMIIR, pm_iir); - -done: - I915_WRITE(DEIER, de_ier); - POSTING_READ(DEIER); - - return ret; -} - -static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret = IRQ_NONE; - u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; - u32 hotplug_mask; - struct drm_i915_master_private *master_priv; - u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; - - atomic_inc(&dev_priv->irq_received); - - if (IS_GEN6(dev)) - bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT; - - /* disable master interrupt before clearing iir */ - de_ier = I915_READ(DEIER); - I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); - POSTING_READ(DEIER); - - de_iir = I915_READ(DEIIR); - gt_iir = I915_READ(GTIIR); - pch_iir = I915_READ(SDEIIR); - pm_iir = I915_READ(GEN6_PMIIR); - - if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && - (!IS_GEN6(dev) || pm_iir == 0)) - goto done; - - if (HAS_PCH_CPT(dev)) - hotplug_mask = SDE_HOTPLUG_MASK_CPT; - else - hotplug_mask = SDE_HOTPLUG_MASK; - - ret = IRQ_HANDLED; - - if (dev->primary->master) { - master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } - - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, &dev_priv->ring[RCS]); - if (gt_iir & bsd_usr_interrupt) - notify_ring(dev, &dev_priv->ring[VCS]); - if (gt_iir & GT_BLT_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); - - if (de_iir & DE_GSE) - intel_opregion_gse_intr(dev); - - if (de_iir & DE_PLANEA_FLIP_DONE) { - intel_prepare_page_flip(dev, 0); - intel_finish_page_flip_plane(dev, 0); - } - - if (de_iir & DE_PLANEB_FLIP_DONE) { - intel_prepare_page_flip(dev, 1); - intel_finish_page_flip_plane(dev, 1); - } - - if (de_iir & DE_PIPEA_VBLANK) - drm_handle_vblank(dev, 0); - - if (de_iir & DE_PIPEB_VBLANK) - drm_handle_vblank(dev, 1); - - /* check event from PCH */ - if (de_iir & DE_PCH_EVENT) { - if (pch_iir & hotplug_mask) - queue_work(dev_priv->wq, &dev_priv->hotplug_work); - pch_irq_handler(dev, pch_iir); - } - - if (de_iir & DE_PCU_EVENT) { - I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); - i915_handle_rps_change(dev); - } - - if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) - gen6_queue_rps_work(dev_priv, pm_iir); - - /* should clear PCH hotplug event before clear CPU irq */ - I915_WRITE(SDEIIR, pch_iir); - I915_WRITE(GTIIR, gt_iir); - I915_WRITE(DEIIR, de_iir); - I915_WRITE(GEN6_PMIIR, pm_iir); - -done: - I915_WRITE(DEIER, de_ier); - POSTING_READ(DEIER); - - return ret; -} - -/** - * i915_error_work_func - do process context error handling work - * @work: work struct - * - * Fire an error uevent so userspace can see that a hang or error - * was detected. - */ -static void i915_error_work_func(struct work_struct *work) -{ - drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, - error_work); - struct drm_device *dev = dev_priv->dev; - char *error_event[] = { "ERROR=1", NULL }; - char *reset_event[] = { "RESET=1", NULL }; - char *reset_done_event[] = { "ERROR=0", NULL }; - - kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); - - if (atomic_read(&dev_priv->mm.wedged)) { - DRM_DEBUG_DRIVER("resetting chip\n"); - kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); - if (!i915_reset(dev, GRDOM_RENDER)) { - atomic_set(&dev_priv->mm.wedged, 0); - kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event); - } - complete_all(&dev_priv->error_completion); - } -} - -#ifdef CONFIG_DEBUG_FS -static struct drm_i915_error_object * -i915_error_object_create(struct drm_i915_private *dev_priv, - struct drm_i915_gem_object *src) -{ - struct drm_i915_error_object *dst; - int page, page_count; - u32 reloc_offset; - - if (src == NULL || src->pages == NULL) - return NULL; - - page_count = src->base.size / PAGE_SIZE; - - dst = kmalloc(sizeof(*dst) + page_count * sizeof(u32 *), GFP_ATOMIC); - if (dst == NULL) - return NULL; - - reloc_offset = src->gtt_offset; - for (page = 0; page < page_count; page++) { - unsigned long flags; - void *d; - - d = kmalloc(PAGE_SIZE, GFP_ATOMIC); - if (d == NULL) - goto unwind; - - local_irq_save(flags); - if (reloc_offset < dev_priv->mm.gtt_mappable_end) { - void __iomem *s; - - /* Simply ignore tiling or any overlapping fence. - * It's part of the error state, and this hopefully - * captures what the GPU read. - */ - - s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - reloc_offset); - memcpy_fromio(d, s, PAGE_SIZE); - io_mapping_unmap_atomic(s); - } else { - void *s; - - drm_clflush_pages(&src->pages[page], 1); - - s = kmap_atomic(src->pages[page]); - memcpy(d, s, PAGE_SIZE); - kunmap_atomic(s); - - drm_clflush_pages(&src->pages[page], 1); - } - local_irq_restore(flags); - - dst->pages[page] = d; - - reloc_offset += PAGE_SIZE; - } - dst->page_count = page_count; - dst->gtt_offset = src->gtt_offset; - - return dst; - -unwind: - while (page--) - kfree(dst->pages[page]); - kfree(dst); - return NULL; -} - -static void -i915_error_object_free(struct drm_i915_error_object *obj) -{ - int page; - - if (obj == NULL) - return; - - for (page = 0; page < obj->page_count; page++) - kfree(obj->pages[page]); - - kfree(obj); -} - -static void -i915_error_state_free(struct drm_device *dev, - struct drm_i915_error_state *error) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(error->ring); i++) { - i915_error_object_free(error->ring[i].batchbuffer); - i915_error_object_free(error->ring[i].ringbuffer); - kfree(error->ring[i].requests); - } - - kfree(error->active_bo); - kfree(error->overlay); - kfree(error); -} - -static u32 capture_bo_list(struct drm_i915_error_buffer *err, - int count, - struct list_head *head) -{ - struct drm_i915_gem_object *obj; - int i = 0; - - list_for_each_entry(obj, head, mm_list) { - err->size = obj->base.size; - err->name = obj->base.name; - err->seqno = obj->last_rendering_seqno; - err->gtt_offset = obj->gtt_offset; - err->read_domains = obj->base.read_domains; - err->write_domain = obj->base.write_domain; - err->fence_reg = obj->fence_reg; - err->pinned = 0; - if (obj->pin_count > 0) - err->pinned = 1; - if (obj->user_pin_count > 0) - err->pinned = -1; - err->tiling = obj->tiling_mode; - err->dirty = obj->dirty; - err->purgeable = obj->madv != I915_MADV_WILLNEED; - err->ring = obj->ring ? obj->ring->id : -1; - err->cache_level = obj->cache_level; - - if (++i == count) - break; - - err++; - } - - return i; -} - -static void i915_gem_record_fences(struct drm_device *dev, - struct drm_i915_error_state *error) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - /* Fences */ - switch (INTEL_INFO(dev)->gen) { - case 7: - case 6: - for (i = 0; i < 16; i++) - error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); - break; - case 5: - case 4: - for (i = 0; i < 16; i++) - error->fence[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); - break; - case 3: - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - error->fence[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); - case 2: - for (i = 0; i < 8; i++) - error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); - break; - - } -} - -static struct drm_i915_error_object * -i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, - struct intel_ring_buffer *ring) -{ - struct drm_i915_gem_object *obj; - u32 seqno; - - if (!ring->get_seqno) - return NULL; - - seqno = ring->get_seqno(ring); - list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { - if (obj->ring != ring) - continue; - - if (i915_seqno_passed(seqno, obj->last_rendering_seqno)) - continue; - - if ((obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) == 0) - continue; - - /* We need to copy these to an anonymous buffer as the simplest - * method to avoid being overwritten by userspace. - */ - return i915_error_object_create(dev_priv, obj); - } - - return NULL; -} - -static void i915_record_ring_state(struct drm_device *dev, - struct drm_i915_error_state *error, - struct intel_ring_buffer *ring) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen >= 6) { - error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); - error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); - error->semaphore_mboxes[ring->id][0] - = I915_READ(RING_SYNC_0(ring->mmio_base)); - error->semaphore_mboxes[ring->id][1] - = I915_READ(RING_SYNC_1(ring->mmio_base)); - } - - if (INTEL_INFO(dev)->gen >= 4) { - error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); - error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); - error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); - error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); - if (ring->id == RCS) { - error->instdone1 = I915_READ(INSTDONE1); - error->bbaddr = I915_READ64(BB_ADDR); - } - } else { - error->ipeir[ring->id] = I915_READ(IPEIR); - error->ipehr[ring->id] = I915_READ(IPEHR); - error->instdone[ring->id] = I915_READ(INSTDONE); - } - - error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); - error->seqno[ring->id] = ring->get_seqno(ring); - error->acthd[ring->id] = intel_ring_get_active_head(ring); - error->head[ring->id] = I915_READ_HEAD(ring); - error->tail[ring->id] = I915_READ_TAIL(ring); - - error->cpu_ring_head[ring->id] = ring->head; - error->cpu_ring_tail[ring->id] = ring->tail; -} - -static void i915_gem_record_rings(struct drm_device *dev, - struct drm_i915_error_state *error) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_request *request; - int i, count; - - for (i = 0; i < I915_NUM_RINGS; i++) { - struct intel_ring_buffer *ring = &dev_priv->ring[i]; - - if (ring->obj == NULL) - continue; - - i915_record_ring_state(dev, error, ring); - - error->ring[i].batchbuffer = - i915_error_first_batchbuffer(dev_priv, ring); - - error->ring[i].ringbuffer = - i915_error_object_create(dev_priv, ring->obj); - - count = 0; - list_for_each_entry(request, &ring->request_list, list) - count++; - - error->ring[i].num_requests = count; - error->ring[i].requests = - kmalloc(count*sizeof(struct drm_i915_error_request), - GFP_ATOMIC); - if (error->ring[i].requests == NULL) { - error->ring[i].num_requests = 0; - continue; - } - - count = 0; - list_for_each_entry(request, &ring->request_list, list) { - struct drm_i915_error_request *erq; - - erq = &error->ring[i].requests[count++]; - erq->seqno = request->seqno; - erq->jiffies = request->emitted_jiffies; - erq->tail = request->tail; - } - } -} - -/** - * i915_capture_error_state - capture an error record for later analysis - * @dev: drm device - * - * Should be called when an error is detected (either a hang or an error - * interrupt) to capture error state from the time of the error. Fills - * out a structure which becomes available in debugfs for user level tools - * to pick up. - */ -static void i915_capture_error_state(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - struct drm_i915_error_state *error; - unsigned long flags; - int i, pipe; - - spin_lock_irqsave(&dev_priv->error_lock, flags); - error = dev_priv->first_error; - spin_unlock_irqrestore(&dev_priv->error_lock, flags); - if (error) - return; - - /* Account for pipe specific data like PIPE*STAT */ - error = kzalloc(sizeof(*error), GFP_ATOMIC); - if (!error) { - DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); - return; - } - - DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n", - dev->primary->index); - - error->eir = I915_READ(EIR); - error->pgtbl_er = I915_READ(PGTBL_ER); - for_each_pipe(pipe) - error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); - - if (INTEL_INFO(dev)->gen >= 6) { - error->error = I915_READ(ERROR_GEN6); - error->done_reg = I915_READ(DONE_REG); - } - - i915_gem_record_fences(dev, error); - i915_gem_record_rings(dev, error); - - /* Record buffers on the active and pinned lists. */ - error->active_bo = NULL; - error->pinned_bo = NULL; - - i = 0; - list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) - i++; - error->active_bo_count = i; - list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) - i++; - error->pinned_bo_count = i - error->active_bo_count; - - error->active_bo = NULL; - error->pinned_bo = NULL; - if (i) { - error->active_bo = kmalloc(sizeof(*error->active_bo)*i, - GFP_ATOMIC); - if (error->active_bo) - error->pinned_bo = - error->active_bo + error->active_bo_count; - } - - if (error->active_bo) - error->active_bo_count = - capture_bo_list(error->active_bo, - error->active_bo_count, - &dev_priv->mm.active_list); - - if (error->pinned_bo) - error->pinned_bo_count = - capture_bo_list(error->pinned_bo, - error->pinned_bo_count, - &dev_priv->mm.pinned_list); - - do_gettimeofday(&error->time); - - error->overlay = intel_overlay_capture_error_state(dev); - error->display = intel_display_capture_error_state(dev); - - spin_lock_irqsave(&dev_priv->error_lock, flags); - if (dev_priv->first_error == NULL) { - dev_priv->first_error = error; - error = NULL; - } - spin_unlock_irqrestore(&dev_priv->error_lock, flags); - - if (error) - i915_error_state_free(dev, error); -} - -void i915_destroy_error_state(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_error_state *error; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->error_lock, flags); - error = dev_priv->first_error; - dev_priv->first_error = NULL; - spin_unlock_irqrestore(&dev_priv->error_lock, flags); - - if (error) - i915_error_state_free(dev, error); -} -#else -#define i915_capture_error_state(x) -#endif - -static void i915_report_and_clear_eir(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 eir = I915_READ(EIR); - int pipe; - - if (!eir) - return; - - printk(KERN_ERR "render error detected, EIR: 0x%08x\n", - eir); - - if (IS_G4X(dev)) { - if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) { - u32 ipeir = I915_READ(IPEIR_I965); - - printk(KERN_ERR " IPEIR: 0x%08x\n", - I915_READ(IPEIR_I965)); - printk(KERN_ERR " IPEHR: 0x%08x\n", - I915_READ(IPEHR_I965)); - printk(KERN_ERR " INSTDONE: 0x%08x\n", - I915_READ(INSTDONE_I965)); - printk(KERN_ERR " INSTPS: 0x%08x\n", - I915_READ(INSTPS)); - printk(KERN_ERR " INSTDONE1: 0x%08x\n", - I915_READ(INSTDONE1)); - printk(KERN_ERR " ACTHD: 0x%08x\n", - I915_READ(ACTHD_I965)); - I915_WRITE(IPEIR_I965, ipeir); - POSTING_READ(IPEIR_I965); - } - if (eir & GM45_ERROR_PAGE_TABLE) { - u32 pgtbl_err = I915_READ(PGTBL_ER); - printk(KERN_ERR "page table error\n"); - printk(KERN_ERR " PGTBL_ER: 0x%08x\n", - pgtbl_err); - I915_WRITE(PGTBL_ER, pgtbl_err); - POSTING_READ(PGTBL_ER); - } - } - - if (!IS_GEN2(dev)) { - if (eir & I915_ERROR_PAGE_TABLE) { - u32 pgtbl_err = I915_READ(PGTBL_ER); - printk(KERN_ERR "page table error\n"); - printk(KERN_ERR " PGTBL_ER: 0x%08x\n", - pgtbl_err); - I915_WRITE(PGTBL_ER, pgtbl_err); - POSTING_READ(PGTBL_ER); - } - } - - if (eir & I915_ERROR_MEMORY_REFRESH) { - printk(KERN_ERR "memory refresh error:\n"); - for_each_pipe(pipe) - printk(KERN_ERR "pipe %c stat: 0x%08x\n", - pipe_name(pipe), I915_READ(PIPESTAT(pipe))); - /* pipestat has already been acked */ - } - if (eir & I915_ERROR_INSTRUCTION) { - printk(KERN_ERR "instruction error\n"); - printk(KERN_ERR " INSTPM: 0x%08x\n", - I915_READ(INSTPM)); - if (INTEL_INFO(dev)->gen < 4) { - u32 ipeir = I915_READ(IPEIR); - - printk(KERN_ERR " IPEIR: 0x%08x\n", - I915_READ(IPEIR)); - printk(KERN_ERR " IPEHR: 0x%08x\n", - I915_READ(IPEHR)); - printk(KERN_ERR " INSTDONE: 0x%08x\n", - I915_READ(INSTDONE)); - printk(KERN_ERR " ACTHD: 0x%08x\n", - I915_READ(ACTHD)); - I915_WRITE(IPEIR, ipeir); - POSTING_READ(IPEIR); - } else { - u32 ipeir = I915_READ(IPEIR_I965); - - printk(KERN_ERR " IPEIR: 0x%08x\n", - I915_READ(IPEIR_I965)); - printk(KERN_ERR " IPEHR: 0x%08x\n", - I915_READ(IPEHR_I965)); - printk(KERN_ERR " INSTDONE: 0x%08x\n", - I915_READ(INSTDONE_I965)); - printk(KERN_ERR " INSTPS: 0x%08x\n", - I915_READ(INSTPS)); - printk(KERN_ERR " INSTDONE1: 0x%08x\n", - I915_READ(INSTDONE1)); - printk(KERN_ERR " ACTHD: 0x%08x\n", - I915_READ(ACTHD_I965)); - I915_WRITE(IPEIR_I965, ipeir); - POSTING_READ(IPEIR_I965); - } - } - - I915_WRITE(EIR, eir); - POSTING_READ(EIR); - eir = I915_READ(EIR); - if (eir) { - /* - * some errors might have become stuck, - * mask them. - */ - DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); - I915_WRITE(EMR, I915_READ(EMR) | eir); - I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); - } -} - -/** - * i915_handle_error - handle an error interrupt - * @dev: drm device - * - * Do some basic checking of regsiter state at error interrupt time and - * dump it to the syslog. Also call i915_capture_error_state() to make - * sure we get a record and make it available in debugfs. Fire a uevent - * so userspace knows something bad happened (should trigger collection - * of a ring dump etc.). - */ -void i915_handle_error(struct drm_device *dev, bool wedged) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - i915_capture_error_state(dev); - i915_report_and_clear_eir(dev); - - if (wedged) { - INIT_COMPLETION(dev_priv->error_completion); - atomic_set(&dev_priv->mm.wedged, 1); - - /* - * Wakeup waiting processes so they don't hang - */ - wake_up_all(&dev_priv->ring[RCS].irq_queue); - if (HAS_BSD(dev)) - wake_up_all(&dev_priv->ring[VCS].irq_queue); - if (HAS_BLT(dev)) - wake_up_all(&dev_priv->ring[BCS].irq_queue); - } - - queue_work(dev_priv->wq, &dev_priv->error_work); -} - -static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_i915_gem_object *obj; - struct intel_unpin_work *work; - unsigned long flags; - bool stall_detected; - - /* Ignore early vblank irqs */ - if (intel_crtc == NULL) - return; - - spin_lock_irqsave(&dev->event_lock, flags); - work = intel_crtc->unpin_work; - - if (work == NULL || work->pending || !work->enable_stall_check) { - /* Either the pending flip IRQ arrived, or we're too early. Don't check */ - spin_unlock_irqrestore(&dev->event_lock, flags); - return; - } - - /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ - obj = work->pending_flip_obj; - if (INTEL_INFO(dev)->gen >= 4) { - int dspsurf = DSPSURF(intel_crtc->plane); - stall_detected = I915_READ(dspsurf) == obj->gtt_offset; - } else { - int dspaddr = DSPADDR(intel_crtc->plane); - stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + - crtc->y * crtc->fb->pitches[0] + - crtc->x * crtc->fb->bits_per_pixel/8); - } - - spin_unlock_irqrestore(&dev->event_lock, flags); - - if (stall_detected) { - DRM_DEBUG_DRIVER("Pageflip stall detected\n"); - intel_prepare_page_flip(dev, intel_crtc->plane); - } -} - -static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - struct drm_i915_master_private *master_priv; - u32 iir, new_iir; - u32 pipe_stats[I915_MAX_PIPES]; - u32 vblank_status; - int vblank = 0; - unsigned long irqflags; - int irq_received; - int ret = IRQ_NONE, pipe; - bool blc_event = false; - - atomic_inc(&dev_priv->irq_received); - - iir = I915_READ(IIR); - - if (INTEL_INFO(dev)->gen >= 4) - vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS; - else - vblank_status = PIPE_VBLANK_INTERRUPT_STATUS; - - for (;;) { - irq_received = iir != 0; - - /* Can't rely on pipestat interrupt bit in iir as it might - * have been cleared after the pipestat interrupt was received. - * It doesn't set the bit in iir again, but it still produces - * interrupts (for non-MSI). - */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) - i915_handle_error(dev, false); - - for_each_pipe(pipe) { - int reg = PIPESTAT(pipe); - pipe_stats[pipe] = I915_READ(reg); - - /* - * Clear the PIPE*STAT regs before the IIR - */ - if (pipe_stats[pipe] & 0x8000ffff) { - if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) - DRM_DEBUG_DRIVER("pipe %c underrun\n", - pipe_name(pipe)); - I915_WRITE(reg, pipe_stats[pipe]); - irq_received = 1; - } - } - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - - if (!irq_received) - break; - - ret = IRQ_HANDLED; - - /* Consume port. Then clear IIR or we'll miss events */ - if ((I915_HAS_HOTPLUG(dev)) && - (iir & I915_DISPLAY_PORT_INTERRUPT)) { - u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); - - DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", - hotplug_status); - if (hotplug_status & dev_priv->hotplug_supported_mask) - queue_work(dev_priv->wq, - &dev_priv->hotplug_work); - - I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); - I915_READ(PORT_HOTPLUG_STAT); - } - - I915_WRITE(IIR, iir); - new_iir = I915_READ(IIR); /* Flush posted writes */ - - if (dev->primary->master) { - master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } - - if (iir & I915_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[RCS]); - if (iir & I915_BSD_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS]); - - if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { - intel_prepare_page_flip(dev, 0); - if (dev_priv->flip_pending_is_done) - intel_finish_page_flip_plane(dev, 0); - } - - if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) { - intel_prepare_page_flip(dev, 1); - if (dev_priv->flip_pending_is_done) - intel_finish_page_flip_plane(dev, 1); - } - - for_each_pipe(pipe) { - if (pipe_stats[pipe] & vblank_status && - drm_handle_vblank(dev, pipe)) { - vblank++; - if (!dev_priv->flip_pending_is_done) { - i915_pageflip_stall_check(dev, pipe); - intel_finish_page_flip(dev, pipe); - } - } - - if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) - blc_event = true; - } - - - if (blc_event || (iir & I915_ASLE_INTERRUPT)) - intel_opregion_asle_intr(dev); - - /* With MSI, interrupts are only generated when iir - * transitions from zero to nonzero. If another bit got - * set while we were handling the existing iir bits, then - * we would never get another interrupt. - * - * This is fine on non-MSI as well, as if we hit this path - * we avoid exiting the interrupt handler only to generate - * another one. - * - * Note that for MSI this could cause a stray interrupt report - * if an interrupt landed in the time between writing IIR and - * the posting read. This should be rare enough to never - * trigger the 99% of 100,000 interrupts test for disabling - * stray interrupts. - */ - iir = new_iir; - } - - return ret; -} - -static int i915_emit_irq(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - - i915_kernel_lost_context(dev); - - DRM_DEBUG_DRIVER("\n"); - - dev_priv->counter++; - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->counter = 1; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_enqueue = dev_priv->counter; - - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->counter); - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); - } - - return dev_priv->counter; -} - -static int i915_wait_irq(struct drm_device * dev, int irq_nr) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - int ret = 0; - struct intel_ring_buffer *ring = LP_RING(dev_priv); - - DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, - READ_BREADCRUMB(dev_priv)); - - if (READ_BREADCRUMB(dev_priv) >= irq_nr) { - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - return 0; - } - - if (master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - - if (ring->irq_get(ring)) { - DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, - READ_BREADCRUMB(dev_priv) >= irq_nr); - ring->irq_put(ring); - } else if (wait_for(READ_BREADCRUMB(dev_priv) >= irq_nr, 3000)) - ret = -EBUSY; - - if (ret == -EBUSY) { - DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", - READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); - } - - return ret; -} - -/* Needs the lock as it touches the ring. - */ -int i915_irq_emit(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_emit_t *emit = data; - int result; - - if (!dev_priv || !LP_RING(dev_priv)->virtual_start) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - - mutex_lock(&dev->struct_mutex); - result = i915_emit_irq(dev); - mutex_unlock(&dev->struct_mutex); - - if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -/* Doesn't need the hardware lock. - */ -int i915_irq_wait(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_irq_wait_t *irqwait = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - return i915_wait_irq(dev, irqwait->irq_seq); -} - -/* Called from drm generic code, passed 'crtc' which - * we use as a pipe index - */ -static int i915_enable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - if (!i915_pipe_enabled(dev, pipe)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - if (INTEL_INFO(dev)->gen >= 4) - i915_enable_pipestat(dev_priv, pipe, - PIPE_START_VBLANK_INTERRUPT_ENABLE); - else - i915_enable_pipestat(dev_priv, pipe, - PIPE_VBLANK_INTERRUPT_ENABLE); - - /* maintain vblank delivery even in deep C-states */ - if (dev_priv->info->gen == 3) - I915_WRITE(INSTPM, INSTPM_AGPBUSY_DIS << 16); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - - return 0; -} - -static int ironlake_enable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - if (!i915_pipe_enabled(dev, pipe)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_enable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK : DE_PIPEB_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - - return 0; -} - -static int ivybridge_enable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - if (!i915_pipe_enabled(dev, pipe)) - return -EINVAL; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_enable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - - return 0; -} - -/* Called from drm generic code, passed 'crtc' which - * we use as a pipe index - */ -static void i915_disable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - if (dev_priv->info->gen == 3) - I915_WRITE(INSTPM, - INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS); - - i915_disable_pipestat(dev_priv, pipe, - PIPE_VBLANK_INTERRUPT_ENABLE | - PIPE_START_VBLANK_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -static void ironlake_disable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_disable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK : DE_PIPEB_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -static void ivybridge_disable_vblank(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ironlake_disable_display_irq(dev_priv, (pipe == 0) ? - DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); -} - -/* Set the vblank monitor pipe - */ -int i915_vblank_pipe_set(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - return 0; -} - -int i915_vblank_pipe_get(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_vblank_pipe_t *pipe = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - - return 0; -} - -/** - * Schedule buffer swap at given vertical blank. - */ -int i915_vblank_swap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* The delayed swap mechanism was fundamentally racy, and has been - * removed. The model was that the client requested a delayed flip/swap - * from the kernel, then waited for vblank before continuing to perform - * rendering. The problem was that the kernel might wake the client - * up before it dispatched the vblank swap (since the lock has to be - * held while touching the ringbuffer), in which case the client would - * clear and start the next frame before the swap occurred, and - * flicker would occur in addition to likely missing the vblank. - * - * In the absence of this ioctl, userland falls back to a correct path - * of waiting for a vblank, then dispatching the swap on its own. - * Context switching to userland and back is plenty fast enough for - * meeting the requirements of vblank swapping. - */ - return -EINVAL; -} - -static u32 -ring_last_seqno(struct intel_ring_buffer *ring) -{ - return list_entry(ring->request_list.prev, - struct drm_i915_gem_request, list)->seqno; -} - -static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) -{ - if (list_empty(&ring->request_list) || - i915_seqno_passed(ring->get_seqno(ring), ring_last_seqno(ring))) { - /* Issue a wake-up to catch stuck h/w. */ - if (ring->waiting_seqno && waitqueue_active(&ring->irq_queue)) { - DRM_ERROR("Hangcheck timer elapsed... %s idle [waiting on %d, at %d], missed IRQ?\n", - ring->name, - ring->waiting_seqno, - ring->get_seqno(ring)); - wake_up_all(&ring->irq_queue); - *err = true; - } - return true; - } - return false; -} - -static bool kick_ring(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 tmp = I915_READ_CTL(ring); - if (tmp & RING_WAIT) { - DRM_ERROR("Kicking stuck wait on %s\n", - ring->name); - I915_WRITE_CTL(ring, tmp); - return true; - } - return false; -} - -/** - * This is called when the chip hasn't reported back with completed - * batchbuffers in a long time. The first time this is called we simply record - * ACTHD. If ACTHD hasn't changed by the time the hangcheck timer elapses - * again, we assume the chip is wedged and try to fix it. - */ -void i915_hangcheck_elapsed(unsigned long data) -{ - struct drm_device *dev = (struct drm_device *)data; - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t acthd, instdone, instdone1, acthd_bsd, acthd_blt; - bool err = false; - - if (!i915_enable_hangcheck) - return; - - /* If all work is done then ACTHD clearly hasn't advanced. */ - if (i915_hangcheck_ring_idle(&dev_priv->ring[RCS], &err) && - i915_hangcheck_ring_idle(&dev_priv->ring[VCS], &err) && - i915_hangcheck_ring_idle(&dev_priv->ring[BCS], &err)) { - dev_priv->hangcheck_count = 0; - if (err) - goto repeat; - return; - } - - if (INTEL_INFO(dev)->gen < 4) { - instdone = I915_READ(INSTDONE); - instdone1 = 0; - } else { - instdone = I915_READ(INSTDONE_I965); - instdone1 = I915_READ(INSTDONE1); - } - acthd = intel_ring_get_active_head(&dev_priv->ring[RCS]); - acthd_bsd = HAS_BSD(dev) ? - intel_ring_get_active_head(&dev_priv->ring[VCS]) : 0; - acthd_blt = HAS_BLT(dev) ? - intel_ring_get_active_head(&dev_priv->ring[BCS]) : 0; - - if (dev_priv->last_acthd == acthd && - dev_priv->last_acthd_bsd == acthd_bsd && - dev_priv->last_acthd_blt == acthd_blt && - dev_priv->last_instdone == instdone && - dev_priv->last_instdone1 == instdone1) { - if (dev_priv->hangcheck_count++ > 1) { - DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); - i915_handle_error(dev, true); - - if (!IS_GEN2(dev)) { - /* Is the chip hanging on a WAIT_FOR_EVENT? - * If so we can simply poke the RB_WAIT bit - * and break the hang. This should work on - * all but the second generation chipsets. - */ - if (kick_ring(&dev_priv->ring[RCS])) - goto repeat; - - if (HAS_BSD(dev) && - kick_ring(&dev_priv->ring[VCS])) - goto repeat; - - if (HAS_BLT(dev) && - kick_ring(&dev_priv->ring[BCS])) - goto repeat; - } - - return; - } - } else { - dev_priv->hangcheck_count = 0; - - dev_priv->last_acthd = acthd; - dev_priv->last_acthd_bsd = acthd_bsd; - dev_priv->last_acthd_blt = acthd_blt; - dev_priv->last_instdone = instdone; - dev_priv->last_instdone1 = instdone1; - } - -repeat: - /* Reset timer case chip hangs without another request being added */ - mod_timer(&dev_priv->hangcheck_timer, - jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); -} - -/* drm_dma.h hooks -*/ -static void ironlake_irq_preinstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - atomic_set(&dev_priv->irq_received, 0); - - INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); - INIT_WORK(&dev_priv->error_work, i915_error_work_func); - if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) - INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); - - I915_WRITE(HWSTAM, 0xeffe); - - /* XXX hotplug from PCH */ - - I915_WRITE(DEIMR, 0xffffffff); - I915_WRITE(DEIER, 0x0); - POSTING_READ(DEIER); - - /* and GT */ - I915_WRITE(GTIMR, 0xffffffff); - I915_WRITE(GTIER, 0x0); - POSTING_READ(GTIER); - - /* south display irq */ - I915_WRITE(SDEIMR, 0xffffffff); - I915_WRITE(SDEIER, 0x0); - POSTING_READ(SDEIER); -} - -/* - * Enable digital hotplug on the PCH, and configure the DP short pulse - * duration to 2ms (which is the minimum in the Display Port spec) - * - * This register is the same on all known PCH chips. - */ - -static void ironlake_enable_pch_hotplug(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 hotplug; - - hotplug = I915_READ(PCH_PORT_HOTPLUG); - hotplug &= ~(PORTD_PULSE_DURATION_MASK|PORTC_PULSE_DURATION_MASK|PORTB_PULSE_DURATION_MASK); - hotplug |= PORTD_HOTPLUG_ENABLE | PORTD_PULSE_DURATION_2ms; - hotplug |= PORTC_HOTPLUG_ENABLE | PORTC_PULSE_DURATION_2ms; - hotplug |= PORTB_HOTPLUG_ENABLE | PORTB_PULSE_DURATION_2ms; - I915_WRITE(PCH_PORT_HOTPLUG, hotplug); -} - -static int ironlake_irq_postinstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - /* enable kind of interrupts always enabled */ - u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | - DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; - u32 render_irqs; - u32 hotplug_mask; - - DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); - if (HAS_BSD(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); - if (HAS_BLT(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - dev_priv->irq_mask = ~display_mask; - - /* should always can generate irq */ - I915_WRITE(DEIIR, I915_READ(DEIIR)); - I915_WRITE(DEIMR, dev_priv->irq_mask); - I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK); - POSTING_READ(DEIER); - - dev_priv->gt_irq_mask = ~0; - - I915_WRITE(GTIIR, I915_READ(GTIIR)); - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - - if (IS_GEN6(dev)) - render_irqs = - GT_USER_INTERRUPT | - GT_GEN6_BSD_USER_INTERRUPT | - GT_BLT_USER_INTERRUPT; - else - render_irqs = - GT_USER_INTERRUPT | - GT_PIPE_NOTIFY | - GT_BSD_USER_INTERRUPT; - I915_WRITE(GTIER, render_irqs); - POSTING_READ(GTIER); - - if (HAS_PCH_CPT(dev)) { - hotplug_mask = (SDE_CRT_HOTPLUG_CPT | - SDE_PORTB_HOTPLUG_CPT | - SDE_PORTC_HOTPLUG_CPT | - SDE_PORTD_HOTPLUG_CPT); - } else { - hotplug_mask = (SDE_CRT_HOTPLUG | - SDE_PORTB_HOTPLUG | - SDE_PORTC_HOTPLUG | - SDE_PORTD_HOTPLUG | - SDE_AUX_MASK); - } - - dev_priv->pch_irq_mask = ~hotplug_mask; - - I915_WRITE(SDEIIR, I915_READ(SDEIIR)); - I915_WRITE(SDEIMR, dev_priv->pch_irq_mask); - I915_WRITE(SDEIER, hotplug_mask); - POSTING_READ(SDEIER); - - ironlake_enable_pch_hotplug(dev); - - if (IS_IRONLAKE_M(dev)) { - /* Clear & enable PCU event interrupts */ - I915_WRITE(DEIIR, DE_PCU_EVENT); - I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT); - ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT); - } - - return 0; -} - -static int ivybridge_irq_postinstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - /* enable kind of interrupts always enabled */ - u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | - DE_PCH_EVENT_IVB | DE_PLANEA_FLIP_DONE_IVB | - DE_PLANEB_FLIP_DONE_IVB; - u32 render_irqs; - u32 hotplug_mask; - - DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); - if (HAS_BSD(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); - if (HAS_BLT(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - dev_priv->irq_mask = ~display_mask; - - /* should always can generate irq */ - I915_WRITE(DEIIR, I915_READ(DEIIR)); - I915_WRITE(DEIMR, dev_priv->irq_mask); - I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK_IVB | - DE_PIPEB_VBLANK_IVB); - POSTING_READ(DEIER); - - dev_priv->gt_irq_mask = ~0; - - I915_WRITE(GTIIR, I915_READ(GTIIR)); - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - - render_irqs = GT_USER_INTERRUPT | GT_GEN6_BSD_USER_INTERRUPT | - GT_BLT_USER_INTERRUPT; - I915_WRITE(GTIER, render_irqs); - POSTING_READ(GTIER); - - hotplug_mask = (SDE_CRT_HOTPLUG_CPT | - SDE_PORTB_HOTPLUG_CPT | - SDE_PORTC_HOTPLUG_CPT | - SDE_PORTD_HOTPLUG_CPT); - dev_priv->pch_irq_mask = ~hotplug_mask; - - I915_WRITE(SDEIIR, I915_READ(SDEIIR)); - I915_WRITE(SDEIMR, dev_priv->pch_irq_mask); - I915_WRITE(SDEIER, hotplug_mask); - POSTING_READ(SDEIER); - - ironlake_enable_pch_hotplug(dev); - - return 0; -} - -static void i915_driver_irq_preinstall(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe; - - atomic_set(&dev_priv->irq_received, 0); - - INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); - INIT_WORK(&dev_priv->error_work, i915_error_work_func); - - if (I915_HAS_HOTPLUG(dev)) { - I915_WRITE(PORT_HOTPLUG_EN, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - } - - I915_WRITE(HWSTAM, 0xeffe); - for_each_pipe(pipe) - I915_WRITE(PIPESTAT(pipe), 0); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - POSTING_READ(IER); -} - -/* - * Must be called after intel_modeset_init or hotplug interrupts won't be - * enabled correctly. - */ -static int i915_driver_irq_postinstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; - u32 error_mask; - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - - /* Unmask the interrupts that we always want on. */ - dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; - - dev_priv->pipestat[0] = 0; - dev_priv->pipestat[1] = 0; - - if (I915_HAS_HOTPLUG(dev)) { - /* Enable in IER... */ - enable_mask |= I915_DISPLAY_PORT_INTERRUPT; - /* and unmask in IMR */ - dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; - } - - /* - * Enable some error detection, note the instruction error mask - * bit is reserved, so we leave it masked. - */ - if (IS_G4X(dev)) { - error_mask = ~(GM45_ERROR_PAGE_TABLE | - GM45_ERROR_MEM_PRIV | - GM45_ERROR_CP_PRIV | - I915_ERROR_MEMORY_REFRESH); - } else { - error_mask = ~(I915_ERROR_PAGE_TABLE | - I915_ERROR_MEMORY_REFRESH); - } - I915_WRITE(EMR, error_mask); - - I915_WRITE(IMR, dev_priv->irq_mask); - I915_WRITE(IER, enable_mask); - POSTING_READ(IER); - - if (I915_HAS_HOTPLUG(dev)) { - u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); - - /* Note HDMI and DP share bits */ - if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) - hotplug_en |= HDMIB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) - hotplug_en |= HDMIC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) - hotplug_en |= HDMID_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) - hotplug_en |= SDVOC_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) - hotplug_en |= SDVOB_HOTPLUG_INT_EN; - if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { - hotplug_en |= CRT_HOTPLUG_INT_EN; - - /* Programming the CRT detection parameters tends - to generate a spurious hotplug event about three - seconds later. So just do it once. - */ - if (IS_G4X(dev)) - hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; - hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; - } - - /* Ignore TV since it's buggy */ - - I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); - } - - intel_opregion_enable_asle(dev); - - return 0; -} - -static void ironlake_irq_uninstall(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - if (!dev_priv) - return; - - dev_priv->vblank_pipe = 0; - - I915_WRITE(HWSTAM, 0xffffffff); - - I915_WRITE(DEIMR, 0xffffffff); - I915_WRITE(DEIER, 0x0); - I915_WRITE(DEIIR, I915_READ(DEIIR)); - - I915_WRITE(GTIMR, 0xffffffff); - I915_WRITE(GTIER, 0x0); - I915_WRITE(GTIIR, I915_READ(GTIIR)); - - I915_WRITE(SDEIMR, 0xffffffff); - I915_WRITE(SDEIER, 0x0); - I915_WRITE(SDEIIR, I915_READ(SDEIIR)); -} - -static void i915_driver_irq_uninstall(struct drm_device * dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipe; - - if (!dev_priv) - return; - - dev_priv->vblank_pipe = 0; - - if (I915_HAS_HOTPLUG(dev)) { - I915_WRITE(PORT_HOTPLUG_EN, 0); - I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); - } - - I915_WRITE(HWSTAM, 0xffffffff); - for_each_pipe(pipe) - I915_WRITE(PIPESTAT(pipe), 0); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - - for_each_pipe(pipe) - I915_WRITE(PIPESTAT(pipe), - I915_READ(PIPESTAT(pipe)) & 0x8000ffff); - I915_WRITE(IIR, I915_READ(IIR)); -} - -void intel_irq_init(struct drm_device *dev) -{ - dev->driver->get_vblank_counter = i915_get_vblank_counter; - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { - dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ - dev->driver->get_vblank_counter = gm45_get_vblank_counter; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; - else - dev->driver->get_vblank_timestamp = NULL; - dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; - - if (IS_IVYBRIDGE(dev)) { - /* Share pre & uninstall handlers with ILK/SNB */ - dev->driver->irq_handler = ivybridge_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ivybridge_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ivybridge_enable_vblank; - dev->driver->disable_vblank = ivybridge_disable_vblank; - } else if (HAS_PCH_SPLIT(dev)) { - dev->driver->irq_handler = ironlake_irq_handler; - dev->driver->irq_preinstall = ironlake_irq_preinstall; - dev->driver->irq_postinstall = ironlake_irq_postinstall; - dev->driver->irq_uninstall = ironlake_irq_uninstall; - dev->driver->enable_vblank = ironlake_enable_vblank; - dev->driver->disable_vblank = ironlake_disable_vblank; - } else { - dev->driver->irq_preinstall = i915_driver_irq_preinstall; - dev->driver->irq_postinstall = i915_driver_irq_postinstall; - dev->driver->irq_uninstall = i915_driver_irq_uninstall; - dev->driver->irq_handler = i915_driver_irq_handler; - dev->driver->enable_vblank = i915_enable_vblank; - dev->driver->disable_vblank = i915_disable_vblank; - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_reg.h deleted file mode 100644 index 29bfd899..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_reg.h +++ /dev/null @@ -1,3888 +0,0 @@ -/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef _I915_REG_H_ -#define _I915_REG_H_ - -#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) - -/* - * The Bridge device's PCI config space has information about the - * fb aperture size and the amount of pre-reserved memory. - * This is all handled in the intel-gtt.ko module. i915.ko only - * cares about the vga bit for the vga rbiter. - */ -#define INTEL_GMCH_CTRL 0x52 -#define INTEL_GMCH_VGA_DISABLE (1 << 1) - -/* PCI config space */ - -#define HPLLCC 0xc0 /* 855 only */ -#define GC_CLOCK_CONTROL_MASK (0xf << 0) -#define GC_CLOCK_133_200 (0 << 0) -#define GC_CLOCK_100_200 (1 << 0) -#define GC_CLOCK_100_133 (2 << 0) -#define GC_CLOCK_166_250 (3 << 0) -#define GCFGC2 0xda -#define GCFGC 0xf0 /* 915+ only */ -#define GC_LOW_FREQUENCY_ENABLE (1 << 7) -#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define GC_DISPLAY_CLOCK_MASK (7 << 4) -#define GM45_GC_RENDER_CLOCK_MASK (0xf << 0) -#define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0) -#define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0) -#define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0) -#define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0) -#define I965_GC_RENDER_CLOCK_MASK (0xf << 0) -#define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0) -#define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0) -#define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0) -#define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0) -#define I945_GC_RENDER_CLOCK_MASK (7 << 0) -#define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0) -#define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0) -#define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0) -#define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0) -#define I915_GC_RENDER_CLOCK_MASK (7 << 0) -#define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0) -#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0) -#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0) -#define LBB 0xf4 - -/* Graphics reset regs */ -#define I965_GDRST 0xc0 /* PCI config register */ -#define ILK_GDSR 0x2ca4 /* MCHBAR offset */ -#define GRDOM_FULL (0<<2) -#define GRDOM_RENDER (1<<2) -#define GRDOM_MEDIA (3<<2) - -#define GEN6_MBCUNIT_SNPCR 0x900c /* for LLC config */ -#define GEN6_MBC_SNPCR_SHIFT 21 -#define GEN6_MBC_SNPCR_MASK (3<<21) -#define GEN6_MBC_SNPCR_MAX (0<<21) -#define GEN6_MBC_SNPCR_MED (1<<21) -#define GEN6_MBC_SNPCR_LOW (2<<21) -#define GEN6_MBC_SNPCR_MIN (3<<21) /* only 1/16th of the cache is shared */ - -#define GEN6_MBCTL 0x0907c -#define GEN6_MBCTL_ENABLE_BOOT_FETCH (1 << 4) -#define GEN6_MBCTL_CTX_FETCH_NEEDED (1 << 3) -#define GEN6_MBCTL_BME_UPDATE_ENABLE (1 << 2) -#define GEN6_MBCTL_MAE_UPDATE_ENABLE (1 << 1) -#define GEN6_MBCTL_BOOT_FETCH_MECH (1 << 0) - -#define GEN6_GDRST 0x941c -#define GEN6_GRDOM_FULL (1 << 0) -#define GEN6_GRDOM_RENDER (1 << 1) -#define GEN6_GRDOM_MEDIA (1 << 2) -#define GEN6_GRDOM_BLT (1 << 3) - -/* PPGTT stuff */ -#define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) - -#define GEN6_PDE_VALID (1 << 0) -#define GEN6_PDE_LARGE_PAGE (2 << 0) /* use 32kb pages */ -/* gen6+ has bit 11-4 for physical addr bit 39-32 */ -#define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) - -#define GEN6_PTE_VALID (1 << 0) -#define GEN6_PTE_UNCACHED (1 << 1) -#define GEN6_PTE_CACHE_LLC (2 << 1) -#define GEN6_PTE_CACHE_LLC_MLC (3 << 1) -#define GEN6_PTE_CACHE_BITS (3 << 1) -#define GEN6_PTE_GFDT (1 << 3) -#define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) - -#define RING_PP_DIR_BASE(ring) ((ring)->mmio_base+0x228) -#define RING_PP_DIR_BASE_READ(ring) ((ring)->mmio_base+0x518) -#define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) -#define PP_DIR_DCLV_2G 0xffffffff - -#define GAM_ECOCHK 0x4090 -#define ECOCHK_SNB_BIT (1<<10) -#define ECOCHK_PPGTT_CACHE64B (0x3<<3) -#define ECOCHK_PPGTT_CACHE4B (0x0<<3) - -/* VGA stuff */ - -#define VGA_ST01_MDA 0x3ba -#define VGA_ST01_CGA 0x3da - -#define VGA_MSR_WRITE 0x3c2 -#define VGA_MSR_READ 0x3cc -#define VGA_MSR_MEM_EN (1<<1) -#define VGA_MSR_CGA_MODE (1<<0) - -#define VGA_SR_INDEX 0x3c4 -#define VGA_SR_DATA 0x3c5 - -#define VGA_AR_INDEX 0x3c0 -#define VGA_AR_VID_EN (1<<5) -#define VGA_AR_DATA_WRITE 0x3c0 -#define VGA_AR_DATA_READ 0x3c1 - -#define VGA_GR_INDEX 0x3ce -#define VGA_GR_DATA 0x3cf -/* GR05 */ -#define VGA_GR_MEM_READ_MODE_SHIFT 3 -#define VGA_GR_MEM_READ_MODE_PLANE 1 -/* GR06 */ -#define VGA_GR_MEM_MODE_MASK 0xc -#define VGA_GR_MEM_MODE_SHIFT 2 -#define VGA_GR_MEM_A0000_AFFFF 0 -#define VGA_GR_MEM_A0000_BFFFF 1 -#define VGA_GR_MEM_B0000_B7FFF 2 -#define VGA_GR_MEM_B0000_BFFFF 3 - -#define VGA_DACMASK 0x3c6 -#define VGA_DACRX 0x3c7 -#define VGA_DACWX 0x3c8 -#define VGA_DACDATA 0x3c9 - -#define VGA_CR_INDEX_MDA 0x3b4 -#define VGA_CR_DATA_MDA 0x3b5 -#define VGA_CR_INDEX_CGA 0x3d4 -#define VGA_CR_DATA_CGA 0x3d5 - -/* - * Memory interface instructions used by the kernel - */ -#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) - -#define MI_NOOP MI_INSTR(0, 0) -#define MI_USER_INTERRUPT MI_INSTR(0x02, 0) -#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0) -#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) -#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1) -#define MI_FLUSH MI_INSTR(0x04, 0) -#define MI_READ_FLUSH (1 << 0) -#define MI_EXE_FLUSH (1 << 1) -#define MI_NO_WRITE_FLUSH (1 << 2) -#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ -#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ -#define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ -#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) -#define MI_SUSPEND_FLUSH MI_INSTR(0x0b, 0) -#define MI_SUSPEND_FLUSH_EN (1<<0) -#define MI_REPORT_HEAD MI_INSTR(0x07, 0) -#define MI_OVERLAY_FLIP MI_INSTR(0x11, 0) -#define MI_OVERLAY_CONTINUE (0x0<<21) -#define MI_OVERLAY_ON (0x1<<21) -#define MI_OVERLAY_OFF (0x2<<21) -#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) -#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) -#define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) -#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) -#define MI_SET_CONTEXT MI_INSTR(0x18, 0) -#define MI_MM_SPACE_GTT (1<<8) -#define MI_MM_SPACE_PHYSICAL (0<<8) -#define MI_SAVE_EXT_STATE_EN (1<<3) -#define MI_RESTORE_EXT_STATE_EN (1<<2) -#define MI_FORCE_RESTORE (1<<1) -#define MI_RESTORE_INHIBIT (1<<0) -#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) -#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ -#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) -#define MI_STORE_DWORD_INDEX_SHIFT 2 -/* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM: - * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw - * simply ignores the register load under certain conditions. - * - One can actually load arbitrary many arbitrary registers: Simply issue x - * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! - */ -#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) -#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ -#define MI_INVALIDATE_TLB (1<<18) -#define MI_INVALIDATE_BSD (1<<7) -#define MI_BATCH_BUFFER MI_INSTR(0x30, 1) -#define MI_BATCH_NON_SECURE (1) -#define MI_BATCH_NON_SECURE_I965 (1<<8) -#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) -#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ -#define MI_SEMAPHORE_GLOBAL_GTT (1<<22) -#define MI_SEMAPHORE_UPDATE (1<<21) -#define MI_SEMAPHORE_COMPARE (1<<20) -#define MI_SEMAPHORE_REGISTER (1<<18) -#define MI_SEMAPHORE_SYNC_RV (2<<16) -#define MI_SEMAPHORE_SYNC_RB (0<<16) -#define MI_SEMAPHORE_SYNC_VR (0<<16) -#define MI_SEMAPHORE_SYNC_VB (2<<16) -#define MI_SEMAPHORE_SYNC_BR (2<<16) -#define MI_SEMAPHORE_SYNC_BV (0<<16) -#define MI_SEMAPHORE_SYNC_INVALID (1<<0) -/* - * 3D instructions used by the kernel - */ -#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags)) - -#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24)) -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) -#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16)) -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) -#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1) -#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) -#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4) -#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) -#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) -#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) -#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4) -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) -#define BLT_DEPTH_8 (0<<24) -#define BLT_DEPTH_16_565 (1<<24) -#define BLT_DEPTH_16_1555 (2<<24) -#define BLT_DEPTH_32 (3<<24) -#define BLT_ROP_GXCOPY (0xcc<<16) -#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */ -#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */ -#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2) -#define ASYNC_FLIP (1<<22) -#define DISPLAY_PLANE_A (0<<20) -#define DISPLAY_PLANE_B (1<<20) -#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|(len-2)) -#define PIPE_CONTROL_CS_STALL (1<<20) -#define PIPE_CONTROL_QW_WRITE (1<<14) -#define PIPE_CONTROL_DEPTH_STALL (1<<13) -#define PIPE_CONTROL_WRITE_FLUSH (1<<12) -#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */ -#define PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE (1<<11) /* MBZ on Ironlake */ -#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */ -#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9) -#define PIPE_CONTROL_NOTIFY (1<<8) -#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4) -#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3) -#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2) -#define PIPE_CONTROL_STALL_AT_SCOREBOARD (1<<1) -#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) -#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ - - -/* - * Reset registers - */ -#define DEBUG_RESET_I830 0x6070 -#define DEBUG_RESET_FULL (1<<7) -#define DEBUG_RESET_RENDER (1<<8) -#define DEBUG_RESET_DISPLAY (1<<9) - - -/* - * Fence registers - */ -#define FENCE_REG_830_0 0x2000 -#define FENCE_REG_945_8 0x3000 -#define I830_FENCE_START_MASK 0x07f80000 -#define I830_FENCE_TILING_Y_SHIFT 12 -#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) -#define I830_FENCE_PITCH_SHIFT 4 -#define I830_FENCE_REG_VALID (1<<0) -#define I915_FENCE_MAX_PITCH_VAL 4 -#define I830_FENCE_MAX_PITCH_VAL 6 -#define I830_FENCE_MAX_SIZE_VAL (1<<8) - -#define I915_FENCE_START_MASK 0x0ff00000 -#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) - -#define FENCE_REG_965_0 0x03000 -#define I965_FENCE_PITCH_SHIFT 2 -#define I965_FENCE_TILING_Y_SHIFT 1 -#define I965_FENCE_REG_VALID (1<<0) -#define I965_FENCE_MAX_PITCH_VAL 0x0400 - -#define FENCE_REG_SANDYBRIDGE_0 0x100000 -#define SANDYBRIDGE_FENCE_PITCH_SHIFT 32 - -/* control register for cpu gtt access */ -#define TILECTL 0x101000 -#define TILECTL_SWZCTL (1 << 0) -#define TILECTL_TLB_PREFETCH_DIS (1 << 2) -#define TILECTL_BACKSNOOP_DIS (1 << 3) - -/* - * Instruction and interrupt control regs - */ -#define PGTBL_ER 0x02024 -#define RENDER_RING_BASE 0x02000 -#define BSD_RING_BASE 0x04000 -#define GEN6_BSD_RING_BASE 0x12000 -#define BLT_RING_BASE 0x22000 -#define RING_TAIL(base) ((base)+0x30) -#define RING_HEAD(base) ((base)+0x34) -#define RING_START(base) ((base)+0x38) -#define RING_CTL(base) ((base)+0x3c) -#define RING_SYNC_0(base) ((base)+0x40) -#define RING_SYNC_1(base) ((base)+0x44) -#define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE)) -#define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE)) -#define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE)) -#define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE)) -#define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE)) -#define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE)) -#define RING_MAX_IDLE(base) ((base)+0x54) -#define RING_HWS_PGA(base) ((base)+0x80) -#define RING_HWS_PGA_GEN6(base) ((base)+0x2080) -#define ARB_MODE 0x04030 -#define ARB_MODE_SWIZZLE_SNB (1<<4) -#define ARB_MODE_SWIZZLE_IVB (1<<5) -#define ARB_MODE_ENABLE(x) GFX_MODE_ENABLE(x) -#define ARB_MODE_DISABLE(x) GFX_MODE_DISABLE(x) -#define RENDER_HWS_PGA_GEN7 (0x04080) -#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) -#define DONE_REG 0x40b0 -#define BSD_HWS_PGA_GEN7 (0x04180) -#define BLT_HWS_PGA_GEN7 (0x04280) -#define RING_ACTHD(base) ((base)+0x74) -#define RING_NOPID(base) ((base)+0x94) -#define RING_IMR(base) ((base)+0xa8) -#define TAIL_ADDR 0x001FFFF8 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 -#define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ -#define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ -#define RING_WAIT_SEMAPHORE (1<<10) /* gen6+ */ -#if 0 -#define PRB0_TAIL 0x02030 -#define PRB0_HEAD 0x02034 -#define PRB0_START 0x02038 -#define PRB0_CTL 0x0203c -#define PRB1_TAIL 0x02040 /* 915+ only */ -#define PRB1_HEAD 0x02044 /* 915+ only */ -#define PRB1_START 0x02048 /* 915+ only */ -#define PRB1_CTL 0x0204c /* 915+ only */ -#endif -#define IPEIR_I965 0x02064 -#define IPEHR_I965 0x02068 -#define INSTDONE_I965 0x0206c -#define RING_IPEIR(base) ((base)+0x64) -#define RING_IPEHR(base) ((base)+0x68) -#define RING_INSTDONE(base) ((base)+0x6c) -#define RING_INSTPS(base) ((base)+0x70) -#define RING_DMA_FADD(base) ((base)+0x78) -#define RING_INSTPM(base) ((base)+0xc0) -#define INSTPS 0x02070 /* 965+ only */ -#define INSTDONE1 0x0207c /* 965+ only */ -#define ACTHD_I965 0x02074 -#define HWS_PGA 0x02080 -#define HWS_ADDRESS_MASK 0xfffff000 -#define HWS_START_ADDRESS_SHIFT 4 -#define PWRCTXA 0x2088 /* 965GM+ only */ -#define PWRCTX_EN (1<<0) -#define IPEIR 0x02088 -#define IPEHR 0x0208c -#define INSTDONE 0x02090 -#define NOPID 0x02094 -#define HWSTAM 0x02098 - -#define ERROR_GEN6 0x040a0 - -/* GM45+ chicken bits -- debug workaround bits that may be required - * for various sorts of correct behavior. The top 16 bits of each are - * the enables for writing to the corresponding low bit. - */ -#define _3D_CHICKEN 0x02084 -#define _3D_CHICKEN2 0x0208c -/* Disables pipelining of read flushes past the SF-WIZ interface. - * Required on all Ironlake steppings according to the B-Spec, but the - * particular danger of not doing so is not specified. - */ -# define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) -#define _3D_CHICKEN3 0x02090 - -#define MI_MODE 0x0209c -# define VS_TIMER_DISPATCH (1 << 6) -# define MI_FLUSH_ENABLE (1 << 12) - -#define GFX_MODE 0x02520 -#define GFX_MODE_GEN7 0x0229c -#define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) -#define GFX_RUN_LIST_ENABLE (1<<15) -#define GFX_TLB_INVALIDATE_ALWAYS (1<<13) -#define GFX_SURFACE_FAULT_ENABLE (1<<12) -#define GFX_REPLAY_MODE (1<<11) -#define GFX_PSMI_GRANULARITY (1<<10) -#define GFX_PPGTT_ENABLE (1<<9) - -#define GFX_MODE_ENABLE(bit) (((bit) << 16) | (bit)) -#define GFX_MODE_DISABLE(bit) (((bit) << 16) | (0)) - -#define SCPD0 0x0209c /* 915+ only */ -#define IER 0x020a0 -#define IIR 0x020a4 -#define IMR 0x020a8 -#define ISR 0x020ac -#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) -#define I915_DISPLAY_PORT_INTERRUPT (1<<17) -#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) -#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14) /* p-state */ -#define I915_HWB_OOM_INTERRUPT (1<<13) -#define I915_SYNC_STATUS_INTERRUPT (1<<12) -#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11) -#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10) -#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9) -#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8) -#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7) -#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) -#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) -#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) -#define I915_DEBUG_INTERRUPT (1<<2) -#define I915_USER_INTERRUPT (1<<1) -#define I915_ASLE_INTERRUPT (1<<0) -#define I915_BSD_USER_INTERRUPT (1<<25) -#define EIR 0x020b0 -#define EMR 0x020b4 -#define ESR 0x020b8 -#define GM45_ERROR_PAGE_TABLE (1<<5) -#define GM45_ERROR_MEM_PRIV (1<<4) -#define I915_ERROR_PAGE_TABLE (1<<4) -#define GM45_ERROR_CP_PRIV (1<<3) -#define I915_ERROR_MEMORY_REFRESH (1<<1) -#define I915_ERROR_INSTRUCTION (1<<0) -#define INSTPM 0x020c0 -#define INSTPM_SELF_EN (1<<12) /* 915GM only */ -#define INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts - will not assert AGPBUSY# and will only - be delivered when out of C3. */ -#define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */ -#define ACTHD 0x020c8 -#define FW_BLC 0x020d8 -#define FW_BLC2 0x020dc -#define FW_BLC_SELF 0x020e0 /* 915+ only */ -#define FW_BLC_SELF_EN_MASK (1<<31) -#define FW_BLC_SELF_FIFO_MASK (1<<16) /* 945 only */ -#define FW_BLC_SELF_EN (1<<15) /* 945 only */ -#define MM_BURST_LENGTH 0x00700000 -#define MM_FIFO_WATERMARK 0x0001F000 -#define LM_BURST_LENGTH 0x00000700 -#define LM_FIFO_WATERMARK 0x0000001F -#define MI_ARB_STATE 0x020e4 /* 915+ only */ -#define MI_ARB_MASK_SHIFT 16 /* shift for enable bits */ - -/* Make render/texture TLB fetches lower priorty than associated data - * fetches. This is not turned on by default - */ -#define MI_ARB_RENDER_TLB_LOW_PRIORITY (1 << 15) - -/* Isoch request wait on GTT enable (Display A/B/C streams). - * Make isoch requests stall on the TLB update. May cause - * display underruns (test mode only) - */ -#define MI_ARB_ISOCH_WAIT_GTT (1 << 14) - -/* Block grant count for isoch requests when block count is - * set to a finite value. - */ -#define MI_ARB_BLOCK_GRANT_MASK (3 << 12) -#define MI_ARB_BLOCK_GRANT_8 (0 << 12) /* for 3 display planes */ -#define MI_ARB_BLOCK_GRANT_4 (1 << 12) /* for 2 display planes */ -#define MI_ARB_BLOCK_GRANT_2 (2 << 12) /* for 1 display plane */ -#define MI_ARB_BLOCK_GRANT_0 (3 << 12) /* don't use */ - -/* Enable render writes to complete in C2/C3/C4 power states. - * If this isn't enabled, render writes are prevented in low - * power states. That seems bad to me. - */ -#define MI_ARB_C3_LP_WRITE_ENABLE (1 << 11) - -/* This acknowledges an async flip immediately instead - * of waiting for 2TLB fetches. - */ -#define MI_ARB_ASYNC_FLIP_ACK_IMMEDIATE (1 << 10) - -/* Enables non-sequential data reads through arbiter - */ -#define MI_ARB_DUAL_DATA_PHASE_DISABLE (1 << 9) - -/* Disable FSB snooping of cacheable write cycles from binner/render - * command stream - */ -#define MI_ARB_CACHE_SNOOP_DISABLE (1 << 8) - -/* Arbiter time slice for non-isoch streams */ -#define MI_ARB_TIME_SLICE_MASK (7 << 5) -#define MI_ARB_TIME_SLICE_1 (0 << 5) -#define MI_ARB_TIME_SLICE_2 (1 << 5) -#define MI_ARB_TIME_SLICE_4 (2 << 5) -#define MI_ARB_TIME_SLICE_6 (3 << 5) -#define MI_ARB_TIME_SLICE_8 (4 << 5) -#define MI_ARB_TIME_SLICE_10 (5 << 5) -#define MI_ARB_TIME_SLICE_14 (6 << 5) -#define MI_ARB_TIME_SLICE_16 (7 << 5) - -/* Low priority grace period page size */ -#define MI_ARB_LOW_PRIORITY_GRACE_4KB (0 << 4) /* default */ -#define MI_ARB_LOW_PRIORITY_GRACE_8KB (1 << 4) - -/* Disable display A/B trickle feed */ -#define MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE (1 << 2) - -/* Set display plane priority */ -#define MI_ARB_DISPLAY_PRIORITY_A_B (0 << 0) /* display A > display B */ -#define MI_ARB_DISPLAY_PRIORITY_B_A (1 << 0) /* display B > display A */ - -#define CACHE_MODE_0 0x02120 /* 915+ only */ -#define CM0_MASK_SHIFT 16 -#define CM0_IZ_OPT_DISABLE (1<<6) -#define CM0_ZR_OPT_DISABLE (1<<5) -#define CM0_STC_EVICT_DISABLE_LRA_SNB (1<<5) -#define CM0_DEPTH_EVICT_DISABLE (1<<4) -#define CM0_COLOR_EVICT_DISABLE (1<<3) -#define CM0_DEPTH_WRITE_DISABLE (1<<1) -#define CM0_RC_OP_FLUSH_DISABLE (1<<0) -#define BB_ADDR 0x02140 /* 8 bytes */ -#define GFX_FLSH_CNTL 0x02170 /* 915+ only */ -#define ECOSKPD 0x021d0 -#define ECO_GATING_CX_ONLY (1<<3) -#define ECO_FLIP_DONE (1<<0) - -/* GEN6 interrupt control */ -#define GEN6_RENDER_HWSTAM 0x2098 -#define GEN6_RENDER_IMR 0x20a8 -#define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) -#define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) -#define GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED (1 << 6) -#define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) -#define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) -#define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) -#define GEN6_RENDER_SYNC_STATUS (1 << 2) -#define GEN6_RENDER_DEBUG_INTERRUPT (1 << 1) -#define GEN6_RENDER_USER_INTERRUPT (1 << 0) - -#define GEN6_BLITTER_HWSTAM 0x22098 -#define GEN6_BLITTER_IMR 0x220a8 -#define GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT (1 << 26) -#define GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR (1 << 25) -#define GEN6_BLITTER_SYNC_STATUS (1 << 24) -#define GEN6_BLITTER_USER_INTERRUPT (1 << 22) - -#define GEN6_BLITTER_ECOSKPD 0x221d0 -#define GEN6_BLITTER_LOCK_SHIFT 16 -#define GEN6_BLITTER_FBC_NOTIFY (1<<3) - -#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050 -#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK (1 << 16) -#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE (1 << 0) -#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 -#define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) - -#define GEN6_BSD_HWSTAM 0x12098 -#define GEN6_BSD_IMR 0x120a8 -#define GEN6_BSD_USER_INTERRUPT (1 << 12) - -#define GEN6_BSD_RNCID 0x12198 - -#define GEN7_FF_THREAD_MODE 0x20a0 -#define GEN7_FF_SCHED_MASK 0x0077070 -#define GEN7_FF_TS_SCHED_HS1 (0x5<<16) -#define GEN7_FF_TS_SCHED_HS0 (0x3<<16) -#define GEN7_FF_TS_SCHED_LOAD_BALANCE (0x1<<16) -#define GEN7_FF_TS_SCHED_HW (0x0<<16) /* Default */ -#define GEN7_FF_VS_SCHED_HS1 (0x5<<12) -#define GEN7_FF_VS_SCHED_HS0 (0x3<<12) -#define GEN7_FF_VS_SCHED_LOAD_BALANCE (0x1<<12) /* Default */ -#define GEN7_FF_VS_SCHED_HW (0x0<<12) -#define GEN7_FF_DS_SCHED_HS1 (0x5<<4) -#define GEN7_FF_DS_SCHED_HS0 (0x3<<4) -#define GEN7_FF_DS_SCHED_LOAD_BALANCE (0x1<<4) /* Default */ -#define GEN7_FF_DS_SCHED_HW (0x0<<4) - -/* - * Framebuffer compression (915+ only) - */ - -#define FBC_CFB_BASE 0x03200 /* 4k page aligned */ -#define FBC_LL_BASE 0x03204 /* 4k page aligned */ -#define FBC_CONTROL 0x03208 -#define FBC_CTL_EN (1<<31) -#define FBC_CTL_PERIODIC (1<<30) -#define FBC_CTL_INTERVAL_SHIFT (16) -#define FBC_CTL_UNCOMPRESSIBLE (1<<14) -#define FBC_CTL_C3_IDLE (1<<13) -#define FBC_CTL_STRIDE_SHIFT (5) -#define FBC_CTL_FENCENO (1<<0) -#define FBC_COMMAND 0x0320c -#define FBC_CMD_COMPRESS (1<<0) -#define FBC_STATUS 0x03210 -#define FBC_STAT_COMPRESSING (1<<31) -#define FBC_STAT_COMPRESSED (1<<30) -#define FBC_STAT_MODIFIED (1<<29) -#define FBC_STAT_CURRENT_LINE (1<<0) -#define FBC_CONTROL2 0x03214 -#define FBC_CTL_FENCE_DBL (0<<4) -#define FBC_CTL_IDLE_IMM (0<<2) -#define FBC_CTL_IDLE_FULL (1<<2) -#define FBC_CTL_IDLE_LINE (2<<2) -#define FBC_CTL_IDLE_DEBUG (3<<2) -#define FBC_CTL_CPU_FENCE (1<<1) -#define FBC_CTL_PLANEA (0<<0) -#define FBC_CTL_PLANEB (1<<0) -#define FBC_FENCE_OFF 0x0321b -#define FBC_TAG 0x03300 - -#define FBC_LL_SIZE (1536) - -/* Framebuffer compression for GM45+ */ -#define DPFC_CB_BASE 0x3200 -#define DPFC_CONTROL 0x3208 -#define DPFC_CTL_EN (1<<31) -#define DPFC_CTL_PLANEA (0<<30) -#define DPFC_CTL_PLANEB (1<<30) -#define DPFC_CTL_FENCE_EN (1<<29) -#define DPFC_CTL_PERSISTENT_MODE (1<<25) -#define DPFC_SR_EN (1<<10) -#define DPFC_CTL_LIMIT_1X (0<<6) -#define DPFC_CTL_LIMIT_2X (1<<6) -#define DPFC_CTL_LIMIT_4X (2<<6) -#define DPFC_RECOMP_CTL 0x320c -#define DPFC_RECOMP_STALL_EN (1<<27) -#define DPFC_RECOMP_STALL_WM_SHIFT (16) -#define DPFC_RECOMP_STALL_WM_MASK (0x07ff0000) -#define DPFC_RECOMP_TIMER_COUNT_SHIFT (0) -#define DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f) -#define DPFC_STATUS 0x3210 -#define DPFC_INVAL_SEG_SHIFT (16) -#define DPFC_INVAL_SEG_MASK (0x07ff0000) -#define DPFC_COMP_SEG_SHIFT (0) -#define DPFC_COMP_SEG_MASK (0x000003ff) -#define DPFC_STATUS2 0x3214 -#define DPFC_FENCE_YOFF 0x3218 -#define DPFC_CHICKEN 0x3224 -#define DPFC_HT_MODIFY (1<<31) - -/* Framebuffer compression for Ironlake */ -#define ILK_DPFC_CB_BASE 0x43200 -#define ILK_DPFC_CONTROL 0x43208 -/* The bit 28-8 is reserved */ -#define DPFC_RESERVED (0x1FFFFF00) -#define ILK_DPFC_RECOMP_CTL 0x4320c -#define ILK_DPFC_STATUS 0x43210 -#define ILK_DPFC_FENCE_YOFF 0x43218 -#define ILK_DPFC_CHICKEN 0x43224 -#define ILK_FBC_RT_BASE 0x2128 -#define ILK_FBC_RT_VALID (1<<0) - -#define ILK_DISPLAY_CHICKEN1 0x42000 -#define ILK_FBCQ_DIS (1<<22) -#define ILK_PABSTRETCH_DIS (1<<21) - - -/* - * Framebuffer compression for Sandybridge - * - * The following two registers are of type GTTMMADR - */ -#define SNB_DPFC_CTL_SA 0x100100 -#define SNB_CPU_FENCE_ENABLE (1<<29) -#define DPFC_CPU_FENCE_OFFSET 0x100104 - - -/* - * GPIO regs - */ -#define GPIOA 0x5010 -#define GPIOB 0x5014 -#define GPIOC 0x5018 -#define GPIOD 0x501c -#define GPIOE 0x5020 -#define GPIOF 0x5024 -#define GPIOG 0x5028 -#define GPIOH 0x502c -# define GPIO_CLOCK_DIR_MASK (1 << 0) -# define GPIO_CLOCK_DIR_IN (0 << 1) -# define GPIO_CLOCK_DIR_OUT (1 << 1) -# define GPIO_CLOCK_VAL_MASK (1 << 2) -# define GPIO_CLOCK_VAL_OUT (1 << 3) -# define GPIO_CLOCK_VAL_IN (1 << 4) -# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) -# define GPIO_DATA_DIR_MASK (1 << 8) -# define GPIO_DATA_DIR_IN (0 << 9) -# define GPIO_DATA_DIR_OUT (1 << 9) -# define GPIO_DATA_VAL_MASK (1 << 10) -# define GPIO_DATA_VAL_OUT (1 << 11) -# define GPIO_DATA_VAL_IN (1 << 12) -# define GPIO_DATA_PULLUP_DISABLE (1 << 13) - -#define GMBUS0 0x5100 /* clock/port select */ -#define GMBUS_RATE_100KHZ (0<<8) -#define GMBUS_RATE_50KHZ (1<<8) -#define GMBUS_RATE_400KHZ (2<<8) /* reserved on Pineview */ -#define GMBUS_RATE_1MHZ (3<<8) /* reserved on Pineview */ -#define GMBUS_HOLD_EXT (1<<7) /* 300ns hold time, rsvd on Pineview */ -#define GMBUS_PORT_DISABLED 0 -#define GMBUS_PORT_SSC 1 -#define GMBUS_PORT_VGADDC 2 -#define GMBUS_PORT_PANEL 3 -#define GMBUS_PORT_DPC 4 /* HDMIC */ -#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */ - /* 6 reserved */ -#define GMBUS_PORT_DPD 7 /* HDMID */ -#define GMBUS_NUM_PORTS 8 -#define GMBUS1 0x5104 /* command/status */ -#define GMBUS_SW_CLR_INT (1<<31) -#define GMBUS_SW_RDY (1<<30) -#define GMBUS_ENT (1<<29) /* enable timeout */ -#define GMBUS_CYCLE_NONE (0<<25) -#define GMBUS_CYCLE_WAIT (1<<25) -#define GMBUS_CYCLE_INDEX (2<<25) -#define GMBUS_CYCLE_STOP (4<<25) -#define GMBUS_BYTE_COUNT_SHIFT 16 -#define GMBUS_SLAVE_INDEX_SHIFT 8 -#define GMBUS_SLAVE_ADDR_SHIFT 1 -#define GMBUS_SLAVE_READ (1<<0) -#define GMBUS_SLAVE_WRITE (0<<0) -#define GMBUS2 0x5108 /* status */ -#define GMBUS_INUSE (1<<15) -#define GMBUS_HW_WAIT_PHASE (1<<14) -#define GMBUS_STALL_TIMEOUT (1<<13) -#define GMBUS_INT (1<<12) -#define GMBUS_HW_RDY (1<<11) -#define GMBUS_SATOER (1<<10) -#define GMBUS_ACTIVE (1<<9) -#define GMBUS3 0x510c /* data buffer bytes 3-0 */ -#define GMBUS4 0x5110 /* interrupt mask (Pineview+) */ -#define GMBUS_SLAVE_TIMEOUT_EN (1<<4) -#define GMBUS_NAK_EN (1<<3) -#define GMBUS_IDLE_EN (1<<2) -#define GMBUS_HW_WAIT_EN (1<<1) -#define GMBUS_HW_RDY_EN (1<<0) -#define GMBUS5 0x5120 /* byte index */ -#define GMBUS_2BYTE_INDEX_EN (1<<31) - -/* - * Clock control & power management - */ - -#define VGA0 0x6000 -#define VGA1 0x6004 -#define VGA_PD 0x6010 -#define VGA0_PD_P2_DIV_4 (1 << 7) -#define VGA0_PD_P1_DIV_2 (1 << 5) -#define VGA0_PD_P1_SHIFT 0 -#define VGA0_PD_P1_MASK (0x1f << 0) -#define VGA1_PD_P2_DIV_4 (1 << 15) -#define VGA1_PD_P1_DIV_2 (1 << 13) -#define VGA1_PD_P1_SHIFT 8 -#define VGA1_PD_P1_MASK (0x1f << 8) -#define _DPLL_A 0x06014 -#define _DPLL_B 0x06018 -#define DPLL(pipe) _PIPE(pipe, _DPLL_A, _DPLL_B) -#define DPLL_VCO_ENABLE (1 << 31) -#define DPLL_DVO_HIGH_SPEED (1 << 30) -#define DPLL_SYNCLOCK_ENABLE (1 << 29) -#define DPLL_VGA_MODE_DIS (1 << 28) -#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -#define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -#define DPLL_MODE_MASK (3 << 26) -#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ -#define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ - -#define SRX_INDEX 0x3c4 -#define SRX_DATA 0x3c5 -#define SR01 1 -#define SR01_SCREEN_OFF (1<<5) - -#define PPCR 0x61204 -#define PPCR_ON (1<<0) - -#define DVOB 0x61140 -#define DVOB_ON (1<<31) -#define DVOC 0x61160 -#define DVOC_ON (1<<31) -#define LVDS 0x61180 -#define LVDS_ON (1<<31) - -/* Scratch pad debug 0 reg: - */ -#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/* - * The i830 generation, in LVDS mode, defines P1 as the bit number set within - * this field (only one bit may be set). - */ -#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -#define DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW 15 -/* i830, required in DVO non-gang */ -#define PLL_P2_DIVIDE_BY_4 (1 << 23) -#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -#define PLL_REF_INPUT_DREFCLK (0 << 13) -#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ -#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -#define PLL_REF_INPUT_MASK (3 << 13) -#define PLL_LOAD_PULSE_PHASE_SHIFT 9 -/* Ironlake */ -# define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9 -# define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9) -# define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x)-1) << 9) -# define DPLL_FPA1_P1_POST_DIV_SHIFT 0 -# define DPLL_FPA1_P1_POST_DIV_MASK 0xff - -/* - * Parallel to Serial Load Pulse phase selection. - * Selects the phase for the 10X DPLL clock for the PCIe - * digital display port. The range is 4 to 13; 10 or more - * is just a flip delay. The default is 6 - */ -#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -#define DISPLAY_RATE_SELECT_FPA1 (1 << 8) -/* - * SDVO multiplier for 945G/GM. Not used on 965. - */ -#define SDVO_MULTIPLIER_MASK 0x000000ff -#define SDVO_MULTIPLIER_SHIFT_HIRES 4 -#define SDVO_MULTIPLIER_SHIFT_VGA 0 -#define _DPLL_A_MD 0x0601c /* 965+ only */ -/* - * UDI pixel divider, controlling how many pixels are stuffed into a packet. - * - * Value is pixels minus 1. Must be set to 1 pixel for SDVO. - */ -#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -#define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/* - * SDVO/UDI pixel multiplier. - * - * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus - * clock rate is 10 times the DPLL clock. At low resolution/refresh rate - * modes, the bus rate would be below the limits, so SDVO allows for stuffing - * dummy bytes in the datastream at an increased clock rate, with both sides of - * the link knowing how many bytes are fill. - * - * So, for a mode with a dotclock of 65Mhz, we would want to double the clock - * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be - * set to 130Mhz, and the SDVO multiplier set to 2x in this register and - * through an SDVO command. - * - * This register field has values of multiplication factor minus 1, with - * a maximum multiplier of 5 for SDVO. - */ -#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/* - * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. - * This best be set to the default value (3) or the CRT won't work. No, - * I don't entirely understand what this does... - */ -#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 -#define _DPLL_B_MD 0x06020 /* 965+ only */ -#define DPLL_MD(pipe) _PIPE(pipe, _DPLL_A_MD, _DPLL_B_MD) -#define _FPA0 0x06040 -#define _FPA1 0x06044 -#define _FPB0 0x06048 -#define _FPB1 0x0604c -#define FP0(pipe) _PIPE(pipe, _FPA0, _FPB0) -#define FP1(pipe) _PIPE(pipe, _FPA1, _FPB1) -#define FP_N_DIV_MASK 0x003f0000 -#define FP_N_PINEVIEW_DIV_MASK 0x00ff0000 -#define FP_N_DIV_SHIFT 16 -#define FP_M1_DIV_MASK 0x00003f00 -#define FP_M1_DIV_SHIFT 8 -#define FP_M2_DIV_MASK 0x0000003f -#define FP_M2_PINEVIEW_DIV_MASK 0x000000ff -#define FP_M2_DIV_SHIFT 0 -#define DPLL_TEST 0x606c -#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -#define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -#define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -#define DPLLB_TEST_N_BYPASS (1 << 19) -#define DPLLB_TEST_M_BYPASS (1 << 18) -#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -#define DPLLA_TEST_N_BYPASS (1 << 3) -#define DPLLA_TEST_M_BYPASS (1 << 2) -#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) -#define D_STATE 0x6104 -#define DSTATE_GFX_RESET_I830 (1<<6) -#define DSTATE_PLL_D3_OFF (1<<3) -#define DSTATE_GFX_CLOCK_GATING (1<<1) -#define DSTATE_DOT_CLOCK_GATING (1<<0) -#define DSPCLK_GATE_D 0x6200 -# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ -# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ -# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ -# define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ -# define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ -# define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ -# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ -# define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ -# define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ -# define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ -# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ -# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ -# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ -# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ -# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ -# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ -# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ -# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ -# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ -# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) -# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) -# define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) -# define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) -# define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ -# define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ -# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ -# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) -# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) -/** - * This bit must be set on the 830 to prevent hangs when turning off the - * overlay scaler. - */ -# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) -# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) -# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) -# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ -# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ - -#define RENCLK_GATE_D1 0x6204 -# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */ -# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */ -# define PC_FE_CLOCK_GATE_DISABLE (1 << 11) -# define PC_BE_CLOCK_GATE_DISABLE (1 << 10) -# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9) -# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8) -# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7) -# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6) -# define MAG_CLOCK_GATE_DISABLE (1 << 5) -/** This bit must be unset on 855,865 */ -# define MECI_CLOCK_GATE_DISABLE (1 << 4) -# define DCMP_CLOCK_GATE_DISABLE (1 << 3) -# define MEC_CLOCK_GATE_DISABLE (1 << 2) -# define MECO_CLOCK_GATE_DISABLE (1 << 1) -/** This bit must be set on 855,865. */ -# define SV_CLOCK_GATE_DISABLE (1 << 0) -# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16) -# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15) -# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14) -# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13) -# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12) -# define I915_WM_CLOCK_GATE_DISABLE (1 << 11) -# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10) -# define I915_PI_CLOCK_GATE_DISABLE (1 << 9) -# define I915_DI_CLOCK_GATE_DISABLE (1 << 8) -# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7) -# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6) -# define I915_SC_CLOCK_GATE_DISABLE (1 << 5) -# define I915_FL_CLOCK_GATE_DISABLE (1 << 4) -# define I915_DM_CLOCK_GATE_DISABLE (1 << 3) -# define I915_PS_CLOCK_GATE_DISABLE (1 << 2) -# define I915_CC_CLOCK_GATE_DISABLE (1 << 1) -# define I915_BY_CLOCK_GATE_DISABLE (1 << 0) - -# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30) -/** This bit must always be set on 965G/965GM */ -# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29) -# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28) -# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27) -# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26) -# define I965_GW_CLOCK_GATE_DISABLE (1 << 25) -# define I965_TD_CLOCK_GATE_DISABLE (1 << 24) -/** This bit must always be set on 965G */ -# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23) -# define I965_IC_CLOCK_GATE_DISABLE (1 << 22) -# define I965_EU_CLOCK_GATE_DISABLE (1 << 21) -# define I965_IF_CLOCK_GATE_DISABLE (1 << 20) -# define I965_TC_CLOCK_GATE_DISABLE (1 << 19) -# define I965_SO_CLOCK_GATE_DISABLE (1 << 17) -# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16) -# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15) -# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14) -# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13) -# define I965_EM_CLOCK_GATE_DISABLE (1 << 12) -# define I965_UC_CLOCK_GATE_DISABLE (1 << 11) -# define I965_SI_CLOCK_GATE_DISABLE (1 << 6) -# define I965_MT_CLOCK_GATE_DISABLE (1 << 5) -# define I965_PL_CLOCK_GATE_DISABLE (1 << 4) -# define I965_DG_CLOCK_GATE_DISABLE (1 << 3) -# define I965_QC_CLOCK_GATE_DISABLE (1 << 2) -# define I965_FT_CLOCK_GATE_DISABLE (1 << 1) -# define I965_DM_CLOCK_GATE_DISABLE (1 << 0) - -#define RENCLK_GATE_D2 0x6208 -#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) -#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) -#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) -#define RAMCLK_GATE_D 0x6210 /* CRL only */ -#define DEUC 0x6214 /* CRL only */ - -/* - * Palette regs - */ - -#define _PALETTE_A 0x0a000 -#define _PALETTE_B 0x0a800 -#define PALETTE(pipe) _PIPE(pipe, _PALETTE_A, _PALETTE_B) - -/* MCH MMIO space */ - -/* - * MCHBAR mirror. - * - * This mirrors the MCHBAR MMIO space whose location is determined by - * device 0 function 0's pci config register 0x44 or 0x48 and matches it in - * every way. It is not accessible from the CP register read instructions. - * - */ -#define MCHBAR_MIRROR_BASE 0x10000 - -#define MCHBAR_MIRROR_BASE_SNB 0x140000 - -/** 915-945 and GM965 MCH register controlling DRAM channel access */ -#define DCC 0x10200 -#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) -#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0) -#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0) -#define DCC_ADDRESSING_MODE_MASK (3 << 0) -#define DCC_CHANNEL_XOR_DISABLE (1 << 10) -#define DCC_CHANNEL_XOR_BIT_17 (1 << 9) - -/** Pineview MCH register contains DDR3 setting */ -#define CSHRDDR3CTL 0x101a8 -#define CSHRDDR3CTL_DDR3 (1 << 2) - -/** 965 MCH register controlling DRAM channel configuration */ -#define C0DRB3 0x10206 -#define C1DRB3 0x10606 - -/** snb MCH registers for reading the DRAM channel configuration */ -#define MAD_DIMM_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5004) -#define MAD_DIMM_C1 (MCHBAR_MIRROR_BASE_SNB + 0x5008) -#define MAD_DIMM_C2 (MCHBAR_MIRROR_BASE_SNB + 0x500C) -#define MAD_DIMM_ECC_MASK (0x3 << 24) -#define MAD_DIMM_ECC_OFF (0x0 << 24) -#define MAD_DIMM_ECC_IO_ON_LOGIC_OFF (0x1 << 24) -#define MAD_DIMM_ECC_IO_OFF_LOGIC_ON (0x2 << 24) -#define MAD_DIMM_ECC_ON (0x3 << 24) -#define MAD_DIMM_ENH_INTERLEAVE (0x1 << 22) -#define MAD_DIMM_RANK_INTERLEAVE (0x1 << 21) -#define MAD_DIMM_B_WIDTH_X16 (0x1 << 20) /* X8 chips if unset */ -#define MAD_DIMM_A_WIDTH_X16 (0x1 << 19) /* X8 chips if unset */ -#define MAD_DIMM_B_DUAL_RANK (0x1 << 18) -#define MAD_DIMM_A_DUAL_RANK (0x1 << 17) -#define MAD_DIMM_A_SELECT (0x1 << 16) -/* DIMM sizes are in multiples of 256mb. */ -#define MAD_DIMM_B_SIZE_SHIFT 8 -#define MAD_DIMM_B_SIZE_MASK (0xff << MAD_DIMM_B_SIZE_SHIFT) -#define MAD_DIMM_A_SIZE_SHIFT 0 -#define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT) - - -/* Clocking configuration register */ -#define CLKCFG 0x10c00 -#define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ -#define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ -#define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ -#define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ -#define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ -#define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ -/* Note, below two are guess */ -#define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ -#define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */ -#define CLKCFG_FSB_MASK (7 << 0) -#define CLKCFG_MEM_533 (1 << 4) -#define CLKCFG_MEM_667 (2 << 4) -#define CLKCFG_MEM_800 (3 << 4) -#define CLKCFG_MEM_MASK (7 << 4) - -#define TSC1 0x11001 -#define TSE (1<<0) -#define TR1 0x11006 -#define TSFS 0x11020 -#define TSFS_SLOPE_MASK 0x0000ff00 -#define TSFS_SLOPE_SHIFT 8 -#define TSFS_INTR_MASK 0x000000ff - -#define CRSTANDVID 0x11100 -#define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ -#define PXVFREQ_PX_MASK 0x7f000000 -#define PXVFREQ_PX_SHIFT 24 -#define VIDFREQ_BASE 0x11110 -#define VIDFREQ1 0x11110 /* VIDFREQ1-4 (0x1111c) (Cantiga) */ -#define VIDFREQ2 0x11114 -#define VIDFREQ3 0x11118 -#define VIDFREQ4 0x1111c -#define VIDFREQ_P0_MASK 0x1f000000 -#define VIDFREQ_P0_SHIFT 24 -#define VIDFREQ_P0_CSCLK_MASK 0x00f00000 -#define VIDFREQ_P0_CSCLK_SHIFT 20 -#define VIDFREQ_P0_CRCLK_MASK 0x000f0000 -#define VIDFREQ_P0_CRCLK_SHIFT 16 -#define VIDFREQ_P1_MASK 0x00001f00 -#define VIDFREQ_P1_SHIFT 8 -#define VIDFREQ_P1_CSCLK_MASK 0x000000f0 -#define VIDFREQ_P1_CSCLK_SHIFT 4 -#define VIDFREQ_P1_CRCLK_MASK 0x0000000f -#define INTTOEXT_BASE_ILK 0x11300 -#define INTTOEXT_BASE 0x11120 /* INTTOEXT1-8 (0x1113c) */ -#define INTTOEXT_MAP3_SHIFT 24 -#define INTTOEXT_MAP3_MASK (0x1f << INTTOEXT_MAP3_SHIFT) -#define INTTOEXT_MAP2_SHIFT 16 -#define INTTOEXT_MAP2_MASK (0x1f << INTTOEXT_MAP2_SHIFT) -#define INTTOEXT_MAP1_SHIFT 8 -#define INTTOEXT_MAP1_MASK (0x1f << INTTOEXT_MAP1_SHIFT) -#define INTTOEXT_MAP0_SHIFT 0 -#define INTTOEXT_MAP0_MASK (0x1f << INTTOEXT_MAP0_SHIFT) -#define MEMSWCTL 0x11170 /* Ironlake only */ -#define MEMCTL_CMD_MASK 0xe000 -#define MEMCTL_CMD_SHIFT 13 -#define MEMCTL_CMD_RCLK_OFF 0 -#define MEMCTL_CMD_RCLK_ON 1 -#define MEMCTL_CMD_CHFREQ 2 -#define MEMCTL_CMD_CHVID 3 -#define MEMCTL_CMD_VMMOFF 4 -#define MEMCTL_CMD_VMMON 5 -#define MEMCTL_CMD_STS (1<<12) /* write 1 triggers command, clears - when command complete */ -#define MEMCTL_FREQ_MASK 0x0f00 /* jitter, from 0-15 */ -#define MEMCTL_FREQ_SHIFT 8 -#define MEMCTL_SFCAVM (1<<7) -#define MEMCTL_TGT_VID_MASK 0x007f -#define MEMIHYST 0x1117c -#define MEMINTREN 0x11180 /* 16 bits */ -#define MEMINT_RSEXIT_EN (1<<8) -#define MEMINT_CX_SUPR_EN (1<<7) -#define MEMINT_CONT_BUSY_EN (1<<6) -#define MEMINT_AVG_BUSY_EN (1<<5) -#define MEMINT_EVAL_CHG_EN (1<<4) -#define MEMINT_MON_IDLE_EN (1<<3) -#define MEMINT_UP_EVAL_EN (1<<2) -#define MEMINT_DOWN_EVAL_EN (1<<1) -#define MEMINT_SW_CMD_EN (1<<0) -#define MEMINTRSTR 0x11182 /* 16 bits */ -#define MEM_RSEXIT_MASK 0xc000 -#define MEM_RSEXIT_SHIFT 14 -#define MEM_CONT_BUSY_MASK 0x3000 -#define MEM_CONT_BUSY_SHIFT 12 -#define MEM_AVG_BUSY_MASK 0x0c00 -#define MEM_AVG_BUSY_SHIFT 10 -#define MEM_EVAL_CHG_MASK 0x0300 -#define MEM_EVAL_BUSY_SHIFT 8 -#define MEM_MON_IDLE_MASK 0x00c0 -#define MEM_MON_IDLE_SHIFT 6 -#define MEM_UP_EVAL_MASK 0x0030 -#define MEM_UP_EVAL_SHIFT 4 -#define MEM_DOWN_EVAL_MASK 0x000c -#define MEM_DOWN_EVAL_SHIFT 2 -#define MEM_SW_CMD_MASK 0x0003 -#define MEM_INT_STEER_GFX 0 -#define MEM_INT_STEER_CMR 1 -#define MEM_INT_STEER_SMI 2 -#define MEM_INT_STEER_SCI 3 -#define MEMINTRSTS 0x11184 -#define MEMINT_RSEXIT (1<<7) -#define MEMINT_CONT_BUSY (1<<6) -#define MEMINT_AVG_BUSY (1<<5) -#define MEMINT_EVAL_CHG (1<<4) -#define MEMINT_MON_IDLE (1<<3) -#define MEMINT_UP_EVAL (1<<2) -#define MEMINT_DOWN_EVAL (1<<1) -#define MEMINT_SW_CMD (1<<0) -#define MEMMODECTL 0x11190 -#define MEMMODE_BOOST_EN (1<<31) -#define MEMMODE_BOOST_FREQ_MASK 0x0f000000 /* jitter for boost, 0-15 */ -#define MEMMODE_BOOST_FREQ_SHIFT 24 -#define MEMMODE_IDLE_MODE_MASK 0x00030000 -#define MEMMODE_IDLE_MODE_SHIFT 16 -#define MEMMODE_IDLE_MODE_EVAL 0 -#define MEMMODE_IDLE_MODE_CONT 1 -#define MEMMODE_HWIDLE_EN (1<<15) -#define MEMMODE_SWMODE_EN (1<<14) -#define MEMMODE_RCLK_GATE (1<<13) -#define MEMMODE_HW_UPDATE (1<<12) -#define MEMMODE_FSTART_MASK 0x00000f00 /* starting jitter, 0-15 */ -#define MEMMODE_FSTART_SHIFT 8 -#define MEMMODE_FMAX_MASK 0x000000f0 /* max jitter, 0-15 */ -#define MEMMODE_FMAX_SHIFT 4 -#define MEMMODE_FMIN_MASK 0x0000000f /* min jitter, 0-15 */ -#define RCBMAXAVG 0x1119c -#define MEMSWCTL2 0x1119e /* Cantiga only */ -#define SWMEMCMD_RENDER_OFF (0 << 13) -#define SWMEMCMD_RENDER_ON (1 << 13) -#define SWMEMCMD_SWFREQ (2 << 13) -#define SWMEMCMD_TARVID (3 << 13) -#define SWMEMCMD_VRM_OFF (4 << 13) -#define SWMEMCMD_VRM_ON (5 << 13) -#define CMDSTS (1<<12) -#define SFCAVM (1<<11) -#define SWFREQ_MASK 0x0380 /* P0-7 */ -#define SWFREQ_SHIFT 7 -#define TARVID_MASK 0x001f -#define MEMSTAT_CTG 0x111a0 -#define RCBMINAVG 0x111a0 -#define RCUPEI 0x111b0 -#define RCDNEI 0x111b4 -#define RSTDBYCTL 0x111b8 -#define RS1EN (1<<31) -#define RS2EN (1<<30) -#define RS3EN (1<<29) -#define D3RS3EN (1<<28) /* Display D3 imlies RS3 */ -#define SWPROMORSX (1<<27) /* RSx promotion timers ignored */ -#define RCWAKERW (1<<26) /* Resetwarn from PCH causes wakeup */ -#define DPRSLPVREN (1<<25) /* Fast voltage ramp enable */ -#define GFXTGHYST (1<<24) /* Hysteresis to allow trunk gating */ -#define RCX_SW_EXIT (1<<23) /* Leave RSx and prevent re-entry */ -#define RSX_STATUS_MASK (7<<20) -#define RSX_STATUS_ON (0<<20) -#define RSX_STATUS_RC1 (1<<20) -#define RSX_STATUS_RC1E (2<<20) -#define RSX_STATUS_RS1 (3<<20) -#define RSX_STATUS_RS2 (4<<20) /* aka rc6 */ -#define RSX_STATUS_RSVD (5<<20) /* deep rc6 unsupported on ilk */ -#define RSX_STATUS_RS3 (6<<20) /* rs3 unsupported on ilk */ -#define RSX_STATUS_RSVD2 (7<<20) -#define UWRCRSXE (1<<19) /* wake counter limit prevents rsx */ -#define RSCRP (1<<18) /* rs requests control on rs1/2 reqs */ -#define JRSC (1<<17) /* rsx coupled to cpu c-state */ -#define RS2INC0 (1<<16) /* allow rs2 in cpu c0 */ -#define RS1CONTSAV_MASK (3<<14) -#define RS1CONTSAV_NO_RS1 (0<<14) /* rs1 doesn't save/restore context */ -#define RS1CONTSAV_RSVD (1<<14) -#define RS1CONTSAV_SAVE_RS1 (2<<14) /* rs1 saves context */ -#define RS1CONTSAV_FULL_RS1 (3<<14) /* rs1 saves and restores context */ -#define NORMSLEXLAT_MASK (3<<12) -#define SLOW_RS123 (0<<12) -#define SLOW_RS23 (1<<12) -#define SLOW_RS3 (2<<12) -#define NORMAL_RS123 (3<<12) -#define RCMODE_TIMEOUT (1<<11) /* 0 is eval interval method */ -#define IMPROMOEN (1<<10) /* promo is immediate or delayed until next idle interval (only for timeout method above) */ -#define RCENTSYNC (1<<9) /* rs coupled to cpu c-state (3/6/7) */ -#define STATELOCK (1<<7) /* locked to rs_cstate if 0 */ -#define RS_CSTATE_MASK (3<<4) -#define RS_CSTATE_C367_RS1 (0<<4) -#define RS_CSTATE_C36_RS1_C7_RS2 (1<<4) -#define RS_CSTATE_RSVD (2<<4) -#define RS_CSTATE_C367_RS2 (3<<4) -#define REDSAVES (1<<3) /* no context save if was idle during rs0 */ -#define REDRESTORES (1<<2) /* no restore if was idle during rs0 */ -#define VIDCTL 0x111c0 -#define VIDSTS 0x111c8 -#define VIDSTART 0x111cc /* 8 bits */ -#define MEMSTAT_ILK 0x111f8 -#define MEMSTAT_VID_MASK 0x7f00 -#define MEMSTAT_VID_SHIFT 8 -#define MEMSTAT_PSTATE_MASK 0x00f8 -#define MEMSTAT_PSTATE_SHIFT 3 -#define MEMSTAT_MON_ACTV (1<<2) -#define MEMSTAT_SRC_CTL_MASK 0x0003 -#define MEMSTAT_SRC_CTL_CORE 0 -#define MEMSTAT_SRC_CTL_TRB 1 -#define MEMSTAT_SRC_CTL_THM 2 -#define MEMSTAT_SRC_CTL_STDBY 3 -#define RCPREVBSYTUPAVG 0x113b8 -#define RCPREVBSYTDNAVG 0x113bc -#define PMMISC 0x11214 -#define MCPPCE_EN (1<<0) /* enable PM_MSG from PCH->MPC */ -#define SDEW 0x1124c -#define CSIEW0 0x11250 -#define CSIEW1 0x11254 -#define CSIEW2 0x11258 -#define PEW 0x1125c -#define DEW 0x11270 -#define MCHAFE 0x112c0 -#define CSIEC 0x112e0 -#define DMIEC 0x112e4 -#define DDREC 0x112e8 -#define PEG0EC 0x112ec -#define PEG1EC 0x112f0 -#define GFXEC 0x112f4 -#define RPPREVBSYTUPAVG 0x113b8 -#define RPPREVBSYTDNAVG 0x113bc -#define ECR 0x11600 -#define ECR_GPFE (1<<31) -#define ECR_IMONE (1<<30) -#define ECR_CAP_MASK 0x0000001f /* Event range, 0-31 */ -#define OGW0 0x11608 -#define OGW1 0x1160c -#define EG0 0x11610 -#define EG1 0x11614 -#define EG2 0x11618 -#define EG3 0x1161c -#define EG4 0x11620 -#define EG5 0x11624 -#define EG6 0x11628 -#define EG7 0x1162c -#define PXW 0x11664 -#define PXWL 0x11680 -#define LCFUSE02 0x116c0 -#define LCFUSE_HIV_MASK 0x000000ff -#define CSIPLL0 0x12c10 -#define DDRMPLL1 0X12c20 -#define PEG_BAND_GAP_DATA 0x14d68 - -#define GEN6_GT_PERF_STATUS 0x145948 -#define GEN6_RP_STATE_LIMITS 0x145994 -#define GEN6_RP_STATE_CAP 0x145998 - -/* - * Logical Context regs - */ -#define CCID 0x2180 -#define CCID_EN (1<<0) -/* - * Overlay regs - */ - -#define OVADD 0x30000 -#define DOVSTA 0x30008 -#define OC_BUF (0x3<<20) -#define OGAMC5 0x30010 -#define OGAMC4 0x30014 -#define OGAMC3 0x30018 -#define OGAMC2 0x3001c -#define OGAMC1 0x30020 -#define OGAMC0 0x30024 - -/* - * Display engine regs - */ - -/* Pipe A timing regs */ -#define _HTOTAL_A 0x60000 -#define _HBLANK_A 0x60004 -#define _HSYNC_A 0x60008 -#define _VTOTAL_A 0x6000c -#define _VBLANK_A 0x60010 -#define _VSYNC_A 0x60014 -#define _PIPEASRC 0x6001c -#define _BCLRPAT_A 0x60020 -#define _VSYNCSHIFT_A 0x60028 - -/* Pipe B timing regs */ -#define _HTOTAL_B 0x61000 -#define _HBLANK_B 0x61004 -#define _HSYNC_B 0x61008 -#define _VTOTAL_B 0x6100c -#define _VBLANK_B 0x61010 -#define _VSYNC_B 0x61014 -#define _PIPEBSRC 0x6101c -#define _BCLRPAT_B 0x61020 -#define _VSYNCSHIFT_B 0x61028 - - -#define HTOTAL(pipe) _PIPE(pipe, _HTOTAL_A, _HTOTAL_B) -#define HBLANK(pipe) _PIPE(pipe, _HBLANK_A, _HBLANK_B) -#define HSYNC(pipe) _PIPE(pipe, _HSYNC_A, _HSYNC_B) -#define VTOTAL(pipe) _PIPE(pipe, _VTOTAL_A, _VTOTAL_B) -#define VBLANK(pipe) _PIPE(pipe, _VBLANK_A, _VBLANK_B) -#define VSYNC(pipe) _PIPE(pipe, _VSYNC_A, _VSYNC_B) -#define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) -#define VSYNCSHIFT(pipe) _PIPE(pipe, _VSYNCSHIFT_A, _VSYNCSHIFT_B) - -/* VGA port control */ -#define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1<<31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1<<30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1<<30) -#define ADPA_PIPE_SELECT(pipe) ((pipe) << 30) -#define ADPA_USE_VGA_HVPOLARITY (1<<15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) -#define ADPA_HSYNC_ACTIVE_LOW 0 -#define ADPA_DPMS_MASK (~(3<<10)) -#define ADPA_DPMS_ON (0<<10) -#define ADPA_DPMS_SUSPEND (1<<10) -#define ADPA_DPMS_STANDBY (2<<10) -#define ADPA_DPMS_OFF (3<<10) - - -/* Hotplug control (945+ only) */ -#define PORT_HOTPLUG_EN 0x61110 -#define HDMIB_HOTPLUG_INT_EN (1 << 29) -#define DPB_HOTPLUG_INT_EN (1 << 29) -#define HDMIC_HOTPLUG_INT_EN (1 << 28) -#define DPC_HOTPLUG_INT_EN (1 << 28) -#define HDMID_HOTPLUG_INT_EN (1 << 27) -#define DPD_HOTPLUG_INT_EN (1 << 27) -#define SDVOB_HOTPLUG_INT_EN (1 << 26) -#define SDVOC_HOTPLUG_INT_EN (1 << 25) -#define TV_HOTPLUG_INT_EN (1 << 18) -#define CRT_HOTPLUG_INT_EN (1 << 9) -#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) -#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) -/* must use period 64 on GM45 according to docs */ -#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8) -#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7) -#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5) -#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5) -#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4) -#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) -#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) -#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) - -#define PORT_HOTPLUG_STAT 0x61114 -#define HDMIB_HOTPLUG_INT_STATUS (1 << 29) -#define DPB_HOTPLUG_INT_STATUS (1 << 29) -#define HDMIC_HOTPLUG_INT_STATUS (1 << 28) -#define DPC_HOTPLUG_INT_STATUS (1 << 28) -#define HDMID_HOTPLUG_INT_STATUS (1 << 27) -#define DPD_HOTPLUG_INT_STATUS (1 << 27) -#define CRT_HOTPLUG_INT_STATUS (1 << 11) -#define TV_HOTPLUG_INT_STATUS (1 << 10) -#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -#define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -#define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -#define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -#define SDVOB_HOTPLUG_INT_STATUS (1 << 6) - -/* SDVO port control */ -#define SDVOB 0x61140 -#define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) -/** - * 915G/GM SDVO pixel multiplier. - * - * Programmed value is multiplier - 1, up to 5x. - * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK - */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_ENCODING_SDVO (0x0 << 10) -#define SDVO_ENCODING_HDMI (0x2 << 10) -/** Requird for HDMI operation */ -#define SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9) -#define SDVO_COLOR_RANGE_16_235 (1 << 8) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVO_AUDIO_ENABLE (1 << 6) -/** New with 965, default is to be set */ -#define SDVO_VSYNC_ACTIVE_HIGH (1 << 4) -/** New with 965, default is to be set */ -#define SDVO_HSYNC_ACTIVE_HIGH (1 << 3) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) -/* Bits to be preserved when writing */ -#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26)) -#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26)) - -/* DVO port control */ -#define DVOA 0x61120 -#define DVOB 0x61140 -#define DVOC 0x61160 -#define DVO_ENABLE (1 << 31) -#define DVO_PIPE_B_SELECT (1 << 30) -#define DVO_PIPE_STALL_UNUSED (0 << 28) -#define DVO_PIPE_STALL (1 << 28) -#define DVO_PIPE_STALL_TV (2 << 28) -#define DVO_PIPE_STALL_MASK (3 << 28) -#define DVO_USE_VGA_SYNC (1 << 15) -#define DVO_DATA_ORDER_I740 (0 << 14) -#define DVO_DATA_ORDER_FP (1 << 14) -#define DVO_VSYNC_DISABLE (1 << 11) -#define DVO_HSYNC_DISABLE (1 << 10) -#define DVO_VSYNC_TRISTATE (1 << 9) -#define DVO_HSYNC_TRISTATE (1 << 8) -#define DVO_BORDER_ENABLE (1 << 7) -#define DVO_DATA_ORDER_GBRG (1 << 6) -#define DVO_DATA_ORDER_RGGB (0 << 6) -#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) -#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) -#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) -#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) -#define DVO_BLANK_ACTIVE_HIGH (1 << 2) -#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ -#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ -#define DVO_PRESERVE_MASK (0x7<<24) -#define DVOA_SRCDIM 0x61124 -#define DVOB_SRCDIM 0x61144 -#define DVOC_SRCDIM 0x61164 -#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 -#define DVO_SRCDIM_VERTICAL_SHIFT 0 - -/* LVDS port control */ -#define LVDS 0x61180 -/* - * Enables the LVDS port. This bit must be set before DPLLs are enabled, as - * the DPLL semantics change when the LVDS is assigned to that pipe. - */ -#define LVDS_PORT_EN (1 << 31) -/* Selects pipe B for LVDS data. Must be set on pre-965. */ -#define LVDS_PIPEB_SELECT (1 << 30) -#define LVDS_PIPE_MASK (1 << 30) -#define LVDS_PIPE(pipe) ((pipe) << 30) -/* LVDS dithering flag on 965/g4x platform */ -#define LVDS_ENABLE_DITHER (1 << 25) -/* LVDS sync polarity flags. Set to invert (i.e. negative) */ -#define LVDS_VSYNC_POLARITY (1 << 21) -#define LVDS_HSYNC_POLARITY (1 << 20) - -/* Enable border for unscaled (or aspect-scaled) display */ -#define LVDS_BORDER_ENABLE (1 << 15) -/* - * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per - * pixel. - */ -#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/* - * Controls the A3 data pair, which contains the additional LSBs for 24 bit - * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be - * on. - */ -#define LVDS_A3_POWER_MASK (3 << 6) -#define LVDS_A3_POWER_DOWN (0 << 6) -#define LVDS_A3_POWER_UP (3 << 6) -/* - * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP - * is set. - */ -#define LVDS_CLKB_POWER_MASK (3 << 4) -#define LVDS_CLKB_POWER_DOWN (0 << 4) -#define LVDS_CLKB_POWER_UP (3 << 4) -/* - * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 - * setting for whether we are in dual-channel mode. The B3 pair will - * additionally only be powered up when LVDS_A3_POWER_UP is set. - */ -#define LVDS_B0B3_POWER_MASK (3 << 2) -#define LVDS_B0B3_POWER_DOWN (0 << 2) -#define LVDS_B0B3_POWER_UP (3 << 2) - -/* Video Data Island Packet control */ -#define VIDEO_DIP_DATA 0x61178 -#define VIDEO_DIP_CTL 0x61170 -#define VIDEO_DIP_ENABLE (1 << 31) -#define VIDEO_DIP_PORT_B (1 << 29) -#define VIDEO_DIP_PORT_C (2 << 29) -#define VIDEO_DIP_ENABLE_AVI (1 << 21) -#define VIDEO_DIP_ENABLE_VENDOR (2 << 21) -#define VIDEO_DIP_ENABLE_SPD (8 << 21) -#define VIDEO_DIP_SELECT_AVI (0 << 19) -#define VIDEO_DIP_SELECT_VENDOR (1 << 19) -#define VIDEO_DIP_SELECT_SPD (3 << 19) -#define VIDEO_DIP_SELECT_MASK (3 << 19) -#define VIDEO_DIP_FREQ_ONCE (0 << 16) -#define VIDEO_DIP_FREQ_VSYNC (1 << 16) -#define VIDEO_DIP_FREQ_2VSYNC (2 << 16) - -/* Panel power sequencing */ -#define PP_STATUS 0x61200 -#define PP_ON (1 << 31) -/* - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -#define PP_READY (1 << 30) -#define PP_SEQUENCE_NONE (0 << 28) -#define PP_SEQUENCE_POWER_UP (1 << 28) -#define PP_SEQUENCE_POWER_DOWN (2 << 28) -#define PP_SEQUENCE_MASK (3 << 28) -#define PP_SEQUENCE_SHIFT 28 -#define PP_CYCLE_DELAY_ACTIVE (1 << 27) -#define PP_SEQUENCE_STATE_MASK 0x0000000f -#define PP_SEQUENCE_STATE_OFF_IDLE (0x0 << 0) -#define PP_SEQUENCE_STATE_OFF_S0_1 (0x1 << 0) -#define PP_SEQUENCE_STATE_OFF_S0_2 (0x2 << 0) -#define PP_SEQUENCE_STATE_OFF_S0_3 (0x3 << 0) -#define PP_SEQUENCE_STATE_ON_IDLE (0x8 << 0) -#define PP_SEQUENCE_STATE_ON_S1_0 (0x9 << 0) -#define PP_SEQUENCE_STATE_ON_S1_2 (0xa << 0) -#define PP_SEQUENCE_STATE_ON_S1_3 (0xb << 0) -#define PP_SEQUENCE_STATE_RESET (0xf << 0) -#define PP_CONTROL 0x61204 -#define POWER_TARGET_ON (1 << 0) -#define PP_ON_DELAYS 0x61208 -#define PP_OFF_DELAYS 0x6120c -#define PP_DIVISOR 0x61210 - -/* Panel fitting */ -#define PFIT_CONTROL 0x61230 -#define PFIT_ENABLE (1 << 31) -#define PFIT_PIPE_MASK (3 << 29) -#define PFIT_PIPE_SHIFT 29 -#define VERT_INTERP_DISABLE (0 << 10) -#define VERT_INTERP_BILINEAR (1 << 10) -#define VERT_INTERP_MASK (3 << 10) -#define VERT_AUTO_SCALE (1 << 9) -#define HORIZ_INTERP_DISABLE (0 << 6) -#define HORIZ_INTERP_BILINEAR (1 << 6) -#define HORIZ_INTERP_MASK (3 << 6) -#define HORIZ_AUTO_SCALE (1 << 5) -#define PANEL_8TO6_DITHER_ENABLE (1 << 3) -#define PFIT_FILTER_FUZZY (0 << 24) -#define PFIT_SCALING_AUTO (0 << 26) -#define PFIT_SCALING_PROGRAMMED (1 << 26) -#define PFIT_SCALING_PILLAR (2 << 26) -#define PFIT_SCALING_LETTER (3 << 26) -#define PFIT_PGM_RATIOS 0x61234 -#define PFIT_VERT_SCALE_MASK 0xfff00000 -#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -/* Pre-965 */ -#define PFIT_VERT_SCALE_SHIFT 20 -#define PFIT_VERT_SCALE_MASK 0xfff00000 -#define PFIT_HORIZ_SCALE_SHIFT 4 -#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 -/* 965+ */ -#define PFIT_VERT_SCALE_SHIFT_965 16 -#define PFIT_VERT_SCALE_MASK_965 0x1fff0000 -#define PFIT_HORIZ_SCALE_SHIFT_965 0 -#define PFIT_HORIZ_SCALE_MASK_965 0x00001fff - -#define PFIT_AUTO_RATIOS 0x61238 - -/* Backlight control */ -#define BLC_PWM_CTL 0x61254 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) -#define BLC_PWM_CTL2 0x61250 /* 965+ only */ -#define BLM_COMBINATION_MODE (1 << 30) -/* - * This is the most significant 15 bits of the number of backlight cycles in a - * complete cycle of the modulated backlight control. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) -/* - * This is the number of cycles out of the backlight modulation cycle for which - * the backlight is on. - * - * This field must be no greater than the number of cycles in the complete - * backlight modulation cycle. - */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) - -#define BLC_HIST_CTL 0x61260 - -/* TV port control */ -#define TV_CTL 0x68000 -/** Enables the TV encoder */ -# define TV_ENC_ENABLE (1 << 31) -/** Sources the TV encoder input from pipe B instead of A. */ -# define TV_ENC_PIPEB_SELECT (1 << 30) -/** Outputs composite video (DAC A only) */ -# define TV_ENC_OUTPUT_COMPOSITE (0 << 28) -/** Outputs SVideo video (DAC B/C) */ -# define TV_ENC_OUTPUT_SVIDEO (1 << 28) -/** Outputs Component video (DAC A/B/C) */ -# define TV_ENC_OUTPUT_COMPONENT (2 << 28) -/** Outputs Composite and SVideo (DAC A/B/C) */ -# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) -# define TV_TRILEVEL_SYNC (1 << 21) -/** Enables slow sync generation (945GM only) */ -# define TV_SLOW_SYNC (1 << 20) -/** Selects 4x oversampling for 480i and 576p */ -# define TV_OVERSAMPLE_4X (0 << 18) -/** Selects 2x oversampling for 720p and 1080i */ -# define TV_OVERSAMPLE_2X (1 << 18) -/** Selects no oversampling for 1080p */ -# define TV_OVERSAMPLE_NONE (2 << 18) -/** Selects 8x oversampling */ -# define TV_OVERSAMPLE_8X (3 << 18) -/** Selects progressive mode rather than interlaced */ -# define TV_PROGRESSIVE (1 << 17) -/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */ -# define TV_PAL_BURST (1 << 16) -/** Field for setting delay of Y compared to C */ -# define TV_YC_SKEW_MASK (7 << 12) -/** Enables a fix for 480p/576p standard definition modes on the 915GM only */ -# define TV_ENC_SDP_FIX (1 << 11) -/** - * Enables a fix for the 915GM only. - * - * Not sure what it does. - */ -# define TV_ENC_C0_FIX (1 << 10) -/** Bits that must be preserved by software */ -# define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf) -# define TV_FUSE_STATE_MASK (3 << 4) -/** Read-only state that reports all features enabled */ -# define TV_FUSE_STATE_ENABLED (0 << 4) -/** Read-only state that reports that Macrovision is disabled in hardware*/ -# define TV_FUSE_STATE_NO_MACROVISION (1 << 4) -/** Read-only state that reports that TV-out is disabled in hardware. */ -# define TV_FUSE_STATE_DISABLED (2 << 4) -/** Normal operation */ -# define TV_TEST_MODE_NORMAL (0 << 0) -/** Encoder test pattern 1 - combo pattern */ -# define TV_TEST_MODE_PATTERN_1 (1 << 0) -/** Encoder test pattern 2 - full screen vertical 75% color bars */ -# define TV_TEST_MODE_PATTERN_2 (2 << 0) -/** Encoder test pattern 3 - full screen horizontal 75% color bars */ -# define TV_TEST_MODE_PATTERN_3 (3 << 0) -/** Encoder test pattern 4 - random noise */ -# define TV_TEST_MODE_PATTERN_4 (4 << 0) -/** Encoder test pattern 5 - linear color ramps */ -# define TV_TEST_MODE_PATTERN_5 (5 << 0) -/** - * This test mode forces the DACs to 50% of full output. - * - * This is used for load detection in combination with TVDAC_SENSE_MASK - */ -# define TV_TEST_MODE_MONITOR_DETECT (7 << 0) -# define TV_TEST_MODE_MASK (7 << 0) - -#define TV_DAC 0x68004 -# define TV_DAC_SAVE 0x00ffff00 -/** - * Reports that DAC state change logic has reported change (RO). - * - * This gets cleared when TV_DAC_STATE_EN is cleared -*/ -# define TVDAC_STATE_CHG (1 << 31) -# define TVDAC_SENSE_MASK (7 << 28) -/** Reports that DAC A voltage is above the detect threshold */ -# define TVDAC_A_SENSE (1 << 30) -/** Reports that DAC B voltage is above the detect threshold */ -# define TVDAC_B_SENSE (1 << 29) -/** Reports that DAC C voltage is above the detect threshold */ -# define TVDAC_C_SENSE (1 << 28) -/** - * Enables DAC state detection logic, for load-based TV detection. - * - * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set - * to off, for load detection to work. - */ -# define TVDAC_STATE_CHG_EN (1 << 27) -/** Sets the DAC A sense value to high */ -# define TVDAC_A_SENSE_CTL (1 << 26) -/** Sets the DAC B sense value to high */ -# define TVDAC_B_SENSE_CTL (1 << 25) -/** Sets the DAC C sense value to high */ -# define TVDAC_C_SENSE_CTL (1 << 24) -/** Overrides the ENC_ENABLE and DAC voltage levels */ -# define DAC_CTL_OVERRIDE (1 << 7) -/** Sets the slew rate. Must be preserved in software */ -# define ENC_TVDAC_SLEW_FAST (1 << 6) -# define DAC_A_1_3_V (0 << 4) -# define DAC_A_1_1_V (1 << 4) -# define DAC_A_0_7_V (2 << 4) -# define DAC_A_MASK (3 << 4) -# define DAC_B_1_3_V (0 << 2) -# define DAC_B_1_1_V (1 << 2) -# define DAC_B_0_7_V (2 << 2) -# define DAC_B_MASK (3 << 2) -# define DAC_C_1_3_V (0 << 0) -# define DAC_C_1_1_V (1 << 0) -# define DAC_C_0_7_V (2 << 0) -# define DAC_C_MASK (3 << 0) - -/** - * CSC coefficients are stored in a floating point format with 9 bits of - * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, - * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with - * -1 (0x3) being the only legal negative value. - */ -#define TV_CSC_Y 0x68010 -# define TV_RY_MASK 0x07ff0000 -# define TV_RY_SHIFT 16 -# define TV_GY_MASK 0x00000fff -# define TV_GY_SHIFT 0 - -#define TV_CSC_Y2 0x68014 -# define TV_BY_MASK 0x07ff0000 -# define TV_BY_SHIFT 16 -/** - * Y attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AY_MASK 0x000003ff -# define TV_AY_SHIFT 0 - -#define TV_CSC_U 0x68018 -# define TV_RU_MASK 0x07ff0000 -# define TV_RU_SHIFT 16 -# define TV_GU_MASK 0x000007ff -# define TV_GU_SHIFT 0 - -#define TV_CSC_U2 0x6801c -# define TV_BU_MASK 0x07ff0000 -# define TV_BU_SHIFT 16 -/** - * U attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AU_MASK 0x000003ff -# define TV_AU_SHIFT 0 - -#define TV_CSC_V 0x68020 -# define TV_RV_MASK 0x0fff0000 -# define TV_RV_SHIFT 16 -# define TV_GV_MASK 0x000007ff -# define TV_GV_SHIFT 0 - -#define TV_CSC_V2 0x68024 -# define TV_BV_MASK 0x07ff0000 -# define TV_BV_SHIFT 16 -/** - * V attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AV_MASK 0x000007ff -# define TV_AV_SHIFT 0 - -#define TV_CLR_KNOBS 0x68028 -/** 2s-complement brightness adjustment */ -# define TV_BRIGHTNESS_MASK 0xff000000 -# define TV_BRIGHTNESS_SHIFT 24 -/** Contrast adjustment, as a 2.6 unsigned floating point number */ -# define TV_CONTRAST_MASK 0x00ff0000 -# define TV_CONTRAST_SHIFT 16 -/** Saturation adjustment, as a 2.6 unsigned floating point number */ -# define TV_SATURATION_MASK 0x0000ff00 -# define TV_SATURATION_SHIFT 8 -/** Hue adjustment, as an integer phase angle in degrees */ -# define TV_HUE_MASK 0x000000ff -# define TV_HUE_SHIFT 0 - -#define TV_CLR_LEVEL 0x6802c -/** Controls the DAC level for black */ -# define TV_BLACK_LEVEL_MASK 0x01ff0000 -# define TV_BLACK_LEVEL_SHIFT 16 -/** Controls the DAC level for blanking */ -# define TV_BLANK_LEVEL_MASK 0x000001ff -# define TV_BLANK_LEVEL_SHIFT 0 - -#define TV_H_CTL_1 0x68030 -/** Number of pixels in the hsync. */ -# define TV_HSYNC_END_MASK 0x1fff0000 -# define TV_HSYNC_END_SHIFT 16 -/** Total number of pixels minus one in the line (display and blanking). */ -# define TV_HTOTAL_MASK 0x00001fff -# define TV_HTOTAL_SHIFT 0 - -#define TV_H_CTL_2 0x68034 -/** Enables the colorburst (needed for non-component color) */ -# define TV_BURST_ENA (1 << 31) -/** Offset of the colorburst from the start of hsync, in pixels minus one. */ -# define TV_HBURST_START_SHIFT 16 -# define TV_HBURST_START_MASK 0x1fff0000 -/** Length of the colorburst */ -# define TV_HBURST_LEN_SHIFT 0 -# define TV_HBURST_LEN_MASK 0x0001fff - -#define TV_H_CTL_3 0x68038 -/** End of hblank, measured in pixels minus one from start of hsync */ -# define TV_HBLANK_END_SHIFT 16 -# define TV_HBLANK_END_MASK 0x1fff0000 -/** Start of hblank, measured in pixels minus one from start of hsync */ -# define TV_HBLANK_START_SHIFT 0 -# define TV_HBLANK_START_MASK 0x0001fff - -#define TV_V_CTL_1 0x6803c -/** XXX */ -# define TV_NBR_END_SHIFT 16 -# define TV_NBR_END_MASK 0x07ff0000 -/** XXX */ -# define TV_VI_END_F1_SHIFT 8 -# define TV_VI_END_F1_MASK 0x00003f00 -/** XXX */ -# define TV_VI_END_F2_SHIFT 0 -# define TV_VI_END_F2_MASK 0x0000003f - -#define TV_V_CTL_2 0x68040 -/** Length of vsync, in half lines */ -# define TV_VSYNC_LEN_MASK 0x07ff0000 -# define TV_VSYNC_LEN_SHIFT 16 -/** Offset of the start of vsync in field 1, measured in one less than the - * number of half lines. - */ -# define TV_VSYNC_START_F1_MASK 0x00007f00 -# define TV_VSYNC_START_F1_SHIFT 8 -/** - * Offset of the start of vsync in field 2, measured in one less than the - * number of half lines. - */ -# define TV_VSYNC_START_F2_MASK 0x0000007f -# define TV_VSYNC_START_F2_SHIFT 0 - -#define TV_V_CTL_3 0x68044 -/** Enables generation of the equalization signal */ -# define TV_EQUAL_ENA (1 << 31) -/** Length of vsync, in half lines */ -# define TV_VEQ_LEN_MASK 0x007f0000 -# define TV_VEQ_LEN_SHIFT 16 -/** Offset of the start of equalization in field 1, measured in one less than - * the number of half lines. - */ -# define TV_VEQ_START_F1_MASK 0x0007f00 -# define TV_VEQ_START_F1_SHIFT 8 -/** - * Offset of the start of equalization in field 2, measured in one less than - * the number of half lines. - */ -# define TV_VEQ_START_F2_MASK 0x000007f -# define TV_VEQ_START_F2_SHIFT 0 - -#define TV_V_CTL_4 0x68048 -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F1_MASK 0x003f0000 -# define TV_VBURST_START_F1_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F1_MASK 0x000000ff -# define TV_VBURST_END_F1_SHIFT 0 - -#define TV_V_CTL_5 0x6804c -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F2_MASK 0x003f0000 -# define TV_VBURST_START_F2_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F2_MASK 0x000000ff -# define TV_VBURST_END_F2_SHIFT 0 - -#define TV_V_CTL_6 0x68050 -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F3_MASK 0x003f0000 -# define TV_VBURST_START_F3_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F3_MASK 0x000000ff -# define TV_VBURST_END_F3_SHIFT 0 - -#define TV_V_CTL_7 0x68054 -/** - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F4_MASK 0x003f0000 -# define TV_VBURST_START_F4_SHIFT 16 -/** - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F4_MASK 0x000000ff -# define TV_VBURST_END_F4_SHIFT 0 - -#define TV_SC_CTL_1 0x68060 -/** Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA1_EN (1 << 31) -/** Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA2_EN (1 << 30) -/** Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA3_EN (1 << 29) -/** Sets the subcarrier DDA to reset frequency every other field */ -# define TV_SC_RESET_EVERY_2 (0 << 24) -/** Sets the subcarrier DDA to reset frequency every fourth field */ -# define TV_SC_RESET_EVERY_4 (1 << 24) -/** Sets the subcarrier DDA to reset frequency every eighth field */ -# define TV_SC_RESET_EVERY_8 (2 << 24) -/** Sets the subcarrier DDA to never reset the frequency */ -# define TV_SC_RESET_NEVER (3 << 24) -/** Sets the peak amplitude of the colorburst.*/ -# define TV_BURST_LEVEL_MASK 0x00ff0000 -# define TV_BURST_LEVEL_SHIFT 16 -/** Sets the increment of the first subcarrier phase generation DDA */ -# define TV_SCDDA1_INC_MASK 0x00000fff -# define TV_SCDDA1_INC_SHIFT 0 - -#define TV_SC_CTL_2 0x68064 -/** Sets the rollover for the second subcarrier phase generation DDA */ -# define TV_SCDDA2_SIZE_MASK 0x7fff0000 -# define TV_SCDDA2_SIZE_SHIFT 16 -/** Sets the increent of the second subcarrier phase generation DDA */ -# define TV_SCDDA2_INC_MASK 0x00007fff -# define TV_SCDDA2_INC_SHIFT 0 - -#define TV_SC_CTL_3 0x68068 -/** Sets the rollover for the third subcarrier phase generation DDA */ -# define TV_SCDDA3_SIZE_MASK 0x7fff0000 -# define TV_SCDDA3_SIZE_SHIFT 16 -/** Sets the increent of the third subcarrier phase generation DDA */ -# define TV_SCDDA3_INC_MASK 0x00007fff -# define TV_SCDDA3_INC_SHIFT 0 - -#define TV_WIN_POS 0x68070 -/** X coordinate of the display from the start of horizontal active */ -# define TV_XPOS_MASK 0x1fff0000 -# define TV_XPOS_SHIFT 16 -/** Y coordinate of the display from the start of vertical active (NBR) */ -# define TV_YPOS_MASK 0x00000fff -# define TV_YPOS_SHIFT 0 - -#define TV_WIN_SIZE 0x68074 -/** Horizontal size of the display window, measured in pixels*/ -# define TV_XSIZE_MASK 0x1fff0000 -# define TV_XSIZE_SHIFT 16 -/** - * Vertical size of the display window, measured in pixels. - * - * Must be even for interlaced modes. - */ -# define TV_YSIZE_MASK 0x00000fff -# define TV_YSIZE_SHIFT 0 - -#define TV_FILTER_CTL_1 0x68080 -/** - * Enables automatic scaling calculation. - * - * If set, the rest of the registers are ignored, and the calculated values can - * be read back from the register. - */ -# define TV_AUTO_SCALE (1 << 31) -/** - * Disables the vertical filter. - * - * This is required on modes more than 1024 pixels wide */ -# define TV_V_FILTER_BYPASS (1 << 29) -/** Enables adaptive vertical filtering */ -# define TV_VADAPT (1 << 28) -# define TV_VADAPT_MODE_MASK (3 << 26) -/** Selects the least adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_LEAST (0 << 26) -/** Selects the moderately adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_MODERATE (1 << 26) -/** Selects the most adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_MOST (3 << 26) -/** - * Sets the horizontal scaling factor. - * - * This should be the fractional part of the horizontal scaling factor divided - * by the oversampling rate. TV_HSCALE should be less than 1, and set to: - * - * (src width - 1) / ((oversample * dest width) - 1) - */ -# define TV_HSCALE_FRAC_MASK 0x00003fff -# define TV_HSCALE_FRAC_SHIFT 0 - -#define TV_FILTER_CTL_2 0x68084 -/** - * Sets the integer part of the 3.15 fixed-point vertical scaling factor. - * - * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) - */ -# define TV_VSCALE_INT_MASK 0x00038000 -# define TV_VSCALE_INT_SHIFT 15 -/** - * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. - * - * \sa TV_VSCALE_INT_MASK - */ -# define TV_VSCALE_FRAC_MASK 0x00007fff -# define TV_VSCALE_FRAC_SHIFT 0 - -#define TV_FILTER_CTL_3 0x68088 -/** - * Sets the integer part of the 3.15 fixed-point vertical scaling factor. - * - * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) - * - * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. - */ -# define TV_VSCALE_IP_INT_MASK 0x00038000 -# define TV_VSCALE_IP_INT_SHIFT 15 -/** - * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. - * - * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. - * - * \sa TV_VSCALE_IP_INT_MASK - */ -# define TV_VSCALE_IP_FRAC_MASK 0x00007fff -# define TV_VSCALE_IP_FRAC_SHIFT 0 - -#define TV_CC_CONTROL 0x68090 -# define TV_CC_ENABLE (1 << 31) -/** - * Specifies which field to send the CC data in. - * - * CC data is usually sent in field 0. - */ -# define TV_CC_FID_MASK (1 << 27) -# define TV_CC_FID_SHIFT 27 -/** Sets the horizontal position of the CC data. Usually 135. */ -# define TV_CC_HOFF_MASK 0x03ff0000 -# define TV_CC_HOFF_SHIFT 16 -/** Sets the vertical position of the CC data. Usually 21 */ -# define TV_CC_LINE_MASK 0x0000003f -# define TV_CC_LINE_SHIFT 0 - -#define TV_CC_DATA 0x68094 -# define TV_CC_RDY (1 << 31) -/** Second word of CC data to be transmitted. */ -# define TV_CC_DATA_2_MASK 0x007f0000 -# define TV_CC_DATA_2_SHIFT 16 -/** First word of CC data to be transmitted. */ -# define TV_CC_DATA_1_MASK 0x0000007f -# define TV_CC_DATA_1_SHIFT 0 - -#define TV_H_LUMA_0 0x68100 -#define TV_H_LUMA_59 0x681ec -#define TV_H_CHROMA_0 0x68200 -#define TV_H_CHROMA_59 0x682ec -#define TV_V_LUMA_0 0x68300 -#define TV_V_LUMA_42 0x683a8 -#define TV_V_CHROMA_0 0x68400 -#define TV_V_CHROMA_42 0x684a8 - -/* Display Port */ -#define DP_A 0x64000 /* eDP */ -#define DP_B 0x64100 -#define DP_C 0x64200 -#define DP_D 0x64300 - -#define DP_PORT_EN (1 << 31) -#define DP_PIPEB_SELECT (1 << 30) -#define DP_PIPE_MASK (1 << 30) - -/* Link training mode - select a suitable mode for each stage */ -#define DP_LINK_TRAIN_PAT_1 (0 << 28) -#define DP_LINK_TRAIN_PAT_2 (1 << 28) -#define DP_LINK_TRAIN_PAT_IDLE (2 << 28) -#define DP_LINK_TRAIN_OFF (3 << 28) -#define DP_LINK_TRAIN_MASK (3 << 28) -#define DP_LINK_TRAIN_SHIFT 28 - -/* CPT Link training mode */ -#define DP_LINK_TRAIN_PAT_1_CPT (0 << 8) -#define DP_LINK_TRAIN_PAT_2_CPT (1 << 8) -#define DP_LINK_TRAIN_PAT_IDLE_CPT (2 << 8) -#define DP_LINK_TRAIN_OFF_CPT (3 << 8) -#define DP_LINK_TRAIN_MASK_CPT (7 << 8) -#define DP_LINK_TRAIN_SHIFT_CPT 8 - -/* Signal voltages. These are mostly controlled by the other end */ -#define DP_VOLTAGE_0_4 (0 << 25) -#define DP_VOLTAGE_0_6 (1 << 25) -#define DP_VOLTAGE_0_8 (2 << 25) -#define DP_VOLTAGE_1_2 (3 << 25) -#define DP_VOLTAGE_MASK (7 << 25) -#define DP_VOLTAGE_SHIFT 25 - -/* Signal pre-emphasis levels, like voltages, the other end tells us what - * they want - */ -#define DP_PRE_EMPHASIS_0 (0 << 22) -#define DP_PRE_EMPHASIS_3_5 (1 << 22) -#define DP_PRE_EMPHASIS_6 (2 << 22) -#define DP_PRE_EMPHASIS_9_5 (3 << 22) -#define DP_PRE_EMPHASIS_MASK (7 << 22) -#define DP_PRE_EMPHASIS_SHIFT 22 - -/* How many wires to use. I guess 3 was too hard */ -#define DP_PORT_WIDTH_1 (0 << 19) -#define DP_PORT_WIDTH_2 (1 << 19) -#define DP_PORT_WIDTH_4 (3 << 19) -#define DP_PORT_WIDTH_MASK (7 << 19) - -/* Mystic DPCD version 1.1 special mode */ -#define DP_ENHANCED_FRAMING (1 << 18) - -/* eDP */ -#define DP_PLL_FREQ_270MHZ (0 << 16) -#define DP_PLL_FREQ_160MHZ (1 << 16) -#define DP_PLL_FREQ_MASK (3 << 16) - -/** locked once port is enabled */ -#define DP_PORT_REVERSAL (1 << 15) - -/* eDP */ -#define DP_PLL_ENABLE (1 << 14) - -/** sends the clock on lane 15 of the PEG for debug */ -#define DP_CLOCK_OUTPUT_ENABLE (1 << 13) - -#define DP_SCRAMBLING_DISABLE (1 << 12) -#define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7) - -/** limit RGB values to avoid confusing TVs */ -#define DP_COLOR_RANGE_16_235 (1 << 8) - -/** Turn on the audio link */ -#define DP_AUDIO_OUTPUT_ENABLE (1 << 6) - -/** vs and hs sync polarity */ -#define DP_SYNC_VS_HIGH (1 << 4) -#define DP_SYNC_HS_HIGH (1 << 3) - -/** A fantasy */ -#define DP_DETECTED (1 << 2) - -/** The aux channel provides a way to talk to the - * signal sink for DDC etc. Max packet size supported - * is 20 bytes in each direction, hence the 5 fixed - * data registers - */ -#define DPA_AUX_CH_CTL 0x64010 -#define DPA_AUX_CH_DATA1 0x64014 -#define DPA_AUX_CH_DATA2 0x64018 -#define DPA_AUX_CH_DATA3 0x6401c -#define DPA_AUX_CH_DATA4 0x64020 -#define DPA_AUX_CH_DATA5 0x64024 - -#define DPB_AUX_CH_CTL 0x64110 -#define DPB_AUX_CH_DATA1 0x64114 -#define DPB_AUX_CH_DATA2 0x64118 -#define DPB_AUX_CH_DATA3 0x6411c -#define DPB_AUX_CH_DATA4 0x64120 -#define DPB_AUX_CH_DATA5 0x64124 - -#define DPC_AUX_CH_CTL 0x64210 -#define DPC_AUX_CH_DATA1 0x64214 -#define DPC_AUX_CH_DATA2 0x64218 -#define DPC_AUX_CH_DATA3 0x6421c -#define DPC_AUX_CH_DATA4 0x64220 -#define DPC_AUX_CH_DATA5 0x64224 - -#define DPD_AUX_CH_CTL 0x64310 -#define DPD_AUX_CH_DATA1 0x64314 -#define DPD_AUX_CH_DATA2 0x64318 -#define DPD_AUX_CH_DATA3 0x6431c -#define DPD_AUX_CH_DATA4 0x64320 -#define DPD_AUX_CH_DATA5 0x64324 - -#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31) -#define DP_AUX_CH_CTL_DONE (1 << 30) -#define DP_AUX_CH_CTL_INTERRUPT (1 << 29) -#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28) -#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_1600us (3 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26) -#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25) -#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20) -#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20 -#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16) -#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16 -#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15) -#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14) -#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13) -#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12) -#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11) -#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff) -#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0 - -/* - * Computing GMCH M and N values for the Display Port link - * - * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes - * - * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz) - * - * The GMCH value is used internally - * - * bytes_per_pixel is the number of bytes coming out of the plane, - * which is after the LUTs, so we want the bytes for our color format. - * For our current usage, this is always 3, one byte for R, G and B. - */ -#define _PIPEA_GMCH_DATA_M 0x70050 -#define _PIPEB_GMCH_DATA_M 0x71050 - -/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ -#define PIPE_GMCH_DATA_M_TU_SIZE_MASK (0x3f << 25) -#define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25 - -#define PIPE_GMCH_DATA_M_MASK (0xffffff) - -#define _PIPEA_GMCH_DATA_N 0x70054 -#define _PIPEB_GMCH_DATA_N 0x71054 -#define PIPE_GMCH_DATA_N_MASK (0xffffff) - -/* - * Computing Link M and N values for the Display Port link - * - * Link M / N = pixel_clock / ls_clk - * - * (the DP spec calls pixel_clock the 'strm_clk') - * - * The Link value is transmitted in the Main Stream - * Attributes and VB-ID. - */ - -#define _PIPEA_DP_LINK_M 0x70060 -#define _PIPEB_DP_LINK_M 0x71060 -#define PIPEA_DP_LINK_M_MASK (0xffffff) - -#define _PIPEA_DP_LINK_N 0x70064 -#define _PIPEB_DP_LINK_N 0x71064 -#define PIPEA_DP_LINK_N_MASK (0xffffff) - -#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M) -#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N) -#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M) -#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N) - -/* Display & cursor control */ - -/* Pipe A */ -#define _PIPEADSL 0x70000 -#define DSL_LINEMASK 0x00000fff -#define _PIPEACONF 0x70008 -#define PIPECONF_ENABLE (1<<31) -#define PIPECONF_DISABLE 0 -#define PIPECONF_DOUBLE_WIDE (1<<30) -#define I965_PIPECONF_ACTIVE (1<<30) -#define PIPECONF_FRAME_START_DELAY_MASK (3<<27) -#define PIPECONF_SINGLE_WIDE 0 -#define PIPECONF_PIPE_UNLOCKED 0 -#define PIPECONF_PIPE_LOCKED (1<<25) -#define PIPECONF_PALETTE 0 -#define PIPECONF_GAMMA (1<<24) -#define PIPECONF_FORCE_BORDER (1<<25) -#define PIPECONF_INTERLACE_MASK (7 << 21) -/* Note that pre-gen3 does not support interlaced display directly. Panel - * fitting must be disabled on pre-ilk for interlaced. */ -#define PIPECONF_PROGRESSIVE (0 << 21) -#define PIPECONF_INTERLACE_W_SYNC_SHIFT_PANEL (4 << 21) /* gen4 only */ -#define PIPECONF_INTERLACE_W_SYNC_SHIFT (5 << 21) /* gen4 only */ -#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) -#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) /* gen3 only */ -/* Ironlake and later have a complete new set of values for interlaced. PFIT - * means panel fitter required, PF means progressive fetch, DBL means power - * saving pixel doubling. */ -#define PIPECONF_PFIT_PF_INTERLACED_ILK (1 << 21) -#define PIPECONF_INTERLACED_ILK (3 << 21) -#define PIPECONF_INTERLACED_DBL_ILK (4 << 21) /* ilk/snb only */ -#define PIPECONF_PFIT_PF_INTERLACED_DBL_ILK (5 << 21) /* ilk/snb only */ -#define PIPECONF_CXSR_DOWNCLOCK (1<<16) -#define PIPECONF_BPP_MASK (0x000000e0) -#define PIPECONF_BPP_8 (0<<5) -#define PIPECONF_BPP_10 (1<<5) -#define PIPECONF_BPP_6 (2<<5) -#define PIPECONF_BPP_12 (3<<5) -#define PIPECONF_DITHER_EN (1<<4) -#define PIPECONF_DITHER_TYPE_MASK (0x0000000c) -#define PIPECONF_DITHER_TYPE_SP (0<<2) -#define PIPECONF_DITHER_TYPE_ST1 (1<<2) -#define PIPECONF_DITHER_TYPE_ST2 (2<<2) -#define PIPECONF_DITHER_TYPE_TEMP (3<<2) -#define _PIPEASTAT 0x70024 -#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) -#define PIPE_CRC_ERROR_ENABLE (1UL<<29) -#define PIPE_CRC_DONE_ENABLE (1UL<<28) -#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27) -#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26) -#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25) -#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24) -#define PIPE_DPST_EVENT_ENABLE (1UL<<23) -#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22) -#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) -#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) -#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */ -#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ -#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16) -#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13) -#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12) -#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11) -#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) -#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9) -#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) -#define PIPE_DPST_EVENT_STATUS (1UL<<7) -#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) -#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) -#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) -#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */ -#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ -#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) -#define PIPE_BPC_MASK (7 << 5) /* Ironlake */ -#define PIPE_8BPC (0 << 5) -#define PIPE_10BPC (1 << 5) -#define PIPE_6BPC (2 << 5) -#define PIPE_12BPC (3 << 5) - -#define PIPESRC(pipe) _PIPE(pipe, _PIPEASRC, _PIPEBSRC) -#define PIPECONF(pipe) _PIPE(pipe, _PIPEACONF, _PIPEBCONF) -#define PIPEDSL(pipe) _PIPE(pipe, _PIPEADSL, _PIPEBDSL) -#define PIPEFRAME(pipe) _PIPE(pipe, _PIPEAFRAMEHIGH, _PIPEBFRAMEHIGH) -#define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL) -#define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) - -#define DSPARB 0x70030 -#define DSPARB_CSTART_MASK (0x7f << 7) -#define DSPARB_CSTART_SHIFT 7 -#define DSPARB_BSTART_MASK (0x7f) -#define DSPARB_BSTART_SHIFT 0 -#define DSPARB_BEND_SHIFT 9 /* on 855 */ -#define DSPARB_AEND_SHIFT 0 - -#define DSPFW1 0x70034 -#define DSPFW_SR_SHIFT 23 -#define DSPFW_SR_MASK (0x1ff<<23) -#define DSPFW_CURSORB_SHIFT 16 -#define DSPFW_CURSORB_MASK (0x3f<<16) -#define DSPFW_PLANEB_SHIFT 8 -#define DSPFW_PLANEB_MASK (0x7f<<8) -#define DSPFW_PLANEA_MASK (0x7f) -#define DSPFW2 0x70038 -#define DSPFW_CURSORA_MASK 0x00003f00 -#define DSPFW_CURSORA_SHIFT 8 -#define DSPFW_PLANEC_MASK (0x7f) -#define DSPFW3 0x7003c -#define DSPFW_HPLL_SR_EN (1<<31) -#define DSPFW_CURSOR_SR_SHIFT 24 -#define PINEVIEW_SELF_REFRESH_EN (1<<30) -#define DSPFW_CURSOR_SR_MASK (0x3f<<24) -#define DSPFW_HPLL_CURSOR_SHIFT 16 -#define DSPFW_HPLL_CURSOR_MASK (0x3f<<16) -#define DSPFW_HPLL_SR_MASK (0x1ff) - -/* FIFO watermark sizes etc */ -#define G4X_FIFO_LINE_SIZE 64 -#define I915_FIFO_LINE_SIZE 64 -#define I830_FIFO_LINE_SIZE 32 - -#define G4X_FIFO_SIZE 127 -#define I965_FIFO_SIZE 512 -#define I945_FIFO_SIZE 127 -#define I915_FIFO_SIZE 95 -#define I855GM_FIFO_SIZE 127 /* In cachelines */ -#define I830_FIFO_SIZE 95 - -#define G4X_MAX_WM 0x3f -#define I915_MAX_WM 0x3f - -#define PINEVIEW_DISPLAY_FIFO 512 /* in 64byte unit */ -#define PINEVIEW_FIFO_LINE_SIZE 64 -#define PINEVIEW_MAX_WM 0x1ff -#define PINEVIEW_DFT_WM 0x3f -#define PINEVIEW_DFT_HPLLOFF_WM 0 -#define PINEVIEW_GUARD_WM 10 -#define PINEVIEW_CURSOR_FIFO 64 -#define PINEVIEW_CURSOR_MAX_WM 0x3f -#define PINEVIEW_CURSOR_DFT_WM 0 -#define PINEVIEW_CURSOR_GUARD_WM 5 - -#define I965_CURSOR_FIFO 64 -#define I965_CURSOR_MAX_WM 32 -#define I965_CURSOR_DFT_WM 8 - -/* define the Watermark register on Ironlake */ -#define WM0_PIPEA_ILK 0x45100 -#define WM0_PIPE_PLANE_MASK (0x7f<<16) -#define WM0_PIPE_PLANE_SHIFT 16 -#define WM0_PIPE_SPRITE_MASK (0x3f<<8) -#define WM0_PIPE_SPRITE_SHIFT 8 -#define WM0_PIPE_CURSOR_MASK (0x1f) - -#define WM0_PIPEB_ILK 0x45104 -#define WM0_PIPEC_IVB 0x45200 -#define WM1_LP_ILK 0x45108 -#define WM1_LP_SR_EN (1<<31) -#define WM1_LP_LATENCY_SHIFT 24 -#define WM1_LP_LATENCY_MASK (0x7f<<24) -#define WM1_LP_FBC_MASK (0xf<<20) -#define WM1_LP_FBC_SHIFT 20 -#define WM1_LP_SR_MASK (0x1ff<<8) -#define WM1_LP_SR_SHIFT 8 -#define WM1_LP_CURSOR_MASK (0x3f) -#define WM2_LP_ILK 0x4510c -#define WM2_LP_EN (1<<31) -#define WM3_LP_ILK 0x45110 -#define WM3_LP_EN (1<<31) -#define WM1S_LP_ILK 0x45120 -#define WM2S_LP_IVB 0x45124 -#define WM3S_LP_IVB 0x45128 -#define WM1S_LP_EN (1<<31) - -/* Memory latency timer register */ -#define MLTR_ILK 0x11222 -#define MLTR_WM1_SHIFT 0 -#define MLTR_WM2_SHIFT 8 -/* the unit of memory self-refresh latency time is 0.5us */ -#define ILK_SRLT_MASK 0x3f -#define ILK_LATENCY(shift) (I915_READ(MLTR_ILK) >> (shift) & ILK_SRLT_MASK) -#define ILK_READ_WM1_LATENCY() ILK_LATENCY(MLTR_WM1_SHIFT) -#define ILK_READ_WM2_LATENCY() ILK_LATENCY(MLTR_WM2_SHIFT) - -/* define the fifo size on Ironlake */ -#define ILK_DISPLAY_FIFO 128 -#define ILK_DISPLAY_MAXWM 64 -#define ILK_DISPLAY_DFTWM 8 -#define ILK_CURSOR_FIFO 32 -#define ILK_CURSOR_MAXWM 16 -#define ILK_CURSOR_DFTWM 8 - -#define ILK_DISPLAY_SR_FIFO 512 -#define ILK_DISPLAY_MAX_SRWM 0x1ff -#define ILK_DISPLAY_DFT_SRWM 0x3f -#define ILK_CURSOR_SR_FIFO 64 -#define ILK_CURSOR_MAX_SRWM 0x3f -#define ILK_CURSOR_DFT_SRWM 8 - -#define ILK_FIFO_LINE_SIZE 64 - -/* define the WM info on Sandybridge */ -#define SNB_DISPLAY_FIFO 128 -#define SNB_DISPLAY_MAXWM 0x7f /* bit 16:22 */ -#define SNB_DISPLAY_DFTWM 8 -#define SNB_CURSOR_FIFO 32 -#define SNB_CURSOR_MAXWM 0x1f /* bit 4:0 */ -#define SNB_CURSOR_DFTWM 8 - -#define SNB_DISPLAY_SR_FIFO 512 -#define SNB_DISPLAY_MAX_SRWM 0x1ff /* bit 16:8 */ -#define SNB_DISPLAY_DFT_SRWM 0x3f -#define SNB_CURSOR_SR_FIFO 64 -#define SNB_CURSOR_MAX_SRWM 0x3f /* bit 5:0 */ -#define SNB_CURSOR_DFT_SRWM 8 - -#define SNB_FBC_MAX_SRWM 0xf /* bit 23:20 */ - -#define SNB_FIFO_LINE_SIZE 64 - - -/* the address where we get all kinds of latency value */ -#define SSKPD 0x5d10 -#define SSKPD_WM_MASK 0x3f -#define SSKPD_WM0_SHIFT 0 -#define SSKPD_WM1_SHIFT 8 -#define SSKPD_WM2_SHIFT 16 -#define SSKPD_WM3_SHIFT 24 - -#define SNB_LATENCY(shift) (I915_READ(MCHBAR_MIRROR_BASE_SNB + SSKPD) >> (shift) & SSKPD_WM_MASK) -#define SNB_READ_WM0_LATENCY() SNB_LATENCY(SSKPD_WM0_SHIFT) -#define SNB_READ_WM1_LATENCY() SNB_LATENCY(SSKPD_WM1_SHIFT) -#define SNB_READ_WM2_LATENCY() SNB_LATENCY(SSKPD_WM2_SHIFT) -#define SNB_READ_WM3_LATENCY() SNB_LATENCY(SSKPD_WM3_SHIFT) - -/* - * The two pipe frame counter registers are not synchronized, so - * reading a stable value is somewhat tricky. The following code - * should work: - * - * do { - * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT; - * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> - * PIPE_FRAME_LOW_SHIFT); - * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> - * PIPE_FRAME_HIGH_SHIFT); - * } while (high1 != high2); - * frame = (high1 << 8) | low1; - */ -#define _PIPEAFRAMEHIGH 0x70040 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define _PIPEAFRAMEPIXEL 0x70044 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 -/* GM45+ just has to be different */ -#define _PIPEA_FRMCOUNT_GM45 0x70040 -#define _PIPEA_FLIPCOUNT_GM45 0x70044 -#define PIPE_FRMCOUNT_GM45(pipe) _PIPE(pipe, _PIPEA_FRMCOUNT_GM45, _PIPEB_FRMCOUNT_GM45) - -/* Cursor A & B regs */ -#define _CURACNTR 0x70080 -/* Old style CUR*CNTR flags (desktop 8xx) */ -#define CURSOR_ENABLE 0x80000000 -#define CURSOR_GAMMA_ENABLE 0x40000000 -#define CURSOR_STRIDE_MASK 0x30000000 -#define CURSOR_FORMAT_SHIFT 24 -#define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) -#define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) -#define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT) -#define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT) -#define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT) -#define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT) -/* New style CUR*CNTR flags */ -#define CURSOR_MODE 0x27 -#define CURSOR_MODE_DISABLE 0x00 -#define CURSOR_MODE_64_32B_AX 0x07 -#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) -#define MCURSOR_PIPE_SELECT (1 << 28) -#define MCURSOR_PIPE_A 0x00 -#define MCURSOR_PIPE_B (1 << 28) -#define MCURSOR_GAMMA_ENABLE (1 << 26) -#define _CURABASE 0x70084 -#define _CURAPOS 0x70088 -#define CURSOR_POS_MASK 0x007FF -#define CURSOR_POS_SIGN 0x8000 -#define CURSOR_X_SHIFT 0 -#define CURSOR_Y_SHIFT 16 -#define CURSIZE 0x700a0 -#define _CURBCNTR 0x700c0 -#define _CURBBASE 0x700c4 -#define _CURBPOS 0x700c8 - -#define _CURBCNTR_IVB 0x71080 -#define _CURBBASE_IVB 0x71084 -#define _CURBPOS_IVB 0x71088 - -#define CURCNTR(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR) -#define CURBASE(pipe) _PIPE(pipe, _CURABASE, _CURBBASE) -#define CURPOS(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS) - -#define CURCNTR_IVB(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR_IVB) -#define CURBASE_IVB(pipe) _PIPE(pipe, _CURABASE, _CURBBASE_IVB) -#define CURPOS_IVB(pipe) _PIPE(pipe, _CURAPOS, _CURBPOS_IVB) - -/* Display A control */ -#define _DSPACNTR 0x70180 -#define DISPLAY_PLANE_ENABLE (1<<31) -#define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1<<30) -#define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) -#define DISPPLANE_8BPP (0x2<<26) -#define DISPPLANE_15_16BPP (0x4<<26) -#define DISPPLANE_16BPP (0x5<<26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) -#define DISPPLANE_32BPP (0x7<<26) -#define DISPPLANE_32BPP_30BIT_NO_ALPHA (0xa<<26) -#define DISPPLANE_STEREO_ENABLE (1<<25) -#define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_SHIFT 24 -#define DISPPLANE_SEL_PIPE_MASK (3< - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "intel_drv.h" -#include "i915_reg.h" - -static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpll_reg; - - /* On IVB, 3rd pipe shares PLL with another one */ - if (pipe > 1) - return false; - - if (HAS_PCH_SPLIT(dev)) - dpll_reg = PCH_DPLL(pipe); - else - dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; - - return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE); -} - -static void i915_save_palette(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); - u32 *array; - int i; - - if (!i915_pipe_enabled(dev, pipe)) - return; - - if (HAS_PCH_SPLIT(dev)) - reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; - - if (pipe == PIPE_A) - array = dev_priv->save_palette_a; - else - array = dev_priv->save_palette_b; - - for (i = 0; i < 256; i++) - array[i] = I915_READ(reg + (i << 2)); -} - -static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); - u32 *array; - int i; - - if (!i915_pipe_enabled(dev, pipe)) - return; - - if (HAS_PCH_SPLIT(dev)) - reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; - - if (pipe == PIPE_A) - array = dev_priv->save_palette_a; - else - array = dev_priv->save_palette_b; - - for (i = 0; i < 256; i++) - I915_WRITE(reg + (i << 2), array[i]); -} - -static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE8(index_port, reg); - return I915_READ8(data_port); -} - -static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_READ8(st01); - I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); - return I915_READ8(VGA_AR_DATA_READ); -} - -static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_READ8(st01); - I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); - I915_WRITE8(VGA_AR_DATA_WRITE, val); -} - -static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE8(index_port, reg); - I915_WRITE8(data_port, val); -} - -static void i915_save_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - u16 cr_index, cr_data, st01; - - /* VGA color palette registers */ - dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); - - /* MSR bits */ - dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { - cr_index = VGA_CR_INDEX_CGA; - cr_data = VGA_CR_DATA_CGA; - st01 = VGA_ST01_CGA; - } else { - cr_index = VGA_CR_INDEX_MDA; - cr_data = VGA_CR_DATA_MDA; - st01 = VGA_ST01_MDA; - } - - /* CRT controller regs */ - i915_write_indexed(dev, cr_index, cr_data, 0x11, - i915_read_indexed(dev, cr_index, cr_data, 0x11) & - (~0x80)); - for (i = 0; i <= 0x24; i++) - dev_priv->saveCR[i] = - i915_read_indexed(dev, cr_index, cr_data, i); - /* Make sure we don't turn off CR group 0 writes */ - dev_priv->saveCR[0x11] &= ~0x80; - - /* Attribute controller registers */ - I915_READ8(st01); - dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX); - for (i = 0; i <= 0x14; i++) - dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0); - I915_READ8(st01); - I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX); - I915_READ8(st01); - - /* Graphics controller registers */ - for (i = 0; i < 9; i++) - dev_priv->saveGR[i] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); - - dev_priv->saveGR[0x10] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); - dev_priv->saveGR[0x11] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); - dev_priv->saveGR[0x18] = - i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); - - /* Sequencer registers */ - for (i = 0; i < 8; i++) - dev_priv->saveSR[i] = - i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); -} - -static void i915_restore_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - u16 cr_index, cr_data, st01; - - /* MSR bits */ - I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR); - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { - cr_index = VGA_CR_INDEX_CGA; - cr_data = VGA_CR_DATA_CGA; - st01 = VGA_ST01_CGA; - } else { - cr_index = VGA_CR_INDEX_MDA; - cr_data = VGA_CR_DATA_MDA; - st01 = VGA_ST01_MDA; - } - - /* Sequencer registers, don't write SR07 */ - for (i = 0; i < 7; i++) - i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, - dev_priv->saveSR[i]); - - /* CRT controller regs */ - /* Enable CR group 0 writes */ - i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); - for (i = 0; i <= 0x24; i++) - i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]); - - /* Graphics controller regs */ - for (i = 0; i < 9; i++) - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, - dev_priv->saveGR[i]); - - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, - dev_priv->saveGR[0x10]); - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, - dev_priv->saveGR[0x11]); - i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, - dev_priv->saveGR[0x18]); - - /* Attribute controller registers */ - I915_READ8(st01); /* switch back to index mode */ - for (i = 0; i <= 0x14; i++) - i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0); - I915_READ8(st01); /* switch back to index mode */ - I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20); - I915_READ8(st01); - - /* VGA color palette registers */ - I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); -} - -static void i915_save_modeset_reg(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - /* Cursor state */ - dev_priv->saveCURACNTR = I915_READ(_CURACNTR); - dev_priv->saveCURAPOS = I915_READ(_CURAPOS); - dev_priv->saveCURABASE = I915_READ(_CURABASE); - dev_priv->saveCURBCNTR = I915_READ(_CURBCNTR); - dev_priv->saveCURBPOS = I915_READ(_CURBPOS); - dev_priv->saveCURBBASE = I915_READ(_CURBBASE); - if (IS_GEN2(dev)) - dev_priv->saveCURSIZE = I915_READ(CURSIZE); - - if (HAS_PCH_SPLIT(dev)) { - dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); - dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); - } - - /* Pipe & plane A info */ - dev_priv->savePIPEACONF = I915_READ(_PIPEACONF); - dev_priv->savePIPEASRC = I915_READ(_PIPEASRC); - if (HAS_PCH_SPLIT(dev)) { - dev_priv->saveFPA0 = I915_READ(_PCH_FPA0); - dev_priv->saveFPA1 = I915_READ(_PCH_FPA1); - dev_priv->saveDPLL_A = I915_READ(_PCH_DPLL_A); - } else { - dev_priv->saveFPA0 = I915_READ(_FPA0); - dev_priv->saveFPA1 = I915_READ(_FPA1); - dev_priv->saveDPLL_A = I915_READ(_DPLL_A); - } - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) - dev_priv->saveDPLL_A_MD = I915_READ(_DPLL_A_MD); - dev_priv->saveHTOTAL_A = I915_READ(_HTOTAL_A); - dev_priv->saveHBLANK_A = I915_READ(_HBLANK_A); - dev_priv->saveHSYNC_A = I915_READ(_HSYNC_A); - dev_priv->saveVTOTAL_A = I915_READ(_VTOTAL_A); - dev_priv->saveVBLANK_A = I915_READ(_VBLANK_A); - dev_priv->saveVSYNC_A = I915_READ(_VSYNC_A); - if (!HAS_PCH_SPLIT(dev)) - dev_priv->saveBCLRPAT_A = I915_READ(_BCLRPAT_A); - - if (HAS_PCH_SPLIT(dev)) { - dev_priv->savePIPEA_DATA_M1 = I915_READ(_PIPEA_DATA_M1); - dev_priv->savePIPEA_DATA_N1 = I915_READ(_PIPEA_DATA_N1); - dev_priv->savePIPEA_LINK_M1 = I915_READ(_PIPEA_LINK_M1); - dev_priv->savePIPEA_LINK_N1 = I915_READ(_PIPEA_LINK_N1); - - dev_priv->saveFDI_TXA_CTL = I915_READ(_FDI_TXA_CTL); - dev_priv->saveFDI_RXA_CTL = I915_READ(_FDI_RXA_CTL); - - dev_priv->savePFA_CTL_1 = I915_READ(_PFA_CTL_1); - dev_priv->savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ); - dev_priv->savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); - - dev_priv->saveTRANSACONF = I915_READ(_TRANSACONF); - dev_priv->saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A); - dev_priv->saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A); - dev_priv->saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A); - dev_priv->saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A); - dev_priv->saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A); - dev_priv->saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A); - } - - dev_priv->saveDSPACNTR = I915_READ(_DSPACNTR); - dev_priv->saveDSPASTRIDE = I915_READ(_DSPASTRIDE); - dev_priv->saveDSPASIZE = I915_READ(_DSPASIZE); - dev_priv->saveDSPAPOS = I915_READ(_DSPAPOS); - dev_priv->saveDSPAADDR = I915_READ(_DSPAADDR); - if (INTEL_INFO(dev)->gen >= 4) { - dev_priv->saveDSPASURF = I915_READ(_DSPASURF); - dev_priv->saveDSPATILEOFF = I915_READ(_DSPATILEOFF); - } - i915_save_palette(dev, PIPE_A); - dev_priv->savePIPEASTAT = I915_READ(_PIPEASTAT); - - /* Pipe & plane B info */ - dev_priv->savePIPEBCONF = I915_READ(_PIPEBCONF); - dev_priv->savePIPEBSRC = I915_READ(_PIPEBSRC); - if (HAS_PCH_SPLIT(dev)) { - dev_priv->saveFPB0 = I915_READ(_PCH_FPB0); - dev_priv->saveFPB1 = I915_READ(_PCH_FPB1); - dev_priv->saveDPLL_B = I915_READ(_PCH_DPLL_B); - } else { - dev_priv->saveFPB0 = I915_READ(_FPB0); - dev_priv->saveFPB1 = I915_READ(_FPB1); - dev_priv->saveDPLL_B = I915_READ(_DPLL_B); - } - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) - dev_priv->saveDPLL_B_MD = I915_READ(_DPLL_B_MD); - dev_priv->saveHTOTAL_B = I915_READ(_HTOTAL_B); - dev_priv->saveHBLANK_B = I915_READ(_HBLANK_B); - dev_priv->saveHSYNC_B = I915_READ(_HSYNC_B); - dev_priv->saveVTOTAL_B = I915_READ(_VTOTAL_B); - dev_priv->saveVBLANK_B = I915_READ(_VBLANK_B); - dev_priv->saveVSYNC_B = I915_READ(_VSYNC_B); - if (!HAS_PCH_SPLIT(dev)) - dev_priv->saveBCLRPAT_B = I915_READ(_BCLRPAT_B); - - if (HAS_PCH_SPLIT(dev)) { - dev_priv->savePIPEB_DATA_M1 = I915_READ(_PIPEB_DATA_M1); - dev_priv->savePIPEB_DATA_N1 = I915_READ(_PIPEB_DATA_N1); - dev_priv->savePIPEB_LINK_M1 = I915_READ(_PIPEB_LINK_M1); - dev_priv->savePIPEB_LINK_N1 = I915_READ(_PIPEB_LINK_N1); - - dev_priv->saveFDI_TXB_CTL = I915_READ(_FDI_TXB_CTL); - dev_priv->saveFDI_RXB_CTL = I915_READ(_FDI_RXB_CTL); - - dev_priv->savePFB_CTL_1 = I915_READ(_PFB_CTL_1); - dev_priv->savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ); - dev_priv->savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); - - dev_priv->saveTRANSBCONF = I915_READ(_TRANSBCONF); - dev_priv->saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B); - dev_priv->saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B); - dev_priv->saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B); - dev_priv->saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B); - dev_priv->saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B); - dev_priv->saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B); - } - - dev_priv->saveDSPBCNTR = I915_READ(_DSPBCNTR); - dev_priv->saveDSPBSTRIDE = I915_READ(_DSPBSTRIDE); - dev_priv->saveDSPBSIZE = I915_READ(_DSPBSIZE); - dev_priv->saveDSPBPOS = I915_READ(_DSPBPOS); - dev_priv->saveDSPBADDR = I915_READ(_DSPBADDR); - if (INTEL_INFO(dev)->gen >= 4) { - dev_priv->saveDSPBSURF = I915_READ(_DSPBSURF); - dev_priv->saveDSPBTILEOFF = I915_READ(_DSPBTILEOFF); - } - i915_save_palette(dev, PIPE_B); - dev_priv->savePIPEBSTAT = I915_READ(_PIPEBSTAT); - - /* Fences */ - switch (INTEL_INFO(dev)->gen) { - case 7: - case 6: - for (i = 0; i < 16; i++) - dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); - break; - case 5: - case 4: - for (i = 0; i < 16; i++) - dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); - break; - case 3: - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); - case 2: - for (i = 0; i < 8; i++) - dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); - break; - } - - return; -} - -static void i915_restore_modeset_reg(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int dpll_a_reg, fpa0_reg, fpa1_reg; - int dpll_b_reg, fpb0_reg, fpb1_reg; - int i; - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - /* Fences */ - switch (INTEL_INFO(dev)->gen) { - case 7: - case 6: - for (i = 0; i < 16; i++) - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); - break; - case 5: - case 4: - for (i = 0; i < 16; i++) - I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); - break; - case 3: - case 2: - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); - break; - } - - - if (HAS_PCH_SPLIT(dev)) { - dpll_a_reg = _PCH_DPLL_A; - dpll_b_reg = _PCH_DPLL_B; - fpa0_reg = _PCH_FPA0; - fpb0_reg = _PCH_FPB0; - fpa1_reg = _PCH_FPA1; - fpb1_reg = _PCH_FPB1; - } else { - dpll_a_reg = _DPLL_A; - dpll_b_reg = _DPLL_B; - fpa0_reg = _FPA0; - fpb0_reg = _FPB0; - fpa1_reg = _FPA1; - fpb1_reg = _FPB1; - } - - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); - I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); - } - - /* Pipe & plane A info */ - /* Prime the clock */ - if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { - I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & - ~DPLL_VCO_ENABLE); - POSTING_READ(dpll_a_reg); - udelay(150); - } - I915_WRITE(fpa0_reg, dev_priv->saveFPA0); - I915_WRITE(fpa1_reg, dev_priv->saveFPA1); - /* Actually enable it */ - I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); - POSTING_READ(dpll_a_reg); - udelay(150); - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { - I915_WRITE(_DPLL_A_MD, dev_priv->saveDPLL_A_MD); - POSTING_READ(_DPLL_A_MD); - } - udelay(150); - - /* Restore mode */ - I915_WRITE(_HTOTAL_A, dev_priv->saveHTOTAL_A); - I915_WRITE(_HBLANK_A, dev_priv->saveHBLANK_A); - I915_WRITE(_HSYNC_A, dev_priv->saveHSYNC_A); - I915_WRITE(_VTOTAL_A, dev_priv->saveVTOTAL_A); - I915_WRITE(_VBLANK_A, dev_priv->saveVBLANK_A); - I915_WRITE(_VSYNC_A, dev_priv->saveVSYNC_A); - if (!HAS_PCH_SPLIT(dev)) - I915_WRITE(_BCLRPAT_A, dev_priv->saveBCLRPAT_A); - - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(_PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); - I915_WRITE(_PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); - I915_WRITE(_PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); - I915_WRITE(_PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1); - - I915_WRITE(_FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); - I915_WRITE(_FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); - - I915_WRITE(_PFA_CTL_1, dev_priv->savePFA_CTL_1); - I915_WRITE(_PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); - I915_WRITE(_PFA_WIN_POS, dev_priv->savePFA_WIN_POS); - - I915_WRITE(_TRANSACONF, dev_priv->saveTRANSACONF); - I915_WRITE(_TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); - I915_WRITE(_TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); - I915_WRITE(_TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); - I915_WRITE(_TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A); - I915_WRITE(_TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A); - I915_WRITE(_TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A); - } - - /* Restore plane info */ - I915_WRITE(_DSPASIZE, dev_priv->saveDSPASIZE); - I915_WRITE(_DSPAPOS, dev_priv->saveDSPAPOS); - I915_WRITE(_PIPEASRC, dev_priv->savePIPEASRC); - I915_WRITE(_DSPAADDR, dev_priv->saveDSPAADDR); - I915_WRITE(_DSPASTRIDE, dev_priv->saveDSPASTRIDE); - if (INTEL_INFO(dev)->gen >= 4) { - I915_WRITE(_DSPASURF, dev_priv->saveDSPASURF); - I915_WRITE(_DSPATILEOFF, dev_priv->saveDSPATILEOFF); - } - - I915_WRITE(_PIPEACONF, dev_priv->savePIPEACONF); - - i915_restore_palette(dev, PIPE_A); - /* Enable the plane */ - I915_WRITE(_DSPACNTR, dev_priv->saveDSPACNTR); - I915_WRITE(_DSPAADDR, I915_READ(_DSPAADDR)); - - /* Pipe & plane B info */ - if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { - I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & - ~DPLL_VCO_ENABLE); - POSTING_READ(dpll_b_reg); - udelay(150); - } - I915_WRITE(fpb0_reg, dev_priv->saveFPB0); - I915_WRITE(fpb1_reg, dev_priv->saveFPB1); - /* Actually enable it */ - I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); - POSTING_READ(dpll_b_reg); - udelay(150); - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { - I915_WRITE(_DPLL_B_MD, dev_priv->saveDPLL_B_MD); - POSTING_READ(_DPLL_B_MD); - } - udelay(150); - - /* Restore mode */ - I915_WRITE(_HTOTAL_B, dev_priv->saveHTOTAL_B); - I915_WRITE(_HBLANK_B, dev_priv->saveHBLANK_B); - I915_WRITE(_HSYNC_B, dev_priv->saveHSYNC_B); - I915_WRITE(_VTOTAL_B, dev_priv->saveVTOTAL_B); - I915_WRITE(_VBLANK_B, dev_priv->saveVBLANK_B); - I915_WRITE(_VSYNC_B, dev_priv->saveVSYNC_B); - if (!HAS_PCH_SPLIT(dev)) - I915_WRITE(_BCLRPAT_B, dev_priv->saveBCLRPAT_B); - - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(_PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); - I915_WRITE(_PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); - I915_WRITE(_PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); - I915_WRITE(_PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1); - - I915_WRITE(_FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); - I915_WRITE(_FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); - - I915_WRITE(_PFB_CTL_1, dev_priv->savePFB_CTL_1); - I915_WRITE(_PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); - I915_WRITE(_PFB_WIN_POS, dev_priv->savePFB_WIN_POS); - - I915_WRITE(_TRANSBCONF, dev_priv->saveTRANSBCONF); - I915_WRITE(_TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); - I915_WRITE(_TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); - I915_WRITE(_TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); - I915_WRITE(_TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B); - I915_WRITE(_TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B); - I915_WRITE(_TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B); - } - - /* Restore plane info */ - I915_WRITE(_DSPBSIZE, dev_priv->saveDSPBSIZE); - I915_WRITE(_DSPBPOS, dev_priv->saveDSPBPOS); - I915_WRITE(_PIPEBSRC, dev_priv->savePIPEBSRC); - I915_WRITE(_DSPBADDR, dev_priv->saveDSPBADDR); - I915_WRITE(_DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); - if (INTEL_INFO(dev)->gen >= 4) { - I915_WRITE(_DSPBSURF, dev_priv->saveDSPBSURF); - I915_WRITE(_DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); - } - - I915_WRITE(_PIPEBCONF, dev_priv->savePIPEBCONF); - - i915_restore_palette(dev, PIPE_B); - /* Enable the plane */ - I915_WRITE(_DSPBCNTR, dev_priv->saveDSPBCNTR); - I915_WRITE(_DSPBADDR, I915_READ(_DSPBADDR)); - - /* Cursor state */ - I915_WRITE(_CURAPOS, dev_priv->saveCURAPOS); - I915_WRITE(_CURACNTR, dev_priv->saveCURACNTR); - I915_WRITE(_CURABASE, dev_priv->saveCURABASE); - I915_WRITE(_CURBPOS, dev_priv->saveCURBPOS); - I915_WRITE(_CURBCNTR, dev_priv->saveCURBCNTR); - I915_WRITE(_CURBBASE, dev_priv->saveCURBBASE); - if (IS_GEN2(dev)) - I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); - - return; -} - -static void i915_save_display(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* Display arbitration control */ - dev_priv->saveDSPARB = I915_READ(DSPARB); - - /* This is only meaningful in non-KMS mode */ - /* Don't save them in KMS mode */ - i915_save_modeset_reg(dev); - - /* CRT state */ - if (HAS_PCH_SPLIT(dev)) { - dev_priv->saveADPA = I915_READ(PCH_ADPA); - } else { - dev_priv->saveADPA = I915_READ(ADPA); - } - - /* LVDS state */ - if (HAS_PCH_SPLIT(dev)) { - dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); - dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL); - dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2); - dev_priv->saveLVDS = I915_READ(PCH_LVDS); - } else { - dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); - dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); - dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); - if (INTEL_INFO(dev)->gen >= 4) - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); - if (IS_MOBILE(dev) && !IS_I830(dev)) - dev_priv->saveLVDS = I915_READ(LVDS); - } - - if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) - dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); - - if (HAS_PCH_SPLIT(dev)) { - dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); - dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); - dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); - } else { - dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); - dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); - dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); - } - - /* Display Port state */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - dev_priv->saveDP_B = I915_READ(DP_B); - dev_priv->saveDP_C = I915_READ(DP_C); - dev_priv->saveDP_D = I915_READ(DP_D); - dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(_PIPEA_GMCH_DATA_M); - dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(_PIPEB_GMCH_DATA_M); - dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(_PIPEA_GMCH_DATA_N); - dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(_PIPEB_GMCH_DATA_N); - dev_priv->savePIPEA_DP_LINK_M = I915_READ(_PIPEA_DP_LINK_M); - dev_priv->savePIPEB_DP_LINK_M = I915_READ(_PIPEB_DP_LINK_M); - dev_priv->savePIPEA_DP_LINK_N = I915_READ(_PIPEA_DP_LINK_N); - dev_priv->savePIPEB_DP_LINK_N = I915_READ(_PIPEB_DP_LINK_N); - } - /* FIXME: save TV & SDVO state */ - - /* Only save FBC state on the platform that supports FBC */ - if (I915_HAS_FBC(dev)) { - if (HAS_PCH_SPLIT(dev)) { - dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); - } else if (IS_GM45(dev)) { - dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); - } else { - dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); - dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); - dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); - dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); - } - } - - /* VGA state */ - dev_priv->saveVGA0 = I915_READ(VGA0); - dev_priv->saveVGA1 = I915_READ(VGA1); - dev_priv->saveVGA_PD = I915_READ(VGA_PD); - if (HAS_PCH_SPLIT(dev)) - dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); - else - dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); - - i915_save_vga(dev); -} - -static void i915_restore_display(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* Display arbitration */ - I915_WRITE(DSPARB, dev_priv->saveDSPARB); - - /* Display port ratios (must be done before clock is set) */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - I915_WRITE(_PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); - I915_WRITE(_PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); - I915_WRITE(_PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); - I915_WRITE(_PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); - I915_WRITE(_PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); - I915_WRITE(_PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); - I915_WRITE(_PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); - I915_WRITE(_PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); - } - - /* This is only meaningful in non-KMS mode */ - /* Don't restore them in KMS mode */ - i915_restore_modeset_reg(dev); - - /* CRT state */ - if (HAS_PCH_SPLIT(dev)) - I915_WRITE(PCH_ADPA, dev_priv->saveADPA); - else - I915_WRITE(ADPA, dev_priv->saveADPA); - - /* LVDS state */ - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) - I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); - - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); - } else if (IS_MOBILE(dev) && !IS_I830(dev)) - I915_WRITE(LVDS, dev_priv->saveLVDS); - - if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) - I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); - - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; - * otherwise we get blank eDP screen after S3 on some machines - */ - I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); - I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); - I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); - I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); - I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); - I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); - I915_WRITE(RSTDBYCTL, - dev_priv->saveMCHBAR_RENDER_STANDBY); - } else { - I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); - I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); - I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL); - I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); - I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); - I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); - I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); - } - - /* Display Port state */ - if (SUPPORTS_INTEGRATED_DP(dev)) { - I915_WRITE(DP_B, dev_priv->saveDP_B); - I915_WRITE(DP_C, dev_priv->saveDP_C); - I915_WRITE(DP_D, dev_priv->saveDP_D); - } - /* FIXME: restore TV & SDVO state */ - - /* only restore FBC info on the platform that supports FBC*/ - intel_disable_fbc(dev); - if (I915_HAS_FBC(dev)) { - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); - } else if (IS_GM45(dev)) { - I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); - } else { - I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); - I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); - I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); - I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); - } - } - /* VGA state */ - if (HAS_PCH_SPLIT(dev)) - I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); - else - I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); - - I915_WRITE(VGA0, dev_priv->saveVGA0); - I915_WRITE(VGA1, dev_priv->saveVGA1); - I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); - POSTING_READ(VGA_PD); - udelay(150); - - i915_restore_vga(dev); -} - -int i915_save_state(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); - - mutex_lock(&dev->struct_mutex); - - /* Hardware status page */ - dev_priv->saveHWS = I915_READ(HWS_PGA); - - i915_save_display(dev); - - /* Interrupt state */ - if (HAS_PCH_SPLIT(dev)) { - dev_priv->saveDEIER = I915_READ(DEIER); - dev_priv->saveDEIMR = I915_READ(DEIMR); - dev_priv->saveGTIER = I915_READ(GTIER); - dev_priv->saveGTIMR = I915_READ(GTIMR); - dev_priv->saveFDI_RXA_IMR = I915_READ(_FDI_RXA_IMR); - dev_priv->saveFDI_RXB_IMR = I915_READ(_FDI_RXB_IMR); - dev_priv->saveMCHBAR_RENDER_STANDBY = - I915_READ(RSTDBYCTL); - dev_priv->savePCH_PORT_HOTPLUG = I915_READ(PCH_PORT_HOTPLUG); - } else { - dev_priv->saveIER = I915_READ(IER); - dev_priv->saveIMR = I915_READ(IMR); - } - - if (IS_IRONLAKE_M(dev)) - ironlake_disable_drps(dev); - if (INTEL_INFO(dev)->gen >= 6) - gen6_disable_rps(dev); - - /* Cache mode state */ - dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); - - /* Memory Arbitration state */ - dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); - - /* Scratch space */ - for (i = 0; i < 16; i++) { - dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); - dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); - } - for (i = 0; i < 3; i++) - dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); - - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -int i915_restore_state(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); - - mutex_lock(&dev->struct_mutex); - - /* Hardware status page */ - I915_WRITE(HWS_PGA, dev_priv->saveHWS); - - i915_restore_display(dev); - - /* Interrupt state */ - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(DEIER, dev_priv->saveDEIER); - I915_WRITE(DEIMR, dev_priv->saveDEIMR); - I915_WRITE(GTIER, dev_priv->saveGTIER); - I915_WRITE(GTIMR, dev_priv->saveGTIMR); - I915_WRITE(_FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR); - I915_WRITE(_FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR); - I915_WRITE(PCH_PORT_HOTPLUG, dev_priv->savePCH_PORT_HOTPLUG); - } else { - I915_WRITE(IER, dev_priv->saveIER); - I915_WRITE(IMR, dev_priv->saveIMR); - } - mutex_unlock(&dev->struct_mutex); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - intel_init_clock_gating(dev); - - if (IS_IRONLAKE_M(dev)) { - ironlake_enable_drps(dev); - intel_init_emon(dev); - } - - if (INTEL_INFO(dev)->gen >= 6) { - gen6_enable_rps(dev_priv); - gen6_update_ring_freq(dev_priv); - } - - mutex_lock(&dev->struct_mutex); - - /* Cache mode state */ - I915_WRITE(CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); - - /* Memory arbitration state */ - I915_WRITE(MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); - - for (i = 0; i < 16; i++) { - I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); - I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]); - } - for (i = 0; i < 3; i++) - I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); - - mutex_unlock(&dev->struct_mutex); - - intel_i2c_reset(dev); - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace.h deleted file mode 100644 index dac7bba4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace.h +++ /dev/null @@ -1,418 +0,0 @@ -#if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) -#define _I915_TRACE_H_ - -#include -#include -#include - -#include -#include "i915_drv.h" -#include "intel_ringbuffer.h" - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM i915 -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) -#define TRACE_INCLUDE_FILE i915_trace - -/* object tracking */ - -TRACE_EVENT(i915_gem_object_create, - TP_PROTO(struct drm_i915_gem_object *obj), - TP_ARGS(obj), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, size) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->size = obj->base.size; - ), - - TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) -); - -TRACE_EVENT(i915_gem_object_bind, - TP_PROTO(struct drm_i915_gem_object *obj, bool mappable), - TP_ARGS(obj, mappable), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, offset) - __field(u32, size) - __field(bool, mappable) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->offset = obj->gtt_space->start; - __entry->size = obj->gtt_space->size; - __entry->mappable = mappable; - ), - - TP_printk("obj=%p, offset=%08x size=%x%s", - __entry->obj, __entry->offset, __entry->size, - __entry->mappable ? ", mappable" : "") -); - -TRACE_EVENT(i915_gem_object_unbind, - TP_PROTO(struct drm_i915_gem_object *obj), - TP_ARGS(obj), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, offset) - __field(u32, size) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->offset = obj->gtt_space->start; - __entry->size = obj->gtt_space->size; - ), - - TP_printk("obj=%p, offset=%08x size=%x", - __entry->obj, __entry->offset, __entry->size) -); - -TRACE_EVENT(i915_gem_object_change_domain, - TP_PROTO(struct drm_i915_gem_object *obj, u32 old_read, u32 old_write), - TP_ARGS(obj, old_read, old_write), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, read_domains) - __field(u32, write_domain) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->read_domains = obj->base.read_domains | (old_read << 16); - __entry->write_domain = obj->base.write_domain | (old_write << 16); - ), - - TP_printk("obj=%p, read=%02x=>%02x, write=%02x=>%02x", - __entry->obj, - __entry->read_domains >> 16, - __entry->read_domains & 0xffff, - __entry->write_domain >> 16, - __entry->write_domain & 0xffff) -); - -TRACE_EVENT(i915_gem_object_pwrite, - TP_PROTO(struct drm_i915_gem_object *obj, u32 offset, u32 len), - TP_ARGS(obj, offset, len), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, offset) - __field(u32, len) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->offset = offset; - __entry->len = len; - ), - - TP_printk("obj=%p, offset=%u, len=%u", - __entry->obj, __entry->offset, __entry->len) -); - -TRACE_EVENT(i915_gem_object_pread, - TP_PROTO(struct drm_i915_gem_object *obj, u32 offset, u32 len), - TP_ARGS(obj, offset, len), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, offset) - __field(u32, len) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->offset = offset; - __entry->len = len; - ), - - TP_printk("obj=%p, offset=%u, len=%u", - __entry->obj, __entry->offset, __entry->len) -); - -TRACE_EVENT(i915_gem_object_fault, - TP_PROTO(struct drm_i915_gem_object *obj, u32 index, bool gtt, bool write), - TP_ARGS(obj, index, gtt, write), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(u32, index) - __field(bool, gtt) - __field(bool, write) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->index = index; - __entry->gtt = gtt; - __entry->write = write; - ), - - TP_printk("obj=%p, %s index=%u %s", - __entry->obj, - __entry->gtt ? "GTT" : "CPU", - __entry->index, - __entry->write ? ", writable" : "") -); - -DECLARE_EVENT_CLASS(i915_gem_object, - TP_PROTO(struct drm_i915_gem_object *obj), - TP_ARGS(obj), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - ), - - TP_fast_assign( - __entry->obj = obj; - ), - - TP_printk("obj=%p", __entry->obj) -); - -DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, - TP_PROTO(struct drm_i915_gem_object *obj), - TP_ARGS(obj) -); - -DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, - TP_PROTO(struct drm_i915_gem_object *obj), - TP_ARGS(obj) -); - -TRACE_EVENT(i915_gem_evict, - TP_PROTO(struct drm_device *dev, u32 size, u32 align, bool mappable), - TP_ARGS(dev, size, align, mappable), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, size) - __field(u32, align) - __field(bool, mappable) - ), - - TP_fast_assign( - __entry->dev = dev->primary->index; - __entry->size = size; - __entry->align = align; - __entry->mappable = mappable; - ), - - TP_printk("dev=%d, size=%d, align=%d %s", - __entry->dev, __entry->size, __entry->align, - __entry->mappable ? ", mappable" : "") -); - -TRACE_EVENT(i915_gem_evict_everything, - TP_PROTO(struct drm_device *dev, bool purgeable), - TP_ARGS(dev, purgeable), - - TP_STRUCT__entry( - __field(u32, dev) - __field(bool, purgeable) - ), - - TP_fast_assign( - __entry->dev = dev->primary->index; - __entry->purgeable = purgeable; - ), - - TP_printk("dev=%d%s", - __entry->dev, - __entry->purgeable ? ", purgeable only" : "") -); - -TRACE_EVENT(i915_gem_ring_dispatch, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, ring) - __field(u32, seqno) - ), - - TP_fast_assign( - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; - __entry->seqno = seqno; - i915_trace_irq_get(ring, seqno); - ), - - TP_printk("dev=%u, ring=%u, seqno=%u", - __entry->dev, __entry->ring, __entry->seqno) -); - -TRACE_EVENT(i915_gem_ring_flush, - TP_PROTO(struct intel_ring_buffer *ring, u32 invalidate, u32 flush), - TP_ARGS(ring, invalidate, flush), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, ring) - __field(u32, invalidate) - __field(u32, flush) - ), - - TP_fast_assign( - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; - __entry->invalidate = invalidate; - __entry->flush = flush; - ), - - TP_printk("dev=%u, ring=%x, invalidate=%04x, flush=%04x", - __entry->dev, __entry->ring, - __entry->invalidate, __entry->flush) -); - -DECLARE_EVENT_CLASS(i915_gem_request, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, ring) - __field(u32, seqno) - ), - - TP_fast_assign( - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; - __entry->seqno = seqno; - ), - - TP_printk("dev=%u, ring=%u, seqno=%u", - __entry->dev, __entry->ring, __entry->seqno) -); - -DEFINE_EVENT(i915_gem_request, i915_gem_request_add, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno) -); - -DEFINE_EVENT(i915_gem_request, i915_gem_request_complete, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno) -); - -DEFINE_EVENT(i915_gem_request, i915_gem_request_retire, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno) -); - -DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_begin, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno) -); - -DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end, - TP_PROTO(struct intel_ring_buffer *ring, u32 seqno), - TP_ARGS(ring, seqno) -); - -DECLARE_EVENT_CLASS(i915_ring, - TP_PROTO(struct intel_ring_buffer *ring), - TP_ARGS(ring), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, ring) - ), - - TP_fast_assign( - __entry->dev = ring->dev->primary->index; - __entry->ring = ring->id; - ), - - TP_printk("dev=%u, ring=%u", __entry->dev, __entry->ring) -); - -DEFINE_EVENT(i915_ring, i915_ring_wait_begin, - TP_PROTO(struct intel_ring_buffer *ring), - TP_ARGS(ring) -); - -DEFINE_EVENT(i915_ring, i915_ring_wait_end, - TP_PROTO(struct intel_ring_buffer *ring), - TP_ARGS(ring) -); - -TRACE_EVENT(i915_flip_request, - TP_PROTO(int plane, struct drm_i915_gem_object *obj), - - TP_ARGS(plane, obj), - - TP_STRUCT__entry( - __field(int, plane) - __field(struct drm_i915_gem_object *, obj) - ), - - TP_fast_assign( - __entry->plane = plane; - __entry->obj = obj; - ), - - TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) -); - -TRACE_EVENT(i915_flip_complete, - TP_PROTO(int plane, struct drm_i915_gem_object *obj), - - TP_ARGS(plane, obj), - - TP_STRUCT__entry( - __field(int, plane) - __field(struct drm_i915_gem_object *, obj) - ), - - TP_fast_assign( - __entry->plane = plane; - __entry->obj = obj; - ), - - TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) -); - -TRACE_EVENT(i915_reg_rw, - TP_PROTO(bool write, u32 reg, u64 val, int len), - - TP_ARGS(write, reg, val, len), - - TP_STRUCT__entry( - __field(u64, val) - __field(u32, reg) - __field(u16, write) - __field(u16, len) - ), - - TP_fast_assign( - __entry->val = (u64)val; - __entry->reg = reg; - __entry->write = write; - __entry->len = len; - ), - - TP_printk("%s reg=0x%x, len=%d, val=(0x%x, 0x%x)", - __entry->write ? "write" : "read", - __entry->reg, __entry->len, - (u32)(__entry->val & 0xffffffff), - (u32)(__entry->val >> 32)) -); - -#endif /* _I915_TRACE_H_ */ - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#include diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace_points.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace_points.c deleted file mode 100644 index ead876eb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/i915_trace_points.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * Authors: - * Chris Wilson - */ - -#include "i915_drv.h" - -#define CREATE_TRACE_POINTS -#include "i915_trace.h" diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_acpi.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_acpi.c deleted file mode 100644 index bae3edf9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_acpi.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Intel ACPI functions - * - * _DSM related code stolen from nouveau_acpi.c. - */ -#include -#include -#include -#include - -#include "drmP.h" - -#define INTEL_DSM_REVISION_ID 1 /* For Calpella anyway... */ - -#define INTEL_DSM_FN_SUPPORTED_FUNCTIONS 0 /* No args */ -#define INTEL_DSM_FN_PLATFORM_MUX_INFO 1 /* No args */ - -static struct intel_dsm_priv { - acpi_handle dhandle; -} intel_dsm_priv; - -static const u8 intel_dsm_guid[] = { - 0xd3, 0x73, 0xd8, 0x7e, - 0xd0, 0xc2, - 0x4f, 0x4e, - 0xa8, 0x54, - 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c -}; - -static int intel_dsm(acpi_handle handle, int func, int arg) -{ - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_object_list input; - union acpi_object params[4]; - union acpi_object *obj; - u32 result; - int ret = 0; - - input.count = 4; - input.pointer = params; - params[0].type = ACPI_TYPE_BUFFER; - params[0].buffer.length = sizeof(intel_dsm_guid); - params[0].buffer.pointer = (char *)intel_dsm_guid; - params[1].type = ACPI_TYPE_INTEGER; - params[1].integer.value = INTEL_DSM_REVISION_ID; - params[2].type = ACPI_TYPE_INTEGER; - params[2].integer.value = func; - params[3].type = ACPI_TYPE_INTEGER; - params[3].integer.value = arg; - - ret = acpi_evaluate_object(handle, "_DSM", &input, &output); - if (ret) { - DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret); - return ret; - } - - obj = (union acpi_object *)output.pointer; - - result = 0; - switch (obj->type) { - case ACPI_TYPE_INTEGER: - result = obj->integer.value; - break; - - case ACPI_TYPE_BUFFER: - if (obj->buffer.length == 4) { - result = (obj->buffer.pointer[0] | - (obj->buffer.pointer[1] << 8) | - (obj->buffer.pointer[2] << 16) | - (obj->buffer.pointer[3] << 24)); - break; - } - default: - ret = -EINVAL; - break; - } - if (result == 0x80000002) - ret = -ENODEV; - - kfree(output.pointer); - return ret; -} - -static char *intel_dsm_port_name(u8 id) -{ - switch (id) { - case 0: - return "Reserved"; - case 1: - return "Analog VGA"; - case 2: - return "LVDS"; - case 3: - return "Reserved"; - case 4: - return "HDMI/DVI_B"; - case 5: - return "HDMI/DVI_C"; - case 6: - return "HDMI/DVI_D"; - case 7: - return "DisplayPort_A"; - case 8: - return "DisplayPort_B"; - case 9: - return "DisplayPort_C"; - case 0xa: - return "DisplayPort_D"; - case 0xb: - case 0xc: - case 0xd: - return "Reserved"; - case 0xe: - return "WiDi"; - default: - return "bad type"; - } -} - -static char *intel_dsm_mux_type(u8 type) -{ - switch (type) { - case 0: - return "unknown"; - case 1: - return "No MUX, iGPU only"; - case 2: - return "No MUX, dGPU only"; - case 3: - return "MUXed between iGPU and dGPU"; - default: - return "bad type"; - } -} - -static void intel_dsm_platform_mux_info(void) -{ - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_object_list input; - union acpi_object params[4]; - union acpi_object *pkg; - int i, ret; - - input.count = 4; - input.pointer = params; - params[0].type = ACPI_TYPE_BUFFER; - params[0].buffer.length = sizeof(intel_dsm_guid); - params[0].buffer.pointer = (char *)intel_dsm_guid; - params[1].type = ACPI_TYPE_INTEGER; - params[1].integer.value = INTEL_DSM_REVISION_ID; - params[2].type = ACPI_TYPE_INTEGER; - params[2].integer.value = INTEL_DSM_FN_PLATFORM_MUX_INFO; - params[3].type = ACPI_TYPE_INTEGER; - params[3].integer.value = 0; - - ret = acpi_evaluate_object(intel_dsm_priv.dhandle, "_DSM", &input, - &output); - if (ret) { - DRM_DEBUG_DRIVER("failed to evaluate _DSM: %d\n", ret); - goto out; - } - - pkg = (union acpi_object *)output.pointer; - - if (pkg->type == ACPI_TYPE_PACKAGE) { - union acpi_object *connector_count = &pkg->package.elements[0]; - DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", - (unsigned long long)connector_count->integer.value); - for (i = 1; i < pkg->package.count; i++) { - union acpi_object *obj = &pkg->package.elements[i]; - union acpi_object *connector_id = - &obj->package.elements[0]; - union acpi_object *info = &obj->package.elements[1]; - DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", - (unsigned long long)connector_id->integer.value); - DRM_DEBUG_DRIVER(" port id: %s\n", - intel_dsm_port_name(info->buffer.pointer[0])); - DRM_DEBUG_DRIVER(" display mux info: %s\n", - intel_dsm_mux_type(info->buffer.pointer[1])); - DRM_DEBUG_DRIVER(" aux/dc mux info: %s\n", - intel_dsm_mux_type(info->buffer.pointer[2])); - DRM_DEBUG_DRIVER(" hpd mux info: %s\n", - intel_dsm_mux_type(info->buffer.pointer[3])); - } - } else { - DRM_ERROR("MUX INFO call failed\n"); - } - -out: - kfree(output.pointer); -} - -static bool intel_dsm_pci_probe(struct pci_dev *pdev) -{ - acpi_handle dhandle, intel_handle; - acpi_status status; - int ret; - - dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); - if (!dhandle) - return false; - - status = acpi_get_handle(dhandle, "_DSM", &intel_handle); - if (ACPI_FAILURE(status)) { - DRM_DEBUG_KMS("no _DSM method for intel device\n"); - return false; - } - - ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0); - if (ret < 0) { - DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); - return false; - } - - intel_dsm_priv.dhandle = dhandle; - - intel_dsm_platform_mux_info(); - return true; -} - -static bool intel_dsm_detect(void) -{ - char acpi_method_name[255] = { 0 }; - struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; - struct pci_dev *pdev = NULL; - bool has_dsm = false; - int vga_count = 0; - - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { - vga_count++; - has_dsm |= intel_dsm_pci_probe(pdev); - } - - if (vga_count == 2 && has_dsm) { - acpi_get_name(intel_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer); - DRM_DEBUG_DRIVER("VGA switcheroo: detected DSM switching method %s handle\n", - acpi_method_name); - return true; - } - - return false; -} - -void intel_register_dsm_handler(void) -{ - if (!intel_dsm_detect()) - return; -} - -void intel_unregister_dsm_handler(void) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.c deleted file mode 100644 index b48fc2a8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Copyright © 2006 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ -#include -#include -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "intel_bios.h" - -#define SLAVE_ADDR1 0x70 -#define SLAVE_ADDR2 0x72 - -static int panel_type; - -static void * -find_section(struct bdb_header *bdb, int section_id) -{ - u8 *base = (u8 *)bdb; - int index = 0; - u16 total, current_size; - u8 current_id; - - /* skip to first section */ - index += bdb->header_size; - total = bdb->bdb_size; - - /* walk the sections looking for section_id */ - while (index < total) { - current_id = *(base + index); - index++; - current_size = *((u16 *)(base + index)); - index += 2; - if (current_id == section_id) - return base + index; - index += current_size; - } - - return NULL; -} - -static u16 -get_blocksize(void *p) -{ - u16 *block_ptr, block_size; - - block_ptr = (u16 *)((char *)p - 2); - block_size = *block_ptr; - return block_size; -} - -static void -fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, - const struct lvds_dvo_timing *dvo_timing) -{ - panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) | - dvo_timing->hactive_lo; - panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + - ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo); - panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + - dvo_timing->hsync_pulse_width; - panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + - ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo); - - panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) | - dvo_timing->vactive_lo; - panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + - dvo_timing->vsync_off; - panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + - dvo_timing->vsync_pulse_width; - panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + - ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo); - panel_fixed_mode->clock = dvo_timing->clock * 10; - panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; - - if (dvo_timing->hsync_positive) - panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC; - else - panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC; - - if (dvo_timing->vsync_positive) - panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC; - else - panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; - - /* Some VBTs have bogus h/vtotal values */ - if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) - panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; - if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) - panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; - - drm_mode_set_name(panel_fixed_mode); -} - -static bool -lvds_dvo_timing_equal_size(const struct lvds_dvo_timing *a, - const struct lvds_dvo_timing *b) -{ - if (a->hactive_hi != b->hactive_hi || - a->hactive_lo != b->hactive_lo) - return false; - - if (a->hsync_off_hi != b->hsync_off_hi || - a->hsync_off_lo != b->hsync_off_lo) - return false; - - if (a->hsync_pulse_width != b->hsync_pulse_width) - return false; - - if (a->hblank_hi != b->hblank_hi || - a->hblank_lo != b->hblank_lo) - return false; - - if (a->vactive_hi != b->vactive_hi || - a->vactive_lo != b->vactive_lo) - return false; - - if (a->vsync_off != b->vsync_off) - return false; - - if (a->vsync_pulse_width != b->vsync_pulse_width) - return false; - - if (a->vblank_hi != b->vblank_hi || - a->vblank_lo != b->vblank_lo) - return false; - - return true; -} - -static const struct lvds_dvo_timing * -get_lvds_dvo_timing(const struct bdb_lvds_lfp_data *lvds_lfp_data, - const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs, - int index) -{ - /* - * the size of fp_timing varies on the different platform. - * So calculate the DVO timing relative offset in LVDS data - * entry to get the DVO timing entry - */ - - int lfp_data_size = - lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset - - lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset; - int dvo_timing_offset = - lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset - - lvds_lfp_data_ptrs->ptr[0].fp_timing_offset; - char *entry = (char *)lvds_lfp_data->data + lfp_data_size * index; - - return (struct lvds_dvo_timing *)(entry + dvo_timing_offset); -} - -/* Try to find integrated panel data */ -static void -parse_lfp_panel_data(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - const struct bdb_lvds_options *lvds_options; - const struct bdb_lvds_lfp_data *lvds_lfp_data; - const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; - const struct lvds_dvo_timing *panel_dvo_timing; - struct drm_display_mode *panel_fixed_mode; - int i, downclock; - - lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); - if (!lvds_options) - return; - - dev_priv->lvds_dither = lvds_options->pixel_dither; - if (lvds_options->panel_type == 0xff) - return; - - panel_type = lvds_options->panel_type; - - lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); - if (!lvds_lfp_data) - return; - - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); - if (!lvds_lfp_data_ptrs) - return; - - dev_priv->lvds_vbt = 1; - - panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data, - lvds_lfp_data_ptrs, - lvds_options->panel_type); - - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); - if (!panel_fixed_mode) - return; - - fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing); - - dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; - - DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n"); - drm_mode_debug_printmodeline(panel_fixed_mode); - - /* - * Iterate over the LVDS panel timing info to find the lowest clock - * for the native resolution. - */ - downclock = panel_dvo_timing->clock; - for (i = 0; i < 16; i++) { - const struct lvds_dvo_timing *dvo_timing; - - dvo_timing = get_lvds_dvo_timing(lvds_lfp_data, - lvds_lfp_data_ptrs, - i); - if (lvds_dvo_timing_equal_size(dvo_timing, panel_dvo_timing) && - dvo_timing->clock < downclock) - downclock = dvo_timing->clock; - } - - if (downclock < panel_dvo_timing->clock && i915_lvds_downclock) { - dev_priv->lvds_downclock_avail = 1; - dev_priv->lvds_downclock = downclock * 10; - DRM_DEBUG_KMS("LVDS downclock is found in VBT. " - "Normal Clock %dKHz, downclock %dKHz\n", - panel_fixed_mode->clock, 10*downclock); - } -} - -/* Try to find sdvo panel data */ -static void -parse_sdvo_panel_data(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - struct lvds_dvo_timing *dvo_timing; - struct drm_display_mode *panel_fixed_mode; - int index; - - index = i915_vbt_sdvo_panel_type; - if (index == -1) { - struct bdb_sdvo_lvds_options *sdvo_lvds_options; - - sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS); - if (!sdvo_lvds_options) - return; - - index = sdvo_lvds_options->panel_type; - } - - dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS); - if (!dvo_timing) - return; - - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); - if (!panel_fixed_mode) - return; - - fill_detail_timing_data(panel_fixed_mode, dvo_timing + index); - - dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode; - - DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n"); - drm_mode_debug_printmodeline(panel_fixed_mode); -} - -static int intel_bios_ssc_frequency(struct drm_device *dev, - bool alternate) -{ - switch (INTEL_INFO(dev)->gen) { - case 2: - return alternate ? 66 : 48; - case 3: - case 4: - return alternate ? 100 : 96; - default: - return alternate ? 100 : 120; - } -} - -static void -parse_general_features(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - struct drm_device *dev = dev_priv->dev; - struct bdb_general_features *general; - - general = find_section(bdb, BDB_GENERAL_FEATURES); - if (general) { - dev_priv->int_tv_support = general->int_tv_support; - dev_priv->int_crt_support = general->int_crt_support; - dev_priv->lvds_use_ssc = general->enable_ssc; - dev_priv->lvds_ssc_freq = - intel_bios_ssc_frequency(dev, general->ssc_freq); - dev_priv->display_clock_mode = general->display_clock_mode; - DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d\n", - dev_priv->int_tv_support, - dev_priv->int_crt_support, - dev_priv->lvds_use_ssc, - dev_priv->lvds_ssc_freq, - dev_priv->display_clock_mode); - } -} - -static void -parse_general_definitions(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_general_definitions *general; - - general = find_section(bdb, BDB_GENERAL_DEFINITIONS); - if (general) { - u16 block_size = get_blocksize(general); - if (block_size >= sizeof(*general)) { - int bus_pin = general->crt_ddc_gmbus_pin; - DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin); - if (bus_pin >= 1 && bus_pin <= 6) - dev_priv->crt_ddc_pin = bus_pin; - } else { - DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n", - block_size); - } - } -} - -static void -parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - struct sdvo_device_mapping *p_mapping; - struct bdb_general_definitions *p_defs; - struct child_device_config *p_child; - int i, child_device_num, count; - u16 block_size; - - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); - if (!p_defs) { - DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); - return; - } - /* judge whether the size of child device meets the requirements. - * If the child device size obtained from general definition block - * is different with sizeof(struct child_device_config), skip the - * parsing of sdvo device info - */ - if (p_defs->child_dev_size != sizeof(*p_child)) { - /* different child dev size . Ignore it */ - DRM_DEBUG_KMS("different child size is found. Invalid.\n"); - return; - } - /* get the block size of general definitions */ - block_size = get_blocksize(p_defs); - /* get the number of child device */ - child_device_num = (block_size - sizeof(*p_defs)) / - sizeof(*p_child); - count = 0; - for (i = 0; i < child_device_num; i++) { - p_child = &(p_defs->devices[i]); - if (!p_child->device_type) { - /* skip the device block if device type is invalid */ - continue; - } - if (p_child->slave_addr != SLAVE_ADDR1 && - p_child->slave_addr != SLAVE_ADDR2) { - /* - * If the slave address is neither 0x70 nor 0x72, - * it is not a SDVO device. Skip it. - */ - continue; - } - if (p_child->dvo_port != DEVICE_PORT_DVOB && - p_child->dvo_port != DEVICE_PORT_DVOC) { - /* skip the incorrect SDVO port */ - DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n"); - continue; - } - DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on" - " %s port\n", - p_child->slave_addr, - (p_child->dvo_port == DEVICE_PORT_DVOB) ? - "SDVOB" : "SDVOC"); - p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]); - if (!p_mapping->initialized) { - p_mapping->dvo_port = p_child->dvo_port; - p_mapping->slave_addr = p_child->slave_addr; - p_mapping->dvo_wiring = p_child->dvo_wiring; - p_mapping->ddc_pin = p_child->ddc_pin; - p_mapping->i2c_pin = p_child->i2c_pin; - p_mapping->initialized = 1; - DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n", - p_mapping->dvo_port, - p_mapping->slave_addr, - p_mapping->dvo_wiring, - p_mapping->ddc_pin, - p_mapping->i2c_pin); - } else { - DRM_DEBUG_KMS("Maybe one SDVO port is shared by " - "two SDVO device.\n"); - } - if (p_child->slave2_addr) { - /* Maybe this is a SDVO device with multiple inputs */ - /* And the mapping info is not added */ - DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this" - " is a SDVO device with multiple inputs.\n"); - } - count++; - } - - if (!count) { - /* No SDVO device info is found */ - DRM_DEBUG_KMS("No SDVO device info is found in VBT\n"); - } - return; -} - -static void -parse_driver_features(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - struct drm_device *dev = dev_priv->dev; - struct bdb_driver_features *driver; - - driver = find_section(bdb, BDB_DRIVER_FEATURES); - if (!driver) - return; - - if (SUPPORTS_EDP(dev) && - driver->lvds_config == BDB_DRIVER_FEATURE_EDP) - dev_priv->edp.support = 1; - - if (driver->dual_frequency) - dev_priv->render_reclock_avail = true; -} - -static void -parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) -{ - struct bdb_edp *edp; - struct edp_power_seq *edp_pps; - struct edp_link_params *edp_link_params; - - edp = find_section(bdb, BDB_EDP); - if (!edp) { - if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) { - DRM_DEBUG_KMS("No eDP BDB found but eDP panel " - "supported, assume %dbpp panel color " - "depth.\n", - dev_priv->edp.bpp); - } - return; - } - - switch ((edp->color_depth >> (panel_type * 2)) & 3) { - case EDP_18BPP: - dev_priv->edp.bpp = 18; - break; - case EDP_24BPP: - dev_priv->edp.bpp = 24; - break; - case EDP_30BPP: - dev_priv->edp.bpp = 30; - break; - } - - /* Get the eDP sequencing and link info */ - edp_pps = &edp->power_seqs[panel_type]; - edp_link_params = &edp->link_params[panel_type]; - - dev_priv->edp.pps = *edp_pps; - - dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 : - DP_LINK_BW_1_62; - switch (edp_link_params->lanes) { - case 0: - dev_priv->edp.lanes = 1; - break; - case 1: - dev_priv->edp.lanes = 2; - break; - case 3: - default: - dev_priv->edp.lanes = 4; - break; - } - switch (edp_link_params->preemphasis) { - case 0: - dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0; - break; - case 1: - dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5; - break; - case 2: - dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6; - break; - case 3: - dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5; - break; - } - switch (edp_link_params->vswing) { - case 0: - dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400; - break; - case 1: - dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600; - break; - case 2: - dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800; - break; - case 3: - dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200; - break; - } -} - -static void -parse_device_mapping(struct drm_i915_private *dev_priv, - struct bdb_header *bdb) -{ - struct bdb_general_definitions *p_defs; - struct child_device_config *p_child, *child_dev_ptr; - int i, child_device_num, count; - u16 block_size; - - p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); - if (!p_defs) { - DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); - return; - } - /* judge whether the size of child device meets the requirements. - * If the child device size obtained from general definition block - * is different with sizeof(struct child_device_config), skip the - * parsing of sdvo device info - */ - if (p_defs->child_dev_size != sizeof(*p_child)) { - /* different child dev size . Ignore it */ - DRM_DEBUG_KMS("different child size is found. Invalid.\n"); - return; - } - /* get the block size of general definitions */ - block_size = get_blocksize(p_defs); - /* get the number of child device */ - child_device_num = (block_size - sizeof(*p_defs)) / - sizeof(*p_child); - count = 0; - /* get the number of child device that is present */ - for (i = 0; i < child_device_num; i++) { - p_child = &(p_defs->devices[i]); - if (!p_child->device_type) { - /* skip the device block if device type is invalid */ - continue; - } - count++; - } - if (!count) { - DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); - return; - } - dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); - if (!dev_priv->child_dev) { - DRM_DEBUG_KMS("No memory space for child device\n"); - return; - } - - dev_priv->child_dev_num = count; - count = 0; - for (i = 0; i < child_device_num; i++) { - p_child = &(p_defs->devices[i]); - if (!p_child->device_type) { - /* skip the device block if device type is invalid */ - continue; - } - child_dev_ptr = dev_priv->child_dev + count; - count++; - memcpy((void *)child_dev_ptr, (void *)p_child, - sizeof(*p_child)); - } - return; -} - -static void -init_vbt_defaults(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - - dev_priv->crt_ddc_pin = GMBUS_PORT_VGADDC; - - /* LFP panel data */ - dev_priv->lvds_dither = 1; - dev_priv->lvds_vbt = 0; - - /* SDVO panel data */ - dev_priv->sdvo_lvds_vbt_mode = NULL; - - /* general features */ - dev_priv->int_tv_support = 1; - dev_priv->int_crt_support = 1; - - /* Default to using SSC */ - dev_priv->lvds_use_ssc = 1; - dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); - DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); - - /* eDP data */ - dev_priv->edp.bpp = 18; -} - -static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Falling back to manually reading VBT from " - "VBIOS ROM for %s\n", - id->ident); - return 1; -} - -static const struct dmi_system_id intel_no_opregion_vbt[] = { - { - .callback = intel_no_opregion_vbt_callback, - .ident = "ThinkCentre A57", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"), - }, - }, - { } -}; - -/** - * intel_parse_bios - find VBT and initialize settings from the BIOS - * @dev: DRM device - * - * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers - * to appropriate values. - * - * Returns 0 on success, nonzero on failure. - */ -bool -intel_parse_bios(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct pci_dev *pdev = dev->pdev; - struct bdb_header *bdb = NULL; - u8 __iomem *bios = NULL; - - init_vbt_defaults(dev_priv); - - /* XXX Should this validation be moved to intel_opregion.c? */ - if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt) { - struct vbt_header *vbt = dev_priv->opregion.vbt; - if (memcmp(vbt->signature, "$VBT", 4) == 0) { - DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", - vbt->signature); - bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); - } else - dev_priv->opregion.vbt = NULL; - } - - if (bdb == NULL) { - struct vbt_header *vbt = NULL; - size_t size; - int i; - - bios = pci_map_rom(pdev, &size); - if (!bios) - return -1; - - /* Scour memory looking for the VBT signature */ - for (i = 0; i + 4 < size; i++) { - if (!memcmp(bios + i, "$VBT", 4)) { - vbt = (struct vbt_header *)(bios + i); - break; - } - } - - if (!vbt) { - DRM_DEBUG_DRIVER("VBT signature missing\n"); - pci_unmap_rom(pdev, bios); - return -1; - } - - bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); - } - - /* Grab useful general definitions */ - parse_general_features(dev_priv, bdb); - parse_general_definitions(dev_priv, bdb); - parse_lfp_panel_data(dev_priv, bdb); - parse_sdvo_panel_data(dev_priv, bdb); - parse_sdvo_device_mapping(dev_priv, bdb); - parse_device_mapping(dev_priv, bdb); - parse_driver_features(dev_priv, bdb); - parse_edp(dev_priv, bdb); - - if (bios) - pci_unmap_rom(pdev, bios); - - return 0; -} - -/* Ensure that vital registers have been initialised, even if the BIOS - * is absent or just failing to do its job. - */ -void intel_setup_bios(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* Set the Panel Power On/Off timings if uninitialized. */ - if ((I915_READ(PP_ON_DELAYS) == 0) && (I915_READ(PP_OFF_DELAYS) == 0)) { - /* Set T2 to 40ms and T5 to 200ms */ - I915_WRITE(PP_ON_DELAYS, 0x019007d0); - - /* Set T3 to 35ms and Tx to 200ms */ - I915_WRITE(PP_OFF_DELAYS, 0x015e07d0); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.h deleted file mode 100644 index dbda6e3b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_bios.h +++ /dev/null @@ -1,619 +0,0 @@ -/* - * Copyright © 2006 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -#ifndef _I830_BIOS_H_ -#define _I830_BIOS_H_ - -#include "drmP.h" - -struct vbt_header { - u8 signature[20]; /**< Always starts with 'VBT$' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 vbt_size; /**< in bytes */ - u8 vbt_checksum; - u8 reserved0; - u32 bdb_offset; /**< from beginning of VBT */ - u32 aim_offset[4]; /**< from beginning of VBT */ -} __attribute__((packed)); - -struct bdb_header { - u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */ - u16 version; /**< decimal */ - u16 header_size; /**< in bytes */ - u16 bdb_size; /**< in bytes */ -}; - -/* strictly speaking, this is a "skip" block, but it has interesting info */ -struct vbios_data { - u8 type; /* 0 == desktop, 1 == mobile */ - u8 relstage; - u8 chipset; - u8 lvds_present:1; - u8 tv_present:1; - u8 rsvd2:6; /* finish byte */ - u8 rsvd3[4]; - u8 signon[155]; - u8 copyright[61]; - u16 code_segment; - u8 dos_boot_mode; - u8 bandwidth_percent; - u8 rsvd4; /* popup memory size */ - u8 resize_pci_bios; - u8 rsvd5; /* is crt already on ddc2 */ -} __attribute__((packed)); - -/* - * There are several types of BIOS data blocks (BDBs), each block has - * an ID and size in the first 3 bytes (ID in first, size in next 2). - * Known types are listed below. - */ -#define BDB_GENERAL_FEATURES 1 -#define BDB_GENERAL_DEFINITIONS 2 -#define BDB_OLD_TOGGLE_LIST 3 -#define BDB_MODE_SUPPORT_LIST 4 -#define BDB_GENERIC_MODE_TABLE 5 -#define BDB_EXT_MMIO_REGS 6 -#define BDB_SWF_IO 7 -#define BDB_SWF_MMIO 8 -#define BDB_DOT_CLOCK_TABLE 9 -#define BDB_MODE_REMOVAL_TABLE 10 -#define BDB_CHILD_DEVICE_TABLE 11 -#define BDB_DRIVER_FEATURES 12 -#define BDB_DRIVER_PERSISTENCE 13 -#define BDB_EXT_TABLE_PTRS 14 -#define BDB_DOT_CLOCK_OVERRIDE 15 -#define BDB_DISPLAY_SELECT 16 -/* 17 rsvd */ -#define BDB_DRIVER_ROTATION 18 -#define BDB_DISPLAY_REMOVE 19 -#define BDB_OEM_CUSTOM 20 -#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ -#define BDB_SDVO_LVDS_OPTIONS 22 -#define BDB_SDVO_PANEL_DTDS 23 -#define BDB_SDVO_LVDS_PNP_IDS 24 -#define BDB_SDVO_LVDS_POWER_SEQ 25 -#define BDB_TV_OPTIONS 26 -#define BDB_EDP 27 -#define BDB_LVDS_OPTIONS 40 -#define BDB_LVDS_LFP_DATA_PTRS 41 -#define BDB_LVDS_LFP_DATA 42 -#define BDB_LVDS_BACKLIGHT 43 -#define BDB_LVDS_POWER 44 -#define BDB_SKIP 254 /* VBIOS private block, ignore */ - -struct bdb_general_features { - /* bits 1 */ - u8 panel_fitting:2; - u8 flexaim:1; - u8 msg_enable:1; - u8 clear_screen:3; - u8 color_flip:1; - - /* bits 2 */ - u8 download_ext_vbt:1; - u8 enable_ssc:1; - u8 ssc_freq:1; - u8 enable_lfp_on_override:1; - u8 disable_ssc_ddt:1; - u8 rsvd7:1; - u8 display_clock_mode:1; - u8 rsvd8:1; /* finish byte */ - - /* bits 3 */ - u8 disable_smooth_vision:1; - u8 single_dvi:1; - u8 rsvd9:6; /* finish byte */ - - /* bits 4 */ - u8 legacy_monitor_detect; - - /* bits 5 */ - u8 int_crt_support:1; - u8 int_tv_support:1; - u8 int_efp_support:1; - u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ - u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ - u8 rsvd11:3; /* finish byte */ -} __attribute__((packed)); - -/* pre-915 */ -#define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */ -#define GPIO_PIN_ADD_I2C 0x05 /* "ADDCARD I2C GPIO pins" */ -#define GPIO_PIN_ADD_DDC 0x04 /* "ADDCARD DDC GPIO pins" */ -#define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */ - -/* Pre 915 */ -#define DEVICE_TYPE_NONE 0x00 -#define DEVICE_TYPE_CRT 0x01 -#define DEVICE_TYPE_TV 0x09 -#define DEVICE_TYPE_EFP 0x12 -#define DEVICE_TYPE_LFP 0x22 -/* On 915+ */ -#define DEVICE_TYPE_CRT_DPMS 0x6001 -#define DEVICE_TYPE_CRT_DPMS_HOTPLUG 0x4001 -#define DEVICE_TYPE_TV_COMPOSITE 0x0209 -#define DEVICE_TYPE_TV_MACROVISION 0x0289 -#define DEVICE_TYPE_TV_RF_COMPOSITE 0x020c -#define DEVICE_TYPE_TV_SVIDEO_COMPOSITE 0x0609 -#define DEVICE_TYPE_TV_SCART 0x0209 -#define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009 -#define DEVICE_TYPE_EFP_HOTPLUG_PWR 0x6012 -#define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR 0x6052 -#define DEVICE_TYPE_EFP_DVI_I 0x6053 -#define DEVICE_TYPE_EFP_DVI_D_DUAL 0x6152 -#define DEVICE_TYPE_EFP_DVI_D_HDCP 0x60d2 -#define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR 0x6062 -#define DEVICE_TYPE_OPENLDI_DUALPIX 0x6162 -#define DEVICE_TYPE_LFP_PANELLINK 0x5012 -#define DEVICE_TYPE_LFP_CMOS_PWR 0x5042 -#define DEVICE_TYPE_LFP_LVDS_PWR 0x5062 -#define DEVICE_TYPE_LFP_LVDS_DUAL 0x5162 -#define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP 0x51e2 - -#define DEVICE_CFG_NONE 0x00 -#define DEVICE_CFG_12BIT_DVOB 0x01 -#define DEVICE_CFG_12BIT_DVOC 0x02 -#define DEVICE_CFG_24BIT_DVOBC 0x09 -#define DEVICE_CFG_24BIT_DVOCB 0x0a -#define DEVICE_CFG_DUAL_DVOB 0x11 -#define DEVICE_CFG_DUAL_DVOC 0x12 -#define DEVICE_CFG_DUAL_DVOBC 0x13 -#define DEVICE_CFG_DUAL_LINK_DVOBC 0x19 -#define DEVICE_CFG_DUAL_LINK_DVOCB 0x1a - -#define DEVICE_WIRE_NONE 0x00 -#define DEVICE_WIRE_DVOB 0x01 -#define DEVICE_WIRE_DVOC 0x02 -#define DEVICE_WIRE_DVOBC 0x03 -#define DEVICE_WIRE_DVOBB 0x05 -#define DEVICE_WIRE_DVOCC 0x06 -#define DEVICE_WIRE_DVOB_MASTER 0x0d -#define DEVICE_WIRE_DVOC_MASTER 0x0e - -#define DEVICE_PORT_DVOA 0x00 /* none on 845+ */ -#define DEVICE_PORT_DVOB 0x01 -#define DEVICE_PORT_DVOC 0x02 - -struct child_device_config { - u16 handle; - u16 device_type; - u8 device_id[10]; /* ascii string */ - u16 addin_offset; - u8 dvo_port; /* See Device_PORT_* above */ - u8 i2c_pin; - u8 slave_addr; - u8 ddc_pin; - u16 edid_ptr; - u8 dvo_cfg; /* See DEVICE_CFG_* above */ - u8 dvo2_port; - u8 i2c2_pin; - u8 slave2_addr; - u8 ddc2_pin; - u8 capabilities; - u8 dvo_wiring;/* See DEVICE_WIRE_* above */ - u8 dvo2_wiring; - u16 extended_type; - u8 dvo_function; -} __attribute__((packed)); - -struct bdb_general_definitions { - /* DDC GPIO */ - u8 crt_ddc_gmbus_pin; - - /* DPMS bits */ - u8 dpms_acpi:1; - u8 skip_boot_crt_detect:1; - u8 dpms_aim:1; - u8 rsvd1:5; /* finish byte */ - - /* boot device bits */ - u8 boot_display[2]; - u8 child_dev_size; - - /* - * Device info: - * If TV is present, it'll be at devices[0]. - * LVDS will be next, either devices[0] or [1], if present. - * On some platforms the number of device is 6. But could be as few as - * 4 if both TV and LVDS are missing. - * And the device num is related with the size of general definition - * block. It is obtained by using the following formula: - * number = (block_size - sizeof(bdb_general_definitions))/ - * sizeof(child_device_config); - */ - struct child_device_config devices[0]; -} __attribute__((packed)); - -struct bdb_lvds_options { - u8 panel_type; - u8 rsvd1; - /* LVDS capabilities, stored in a dword */ - u8 pfit_mode:2; - u8 pfit_text_mode_enhanced:1; - u8 pfit_gfx_mode_enhanced:1; - u8 pfit_ratio_auto:1; - u8 pixel_dither:1; - u8 lvds_edid:1; - u8 rsvd2:1; - u8 rsvd4; -} __attribute__((packed)); - -/* LFP pointer table contains entries to the struct below */ -struct bdb_lvds_lfp_data_ptr { - u16 fp_timing_offset; /* offsets are from start of bdb */ - u8 fp_table_size; - u16 dvo_timing_offset; - u8 dvo_table_size; - u16 panel_pnp_id_offset; - u8 pnp_table_size; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data_ptrs { - u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ - struct bdb_lvds_lfp_data_ptr ptr[16]; -} __attribute__((packed)); - -/* LFP data has 3 blocks per entry */ -struct lvds_fp_timing { - u16 x_res; - u16 y_res; - u32 lvds_reg; - u32 lvds_reg_val; - u32 pp_on_reg; - u32 pp_on_reg_val; - u32 pp_off_reg; - u32 pp_off_reg_val; - u32 pp_cycle_reg; - u32 pp_cycle_reg_val; - u32 pfit_reg; - u32 pfit_reg_val; - u16 terminator; -} __attribute__((packed)); - -struct lvds_dvo_timing { - u16 clock; /**< In 10khz */ - u8 hactive_lo; - u8 hblank_lo; - u8 hblank_hi:4; - u8 hactive_hi:4; - u8 vactive_lo; - u8 vblank_lo; - u8 vblank_hi:4; - u8 vactive_hi:4; - u8 hsync_off_lo; - u8 hsync_pulse_width; - u8 vsync_pulse_width:4; - u8 vsync_off:4; - u8 rsvd0:6; - u8 hsync_off_hi:2; - u8 h_image; - u8 v_image; - u8 max_hv; - u8 h_border; - u8 v_border; - u8 rsvd1:3; - u8 digital:2; - u8 vsync_positive:1; - u8 hsync_positive:1; - u8 rsvd2:1; -} __attribute__((packed)); - -struct lvds_pnp_id { - u16 mfg_name; - u16 product_code; - u32 serial; - u8 mfg_week; - u8 mfg_year; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data_entry { - struct lvds_fp_timing fp_timing; - struct lvds_dvo_timing dvo_timing; - struct lvds_pnp_id pnp_id; -} __attribute__((packed)); - -struct bdb_lvds_lfp_data { - struct bdb_lvds_lfp_data_entry data[16]; -} __attribute__((packed)); - -struct aimdb_header { - char signature[16]; - char oem_device[20]; - u16 aimdb_version; - u16 aimdb_header_size; - u16 aimdb_size; -} __attribute__((packed)); - -struct aimdb_block { - u8 aimdb_id; - u16 aimdb_size; -} __attribute__((packed)); - -struct vch_panel_data { - u16 fp_timing_offset; - u8 fp_timing_size; - u16 dvo_timing_offset; - u8 dvo_timing_size; - u16 text_fitting_offset; - u8 text_fitting_size; - u16 graphics_fitting_offset; - u8 graphics_fitting_size; -} __attribute__((packed)); - -struct vch_bdb_22 { - struct aimdb_block aimdb_block; - struct vch_panel_data panels[16]; -} __attribute__((packed)); - -struct bdb_sdvo_lvds_options { - u8 panel_backlight; - u8 h40_set_panel_type; - u8 panel_type; - u8 ssc_clk_freq; - u16 als_low_trip; - u16 als_high_trip; - u8 sclalarcoeff_tab_row_num; - u8 sclalarcoeff_tab_row_size; - u8 coefficient[8]; - u8 panel_misc_bits_1; - u8 panel_misc_bits_2; - u8 panel_misc_bits_3; - u8 panel_misc_bits_4; -} __attribute__((packed)); - - -#define BDB_DRIVER_FEATURE_NO_LVDS 0 -#define BDB_DRIVER_FEATURE_INT_LVDS 1 -#define BDB_DRIVER_FEATURE_SDVO_LVDS 2 -#define BDB_DRIVER_FEATURE_EDP 3 - -struct bdb_driver_features { - u8 boot_dev_algorithm:1; - u8 block_display_switch:1; - u8 allow_display_switch:1; - u8 hotplug_dvo:1; - u8 dual_view_zoom:1; - u8 int15h_hook:1; - u8 sprite_in_clone:1; - u8 primary_lfp_id:1; - - u16 boot_mode_x; - u16 boot_mode_y; - u8 boot_mode_bpp; - u8 boot_mode_refresh; - - u16 enable_lfp_primary:1; - u16 selective_mode_pruning:1; - u16 dual_frequency:1; - u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ - u16 nt_clone_support:1; - u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ - u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ - u16 cui_aspect_scaling:1; - u16 preserve_aspect_ratio:1; - u16 sdvo_device_power_down:1; - u16 crt_hotplug:1; - u16 lvds_config:2; - u16 tv_hotplug:1; - u16 hdmi_config:2; - - u8 static_display:1; - u8 reserved2:7; - u16 legacy_crt_max_x; - u16 legacy_crt_max_y; - u8 legacy_crt_max_refresh; - - u8 hdmi_termination; - u8 custom_vbt_version; -} __attribute__((packed)); - -#define EDP_18BPP 0 -#define EDP_24BPP 1 -#define EDP_30BPP 2 -#define EDP_RATE_1_62 0 -#define EDP_RATE_2_7 1 -#define EDP_LANE_1 0 -#define EDP_LANE_2 1 -#define EDP_LANE_4 3 -#define EDP_PREEMPHASIS_NONE 0 -#define EDP_PREEMPHASIS_3_5dB 1 -#define EDP_PREEMPHASIS_6dB 2 -#define EDP_PREEMPHASIS_9_5dB 3 -#define EDP_VSWING_0_4V 0 -#define EDP_VSWING_0_6V 1 -#define EDP_VSWING_0_8V 2 -#define EDP_VSWING_1_2V 3 - -struct edp_power_seq { - u16 t1_t3; - u16 t8; - u16 t9; - u16 t10; - u16 t11_t12; -} __attribute__ ((packed)); - -struct edp_link_params { - u8 rate:4; - u8 lanes:4; - u8 preemphasis:4; - u8 vswing:4; -} __attribute__ ((packed)); - -struct bdb_edp { - struct edp_power_seq power_seqs[16]; - u32 color_depth; - struct edp_link_params link_params[16]; - u32 sdrrs_msa_timing_delay; - - /* ith bit indicates enabled/disabled for (i+1)th panel */ - u16 edp_s3d_feature; - u16 edp_t3_optimization; -} __attribute__ ((packed)); - -void intel_setup_bios(struct drm_device *dev); -bool intel_parse_bios(struct drm_device *dev); - -/* - * Driver<->VBIOS interaction occurs through scratch bits in - * GR18 & SWF*. - */ - -/* GR18 bits are set on display switch and hotkey events */ -#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */ -#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */ -#define GR18_HK_NONE (0x0<<3) -#define GR18_HK_LFP_STRETCH (0x1<<3) -#define GR18_HK_TOGGLE_DISP (0x2<<3) -#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */ -#define GR18_HK_POPUP_DISABLED (0x6<<3) -#define GR18_HK_POPUP_ENABLED (0x7<<3) -#define GR18_HK_PFIT (0x8<<3) -#define GR18_HK_APM_CHANGE (0xa<<3) -#define GR18_HK_MULTIPLE (0xc<<3) -#define GR18_USER_INT_EN (1<<2) -#define GR18_A0000_FLUSH_EN (1<<1) -#define GR18_SMM_EN (1<<0) - -/* Set by driver, cleared by VBIOS */ -#define SWF00_YRES_SHIFT 16 -#define SWF00_XRES_SHIFT 0 -#define SWF00_RES_MASK 0xffff - -/* Set by VBIOS at boot time and driver at runtime */ -#define SWF01_TV2_FORMAT_SHIFT 8 -#define SWF01_TV1_FORMAT_SHIFT 0 -#define SWF01_TV_FORMAT_MASK 0xffff - -#define SWF10_VBIOS_BLC_I2C_EN (1<<29) -#define SWF10_GTT_OVERRIDE_EN (1<<28) -#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */ -#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24) -#define SWF10_OLD_TOGGLE 0x0 -#define SWF10_TOGGLE_LIST_1 0x1 -#define SWF10_TOGGLE_LIST_2 0x2 -#define SWF10_TOGGLE_LIST_3 0x3 -#define SWF10_TOGGLE_LIST_4 0x4 -#define SWF10_PANNING_EN (1<<23) -#define SWF10_DRIVER_LOADED (1<<22) -#define SWF10_EXTENDED_DESKTOP (1<<21) -#define SWF10_EXCLUSIVE_MODE (1<<20) -#define SWF10_OVERLAY_EN (1<<19) -#define SWF10_PLANEB_HOLDOFF (1<<18) -#define SWF10_PLANEA_HOLDOFF (1<<17) -#define SWF10_VGA_HOLDOFF (1<<16) -#define SWF10_ACTIVE_DISP_MASK 0xffff -#define SWF10_PIPEB_LFP2 (1<<15) -#define SWF10_PIPEB_EFP2 (1<<14) -#define SWF10_PIPEB_TV2 (1<<13) -#define SWF10_PIPEB_CRT2 (1<<12) -#define SWF10_PIPEB_LFP (1<<11) -#define SWF10_PIPEB_EFP (1<<10) -#define SWF10_PIPEB_TV (1<<9) -#define SWF10_PIPEB_CRT (1<<8) -#define SWF10_PIPEA_LFP2 (1<<7) -#define SWF10_PIPEA_EFP2 (1<<6) -#define SWF10_PIPEA_TV2 (1<<5) -#define SWF10_PIPEA_CRT2 (1<<4) -#define SWF10_PIPEA_LFP (1<<3) -#define SWF10_PIPEA_EFP (1<<2) -#define SWF10_PIPEA_TV (1<<1) -#define SWF10_PIPEA_CRT (1<<0) - -#define SWF11_MEMORY_SIZE_SHIFT 16 -#define SWF11_SV_TEST_EN (1<<15) -#define SWF11_IS_AGP (1<<14) -#define SWF11_DISPLAY_HOLDOFF (1<<13) -#define SWF11_DPMS_REDUCED (1<<12) -#define SWF11_IS_VBE_MODE (1<<11) -#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */ -#define SWF11_DPMS_MASK 0x07 -#define SWF11_DPMS_OFF (1<<2) -#define SWF11_DPMS_SUSPEND (1<<1) -#define SWF11_DPMS_STANDBY (1<<0) -#define SWF11_DPMS_ON 0 - -#define SWF14_GFX_PFIT_EN (1<<31) -#define SWF14_TEXT_PFIT_EN (1<<30) -#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ -#define SWF14_POPUP_EN (1<<28) -#define SWF14_DISPLAY_HOLDOFF (1<<27) -#define SWF14_DISP_DETECT_EN (1<<26) -#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */ -#define SWF14_DRIVER_STATUS (1<<24) -#define SWF14_OS_TYPE_WIN9X (1<<23) -#define SWF14_OS_TYPE_WINNT (1<<22) -/* 21:19 rsvd */ -#define SWF14_PM_TYPE_MASK 0x00070000 -#define SWF14_PM_ACPI_VIDEO (0x4 << 16) -#define SWF14_PM_ACPI (0x3 << 16) -#define SWF14_PM_APM_12 (0x2 << 16) -#define SWF14_PM_APM_11 (0x1 << 16) -#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */ - /* if GR18 indicates a display switch */ -#define SWF14_DS_PIPEB_LFP2_EN (1<<15) -#define SWF14_DS_PIPEB_EFP2_EN (1<<14) -#define SWF14_DS_PIPEB_TV2_EN (1<<13) -#define SWF14_DS_PIPEB_CRT2_EN (1<<12) -#define SWF14_DS_PIPEB_LFP_EN (1<<11) -#define SWF14_DS_PIPEB_EFP_EN (1<<10) -#define SWF14_DS_PIPEB_TV_EN (1<<9) -#define SWF14_DS_PIPEB_CRT_EN (1<<8) -#define SWF14_DS_PIPEA_LFP2_EN (1<<7) -#define SWF14_DS_PIPEA_EFP2_EN (1<<6) -#define SWF14_DS_PIPEA_TV2_EN (1<<5) -#define SWF14_DS_PIPEA_CRT2_EN (1<<4) -#define SWF14_DS_PIPEA_LFP_EN (1<<3) -#define SWF14_DS_PIPEA_EFP_EN (1<<2) -#define SWF14_DS_PIPEA_TV_EN (1<<1) -#define SWF14_DS_PIPEA_CRT_EN (1<<0) - /* if GR18 indicates a panel fitting request */ -#define SWF14_PFIT_EN (1<<0) /* 0 means disable */ - /* if GR18 indicates an APM change request */ -#define SWF14_APM_HIBERNATE 0x4 -#define SWF14_APM_SUSPEND 0x3 -#define SWF14_APM_STANDBY 0x1 -#define SWF14_APM_RESTORE 0x0 - -/* Add the device class for LFP, TV, HDMI */ -#define DEVICE_TYPE_INT_LFP 0x1022 -#define DEVICE_TYPE_INT_TV 0x1009 -#define DEVICE_TYPE_HDMI 0x60D2 -#define DEVICE_TYPE_DP 0x68C6 -#define DEVICE_TYPE_eDP 0x78C6 - -/* define the DVO port for HDMI output type */ -#define DVO_B 1 -#define DVO_C 2 -#define DVO_D 3 - -/* define the PORT for DP output type */ -#define PORT_IDPB 7 -#define PORT_IDPC 8 -#define PORT_IDPD 9 - -#endif /* _I830_BIOS_H_ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_crt.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_crt.c deleted file mode 100644 index 90b9793f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_crt.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ - -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "drm_edid.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/* Here's the desired hotplug mode */ -#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ - ADPA_CRT_HOTPLUG_WARMUP_10MS | \ - ADPA_CRT_HOTPLUG_SAMPLE_4S | \ - ADPA_CRT_HOTPLUG_VOLTAGE_50 | \ - ADPA_CRT_HOTPLUG_VOLREF_325MV | \ - ADPA_CRT_HOTPLUG_ENABLE) - -struct intel_crt { - struct intel_encoder base; - bool force_hotplug_required; -}; - -static struct intel_crt *intel_attached_crt(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_crt, base); -} - -static void intel_crt_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 temp, reg; - - if (HAS_PCH_SPLIT(dev)) - reg = PCH_ADPA; - else - reg = ADPA; - - temp = I915_READ(reg); - temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); - temp &= ~ADPA_DAC_ENABLE; - - switch (mode) { - case DRM_MODE_DPMS_ON: - temp |= ADPA_DAC_ENABLE; - break; - case DRM_MODE_DPMS_STANDBY: - temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE; - break; - case DRM_MODE_DPMS_SUSPEND: - temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE; - break; - case DRM_MODE_DPMS_OFF: - temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; - break; - } - - I915_WRITE(reg, temp); -} - -static int intel_crt_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_device *dev = connector->dev; - - int max_clock = 0; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (mode->clock < 25000) - return MODE_CLOCK_LOW; - - if (IS_GEN2(dev)) - max_clock = 350000; - else - max_clock = 400000; - if (mode->clock > max_clock) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static bool intel_crt_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void intel_crt_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_i915_private *dev_priv = dev->dev_private; - int dpll_md_reg; - u32 adpa, dpll_md; - u32 adpa_reg; - - dpll_md_reg = DPLL_MD(intel_crtc->pipe); - - if (HAS_PCH_SPLIT(dev)) - adpa_reg = PCH_ADPA; - else - adpa_reg = ADPA; - - /* - * Disable separate mode multiplier used when cloning SDVO to CRT - * XXX this needs to be adjusted when we really are cloning - */ - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { - dpll_md = I915_READ(dpll_md_reg); - I915_WRITE(dpll_md_reg, - dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); - } - - adpa = ADPA_HOTPLUG_BITS; - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - adpa |= ADPA_HSYNC_ACTIVE_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - adpa |= ADPA_VSYNC_ACTIVE_HIGH; - - /* For CPT allow 3 pipe config, for others just use A or B */ - if (HAS_PCH_CPT(dev)) - adpa |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); - else if (intel_crtc->pipe == 0) - adpa |= ADPA_PIPE_A_SELECT; - else - adpa |= ADPA_PIPE_B_SELECT; - - if (!HAS_PCH_SPLIT(dev)) - I915_WRITE(BCLRPAT(intel_crtc->pipe), 0); - - I915_WRITE(adpa_reg, adpa); -} - -static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct intel_crt *crt = intel_attached_crt(connector); - struct drm_i915_private *dev_priv = dev->dev_private; - u32 adpa; - bool ret; - - /* The first time through, trigger an explicit detection cycle */ - if (crt->force_hotplug_required) { - bool turn_off_dac = HAS_PCH_SPLIT(dev); - u32 save_adpa; - - crt->force_hotplug_required = 0; - - save_adpa = adpa = I915_READ(PCH_ADPA); - DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); - - adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; - if (turn_off_dac) - adpa &= ~ADPA_DAC_ENABLE; - - I915_WRITE(PCH_ADPA, adpa); - - if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, - 1000)) - DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); - - if (turn_off_dac) { - I915_WRITE(PCH_ADPA, save_adpa); - POSTING_READ(PCH_ADPA); - } - } - - /* Check the status to see if both blue and green are on now */ - adpa = I915_READ(PCH_ADPA); - if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) - ret = true; - else - ret = false; - DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); - - return ret; -} - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. - * - * Not for i915G/i915GM - * - * \return true if CRT is connected. - * \return false if CRT is disconnected. - */ -static bool intel_crt_detect_hotplug(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 hotplug_en, orig, stat; - bool ret = false; - int i, tries = 0; - - if (HAS_PCH_SPLIT(dev)) - return intel_ironlake_crt_detect_hotplug(connector); - - /* - * On 4 series desktop, CRT detect sequence need to be done twice - * to get a reliable result. - */ - - if (IS_G4X(dev) && !IS_GM45(dev)) - tries = 2; - else - tries = 1; - hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); - hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; - - for (i = 0; i < tries ; i++) { - /* turn on the FORCE_DETECT */ - I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); - /* wait for FORCE_DETECT to go off */ - if (wait_for((I915_READ(PORT_HOTPLUG_EN) & - CRT_HOTPLUG_FORCE_DETECT) == 0, - 1000)) - DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); - } - - stat = I915_READ(PORT_HOTPLUG_STAT); - if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE) - ret = true; - - /* clear the interrupt we just generated, if any */ - I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS); - - /* and put the bits back */ - I915_WRITE(PORT_HOTPLUG_EN, orig); - - return ret; -} - -static bool intel_crt_detect_ddc(struct drm_connector *connector) -{ - struct intel_crt *crt = intel_attached_crt(connector); - struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; - - /* CRT should always be at 0, but check anyway */ - if (crt->base.type != INTEL_OUTPUT_ANALOG) - return false; - - if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { - struct edid *edid; - bool is_digital = false; - - edid = drm_get_edid(connector, - &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); - /* - * This may be a DVI-I connector with a shared DDC - * link between analog and digital outputs, so we - * have to check the EDID input spec of the attached device. - * - * On the other hand, what should we do if it is a broken EDID? - */ - if (edid != NULL) { - is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - if (!is_digital) { - DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); - return true; - } else { - DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n"); - } - } - - return false; -} - -static enum drm_connector_status -intel_crt_load_detect(struct intel_crt *crt) -{ - struct drm_device *dev = crt->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t pipe = to_intel_crtc(crt->base.base.crtc)->pipe; - uint32_t save_bclrpat; - uint32_t save_vtotal; - uint32_t vtotal, vactive; - uint32_t vsample; - uint32_t vblank, vblank_start, vblank_end; - uint32_t dsl; - uint32_t bclrpat_reg; - uint32_t vtotal_reg; - uint32_t vblank_reg; - uint32_t vsync_reg; - uint32_t pipeconf_reg; - uint32_t pipe_dsl_reg; - uint8_t st00; - enum drm_connector_status status; - - DRM_DEBUG_KMS("starting load-detect on CRT\n"); - - bclrpat_reg = BCLRPAT(pipe); - vtotal_reg = VTOTAL(pipe); - vblank_reg = VBLANK(pipe); - vsync_reg = VSYNC(pipe); - pipeconf_reg = PIPECONF(pipe); - pipe_dsl_reg = PIPEDSL(pipe); - - save_bclrpat = I915_READ(bclrpat_reg); - save_vtotal = I915_READ(vtotal_reg); - vblank = I915_READ(vblank_reg); - - vtotal = ((save_vtotal >> 16) & 0xfff) + 1; - vactive = (save_vtotal & 0x7ff) + 1; - - vblank_start = (vblank & 0xfff) + 1; - vblank_end = ((vblank >> 16) & 0xfff) + 1; - - /* Set the border color to purple. */ - I915_WRITE(bclrpat_reg, 0x500050); - - if (!IS_GEN2(dev)) { - uint32_t pipeconf = I915_READ(pipeconf_reg); - I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); - POSTING_READ(pipeconf_reg); - /* Wait for next Vblank to substitue - * border color for Color info */ - intel_wait_for_vblank(dev, pipe); - st00 = I915_READ8(VGA_MSR_WRITE); - status = ((st00 & (1 << 4)) != 0) ? - connector_status_connected : - connector_status_disconnected; - - I915_WRITE(pipeconf_reg, pipeconf); - } else { - bool restore_vblank = false; - int count, detect; - - /* - * If there isn't any border, add some. - * Yes, this will flicker - */ - if (vblank_start <= vactive && vblank_end >= vtotal) { - uint32_t vsync = I915_READ(vsync_reg); - uint32_t vsync_start = (vsync & 0xffff) + 1; - - vblank_start = vsync_start; - I915_WRITE(vblank_reg, - (vblank_start - 1) | - ((vblank_end - 1) << 16)); - restore_vblank = true; - } - /* sample in the vertical border, selecting the larger one */ - if (vblank_start - vactive >= vtotal - vblank_end) - vsample = (vblank_start + vactive) >> 1; - else - vsample = (vtotal + vblank_end) >> 1; - - /* - * Wait for the border to be displayed - */ - while (I915_READ(pipe_dsl_reg) >= vactive) - ; - while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample) - ; - /* - * Watch ST00 for an entire scanline - */ - detect = 0; - count = 0; - do { - count++; - /* Read the ST00 VGA status register */ - st00 = I915_READ8(VGA_MSR_WRITE); - if (st00 & (1 << 4)) - detect++; - } while ((I915_READ(pipe_dsl_reg) == dsl)); - - /* restore vblank if necessary */ - if (restore_vblank) - I915_WRITE(vblank_reg, vblank); - /* - * If more than 3/4 of the scanline detected a monitor, - * then it is assumed to be present. This works even on i830, - * where there isn't any way to force the border color across - * the screen - */ - status = detect * 4 > count * 3 ? - connector_status_connected : - connector_status_disconnected; - } - - /* Restore previous settings */ - I915_WRITE(bclrpat_reg, save_bclrpat); - - return status; -} - -static enum drm_connector_status -intel_crt_detect(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - struct intel_crt *crt = intel_attached_crt(connector); - enum drm_connector_status status; - struct intel_load_detect_pipe tmp; - - if (I915_HAS_HOTPLUG(dev)) { - if (intel_crt_detect_hotplug(connector)) { - DRM_DEBUG_KMS("CRT detected via hotplug\n"); - return connector_status_connected; - } else { - DRM_DEBUG_KMS("CRT not detected via hotplug\n"); - return connector_status_disconnected; - } - } - - if (intel_crt_detect_ddc(connector)) - return connector_status_connected; - - if (!force) - return connector->status; - - /* for pre-945g platforms use load detect */ - if (intel_get_load_detect_pipe(&crt->base, connector, NULL, - &tmp)) { - if (intel_crt_detect_ddc(connector)) - status = connector_status_connected; - else - status = intel_crt_load_detect(crt); - intel_release_load_detect_pipe(&crt->base, connector, - &tmp); - } else - status = connector_status_unknown; - - return status; -} - -static void intel_crt_destroy(struct drm_connector *connector) -{ - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static int intel_crt_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - ret = intel_ddc_get_modes(connector, - &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); - if (ret || !IS_G4X(dev)) - return ret; - - /* Try to probe digital port for output in DVI-I -> VGA mode. */ - return intel_ddc_get_modes(connector, - &dev_priv->gmbus[GMBUS_PORT_DPB].adapter); -} - -static int intel_crt_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - return 0; -} - -static void intel_crt_reset(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct intel_crt *crt = intel_attached_crt(connector); - - if (HAS_PCH_SPLIT(dev)) - crt->force_hotplug_required = 1; -} - -/* - * Routines for controlling stuff on the analog port - */ - -static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { - .dpms = intel_crt_dpms, - .mode_fixup = intel_crt_mode_fixup, - .prepare = intel_encoder_prepare, - .commit = intel_encoder_commit, - .mode_set = intel_crt_mode_set, -}; - -static const struct drm_connector_funcs intel_crt_connector_funcs = { - .reset = intel_crt_reset, - .dpms = drm_helper_connector_dpms, - .detect = intel_crt_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = intel_crt_destroy, - .set_property = intel_crt_set_property, -}; - -static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = { - .mode_valid = intel_crt_mode_valid, - .get_modes = intel_crt_get_modes, - .best_encoder = intel_best_encoder, -}; - -static const struct drm_encoder_funcs intel_crt_enc_funcs = { - .destroy = intel_encoder_destroy, -}; - -static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident); - return 1; -} - -static const struct dmi_system_id intel_no_crt[] = { - { - .callback = intel_no_crt_dmi_callback, - .ident = "ACER ZGB", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ACER"), - DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), - }, - }, - { } -}; - -void intel_crt_init(struct drm_device *dev) -{ - struct drm_connector *connector; - struct intel_crt *crt; - struct intel_connector *intel_connector; - struct drm_i915_private *dev_priv = dev->dev_private; - - /* Skip machines without VGA that falsely report hotplug events */ - if (dmi_check_system(intel_no_crt)) - return; - - crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); - if (!crt) - return; - - intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); - if (!intel_connector) { - kfree(crt); - return; - } - - connector = &intel_connector->base; - drm_connector_init(dev, &intel_connector->base, - &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - - drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, - DRM_MODE_ENCODER_DAC); - - intel_connector_attach_encoder(intel_connector, &crt->base); - - crt->base.type = INTEL_OUTPUT_ANALOG; - crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | - 1 << INTEL_ANALOG_CLONE_BIT | - 1 << INTEL_SDVO_LVDS_CLONE_BIT); - crt->base.crtc_mask = (1 << 0) | (1 << 1); - if (IS_GEN2(dev)) - connector->interlace_allowed = 0; - else - connector->interlace_allowed = 1; - connector->doublescan_allowed = 0; - - drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); - drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); - - drm_sysfs_connector_add(connector); - - if (I915_HAS_HOTPLUG(dev)) - connector->polled = DRM_CONNECTOR_POLL_HPD; - else - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - - /* - * Configure the automatic hotplug detection stuff - */ - crt->force_hotplug_required = 0; - if (HAS_PCH_SPLIT(dev)) { - u32 adpa; - - adpa = I915_READ(PCH_ADPA); - adpa &= ~ADPA_CRT_HOTPLUG_MASK; - adpa |= ADPA_HOTPLUG_BITS; - I915_WRITE(PCH_ADPA, adpa); - POSTING_READ(PCH_ADPA); - - DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); - crt->force_hotplug_required = 1; - } - - dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_display.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_display.c deleted file mode 100644 index d4d162f6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_display.c +++ /dev/null @@ -1,9458 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "drmP.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_trace.h" -#include "drm_dp_helper.h" -#include "drm_crtc_helper.h" -#include - -#define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) - -bool intel_pipe_has_type(struct drm_crtc *crtc, int type); -static void intel_update_watermarks(struct drm_device *dev); -static void intel_increase_pllclock(struct drm_crtc *crtc); -static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); - -typedef struct { - /* given values */ - int n; - int m1, m2; - int p1, p2; - /* derived values */ - int dot; - int vco; - int m; - int p; -} intel_clock_t; - -typedef struct { - int min, max; -} intel_range_t; - -typedef struct { - int dot_limit; - int p2_slow, p2_fast; -} intel_p2_t; - -#define INTEL_P2_NUM 2 -typedef struct intel_limit intel_limit_t; -struct intel_limit { - intel_range_t dot, vco, n, m, m1, m2, p, p1; - intel_p2_t p2; - bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, - int, int, intel_clock_t *, intel_clock_t *); -}; - -/* FDI */ -#define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ - -static bool -intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock); -static bool -intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock); - -static bool -intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock); -static bool -intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock); - -static inline u32 /* units of 100MHz */ -intel_fdi_link_freq(struct drm_device *dev) -{ - if (IS_GEN5(dev)) { - struct drm_i915_private *dev_priv = dev->dev_private; - return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2; - } else - return 27; -} - -static const intel_limit_t intel_limits_i8xx_dvo = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 930000, .max = 1400000 }, - .n = { .min = 3, .max = 16 }, - .m = { .min = 96, .max = 140 }, - .m1 = { .min = 18, .max = 26 }, - .m2 = { .min = 6, .max = 16 }, - .p = { .min = 4, .max = 128 }, - .p1 = { .min = 2, .max = 33 }, - .p2 = { .dot_limit = 165000, - .p2_slow = 4, .p2_fast = 2 }, - .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i8xx_lvds = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 930000, .max = 1400000 }, - .n = { .min = 3, .max = 16 }, - .m = { .min = 96, .max = 140 }, - .m1 = { .min = 18, .max = 26 }, - .m2 = { .min = 6, .max = 16 }, - .p = { .min = 4, .max = 128 }, - .p1 = { .min = 1, .max = 6 }, - .p2 = { .dot_limit = 165000, - .p2_slow = 14, .p2_fast = 7 }, - .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i9xx_sdvo = { - .dot = { .min = 20000, .max = 400000 }, - .vco = { .min = 1400000, .max = 2800000 }, - .n = { .min = 1, .max = 6 }, - .m = { .min = 70, .max = 120 }, - .m1 = { .min = 10, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 200000, - .p2_slow = 10, .p2_fast = 5 }, - .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_i9xx_lvds = { - .dot = { .min = 20000, .max = 400000 }, - .vco = { .min = 1400000, .max = 2800000 }, - .n = { .min = 1, .max = 6 }, - .m = { .min = 70, .max = 120 }, - .m1 = { .min = 10, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 7, .max = 98 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 112000, - .p2_slow = 14, .p2_fast = 7 }, - .find_pll = intel_find_best_PLL, -}; - - -static const intel_limit_t intel_limits_g4x_sdvo = { - .dot = { .min = 25000, .max = 270000 }, - .vco = { .min = 1750000, .max = 3500000}, - .n = { .min = 1, .max = 4 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 17, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 10, .max = 30 }, - .p1 = { .min = 1, .max = 3}, - .p2 = { .dot_limit = 270000, - .p2_slow = 10, - .p2_fast = 10 - }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_hdmi = { - .dot = { .min = 22000, .max = 400000 }, - .vco = { .min = 1750000, .max = 3500000}, - .n = { .min = 1, .max = 4 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 16, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8}, - .p2 = { .dot_limit = 165000, - .p2_slow = 10, .p2_fast = 5 }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_single_channel_lvds = { - .dot = { .min = 20000, .max = 115000 }, - .vco = { .min = 1750000, .max = 3500000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 17, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 28, .max = 112 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 0, - .p2_slow = 14, .p2_fast = 14 - }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { - .dot = { .min = 80000, .max = 224000 }, - .vco = { .min = 1750000, .max = 3500000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 104, .max = 138 }, - .m1 = { .min = 17, .max = 23 }, - .m2 = { .min = 5, .max = 11 }, - .p = { .min = 14, .max = 42 }, - .p1 = { .min = 2, .max = 6 }, - .p2 = { .dot_limit = 0, - .p2_slow = 7, .p2_fast = 7 - }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_g4x_display_port = { - .dot = { .min = 161670, .max = 227000 }, - .vco = { .min = 1750000, .max = 3500000}, - .n = { .min = 1, .max = 2 }, - .m = { .min = 97, .max = 108 }, - .m1 = { .min = 0x10, .max = 0x12 }, - .m2 = { .min = 0x05, .max = 0x06 }, - .p = { .min = 10, .max = 20 }, - .p1 = { .min = 1, .max = 2}, - .p2 = { .dot_limit = 0, - .p2_slow = 10, .p2_fast = 10 }, - .find_pll = intel_find_pll_g4x_dp, -}; - -static const intel_limit_t intel_limits_pineview_sdvo = { - .dot = { .min = 20000, .max = 400000}, - .vco = { .min = 1700000, .max = 3500000 }, - /* Pineview's Ncounter is a ring counter */ - .n = { .min = 3, .max = 6 }, - .m = { .min = 2, .max = 256 }, - /* Pineview only has one combined m divider, which we treat as m2. */ - .m1 = { .min = 0, .max = 0 }, - .m2 = { .min = 0, .max = 254 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 200000, - .p2_slow = 10, .p2_fast = 5 }, - .find_pll = intel_find_best_PLL, -}; - -static const intel_limit_t intel_limits_pineview_lvds = { - .dot = { .min = 20000, .max = 400000 }, - .vco = { .min = 1700000, .max = 3500000 }, - .n = { .min = 3, .max = 6 }, - .m = { .min = 2, .max = 256 }, - .m1 = { .min = 0, .max = 0 }, - .m2 = { .min = 0, .max = 254 }, - .p = { .min = 7, .max = 112 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 112000, - .p2_slow = 14, .p2_fast = 14 }, - .find_pll = intel_find_best_PLL, -}; - -/* Ironlake / Sandybridge - * - * We calculate clock using (register_value + 2) for N/M1/M2, so here - * the range value for them is (actual_value - 2). - */ -static const intel_limit_t intel_limits_ironlake_dac = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 5 }, - .m = { .min = 79, .max = 127 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 5, .max = 80 }, - .p1 = { .min = 1, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 10, .p2_fast = 5 }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_ironlake_single_lvds = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 79, .max = 118 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 28, .max = 112 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 14, .p2_fast = 14 }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_ironlake_dual_lvds = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 79, .max = 127 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 14, .max = 56 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 7, .p2_fast = 7 }, - .find_pll = intel_g4x_find_best_PLL, -}; - -/* LVDS 100mhz refclk limits. */ -static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 2 }, - .m = { .min = 79, .max = 126 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 28, .max = 112 }, - .p1 = { .min = 2, .max = 8 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 14, .p2_fast = 14 }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000 }, - .n = { .min = 1, .max = 3 }, - .m = { .min = 79, .max = 126 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 14, .max = 42 }, - .p1 = { .min = 2, .max = 6 }, - .p2 = { .dot_limit = 225000, - .p2_slow = 7, .p2_fast = 7 }, - .find_pll = intel_g4x_find_best_PLL, -}; - -static const intel_limit_t intel_limits_ironlake_display_port = { - .dot = { .min = 25000, .max = 350000 }, - .vco = { .min = 1760000, .max = 3510000}, - .n = { .min = 1, .max = 2 }, - .m = { .min = 81, .max = 90 }, - .m1 = { .min = 12, .max = 22 }, - .m2 = { .min = 5, .max = 9 }, - .p = { .min = 10, .max = 20 }, - .p1 = { .min = 1, .max = 2}, - .p2 = { .dot_limit = 0, - .p2_slow = 10, .p2_fast = 10 }, - .find_pll = intel_find_pll_ironlake_dp, -}; - -static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, - int refclk) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - const intel_limit_t *limit; - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) { - /* LVDS dual channel */ - if (refclk == 100000) - limit = &intel_limits_ironlake_dual_lvds_100m; - else - limit = &intel_limits_ironlake_dual_lvds; - } else { - if (refclk == 100000) - limit = &intel_limits_ironlake_single_lvds_100m; - else - limit = &intel_limits_ironlake_single_lvds; - } - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || - HAS_eDP) - limit = &intel_limits_ironlake_display_port; - else - limit = &intel_limits_ironlake_dac; - - return limit; -} - -static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - const intel_limit_t *limit; - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - /* LVDS with dual channel */ - limit = &intel_limits_g4x_dual_channel_lvds; - else - /* LVDS with dual channel */ - limit = &intel_limits_g4x_single_channel_lvds; - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { - limit = &intel_limits_g4x_hdmi; - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { - limit = &intel_limits_g4x_sdvo; - } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { - limit = &intel_limits_g4x_display_port; - } else /* The option is for other outputs */ - limit = &intel_limits_i9xx_sdvo; - - return limit; -} - -static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) -{ - struct drm_device *dev = crtc->dev; - const intel_limit_t *limit; - - if (HAS_PCH_SPLIT(dev)) - limit = intel_ironlake_limit(crtc, refclk); - else if (IS_G4X(dev)) { - limit = intel_g4x_limit(crtc); - } else if (IS_PINEVIEW(dev)) { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_pineview_lvds; - else - limit = &intel_limits_pineview_sdvo; - } else if (!IS_GEN2(dev)) { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i9xx_lvds; - else - limit = &intel_limits_i9xx_sdvo; - } else { - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) - limit = &intel_limits_i8xx_lvds; - else - limit = &intel_limits_i8xx_dvo; - } - return limit; -} - -/* m1 is reserved as 0 in Pineview, n is a ring counter */ -static void pineview_clock(int refclk, intel_clock_t *clock) -{ - clock->m = clock->m2 + 2; - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / clock->n; - clock->dot = clock->vco / clock->p; -} - -static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) -{ - if (IS_PINEVIEW(dev)) { - pineview_clock(refclk, clock); - return; - } - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/** - * Returns whether any output on the specified pipe is of the specified type - */ -bool intel_pipe_has_type(struct drm_crtc *crtc, int type) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) - if (encoder->base.crtc == crtc && encoder->type == type) - return true; - - return false; -} - -#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) -/** - * Returns whether the given set of divisors are valid for a given refclk with - * the given connectors. - */ - -static bool intel_PLL_is_valid(struct drm_device *dev, - const intel_limit_t *limit, - const intel_clock_t *clock) -{ - if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) - INTELPllInvalid("p1 out of range\n"); - if (clock->p < limit->p.min || limit->p.max < clock->p) - INTELPllInvalid("p out of range\n"); - if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) - INTELPllInvalid("m2 out of range\n"); - if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) - INTELPllInvalid("m1 out of range\n"); - if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev)) - INTELPllInvalid("m1 <= m2\n"); - if (clock->m < limit->m.min || limit->m.max < clock->m) - INTELPllInvalid("m out of range\n"); - if (clock->n < limit->n.min || limit->n.max < clock->n) - INTELPllInvalid("n out of range\n"); - if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) - INTELPllInvalid("vco out of range\n"); - /* XXX: We may need to be checking "Dot clock" depending on the multiplier, - * connector, etc., rather than just a single range. - */ - if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) - INTELPllInvalid("dot out of range\n"); - - return true; -} - -static bool -intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock) - -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - intel_clock_t clock; - int err = target; - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - (I915_READ(LVDS)) != 0) { - /* - * For LVDS, if the panel is on, just rely on its current - * settings for dual-channel. We haven't figured out how to - * reliably set up different single/dual channel state, if we - * even can. - */ - if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset(best_clock, 0, sizeof(*best_clock)); - - for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; - clock.m1++) { - for (clock.m2 = limit->m2.min; - clock.m2 <= limit->m2.max; clock.m2++) { - /* m1 is always 0 in Pineview */ - if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) - break; - for (clock.n = limit->n.min; - clock.n <= limit->n.max; clock.n++) { - for (clock.p1 = limit->p1.min; - clock.p1 <= limit->p1.max; clock.p1++) { - int this_err; - - intel_clock(dev, refclk, &clock); - if (!intel_PLL_is_valid(dev, limit, - &clock)) - continue; - if (match_clock && - clock.p != match_clock->p) - continue; - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - } - } - - return (err != target); -} - -static bool -intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - intel_clock_t clock; - int max_n; - bool found; - /* approximately equals target * 0.00585 */ - int err_most = (target >> 8) + (target >> 9); - found = false; - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - int lvds_reg; - - if (HAS_PCH_SPLIT(dev)) - lvds_reg = PCH_LVDS; - else - lvds_reg = LVDS; - if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset(best_clock, 0, sizeof(*best_clock)); - max_n = limit->n.max; - /* based on hardware requirement, prefer smaller n to precision */ - for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { - /* based on hardware requirement, prefere larger m1,m2 */ - for (clock.m1 = limit->m1.max; - clock.m1 >= limit->m1.min; clock.m1--) { - for (clock.m2 = limit->m2.max; - clock.m2 >= limit->m2.min; clock.m2--) { - for (clock.p1 = limit->p1.max; - clock.p1 >= limit->p1.min; clock.p1--) { - int this_err; - - intel_clock(dev, refclk, &clock); - if (!intel_PLL_is_valid(dev, limit, - &clock)) - continue; - if (match_clock && - clock.p != match_clock->p) - continue; - - this_err = abs(clock.dot - target); - if (this_err < err_most) { - *best_clock = clock; - err_most = this_err; - max_n = clock.n; - found = true; - } - } - } - } - } - return found; -} - -static bool -intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock) -{ - struct drm_device *dev = crtc->dev; - intel_clock_t clock; - - if (target < 200000) { - clock.n = 1; - clock.p1 = 2; - clock.p2 = 10; - clock.m1 = 12; - clock.m2 = 9; - } else { - clock.n = 2; - clock.p1 = 1; - clock.p2 = 10; - clock.m1 = 14; - clock.m2 = 8; - } - intel_clock(dev, refclk, &clock); - memcpy(best_clock, &clock, sizeof(intel_clock_t)); - return true; -} - -/* DisplayPort has only two frequencies, 162MHz and 270MHz */ -static bool -intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *match_clock, - intel_clock_t *best_clock) -{ - intel_clock_t clock; - if (target < 200000) { - clock.p1 = 2; - clock.p2 = 10; - clock.n = 2; - clock.m1 = 23; - clock.m2 = 8; - } else { - clock.p1 = 1; - clock.p2 = 10; - clock.n = 1; - clock.m1 = 14; - clock.m2 = 2; - } - clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); - clock.p = (clock.p1 * clock.p2); - clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; - clock.vco = 0; - memcpy(best_clock, &clock, sizeof(intel_clock_t)); - return true; -} - -/** - * intel_wait_for_vblank - wait for vblank on a given pipe - * @dev: drm device - * @pipe: pipe to wait for - * - * Wait for vblank to occur on a given pipe. Needed for various bits of - * mode setting code. - */ -void intel_wait_for_vblank(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int pipestat_reg = PIPESTAT(pipe); - - /* Clear existing vblank status. Note this will clear any other - * sticky status fields as well. - * - * This races with i915_driver_irq_handler() with the result - * that either function could miss a vblank event. Here it is not - * fatal, as we will either wait upon the next vblank interrupt or - * timeout. Generally speaking intel_wait_for_vblank() is only - * called during modeset at which time the GPU should be idle and - * should *not* be performing page flips and thus not waiting on - * vblanks... - * Currently, the result of us stealing a vblank from the irq - * handler is that a single frame will be skipped during swapbuffers. - */ - I915_WRITE(pipestat_reg, - I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); - - /* Wait for vblank interrupt bit to set */ - if (wait_for(I915_READ(pipestat_reg) & - PIPE_VBLANK_INTERRUPT_STATUS, - 50)) - DRM_DEBUG_KMS("vblank wait timed out\n"); -} - -/* - * intel_wait_for_pipe_off - wait for pipe to turn off - * @dev: drm device - * @pipe: pipe to wait for - * - * After disabling a pipe, we can't wait for vblank in the usual way, - * spinning on the vblank interrupt status bit, since we won't actually - * see an interrupt when the pipe is disabled. - * - * On Gen4 and above: - * wait for the pipe register state bit to turn off - * - * Otherwise: - * wait for the display line value to settle (it usually - * ends up stopping at the start of the next frame). - * - */ -void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen >= 4) { - int reg = PIPECONF(pipe); - - /* Wait for the Pipe State to go off */ - if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, - 100)) - DRM_DEBUG_KMS("pipe_off wait timed out\n"); - } else { - u32 last_line; - int reg = PIPEDSL(pipe); - unsigned long timeout = jiffies + msecs_to_jiffies(100); - - /* Wait for the display line to settle */ - do { - last_line = I915_READ(reg) & DSL_LINEMASK; - mdelay(5); - } while (((I915_READ(reg) & DSL_LINEMASK) != last_line) && - time_after(timeout, jiffies)); - if (time_after(jiffies, timeout)) - DRM_DEBUG_KMS("pipe_off wait timed out\n"); - } -} - -static const char *state_string(bool enabled) -{ - return enabled ? "on" : "off"; -} - -/* Only for pre-ILK configs */ -static void assert_pll(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - int reg; - u32 val; - bool cur_state; - - reg = DPLL(pipe); - val = I915_READ(reg); - cur_state = !!(val & DPLL_VCO_ENABLE); - WARN(cur_state != state, - "PLL state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); -} -#define assert_pll_enabled(d, p) assert_pll(d, p, true) -#define assert_pll_disabled(d, p) assert_pll(d, p, false) - -/* For ILK+ */ -static void assert_pch_pll(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - int reg; - u32 val; - bool cur_state; - - if (HAS_PCH_CPT(dev_priv->dev)) { - u32 pch_dpll; - - pch_dpll = I915_READ(PCH_DPLL_SEL); - - /* Make sure the selected PLL is enabled to the transcoder */ - WARN(!((pch_dpll >> (4 * pipe)) & 8), - "transcoder %d PLL not enabled\n", pipe); - - /* Convert the transcoder pipe number to a pll pipe number */ - pipe = (pch_dpll >> (4 * pipe)) & 1; - } - - reg = PCH_DPLL(pipe); - val = I915_READ(reg); - cur_state = !!(val & DPLL_VCO_ENABLE); - WARN(cur_state != state, - "PCH PLL state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); -} -#define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, true) -#define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, false) - -static void assert_fdi_tx(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - int reg; - u32 val; - bool cur_state; - - reg = FDI_TX_CTL(pipe); - val = I915_READ(reg); - cur_state = !!(val & FDI_TX_ENABLE); - WARN(cur_state != state, - "FDI TX state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); -} -#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true) -#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false) - -static void assert_fdi_rx(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - int reg; - u32 val; - bool cur_state; - - reg = FDI_RX_CTL(pipe); - val = I915_READ(reg); - cur_state = !!(val & FDI_RX_ENABLE); - WARN(cur_state != state, - "FDI RX state assertion failure (expected %s, current %s)\n", - state_string(state), state_string(cur_state)); -} -#define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true) -#define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false) - -static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - - /* ILK FDI PLL is always enabled */ - if (dev_priv->info->gen == 5) - return; - - reg = FDI_TX_CTL(pipe); - val = I915_READ(reg); - WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); -} - -static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - - reg = FDI_RX_CTL(pipe); - val = I915_READ(reg); - WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); -} - -static void assert_panel_unlocked(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int pp_reg, lvds_reg; - u32 val; - enum pipe panel_pipe = PIPE_A; - bool locked = true; - - if (HAS_PCH_SPLIT(dev_priv->dev)) { - pp_reg = PCH_PP_CONTROL; - lvds_reg = PCH_LVDS; - } else { - pp_reg = PP_CONTROL; - lvds_reg = LVDS; - } - - val = I915_READ(pp_reg); - if (!(val & PANEL_POWER_ON) || - ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS)) - locked = false; - - if (I915_READ(lvds_reg) & LVDS_PIPEB_SELECT) - panel_pipe = PIPE_B; - - WARN(panel_pipe == pipe && locked, - "panel assertion failure, pipe %c regs locked\n", - pipe_name(pipe)); -} - -void assert_pipe(struct drm_i915_private *dev_priv, - enum pipe pipe, bool state) -{ - int reg; - u32 val; - bool cur_state; - - /* if we need the pipe A quirk it must be always on */ - if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) - state = true; - - reg = PIPECONF(pipe); - val = I915_READ(reg); - cur_state = !!(val & PIPECONF_ENABLE); - WARN(cur_state != state, - "pipe %c assertion failure (expected %s, current %s)\n", - pipe_name(pipe), state_string(state), state_string(cur_state)); -} - -static void assert_plane(struct drm_i915_private *dev_priv, - enum plane plane, bool state) -{ - int reg; - u32 val; - bool cur_state; - - reg = DSPCNTR(plane); - val = I915_READ(reg); - cur_state = !!(val & DISPLAY_PLANE_ENABLE); - WARN(cur_state != state, - "plane %c assertion failure (expected %s, current %s)\n", - plane_name(plane), state_string(state), state_string(cur_state)); -} - -#define assert_plane_enabled(d, p) assert_plane(d, p, true) -#define assert_plane_disabled(d, p) assert_plane(d, p, false) - -static void assert_planes_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg, i; - u32 val; - int cur_pipe; - - /* Planes are fixed to pipes on ILK+ */ - if (HAS_PCH_SPLIT(dev_priv->dev)) { - reg = DSPCNTR(pipe); - val = I915_READ(reg); - WARN((val & DISPLAY_PLANE_ENABLE), - "plane %c assertion failure, should be disabled but not\n", - plane_name(pipe)); - return; - } - - /* Need to check both planes against the pipe */ - for (i = 0; i < 2; i++) { - reg = DSPCNTR(i); - val = I915_READ(reg); - cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> - DISPPLANE_SEL_PIPE_SHIFT; - WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe, - "plane %c assertion failure, should be off on pipe %c but is still active\n", - plane_name(i), pipe_name(pipe)); - } -} - -static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) -{ - u32 val; - bool enabled; - - val = I915_READ(PCH_DREF_CONTROL); - enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | - DREF_SUPERSPREAD_SOURCE_MASK)); - WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); -} - -static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - bool enabled; - - reg = TRANSCONF(pipe); - val = I915_READ(reg); - enabled = !!(val & TRANS_ENABLE); - WARN(enabled, - "transcoder assertion failed, should be off on pipe %c but is still active\n", - pipe_name(pipe)); -} - -static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 port_sel, u32 val) -{ - if ((val & DP_PORT_EN) == 0) - return false; - - if (HAS_PCH_CPT(dev_priv->dev)) { - u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); - u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); - if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) - return false; - } else { - if ((val & DP_PIPE_MASK) != (pipe << 30)) - return false; - } - return true; -} - -static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 val) -{ - if ((val & PORT_ENABLE) == 0) - return false; - - if (HAS_PCH_CPT(dev_priv->dev)) { - if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) - return false; - } else { - if ((val & TRANSCODER_MASK) != TRANSCODER(pipe)) - return false; - } - return true; -} - -static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 val) -{ - if ((val & LVDS_PORT_EN) == 0) - return false; - - if (HAS_PCH_CPT(dev_priv->dev)) { - if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) - return false; - } else { - if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe)) - return false; - } - return true; -} - -static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv, - enum pipe pipe, u32 val) -{ - if ((val & ADPA_DAC_ENABLE) == 0) - return false; - if (HAS_PCH_CPT(dev_priv->dev)) { - if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) - return false; - } else { - if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe)) - return false; - } - return true; -} - -static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe, int reg, u32 port_sel) -{ - u32 val = I915_READ(reg); - WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), - "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", - reg, pipe_name(pipe)); -} - -static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe, int reg) -{ - u32 val = I915_READ(reg); - WARN(hdmi_pipe_enabled(dev_priv, val, pipe), - "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", - reg, pipe_name(pipe)); -} - -static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - - assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); - assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); - assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); - - reg = PCH_ADPA; - val = I915_READ(reg); - WARN(adpa_pipe_enabled(dev_priv, val, pipe), - "PCH VGA enabled on transcoder %c, should be disabled\n", - pipe_name(pipe)); - - reg = PCH_LVDS; - val = I915_READ(reg); - WARN(lvds_pipe_enabled(dev_priv, val, pipe), - "PCH LVDS enabled on transcoder %c, should be disabled\n", - pipe_name(pipe)); - - assert_pch_hdmi_disabled(dev_priv, pipe, HDMIB); - assert_pch_hdmi_disabled(dev_priv, pipe, HDMIC); - assert_pch_hdmi_disabled(dev_priv, pipe, HDMID); -} - -/** - * intel_enable_pll - enable a PLL - * @dev_priv: i915 private structure - * @pipe: pipe PLL to enable - * - * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to - * make sure the PLL reg is writable first though, since the panel write - * protect mechanism may be enabled. - * - * Note! This is for pre-ILK only. - */ -static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) -{ - int reg; - u32 val; - - /* No really, not for ILK+ */ - BUG_ON(dev_priv->info->gen >= 5); - - /* PLL is protected by panel, make sure we can write it */ - if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) - assert_panel_unlocked(dev_priv, pipe); - - reg = DPLL(pipe); - val = I915_READ(reg); - val |= DPLL_VCO_ENABLE; - - /* We do this three times for luck */ - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(150); /* wait for warmup */ -} - -/** - * intel_disable_pll - disable a PLL - * @dev_priv: i915 private structure - * @pipe: pipe PLL to disable - * - * Disable the PLL for @pipe, making sure the pipe is off first. - * - * Note! This is for pre-ILK only. - */ -static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) -{ - int reg; - u32 val; - - /* Don't disable pipe A or pipe A PLLs if needed */ - if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) - return; - - /* Make sure the pipe isn't still relying on us */ - assert_pipe_disabled(dev_priv, pipe); - - reg = DPLL(pipe); - val = I915_READ(reg); - val &= ~DPLL_VCO_ENABLE; - I915_WRITE(reg, val); - POSTING_READ(reg); -} - -/** - * intel_enable_pch_pll - enable PCH PLL - * @dev_priv: i915 private structure - * @pipe: pipe PLL to enable - * - * The PCH PLL needs to be enabled before the PCH transcoder, since it - * drives the transcoder clock. - */ -static void intel_enable_pch_pll(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - - if (pipe > 1) - return; - - /* PCH only available on ILK+ */ - BUG_ON(dev_priv->info->gen < 5); - - /* PCH refclock must be enabled first */ - assert_pch_refclk_enabled(dev_priv); - - reg = PCH_DPLL(pipe); - val = I915_READ(reg); - val |= DPLL_VCO_ENABLE; - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(200); -} - -static void intel_disable_pch_pll(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val, pll_mask = TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL, - pll_sel = TRANSC_DPLL_ENABLE; - - if (pipe > 1) - return; - - /* PCH only available on ILK+ */ - BUG_ON(dev_priv->info->gen < 5); - - /* Make sure transcoder isn't still depending on us */ - assert_transcoder_disabled(dev_priv, pipe); - - if (pipe == 0) - pll_sel |= TRANSC_DPLLA_SEL; - else if (pipe == 1) - pll_sel |= TRANSC_DPLLB_SEL; - - - if ((I915_READ(PCH_DPLL_SEL) & pll_mask) == pll_sel) - return; - - reg = PCH_DPLL(pipe); - val = I915_READ(reg); - val &= ~DPLL_VCO_ENABLE; - I915_WRITE(reg, val); - POSTING_READ(reg); - udelay(200); -} - -static void intel_enable_transcoder(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val, pipeconf_val; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - - /* PCH only available on ILK+ */ - BUG_ON(dev_priv->info->gen < 5); - - /* Make sure PCH DPLL is enabled */ - assert_pch_pll_enabled(dev_priv, pipe); - - /* FDI must be feeding us bits for PCH ports */ - assert_fdi_tx_enabled(dev_priv, pipe); - assert_fdi_rx_enabled(dev_priv, pipe); - - reg = TRANSCONF(pipe); - val = I915_READ(reg); - pipeconf_val = I915_READ(PIPECONF(pipe)); - - if (HAS_PCH_IBX(dev_priv->dev)) { - /* - * make the BPC in transcoder be consistent with - * that in pipeconf reg. - */ - val &= ~PIPE_BPC_MASK; - val |= pipeconf_val & PIPE_BPC_MASK; - } - - val &= ~TRANS_INTERLACE_MASK; - if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) - if (HAS_PCH_IBX(dev_priv->dev) && - intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) - val |= TRANS_LEGACY_INTERLACED_ILK; - else - val |= TRANS_INTERLACED; - else - val |= TRANS_PROGRESSIVE; - - I915_WRITE(reg, val | TRANS_ENABLE); - if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) - DRM_ERROR("failed to enable transcoder %d\n", pipe); -} - -static void intel_disable_transcoder(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - - /* FDI relies on the transcoder */ - assert_fdi_tx_disabled(dev_priv, pipe); - assert_fdi_rx_disabled(dev_priv, pipe); - - /* Ports must be off as well */ - assert_pch_ports_disabled(dev_priv, pipe); - - reg = TRANSCONF(pipe); - val = I915_READ(reg); - val &= ~TRANS_ENABLE; - I915_WRITE(reg, val); - /* wait for PCH transcoder off, transcoder state */ - if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) - DRM_ERROR("failed to disable transcoder %d\n", pipe); -} - -/** - * intel_enable_pipe - enable a pipe, asserting requirements - * @dev_priv: i915 private structure - * @pipe: pipe to enable - * @pch_port: on ILK+, is this pipe driving a PCH port or not - * - * Enable @pipe, making sure that various hardware specific requirements - * are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc. - * - * @pipe should be %PIPE_A or %PIPE_B. - * - * Will wait until the pipe is actually running (i.e. first vblank) before - * returning. - */ -static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, - bool pch_port) -{ - int reg; - u32 val; - - /* - * A pipe without a PLL won't actually be able to drive bits from - * a plane. On ILK+ the pipe PLLs are integrated, so we don't - * need the check. - */ - if (!HAS_PCH_SPLIT(dev_priv->dev)) - assert_pll_enabled(dev_priv, pipe); - else { - if (pch_port) { - /* if driving the PCH, we need FDI enabled */ - assert_fdi_rx_pll_enabled(dev_priv, pipe); - assert_fdi_tx_pll_enabled(dev_priv, pipe); - } - /* FIXME: assert CPU port conditions for SNB+ */ - } - - reg = PIPECONF(pipe); - val = I915_READ(reg); - if (val & PIPECONF_ENABLE) - return; - - I915_WRITE(reg, val | PIPECONF_ENABLE); - intel_wait_for_vblank(dev_priv->dev, pipe); -} - -/** - * intel_disable_pipe - disable a pipe, asserting requirements - * @dev_priv: i915 private structure - * @pipe: pipe to disable - * - * Disable @pipe, making sure that various hardware specific requirements - * are met, if applicable, e.g. plane disabled, panel fitter off, etc. - * - * @pipe should be %PIPE_A or %PIPE_B. - * - * Will wait until the pipe has shut down before returning. - */ -static void intel_disable_pipe(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - int reg; - u32 val; - - /* - * Make sure planes won't keep trying to pump pixels to us, - * or we might hang the display. - */ - assert_planes_disabled(dev_priv, pipe); - - /* Don't disable pipe A or pipe A PLLs if needed */ - if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) - return; - - reg = PIPECONF(pipe); - val = I915_READ(reg); - if ((val & PIPECONF_ENABLE) == 0) - return; - - I915_WRITE(reg, val & ~PIPECONF_ENABLE); - intel_wait_for_pipe_off(dev_priv->dev, pipe); -} - -/* - * Plane regs are double buffered, going from enabled->disabled needs a - * trigger in order to latch. The display address reg provides this. - */ -static void intel_flush_display_plane(struct drm_i915_private *dev_priv, - enum plane plane) -{ - I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); - I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane))); -} - -/** - * intel_enable_plane - enable a display plane on a given pipe - * @dev_priv: i915 private structure - * @plane: plane to enable - * @pipe: pipe being fed - * - * Enable @plane on @pipe, making sure that @pipe is running first. - */ -static void intel_enable_plane(struct drm_i915_private *dev_priv, - enum plane plane, enum pipe pipe) -{ - int reg; - u32 val; - - /* If the pipe isn't enabled, we can't pump pixels and may hang */ - assert_pipe_enabled(dev_priv, pipe); - - reg = DSPCNTR(plane); - val = I915_READ(reg); - if (val & DISPLAY_PLANE_ENABLE) - return; - - I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); - intel_flush_display_plane(dev_priv, plane); - intel_wait_for_vblank(dev_priv->dev, pipe); -} - -/** - * intel_disable_plane - disable a display plane - * @dev_priv: i915 private structure - * @plane: plane to disable - * @pipe: pipe consuming the data - * - * Disable @plane; should be an independent operation. - */ -static void intel_disable_plane(struct drm_i915_private *dev_priv, - enum plane plane, enum pipe pipe) -{ - int reg; - u32 val; - - reg = DSPCNTR(plane); - val = I915_READ(reg); - if ((val & DISPLAY_PLANE_ENABLE) == 0) - return; - - I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); - intel_flush_display_plane(dev_priv, plane); - intel_wait_for_vblank(dev_priv->dev, pipe); -} - -static void disable_pch_dp(struct drm_i915_private *dev_priv, - enum pipe pipe, int reg, u32 port_sel) -{ - u32 val = I915_READ(reg); - if (dp_pipe_enabled(dev_priv, pipe, port_sel, val)) { - DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); - I915_WRITE(reg, val & ~DP_PORT_EN); - } -} - -static void disable_pch_hdmi(struct drm_i915_private *dev_priv, - enum pipe pipe, int reg) -{ - u32 val = I915_READ(reg); - if (hdmi_pipe_enabled(dev_priv, val, pipe)) { - DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", - reg, pipe); - I915_WRITE(reg, val & ~PORT_ENABLE); - } -} - -/* Disable any ports connected to this transcoder */ -static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, - enum pipe pipe) -{ - u32 reg, val; - - val = I915_READ(PCH_PP_CONTROL); - I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); - - disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); - disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); - disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); - - reg = PCH_ADPA; - val = I915_READ(reg); - if (adpa_pipe_enabled(dev_priv, val, pipe)) - I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); - - reg = PCH_LVDS; - val = I915_READ(reg); - if (lvds_pipe_enabled(dev_priv, val, pipe)) { - DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); - I915_WRITE(reg, val & ~LVDS_PORT_EN); - POSTING_READ(reg); - udelay(100); - } - - disable_pch_hdmi(dev_priv, pipe, HDMIB); - disable_pch_hdmi(dev_priv, pipe, HDMIC); - disable_pch_hdmi(dev_priv, pipe, HDMID); -} - -static void i8xx_disable_fbc(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 fbc_ctl; - - /* Disable compression */ - fbc_ctl = I915_READ(FBC_CONTROL); - if ((fbc_ctl & FBC_CTL_EN) == 0) - return; - - fbc_ctl &= ~FBC_CTL_EN; - I915_WRITE(FBC_CONTROL, fbc_ctl); - - /* Wait for compressing bit to clear */ - if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { - DRM_DEBUG_KMS("FBC idle timed out\n"); - return; - } - - DRM_DEBUG_KMS("disabled FBC\n"); -} - -static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int cfb_pitch; - int plane, i; - u32 fbc_ctl, fbc_ctl2; - - cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; - if (fb->pitches[0] < cfb_pitch) - cfb_pitch = fb->pitches[0]; - - /* FBC_CTL wants 64B units */ - cfb_pitch = (cfb_pitch / 64) - 1; - plane = intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; - - /* Clear old tags */ - for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) - I915_WRITE(FBC_TAG + (i * 4), 0); - - /* Set it up... */ - fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; - fbc_ctl2 |= plane; - I915_WRITE(FBC_CONTROL2, fbc_ctl2); - I915_WRITE(FBC_FENCE_OFF, crtc->y); - - /* enable it... */ - fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; - if (IS_I945GM(dev)) - fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ - fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; - fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; - fbc_ctl |= obj->fence_reg; - I915_WRITE(FBC_CONTROL, fbc_ctl); - - DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %d, ", - cfb_pitch, crtc->y, intel_crtc->plane); -} - -static bool i8xx_fbc_enabled(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - return I915_READ(FBC_CONTROL) & FBC_CTL_EN; -} - -static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; - unsigned long stall_watermark = 200; - u32 dpfc_ctl; - - dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; - dpfc_ctl |= DPFC_CTL_FENCE_EN | obj->fence_reg; - I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); - - I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | - (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | - (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); - I915_WRITE(DPFC_FENCE_YOFF, crtc->y); - - /* enable it... */ - I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN); - - DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); -} - -static void g4x_disable_fbc(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpfc_ctl; - - /* Disable compression */ - dpfc_ctl = I915_READ(DPFC_CONTROL); - if (dpfc_ctl & DPFC_CTL_EN) { - dpfc_ctl &= ~DPFC_CTL_EN; - I915_WRITE(DPFC_CONTROL, dpfc_ctl); - - DRM_DEBUG_KMS("disabled FBC\n"); - } -} - -static bool g4x_fbc_enabled(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; -} - -static void sandybridge_blit_fbc_update(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 blt_ecoskpd; - - /* Make sure blitter notifies FBC of writes */ - gen6_gt_force_wake_get(dev_priv); - blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); - blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << - GEN6_BLITTER_LOCK_SHIFT; - I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); - blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY; - I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); - blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY << - GEN6_BLITTER_LOCK_SHIFT); - I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); - POSTING_READ(GEN6_BLITTER_ECOSKPD); - gen6_gt_force_wake_put(dev_priv); -} - -static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = crtc->fb; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; - unsigned long stall_watermark = 200; - u32 dpfc_ctl; - - dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); - dpfc_ctl &= DPFC_RESERVED; - dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); - /* Set persistent mode for front-buffer rendering, ala X. */ - dpfc_ctl |= DPFC_CTL_PERSISTENT_MODE; - dpfc_ctl |= (DPFC_CTL_FENCE_EN | obj->fence_reg); - I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); - - I915_WRITE(ILK_DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | - (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | - (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); - I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); - I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); - /* enable it... */ - I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); - - if (IS_GEN6(dev)) { - I915_WRITE(SNB_DPFC_CTL_SA, - SNB_CPU_FENCE_ENABLE | obj->fence_reg); - I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); - sandybridge_blit_fbc_update(dev); - } - - DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); -} - -static void ironlake_disable_fbc(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpfc_ctl; - - /* Disable compression */ - dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); - if (dpfc_ctl & DPFC_CTL_EN) { - dpfc_ctl &= ~DPFC_CTL_EN; - I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); - - DRM_DEBUG_KMS("disabled FBC\n"); - } -} - -static bool ironlake_fbc_enabled(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN; -} - -bool intel_fbc_enabled(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!dev_priv->display.fbc_enabled) - return false; - - return dev_priv->display.fbc_enabled(dev); -} - -static void intel_fbc_work_fn(struct work_struct *__work) -{ - struct intel_fbc_work *work = - container_of(to_delayed_work(__work), - struct intel_fbc_work, work); - struct drm_device *dev = work->crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - mutex_lock(&dev->struct_mutex); - if (work == dev_priv->fbc_work) { - /* Double check that we haven't switched fb without cancelling - * the prior work. - */ - if (work->crtc->fb == work->fb) { - dev_priv->display.enable_fbc(work->crtc, - work->interval); - - dev_priv->cfb_plane = to_intel_crtc(work->crtc)->plane; - dev_priv->cfb_fb = work->crtc->fb->base.id; - dev_priv->cfb_y = work->crtc->y; - } - - dev_priv->fbc_work = NULL; - } - mutex_unlock(&dev->struct_mutex); - - kfree(work); -} - -static void intel_cancel_fbc_work(struct drm_i915_private *dev_priv) -{ - if (dev_priv->fbc_work == NULL) - return; - - DRM_DEBUG_KMS("cancelling pending FBC enable\n"); - - /* Synchronisation is provided by struct_mutex and checking of - * dev_priv->fbc_work, so we can perform the cancellation - * entirely asynchronously. - */ - if (cancel_delayed_work(&dev_priv->fbc_work->work)) - /* tasklet was killed before being run, clean up */ - kfree(dev_priv->fbc_work); - - /* Mark the work as no longer wanted so that if it does - * wake-up (because the work was already running and waiting - * for our mutex), it will discover that is no longer - * necessary to run. - */ - dev_priv->fbc_work = NULL; -} - -static void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) -{ - struct intel_fbc_work *work; - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!dev_priv->display.enable_fbc) - return; - - intel_cancel_fbc_work(dev_priv); - - work = kzalloc(sizeof *work, GFP_KERNEL); - if (work == NULL) { - dev_priv->display.enable_fbc(crtc, interval); - return; - } - - work->crtc = crtc; - work->fb = crtc->fb; - work->interval = interval; - INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn); - - dev_priv->fbc_work = work; - - DRM_DEBUG_KMS("scheduling delayed FBC enable\n"); - - /* Delay the actual enabling to let pageflipping cease and the - * display to settle before starting the compression. Note that - * this delay also serves a second purpose: it allows for a - * vblank to pass after disabling the FBC before we attempt - * to modify the control registers. - * - * A more complicated solution would involve tracking vblanks - * following the termination of the page-flipping sequence - * and indeed performing the enable as a co-routine and not - * waiting synchronously upon the vblank. - */ - schedule_delayed_work(&work->work, msecs_to_jiffies(50)); -} - -void intel_disable_fbc(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - intel_cancel_fbc_work(dev_priv); - - if (!dev_priv->display.disable_fbc) - return; - - dev_priv->display.disable_fbc(dev); - dev_priv->cfb_plane = -1; -} - -/** - * intel_update_fbc - enable/disable FBC as needed - * @dev: the drm_device - * - * Set up the framebuffer compression hardware at mode set time. We - * enable it if possible: - * - plane A only (on pre-965) - * - no pixel mulitply/line duplication - * - no alpha buffer discard - * - no dual wide - * - framebuffer <= 2048 in width, 1536 in height - * - * We can't assume that any compression will take place (worst case), - * so the compressed buffer has to be the same size as the uncompressed - * one. It also must reside (along with the line length buffer) in - * stolen memory. - * - * We need to enable/disable FBC on a global basis. - */ -static void intel_update_fbc(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = NULL, *tmp_crtc; - struct intel_crtc *intel_crtc; - struct drm_framebuffer *fb; - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; - int enable_fbc; - - DRM_DEBUG_KMS("\n"); - - if (!i915_powersave) - return; - - if (!I915_HAS_FBC(dev)) - return; - - /* - * If FBC is already on, we just have to verify that we can - * keep it that way... - * Need to disable if: - * - more than one pipe is active - * - changing FBC params (stride, fence, mode) - * - new fb is too large to fit in compressed buffer - * - going to an unsupported config (interlace, pixel multiply, etc.) - */ - list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) { - if (tmp_crtc->enabled && tmp_crtc->fb) { - if (crtc) { - DRM_DEBUG_KMS("more than one pipe active, disabling compression\n"); - dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES; - goto out_disable; - } - crtc = tmp_crtc; - } - } - - if (!crtc || crtc->fb == NULL) { - DRM_DEBUG_KMS("no output, disabling\n"); - dev_priv->no_fbc_reason = FBC_NO_OUTPUT; - goto out_disable; - } - - intel_crtc = to_intel_crtc(crtc); - fb = crtc->fb; - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - - enable_fbc = i915_enable_fbc; - if (enable_fbc < 0) { - DRM_DEBUG_KMS("fbc set to per-chip default\n"); - enable_fbc = 1; - if (INTEL_INFO(dev)->gen <= 6) - enable_fbc = 0; - } - if (!enable_fbc) { - DRM_DEBUG_KMS("fbc disabled per module param\n"); - dev_priv->no_fbc_reason = FBC_MODULE_PARAM; - goto out_disable; - } - if (intel_fb->obj->base.size > dev_priv->cfb_size) { - DRM_DEBUG_KMS("framebuffer too large, disabling " - "compression\n"); - dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; - goto out_disable; - } - if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) || - (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) { - DRM_DEBUG_KMS("mode incompatible with compression, " - "disabling\n"); - dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE; - goto out_disable; - } - if ((crtc->mode.hdisplay > 2048) || - (crtc->mode.vdisplay > 1536)) { - DRM_DEBUG_KMS("mode too large for compression, disabling\n"); - dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE; - goto out_disable; - } - if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) { - DRM_DEBUG_KMS("plane not 0, disabling compression\n"); - dev_priv->no_fbc_reason = FBC_BAD_PLANE; - goto out_disable; - } - - /* The use of a CPU fence is mandatory in order to detect writes - * by the CPU to the scanout and trigger updates to the FBC. - */ - if (obj->tiling_mode != I915_TILING_X || - obj->fence_reg == I915_FENCE_REG_NONE) { - DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n"); - dev_priv->no_fbc_reason = FBC_NOT_TILED; - goto out_disable; - } - - /* If the kernel debugger is active, always disable compression */ - if (in_dbg_master()) - goto out_disable; - - /* If the scanout has not changed, don't modify the FBC settings. - * Note that we make the fundamental assumption that the fb->obj - * cannot be unpinned (and have its GTT offset and fence revoked) - * without first being decoupled from the scanout and FBC disabled. - */ - if (dev_priv->cfb_plane == intel_crtc->plane && - dev_priv->cfb_fb == fb->base.id && - dev_priv->cfb_y == crtc->y) - return; - - if (intel_fbc_enabled(dev)) { - /* We update FBC along two paths, after changing fb/crtc - * configuration (modeswitching) and after page-flipping - * finishes. For the latter, we know that not only did - * we disable the FBC at the start of the page-flip - * sequence, but also more than one vblank has passed. - * - * For the former case of modeswitching, it is possible - * to switch between two FBC valid configurations - * instantaneously so we do need to disable the FBC - * before we can modify its control registers. We also - * have to wait for the next vblank for that to take - * effect. However, since we delay enabling FBC we can - * assume that a vblank has passed since disabling and - * that we can safely alter the registers in the deferred - * callback. - * - * In the scenario that we go from a valid to invalid - * and then back to valid FBC configuration we have - * no strict enforcement that a vblank occurred since - * disabling the FBC. However, along all current pipe - * disabling paths we do need to wait for a vblank at - * some point. And we wait before enabling FBC anyway. - */ - DRM_DEBUG_KMS("disabling active FBC for update\n"); - intel_disable_fbc(dev); - } - - intel_enable_fbc(crtc, 500); - return; - -out_disable: - /* Multiple disables should be harmless */ - if (intel_fbc_enabled(dev)) { - DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); - intel_disable_fbc(dev); - } -} - -int -intel_pin_and_fence_fb_obj(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 alignment; - int ret; - - switch (obj->tiling_mode) { - case I915_TILING_NONE: - if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) - alignment = 128 * 1024; - else if (INTEL_INFO(dev)->gen >= 4) - alignment = 4 * 1024; - else - alignment = 64 * 1024; - break; - case I915_TILING_X: - /* pin() will align the object as required by fence */ - alignment = 0; - break; - case I915_TILING_Y: - /* FIXME: Is this true? */ - DRM_ERROR("Y tiled not allowed for scan out buffers\n"); - return -EINVAL; - default: - BUG(); - } - - dev_priv->mm.interruptible = false; - ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); - if (ret) - goto err_interruptible; - - /* Install a fence for tiled scan-out. Pre-i965 always needs a - * fence, whereas 965+ only requires a fence if using - * framebuffer compression. For simplicity, we always install - * a fence as the cost is not that onerous. - */ - if (obj->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence(obj, pipelined); - if (ret) - goto err_unpin; - - i915_gem_object_pin_fence(obj); - } - - dev_priv->mm.interruptible = true; - return 0; - -err_unpin: - i915_gem_object_unpin(obj); -err_interruptible: - dev_priv->mm.interruptible = true; - return ret; -} - -void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) -{ - i915_gem_object_unpin_fence(obj); - i915_gem_object_unpin(obj); -} - -static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, - int x, int y) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; - int plane = intel_crtc->plane; - unsigned long Start, Offset; - u32 dspcntr; - u32 reg; - - switch (plane) { - case 0: - case 1: - break; - default: - DRM_ERROR("Can't update plane %d in SAREA\n", plane); - return -EINVAL; - } - - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - - reg = DSPCNTR(plane); - dspcntr = I915_READ(reg); - /* Mask out pixel format bits in case we change it */ - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - switch (fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (fb->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel); - return -EINVAL; - } - if (INTEL_INFO(dev)->gen >= 4) { - if (obj->tiling_mode != I915_TILING_NONE) - dspcntr |= DISPPLANE_TILED; - else - dspcntr &= ~DISPPLANE_TILED; - } - - I915_WRITE(reg, dspcntr); - - Start = obj->gtt_offset; - Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); - - DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", - Start, Offset, x, y, fb->pitches[0]); - I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); - if (INTEL_INFO(dev)->gen >= 4) { - I915_WRITE(DSPSURF(plane), Start); - I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); - I915_WRITE(DSPADDR(plane), Offset); - } else - I915_WRITE(DSPADDR(plane), Start + Offset); - POSTING_READ(reg); - - return 0; -} - -static int ironlake_update_plane(struct drm_crtc *crtc, - struct drm_framebuffer *fb, int x, int y) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; - int plane = intel_crtc->plane; - unsigned long Start, Offset; - u32 dspcntr; - u32 reg; - - switch (plane) { - case 0: - case 1: - case 2: - break; - default: - DRM_ERROR("Can't update plane %d in SAREA\n", plane); - return -EINVAL; - } - - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - - reg = DSPCNTR(plane); - dspcntr = I915_READ(reg); - /* Mask out pixel format bits in case we change it */ - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; - switch (fb->bits_per_pixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (fb->depth != 16) - return -EINVAL; - - dspcntr |= DISPPLANE_16BPP; - break; - case 24: - case 32: - if (fb->depth == 24) - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - else if (fb->depth == 30) - dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA; - else - return -EINVAL; - break; - default: - DRM_ERROR("Unknown color depth %d\n", fb->bits_per_pixel); - return -EINVAL; - } - - if (obj->tiling_mode != I915_TILING_NONE) - dspcntr |= DISPPLANE_TILED; - else - dspcntr &= ~DISPPLANE_TILED; - - /* must disable */ - dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; - - I915_WRITE(reg, dspcntr); - - Start = obj->gtt_offset; - Offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); - - DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", - Start, Offset, x, y, fb->pitches[0]); - I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); - I915_WRITE(DSPSURF(plane), Start); - I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); - I915_WRITE(DSPADDR(plane), Offset); - POSTING_READ(reg); - - return 0; -} - -/* Assume fb object is pinned & idle & fenced and just update base pointers */ -static int -intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - ret = dev_priv->display.update_plane(crtc, fb, x, y); - if (ret) - return ret; - - intel_update_fbc(dev); - intel_increase_pllclock(crtc); - - return 0; -} - -static int -intel_finish_fb(struct drm_framebuffer *old_fb) -{ - struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - bool was_interruptible = dev_priv->mm.interruptible; - int ret; - - wait_event(dev_priv->pending_flip_queue, - atomic_read(&dev_priv->mm.wedged) || - atomic_read(&obj->pending_flip) == 0); - - /* Big Hammer, we also need to ensure that any pending - * MI_WAIT_FOR_EVENT inside a user batch buffer on the - * current scanout is retired before unpinning the old - * framebuffer. - * - * This should only fail upon a hung GPU, in which case we - * can safely continue. - */ - dev_priv->mm.interruptible = false; - ret = i915_gem_object_finish_gpu(obj); - dev_priv->mm.interruptible = was_interruptible; - - return ret; -} - -static int -intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_master_private *master_priv; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int ret; - - /* no fb bound */ - if (!crtc->fb) { - DRM_ERROR("No FB bound\n"); - return 0; - } - - switch (intel_crtc->plane) { - case 0: - case 1: - break; - case 2: - if (IS_IVYBRIDGE(dev)) - break; - /* fall through otherwise */ - default: - DRM_ERROR("no plane for crtc\n"); - return -EINVAL; - } - - mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, - to_intel_framebuffer(crtc->fb)->obj, - NULL); - if (ret != 0) { - mutex_unlock(&dev->struct_mutex); - DRM_ERROR("pin & fence failed\n"); - return ret; - } - - if (old_fb) - intel_finish_fb(old_fb); - - ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, - LEAVE_ATOMIC_MODE_SET); - if (ret) { - intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); - mutex_unlock(&dev->struct_mutex); - DRM_ERROR("failed to update base address\n"); - return ret; - } - - if (old_fb) { - intel_wait_for_vblank(dev, intel_crtc->pipe); - intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); - } - - mutex_unlock(&dev->struct_mutex); - - if (!dev->primary->master) - return 0; - - master_priv = dev->primary->master->driver_priv; - if (!master_priv->sarea_priv) - return 0; - - if (intel_crtc->pipe) { - master_priv->sarea_priv->pipeB_x = x; - master_priv->sarea_priv->pipeB_y = y; - } else { - master_priv->sarea_priv->pipeA_x = x; - master_priv->sarea_priv->pipeA_y = y; - } - - return 0; -} - -static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpa_ctl; - - DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock); - dpa_ctl = I915_READ(DP_A); - dpa_ctl &= ~DP_PLL_FREQ_MASK; - - if (clock < 200000) { - u32 temp; - dpa_ctl |= DP_PLL_FREQ_160MHZ; - /* workaround for 160Mhz: - 1) program 0x4600c bits 15:0 = 0x8124 - 2) program 0x46010 bit 0 = 1 - 3) program 0x46034 bit 24 = 1 - 4) program 0x64000 bit 14 = 1 - */ - temp = I915_READ(0x4600c); - temp &= 0xffff0000; - I915_WRITE(0x4600c, temp | 0x8124); - - temp = I915_READ(0x46010); - I915_WRITE(0x46010, temp | 1); - - temp = I915_READ(0x46034); - I915_WRITE(0x46034, temp | (1 << 24)); - } else { - dpa_ctl |= DP_PLL_FREQ_270MHZ; - } - I915_WRITE(DP_A, dpa_ctl); - - POSTING_READ(DP_A); - udelay(500); -} - -static void intel_fdi_normal_train(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp; - - /* enable normal train */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - if (IS_IVYBRIDGE(dev)) { - temp &= ~FDI_LINK_TRAIN_NONE_IVB; - temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; - } - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_NORMAL_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE; - } - I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); - - /* wait one idle pattern time */ - POSTING_READ(reg); - udelay(1000); - - /* IVB wants error correction enabled */ - if (IS_IVYBRIDGE(dev)) - I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE | - FDI_FE_ERRC_ENABLE); -} - -static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 flags = I915_READ(SOUTH_CHICKEN1); - - flags |= FDI_PHASE_SYNC_OVR(pipe); - I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */ - flags |= FDI_PHASE_SYNC_EN(pipe); - I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */ - POSTING_READ(SOUTH_CHICKEN1); -} - -/* The FDI link training functions for ILK/Ibexpeak. */ -static void ironlake_fdi_link_train(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - u32 reg, temp, tries; - - /* FDI needs bits from pipe & plane first */ - assert_pipe_enabled(dev_priv, pipe); - assert_plane_enabled(dev_priv, plane); - - /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit - for train result */ - reg = FDI_RX_IMR(pipe); - temp = I915_READ(reg); - temp &= ~FDI_RX_SYMBOL_LOCK; - temp &= ~FDI_RX_BIT_LOCK; - I915_WRITE(reg, temp); - I915_READ(reg); - udelay(150); - - /* enable CPU FDI TX and PCH FDI RX */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(7 << 19); - temp |= (intel_crtc->fdi_lanes - 1) << 19; - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; - I915_WRITE(reg, temp | FDI_TX_ENABLE); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; - I915_WRITE(reg, temp | FDI_RX_ENABLE); - - POSTING_READ(reg); - udelay(150); - - /* Ironlake workaround, enable clock pointer after FDI enable*/ - if (HAS_PCH_IBX(dev)) { - I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR); - I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR | - FDI_RX_PHASE_SYNC_POINTER_EN); - } - - reg = FDI_RX_IIR(pipe); - for (tries = 0; tries < 5; tries++) { - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if ((temp & FDI_RX_BIT_LOCK)) { - DRM_DEBUG_KMS("FDI train 1 done.\n"); - I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); - break; - } - } - if (tries == 5) - DRM_ERROR("FDI train 1 fail!\n"); - - /* Train 2 */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_2; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_2; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - reg = FDI_RX_IIR(pipe); - for (tries = 0; tries < 5; tries++) { - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_SYMBOL_LOCK) { - I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); - DRM_DEBUG_KMS("FDI train 2 done.\n"); - break; - } - } - if (tries == 5) - DRM_ERROR("FDI train 2 fail!\n"); - - DRM_DEBUG_KMS("FDI train done\n"); - -} - -static const int snb_b_fdi_train_param[] = { - FDI_LINK_TRAIN_400MV_0DB_SNB_B, - FDI_LINK_TRAIN_400MV_6DB_SNB_B, - FDI_LINK_TRAIN_600MV_3_5DB_SNB_B, - FDI_LINK_TRAIN_800MV_0DB_SNB_B, -}; - -/* The FDI link training functions for SNB/Cougarpoint. */ -static void gen6_fdi_link_train(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp, i; - - /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit - for train result */ - reg = FDI_RX_IMR(pipe); - temp = I915_READ(reg); - temp &= ~FDI_RX_SYMBOL_LOCK; - temp &= ~FDI_RX_BIT_LOCK; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - /* enable CPU FDI TX and PCH FDI RX */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(7 << 19); - temp |= (intel_crtc->fdi_lanes - 1) << 19; - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - /* SNB-B */ - temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - I915_WRITE(reg, temp | FDI_TX_ENABLE); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; - } - I915_WRITE(reg, temp | FDI_RX_ENABLE); - - POSTING_READ(reg); - udelay(150); - - if (HAS_PCH_CPT(dev)) - cpt_phase_pointer_enable(dev, pipe); - - for (i = 0; i < 4; i++) { - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= snb_b_fdi_train_param[i]; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(500); - - reg = FDI_RX_IIR(pipe); - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_BIT_LOCK) { - I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); - DRM_DEBUG_KMS("FDI train 1 done.\n"); - break; - } - } - if (i == 4) - DRM_ERROR("FDI train 1 fail!\n"); - - /* Train 2 */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_2; - if (IS_GEN6(dev)) { - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - /* SNB-B */ - temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - } - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_2; - } - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - for (i = 0; i < 4; i++) { - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= snb_b_fdi_train_param[i]; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(500); - - reg = FDI_RX_IIR(pipe); - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_SYMBOL_LOCK) { - I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); - DRM_DEBUG_KMS("FDI train 2 done.\n"); - break; - } - } - if (i == 4) - DRM_ERROR("FDI train 2 fail!\n"); - - DRM_DEBUG_KMS("FDI train done.\n"); -} - -/* Manual link training for Ivy Bridge A0 parts */ -static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp, i; - - /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit - for train result */ - reg = FDI_RX_IMR(pipe); - temp = I915_READ(reg); - temp &= ~FDI_RX_SYMBOL_LOCK; - temp &= ~FDI_RX_BIT_LOCK; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - /* enable CPU FDI TX and PCH FDI RX */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(7 << 19); - temp |= (intel_crtc->fdi_lanes - 1) << 19; - temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); - temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - temp |= FDI_COMPOSITE_SYNC; - I915_WRITE(reg, temp | FDI_TX_ENABLE); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_AUTO; - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; - temp |= FDI_COMPOSITE_SYNC; - I915_WRITE(reg, temp | FDI_RX_ENABLE); - - POSTING_READ(reg); - udelay(150); - - if (HAS_PCH_CPT(dev)) - cpt_phase_pointer_enable(dev, pipe); - - for (i = 0; i < 4; i++) { - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= snb_b_fdi_train_param[i]; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(500); - - reg = FDI_RX_IIR(pipe); - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_BIT_LOCK || - (I915_READ(reg) & FDI_RX_BIT_LOCK)) { - I915_WRITE(reg, temp | FDI_RX_BIT_LOCK); - DRM_DEBUG_KMS("FDI train 1 done.\n"); - break; - } - } - if (i == 4) - DRM_ERROR("FDI train 1 fail!\n"); - - /* Train 2 */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE_IVB; - temp |= FDI_LINK_TRAIN_PATTERN_2_IVB; - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(150); - - for (i = 0; i < 4; i++) { - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; - temp |= snb_b_fdi_train_param[i]; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(500); - - reg = FDI_RX_IIR(pipe); - temp = I915_READ(reg); - DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp); - - if (temp & FDI_RX_SYMBOL_LOCK) { - I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK); - DRM_DEBUG_KMS("FDI train 2 done.\n"); - break; - } - } - if (i == 4) - DRM_ERROR("FDI train 2 fail!\n"); - - DRM_DEBUG_KMS("FDI train done.\n"); -} - -static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp; - - /* Write the TU size bits so error detection works */ - I915_WRITE(FDI_RX_TUSIZE1(pipe), - I915_READ(PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); - - /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~((0x7 << 19) | (0x7 << 16)); - temp |= (intel_crtc->fdi_lanes - 1) << 19; - temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; - I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE); - - POSTING_READ(reg); - udelay(200); - - /* Switch from Rawclk to PCDclk */ - temp = I915_READ(reg); - I915_WRITE(reg, temp | FDI_PCDCLK); - - POSTING_READ(reg); - udelay(200); - - /* Enable CPU FDI TX PLL, always on for Ironlake */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - if ((temp & FDI_TX_PLL_ENABLE) == 0) { - I915_WRITE(reg, temp | FDI_TX_PLL_ENABLE); - - POSTING_READ(reg); - udelay(100); - } -} - -static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 flags = I915_READ(SOUTH_CHICKEN1); - - flags &= ~(FDI_PHASE_SYNC_EN(pipe)); - I915_WRITE(SOUTH_CHICKEN1, flags); /* once to disable... */ - flags &= ~(FDI_PHASE_SYNC_OVR(pipe)); - I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to lock */ - POSTING_READ(SOUTH_CHICKEN1); -} -static void ironlake_fdi_disable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp; - - /* disable CPU FDI tx and PCH FDI rx */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - I915_WRITE(reg, temp & ~FDI_TX_ENABLE); - POSTING_READ(reg); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(0x7 << 16); - temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; - I915_WRITE(reg, temp & ~FDI_RX_ENABLE); - - POSTING_READ(reg); - udelay(100); - - /* Ironlake workaround, disable clock pointer after downing FDI */ - if (HAS_PCH_IBX(dev)) { - I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR); - I915_WRITE(FDI_RX_CHICKEN(pipe), - I915_READ(FDI_RX_CHICKEN(pipe) & - ~FDI_RX_PHASE_SYNC_POINTER_EN)); - } else if (HAS_PCH_CPT(dev)) { - cpt_phase_pointer_disable(dev, pipe); - } - - /* still set train pattern 1 */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; - } - /* BPC in FDI rx is consistent with that in PIPECONF */ - temp &= ~(0x07 << 16); - temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; - I915_WRITE(reg, temp); - - POSTING_READ(reg); - udelay(100); -} - -/* - * When we disable a pipe, we need to clear any pending scanline wait events - * to avoid hanging the ring, which we assume we are waiting on. - */ -static void intel_clear_scanline_wait(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; - u32 tmp; - - if (IS_GEN2(dev)) - /* Can't break the hang on i8xx */ - return; - - ring = LP_RING(dev_priv); - tmp = I915_READ_CTL(ring); - if (tmp & RING_WAIT) - I915_WRITE_CTL(ring, tmp); -} - -static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) -{ - struct drm_i915_gem_object *obj; - struct drm_i915_private *dev_priv; - - if (crtc->fb == NULL) - return; - - obj = to_intel_framebuffer(crtc->fb)->obj; - dev_priv = crtc->dev->dev_private; - wait_event(dev_priv->pending_flip_queue, - atomic_read(&obj->pending_flip) == 0); -} - -static bool intel_crtc_driving_pch(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - - /* - * If there's a non-PCH eDP on this crtc, it must be DP_A, and that - * must be driven by its own crtc; no sharing is possible. - */ - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { - if (encoder->base.crtc != crtc) - continue; - - switch (encoder->type) { - case INTEL_OUTPUT_EDP: - if (!intel_encoder_is_pch_edp(&encoder->base)) - return false; - continue; - } - } - - return true; -} - -/* - * Enable PCH resources required for PCH ports: - * - PCH PLLs - * - FDI training & RX/TX - * - update transcoder timings - * - DP transcoding bits - * - transcoder - */ -static void ironlake_pch_enable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp, transc_sel; - - /* For PCH output, training FDI link */ - dev_priv->display.fdi_link_train(crtc); - - intel_enable_pch_pll(dev_priv, pipe); - - if (HAS_PCH_CPT(dev)) { - transc_sel = intel_crtc->use_pll_a ? TRANSC_DPLLA_SEL : - TRANSC_DPLLB_SEL; - - /* Be sure PCH DPLL SEL is set */ - temp = I915_READ(PCH_DPLL_SEL); - if (pipe == 0) { - temp &= ~(TRANSA_DPLLB_SEL); - temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); - } else if (pipe == 1) { - temp &= ~(TRANSB_DPLLB_SEL); - temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); - } else if (pipe == 2) { - temp &= ~(TRANSC_DPLLB_SEL); - temp |= (TRANSC_DPLL_ENABLE | transc_sel); - } - I915_WRITE(PCH_DPLL_SEL, temp); - } - - /* set transcoder timing, panel must allow it */ - assert_panel_unlocked(dev_priv, pipe); - I915_WRITE(TRANS_HTOTAL(pipe), I915_READ(HTOTAL(pipe))); - I915_WRITE(TRANS_HBLANK(pipe), I915_READ(HBLANK(pipe))); - I915_WRITE(TRANS_HSYNC(pipe), I915_READ(HSYNC(pipe))); - - I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe))); - I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); - I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); - I915_WRITE(TRANS_VSYNCSHIFT(pipe), I915_READ(VSYNCSHIFT(pipe))); - - intel_fdi_normal_train(crtc); - - /* For PCH DP, enable TRANS_DP_CTL */ - if (HAS_PCH_CPT(dev) && - (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { - u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5; - reg = TRANS_DP_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(TRANS_DP_PORT_SEL_MASK | - TRANS_DP_SYNC_MASK | - TRANS_DP_BPC_MASK); - temp |= (TRANS_DP_OUTPUT_ENABLE | - TRANS_DP_ENH_FRAMING); - temp |= bpc << 9; /* same format but at 11:9 */ - - if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) - temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; - if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC) - temp |= TRANS_DP_VSYNC_ACTIVE_HIGH; - - switch (intel_trans_dp_port_sel(crtc)) { - case PCH_DP_B: - temp |= TRANS_DP_PORT_SEL_B; - break; - case PCH_DP_C: - temp |= TRANS_DP_PORT_SEL_C; - break; - case PCH_DP_D: - temp |= TRANS_DP_PORT_SEL_D; - break; - default: - DRM_DEBUG_KMS("Wrong PCH DP port return. Guess port B\n"); - temp |= TRANS_DP_PORT_SEL_B; - break; - } - - I915_WRITE(reg, temp); - } - - intel_enable_transcoder(dev_priv, pipe); -} - -void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int dslreg = PIPEDSL(pipe), tc2reg = TRANS_CHICKEN2(pipe); - u32 temp; - - temp = I915_READ(dslreg); - udelay(500); - if (wait_for(I915_READ(dslreg) != temp, 5)) { - /* Without this, mode sets may fail silently on FDI */ - I915_WRITE(tc2reg, TRANS_AUTOTRAIN_GEN_STALL_DIS); - udelay(250); - I915_WRITE(tc2reg, 0); - if (wait_for(I915_READ(dslreg) != temp, 5)) - DRM_ERROR("mode set failed: pipe %d stuck\n", pipe); - } -} - -static void ironlake_crtc_enable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - u32 temp; - bool is_pch_port; - - if (intel_crtc->active) - return; - - intel_crtc->active = true; - intel_update_watermarks(dev); - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - temp = I915_READ(PCH_LVDS); - if ((temp & LVDS_PORT_EN) == 0) - I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); - } - - is_pch_port = intel_crtc_driving_pch(crtc); - - if (is_pch_port) - ironlake_fdi_pll_enable(crtc); - else - ironlake_fdi_disable(crtc); - - /* Enable panel fitting for LVDS */ - if (dev_priv->pch_pf_size && - (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || HAS_eDP)) { - /* Force use of hard-coded filter coefficients - * as some pre-programmed values are broken, - * e.g. x201. - */ - I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3); - I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos); - I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); - } - - /* - * On ILK+ LUT must be loaded before the pipe is running but with - * clocks enabled - */ - intel_crtc_load_lut(crtc); - - intel_enable_pipe(dev_priv, pipe, is_pch_port); - intel_enable_plane(dev_priv, plane, pipe); - - if (is_pch_port) - ironlake_pch_enable(crtc); - - mutex_lock(&dev->struct_mutex); - intel_update_fbc(dev); - mutex_unlock(&dev->struct_mutex); - - intel_crtc_update_cursor(crtc, true); -} - -static void ironlake_crtc_disable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - u32 reg, temp; - - if (!intel_crtc->active) - return; - - intel_crtc_wait_for_pending_flips(crtc); - drm_vblank_off(dev, pipe); - intel_crtc_update_cursor(crtc, false); - - intel_disable_plane(dev_priv, plane, pipe); - - if (dev_priv->cfb_plane == plane) - intel_disable_fbc(dev); - - intel_disable_pipe(dev_priv, pipe); - - /* Disable PF */ - I915_WRITE(PF_CTL(pipe), 0); - I915_WRITE(PF_WIN_SZ(pipe), 0); - - ironlake_fdi_disable(crtc); - - /* This is a horrible layering violation; we should be doing this in - * the connector/encoder ->prepare instead, but we don't always have - * enough information there about the config to know whether it will - * actually be necessary or just cause undesired flicker. - */ - intel_disable_pch_ports(dev_priv, pipe); - - intel_disable_transcoder(dev_priv, pipe); - - if (HAS_PCH_CPT(dev)) { - /* disable TRANS_DP_CTL */ - reg = TRANS_DP_CTL(pipe); - temp = I915_READ(reg); - temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK); - temp |= TRANS_DP_PORT_SEL_NONE; - I915_WRITE(reg, temp); - - /* disable DPLL_SEL */ - temp = I915_READ(PCH_DPLL_SEL); - switch (pipe) { - case 0: - temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL); - break; - case 1: - temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); - break; - case 2: - /* C shares PLL A or B */ - temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL); - break; - default: - BUG(); /* wtf */ - } - I915_WRITE(PCH_DPLL_SEL, temp); - } - - /* disable PCH DPLL */ - if (!intel_crtc->no_pll) - intel_disable_pch_pll(dev_priv, pipe); - - /* Switch from PCDclk to Rawclk */ - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - I915_WRITE(reg, temp & ~FDI_PCDCLK); - - /* Disable CPU FDI TX PLL */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - I915_WRITE(reg, temp & ~FDI_TX_PLL_ENABLE); - - POSTING_READ(reg); - udelay(100); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - I915_WRITE(reg, temp & ~FDI_RX_PLL_ENABLE); - - /* Wait for the clocks to turn off. */ - POSTING_READ(reg); - udelay(100); - - intel_crtc->active = false; - intel_update_watermarks(dev); - - mutex_lock(&dev->struct_mutex); - intel_update_fbc(dev); - intel_clear_scanline_wait(dev); - mutex_unlock(&dev->struct_mutex); -} - -static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); - ironlake_crtc_enable(crtc); - break; - - case DRM_MODE_DPMS_OFF: - DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); - ironlake_crtc_disable(crtc); - break; - } -} - -static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) -{ - if (!enable && intel_crtc->overlay) { - struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - mutex_lock(&dev->struct_mutex); - dev_priv->mm.interruptible = false; - (void) intel_overlay_switch_off(intel_crtc->overlay); - dev_priv->mm.interruptible = true; - mutex_unlock(&dev->struct_mutex); - } - - /* Let userspace switch the overlay on again. In most cases userspace - * has to recompute where to put it anyway. - */ -} - -static void i9xx_crtc_enable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - - if (intel_crtc->active) - return; - - intel_crtc->active = true; - intel_update_watermarks(dev); - - intel_enable_pll(dev_priv, pipe); - intel_enable_pipe(dev_priv, pipe, false); - intel_enable_plane(dev_priv, plane, pipe); - - intel_crtc_load_lut(crtc); - intel_update_fbc(dev); - - /* Give the overlay scaler a chance to enable if it's on this pipe */ - intel_crtc_dpms_overlay(intel_crtc, true); - intel_crtc_update_cursor(crtc, true); -} - -static void i9xx_crtc_disable(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - - if (!intel_crtc->active) - return; - - /* Give the overlay scaler a chance to disable if it's on this pipe */ - intel_crtc_wait_for_pending_flips(crtc); - drm_vblank_off(dev, pipe); - intel_crtc_dpms_overlay(intel_crtc, false); - intel_crtc_update_cursor(crtc, false); - - if (dev_priv->cfb_plane == plane) - intel_disable_fbc(dev); - - intel_disable_plane(dev_priv, plane, pipe); - intel_disable_pipe(dev_priv, pipe); - intel_disable_pll(dev_priv, pipe); - - intel_crtc->active = false; - intel_update_fbc(dev); - intel_update_watermarks(dev); - intel_clear_scanline_wait(dev); -} - -static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - /* XXX: When our outputs are all unaware of DPMS modes other than off - * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. - */ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - i9xx_crtc_enable(crtc); - break; - case DRM_MODE_DPMS_OFF: - i9xx_crtc_disable(crtc); - break; - } -} - -/** - * Sets the power management mode of the pipe and plane. - */ -static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - bool enabled; - - if (intel_crtc->dpms_mode == mode) - return; - - intel_crtc->dpms_mode = mode; - - dev_priv->display.dpms(crtc, mode); - - if (!dev->primary->master) - return; - - master_priv = dev->primary->master->driver_priv; - if (!master_priv->sarea_priv) - return; - - enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; - - switch (pipe) { - case 0: - master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0; - master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0; - break; - case 1: - master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0; - master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0; - break; - default: - DRM_ERROR("Can't update pipe %c in SAREA\n", pipe_name(pipe)); - break; - } -} - -static void intel_crtc_disable(struct drm_crtc *crtc) -{ - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - struct drm_device *dev = crtc->dev; - - /* Flush any pending WAITs before we disable the pipe. Note that - * we need to drop the struct_mutex in order to acquire it again - * during the lowlevel dpms routines around a couple of the - * operations. It does not look trivial nor desirable to move - * that locking higher. So instead we leave a window for the - * submission of further commands on the fb before we can actually - * disable it. This race with userspace exists anyway, and we can - * only rely on the pipe being disabled by userspace after it - * receives the hotplug notification and has flushed any pending - * batches. - */ - if (crtc->fb) { - mutex_lock(&dev->struct_mutex); - intel_finish_fb(crtc->fb); - mutex_unlock(&dev->struct_mutex); - } - - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); - assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); - assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); - - if (crtc->fb) { - mutex_lock(&dev->struct_mutex); - intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); - mutex_unlock(&dev->struct_mutex); - } -} - -/* Prepare for a mode set. - * - * Note we could be a lot smarter here. We need to figure out which outputs - * will be enabled, which disabled (in short, how the config will changes) - * and perform the minimum necessary steps to accomplish that, e.g. updating - * watermarks, FBC configuration, making sure PLLs are programmed correctly, - * panel fitting is in the proper state, etc. - */ -static void i9xx_crtc_prepare(struct drm_crtc *crtc) -{ - i9xx_crtc_disable(crtc); -} - -static void i9xx_crtc_commit(struct drm_crtc *crtc) -{ - i9xx_crtc_enable(crtc); -} - -static void ironlake_crtc_prepare(struct drm_crtc *crtc) -{ - ironlake_crtc_disable(crtc); -} - -static void ironlake_crtc_commit(struct drm_crtc *crtc) -{ - ironlake_crtc_enable(crtc); -} - -void intel_encoder_prepare(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - /* lvds has its own version of prepare see intel_lvds_prepare */ - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); -} - -void intel_encoder_commit(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - struct drm_device *dev = encoder->dev; - struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->base.crtc); - - /* lvds has its own version of commit see intel_lvds_commit */ - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); - - if (HAS_PCH_CPT(dev)) - intel_cpt_verify_modeset(dev, intel_crtc->pipe); -} - -void intel_encoder_destroy(struct drm_encoder *encoder) -{ - struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - - drm_encoder_cleanup(encoder); - kfree(intel_encoder); -} - -static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = crtc->dev; - - if (HAS_PCH_SPLIT(dev)) { - /* FDI link clock is fixed at 2.7G */ - if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) - return false; - } - - /* All interlaced capable intel hw wants timings in frames. Note though - * that intel_lvds_mode_fixup does some funny tricks with the crtc - * timings, so we need to be careful not to clobber these.*/ - if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) - drm_mode_set_crtcinfo(adjusted_mode, 0); - - return true; -} - -static int i945_get_display_clock_speed(struct drm_device *dev) -{ - return 400000; -} - -static int i915_get_display_clock_speed(struct drm_device *dev) -{ - return 333000; -} - -static int i9xx_misc_get_display_clock_speed(struct drm_device *dev) -{ - return 200000; -} - -static int i915gm_get_display_clock_speed(struct drm_device *dev) -{ - u16 gcfgc = 0; - - pci_read_config_word(dev->pdev, GCFGC, &gcfgc); - - if (gcfgc & GC_LOW_FREQUENCY_ENABLE) - return 133000; - else { - switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { - case GC_DISPLAY_CLOCK_333_MHZ: - return 333000; - default: - case GC_DISPLAY_CLOCK_190_200_MHZ: - return 190000; - } - } -} - -static int i865_get_display_clock_speed(struct drm_device *dev) -{ - return 266000; -} - -static int i855_get_display_clock_speed(struct drm_device *dev) -{ - u16 hpllcc = 0; - /* Assume that the hardware is in the high speed state. This - * should be the default. - */ - switch (hpllcc & GC_CLOCK_CONTROL_MASK) { - case GC_CLOCK_133_200: - case GC_CLOCK_100_200: - return 200000; - case GC_CLOCK_166_250: - return 250000; - case GC_CLOCK_100_133: - return 133000; - } - - /* Shouldn't happen */ - return 0; -} - -static int i830_get_display_clock_speed(struct drm_device *dev) -{ - return 133000; -} - -struct fdi_m_n { - u32 tu; - u32 gmch_m; - u32 gmch_n; - u32 link_m; - u32 link_n; -}; - -static void -fdi_reduce_ratio(u32 *num, u32 *den) -{ - while (*num > 0xffffff || *den > 0xffffff) { - *num >>= 1; - *den >>= 1; - } -} - -static void -ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, - int link_clock, struct fdi_m_n *m_n) -{ - m_n->tu = 64; /* default size */ - - /* BUG_ON(pixel_clock > INT_MAX / 36); */ - m_n->gmch_m = bits_per_pixel * pixel_clock; - m_n->gmch_n = link_clock * nlanes * 8; - fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); - - m_n->link_m = pixel_clock; - m_n->link_n = link_clock; - fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); -} - - -struct intel_watermark_params { - unsigned long fifo_size; - unsigned long max_wm; - unsigned long default_wm; - unsigned long guard_size; - unsigned long cacheline_size; -}; - -/* Pineview has different values for various configs */ -static const struct intel_watermark_params pineview_display_wm = { - PINEVIEW_DISPLAY_FIFO, - PINEVIEW_MAX_WM, - PINEVIEW_DFT_WM, - PINEVIEW_GUARD_WM, - PINEVIEW_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params pineview_display_hplloff_wm = { - PINEVIEW_DISPLAY_FIFO, - PINEVIEW_MAX_WM, - PINEVIEW_DFT_HPLLOFF_WM, - PINEVIEW_GUARD_WM, - PINEVIEW_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params pineview_cursor_wm = { - PINEVIEW_CURSOR_FIFO, - PINEVIEW_CURSOR_MAX_WM, - PINEVIEW_CURSOR_DFT_WM, - PINEVIEW_CURSOR_GUARD_WM, - PINEVIEW_FIFO_LINE_SIZE, -}; -static const struct intel_watermark_params pineview_cursor_hplloff_wm = { - PINEVIEW_CURSOR_FIFO, - PINEVIEW_CURSOR_MAX_WM, - PINEVIEW_CURSOR_DFT_WM, - PINEVIEW_CURSOR_GUARD_WM, - PINEVIEW_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params g4x_wm_info = { - G4X_FIFO_SIZE, - G4X_MAX_WM, - G4X_MAX_WM, - 2, - G4X_FIFO_LINE_SIZE, -}; -static const struct intel_watermark_params g4x_cursor_wm_info = { - I965_CURSOR_FIFO, - I965_CURSOR_MAX_WM, - I965_CURSOR_DFT_WM, - 2, - G4X_FIFO_LINE_SIZE, -}; -static const struct intel_watermark_params i965_cursor_wm_info = { - I965_CURSOR_FIFO, - I965_CURSOR_MAX_WM, - I965_CURSOR_DFT_WM, - 2, - I915_FIFO_LINE_SIZE, -}; -static const struct intel_watermark_params i945_wm_info = { - I945_FIFO_SIZE, - I915_MAX_WM, - 1, - 2, - I915_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params i915_wm_info = { - I915_FIFO_SIZE, - I915_MAX_WM, - 1, - 2, - I915_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params i855_wm_info = { - I855GM_FIFO_SIZE, - I915_MAX_WM, - 1, - 2, - I830_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params i830_wm_info = { - I830_FIFO_SIZE, - I915_MAX_WM, - 1, - 2, - I830_FIFO_LINE_SIZE -}; - -static const struct intel_watermark_params ironlake_display_wm_info = { - ILK_DISPLAY_FIFO, - ILK_DISPLAY_MAXWM, - ILK_DISPLAY_DFTWM, - 2, - ILK_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params ironlake_cursor_wm_info = { - ILK_CURSOR_FIFO, - ILK_CURSOR_MAXWM, - ILK_CURSOR_DFTWM, - 2, - ILK_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params ironlake_display_srwm_info = { - ILK_DISPLAY_SR_FIFO, - ILK_DISPLAY_MAX_SRWM, - ILK_DISPLAY_DFT_SRWM, - 2, - ILK_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params ironlake_cursor_srwm_info = { - ILK_CURSOR_SR_FIFO, - ILK_CURSOR_MAX_SRWM, - ILK_CURSOR_DFT_SRWM, - 2, - ILK_FIFO_LINE_SIZE -}; - -static const struct intel_watermark_params sandybridge_display_wm_info = { - SNB_DISPLAY_FIFO, - SNB_DISPLAY_MAXWM, - SNB_DISPLAY_DFTWM, - 2, - SNB_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params sandybridge_cursor_wm_info = { - SNB_CURSOR_FIFO, - SNB_CURSOR_MAXWM, - SNB_CURSOR_DFTWM, - 2, - SNB_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params sandybridge_display_srwm_info = { - SNB_DISPLAY_SR_FIFO, - SNB_DISPLAY_MAX_SRWM, - SNB_DISPLAY_DFT_SRWM, - 2, - SNB_FIFO_LINE_SIZE -}; -static const struct intel_watermark_params sandybridge_cursor_srwm_info = { - SNB_CURSOR_SR_FIFO, - SNB_CURSOR_MAX_SRWM, - SNB_CURSOR_DFT_SRWM, - 2, - SNB_FIFO_LINE_SIZE -}; - - -/** - * intel_calculate_wm - calculate watermark level - * @clock_in_khz: pixel clock - * @wm: chip FIFO params - * @pixel_size: display pixel size - * @latency_ns: memory latency for the platform - * - * Calculate the watermark level (the level at which the display plane will - * start fetching from memory again). Each chip has a different display - * FIFO size and allocation, so the caller needs to figure that out and pass - * in the correct intel_watermark_params structure. - * - * As the pixel clock runs, the FIFO will be drained at a rate that depends - * on the pixel size. When it reaches the watermark level, it'll start - * fetching FIFO line sized based chunks from memory until the FIFO fills - * past the watermark point. If the FIFO drains completely, a FIFO underrun - * will occur, and a display engine hang could result. - */ -static unsigned long intel_calculate_wm(unsigned long clock_in_khz, - const struct intel_watermark_params *wm, - int fifo_size, - int pixel_size, - unsigned long latency_ns) -{ - long entries_required, wm_size; - - /* - * Note: we need to make sure we don't overflow for various clock & - * latency values. - * clocks go from a few thousand to several hundred thousand. - * latency is usually a few thousand - */ - entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / - 1000; - entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size); - - DRM_DEBUG_KMS("FIFO entries required for mode: %ld\n", entries_required); - - wm_size = fifo_size - (entries_required + wm->guard_size); - - DRM_DEBUG_KMS("FIFO watermark level: %ld\n", wm_size); - - /* Don't promote wm_size to unsigned... */ - if (wm_size > (long)wm->max_wm) - wm_size = wm->max_wm; - if (wm_size <= 0) - wm_size = wm->default_wm; - return wm_size; -} - -struct cxsr_latency { - int is_desktop; - int is_ddr3; - unsigned long fsb_freq; - unsigned long mem_freq; - unsigned long display_sr; - unsigned long display_hpll_disable; - unsigned long cursor_sr; - unsigned long cursor_hpll_disable; -}; - -static const struct cxsr_latency cxsr_latency_table[] = { - {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ - {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ - {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ - {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ - {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ - - {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ - {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ - {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ - {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ - {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ - - {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ - {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ - {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ - {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ - {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ - - {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ - {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ - {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ - {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ - {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ - - {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ - {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ - {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ - {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ - {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ - - {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ - {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ - {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ - {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ - {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ -}; - -static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, - int is_ddr3, - int fsb, - int mem) -{ - const struct cxsr_latency *latency; - int i; - - if (fsb == 0 || mem == 0) - return NULL; - - for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { - latency = &cxsr_latency_table[i]; - if (is_desktop == latency->is_desktop && - is_ddr3 == latency->is_ddr3 && - fsb == latency->fsb_freq && mem == latency->mem_freq) - return latency; - } - - DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); - - return NULL; -} - -static void pineview_disable_cxsr(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* deactivate cxsr */ - I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); -} - -/* - * Latency for FIFO fetches is dependent on several factors: - * - memory configuration (speed, channels) - * - chipset - * - current MCH state - * It can be fairly high in some situations, so here we assume a fairly - * pessimal value. It's a tradeoff between extra memory fetches (if we - * set this value too high, the FIFO will fetch frequently to stay full) - * and power consumption (set it too low to save power and we might see - * FIFO underruns and display "flicker"). - * - * A value of 5us seems to be a good balance; safe for very low end - * platforms but not overly aggressive on lower latency configs. - */ -static const int latency_ns = 5000; - -static int i9xx_get_fifo_size(struct drm_device *dev, int plane) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dsparb = I915_READ(DSPARB); - int size; - - size = dsparb & 0x7f; - if (plane) - size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; - - DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, - plane ? "B" : "A", size); - - return size; -} - -static int i85x_get_fifo_size(struct drm_device *dev, int plane) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dsparb = I915_READ(DSPARB); - int size; - - size = dsparb & 0x1ff; - if (plane) - size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; - size >>= 1; /* Convert to cachelines */ - - DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, - plane ? "B" : "A", size); - - return size; -} - -static int i845_get_fifo_size(struct drm_device *dev, int plane) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dsparb = I915_READ(DSPARB); - int size; - - size = dsparb & 0x7f; - size >>= 2; /* Convert to cachelines */ - - DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, - plane ? "B" : "A", - size); - - return size; -} - -static int i830_get_fifo_size(struct drm_device *dev, int plane) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dsparb = I915_READ(DSPARB); - int size; - - size = dsparb & 0x7f; - size >>= 1; /* Convert to cachelines */ - - DRM_DEBUG_KMS("FIFO size - (0x%08x) %s: %d\n", dsparb, - plane ? "B" : "A", size); - - return size; -} - -static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) -{ - struct drm_crtc *crtc, *enabled = NULL; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (crtc->enabled && crtc->fb) { - if (enabled) - return NULL; - enabled = crtc; - } - } - - return enabled; -} - -static void pineview_update_wm(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - const struct cxsr_latency *latency; - u32 reg; - unsigned long wm; - - latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, - dev_priv->fsb_freq, dev_priv->mem_freq); - if (!latency) { - DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); - pineview_disable_cxsr(dev); - return; - } - - crtc = single_enabled_crtc(dev); - if (crtc) { - int clock = crtc->mode.clock; - int pixel_size = crtc->fb->bits_per_pixel / 8; - - /* Display SR */ - wm = intel_calculate_wm(clock, &pineview_display_wm, - pineview_display_wm.fifo_size, - pixel_size, latency->display_sr); - reg = I915_READ(DSPFW1); - reg &= ~DSPFW_SR_MASK; - reg |= wm << DSPFW_SR_SHIFT; - I915_WRITE(DSPFW1, reg); - DRM_DEBUG_KMS("DSPFW1 register is %x\n", reg); - - /* cursor SR */ - wm = intel_calculate_wm(clock, &pineview_cursor_wm, - pineview_display_wm.fifo_size, - pixel_size, latency->cursor_sr); - reg = I915_READ(DSPFW3); - reg &= ~DSPFW_CURSOR_SR_MASK; - reg |= (wm & 0x3f) << DSPFW_CURSOR_SR_SHIFT; - I915_WRITE(DSPFW3, reg); - - /* Display HPLL off SR */ - wm = intel_calculate_wm(clock, &pineview_display_hplloff_wm, - pineview_display_hplloff_wm.fifo_size, - pixel_size, latency->display_hpll_disable); - reg = I915_READ(DSPFW3); - reg &= ~DSPFW_HPLL_SR_MASK; - reg |= wm & DSPFW_HPLL_SR_MASK; - I915_WRITE(DSPFW3, reg); - - /* cursor HPLL off SR */ - wm = intel_calculate_wm(clock, &pineview_cursor_hplloff_wm, - pineview_display_hplloff_wm.fifo_size, - pixel_size, latency->cursor_hpll_disable); - reg = I915_READ(DSPFW3); - reg &= ~DSPFW_HPLL_CURSOR_MASK; - reg |= (wm & 0x3f) << DSPFW_HPLL_CURSOR_SHIFT; - I915_WRITE(DSPFW3, reg); - DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); - - /* activate cxsr */ - I915_WRITE(DSPFW3, - I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); - DRM_DEBUG_KMS("Self-refresh is enabled\n"); - } else { - pineview_disable_cxsr(dev); - DRM_DEBUG_KMS("Self-refresh is disabled\n"); - } -} - -static bool g4x_compute_wm0(struct drm_device *dev, - int plane, - const struct intel_watermark_params *display, - int display_latency_ns, - const struct intel_watermark_params *cursor, - int cursor_latency_ns, - int *plane_wm, - int *cursor_wm) -{ - struct drm_crtc *crtc; - int htotal, hdisplay, clock, pixel_size; - int line_time_us, line_count; - int entries, tlb_miss; - - crtc = intel_get_crtc_for_plane(dev, plane); - if (crtc->fb == NULL || !crtc->enabled) { - *cursor_wm = cursor->guard_size; - *plane_wm = display->guard_size; - return false; - } - - htotal = crtc->mode.htotal; - hdisplay = crtc->mode.hdisplay; - clock = crtc->mode.clock; - pixel_size = crtc->fb->bits_per_pixel / 8; - - /* Use the small buffer method to calculate plane watermark */ - entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; - tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8; - if (tlb_miss > 0) - entries += tlb_miss; - entries = DIV_ROUND_UP(entries, display->cacheline_size); - *plane_wm = entries + display->guard_size; - if (*plane_wm > (int)display->max_wm) - *plane_wm = display->max_wm; - - /* Use the large buffer method to calculate cursor watermark */ - line_time_us = ((htotal * 1000) / clock); - line_count = (cursor_latency_ns / line_time_us + 1000) / 1000; - entries = line_count * 64 * pixel_size; - tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8; - if (tlb_miss > 0) - entries += tlb_miss; - entries = DIV_ROUND_UP(entries, cursor->cacheline_size); - *cursor_wm = entries + cursor->guard_size; - if (*cursor_wm > (int)cursor->max_wm) - *cursor_wm = (int)cursor->max_wm; - - return true; -} - -/* - * Check the wm result. - * - * If any calculated watermark values is larger than the maximum value that - * can be programmed into the associated watermark register, that watermark - * must be disabled. - */ -static bool g4x_check_srwm(struct drm_device *dev, - int display_wm, int cursor_wm, - const struct intel_watermark_params *display, - const struct intel_watermark_params *cursor) -{ - DRM_DEBUG_KMS("SR watermark: display plane %d, cursor %d\n", - display_wm, cursor_wm); - - if (display_wm > display->max_wm) { - DRM_DEBUG_KMS("display watermark is too large(%d/%ld), disabling\n", - display_wm, display->max_wm); - return false; - } - - if (cursor_wm > cursor->max_wm) { - DRM_DEBUG_KMS("cursor watermark is too large(%d/%ld), disabling\n", - cursor_wm, cursor->max_wm); - return false; - } - - if (!(display_wm || cursor_wm)) { - DRM_DEBUG_KMS("SR latency is 0, disabling\n"); - return false; - } - - return true; -} - -static bool g4x_compute_srwm(struct drm_device *dev, - int plane, - int latency_ns, - const struct intel_watermark_params *display, - const struct intel_watermark_params *cursor, - int *display_wm, int *cursor_wm) -{ - struct drm_crtc *crtc; - int hdisplay, htotal, pixel_size, clock; - unsigned long line_time_us; - int line_count, line_size; - int small, large; - int entries; - - if (!latency_ns) { - *display_wm = *cursor_wm = 0; - return false; - } - - crtc = intel_get_crtc_for_plane(dev, plane); - hdisplay = crtc->mode.hdisplay; - htotal = crtc->mode.htotal; - clock = crtc->mode.clock; - pixel_size = crtc->fb->bits_per_pixel / 8; - - line_time_us = (htotal * 1000) / clock; - line_count = (latency_ns / line_time_us + 1000) / 1000; - line_size = hdisplay * pixel_size; - - /* Use the minimum of the small and large buffer method for primary */ - small = ((clock * pixel_size / 1000) * latency_ns) / 1000; - large = line_count * line_size; - - entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); - *display_wm = entries + display->guard_size; - - /* calculate the self-refresh watermark for display cursor */ - entries = line_count * pixel_size * 64; - entries = DIV_ROUND_UP(entries, cursor->cacheline_size); - *cursor_wm = entries + cursor->guard_size; - - return g4x_check_srwm(dev, - *display_wm, *cursor_wm, - display, cursor); -} - -#define single_plane_enabled(mask) is_power_of_2(mask) - -static void g4x_update_wm(struct drm_device *dev) -{ - static const int sr_latency_ns = 12000; - struct drm_i915_private *dev_priv = dev->dev_private; - int planea_wm, planeb_wm, cursora_wm, cursorb_wm; - int plane_sr, cursor_sr; - unsigned int enabled = 0; - - if (g4x_compute_wm0(dev, 0, - &g4x_wm_info, latency_ns, - &g4x_cursor_wm_info, latency_ns, - &planea_wm, &cursora_wm)) - enabled |= 1; - - if (g4x_compute_wm0(dev, 1, - &g4x_wm_info, latency_ns, - &g4x_cursor_wm_info, latency_ns, - &planeb_wm, &cursorb_wm)) - enabled |= 2; - - plane_sr = cursor_sr = 0; - if (single_plane_enabled(enabled) && - g4x_compute_srwm(dev, ffs(enabled) - 1, - sr_latency_ns, - &g4x_wm_info, - &g4x_cursor_wm_info, - &plane_sr, &cursor_sr)) - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); - else - I915_WRITE(FW_BLC_SELF, - I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN); - - DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", - planea_wm, cursora_wm, - planeb_wm, cursorb_wm, - plane_sr, cursor_sr); - - I915_WRITE(DSPFW1, - (plane_sr << DSPFW_SR_SHIFT) | - (cursorb_wm << DSPFW_CURSORB_SHIFT) | - (planeb_wm << DSPFW_PLANEB_SHIFT) | - planea_wm); - I915_WRITE(DSPFW2, - (I915_READ(DSPFW2) & DSPFW_CURSORA_MASK) | - (cursora_wm << DSPFW_CURSORA_SHIFT)); - /* HPLL off in SR has some issues on G4x... disable it */ - I915_WRITE(DSPFW3, - (I915_READ(DSPFW3) & ~DSPFW_HPLL_SR_EN) | - (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); -} - -static void i965_update_wm(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - int srwm = 1; - int cursor_sr = 16; - - /* Calc sr entries for one plane configs */ - crtc = single_enabled_crtc(dev); - if (crtc) { - /* self-refresh has much higher latency */ - static const int sr_latency_ns = 12000; - int clock = crtc->mode.clock; - int htotal = crtc->mode.htotal; - int hdisplay = crtc->mode.hdisplay; - int pixel_size = crtc->fb->bits_per_pixel / 8; - unsigned long line_time_us; - int entries; - - line_time_us = ((htotal * 1000) / clock); - - /* Use ns/us then divide to preserve precision */ - entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * - pixel_size * hdisplay; - entries = DIV_ROUND_UP(entries, I915_FIFO_LINE_SIZE); - srwm = I965_FIFO_SIZE - entries; - if (srwm < 0) - srwm = 1; - srwm &= 0x1ff; - DRM_DEBUG_KMS("self-refresh entries: %d, wm: %d\n", - entries, srwm); - - entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * - pixel_size * 64; - entries = DIV_ROUND_UP(entries, - i965_cursor_wm_info.cacheline_size); - cursor_sr = i965_cursor_wm_info.fifo_size - - (entries + i965_cursor_wm_info.guard_size); - - if (cursor_sr > i965_cursor_wm_info.max_wm) - cursor_sr = i965_cursor_wm_info.max_wm; - - DRM_DEBUG_KMS("self-refresh watermark: display plane %d " - "cursor %d\n", srwm, cursor_sr); - - if (IS_CRESTLINE(dev)) - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); - } else { - /* Turn off self refresh if both pipes are enabled */ - if (IS_CRESTLINE(dev)) - I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) - & ~FW_BLC_SELF_EN); - } - - DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", - srwm); - - /* 965 has limitations... */ - I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | - (8 << 16) | (8 << 8) | (8 << 0)); - I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); - /* update cursor SR watermark */ - I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); -} - -static void i9xx_update_wm(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - const struct intel_watermark_params *wm_info; - uint32_t fwater_lo; - uint32_t fwater_hi; - int cwm, srwm = 1; - int fifo_size; - int planea_wm, planeb_wm; - struct drm_crtc *crtc, *enabled = NULL; - - if (IS_I945GM(dev)) - wm_info = &i945_wm_info; - else if (!IS_GEN2(dev)) - wm_info = &i915_wm_info; - else - wm_info = &i855_wm_info; - - fifo_size = dev_priv->display.get_fifo_size(dev, 0); - crtc = intel_get_crtc_for_plane(dev, 0); - if (crtc->enabled && crtc->fb) { - planea_wm = intel_calculate_wm(crtc->mode.clock, - wm_info, fifo_size, - crtc->fb->bits_per_pixel / 8, - latency_ns); - enabled = crtc; - } else - planea_wm = fifo_size - wm_info->guard_size; - - fifo_size = dev_priv->display.get_fifo_size(dev, 1); - crtc = intel_get_crtc_for_plane(dev, 1); - if (crtc->enabled && crtc->fb) { - planeb_wm = intel_calculate_wm(crtc->mode.clock, - wm_info, fifo_size, - crtc->fb->bits_per_pixel / 8, - latency_ns); - if (enabled == NULL) - enabled = crtc; - else - enabled = NULL; - } else - planeb_wm = fifo_size - wm_info->guard_size; - - DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); - - /* - * Overlay gets an aggressive default since video jitter is bad. - */ - cwm = 2; - - /* Play safe and disable self-refresh before adjusting watermarks. */ - if (IS_I945G(dev) || IS_I945GM(dev)) - I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | 0); - else if (IS_I915GM(dev)) - I915_WRITE(INSTPM, I915_READ(INSTPM) & ~INSTPM_SELF_EN); - - /* Calc sr entries for one plane configs */ - if (HAS_FW_BLC(dev) && enabled) { - /* self-refresh has much higher latency */ - static const int sr_latency_ns = 6000; - int clock = enabled->mode.clock; - int htotal = enabled->mode.htotal; - int hdisplay = enabled->mode.hdisplay; - int pixel_size = enabled->fb->bits_per_pixel / 8; - unsigned long line_time_us; - int entries; - - line_time_us = (htotal * 1000) / clock; - - /* Use ns/us then divide to preserve precision */ - entries = (((sr_latency_ns / line_time_us) + 1000) / 1000) * - pixel_size * hdisplay; - entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); - DRM_DEBUG_KMS("self-refresh entries: %d\n", entries); - srwm = wm_info->fifo_size - entries; - if (srwm < 0) - srwm = 1; - - if (IS_I945G(dev) || IS_I945GM(dev)) - I915_WRITE(FW_BLC_SELF, - FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); - else if (IS_I915GM(dev)) - I915_WRITE(FW_BLC_SELF, srwm & 0x3f); - } - - DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", - planea_wm, planeb_wm, cwm, srwm); - - fwater_lo = ((planeb_wm & 0x3f) << 16) | (planea_wm & 0x3f); - fwater_hi = (cwm & 0x1f); - - /* Set request length to 8 cachelines per fetch */ - fwater_lo = fwater_lo | (1 << 24) | (1 << 8); - fwater_hi = fwater_hi | (1 << 8); - - I915_WRITE(FW_BLC, fwater_lo); - I915_WRITE(FW_BLC2, fwater_hi); - - if (HAS_FW_BLC(dev)) { - if (enabled) { - if (IS_I945G(dev) || IS_I945GM(dev)) - I915_WRITE(FW_BLC_SELF, - FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); - else if (IS_I915GM(dev)) - I915_WRITE(INSTPM, I915_READ(INSTPM) | INSTPM_SELF_EN); - DRM_DEBUG_KMS("memory self refresh enabled\n"); - } else - DRM_DEBUG_KMS("memory self refresh disabled\n"); - } -} - -static void i830_update_wm(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - uint32_t fwater_lo; - int planea_wm; - - crtc = single_enabled_crtc(dev); - if (crtc == NULL) - return; - - planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info, - dev_priv->display.get_fifo_size(dev, 0), - crtc->fb->bits_per_pixel / 8, - latency_ns); - fwater_lo = I915_READ(FW_BLC) & ~0xfff; - fwater_lo |= (3<<8) | planea_wm; - - DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm); - - I915_WRITE(FW_BLC, fwater_lo); -} - -#define ILK_LP0_PLANE_LATENCY 700 -#define ILK_LP0_CURSOR_LATENCY 1300 - -/* - * Check the wm result. - * - * If any calculated watermark values is larger than the maximum value that - * can be programmed into the associated watermark register, that watermark - * must be disabled. - */ -static bool ironlake_check_srwm(struct drm_device *dev, int level, - int fbc_wm, int display_wm, int cursor_wm, - const struct intel_watermark_params *display, - const struct intel_watermark_params *cursor) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," - " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); - - if (fbc_wm > SNB_FBC_MAX_SRWM) { - DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", - fbc_wm, SNB_FBC_MAX_SRWM, level); - - /* fbc has it's own way to disable FBC WM */ - I915_WRITE(DISP_ARB_CTL, - I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); - return false; - } - - if (display_wm > display->max_wm) { - DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", - display_wm, SNB_DISPLAY_MAX_SRWM, level); - return false; - } - - if (cursor_wm > cursor->max_wm) { - DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", - cursor_wm, SNB_CURSOR_MAX_SRWM, level); - return false; - } - - if (!(fbc_wm || display_wm || cursor_wm)) { - DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); - return false; - } - - return true; -} - -/* - * Compute watermark values of WM[1-3], - */ -static bool ironlake_compute_srwm(struct drm_device *dev, int level, int plane, - int latency_ns, - const struct intel_watermark_params *display, - const struct intel_watermark_params *cursor, - int *fbc_wm, int *display_wm, int *cursor_wm) -{ - struct drm_crtc *crtc; - unsigned long line_time_us; - int hdisplay, htotal, pixel_size, clock; - int line_count, line_size; - int small, large; - int entries; - - if (!latency_ns) { - *fbc_wm = *display_wm = *cursor_wm = 0; - return false; - } - - crtc = intel_get_crtc_for_plane(dev, plane); - hdisplay = crtc->mode.hdisplay; - htotal = crtc->mode.htotal; - clock = crtc->mode.clock; - pixel_size = crtc->fb->bits_per_pixel / 8; - - line_time_us = (htotal * 1000) / clock; - line_count = (latency_ns / line_time_us + 1000) / 1000; - line_size = hdisplay * pixel_size; - - /* Use the minimum of the small and large buffer method for primary */ - small = ((clock * pixel_size / 1000) * latency_ns) / 1000; - large = line_count * line_size; - - entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); - *display_wm = entries + display->guard_size; - - /* - * Spec says: - * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 - */ - *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; - - /* calculate the self-refresh watermark for display cursor */ - entries = line_count * pixel_size * 64; - entries = DIV_ROUND_UP(entries, cursor->cacheline_size); - *cursor_wm = entries + cursor->guard_size; - - return ironlake_check_srwm(dev, level, - *fbc_wm, *display_wm, *cursor_wm, - display, cursor); -} - -static void ironlake_update_wm(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int fbc_wm, plane_wm, cursor_wm; - unsigned int enabled; - - enabled = 0; - if (g4x_compute_wm0(dev, 0, - &ironlake_display_wm_info, - ILK_LP0_PLANE_LATENCY, - &ironlake_cursor_wm_info, - ILK_LP0_CURSOR_LATENCY, - &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEA_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); - DRM_DEBUG_KMS("FIFO watermarks For pipe A -" - " plane %d, " "cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 1; - } - - if (g4x_compute_wm0(dev, 1, - &ironlake_display_wm_info, - ILK_LP0_PLANE_LATENCY, - &ironlake_cursor_wm_info, - ILK_LP0_CURSOR_LATENCY, - &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEB_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); - DRM_DEBUG_KMS("FIFO watermarks For pipe B -" - " plane %d, cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 2; - } - - /* - * Calculate and update the self-refresh watermark only when one - * display plane is used. - */ - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - if (!single_plane_enabled(enabled)) - return; - enabled = ffs(enabled) - 1; - - /* WM1 */ - if (!ironlake_compute_srwm(dev, 1, enabled, - ILK_READ_WM1_LATENCY() * 500, - &ironlake_display_srwm_info, - &ironlake_cursor_srwm_info, - &fbc_wm, &plane_wm, &cursor_wm)) - return; - - I915_WRITE(WM1_LP_ILK, - WM1_LP_SR_EN | - (ILK_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | - (fbc_wm << WM1_LP_FBC_SHIFT) | - (plane_wm << WM1_LP_SR_SHIFT) | - cursor_wm); - - /* WM2 */ - if (!ironlake_compute_srwm(dev, 2, enabled, - ILK_READ_WM2_LATENCY() * 500, - &ironlake_display_srwm_info, - &ironlake_cursor_srwm_info, - &fbc_wm, &plane_wm, &cursor_wm)) - return; - - I915_WRITE(WM2_LP_ILK, - WM2_LP_EN | - (ILK_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | - (fbc_wm << WM1_LP_FBC_SHIFT) | - (plane_wm << WM1_LP_SR_SHIFT) | - cursor_wm); - - /* - * WM3 is unsupported on ILK, probably because we don't have latency - * data for that power state - */ -} - -void sandybridge_update_wm(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ - u32 val; - int fbc_wm, plane_wm, cursor_wm; - unsigned int enabled; - - enabled = 0; - if (g4x_compute_wm0(dev, 0, - &sandybridge_display_wm_info, latency, - &sandybridge_cursor_wm_info, latency, - &plane_wm, &cursor_wm)) { - val = I915_READ(WM0_PIPEA_ILK); - val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); - I915_WRITE(WM0_PIPEA_ILK, val | - ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); - DRM_DEBUG_KMS("FIFO watermarks For pipe A -" - " plane %d, " "cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 1; - } - - if (g4x_compute_wm0(dev, 1, - &sandybridge_display_wm_info, latency, - &sandybridge_cursor_wm_info, latency, - &plane_wm, &cursor_wm)) { - val = I915_READ(WM0_PIPEB_ILK); - val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); - I915_WRITE(WM0_PIPEB_ILK, val | - ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); - DRM_DEBUG_KMS("FIFO watermarks For pipe B -" - " plane %d, cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 2; - } - - /* IVB has 3 pipes */ - if (IS_IVYBRIDGE(dev) && - g4x_compute_wm0(dev, 2, - &sandybridge_display_wm_info, latency, - &sandybridge_cursor_wm_info, latency, - &plane_wm, &cursor_wm)) { - val = I915_READ(WM0_PIPEC_IVB); - val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); - I915_WRITE(WM0_PIPEC_IVB, val | - ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); - DRM_DEBUG_KMS("FIFO watermarks For pipe C -" - " plane %d, cursor: %d\n", - plane_wm, cursor_wm); - enabled |= 3; - } - - /* - * Calculate and update the self-refresh watermark only when one - * display plane is used. - * - * SNB support 3 levels of watermark. - * - * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, - * and disabled in the descending order - * - */ - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - if (!single_plane_enabled(enabled) || - dev_priv->sprite_scaling_enabled) - return; - enabled = ffs(enabled) - 1; - - /* WM1 */ - if (!ironlake_compute_srwm(dev, 1, enabled, - SNB_READ_WM1_LATENCY() * 500, - &sandybridge_display_srwm_info, - &sandybridge_cursor_srwm_info, - &fbc_wm, &plane_wm, &cursor_wm)) - return; - - I915_WRITE(WM1_LP_ILK, - WM1_LP_SR_EN | - (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | - (fbc_wm << WM1_LP_FBC_SHIFT) | - (plane_wm << WM1_LP_SR_SHIFT) | - cursor_wm); - - /* WM2 */ - if (!ironlake_compute_srwm(dev, 2, enabled, - SNB_READ_WM2_LATENCY() * 500, - &sandybridge_display_srwm_info, - &sandybridge_cursor_srwm_info, - &fbc_wm, &plane_wm, &cursor_wm)) - return; - - I915_WRITE(WM2_LP_ILK, - WM2_LP_EN | - (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | - (fbc_wm << WM1_LP_FBC_SHIFT) | - (plane_wm << WM1_LP_SR_SHIFT) | - cursor_wm); - - /* WM3 */ - if (!ironlake_compute_srwm(dev, 3, enabled, - SNB_READ_WM3_LATENCY() * 500, - &sandybridge_display_srwm_info, - &sandybridge_cursor_srwm_info, - &fbc_wm, &plane_wm, &cursor_wm)) - return; - - I915_WRITE(WM3_LP_ILK, - WM3_LP_EN | - (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | - (fbc_wm << WM1_LP_FBC_SHIFT) | - (plane_wm << WM1_LP_SR_SHIFT) | - cursor_wm); -} - -static bool -sandybridge_compute_sprite_wm(struct drm_device *dev, int plane, - uint32_t sprite_width, int pixel_size, - const struct intel_watermark_params *display, - int display_latency_ns, int *sprite_wm) -{ - struct drm_crtc *crtc; - int clock; - int entries, tlb_miss; - - crtc = intel_get_crtc_for_plane(dev, plane); - if (crtc->fb == NULL || !crtc->enabled) { - *sprite_wm = display->guard_size; - return false; - } - - clock = crtc->mode.clock; - - /* Use the small buffer method to calculate the sprite watermark */ - entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000; - tlb_miss = display->fifo_size*display->cacheline_size - - sprite_width * 8; - if (tlb_miss > 0) - entries += tlb_miss; - entries = DIV_ROUND_UP(entries, display->cacheline_size); - *sprite_wm = entries + display->guard_size; - if (*sprite_wm > (int)display->max_wm) - *sprite_wm = display->max_wm; - - return true; -} - -static bool -sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, - uint32_t sprite_width, int pixel_size, - const struct intel_watermark_params *display, - int latency_ns, int *sprite_wm) -{ - struct drm_crtc *crtc; - unsigned long line_time_us; - int clock; - int line_count, line_size; - int small, large; - int entries; - - if (!latency_ns) { - *sprite_wm = 0; - return false; - } - - crtc = intel_get_crtc_for_plane(dev, plane); - clock = crtc->mode.clock; - if (!clock) { - *sprite_wm = 0; - return false; - } - - line_time_us = (sprite_width * 1000) / clock; - if (!line_time_us) { - *sprite_wm = 0; - return false; - } - - line_count = (latency_ns / line_time_us + 1000) / 1000; - line_size = sprite_width * pixel_size; - - /* Use the minimum of the small and large buffer method for primary */ - small = ((clock * pixel_size / 1000) * latency_ns) / 1000; - large = line_count * line_size; - - entries = DIV_ROUND_UP(min(small, large), display->cacheline_size); - *sprite_wm = entries + display->guard_size; - - return *sprite_wm > 0x3ff ? false : true; -} - -static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, - uint32_t sprite_width, int pixel_size) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ - u32 val; - int sprite_wm, reg; - int ret; - - switch (pipe) { - case 0: - reg = WM0_PIPEA_ILK; - break; - case 1: - reg = WM0_PIPEB_ILK; - break; - case 2: - reg = WM0_PIPEC_IVB; - break; - default: - return; /* bad pipe */ - } - - ret = sandybridge_compute_sprite_wm(dev, pipe, sprite_width, pixel_size, - &sandybridge_display_wm_info, - latency, &sprite_wm); - if (!ret) { - DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n", - pipe); - return; - } - - val = I915_READ(reg); - val &= ~WM0_PIPE_SPRITE_MASK; - I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); - DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); - - - ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, - pixel_size, - &sandybridge_display_srwm_info, - SNB_READ_WM1_LATENCY() * 500, - &sprite_wm); - if (!ret) { - DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n", - pipe); - return; - } - I915_WRITE(WM1S_LP_ILK, sprite_wm); - - /* Only IVB has two more LP watermarks for sprite */ - if (!IS_IVYBRIDGE(dev)) - return; - - ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, - pixel_size, - &sandybridge_display_srwm_info, - SNB_READ_WM2_LATENCY() * 500, - &sprite_wm); - if (!ret) { - DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n", - pipe); - return; - } - I915_WRITE(WM2S_LP_IVB, sprite_wm); - - ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width, - pixel_size, - &sandybridge_display_srwm_info, - SNB_READ_WM3_LATENCY() * 500, - &sprite_wm); - if (!ret) { - DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n", - pipe); - return; - } - I915_WRITE(WM3S_LP_IVB, sprite_wm); -} - -/** - * intel_update_watermarks - update FIFO watermark values based on current modes - * - * Calculate watermark values for the various WM regs based on current mode - * and plane configuration. - * - * There are several cases to deal with here: - * - normal (i.e. non-self-refresh) - * - self-refresh (SR) mode - * - lines are large relative to FIFO size (buffer can hold up to 2) - * - lines are small relative to FIFO size (buffer can hold more than 2 - * lines), so need to account for TLB latency - * - * The normal calculation is: - * watermark = dotclock * bytes per pixel * latency - * where latency is platform & configuration dependent (we assume pessimal - * values here). - * - * The SR calculation is: - * watermark = (trunc(latency/line time)+1) * surface width * - * bytes per pixel - * where - * line time = htotal / dotclock - * surface width = hdisplay for normal plane and 64 for cursor - * and latency is assumed to be high, as above. - * - * The final value programmed to the register should always be rounded up, - * and include an extra 2 entries to account for clock crossings. - * - * We don't use the sprite, so we can ignore that. And on Crestline we have - * to set the non-SR watermarks to 8. - */ -static void intel_update_watermarks(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->display.update_wm) - dev_priv->display.update_wm(dev); -} - -void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, - uint32_t sprite_width, int pixel_size) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->display.update_sprite_wm) - dev_priv->display.update_sprite_wm(dev, pipe, sprite_width, - pixel_size); -} - -static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) -{ - if (i915_panel_use_ssc >= 0) - return i915_panel_use_ssc != 0; - return dev_priv->lvds_use_ssc - && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); -} - -/** - * intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send - * @crtc: CRTC structure - * @mode: requested mode - * - * A pipe may be connected to one or more outputs. Based on the depth of the - * attached framebuffer, choose a good color depth to use on the pipe. - * - * If possible, match the pipe depth to the fb depth. In some cases, this - * isn't ideal, because the connected output supports a lesser or restricted - * set of depths. Resolve that here: - * LVDS typically supports only 6bpc, so clamp down in that case - * HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc - * Displays may support a restricted set as well, check EDID and clamp as - * appropriate. - * DP may want to dither down to 6bpc to fit larger modes - * - * RETURNS: - * Dithering requirement (i.e. false if display bpc and pipe bpc match, - * true if they don't match). - */ -static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, - unsigned int *pipe_bpp, - struct drm_display_mode *mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_encoder *encoder; - struct drm_connector *connector; - unsigned int display_bpc = UINT_MAX, bpc; - - /* Walk the encoders & connectors on this crtc, get min bpc */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - - if (encoder->crtc != crtc) - continue; - - if (intel_encoder->type == INTEL_OUTPUT_LVDS) { - unsigned int lvds_bpc; - - if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) == - LVDS_A3_POWER_UP) - lvds_bpc = 8; - else - lvds_bpc = 6; - - if (lvds_bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); - display_bpc = lvds_bpc; - } - continue; - } - - if (intel_encoder->type == INTEL_OUTPUT_EDP) { - /* Use VBT settings if we have an eDP panel */ - unsigned int edp_bpc = dev_priv->edp.bpp / 3; - - if (edp_bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); - display_bpc = edp_bpc; - } - continue; - } - - /* Not one of the known troublemakers, check the EDID */ - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { - if (connector->encoder != encoder) - continue; - - /* Don't use an invalid EDID bpc value */ - if (connector->display_info.bpc && - connector->display_info.bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); - display_bpc = connector->display_info.bpc; - } - } - - /* - * HDMI is either 12 or 8, so if the display lets 10bpc sneak - * through, clamp it down. (Note: >12bpc will be caught below.) - */ - if (intel_encoder->type == INTEL_OUTPUT_HDMI) { - if (display_bpc > 8 && display_bpc < 12) { - DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); - display_bpc = 12; - } else { - DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); - display_bpc = 8; - } - } - } - - if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { - DRM_DEBUG_KMS("Dithering DP to 6bpc\n"); - display_bpc = 6; - } - - /* - * We could just drive the pipe at the highest bpc all the time and - * enable dithering as needed, but that costs bandwidth. So choose - * the minimum value that expresses the full color range of the fb but - * also stays within the max display bpc discovered above. - */ - - switch (crtc->fb->depth) { - case 8: - bpc = 8; /* since we go through a colormap */ - break; - case 15: - case 16: - bpc = 6; /* min is 18bpp */ - break; - case 24: - bpc = 8; - break; - case 30: - bpc = 10; - break; - case 48: - bpc = 12; - break; - default: - DRM_DEBUG("unsupported depth, assuming 24 bits\n"); - bpc = min((unsigned int)8, display_bpc); - break; - } - - display_bpc = min(display_bpc, bpc); - - DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n", - bpc, display_bpc); - - *pipe_bpp = display_bpc * 3; - - return display_bpc != bpc; -} - -static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int refclk; - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - intel_panel_use_ssc(dev_priv) && num_connectors < 2) { - refclk = dev_priv->lvds_ssc_freq * 1000; - DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", - refclk / 1000); - } else if (!IS_GEN2(dev)) { - refclk = 96000; - } else { - refclk = 48000; - } - - return refclk; -} - -static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, - intel_clock_t *clock) -{ - /* SDVO TV has fixed PLL values depend on its clock range, - this mirrors vbios setting. */ - if (adjusted_mode->clock >= 100000 - && adjusted_mode->clock < 140500) { - clock->p1 = 2; - clock->p2 = 10; - clock->n = 3; - clock->m1 = 16; - clock->m2 = 8; - } else if (adjusted_mode->clock >= 140500 - && adjusted_mode->clock <= 200000) { - clock->p1 = 1; - clock->p2 = 10; - clock->n = 6; - clock->m1 = 12; - clock->m2 = 8; - } -} - -static void i9xx_update_pll_dividers(struct drm_crtc *crtc, - intel_clock_t *clock, - intel_clock_t *reduced_clock) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 fp, fp2 = 0; - - if (IS_PINEVIEW(dev)) { - fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; - if (reduced_clock) - fp2 = (1 << reduced_clock->n) << 16 | - reduced_clock->m1 << 8 | reduced_clock->m2; - } else { - fp = clock->n << 16 | clock->m1 << 8 | clock->m2; - if (reduced_clock) - fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 | - reduced_clock->m2; - } - - I915_WRITE(FP0(pipe), fp); - - intel_crtc->lowfreq_avail = false; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && - reduced_clock && i915_powersave) { - I915_WRITE(FP1(pipe), fp2); - intel_crtc->lowfreq_avail = true; - } else { - I915_WRITE(FP1(pipe), fp); - } -} - -static int i9xx_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - int refclk, num_connectors = 0; - intel_clock_t clock, reduced_clock; - u32 dpll, dspcntr, pipeconf, vsyncshift; - bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; - bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - const intel_limit_t *limit; - int ret; - u32 temp; - u32 lvds_sync = 0; - - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { - if (encoder->base.crtc != crtc) - continue; - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - case INTEL_OUTPUT_HDMI: - is_sdvo = true; - if (encoder->needs_tv_clock) - is_tv = true; - break; - case INTEL_OUTPUT_DVO: - is_dvo = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; - case INTEL_OUTPUT_DISPLAYPORT: - is_dp = true; - break; - } - - num_connectors++; - } - - refclk = i9xx_get_refclk(crtc, num_connectors); - - /* - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ - limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, - &clock); - if (!ok) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; - } - - /* Ensure that the cursor is valid for the new mode before changing... */ - intel_crtc_update_cursor(crtc, true); - - if (is_lvds && dev_priv->lvds_downclock_avail) { - /* - * Ensure we match the reduced clock's P to the target clock. - * If the clocks don't match, we can't switch the display clock - * by using the FP0/FP1. In such case we will disable the LVDS - * downclock feature. - */ - has_reduced_clock = limit->find_pll(limit, crtc, - dev_priv->lvds_downclock, - refclk, - &clock, - &reduced_clock); - } - - if (is_sdvo && is_tv) - i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); - - i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ? - &reduced_clock : NULL); - - dpll = DPLL_VGA_MODE_DIS; - - if (!IS_GEN2(dev)) { - if (is_lvds) - dpll |= DPLLB_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - if (is_sdvo) { - int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); - if (pixel_multiplier > 1) { - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - } - dpll |= DPLL_DVO_HIGH_SPEED; - } - if (is_dp) - dpll |= DPLL_DVO_HIGH_SPEED; - - /* compute bitmask from p1 value */ - if (IS_PINEVIEW(dev)) - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; - else { - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - if (IS_G4X(dev) && has_reduced_clock) - dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - } - switch (clock.p2) { - case 5: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; - break; - case 7: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; - break; - case 10: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; - break; - case 14: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; - break; - } - if (INTEL_INFO(dev)->gen >= 4) - dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); - } else { - if (is_lvds) { - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - } else { - if (clock.p1 == 2) - dpll |= PLL_P1_DIVIDE_BY_TWO; - else - dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT; - if (clock.p2 == 4) - dpll |= PLL_P2_DIVIDE_BY_4; - } - } - - if (is_sdvo && is_tv) - dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (is_tv) - /* XXX: just matching BIOS for now */ - /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) - dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; - else - dpll |= PLL_REF_INPUT_DREFCLK; - - /* setup pipeconf */ - pipeconf = I915_READ(PIPECONF(pipe)); - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - if (pipe == 0 && INTEL_INFO(dev)->gen < 4) { - /* Enable pixel doubling when the dot clock is > 90% of the (display) - * core speed. - * - * XXX: No double-wide on 915GM pipe B. Is that the only reason for the - * pipe == 0 check? - */ - if (mode->clock > - dev_priv->display.get_display_clock_speed(dev) * 9 / 10) - pipeconf |= PIPECONF_DOUBLE_WIDE; - else - pipeconf &= ~PIPECONF_DOUBLE_WIDE; - } - - /* default to 8bpc */ - pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); - if (is_dp) { - if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { - pipeconf |= PIPECONF_BPP_6 | - PIPECONF_DITHER_EN | - PIPECONF_DITHER_TYPE_SP; - } - } - - dpll |= DPLL_VCO_ENABLE; - - DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - drm_mode_debug_printmodeline(mode); - - I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); - - POSTING_READ(DPLL(pipe)); - udelay(150); - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) { - temp = I915_READ(LVDS); - temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (pipe == 1) { - temp |= LVDS_PIPEB_SELECT; - } else { - temp &= ~LVDS_PIPEB_SELECT; - } - /* set the corresponsding LVDS_BORDER bit */ - temp |= dev_priv->lvds_border_bits; - /* Set the B0-B3 data pairs corresponding to whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more thoroughly into how - * panels behave in the two modes. - */ - /* set the dithering flag on LVDS as needed */ - if (INTEL_INFO(dev)->gen >= 4) { - if (dev_priv->lvds_dither) - temp |= LVDS_ENABLE_DITHER; - else - temp &= ~LVDS_ENABLE_DITHER; - } - if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) - lvds_sync |= LVDS_HSYNC_POLARITY; - if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) - lvds_sync |= LVDS_VSYNC_POLARITY; - if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) - != lvds_sync) { - char flags[2] = "-+"; - DRM_INFO("Changing LVDS panel from " - "(%chsync, %cvsync) to (%chsync, %cvsync)\n", - flags[!(temp & LVDS_HSYNC_POLARITY)], - flags[!(temp & LVDS_VSYNC_POLARITY)], - flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], - flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); - temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); - temp |= lvds_sync; - } - I915_WRITE(LVDS, temp); - } - - if (is_dp) { - intel_dp_set_m_n(crtc, mode, adjusted_mode); - } - - I915_WRITE(DPLL(pipe), dpll); - - /* Wait for the clocks to stabilize. */ - POSTING_READ(DPLL(pipe)); - udelay(150); - - if (INTEL_INFO(dev)->gen >= 4) { - temp = 0; - if (is_sdvo) { - temp = intel_mode_get_pixel_multiplier(adjusted_mode); - if (temp > 1) - temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; - else - temp = 0; - } - I915_WRITE(DPLL_MD(pipe), temp); - } else { - /* The pixel multiplier can only be updated once the - * DPLL is enabled and the clocks are stable. - * - * So write it again. - */ - I915_WRITE(DPLL(pipe), dpll); - } - - if (HAS_PIPE_CXSR(dev)) { - if (intel_crtc->lowfreq_avail) { - DRM_DEBUG_KMS("enabling CxSR downclocking\n"); - pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } else { - DRM_DEBUG_KMS("disabling CxSR downclocking\n"); - pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; - } - } - - pipeconf &= ~PIPECONF_INTERLACE_MASK; - if (!IS_GEN2(dev) && - adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { - pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; - /* the chip adds 2 halflines automatically */ - adjusted_mode->crtc_vtotal -= 1; - adjusted_mode->crtc_vblank_end -= 1; - vsyncshift = adjusted_mode->crtc_hsync_start - - adjusted_mode->crtc_htotal/2; - } else { - pipeconf |= PIPECONF_PROGRESSIVE; - vsyncshift = 0; - } - - if (!IS_GEN3(dev)) - I915_WRITE(VSYNCSHIFT(pipe), vsyncshift); - - I915_WRITE(HTOTAL(pipe), - (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - I915_WRITE(HBLANK(pipe), - (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - I915_WRITE(HSYNC(pipe), - (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - - I915_WRITE(VTOTAL(pipe), - (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - I915_WRITE(VBLANK(pipe), - (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - I915_WRITE(VSYNC(pipe), - (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - I915_WRITE(DSPSIZE(plane), - ((mode->vdisplay - 1) << 16) | - (mode->hdisplay - 1)); - I915_WRITE(DSPPOS(plane), 0); - I915_WRITE(PIPESRC(pipe), - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - - I915_WRITE(PIPECONF(pipe), pipeconf); - POSTING_READ(PIPECONF(pipe)); - intel_enable_pipe(dev_priv, pipe, false); - - intel_wait_for_vblank(dev, pipe); - - I915_WRITE(DSPCNTR(plane), dspcntr); - POSTING_READ(DSPCNTR(plane)); - intel_enable_plane(dev_priv, plane, pipe); - - ret = intel_pipe_set_base(crtc, x, y, old_fb); - - intel_update_watermarks(dev); - - return ret; -} - -/* - * Initialize reference clocks when the driver loads - */ -void ironlake_init_pch_refclk(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - u32 temp; - bool has_lvds = false; - bool has_cpu_edp = false; - bool has_pch_edp = false; - bool has_panel = false; - bool has_ck505 = false; - bool can_ssc = false; - - /* We need to take the global config into account */ - list_for_each_entry(encoder, &mode_config->encoder_list, - base.head) { - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - has_panel = true; - has_lvds = true; - break; - case INTEL_OUTPUT_EDP: - has_panel = true; - if (intel_encoder_is_pch_edp(&encoder->base)) - has_pch_edp = true; - else - has_cpu_edp = true; - break; - } - } - - if (HAS_PCH_IBX(dev)) { - has_ck505 = dev_priv->display_clock_mode; - can_ssc = has_ck505; - } else { - has_ck505 = false; - can_ssc = true; - } - - DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n", - has_panel, has_lvds, has_pch_edp, has_cpu_edp, - has_ck505); - - /* Ironlake: try to setup display ref clock before DPLL - * enabling. This is only under driver's control after - * PCH B stepping, previous chipset stepping should be - * ignoring this setting. - */ - temp = I915_READ(PCH_DREF_CONTROL); - /* Always enable nonspread source */ - temp &= ~DREF_NONSPREAD_SOURCE_MASK; - - if (has_ck505) - temp |= DREF_NONSPREAD_CK505_ENABLE; - else - temp |= DREF_NONSPREAD_SOURCE_ENABLE; - - if (has_panel) { - temp &= ~DREF_SSC_SOURCE_MASK; - temp |= DREF_SSC_SOURCE_ENABLE; - - /* SSC must be turned on before enabling the CPU output */ - if (intel_panel_use_ssc(dev_priv) && can_ssc) { - DRM_DEBUG_KMS("Using SSC on panel\n"); - temp |= DREF_SSC1_ENABLE; - } else - temp &= ~DREF_SSC1_ENABLE; - - /* Get SSC going before enabling the outputs */ - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - - temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - - /* Enable CPU source on CPU attached eDP */ - if (has_cpu_edp) { - if (intel_panel_use_ssc(dev_priv) && can_ssc) { - DRM_DEBUG_KMS("Using SSC on eDP\n"); - temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; - } - else - temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; - } else - temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; - - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - } else { - DRM_DEBUG_KMS("Disabling SSC entirely\n"); - - temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; - - /* Turn off CPU output */ - temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; - - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - - /* Turn off the SSC source */ - temp &= ~DREF_SSC_SOURCE_MASK; - temp |= DREF_SSC_SOURCE_DISABLE; - - /* Turn off SSC1 */ - temp &= ~ DREF_SSC1_ENABLE; - - I915_WRITE(PCH_DREF_CONTROL, temp); - POSTING_READ(PCH_DREF_CONTROL); - udelay(200); - } -} - -static int ironlake_get_refclk(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_encoder *encoder; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *edp_encoder = NULL; - int num_connectors = 0; - bool is_lvds = false; - - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { - if (encoder->base.crtc != crtc) - continue; - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_EDP: - edp_encoder = encoder; - break; - } - num_connectors++; - } - - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { - DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", - dev_priv->lvds_ssc_freq); - return dev_priv->lvds_ssc_freq * 1000; - } - - return 120000; -} - -static int ironlake_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - int refclk, num_connectors = 0; - intel_clock_t clock, reduced_clock; - u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; - bool ok, has_reduced_clock = false, is_sdvo = false; - bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; - struct intel_encoder *has_edp_encoder = NULL; - struct drm_mode_config *mode_config = &dev->mode_config; - struct intel_encoder *encoder; - const intel_limit_t *limit; - int ret; - struct fdi_m_n m_n = {0}; - u32 temp; - u32 lvds_sync = 0; - int target_clock, pixel_multiplier, lane, link_bw, factor; - unsigned int pipe_bpp; - bool dither; - - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { - if (encoder->base.crtc != crtc) - continue; - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - case INTEL_OUTPUT_HDMI: - is_sdvo = true; - if (encoder->needs_tv_clock) - is_tv = true; - break; - case INTEL_OUTPUT_TVOUT: - is_tv = true; - break; - case INTEL_OUTPUT_ANALOG: - is_crt = true; - break; - case INTEL_OUTPUT_DISPLAYPORT: - is_dp = true; - break; - case INTEL_OUTPUT_EDP: - has_edp_encoder = encoder; - break; - } - - num_connectors++; - } - - refclk = ironlake_get_refclk(crtc); - - /* - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ - limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, - &clock); - if (!ok) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); - return -EINVAL; - } - - /* Ensure that the cursor is valid for the new mode before changing... */ - intel_crtc_update_cursor(crtc, true); - - if (is_lvds && dev_priv->lvds_downclock_avail) { - /* - * Ensure we match the reduced clock's P to the target clock. - * If the clocks don't match, we can't switch the display clock - * by using the FP0/FP1. In such case we will disable the LVDS - * downclock feature. - */ - has_reduced_clock = limit->find_pll(limit, crtc, - dev_priv->lvds_downclock, - refclk, - &clock, - &reduced_clock); - } - /* SDVO TV has fixed PLL values depend on its clock range, - this mirrors vbios setting. */ - if (is_sdvo && is_tv) { - if (adjusted_mode->clock >= 100000 - && adjusted_mode->clock < 140500) { - clock.p1 = 2; - clock.p2 = 10; - clock.n = 3; - clock.m1 = 16; - clock.m2 = 8; - } else if (adjusted_mode->clock >= 140500 - && adjusted_mode->clock <= 200000) { - clock.p1 = 1; - clock.p2 = 10; - clock.n = 6; - clock.m1 = 12; - clock.m2 = 8; - } - } - - /* FDI link */ - pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); - lane = 0; - /* CPU eDP doesn't require FDI link, so just set DP M/N - according to current link config */ - if (has_edp_encoder && - !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - target_clock = mode->clock; - intel_edp_link_config(has_edp_encoder, - &lane, &link_bw); - } else { - /* [e]DP over FDI requires target mode clock - instead of link clock */ - if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) - target_clock = mode->clock; - else - target_clock = adjusted_mode->clock; - - /* FDI is a binary signal running at ~2.7GHz, encoding - * each output octet as 10 bits. The actual frequency - * is stored as a divider into a 100MHz clock, and the - * mode pixel clock is stored in units of 1KHz. - * Hence the bw of each lane in terms of the mode signal - * is: - */ - link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10; - } - - /* determine panel color depth */ - temp = I915_READ(PIPECONF(pipe)); - temp &= ~PIPE_BPC_MASK; - dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode); - switch (pipe_bpp) { - case 18: - temp |= PIPE_6BPC; - break; - case 24: - temp |= PIPE_8BPC; - break; - case 30: - temp |= PIPE_10BPC; - break; - case 36: - temp |= PIPE_12BPC; - break; - default: - WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n", - pipe_bpp); - temp |= PIPE_8BPC; - pipe_bpp = 24; - break; - } - - intel_crtc->bpp = pipe_bpp; - I915_WRITE(PIPECONF(pipe), temp); - - if (!lane) { - /* - * Account for spread spectrum to avoid - * oversubscribing the link. Max center spread - * is 2.5%; use 5% for safety's sake. - */ - u32 bps = target_clock * intel_crtc->bpp * 21 / 20; - lane = bps / (link_bw * 8) + 1; - } - - intel_crtc->fdi_lanes = lane; - - if (pixel_multiplier > 1) - link_bw *= pixel_multiplier; - ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, - &m_n); - - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - if (has_reduced_clock) - fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | - reduced_clock.m2; - - /* Enable autotuning of the PLL clock (if permissible) */ - factor = 21; - if (is_lvds) { - if ((intel_panel_use_ssc(dev_priv) && - dev_priv->lvds_ssc_freq == 100) || - (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) - factor = 25; - } else if (is_sdvo && is_tv) - factor = 20; - - if (clock.m < factor * clock.n) - fp |= FP_CB_TUNE; - - dpll = 0; - - if (is_lvds) - dpll |= DPLLB_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - if (is_sdvo) { - int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); - if (pixel_multiplier > 1) { - dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; - } - dpll |= DPLL_DVO_HIGH_SPEED; - } - if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) - dpll |= DPLL_DVO_HIGH_SPEED; - - /* compute bitmask from p1 value */ - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - /* also FPA1 */ - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - - switch (clock.p2) { - case 5: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; - break; - case 7: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; - break; - case 10: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; - break; - case 14: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; - break; - } - - if (is_sdvo && is_tv) - dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (is_tv) - /* XXX: just matching BIOS for now */ - /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) - dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; - else - dpll |= PLL_REF_INPUT_DREFCLK; - - /* setup pipeconf */ - pipeconf = I915_READ(PIPECONF(pipe)); - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); - drm_mode_debug_printmodeline(mode); - - /* PCH eDP needs FDI, but CPU eDP does not */ - if (!intel_crtc->no_pll) { - if (!has_edp_encoder || - intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - I915_WRITE(PCH_FP0(pipe), fp); - I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); - - POSTING_READ(PCH_DPLL(pipe)); - udelay(150); - } - } else { - if (dpll == (I915_READ(PCH_DPLL(0)) & 0x7fffffff) && - fp == I915_READ(PCH_FP0(0))) { - intel_crtc->use_pll_a = true; - DRM_DEBUG_KMS("using pipe a dpll\n"); - } else if (dpll == (I915_READ(PCH_DPLL(1)) & 0x7fffffff) && - fp == I915_READ(PCH_FP0(1))) { - intel_crtc->use_pll_a = false; - DRM_DEBUG_KMS("using pipe b dpll\n"); - } else { - DRM_DEBUG_KMS("no matching PLL configuration for pipe 2\n"); - return -EINVAL; - } - } - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) { - temp = I915_READ(PCH_LVDS); - temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (HAS_PCH_CPT(dev)) { - temp &= ~PORT_TRANS_SEL_MASK; - temp |= PORT_TRANS_SEL_CPT(pipe); - } else { - if (pipe == 1) - temp |= LVDS_PIPEB_SELECT; - else - temp &= ~LVDS_PIPEB_SELECT; - } - - /* set the corresponsding LVDS_BORDER bit */ - temp |= dev_priv->lvds_border_bits; - /* Set the B0-B3 data pairs corresponding to whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more thoroughly into how - * panels behave in the two modes. - */ - if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) - lvds_sync |= LVDS_HSYNC_POLARITY; - if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) - lvds_sync |= LVDS_VSYNC_POLARITY; - if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY)) - != lvds_sync) { - char flags[2] = "-+"; - DRM_INFO("Changing LVDS panel from " - "(%chsync, %cvsync) to (%chsync, %cvsync)\n", - flags[!(temp & LVDS_HSYNC_POLARITY)], - flags[!(temp & LVDS_VSYNC_POLARITY)], - flags[!(lvds_sync & LVDS_HSYNC_POLARITY)], - flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]); - temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); - temp |= lvds_sync; - } - I915_WRITE(PCH_LVDS, temp); - } - - pipeconf &= ~PIPECONF_DITHER_EN; - pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; - if ((is_lvds && dev_priv->lvds_dither) || dither) { - pipeconf |= PIPECONF_DITHER_EN; - pipeconf |= PIPECONF_DITHER_TYPE_SP; - } - if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - intel_dp_set_m_n(crtc, mode, adjusted_mode); - } else { - /* For non-DP output, clear any trans DP clock recovery setting.*/ - I915_WRITE(TRANSDATA_M1(pipe), 0); - I915_WRITE(TRANSDATA_N1(pipe), 0); - I915_WRITE(TRANSDPLINK_M1(pipe), 0); - I915_WRITE(TRANSDPLINK_N1(pipe), 0); - } - - if (!intel_crtc->no_pll && - (!has_edp_encoder || - intel_encoder_is_pch_edp(&has_edp_encoder->base))) { - I915_WRITE(PCH_DPLL(pipe), dpll); - - /* Wait for the clocks to stabilize. */ - POSTING_READ(PCH_DPLL(pipe)); - udelay(150); - - /* The pixel multiplier can only be updated once the - * DPLL is enabled and the clocks are stable. - * - * So write it again. - */ - I915_WRITE(PCH_DPLL(pipe), dpll); - } - - intel_crtc->lowfreq_avail = false; - if (!intel_crtc->no_pll) { - if (is_lvds && has_reduced_clock && i915_powersave) { - I915_WRITE(PCH_FP1(pipe), fp2); - intel_crtc->lowfreq_avail = true; - if (HAS_PIPE_CXSR(dev)) { - DRM_DEBUG_KMS("enabling CxSR downclocking\n"); - pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } - } else { - I915_WRITE(PCH_FP1(pipe), fp); - if (HAS_PIPE_CXSR(dev)) { - DRM_DEBUG_KMS("disabling CxSR downclocking\n"); - pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; - } - } - } - - pipeconf &= ~PIPECONF_INTERLACE_MASK; - if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { - pipeconf |= PIPECONF_INTERLACED_ILK; - /* the chip adds 2 halflines automatically */ - adjusted_mode->crtc_vtotal -= 1; - adjusted_mode->crtc_vblank_end -= 1; - I915_WRITE(VSYNCSHIFT(pipe), - adjusted_mode->crtc_hsync_start - - adjusted_mode->crtc_htotal/2); - } else { - pipeconf |= PIPECONF_PROGRESSIVE; - I915_WRITE(VSYNCSHIFT(pipe), 0); - } - - I915_WRITE(HTOTAL(pipe), - (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - I915_WRITE(HBLANK(pipe), - (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - I915_WRITE(HSYNC(pipe), - (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - - I915_WRITE(VTOTAL(pipe), - (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - I915_WRITE(VBLANK(pipe), - (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - I915_WRITE(VSYNC(pipe), - (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - - /* pipesrc controls the size that is scaled from, which should - * always be the user's requested size. - */ - I915_WRITE(PIPESRC(pipe), - ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - - I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m); - I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n); - I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m); - I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n); - - if (has_edp_encoder && - !intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - ironlake_set_pll_edp(crtc, adjusted_mode->clock); - } - - I915_WRITE(PIPECONF(pipe), pipeconf); - POSTING_READ(PIPECONF(pipe)); - - intel_wait_for_vblank(dev, pipe); - - I915_WRITE(DSPCNTR(plane), dspcntr); - POSTING_READ(DSPCNTR(plane)); - - ret = intel_pipe_set_base(crtc, x, y, old_fb); - - intel_update_watermarks(dev); - - return ret; -} - -static int intel_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int ret; - - drm_vblank_pre_modeset(dev, pipe); - - ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, - x, y, old_fb); - drm_vblank_post_modeset(dev, pipe); - - if (ret) - intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; - else - intel_crtc->dpms_mode = DRM_MODE_DPMS_ON; - - return ret; -} - -static bool intel_eld_uptodate(struct drm_connector *connector, - int reg_eldv, uint32_t bits_eldv, - int reg_elda, uint32_t bits_elda, - int reg_edid) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - uint8_t *eld = connector->eld; - uint32_t i; - - i = I915_READ(reg_eldv); - i &= bits_eldv; - - if (!eld[0]) - return !i; - - if (!i) - return false; - - i = I915_READ(reg_elda); - i &= ~bits_elda; - I915_WRITE(reg_elda, i); - - for (i = 0; i < eld[2]; i++) - if (I915_READ(reg_edid) != *((uint32_t *)eld + i)) - return false; - - return true; -} - -static void g4x_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - uint8_t *eld = connector->eld; - uint32_t eldv; - uint32_t len; - uint32_t i; - - i = I915_READ(G4X_AUD_VID_DID); - - if (i == INTEL_AUDIO_DEVBLC || i == INTEL_AUDIO_DEVCL) - eldv = G4X_ELDV_DEVCL_DEVBLC; - else - eldv = G4X_ELDV_DEVCTG; - - if (intel_eld_uptodate(connector, - G4X_AUD_CNTL_ST, eldv, - G4X_AUD_CNTL_ST, G4X_ELD_ADDR, - G4X_HDMIW_HDMIEDID)) - return; - - i = I915_READ(G4X_AUD_CNTL_ST); - i &= ~(eldv | G4X_ELD_ADDR); - len = (i >> 9) & 0x1f; /* ELD buffer size */ - I915_WRITE(G4X_AUD_CNTL_ST, i); - - if (!eld[0]) - return; - - len = min_t(uint8_t, eld[2], len); - DRM_DEBUG_DRIVER("ELD size %d\n", len); - for (i = 0; i < len; i++) - I915_WRITE(G4X_HDMIW_HDMIEDID, *((uint32_t *)eld + i)); - - i = I915_READ(G4X_AUD_CNTL_ST); - i |= eldv; - I915_WRITE(G4X_AUD_CNTL_ST, i); -} - -static void ironlake_write_eld(struct drm_connector *connector, - struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - uint8_t *eld = connector->eld; - uint32_t eldv; - uint32_t i; - int len; - int hdmiw_hdmiedid; - int aud_config; - int aud_cntl_st; - int aud_cntrl_st2; - - if (HAS_PCH_IBX(connector->dev)) { - hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A; - aud_config = IBX_AUD_CONFIG_A; - aud_cntl_st = IBX_AUD_CNTL_ST_A; - aud_cntrl_st2 = IBX_AUD_CNTL_ST2; - } else { - hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A; - aud_config = CPT_AUD_CONFIG_A; - aud_cntl_st = CPT_AUD_CNTL_ST_A; - aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; - } - - i = to_intel_crtc(crtc)->pipe; - hdmiw_hdmiedid += i * 0x100; - aud_cntl_st += i * 0x100; - aud_config += i * 0x100; - - DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i)); - - i = I915_READ(aud_cntl_st); - i = (i >> 29) & 0x3; /* DIP_Port_Select, 0x1 = PortB */ - if (!i) { - DRM_DEBUG_DRIVER("Audio directed to unknown port\n"); - /* operate blindly on all ports */ - eldv = IBX_ELD_VALIDB; - eldv |= IBX_ELD_VALIDB << 4; - eldv |= IBX_ELD_VALIDB << 8; - } else { - DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i); - eldv = IBX_ELD_VALIDB << ((i - 1) * 4); - } - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { - DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); - eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ - I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ - } else - I915_WRITE(aud_config, 0); - - if (intel_eld_uptodate(connector, - aud_cntrl_st2, eldv, - aud_cntl_st, IBX_ELD_ADDRESS, - hdmiw_hdmiedid)) - return; - - i = I915_READ(aud_cntrl_st2); - i &= ~eldv; - I915_WRITE(aud_cntrl_st2, i); - - if (!eld[0]) - return; - - i = I915_READ(aud_cntl_st); - i &= ~IBX_ELD_ADDRESS; - I915_WRITE(aud_cntl_st, i); - - len = min_t(uint8_t, eld[2], 21); /* 84 bytes of hw ELD buffer */ - DRM_DEBUG_DRIVER("ELD size %d\n", len); - for (i = 0; i < len; i++) - I915_WRITE(hdmiw_hdmiedid, *((uint32_t *)eld + i)); - - i = I915_READ(aud_cntrl_st2); - i |= eldv; - I915_WRITE(aud_cntrl_st2, i); -} - -void intel_write_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct drm_crtc *crtc = encoder->crtc; - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - connector = drm_select_eld(encoder, mode); - if (!connector) - return; - - DRM_DEBUG_DRIVER("ELD on [CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", - connector->base.id, - drm_get_connector_name(connector), - connector->encoder->base.id, - drm_get_encoder_name(connector->encoder)); - - connector->eld[6] = drm_av_sync_delay(connector, mode) / 2; - - if (dev_priv->display.write_eld) - dev_priv->display.write_eld(connector, crtc); -} - -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -void intel_crtc_load_lut(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int palreg = PALETTE(intel_crtc->pipe); - int i; - - /* The clocks have to be on to load the palette. */ - if (!crtc->enabled || !intel_crtc->active) - return; - - /* use legacy palette for Ironlake */ - if (HAS_PCH_SPLIT(dev)) - palreg = LGC_PALETTE(intel_crtc->pipe); - - for (i = 0; i < 256; i++) { - I915_WRITE(palreg + 4 * i, - (intel_crtc->lut_r[i] << 16) | - (intel_crtc->lut_g[i] << 8) | - intel_crtc->lut_b[i]); - } -} - -static void i845_update_cursor(struct drm_crtc *crtc, u32 base) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - bool visible = base != 0; - u32 cntl; - - if (intel_crtc->cursor_visible == visible) - return; - - cntl = I915_READ(_CURACNTR); - if (visible) { - /* On these chipsets we can only modify the base whilst - * the cursor is disabled. - */ - I915_WRITE(_CURABASE, base); - - cntl &= ~(CURSOR_FORMAT_MASK); - /* XXX width must be 64, stride 256 => 0x00 << 28 */ - cntl |= CURSOR_ENABLE | - CURSOR_GAMMA_ENABLE | - CURSOR_FORMAT_ARGB; - } else - cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); - I915_WRITE(_CURACNTR, cntl); - - intel_crtc->cursor_visible = visible; -} - -static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - bool visible = base != 0; - - if (intel_crtc->cursor_visible != visible) { - uint32_t cntl = I915_READ(CURCNTR(pipe)); - if (base) { - cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - cntl |= pipe << 28; /* Connect to correct pipe */ - } else { - cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); - cntl |= CURSOR_MODE_DISABLE; - } - I915_WRITE(CURCNTR(pipe), cntl); - - intel_crtc->cursor_visible = visible; - } - /* and commit changes on next vblank */ - I915_WRITE(CURBASE(pipe), base); -} - -static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - bool visible = base != 0; - - if (intel_crtc->cursor_visible != visible) { - uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); - if (base) { - cntl &= ~CURSOR_MODE; - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - } else { - cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); - cntl |= CURSOR_MODE_DISABLE; - } - I915_WRITE(CURCNTR_IVB(pipe), cntl); - - intel_crtc->cursor_visible = visible; - } - /* and commit changes on next vblank */ - I915_WRITE(CURBASE_IVB(pipe), base); -} - -/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ -static void intel_crtc_update_cursor(struct drm_crtc *crtc, - bool on) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int x = intel_crtc->cursor_x; - int y = intel_crtc->cursor_y; - u32 base, pos; - bool visible; - - pos = 0; - - if (on && crtc->enabled && crtc->fb) { - base = intel_crtc->cursor_addr; - if (x > (int) crtc->fb->width) - base = 0; - - if (y > (int) crtc->fb->height) - base = 0; - } else - base = 0; - - if (x < 0) { - if (x + intel_crtc->cursor_width < 0) - base = 0; - - pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; - x = -x; - } - pos |= x << CURSOR_X_SHIFT; - - if (y < 0) { - if (y + intel_crtc->cursor_height < 0) - base = 0; - - pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; - y = -y; - } - pos |= y << CURSOR_Y_SHIFT; - - visible = base != 0; - if (!visible && !intel_crtc->cursor_visible) - return; - - if (IS_IVYBRIDGE(dev)) { - I915_WRITE(CURPOS_IVB(pipe), pos); - ivb_update_cursor(crtc, base); - } else { - I915_WRITE(CURPOS(pipe), pos); - if (IS_845G(dev) || IS_I865G(dev)) - i845_update_cursor(crtc, base); - else - i9xx_update_cursor(crtc, base); - } - - if (visible) - intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); -} - -static int intel_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file, - uint32_t handle, - uint32_t width, uint32_t height) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_i915_gem_object *obj; - uint32_t addr; - int ret; - - DRM_DEBUG_KMS("\n"); - - /* if we want to turn off the cursor ignore width and height */ - if (!handle) { - DRM_DEBUG_KMS("cursor off\n"); - addr = 0; - obj = NULL; - mutex_lock(&dev->struct_mutex); - goto finish; - } - - /* Currently we only support 64x64 cursors */ - if (width != 64 || height != 64) { - DRM_ERROR("we currently only support 64x64 cursors\n"); - return -EINVAL; - } - - obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); - if (&obj->base == NULL) - return -ENOENT; - - if (obj->base.size < width * height * 4) { - DRM_ERROR("buffer is to small\n"); - ret = -ENOMEM; - goto fail; - } - - /* we only need to pin inside GTT if cursor is non-phy */ - mutex_lock(&dev->struct_mutex); - if (!dev_priv->info->cursor_needs_physical) { - if (obj->tiling_mode) { - DRM_ERROR("cursor cannot be tiled\n"); - ret = -EINVAL; - goto fail_locked; - } - - ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL); - if (ret) { - DRM_ERROR("failed to move cursor bo into the GTT\n"); - goto fail_locked; - } - - ret = i915_gem_object_put_fence(obj); - if (ret) { - DRM_ERROR("failed to release fence for cursor"); - goto fail_unpin; - } - - addr = obj->gtt_offset; - } else { - int align = IS_I830(dev) ? 16 * 1024 : 256; - ret = i915_gem_attach_phys_object(dev, obj, - (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, - align); - if (ret) { - DRM_ERROR("failed to attach phys object\n"); - goto fail_locked; - } - addr = obj->phys_obj->handle->busaddr; - } - - if (IS_GEN2(dev)) - I915_WRITE(CURSIZE, (height << 12) | width); - - finish: - if (intel_crtc->cursor_bo) { - if (dev_priv->info->cursor_needs_physical) { - if (intel_crtc->cursor_bo != obj) - i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); - } else - i915_gem_object_unpin(intel_crtc->cursor_bo); - drm_gem_object_unreference(&intel_crtc->cursor_bo->base); - } - - mutex_unlock(&dev->struct_mutex); - - intel_crtc->cursor_addr = addr; - intel_crtc->cursor_bo = obj; - intel_crtc->cursor_width = width; - intel_crtc->cursor_height = height; - - intel_crtc_update_cursor(crtc, true); - - return 0; -fail_unpin: - i915_gem_object_unpin(obj); -fail_locked: - mutex_unlock(&dev->struct_mutex); -fail: - drm_gem_object_unreference_unlocked(&obj->base); - return ret; -} - -static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - intel_crtc->cursor_x = x; - intel_crtc->cursor_y = y; - - intel_crtc_update_cursor(crtc, true); - - return 0; -} - -/** Sets the color ramps on behalf of RandR */ -void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - intel_crtc->lut_r[regno] = red >> 8; - intel_crtc->lut_g[regno] = green >> 8; - intel_crtc->lut_b[regno] = blue >> 8; -} - -void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - *red = intel_crtc->lut_r[regno] << 8; - *green = intel_crtc->lut_g[regno] << 8; - *blue = intel_crtc->lut_b[regno] << 8; -} - -static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, uint32_t start, uint32_t size) -{ - int end = (start + size > 256) ? 256 : start + size, i; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - for (i = start; i < end; i++) { - intel_crtc->lut_r[i] = red[i] >> 8; - intel_crtc->lut_g[i] = green[i] >> 8; - intel_crtc->lut_b[i] = blue[i] >> 8; - } - - intel_crtc_load_lut(crtc); -} - -/** - * Get a pipe with a simple mode set on it for doing load-based monitor - * detection. - * - * It will be up to the load-detect code to adjust the pipe as appropriate for - * its requirements. The pipe will be connected to no other encoders. - * - * Currently this code will only succeed if there is a pipe with no encoders - * configured for it. In the future, it could choose to temporarily disable - * some outputs to free up a pipe for its use. - * - * \return crtc, or NULL if no pipes are available. - */ - -/* VESA 640x480x72Hz mode to set on the pipe */ -static struct drm_display_mode load_detect_mode = { - DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664, - 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), -}; - -static struct drm_framebuffer * -intel_framebuffer_create(struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_i915_gem_object *obj) -{ - struct intel_framebuffer *intel_fb; - int ret; - - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); - if (!intel_fb) { - drm_gem_object_unreference_unlocked(&obj->base); - return ERR_PTR(-ENOMEM); - } - - ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); - if (ret) { - drm_gem_object_unreference_unlocked(&obj->base); - kfree(intel_fb); - return ERR_PTR(ret); - } - - return &intel_fb->base; -} - -static u32 -intel_framebuffer_pitch_for_width(int width, int bpp) -{ - u32 pitch = DIV_ROUND_UP(width * bpp, 8); - return ALIGN(pitch, 64); -} - -static u32 -intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp) -{ - u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp); - return ALIGN(pitch * mode->vdisplay, PAGE_SIZE); -} - -static struct drm_framebuffer * -intel_framebuffer_create_for_mode(struct drm_device *dev, - struct drm_display_mode *mode, - int depth, int bpp) -{ - struct drm_i915_gem_object *obj; - struct drm_mode_fb_cmd2 mode_cmd; - - obj = i915_gem_alloc_object(dev, - intel_framebuffer_size_for_mode(mode, bpp)); - if (obj == NULL) - return ERR_PTR(-ENOMEM); - - mode_cmd.width = mode->hdisplay; - mode_cmd.height = mode->vdisplay; - mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, - bpp); - mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); - - return intel_framebuffer_create(dev, &mode_cmd, obj); -} - -static struct drm_framebuffer * -mode_fits_in_fbdev(struct drm_device *dev, - struct drm_display_mode *mode) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - struct drm_framebuffer *fb; - - if (dev_priv->fbdev == NULL) - return NULL; - - obj = dev_priv->fbdev->ifb.obj; - if (obj == NULL) - return NULL; - - fb = &dev_priv->fbdev->ifb.base; - if (fb->pitches[0] < intel_framebuffer_pitch_for_width(mode->hdisplay, - fb->bits_per_pixel)) - return NULL; - - if (obj->base.size < mode->vdisplay * fb->pitches[0]) - return NULL; - - return fb; -} - -bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct intel_load_detect_pipe *old) -{ - struct intel_crtc *intel_crtc; - struct drm_crtc *possible_crtc; - struct drm_encoder *encoder = &intel_encoder->base; - struct drm_crtc *crtc = NULL; - struct drm_device *dev = encoder->dev; - struct drm_framebuffer *old_fb; - int i = -1; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", - connector->base.id, drm_get_connector_name(connector), - encoder->base.id, drm_get_encoder_name(encoder)); - - /* - * Algorithm gets a little messy: - * - * - if the connector already has an assigned crtc, use it (but make - * sure it's on first) - * - * - try to find the first unused crtc that can drive this connector, - * and use that if we find one - */ - - /* See if we already have a CRTC for this connector */ - if (encoder->crtc) { - crtc = encoder->crtc; - - intel_crtc = to_intel_crtc(crtc); - old->dpms_mode = intel_crtc->dpms_mode; - old->load_detect_temp = false; - - /* Make sure the crtc and connector are running */ - if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) { - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_crtc_helper_funcs *crtc_funcs; - - crtc_funcs = crtc->helper_private; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); - - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); - } - - return true; - } - - /* Find an unused one (if possible) */ - list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) { - i++; - if (!(encoder->possible_crtcs & (1 << i))) - continue; - if (!possible_crtc->enabled) { - crtc = possible_crtc; - break; - } - } - - /* - * If we didn't find an unused CRTC, don't use any. - */ - if (!crtc) { - DRM_DEBUG_KMS("no pipe available for load-detect\n"); - return false; - } - - encoder->crtc = crtc; - connector->encoder = encoder; - - intel_crtc = to_intel_crtc(crtc); - old->dpms_mode = intel_crtc->dpms_mode; - old->load_detect_temp = true; - old->release_fb = NULL; - - if (!mode) - mode = &load_detect_mode; - - old_fb = crtc->fb; - - /* We need a framebuffer large enough to accommodate all accesses - * that the plane may generate whilst we perform load detection. - * We can not rely on the fbcon either being present (we get called - * during its initialisation to detect all boot displays, or it may - * not even exist) or that it is large enough to satisfy the - * requested mode. - */ - crtc->fb = mode_fits_in_fbdev(dev, mode); - if (crtc->fb == NULL) { - DRM_DEBUG_KMS("creating tmp fb for load-detection\n"); - crtc->fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32); - old->release_fb = crtc->fb; - } else - DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); - if (IS_ERR(crtc->fb)) { - DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); - crtc->fb = old_fb; - return false; - } - - if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) { - DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); - if (old->release_fb) - old->release_fb->funcs->destroy(old->release_fb); - crtc->fb = old_fb; - return false; - } - - /* let the connector get through one full cycle before testing */ - intel_wait_for_vblank(dev, intel_crtc->pipe); - - return true; -} - -void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct intel_load_detect_pipe *old) -{ - struct drm_encoder *encoder = &intel_encoder->base; - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc = encoder->crtc; - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", - connector->base.id, drm_get_connector_name(connector), - encoder->base.id, drm_get_encoder_name(encoder)); - - if (old->load_detect_temp) { - connector->encoder = NULL; - drm_helper_disable_unused_functions(dev); - - if (old->release_fb) - old->release_fb->funcs->destroy(old->release_fb); - - return; - } - - /* Switch crtc and encoder back off if necessary */ - if (old->dpms_mode != DRM_MODE_DPMS_ON) { - encoder_funcs->dpms(encoder, old->dpms_mode); - crtc_funcs->dpms(crtc, old->dpms_mode); - } -} - -/* Returns the clock of the currently programmed mode of the given pipe. */ -static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 dpll = I915_READ(DPLL(pipe)); - u32 fp; - intel_clock_t clock; - - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = I915_READ(FP0(pipe)); - else - fp = I915_READ(FP1(pipe)); - - clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - if (IS_PINEVIEW(dev)) { - clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; - clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT; - } else { - clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; - clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; - } - - if (!IS_GEN2(dev)) { - if (IS_PINEVIEW(dev)) - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >> - DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW); - else - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - - switch (dpll & DPLL_MODE_MASK) { - case DPLLB_MODE_DAC_SERIAL: - clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? - 5 : 10; - break; - case DPLLB_MODE_LVDS: - clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? - 7 : 14; - break; - default: - DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed " - "mode\n", (int)(dpll & DPLL_MODE_MASK)); - return 0; - } - - /* XXX: Handle the 100Mhz refclk */ - intel_clock(dev, 96000, &clock); - } else { - bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); - - if (is_lvds) { - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - clock.p2 = 14; - - if ((dpll & PLL_REF_INPUT_MASK) == - PLLB_REF_INPUT_SPREADSPECTRUMIN) { - /* XXX: might not be 66MHz */ - intel_clock(dev, 66000, &clock); - } else - intel_clock(dev, 48000, &clock); - } else { - if (dpll & PLL_P1_DIVIDE_BY_TWO) - clock.p1 = 2; - else { - clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> - DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; - } - if (dpll & PLL_P2_DIVIDE_BY_4) - clock.p2 = 4; - else - clock.p2 = 2; - - intel_clock(dev, 48000, &clock); - } - } - - /* XXX: It would be nice to validate the clocks, but we can't reuse - * i830PllIsValid() because it relies on the xf86_config connector - * configuration being accurate, which it isn't necessarily. - */ - - return clock.dot; -} - -/** Returns the currently programmed mode of the given pipe. */ -struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - struct drm_display_mode *mode; - int htot = I915_READ(HTOTAL(pipe)); - int hsync = I915_READ(HSYNC(pipe)); - int vtot = I915_READ(VTOTAL(pipe)); - int vsync = I915_READ(VSYNC(pipe)); - - mode = kzalloc(sizeof(*mode), GFP_KERNEL); - if (!mode) - return NULL; - - mode->clock = intel_crtc_clock_get(dev, crtc); - mode->hdisplay = (htot & 0xffff) + 1; - mode->htotal = ((htot & 0xffff0000) >> 16) + 1; - mode->hsync_start = (hsync & 0xffff) + 1; - mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; - mode->vdisplay = (vtot & 0xffff) + 1; - mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->vsync_start = (vsync & 0xffff) + 1; - mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; - - drm_mode_set_name(mode); - drm_mode_set_crtcinfo(mode, 0); - - return mode; -} - -#define GPU_IDLE_TIMEOUT 500 /* ms */ - -/* When this timer fires, we've been idle for awhile */ -static void intel_gpu_idle_timer(unsigned long arg) -{ - struct drm_device *dev = (struct drm_device *)arg; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!list_empty(&dev_priv->mm.active_list)) { - /* Still processing requests, so just re-arm the timer. */ - mod_timer(&dev_priv->idle_timer, jiffies + - msecs_to_jiffies(GPU_IDLE_TIMEOUT)); - return; - } - - dev_priv->busy = false; - queue_work(dev_priv->wq, &dev_priv->idle_work); -} - -#define CRTC_IDLE_TIMEOUT 1000 /* ms */ - -static void intel_crtc_idle_timer(unsigned long arg) -{ - struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; - struct drm_crtc *crtc = &intel_crtc->base; - drm_i915_private_t *dev_priv = crtc->dev->dev_private; - struct intel_framebuffer *intel_fb; - - intel_fb = to_intel_framebuffer(crtc->fb); - if (intel_fb && intel_fb->obj->active) { - /* The framebuffer is still being accessed by the GPU. */ - mod_timer(&intel_crtc->idle_timer, jiffies + - msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); - return; - } - - intel_crtc->busy = false; - queue_work(dev_priv->wq, &dev_priv->idle_work); -} - -static void intel_increase_pllclock(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - int dpll_reg = DPLL(pipe); - int dpll; - - if (HAS_PCH_SPLIT(dev)) - return; - - if (!dev_priv->lvds_downclock_avail) - return; - - dpll = I915_READ(dpll_reg); - if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { - DRM_DEBUG_DRIVER("upclocking LVDS\n"); - - assert_panel_unlocked(dev_priv, pipe); - - dpll &= ~DISPLAY_RATE_SELECT_FPA1; - I915_WRITE(dpll_reg, dpll); - intel_wait_for_vblank(dev, pipe); - - dpll = I915_READ(dpll_reg); - if (dpll & DISPLAY_RATE_SELECT_FPA1) - DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); - } - - /* Schedule downclock */ - mod_timer(&intel_crtc->idle_timer, jiffies + - msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); -} - -static void intel_decrease_pllclock(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - if (HAS_PCH_SPLIT(dev)) - return; - - if (!dev_priv->lvds_downclock_avail) - return; - - /* - * Since this is called by a timer, we should never get here in - * the manual case. - */ - if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { - int pipe = intel_crtc->pipe; - int dpll_reg = DPLL(pipe); - u32 dpll; - - DRM_DEBUG_DRIVER("downclocking LVDS\n"); - - assert_panel_unlocked(dev_priv, pipe); - - dpll = I915_READ(dpll_reg); - dpll |= DISPLAY_RATE_SELECT_FPA1; - I915_WRITE(dpll_reg, dpll); - intel_wait_for_vblank(dev, pipe); - dpll = I915_READ(dpll_reg); - if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) - DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); - } -} - -/** - * intel_idle_update - adjust clocks for idleness - * @work: work struct - * - * Either the GPU or display (or both) went idle. Check the busy status - * here and adjust the CRTC and GPU clocks as necessary. - */ -static void intel_idle_update(struct work_struct *work) -{ - drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, - idle_work); - struct drm_device *dev = dev_priv->dev; - struct drm_crtc *crtc; - struct intel_crtc *intel_crtc; - - if (!i915_powersave) - return; - - mutex_lock(&dev->struct_mutex); - - i915_update_gfx_val(dev_priv); - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - /* Skip inactive CRTCs */ - if (!crtc->fb) - continue; - - intel_crtc = to_intel_crtc(crtc); - if (!intel_crtc->busy) - intel_decrease_pllclock(crtc); - } - - - mutex_unlock(&dev->struct_mutex); -} - -/** - * intel_mark_busy - mark the GPU and possibly the display busy - * @dev: drm device - * @obj: object we're operating on - * - * Callers can use this function to indicate that the GPU is busy processing - * commands. If @obj matches one of the CRTC objects (i.e. it's a scanout - * buffer), we'll also mark the display as busy, so we know to increase its - * clock frequency. - */ -void intel_mark_busy(struct drm_device *dev, struct drm_i915_gem_object *obj) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = NULL; - struct intel_framebuffer *intel_fb; - struct intel_crtc *intel_crtc; - - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - return; - - if (!dev_priv->busy) - dev_priv->busy = true; - else - mod_timer(&dev_priv->idle_timer, jiffies + - msecs_to_jiffies(GPU_IDLE_TIMEOUT)); - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (!crtc->fb) - continue; - - intel_crtc = to_intel_crtc(crtc); - intel_fb = to_intel_framebuffer(crtc->fb); - if (intel_fb->obj == obj) { - if (!intel_crtc->busy) { - /* Non-busy -> busy, upclock */ - intel_increase_pllclock(crtc); - intel_crtc->busy = true; - } else { - /* Busy -> busy, put off timer */ - mod_timer(&intel_crtc->idle_timer, jiffies + - msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); - } - } - } -} - -static void intel_crtc_destroy(struct drm_crtc *crtc) -{ - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct intel_unpin_work *work; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - work = intel_crtc->unpin_work; - intel_crtc->unpin_work = NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); - - if (work) { - cancel_work_sync(&work->work); - kfree(work); - } - - drm_crtc_cleanup(crtc); - - kfree(intel_crtc); -} - -static void intel_unpin_work_fn(struct work_struct *__work) -{ - struct intel_unpin_work *work = - container_of(__work, struct intel_unpin_work, work); - - mutex_lock(&work->dev->struct_mutex); - intel_unpin_fb_obj(work->old_fb_obj); - drm_gem_object_unreference(&work->pending_flip_obj->base); - drm_gem_object_unreference(&work->old_fb_obj->base); - - intel_update_fbc(work->dev); - mutex_unlock(&work->dev->struct_mutex); - kfree(work); -} - -static void do_intel_finish_page_flip(struct drm_device *dev, - struct drm_crtc *crtc) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_unpin_work *work; - struct drm_i915_gem_object *obj; - struct drm_pending_vblank_event *e; - struct timeval tnow, tvbl; - unsigned long flags; - - /* Ignore early vblank irqs */ - if (intel_crtc == NULL) - return; - - do_gettimeofday(&tnow); - - spin_lock_irqsave(&dev->event_lock, flags); - work = intel_crtc->unpin_work; - if (work == NULL || !work->pending) { - spin_unlock_irqrestore(&dev->event_lock, flags); - return; - } - - intel_crtc->unpin_work = NULL; - - if (work->event) { - e = work->event; - e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); - - /* Called before vblank count and timestamps have - * been updated for the vblank interval of flip - * completion? Need to increment vblank count and - * add one videorefresh duration to returned timestamp - * to account for this. We assume this happened if we - * get called over 0.9 frame durations after the last - * timestamped vblank. - * - * This calculation can not be used with vrefresh rates - * below 5Hz (10Hz to be on the safe side) without - * promoting to 64 integers. - */ - if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) > - 9 * crtc->framedur_ns) { - e->event.sequence++; - tvbl = ns_to_timeval(timeval_to_ns(&tvbl) + - crtc->framedur_ns); - } - - e->event.tv_sec = tvbl.tv_sec; - e->event.tv_usec = tvbl.tv_usec; - - list_add_tail(&e->base.link, - &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - drm_vblank_put(dev, intel_crtc->pipe); - - spin_unlock_irqrestore(&dev->event_lock, flags); - - obj = work->old_fb_obj; - - atomic_clear_mask(1 << intel_crtc->plane, - &obj->pending_flip.counter); - if (atomic_read(&obj->pending_flip) == 0) - wake_up(&dev_priv->pending_flip_queue); - - schedule_work(&work->work); - - trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); -} - -void intel_finish_page_flip(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - - do_intel_finish_page_flip(dev, crtc); -} - -void intel_finish_page_flip_plane(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; - - do_intel_finish_page_flip(dev, crtc); -} - -void intel_prepare_page_flip(struct drm_device *dev, int plane) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = - to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]); - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - if (intel_crtc->unpin_work) { - if ((++intel_crtc->unpin_work->pending) > 1) - DRM_ERROR("Prepared flip multiple times\n"); - } else { - DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); - } - spin_unlock_irqrestore(&dev->event_lock, flags); -} - -static int intel_gen2_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long offset; - u32 flip_mask; - int ret; - - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); - if (ret) - goto out; - - /* Offset into the new buffer for cases of shared fbs between CRTCs */ - offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; - - ret = BEGIN_LP_RING(6); - if (ret) - goto out; - - /* Can't queue multiple flips, so wait for the previous - * one to finish before executing the next. - */ - if (intel_crtc->plane) - flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; - else - flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); - OUT_RING(MI_NOOP); - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitches[0]); - OUT_RING(obj->gtt_offset + offset); - OUT_RING(0); /* aux display base address, unused */ - ADVANCE_LP_RING(); -out: - return ret; -} - -static int intel_gen3_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - unsigned long offset; - u32 flip_mask; - int ret; - - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); - if (ret) - goto out; - - /* Offset into the new buffer for cases of shared fbs between CRTCs */ - offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; - - ret = BEGIN_LP_RING(6); - if (ret) - goto out; - - if (intel_crtc->plane) - flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; - else - flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); - OUT_RING(MI_NOOP); - OUT_RING(MI_DISPLAY_FLIP_I915 | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitches[0]); - OUT_RING(obj->gtt_offset + offset); - OUT_RING(MI_NOOP); - - ADVANCE_LP_RING(); -out: - return ret; -} - -static int intel_gen4_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint32_t pf, pipesrc; - int ret; - - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); - if (ret) - goto out; - - ret = BEGIN_LP_RING(4); - if (ret) - goto out; - - /* i965+ uses the linear or tiled offsets from the - * Display Registers (which do not change across a page-flip) - * so we need only reprogram the base address. - */ - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitches[0]); - OUT_RING(obj->gtt_offset | obj->tiling_mode); - - /* XXX Enabling the panel-fitter across page-flip is so far - * untested on non-native modes, so ignore it for now. - * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; - */ - pf = 0; - pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; - OUT_RING(pf | pipesrc); - ADVANCE_LP_RING(); -out: - return ret; -} - -static int intel_gen6_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint32_t pf, pipesrc; - int ret; - - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); - if (ret) - goto out; - - ret = BEGIN_LP_RING(4); - if (ret) - goto out; - - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitches[0] | obj->tiling_mode); - OUT_RING(obj->gtt_offset); - - /* Contrary to the suggestions in the documentation, - * "Enable Panel Fitter" does not seem to be required when page - * flipping with a non-native mode, and worse causes a normal - * modeset to fail. - * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; - */ - pf = 0; - pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; - OUT_RING(pf | pipesrc); - ADVANCE_LP_RING(); -out: - return ret; -} - -/* - * On gen7 we currently use the blit ring because (in early silicon at least) - * the render ring doesn't give us interrpts for page flip completion, which - * means clients will hang after the first flip is queued. Fortunately the - * blit ring generates interrupts properly, so use it instead. - */ -static int intel_gen7_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; - int ret; - - ret = intel_pin_and_fence_fb_obj(dev, obj, ring); - if (ret) - goto out; - - ret = intel_ring_begin(ring, 4); - if (ret) - goto out; - - intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); - intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); - intel_ring_emit(ring, (obj->gtt_offset)); - intel_ring_emit(ring, (MI_NOOP)); - intel_ring_advance(ring); -out: - return ret; -} - -static int intel_default_queue_flip(struct drm_device *dev, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj) -{ - return -ENODEV; -} - -static int intel_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_unpin_work *work; - unsigned long flags; - int ret; - - work = kzalloc(sizeof *work, GFP_KERNEL); - if (work == NULL) - return -ENOMEM; - - work->event = event; - work->dev = crtc->dev; - intel_fb = to_intel_framebuffer(crtc->fb); - work->old_fb_obj = intel_fb->obj; - INIT_WORK(&work->work, intel_unpin_work_fn); - - ret = drm_vblank_get(dev, intel_crtc->pipe); - if (ret) - goto free_work; - - /* We borrow the event spin lock for protecting unpin_work */ - spin_lock_irqsave(&dev->event_lock, flags); - if (intel_crtc->unpin_work) { - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(work); - drm_vblank_put(dev, intel_crtc->pipe); - - DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); - return -EBUSY; - } - intel_crtc->unpin_work = work; - spin_unlock_irqrestore(&dev->event_lock, flags); - - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - - mutex_lock(&dev->struct_mutex); - - /* Reference the objects for the scheduled work. */ - drm_gem_object_reference(&work->old_fb_obj->base); - drm_gem_object_reference(&obj->base); - - crtc->fb = fb; - - work->pending_flip_obj = obj; - - work->enable_stall_check = true; - - /* Block clients from rendering to the new back buffer until - * the flip occurs and the object is no longer visible. - */ - atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); - - ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); - if (ret) - goto cleanup_pending; - - intel_disable_fbc(dev); - mutex_unlock(&dev->struct_mutex); - - trace_i915_flip_request(intel_crtc->plane, obj); - - return 0; - -cleanup_pending: - atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); - drm_gem_object_unreference(&work->old_fb_obj->base); - drm_gem_object_unreference(&obj->base); - mutex_unlock(&dev->struct_mutex); - - spin_lock_irqsave(&dev->event_lock, flags); - intel_crtc->unpin_work = NULL; - spin_unlock_irqrestore(&dev->event_lock, flags); - - drm_vblank_put(dev, intel_crtc->pipe); -free_work: - kfree(work); - - return ret; -} - -static void intel_sanitize_modesetting(struct drm_device *dev, - int pipe, int plane) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 reg, val; - int i; - - /* Clear any frame start delays used for debugging left by the BIOS */ - for_each_pipe(i) { - reg = PIPECONF(i); - I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); - } - - if (HAS_PCH_SPLIT(dev)) - return; - - /* Who knows what state these registers were left in by the BIOS or - * grub? - * - * If we leave the registers in a conflicting state (e.g. with the - * display plane reading from the other pipe than the one we intend - * to use) then when we attempt to teardown the active mode, we will - * not disable the pipes and planes in the correct order -- leaving - * a plane reading from a disabled pipe and possibly leading to - * undefined behaviour. - */ - - reg = DSPCNTR(plane); - val = I915_READ(reg); - - if ((val & DISPLAY_PLANE_ENABLE) == 0) - return; - if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) - return; - - /* This display plane is active and attached to the other CPU pipe. */ - pipe = !pipe; - - /* Disable the plane and wait for it to stop reading from the pipe. */ - intel_disable_plane(dev_priv, plane, pipe); - intel_disable_pipe(dev_priv, pipe); -} - -static void intel_crtc_reset(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - /* Reset flags back to the 'unknown' status so that they - * will be correctly set on the initial modeset. - */ - intel_crtc->dpms_mode = -1; - - /* We need to fix up any BIOS configuration that conflicts with - * our expectations. - */ - intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); -} - -static struct drm_crtc_helper_funcs intel_helper_funcs = { - .dpms = intel_crtc_dpms, - .mode_fixup = intel_crtc_mode_fixup, - .mode_set = intel_crtc_mode_set, - .mode_set_base = intel_pipe_set_base, - .mode_set_base_atomic = intel_pipe_set_base_atomic, - .load_lut = intel_crtc_load_lut, - .disable = intel_crtc_disable, -}; - -static const struct drm_crtc_funcs intel_crtc_funcs = { - .reset = intel_crtc_reset, - .cursor_set = intel_crtc_cursor_set, - .cursor_move = intel_crtc_cursor_move, - .gamma_set = intel_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, - .destroy = intel_crtc_destroy, - .page_flip = intel_crtc_page_flip, -}; - -static void intel_crtc_init(struct drm_device *dev, int pipe) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc; - int i; - - intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); - if (intel_crtc == NULL) - return; - - drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); - - drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); - for (i = 0; i < 256; i++) { - intel_crtc->lut_r[i] = i; - intel_crtc->lut_g[i] = i; - intel_crtc->lut_b[i] = i; - } - - /* Swap pipes & planes for FBC on pre-965 */ - intel_crtc->pipe = pipe; - intel_crtc->plane = pipe; - if (IS_MOBILE(dev) && IS_GEN3(dev)) { - DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); - intel_crtc->plane = !pipe; - } - - BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || - dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); - dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; - dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; - - intel_crtc_reset(&intel_crtc->base); - intel_crtc->active = true; /* force the pipe off on setup_init_config */ - intel_crtc->bpp = 24; /* default for pre-Ironlake */ - - if (HAS_PCH_SPLIT(dev)) { - if (pipe == 2 && IS_IVYBRIDGE(dev)) - intel_crtc->no_pll = true; - intel_helper_funcs.prepare = ironlake_crtc_prepare; - intel_helper_funcs.commit = ironlake_crtc_commit; - } else { - intel_helper_funcs.prepare = i9xx_crtc_prepare; - intel_helper_funcs.commit = i9xx_crtc_commit; - } - - drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); - - intel_crtc->busy = false; - - setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, - (unsigned long)intel_crtc); -} - -int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; - struct drm_mode_object *drmmode_obj; - struct intel_crtc *crtc; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, - DRM_MODE_OBJECT_CRTC); - - if (!drmmode_obj) { - DRM_ERROR("no such CRTC id\n"); - return -EINVAL; - } - - crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); - pipe_from_crtc_id->pipe = crtc->pipe; - - return 0; -} - -static int intel_encoder_clones(struct drm_device *dev, int type_mask) -{ - struct intel_encoder *encoder; - int index_mask = 0; - int entry = 0; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { - if (type_mask & encoder->clone_mask) - index_mask |= (1 << entry); - entry++; - } - - return index_mask; -} - -static bool has_edp_a(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!IS_MOBILE(dev)) - return false; - - if ((I915_READ(DP_A) & DP_DETECTED) == 0) - return false; - - if (IS_GEN5(dev) && - (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) - return false; - - return true; -} - -static void intel_setup_outputs(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_encoder *encoder; - bool dpd_is_edp = false; - bool has_lvds; - - has_lvds = intel_lvds_init(dev); - if (!has_lvds && !HAS_PCH_SPLIT(dev)) { - /* disable the panel fitter on everything but LVDS */ - I915_WRITE(PFIT_CONTROL, 0); - } - - if (HAS_PCH_SPLIT(dev)) { - dpd_is_edp = intel_dpd_is_edp(dev); - - if (has_edp_a(dev)) - intel_dp_init(dev, DP_A); - - if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) - intel_dp_init(dev, PCH_DP_D); - } - - intel_crt_init(dev); - - if (HAS_PCH_SPLIT(dev)) { - int found; - - if (I915_READ(HDMIB) & PORT_DETECTED) { - /* PCH SDVOB multiplex with HDMIB */ - found = intel_sdvo_init(dev, PCH_SDVOB); - if (!found) - intel_hdmi_init(dev, HDMIB); - if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) - intel_dp_init(dev, PCH_DP_B); - } - - if (I915_READ(HDMIC) & PORT_DETECTED) - intel_hdmi_init(dev, HDMIC); - - if (I915_READ(HDMID) & PORT_DETECTED) - intel_hdmi_init(dev, HDMID); - - if (I915_READ(PCH_DP_C) & DP_DETECTED) - intel_dp_init(dev, PCH_DP_C); - - if (!dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) - intel_dp_init(dev, PCH_DP_D); - - } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { - bool found = false; - - if (I915_READ(SDVOB) & SDVO_DETECTED) { - DRM_DEBUG_KMS("probing SDVOB\n"); - found = intel_sdvo_init(dev, SDVOB); - if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) { - DRM_DEBUG_KMS("probing HDMI on SDVOB\n"); - intel_hdmi_init(dev, SDVOB); - } - - if (!found && SUPPORTS_INTEGRATED_DP(dev)) { - DRM_DEBUG_KMS("probing DP_B\n"); - intel_dp_init(dev, DP_B); - } - } - - /* Before G4X SDVOC doesn't have its own detect register */ - - if (I915_READ(SDVOB) & SDVO_DETECTED) { - DRM_DEBUG_KMS("probing SDVOC\n"); - found = intel_sdvo_init(dev, SDVOC); - } - - if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { - - if (SUPPORTS_INTEGRATED_HDMI(dev)) { - DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); - intel_hdmi_init(dev, SDVOC); - } - if (SUPPORTS_INTEGRATED_DP(dev)) { - DRM_DEBUG_KMS("probing DP_C\n"); - intel_dp_init(dev, DP_C); - } - } - - if (SUPPORTS_INTEGRATED_DP(dev) && - (I915_READ(DP_D) & DP_DETECTED)) { - DRM_DEBUG_KMS("probing DP_D\n"); - intel_dp_init(dev, DP_D); - } - } else if (IS_GEN2(dev)) - intel_dvo_init(dev); - - if (SUPPORTS_TV(dev)) - intel_tv_init(dev); - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { - encoder->base.possible_crtcs = encoder->crtc_mask; - encoder->base.possible_clones = - intel_encoder_clones(dev, encoder->clone_mask); - } - - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(dev); - - if (HAS_PCH_SPLIT(dev)) - ironlake_init_pch_refclk(dev); -} - -static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - - drm_framebuffer_cleanup(fb); - drm_gem_object_unreference_unlocked(&intel_fb->obj->base); - - kfree(intel_fb); -} - -static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file, - unsigned int *handle) -{ - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj = intel_fb->obj; - - return drm_gem_handle_create(file, &obj->base, handle); -} - -static const struct drm_framebuffer_funcs intel_fb_funcs = { - .destroy = intel_user_framebuffer_destroy, - .create_handle = intel_user_framebuffer_create_handle, -}; - -int intel_framebuffer_init(struct drm_device *dev, - struct intel_framebuffer *intel_fb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_i915_gem_object *obj) -{ - int ret; - - if (obj->tiling_mode == I915_TILING_Y) - return -EINVAL; - - if (mode_cmd->pitches[0] & 63) - return -EINVAL; - - switch (mode_cmd->pixel_format) { - case DRM_FORMAT_RGB332: - case DRM_FORMAT_RGB565: - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_ARGB2101010: - /* RGB formats are common across chipsets */ - break; - case DRM_FORMAT_YUYV: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_YVYU: - case DRM_FORMAT_VYUY: - break; - default: - DRM_DEBUG_KMS("unsupported pixel format %u\n", - mode_cmd->pixel_format); - return -EINVAL; - } - - ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); - if (ret) { - DRM_ERROR("framebuffer init failed %d\n", ret); - return ret; - } - - drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); - intel_fb->obj = obj; - return 0; -} - -static struct drm_framebuffer * -intel_user_framebuffer_create(struct drm_device *dev, - struct drm_file *filp, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_i915_gem_object *obj; - - obj = to_intel_bo(drm_gem_object_lookup(dev, filp, - mode_cmd->handles[0])); - if (&obj->base == NULL) - return ERR_PTR(-ENOENT); - - return intel_framebuffer_create(dev, mode_cmd, obj); -} - -static const struct drm_mode_config_funcs intel_mode_funcs = { - .fb_create = intel_user_framebuffer_create, - .output_poll_changed = intel_fb_output_poll_changed, -}; - -static struct drm_i915_gem_object * -intel_alloc_context_page(struct drm_device *dev) -{ - struct drm_i915_gem_object *ctx; - int ret; - - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - - ctx = i915_gem_alloc_object(dev, 4096); - if (!ctx) { - DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); - return NULL; - } - - ret = i915_gem_object_pin(ctx, 4096, true); - if (ret) { - DRM_ERROR("failed to pin power context: %d\n", ret); - goto err_unref; - } - - ret = i915_gem_object_set_to_gtt_domain(ctx, 1); - if (ret) { - DRM_ERROR("failed to set-domain on power context: %d\n", ret); - goto err_unpin; - } - - return ctx; - -err_unpin: - i915_gem_object_unpin(ctx); -err_unref: - drm_gem_object_unreference(&ctx->base); - mutex_unlock(&dev->struct_mutex); - return NULL; -} - -bool ironlake_set_drps(struct drm_device *dev, u8 val) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u16 rgvswctl; - - rgvswctl = I915_READ16(MEMSWCTL); - if (rgvswctl & MEMCTL_CMD_STS) { - DRM_DEBUG("gpu busy, RCS change rejected\n"); - return false; /* still busy with another command */ - } - - rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | - (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; - I915_WRITE16(MEMSWCTL, rgvswctl); - POSTING_READ16(MEMSWCTL); - - rgvswctl |= MEMCTL_CMD_STS; - I915_WRITE16(MEMSWCTL, rgvswctl); - - return true; -} - -void ironlake_enable_drps(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 rgvmodectl = I915_READ(MEMMODECTL); - u8 fmax, fmin, fstart, vstart; - - /* Enable temp reporting */ - I915_WRITE16(PMMISC, I915_READ(PMMISC) | MCPPCE_EN); - I915_WRITE16(TSC1, I915_READ(TSC1) | TSE); - - /* 100ms RC evaluation intervals */ - I915_WRITE(RCUPEI, 100000); - I915_WRITE(RCDNEI, 100000); - - /* Set max/min thresholds to 90ms and 80ms respectively */ - I915_WRITE(RCBMAXAVG, 90000); - I915_WRITE(RCBMINAVG, 80000); - - I915_WRITE(MEMIHYST, 1); - - /* Set up min, max, and cur for interrupt handling */ - fmax = (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT; - fmin = (rgvmodectl & MEMMODE_FMIN_MASK); - fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> - MEMMODE_FSTART_SHIFT; - - vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> - PXVFREQ_PX_SHIFT; - - dev_priv->fmax = fmax; /* IPS callback will increase this */ - dev_priv->fstart = fstart; - - dev_priv->max_delay = fstart; - dev_priv->min_delay = fmin; - dev_priv->cur_delay = fstart; - - DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", - fmax, fmin, fstart); - - I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); - - /* - * Interrupts will be enabled in ironlake_irq_postinstall - */ - - I915_WRITE(VIDSTART, vstart); - POSTING_READ(VIDSTART); - - rgvmodectl |= MEMMODE_SWMODE_EN; - I915_WRITE(MEMMODECTL, rgvmodectl); - - if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 10)) - DRM_ERROR("stuck trying to change perf mode\n"); - msleep(1); - - ironlake_set_drps(dev, fstart); - - dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + - I915_READ(0x112e0); - dev_priv->last_time1 = jiffies_to_msecs(jiffies); - dev_priv->last_count2 = I915_READ(0x112f4); - getrawmonotonic(&dev_priv->last_time2); -} - -void ironlake_disable_drps(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u16 rgvswctl = I915_READ16(MEMSWCTL); - - /* Ack interrupts, disable EFC interrupt */ - I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); - I915_WRITE(MEMINTRSTS, MEMINT_EVAL_CHG); - I915_WRITE(DEIER, I915_READ(DEIER) & ~DE_PCU_EVENT); - I915_WRITE(DEIIR, DE_PCU_EVENT); - I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); - - /* Go back to the starting frequency */ - ironlake_set_drps(dev, dev_priv->fstart); - msleep(1); - rgvswctl |= MEMCTL_CMD_STS; - I915_WRITE(MEMSWCTL, rgvswctl); - msleep(1); - -} - -void gen6_set_rps(struct drm_device *dev, u8 val) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 swreq; - - swreq = (val & 0x3ff) << 25; - I915_WRITE(GEN6_RPNSWREQ, swreq); -} - -void gen6_disable_rps(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(GEN6_RPNSWREQ, 1 << 31); - I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); - I915_WRITE(GEN6_PMIER, 0); - /* Complete PM interrupt masking here doesn't race with the rps work - * item again unmasking PM interrupts because that is using a different - * register (PMIMR) to mask PM interrupts. The only risk is in leaving - * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */ - - spin_lock_irq(&dev_priv->rps_lock); - dev_priv->pm_iir = 0; - spin_unlock_irq(&dev_priv->rps_lock); - - I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); -} - -static unsigned long intel_pxfreq(u32 vidfreq) -{ - unsigned long freq; - int div = (vidfreq & 0x3f0000) >> 16; - int post = (vidfreq & 0x3000) >> 12; - int pre = (vidfreq & 0x7); - - if (!pre) - return 0; - - freq = ((div * 133333) / ((1<dev_private; - u32 lcfuse; - u8 pxw[16]; - int i; - - /* Disable to program */ - I915_WRITE(ECR, 0); - POSTING_READ(ECR); - - /* Program energy weights for various events */ - I915_WRITE(SDEW, 0x15040d00); - I915_WRITE(CSIEW0, 0x007f0000); - I915_WRITE(CSIEW1, 0x1e220004); - I915_WRITE(CSIEW2, 0x04000004); - - for (i = 0; i < 5; i++) - I915_WRITE(PEW + (i * 4), 0); - for (i = 0; i < 3; i++) - I915_WRITE(DEW + (i * 4), 0); - - /* Program P-state weights to account for frequency power adjustment */ - for (i = 0; i < 16; i++) { - u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); - unsigned long freq = intel_pxfreq(pxvidfreq); - unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> - PXVFREQ_PX_SHIFT; - unsigned long val; - - val = vid * vid; - val *= (freq / 1000); - val *= 255; - val /= (127*127*900); - if (val > 0xff) - DRM_ERROR("bad pxval: %ld\n", val); - pxw[i] = val; - } - /* Render standby states get 0 weight */ - pxw[14] = 0; - pxw[15] = 0; - - for (i = 0; i < 4; i++) { - u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | - (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); - I915_WRITE(PXW + (i * 4), val); - } - - /* Adjust magic regs to magic values (more experimental results) */ - I915_WRITE(OGW0, 0); - I915_WRITE(OGW1, 0); - I915_WRITE(EG0, 0x00007f00); - I915_WRITE(EG1, 0x0000000e); - I915_WRITE(EG2, 0x000e0000); - I915_WRITE(EG3, 0x68000300); - I915_WRITE(EG4, 0x42000000); - I915_WRITE(EG5, 0x00140031); - I915_WRITE(EG6, 0); - I915_WRITE(EG7, 0); - - for (i = 0; i < 8; i++) - I915_WRITE(PXWL + (i * 4), 0); - - /* Enable PMON + select events */ - I915_WRITE(ECR, 0x80000019); - - lcfuse = I915_READ(LCFUSE02); - - dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); -} - -static int intel_enable_rc6(struct drm_device *dev) -{ - /* - * Respect the kernel parameter if it is set - */ - if (i915_enable_rc6 >= 0) - return i915_enable_rc6; - - /* - * Disable RC6 on Ironlake - */ - if (INTEL_INFO(dev)->gen == 5) - return 0; - - /* - * Disable rc6 on Sandybridge - */ - if (INTEL_INFO(dev)->gen == 6) { - DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n"); - return INTEL_RC6_ENABLE; - } - DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n"); - return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); -} - -void gen6_enable_rps(struct drm_i915_private *dev_priv) -{ - u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); - u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); - u32 pcu_mbox, rc6_mask = 0; - u32 gtfifodbg; - int cur_freq, min_freq, max_freq; - int rc6_mode; - int i; - - /* Here begins a magic sequence of register writes to enable - * auto-downclocking. - * - * Perhaps there might be some value in exposing these to - * userspace... - */ - I915_WRITE(GEN6_RC_STATE, 0); - mutex_lock(&dev_priv->dev->struct_mutex); - - /* Clear the DBG now so we don't confuse earlier errors */ - if ((gtfifodbg = I915_READ(GTFIFODBG))) { - DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg); - I915_WRITE(GTFIFODBG, gtfifodbg); - } - - gen6_gt_force_wake_get(dev_priv); - - /* disable the counters and set deterministic thresholds */ - I915_WRITE(GEN6_RC_CONTROL, 0); - - I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); - I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); - I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); - I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); - I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); - - for (i = 0; i < I915_NUM_RINGS; i++) - I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10); - - I915_WRITE(GEN6_RC_SLEEP, 0); - I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); - I915_WRITE(GEN6_RC6_THRESHOLD, 50000); - I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); - I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ - - rc6_mode = intel_enable_rc6(dev_priv->dev); - if (rc6_mode & INTEL_RC6_ENABLE) - rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; - - if (rc6_mode & INTEL_RC6p_ENABLE) - rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; - - if (rc6_mode & INTEL_RC6pp_ENABLE) - rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; - - DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", - (rc6_mode & INTEL_RC6_ENABLE) ? "on" : "off", - (rc6_mode & INTEL_RC6p_ENABLE) ? "on" : "off", - (rc6_mode & INTEL_RC6pp_ENABLE) ? "on" : "off"); - - I915_WRITE(GEN6_RC_CONTROL, - rc6_mask | - GEN6_RC_CTL_EI_MODE(1) | - GEN6_RC_CTL_HW_ENABLE); - - I915_WRITE(GEN6_RPNSWREQ, - GEN6_FREQUENCY(10) | - GEN6_OFFSET(0) | - GEN6_AGGRESSIVE_TURBO); - I915_WRITE(GEN6_RC_VIDEO_FREQ, - GEN6_FREQUENCY(12)); - - I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); - I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, - 18 << 24 | - 6 << 16); - I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); - I915_WRITE(GEN6_RP_UP_EI, 100000); - I915_WRITE(GEN6_RP_DOWN_EI, 5000000); - I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_CONT); - - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, - 500)) - DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); - - I915_WRITE(GEN6_PCODE_DATA, 0); - I915_WRITE(GEN6_PCODE_MAILBOX, - GEN6_PCODE_READY | - GEN6_PCODE_WRITE_MIN_FREQ_TABLE); - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, - 500)) - DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); - - min_freq = (rp_state_cap & 0xff0000) >> 16; - max_freq = rp_state_cap & 0xff; - cur_freq = (gt_perf_status & 0xff00) >> 8; - - /* Check for overclock support */ - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, - 500)) - DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); - I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_READ_OC_PARAMS); - pcu_mbox = I915_READ(GEN6_PCODE_DATA); - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, - 500)) - DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); - if (pcu_mbox & (1<<31)) { /* OC supported */ - max_freq = pcu_mbox & 0xff; - DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); - } - - /* In units of 100MHz */ - dev_priv->max_delay = max_freq; - dev_priv->min_delay = min_freq; - dev_priv->cur_delay = cur_freq; - - /* requires MSI enabled */ - I915_WRITE(GEN6_PMIER, - GEN6_PM_MBOX_EVENT | - GEN6_PM_THERMAL_EVENT | - GEN6_PM_RP_DOWN_TIMEOUT | - GEN6_PM_RP_UP_THRESHOLD | - GEN6_PM_RP_DOWN_THRESHOLD | - GEN6_PM_RP_UP_EI_EXPIRED | - GEN6_PM_RP_DOWN_EI_EXPIRED); - spin_lock_irq(&dev_priv->rps_lock); - WARN_ON(dev_priv->pm_iir != 0); - I915_WRITE(GEN6_PMIMR, 0); - spin_unlock_irq(&dev_priv->rps_lock); - /* enable all PM interrupts */ - I915_WRITE(GEN6_PMINTRMSK, 0); - - gen6_gt_force_wake_put(dev_priv); - mutex_unlock(&dev_priv->dev->struct_mutex); -} - -void gen6_update_ring_freq(struct drm_i915_private *dev_priv) -{ - int min_freq = 15; - int gpu_freq, ia_freq, max_ia_freq; - int scaling_factor = 180; - - max_ia_freq = cpufreq_quick_get_max(0); - /* - * Default to measured freq if none found, PCU will ensure we don't go - * over - */ - if (!max_ia_freq) - max_ia_freq = tsc_khz; - - /* Convert from kHz to MHz */ - max_ia_freq /= 1000; - - mutex_lock(&dev_priv->dev->struct_mutex); - - /* - * For each potential GPU frequency, load a ring frequency we'd like - * to use for memory access. We do this by specifying the IA frequency - * the PCU should use as a reference to determine the ring frequency. - */ - for (gpu_freq = dev_priv->max_delay; gpu_freq >= dev_priv->min_delay; - gpu_freq--) { - int diff = dev_priv->max_delay - gpu_freq; - - /* - * For GPU frequencies less than 750MHz, just use the lowest - * ring freq. - */ - if (gpu_freq < min_freq) - ia_freq = 800; - else - ia_freq = max_ia_freq - ((diff * scaling_factor) / 2); - ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100); - - I915_WRITE(GEN6_PCODE_DATA, - (ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT) | - gpu_freq); - I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | - GEN6_PCODE_WRITE_MIN_FREQ_TABLE); - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & - GEN6_PCODE_READY) == 0, 10)) { - DRM_ERROR("pcode write of freq table timed out\n"); - continue; - } - } - - mutex_unlock(&dev_priv->dev->struct_mutex); -} - -static void ironlake_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - - /* Required for FBC */ - dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE | - DPFCRUNIT_CLOCK_GATE_DISABLE | - DPFDUNIT_CLOCK_GATE_DISABLE; - /* Required for CxSR */ - dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; - - I915_WRITE(PCH_3DCGDIS0, - MARIUNIT_CLOCK_GATE_DISABLE | - SVSMUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(PCH_3DCGDIS1, - VFMUNIT_CLOCK_GATE_DISABLE); - - I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - - /* - * According to the spec the following bits should be set in - * order to enable memory self-refresh - * The bit 22/21 of 0x42004 - * The bit 5 of 0x42020 - * The bit 15 of 0x45000 - */ - I915_WRITE(ILK_DISPLAY_CHICKEN2, - (I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL)); - I915_WRITE(ILK_DSPCLK_GATE, - (I915_READ(ILK_DSPCLK_GATE) | - ILK_DPARB_CLK_GATE)); - I915_WRITE(DISP_ARB_CTL, - (I915_READ(DISP_ARB_CTL) | - DISP_FBC_WM_DIS)); - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - /* - * Based on the document from hardware guys the following bits - * should be set unconditionally in order to enable FBC. - * The bit 22 of 0x42000 - * The bit 22 of 0x42004 - * The bit 7,8,9 of 0x42020. - */ - if (IS_IRONLAKE_M(dev)) { - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE); - I915_WRITE(ILK_DSPCLK_GATE, - I915_READ(ILK_DSPCLK_GATE) | - ILK_DPFC_DIS1 | - ILK_DPFC_DIS2 | - ILK_CLK_FBC); - } - - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_ELPIN_409_SELECT); - I915_WRITE(_3D_CHICKEN2, - _3D_CHICKEN2_WM_READ_PIPELINED << 16 | - _3D_CHICKEN2_WM_READ_PIPELINED); -} - -static void gen6_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; - uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - - I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_ELPIN_409_SELECT); - - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - I915_WRITE(GEN6_UCGCTL1, - I915_READ(GEN6_UCGCTL1) | - GEN6_BLBUNIT_CLOCK_GATE_DISABLE); - - /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock - * gating disable must be set. Failure to set it results in - * flickering pixels due to Z write ordering failures after - * some amount of runtime in the Mesa "fire" demo, and Unigine - * Sanctuary and Tropics, and apparently anything else with - * alpha test or pixel discard. - * - * According to the spec, bit 11 (RCCUNIT) must also be set, - * but we didn't debug actual testcases to find it out. - */ - I915_WRITE(GEN6_UCGCTL2, - GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | - GEN6_RCCUNIT_CLOCK_GATE_DISABLE); - - /* - * According to the spec the following bits should be - * set in order to enable memory self-refresh and fbc: - * The bit21 and bit22 of 0x42000 - * The bit21 and bit22 of 0x42004 - * The bit5 and bit7 of 0x42020 - * The bit14 of 0x70180 - * The bit14 of 0x71180 - */ - I915_WRITE(ILK_DISPLAY_CHICKEN1, - I915_READ(ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); - I915_WRITE(ILK_DISPLAY_CHICKEN2, - I915_READ(ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL); - I915_WRITE(ILK_DSPCLK_GATE, - I915_READ(ILK_DSPCLK_GATE) | - ILK_DPARB_CLK_GATE | - ILK_DPFD_CLK_GATE); - - for_each_pipe(pipe) { - I915_WRITE(DSPCNTR(pipe), - I915_READ(DSPCNTR(pipe)) | - DISPPLANE_TRICKLE_FEED_DISABLE); - intel_flush_display_plane(dev_priv, pipe); - } -} - -static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) -{ - uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE); - - reg &= ~GEN7_FF_SCHED_MASK; - reg |= GEN7_FF_TS_SCHED_HW; - reg |= GEN7_FF_VS_SCHED_HW; - reg |= GEN7_FF_DS_SCHED_HW; - - I915_WRITE(GEN7_FF_THREAD_MODE, reg); -} - -static void ivybridge_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; - uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; - - I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); - - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); - - /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. - * This implements the WaDisableRCZUnitClockGating workaround. - */ - I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - - I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); - - I915_WRITE(IVB_CHICKEN3, - CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | - CHICKEN3_DGMG_DONE_FIX_DISABLE); - - /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ - I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, - GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); - - /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ - I915_WRITE(GEN7_L3CNTLREG1, - GEN7_WA_FOR_GEN7_L3_CONTROL); - I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, - GEN7_WA_L3_CHICKEN_MODE); - - /* This is required by WaCatErrorRejectionIssue */ - I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | - GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - - for_each_pipe(pipe) { - I915_WRITE(DSPCNTR(pipe), - I915_READ(DSPCNTR(pipe)) | - DISPPLANE_TRICKLE_FEED_DISABLE); - intel_flush_display_plane(dev_priv, pipe); - } - - gen7_setup_fixed_func_scheduler(dev_priv); -} - -static void g4x_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dspclk_gate; - - I915_WRITE(RENCLK_GATE_D1, 0); - I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | - GS_UNIT_CLOCK_GATE_DISABLE | - CL_UNIT_CLOCK_GATE_DISABLE); - I915_WRITE(RAMCLK_GATE_D, 0); - dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE; - if (IS_GM45(dev)) - dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - I915_WRITE(DSPCLK_GATE_D, dspclk_gate); -} - -static void crestline_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); - I915_WRITE(RENCLK_GATE_D2, 0); - I915_WRITE(DSPCLK_GATE_D, 0); - I915_WRITE(RAMCLK_GATE_D, 0); - I915_WRITE16(DEUC, 0); -} - -static void broadwater_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | - I965_RCC_CLOCK_GATE_DISABLE | - I965_RCPB_CLOCK_GATE_DISABLE | - I965_ISC_CLOCK_GATE_DISABLE | - I965_FBC_CLOCK_GATE_DISABLE); - I915_WRITE(RENCLK_GATE_D2, 0); -} - -static void gen3_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dstate = I915_READ(D_STATE); - - dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | - DSTATE_DOT_CLOCK_GATING; - I915_WRITE(D_STATE, dstate); -} - -static void i85x_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); -} - -static void i830_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); -} - -static void ibx_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); -} - -static void cpt_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; - - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); - I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | - DPLS_EDP_PPS_FIX_DIS); - /* Without this, mode sets may fail silently on FDI */ - for_each_pipe(pipe) - I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); -} - -static void ironlake_teardown_rc6(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->renderctx) { - i915_gem_object_unpin(dev_priv->renderctx); - drm_gem_object_unreference(&dev_priv->renderctx->base); - dev_priv->renderctx = NULL; - } - - if (dev_priv->pwrctx) { - i915_gem_object_unpin(dev_priv->pwrctx); - drm_gem_object_unreference(&dev_priv->pwrctx->base); - dev_priv->pwrctx = NULL; - } -} - -static void ironlake_disable_rc6(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (I915_READ(PWRCTXA)) { - /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); - wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), - 50); - - I915_WRITE(PWRCTXA, 0); - POSTING_READ(PWRCTXA); - - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); - POSTING_READ(RSTDBYCTL); - } - - ironlake_teardown_rc6(dev); -} - -static int ironlake_setup_rc6(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->renderctx == NULL) - dev_priv->renderctx = intel_alloc_context_page(dev); - if (!dev_priv->renderctx) - return -ENOMEM; - - if (dev_priv->pwrctx == NULL) - dev_priv->pwrctx = intel_alloc_context_page(dev); - if (!dev_priv->pwrctx) { - ironlake_teardown_rc6(dev); - return -ENOMEM; - } - - return 0; -} - -void ironlake_enable_rc6(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - /* rc6 disabled by default due to repeated reports of hanging during - * boot and resume. - */ - if (!intel_enable_rc6(dev)) - return; - - mutex_lock(&dev->struct_mutex); - ret = ironlake_setup_rc6(dev); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return; - } - - /* - * GPU can automatically power down the render unit if given a page - * to save state. - */ - ret = BEGIN_LP_RING(6); - if (ret) { - ironlake_teardown_rc6(dev); - mutex_unlock(&dev->struct_mutex); - return; - } - - OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); - OUT_RING(MI_SET_CONTEXT); - OUT_RING(dev_priv->renderctx->gtt_offset | - MI_MM_SPACE_GTT | - MI_SAVE_EXT_STATE_EN | - MI_RESTORE_EXT_STATE_EN | - MI_RESTORE_INHIBIT); - OUT_RING(MI_SUSPEND_FLUSH); - OUT_RING(MI_NOOP); - OUT_RING(MI_FLUSH); - ADVANCE_LP_RING(); - - /* - * Wait for the command parser to advance past MI_SET_CONTEXT. The HW - * does an implicit flush, combined with MI_FLUSH above, it should be - * safe to assume that renderctx is valid - */ - ret = intel_wait_ring_idle(LP_RING(dev_priv)); - if (ret) { - DRM_ERROR("failed to enable ironlake power power savings\n"); - ironlake_teardown_rc6(dev); - mutex_unlock(&dev->struct_mutex); - return; - } - - I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); - mutex_unlock(&dev->struct_mutex); -} - -void intel_init_clock_gating(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->display.init_clock_gating(dev); - - if (dev_priv->display.init_pch_clock_gating) - dev_priv->display.init_pch_clock_gating(dev); -} - -/* Set up chip specific display functions */ -static void intel_init_display(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* We always want a DPMS function */ - if (HAS_PCH_SPLIT(dev)) { - dev_priv->display.dpms = ironlake_crtc_dpms; - dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; - dev_priv->display.update_plane = ironlake_update_plane; - } else { - dev_priv->display.dpms = i9xx_crtc_dpms; - dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; - dev_priv->display.update_plane = i9xx_update_plane; - } - - if (I915_HAS_FBC(dev)) { - if (HAS_PCH_SPLIT(dev)) { - dev_priv->display.fbc_enabled = ironlake_fbc_enabled; - dev_priv->display.enable_fbc = ironlake_enable_fbc; - dev_priv->display.disable_fbc = ironlake_disable_fbc; - } else if (IS_GM45(dev)) { - dev_priv->display.fbc_enabled = g4x_fbc_enabled; - dev_priv->display.enable_fbc = g4x_enable_fbc; - dev_priv->display.disable_fbc = g4x_disable_fbc; - } else if (IS_CRESTLINE(dev)) { - dev_priv->display.fbc_enabled = i8xx_fbc_enabled; - dev_priv->display.enable_fbc = i8xx_enable_fbc; - dev_priv->display.disable_fbc = i8xx_disable_fbc; - } - /* 855GM needs testing */ - } - - /* Returns the core display clock speed */ - if (IS_I945G(dev) || (IS_G33(dev) && !IS_PINEVIEW_M(dev))) - dev_priv->display.get_display_clock_speed = - i945_get_display_clock_speed; - else if (IS_I915G(dev)) - dev_priv->display.get_display_clock_speed = - i915_get_display_clock_speed; - else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev)) - dev_priv->display.get_display_clock_speed = - i9xx_misc_get_display_clock_speed; - else if (IS_I915GM(dev)) - dev_priv->display.get_display_clock_speed = - i915gm_get_display_clock_speed; - else if (IS_I865G(dev)) - dev_priv->display.get_display_clock_speed = - i865_get_display_clock_speed; - else if (IS_I85X(dev)) - dev_priv->display.get_display_clock_speed = - i855_get_display_clock_speed; - else /* 852, 830 */ - dev_priv->display.get_display_clock_speed = - i830_get_display_clock_speed; - - /* For FIFO watermark updates */ - if (HAS_PCH_SPLIT(dev)) { - dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; - dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; - - /* IVB configs may use multi-threaded forcewake */ - if (IS_IVYBRIDGE(dev)) { - u32 ecobus; - - /* A small trick here - if the bios hasn't configured MT forcewake, - * and if the device is in RC6, then force_wake_mt_get will not wake - * the device and the ECOBUS read will return zero. Which will be - * (correctly) interpreted by the test below as MT forcewake being - * disabled. - */ - mutex_lock(&dev->struct_mutex); - __gen6_gt_force_wake_mt_get(dev_priv); - ecobus = I915_READ_NOTRACE(ECOBUS); - __gen6_gt_force_wake_mt_put(dev_priv); - mutex_unlock(&dev->struct_mutex); - - if (ecobus & FORCEWAKE_MT_ENABLE) { - DRM_DEBUG_KMS("Using MT version of forcewake\n"); - dev_priv->display.force_wake_get = - __gen6_gt_force_wake_mt_get; - dev_priv->display.force_wake_put = - __gen6_gt_force_wake_mt_put; - } - } - - if (HAS_PCH_IBX(dev)) - dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; - else if (HAS_PCH_CPT(dev)) - dev_priv->display.init_pch_clock_gating = cpt_init_clock_gating; - - if (IS_GEN5(dev)) { - if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK) - dev_priv->display.update_wm = ironlake_update_wm; - else { - DRM_DEBUG_KMS("Failed to get proper latency. " - "Disable CxSR\n"); - dev_priv->display.update_wm = NULL; - } - dev_priv->display.fdi_link_train = ironlake_fdi_link_train; - dev_priv->display.init_clock_gating = ironlake_init_clock_gating; - dev_priv->display.write_eld = ironlake_write_eld; - } else if (IS_GEN6(dev)) { - if (SNB_READ_WM0_LATENCY()) { - dev_priv->display.update_wm = sandybridge_update_wm; - dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; - } else { - DRM_DEBUG_KMS("Failed to read display plane latency. " - "Disable CxSR\n"); - dev_priv->display.update_wm = NULL; - } - dev_priv->display.fdi_link_train = gen6_fdi_link_train; - dev_priv->display.init_clock_gating = gen6_init_clock_gating; - dev_priv->display.write_eld = ironlake_write_eld; - } else if (IS_IVYBRIDGE(dev)) { - /* FIXME: detect B0+ stepping and use auto training */ - dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; - if (SNB_READ_WM0_LATENCY()) { - dev_priv->display.update_wm = sandybridge_update_wm; - dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm; - } else { - DRM_DEBUG_KMS("Failed to read display plane latency. " - "Disable CxSR\n"); - dev_priv->display.update_wm = NULL; - } - dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; - dev_priv->display.write_eld = ironlake_write_eld; - } else - dev_priv->display.update_wm = NULL; - } else if (IS_PINEVIEW(dev)) { - if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), - dev_priv->is_ddr3, - dev_priv->fsb_freq, - dev_priv->mem_freq)) { - DRM_INFO("failed to find known CxSR latency " - "(found ddr%s fsb freq %d, mem freq %d), " - "disabling CxSR\n", - (dev_priv->is_ddr3 == 1) ? "3" : "2", - dev_priv->fsb_freq, dev_priv->mem_freq); - /* Disable CxSR and never update its watermark again */ - pineview_disable_cxsr(dev); - dev_priv->display.update_wm = NULL; - } else - dev_priv->display.update_wm = pineview_update_wm; - dev_priv->display.init_clock_gating = gen3_init_clock_gating; - } else if (IS_G4X(dev)) { - dev_priv->display.write_eld = g4x_write_eld; - dev_priv->display.update_wm = g4x_update_wm; - dev_priv->display.init_clock_gating = g4x_init_clock_gating; - } else if (IS_GEN4(dev)) { - dev_priv->display.update_wm = i965_update_wm; - if (IS_CRESTLINE(dev)) - dev_priv->display.init_clock_gating = crestline_init_clock_gating; - else if (IS_BROADWATER(dev)) - dev_priv->display.init_clock_gating = broadwater_init_clock_gating; - } else if (IS_GEN3(dev)) { - dev_priv->display.update_wm = i9xx_update_wm; - dev_priv->display.get_fifo_size = i9xx_get_fifo_size; - dev_priv->display.init_clock_gating = gen3_init_clock_gating; - } else if (IS_I865G(dev)) { - dev_priv->display.update_wm = i830_update_wm; - dev_priv->display.init_clock_gating = i85x_init_clock_gating; - dev_priv->display.get_fifo_size = i830_get_fifo_size; - } else if (IS_I85X(dev)) { - dev_priv->display.update_wm = i9xx_update_wm; - dev_priv->display.get_fifo_size = i85x_get_fifo_size; - dev_priv->display.init_clock_gating = i85x_init_clock_gating; - } else { - dev_priv->display.update_wm = i830_update_wm; - dev_priv->display.init_clock_gating = i830_init_clock_gating; - if (IS_845G(dev)) - dev_priv->display.get_fifo_size = i845_get_fifo_size; - else - dev_priv->display.get_fifo_size = i830_get_fifo_size; - } - - /* Default just returns -ENODEV to indicate unsupported */ - dev_priv->display.queue_flip = intel_default_queue_flip; - - switch (INTEL_INFO(dev)->gen) { - case 2: - dev_priv->display.queue_flip = intel_gen2_queue_flip; - break; - - case 3: - dev_priv->display.queue_flip = intel_gen3_queue_flip; - break; - - case 4: - case 5: - dev_priv->display.queue_flip = intel_gen4_queue_flip; - break; - - case 6: - dev_priv->display.queue_flip = intel_gen6_queue_flip; - break; - case 7: - dev_priv->display.queue_flip = intel_gen7_queue_flip; - break; - } -} - -/* - * Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend, - * resume, or other times. This quirk makes sure that's the case for - * affected systems. - */ -static void quirk_pipea_force(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->quirks |= QUIRK_PIPEA_FORCE; - DRM_DEBUG_DRIVER("applying pipe a force quirk\n"); -} - -/* - * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason - */ -static void quirk_ssc_force_disable(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; -} - -struct intel_quirk { - int device; - int subsystem_vendor; - int subsystem_device; - void (*hook)(struct drm_device *dev); -}; - -struct intel_quirk intel_quirks[] = { - /* HP Mini needs pipe A force quirk (LP: #322104) */ - { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, - - /* Thinkpad R31 needs pipe A force quirk */ - { 0x3577, 0x1014, 0x0505, quirk_pipea_force }, - /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ - { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, - - /* ThinkPad X30 needs pipe A force quirk (LP: #304614) */ - { 0x3577, 0x1014, 0x0513, quirk_pipea_force }, - /* ThinkPad X40 needs pipe A force quirk */ - - /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ - { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, - - /* 855 & before need to leave pipe A & dpll A up */ - { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, - { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, - - /* Lenovo U160 cannot use SSC on LVDS */ - { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, - - /* Sony Vaio Y cannot use SSC on LVDS */ - { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, -}; - -static void intel_init_quirks(struct drm_device *dev) -{ - struct pci_dev *d = dev->pdev; - int i; - - for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) { - struct intel_quirk *q = &intel_quirks[i]; - - if (d->device == q->device && - (d->subsystem_vendor == q->subsystem_vendor || - q->subsystem_vendor == PCI_ANY_ID) && - (d->subsystem_device == q->subsystem_device || - q->subsystem_device == PCI_ANY_ID)) - q->hook(dev); - } -} - -/* Disable the VGA plane that we never use */ -static void i915_disable_vga(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u8 sr1; - u32 vga_reg; - - if (HAS_PCH_SPLIT(dev)) - vga_reg = CPU_VGACNTRL; - else - vga_reg = VGACNTRL; - - vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); - outb(1, VGA_SR_INDEX); - sr1 = inb(VGA_SR_DATA); - outb(sr1 | 1<<5, VGA_SR_DATA); - vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); - udelay(300); - - I915_WRITE(vga_reg, VGA_DISP_DISABLE); - POSTING_READ(vga_reg); -} - -void intel_modeset_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i, ret; - - drm_mode_config_init(dev); - - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - - dev->mode_config.preferred_depth = 24; - dev->mode_config.prefer_shadow = 1; - - dev->mode_config.funcs = (void *)&intel_mode_funcs; - - intel_init_quirks(dev); - - intel_init_display(dev); - - if (IS_GEN2(dev)) { - dev->mode_config.max_width = 2048; - dev->mode_config.max_height = 2048; - } else if (IS_GEN3(dev)) { - dev->mode_config.max_width = 4096; - dev->mode_config.max_height = 4096; - } else { - dev->mode_config.max_width = 8192; - dev->mode_config.max_height = 8192; - } - dev->mode_config.fb_base = dev->agp->base; - - DRM_DEBUG_KMS("%d display pipe%s available.\n", - dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); - - for (i = 0; i < dev_priv->num_pipe; i++) { - intel_crtc_init(dev, i); - ret = intel_plane_init(dev, i); - if (ret) - DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); - } - - /* Just disable it once at startup */ - i915_disable_vga(dev); - intel_setup_outputs(dev); - - intel_init_clock_gating(dev); - - if (IS_IRONLAKE_M(dev)) { - ironlake_enable_drps(dev); - intel_init_emon(dev); - } - - if (IS_GEN6(dev) || IS_GEN7(dev)) { - gen6_enable_rps(dev_priv); - gen6_update_ring_freq(dev_priv); - } - - INIT_WORK(&dev_priv->idle_work, intel_idle_update); - setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, - (unsigned long)dev); -} - -void intel_modeset_gem_init(struct drm_device *dev) -{ - if (IS_IRONLAKE_M(dev)) - ironlake_enable_rc6(dev); - - intel_setup_overlay(dev); -} - -void intel_modeset_cleanup(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct intel_crtc *intel_crtc; - - drm_kms_helper_poll_fini(dev); - mutex_lock(&dev->struct_mutex); - - intel_unregister_dsm_handler(); - - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - /* Skip inactive CRTCs */ - if (!crtc->fb) - continue; - - intel_crtc = to_intel_crtc(crtc); - intel_increase_pllclock(crtc); - } - - intel_disable_fbc(dev); - - if (IS_IRONLAKE_M(dev)) - ironlake_disable_drps(dev); - if (IS_GEN6(dev) || IS_GEN7(dev)) - gen6_disable_rps(dev); - - if (IS_IRONLAKE_M(dev)) - ironlake_disable_rc6(dev); - - mutex_unlock(&dev->struct_mutex); - - /* Disable the irq before mode object teardown, for the irq might - * enqueue unpin/hotplug work. */ - drm_irq_uninstall(dev); - cancel_work_sync(&dev_priv->hotplug_work); - cancel_work_sync(&dev_priv->rps_work); - - /* flush any delayed tasks or pending work */ - flush_scheduled_work(); - - /* Shut off idle work before the crtcs get freed. */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - intel_crtc = to_intel_crtc(crtc); - del_timer_sync(&intel_crtc->idle_timer); - } - del_timer_sync(&dev_priv->idle_timer); - cancel_work_sync(&dev_priv->idle_work); - - drm_mode_config_cleanup(dev); -} - -/* - * Return which encoder is currently attached for connector. - */ -struct drm_encoder *intel_best_encoder(struct drm_connector *connector) -{ - return &intel_attached_encoder(connector)->base; -} - -void intel_connector_attach_encoder(struct intel_connector *connector, - struct intel_encoder *encoder) -{ - connector->encoder = encoder; - drm_mode_connector_attach_encoder(&connector->base, - &encoder->base); -} - -/* - * set vga decode state - true == enable VGA decode - */ -int intel_modeset_vga_set_state(struct drm_device *dev, bool state) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u16 gmch_ctrl; - - pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl); - if (state) - gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; - else - gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; - pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); - return 0; -} - -#ifdef CONFIG_DEBUG_FS -#include - -struct intel_display_error_state { - struct intel_cursor_error_state { - u32 control; - u32 position; - u32 base; - u32 size; - } cursor[2]; - - struct intel_pipe_error_state { - u32 conf; - u32 source; - - u32 htotal; - u32 hblank; - u32 hsync; - u32 vtotal; - u32 vblank; - u32 vsync; - } pipe[2]; - - struct intel_plane_error_state { - u32 control; - u32 stride; - u32 size; - u32 pos; - u32 addr; - u32 surface; - u32 tile_offset; - } plane[2]; -}; - -struct intel_display_error_state * -intel_display_capture_error_state(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_display_error_state *error; - int i; - - error = kmalloc(sizeof(*error), GFP_ATOMIC); - if (error == NULL) - return NULL; - - for (i = 0; i < 2; i++) { - error->cursor[i].control = I915_READ(CURCNTR(i)); - error->cursor[i].position = I915_READ(CURPOS(i)); - error->cursor[i].base = I915_READ(CURBASE(i)); - - error->plane[i].control = I915_READ(DSPCNTR(i)); - error->plane[i].stride = I915_READ(DSPSTRIDE(i)); - error->plane[i].size = I915_READ(DSPSIZE(i)); - error->plane[i].pos = I915_READ(DSPPOS(i)); - error->plane[i].addr = I915_READ(DSPADDR(i)); - if (INTEL_INFO(dev)->gen >= 4) { - error->plane[i].surface = I915_READ(DSPSURF(i)); - error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); - } - - error->pipe[i].conf = I915_READ(PIPECONF(i)); - error->pipe[i].source = I915_READ(PIPESRC(i)); - error->pipe[i].htotal = I915_READ(HTOTAL(i)); - error->pipe[i].hblank = I915_READ(HBLANK(i)); - error->pipe[i].hsync = I915_READ(HSYNC(i)); - error->pipe[i].vtotal = I915_READ(VTOTAL(i)); - error->pipe[i].vblank = I915_READ(VBLANK(i)); - error->pipe[i].vsync = I915_READ(VSYNC(i)); - } - - return error; -} - -void -intel_display_print_error_state(struct seq_file *m, - struct drm_device *dev, - struct intel_display_error_state *error) -{ - int i; - - for (i = 0; i < 2; i++) { - seq_printf(m, "Pipe [%d]:\n", i); - seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); - seq_printf(m, " SRC: %08x\n", error->pipe[i].source); - seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); - seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); - seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); - seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); - seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); - seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); - - seq_printf(m, "Plane [%d]:\n", i); - seq_printf(m, " CNTR: %08x\n", error->plane[i].control); - seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); - seq_printf(m, " SIZE: %08x\n", error->plane[i].size); - seq_printf(m, " POS: %08x\n", error->plane[i].pos); - seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); - if (INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " SURF: %08x\n", error->plane[i].surface); - seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); - } - - seq_printf(m, "Cursor [%d]:\n", i); - seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); - seq_printf(m, " POS: %08x\n", error->cursor[i].position); - seq_printf(m, " BASE: %08x\n", error->cursor[i].base); - } -} -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dp.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dp.c deleted file mode 100644 index 68624218..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dp.c +++ /dev/null @@ -1,2566 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Keith Packard - * - */ - -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "drm_dp_helper.h" - -#define DP_RECEIVER_CAP_SIZE 0xf -#define DP_LINK_STATUS_SIZE 6 -#define DP_LINK_CHECK_TIMEOUT (10 * 1000) - -#define DP_LINK_CONFIGURATION_SIZE 9 - -struct intel_dp { - struct intel_encoder base; - uint32_t output_reg; - uint32_t DP; - uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; - bool has_audio; - enum hdmi_force_audio force_audio; - uint32_t color_range; - int dpms_mode; - uint8_t link_bw; - uint8_t lane_count; - uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; - struct i2c_adapter adapter; - struct i2c_algo_dp_aux_data algo; - bool is_pch_edp; - uint8_t train_set[4]; - int panel_power_up_delay; - int panel_power_down_delay; - int panel_power_cycle_delay; - int backlight_on_delay; - int backlight_off_delay; - struct drm_display_mode *panel_fixed_mode; /* for eDP */ - struct delayed_work panel_vdd_work; - bool want_panel_vdd; -}; - -/** - * is_edp - is the given port attached to an eDP panel (either CPU or PCH) - * @intel_dp: DP struct - * - * If a CPU or PCH DP output is attached to an eDP panel, this function - * will return true, and false otherwise. - */ -static bool is_edp(struct intel_dp *intel_dp) -{ - return intel_dp->base.type == INTEL_OUTPUT_EDP; -} - -/** - * is_pch_edp - is the port on the PCH and attached to an eDP panel? - * @intel_dp: DP struct - * - * Returns true if the given DP struct corresponds to a PCH DP port attached - * to an eDP panel, false otherwise. Helpful for determining whether we - * may need FDI resources for a given DP output or not. - */ -static bool is_pch_edp(struct intel_dp *intel_dp) -{ - return intel_dp->is_pch_edp; -} - -/** - * is_cpu_edp - is the port on the CPU and attached to an eDP panel? - * @intel_dp: DP struct - * - * Returns true if the given DP struct corresponds to a CPU eDP port. - */ -static bool is_cpu_edp(struct intel_dp *intel_dp) -{ - return is_edp(intel_dp) && !is_pch_edp(intel_dp); -} - -static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) -{ - return container_of(encoder, struct intel_dp, base.base); -} - -static struct intel_dp *intel_attached_dp(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_dp, base); -} - -/** - * intel_encoder_is_pch_edp - is the given encoder a PCH attached eDP? - * @encoder: DRM encoder - * - * Return true if @encoder corresponds to a PCH attached eDP panel. Needed - * by intel_display.c. - */ -bool intel_encoder_is_pch_edp(struct drm_encoder *encoder) -{ - struct intel_dp *intel_dp; - - if (!encoder) - return false; - - intel_dp = enc_to_intel_dp(encoder); - - return is_pch_edp(intel_dp); -} - -static void intel_dp_start_link_train(struct intel_dp *intel_dp); -static void intel_dp_complete_link_train(struct intel_dp *intel_dp); -static void intel_dp_link_down(struct intel_dp *intel_dp); - -void -intel_edp_link_config(struct intel_encoder *intel_encoder, - int *lane_num, int *link_bw) -{ - struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); - - *lane_num = intel_dp->lane_count; - if (intel_dp->link_bw == DP_LINK_BW_1_62) - *link_bw = 162000; - else if (intel_dp->link_bw == DP_LINK_BW_2_7) - *link_bw = 270000; -} - -static int -intel_dp_max_lane_count(struct intel_dp *intel_dp) -{ - int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; - switch (max_lane_count) { - case 1: case 2: case 4: - break; - default: - max_lane_count = 4; - } - return max_lane_count; -} - -static int -intel_dp_max_link_bw(struct intel_dp *intel_dp) -{ - int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; - - switch (max_link_bw) { - case DP_LINK_BW_1_62: - case DP_LINK_BW_2_7: - break; - default: - max_link_bw = DP_LINK_BW_1_62; - break; - } - return max_link_bw; -} - -static int -intel_dp_link_clock(uint8_t link_bw) -{ - if (link_bw == DP_LINK_BW_2_7) - return 270000; - else - return 162000; -} - -/* - * The units on the numbers in the next two are... bizarre. Examples will - * make it clearer; this one parallels an example in the eDP spec. - * - * intel_dp_max_data_rate for one lane of 2.7GHz evaluates as: - * - * 270000 * 1 * 8 / 10 == 216000 - * - * The actual data capacity of that configuration is 2.16Gbit/s, so the - * units are decakilobits. ->clock in a drm_display_mode is in kilohertz - - * or equivalently, kilopixels per second - so for 1680x1050R it'd be - * 119000. At 18bpp that's 2142000 kilobits per second. - * - * Thus the strange-looking division by 10 in intel_dp_link_required, to - * get the result in decakilobits instead of kilobits. - */ - -static int -intel_dp_link_required(int pixel_clock, int bpp) -{ - return (pixel_clock * bpp + 9) / 10; -} - -static int -intel_dp_max_data_rate(int max_link_clock, int max_lanes) -{ - return (max_link_clock * max_lanes * 8) / 10; -} - -static bool -intel_dp_adjust_dithering(struct intel_dp *intel_dp, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); - int max_lanes = intel_dp_max_lane_count(intel_dp); - int max_rate, mode_rate; - - mode_rate = intel_dp_link_required(mode->clock, 24); - max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); - - if (mode_rate > max_rate) { - mode_rate = intel_dp_link_required(mode->clock, 18); - if (mode_rate > max_rate) - return false; - - if (adjusted_mode) - adjusted_mode->private_flags - |= INTEL_MODE_DP_FORCE_6BPC; - - return true; - } - - return true; -} - -static int -intel_dp_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - - if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { - if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) - return MODE_PANEL; - - if (mode->vdisplay > intel_dp->panel_fixed_mode->vdisplay) - return MODE_PANEL; - } - - if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) - return MODE_CLOCK_HIGH; - - if (mode->clock < 10000) - return MODE_CLOCK_LOW; - - return MODE_OK; -} - -static uint32_t -pack_aux(uint8_t *src, int src_bytes) -{ - int i; - uint32_t v = 0; - - if (src_bytes > 4) - src_bytes = 4; - for (i = 0; i < src_bytes; i++) - v |= ((uint32_t) src[i]) << ((3-i) * 8); - return v; -} - -static void -unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) -{ - int i; - if (dst_bytes > 4) - dst_bytes = 4; - for (i = 0; i < dst_bytes; i++) - dst[i] = src >> ((3-i) * 8); -} - -/* hrawclock is 1/4 the FSB frequency */ -static int -intel_hrawclk(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t clkcfg; - - clkcfg = I915_READ(CLKCFG); - switch (clkcfg & CLKCFG_FSB_MASK) { - case CLKCFG_FSB_400: - return 100; - case CLKCFG_FSB_533: - return 133; - case CLKCFG_FSB_667: - return 166; - case CLKCFG_FSB_800: - return 200; - case CLKCFG_FSB_1067: - return 266; - case CLKCFG_FSB_1333: - return 333; - /* these two are just a guess; one of them might be right */ - case CLKCFG_FSB_1600: - case CLKCFG_FSB_1600_ALT: - return 400; - default: - return 133; - } -} - -static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0; -} - -static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0; -} - -static void -intel_dp_check_edp(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!is_edp(intel_dp)) - return; - if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) { - WARN(1, "eDP powered off while attempting aux channel communication.\n"); - DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n", - I915_READ(PCH_PP_STATUS), - I915_READ(PCH_PP_CONTROL)); - } -} - -static int -intel_dp_aux_ch(struct intel_dp *intel_dp, - uint8_t *send, int send_bytes, - uint8_t *recv, int recv_size) -{ - uint32_t output_reg = intel_dp->output_reg; - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t ch_ctl = output_reg + 0x10; - uint32_t ch_data = ch_ctl + 4; - int i; - int recv_bytes; - uint32_t status; - uint32_t aux_clock_divider; - int try, precharge; - - intel_dp_check_edp(intel_dp); - /* The clock divider is based off the hrawclk, - * and would like to run at 2MHz. So, take the - * hrawclk value and divide by 2 and use that - * - * Note that PCH attached eDP panels should use a 125MHz input - * clock divider. - */ - if (is_cpu_edp(intel_dp)) { - if (IS_GEN6(dev) || IS_GEN7(dev)) - aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ - else - aux_clock_divider = 225; /* eDP input clock at 450Mhz */ - } else if (HAS_PCH_SPLIT(dev)) - aux_clock_divider = 63; /* IRL input clock fixed at 125Mhz */ - else - aux_clock_divider = intel_hrawclk(dev) / 2; - - if (IS_GEN6(dev)) - precharge = 3; - else - precharge = 5; - - /* Try to wait for any previous AUX channel activity */ - for (try = 0; try < 3; try++) { - status = I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - msleep(1); - } - - if (try == 3) { - WARN(1, "dp_aux_ch not started status 0x%08x\n", - I915_READ(ch_ctl)); - return -EBUSY; - } - - /* Must try at least 3 times according to DP spec */ - for (try = 0; try < 5; try++) { - /* Load the send data into the aux channel data registers */ - for (i = 0; i < send_bytes; i += 4) - I915_WRITE(ch_data + i, - pack_aux(send + i, send_bytes - i)); - - /* Send the command and wait for it to complete */ - I915_WRITE(ch_ctl, - DP_AUX_CH_CTL_SEND_BUSY | - DP_AUX_CH_CTL_TIME_OUT_400us | - (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | - (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR); - for (;;) { - status = I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - udelay(100); - } - - /* Clear done status and any errors */ - I915_WRITE(ch_ctl, - status | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR); - - if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR)) - continue; - if (status & DP_AUX_CH_CTL_DONE) - break; - } - - if ((status & DP_AUX_CH_CTL_DONE) == 0) { - DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); - return -EBUSY; - } - - /* Check for timeout or receive error. - * Timeouts occur when the sink is not connected - */ - if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { - DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); - return -EIO; - } - - /* Timeouts occur when the device isn't connected, so they're - * "normal" -- don't fill the kernel log with these */ - if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { - DRM_DEBUG_KMS("dp_aux_ch timeout status 0x%08x\n", status); - return -ETIMEDOUT; - } - - /* Unload any bytes sent back from the other side */ - recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> - DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); - if (recv_bytes > recv_size) - recv_bytes = recv_size; - - for (i = 0; i < recv_bytes; i += 4) - unpack_aux(I915_READ(ch_data + i), - recv + i, recv_bytes - i); - - return recv_bytes; -} - -/* Write data to the aux channel in native mode */ -static int -intel_dp_aux_native_write(struct intel_dp *intel_dp, - uint16_t address, uint8_t *send, int send_bytes) -{ - int ret; - uint8_t msg[20]; - int msg_bytes; - uint8_t ack; - - intel_dp_check_edp(intel_dp); - if (send_bytes > 16) - return -1; - msg[0] = AUX_NATIVE_WRITE << 4; - msg[1] = address >> 8; - msg[2] = address & 0xff; - msg[3] = send_bytes - 1; - memcpy(&msg[4], send, send_bytes); - msg_bytes = send_bytes + 4; - for (;;) { - ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); - if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - break; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(100); - else - return -EIO; - } - return send_bytes; -} - -/* Write a single byte to the aux channel in native mode */ -static int -intel_dp_aux_native_write_1(struct intel_dp *intel_dp, - uint16_t address, uint8_t byte) -{ - return intel_dp_aux_native_write(intel_dp, address, &byte, 1); -} - -/* read bytes from a native aux channel */ -static int -intel_dp_aux_native_read(struct intel_dp *intel_dp, - uint16_t address, uint8_t *recv, int recv_bytes) -{ - uint8_t msg[4]; - int msg_bytes; - uint8_t reply[20]; - int reply_bytes; - uint8_t ack; - int ret; - - intel_dp_check_edp(intel_dp); - msg[0] = AUX_NATIVE_READ << 4; - msg[1] = address >> 8; - msg[2] = address & 0xff; - msg[3] = recv_bytes - 1; - - msg_bytes = 4; - reply_bytes = recv_bytes + 1; - - for (;;) { - ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, - reply, reply_bytes); - if (ret == 0) - return -EPROTO; - if (ret < 0) - return ret; - ack = reply[0]; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) { - memcpy(recv, reply + 1, ret - 1); - return ret - 1; - } - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(100); - else - return -EIO; - } -} - -static int -intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, - uint8_t write_byte, uint8_t *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - struct intel_dp *intel_dp = container_of(adapter, - struct intel_dp, - adapter); - uint16_t address = algo_data->address; - uint8_t msg[5]; - uint8_t reply[2]; - unsigned retry; - int msg_bytes; - int reply_bytes; - int ret; - - intel_dp_check_edp(intel_dp); - /* Set up the command byte */ - if (mode & MODE_I2C_READ) - msg[0] = AUX_I2C_READ << 4; - else - msg[0] = AUX_I2C_WRITE << 4; - - if (!(mode & MODE_I2C_STOP)) - msg[0] |= AUX_I2C_MOT << 4; - - msg[1] = address >> 8; - msg[2] = address; - - switch (mode) { - case MODE_I2C_WRITE: - msg[3] = 0; - msg[4] = write_byte; - msg_bytes = 5; - reply_bytes = 1; - break; - case MODE_I2C_READ: - msg[3] = 0; - msg_bytes = 4; - reply_bytes = 2; - break; - default: - msg_bytes = 3; - reply_bytes = 1; - break; - } - - for (retry = 0; retry < 5; retry++) { - ret = intel_dp_aux_ch(intel_dp, - msg, msg_bytes, - reply, reply_bytes); - if (ret < 0) { - DRM_DEBUG_KMS("aux_ch failed %d\n", ret); - return ret; - } - - switch (reply[0] & AUX_NATIVE_REPLY_MASK) { - case AUX_NATIVE_REPLY_ACK: - /* I2C-over-AUX Reply field is only valid - * when paired with AUX ACK. - */ - break; - case AUX_NATIVE_REPLY_NACK: - DRM_DEBUG_KMS("aux_ch native nack\n"); - return -EREMOTEIO; - case AUX_NATIVE_REPLY_DEFER: - udelay(100); - continue; - default: - DRM_ERROR("aux_ch invalid native reply 0x%02x\n", - reply[0]); - return -EREMOTEIO; - } - - switch (reply[0] & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - if (mode == MODE_I2C_READ) { - *read_byte = reply[1]; - } - return reply_bytes - 1; - case AUX_I2C_REPLY_NACK: - DRM_DEBUG_KMS("aux_i2c nack\n"); - return -EREMOTEIO; - case AUX_I2C_REPLY_DEFER: - DRM_DEBUG_KMS("aux_i2c defer\n"); - udelay(100); - break; - default: - DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); - return -EREMOTEIO; - } - } - - DRM_ERROR("too many retries, giving up\n"); - return -EREMOTEIO; -} - -static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp); -static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync); - -static int -intel_dp_i2c_init(struct intel_dp *intel_dp, - struct intel_connector *intel_connector, const char *name) -{ - int ret; - - DRM_DEBUG_KMS("i2c_init %s\n", name); - intel_dp->algo.running = false; - intel_dp->algo.address = 0; - intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch; - - memset(&intel_dp->adapter, '\0', sizeof(intel_dp->adapter)); - intel_dp->adapter.owner = THIS_MODULE; - intel_dp->adapter.class = I2C_CLASS_DDC; - strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); - intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; - intel_dp->adapter.algo_data = &intel_dp->algo; - intel_dp->adapter.dev.parent = &intel_connector->base.kdev; - - ironlake_edp_panel_vdd_on(intel_dp); - ret = i2c_dp_aux_add_bus(&intel_dp->adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); - return ret; -} - -static bool -intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - int lane_count, clock; - int max_lane_count = intel_dp_max_lane_count(intel_dp); - int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; - int bpp; - static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; - - if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { - intel_fixed_panel_mode(intel_dp->panel_fixed_mode, adjusted_mode); - intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, - mode, adjusted_mode); - /* - * the mode->clock is used to calculate the Data&Link M/N - * of the pipe. For the eDP the fixed clock should be used. - */ - mode->clock = intel_dp->panel_fixed_mode->clock; - } - - if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) - return false; - - bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; - - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { - for (clock = 0; clock <= max_clock; clock++) { - int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); - - if (intel_dp_link_required(mode->clock, bpp) - <= link_avail) { - intel_dp->link_bw = bws[clock]; - intel_dp->lane_count = lane_count; - adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); - DRM_DEBUG_KMS("Display port link bw %02x lane " - "count %d clock %d\n", - intel_dp->link_bw, intel_dp->lane_count, - adjusted_mode->clock); - return true; - } - } - } - - return false; -} - -struct intel_dp_m_n { - uint32_t tu; - uint32_t gmch_m; - uint32_t gmch_n; - uint32_t link_m; - uint32_t link_n; -}; - -static void -intel_reduce_ratio(uint32_t *num, uint32_t *den) -{ - while (*num > 0xffffff || *den > 0xffffff) { - *num >>= 1; - *den >>= 1; - } -} - -static void -intel_dp_compute_m_n(int bpp, - int nlanes, - int pixel_clock, - int link_clock, - struct intel_dp_m_n *m_n) -{ - m_n->tu = 64; - m_n->gmch_m = (pixel_clock * bpp) >> 3; - m_n->gmch_n = link_clock * nlanes; - intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); - m_n->link_m = pixel_clock; - m_n->link_n = link_clock; - intel_reduce_ratio(&m_n->link_m, &m_n->link_n); -} - -void -intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_encoder *encoder; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int lane_count = 4; - struct intel_dp_m_n m_n; - int pipe = intel_crtc->pipe; - - /* - * Find the lane count in the intel_encoder private - */ - list_for_each_entry(encoder, &mode_config->encoder_list, head) { - struct intel_dp *intel_dp; - - if (encoder->crtc != crtc) - continue; - - intel_dp = enc_to_intel_dp(encoder); - if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || - intel_dp->base.type == INTEL_OUTPUT_EDP) - { - lane_count = intel_dp->lane_count; - break; - } - } - - /* - * Compute the GMCH and Link ratios. The '3' here is - * the number of bytes_per_pixel post-LUT, which we always - * set up for 8-bits of R/G/B, or 3 bytes total. - */ - intel_dp_compute_m_n(intel_crtc->bpp, lane_count, - mode->clock, adjusted_mode->clock, &m_n); - - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(TRANSDATA_M1(pipe), - ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | - m_n.gmch_m); - I915_WRITE(TRANSDATA_N1(pipe), m_n.gmch_n); - I915_WRITE(TRANSDPLINK_M1(pipe), m_n.link_m); - I915_WRITE(TRANSDPLINK_N1(pipe), m_n.link_n); - } else { - I915_WRITE(PIPE_GMCH_DATA_M(pipe), - ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | - m_n.gmch_m); - I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n.gmch_n); - I915_WRITE(PIPE_DP_LINK_M(pipe), m_n.link_m); - I915_WRITE(PIPE_DP_LINK_N(pipe), m_n.link_n); - } -} - -static void ironlake_edp_pll_on(struct drm_encoder *encoder); -static void ironlake_edp_pll_off(struct drm_encoder *encoder); - -static void -intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_crtc *crtc = intel_dp->base.base.crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - - /* Turn on the eDP PLL if needed */ - if (is_edp(intel_dp)) { - if (!is_pch_edp(intel_dp)) - ironlake_edp_pll_on(encoder); - else - ironlake_edp_pll_off(encoder); - } - - /* - * There are four kinds of DP registers: - * - * IBX PCH - * SNB CPU - * IVB CPU - * CPT PCH - * - * IBX PCH and CPU are the same for almost everything, - * except that the CPU DP PLL is configured in this - * register - * - * CPT PCH is quite different, having many bits moved - * to the TRANS_DP_CTL register instead. That - * configuration happens (oddly) in ironlake_pch_enable - */ - - /* Preserve the BIOS-computed detected bit. This is - * supposed to be read-only. - */ - intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; - intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; - - /* Handle DP bits in common between all three register formats */ - - intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; - - switch (intel_dp->lane_count) { - case 1: - intel_dp->DP |= DP_PORT_WIDTH_1; - break; - case 2: - intel_dp->DP |= DP_PORT_WIDTH_2; - break; - case 4: - intel_dp->DP |= DP_PORT_WIDTH_4; - break; - } - if (intel_dp->has_audio) { - DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n", - pipe_name(intel_crtc->pipe)); - intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; - intel_write_eld(encoder, adjusted_mode); - } - memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); - intel_dp->link_configuration[0] = intel_dp->link_bw; - intel_dp->link_configuration[1] = intel_dp->lane_count; - intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; - /* - * Check for DPCD version > 1.1 and enhanced framing support - */ - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && - (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { - intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - } - - /* Split out the IBX/CPU vs CPT settings */ - - if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) { - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - intel_dp->DP |= DP_SYNC_HS_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - intel_dp->DP |= DP_SYNC_VS_HIGH; - intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; - - if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) - intel_dp->DP |= DP_ENHANCED_FRAMING; - - intel_dp->DP |= intel_crtc->pipe << 29; - - /* don't miss out required setting for eDP */ - intel_dp->DP |= DP_PLL_ENABLE; - if (adjusted_mode->clock < 200000) - intel_dp->DP |= DP_PLL_FREQ_160MHZ; - else - intel_dp->DP |= DP_PLL_FREQ_270MHZ; - } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { - intel_dp->DP |= intel_dp->color_range; - - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - intel_dp->DP |= DP_SYNC_HS_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - intel_dp->DP |= DP_SYNC_VS_HIGH; - intel_dp->DP |= DP_LINK_TRAIN_OFF; - - if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) - intel_dp->DP |= DP_ENHANCED_FRAMING; - - if (intel_crtc->pipe == 1) - intel_dp->DP |= DP_PIPEB_SELECT; - - if (is_cpu_edp(intel_dp)) { - /* don't miss out required setting for eDP */ - intel_dp->DP |= DP_PLL_ENABLE; - if (adjusted_mode->clock < 200000) - intel_dp->DP |= DP_PLL_FREQ_160MHZ; - else - intel_dp->DP |= DP_PLL_FREQ_270MHZ; - } - } else { - intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; - } -} - -#define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) -#define IDLE_ON_VALUE (PP_ON | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE) - -#define IDLE_OFF_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) -#define IDLE_OFF_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) - -#define IDLE_CYCLE_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) -#define IDLE_CYCLE_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) - -static void ironlake_wait_panel_status(struct intel_dp *intel_dp, - u32 mask, - u32 value) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", - mask, value, - I915_READ(PCH_PP_STATUS), - I915_READ(PCH_PP_CONTROL)); - - if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) { - DRM_ERROR("Panel status timeout: status %08x control %08x\n", - I915_READ(PCH_PP_STATUS), - I915_READ(PCH_PP_CONTROL)); - } -} - -static void ironlake_wait_panel_on(struct intel_dp *intel_dp) -{ - DRM_DEBUG_KMS("Wait for panel power on\n"); - ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE); -} - -static void ironlake_wait_panel_off(struct intel_dp *intel_dp) -{ - DRM_DEBUG_KMS("Wait for panel power off time\n"); - ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE); -} - -static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp) -{ - DRM_DEBUG_KMS("Wait for panel power cycle\n"); - ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE); -} - - -/* Read the current pp_control value, unlocking the register if it - * is locked - */ - -static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv) -{ - u32 control = I915_READ(PCH_PP_CONTROL); - - control &= ~PANEL_UNLOCK_MASK; - control |= PANEL_UNLOCK_REGS; - return control; -} - -static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; - - if (!is_edp(intel_dp)) - return; - DRM_DEBUG_KMS("Turn eDP VDD on\n"); - - WARN(intel_dp->want_panel_vdd, - "eDP VDD already requested on\n"); - - intel_dp->want_panel_vdd = true; - - if (ironlake_edp_have_panel_vdd(intel_dp)) { - DRM_DEBUG_KMS("eDP VDD already on\n"); - return; - } - - if (!ironlake_edp_have_panel_power(intel_dp)) - ironlake_wait_panel_power_cycle(intel_dp); - - pp = ironlake_get_pp_control(dev_priv); - pp |= EDP_FORCE_VDD; - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", - I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); - - /* - * If the panel wasn't on, delay before accessing aux channel - */ - if (!ironlake_edp_have_panel_power(intel_dp)) { - DRM_DEBUG_KMS("eDP was not running\n"); - msleep(intel_dp->panel_power_up_delay); - } -} - -static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; - - if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { - pp = ironlake_get_pp_control(dev_priv); - pp &= ~EDP_FORCE_VDD; - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - - /* Make sure sequencer is idle before allowing subsequent activity */ - DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", - I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); - - msleep(intel_dp->panel_power_down_delay); - } -} - -static void ironlake_panel_vdd_work(struct work_struct *__work) -{ - struct intel_dp *intel_dp = container_of(to_delayed_work(__work), - struct intel_dp, panel_vdd_work); - struct drm_device *dev = intel_dp->base.base.dev; - - mutex_lock(&dev->mode_config.mutex); - ironlake_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev->mode_config.mutex); -} - -static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) -{ - if (!is_edp(intel_dp)) - return; - - DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd); - WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); - - intel_dp->want_panel_vdd = false; - - if (sync) { - ironlake_panel_vdd_off_sync(intel_dp); - } else { - /* - * Queue the timer to fire a long - * time from now (relative to the power down delay) - * to keep the panel power up across a sequence of operations - */ - schedule_delayed_work(&intel_dp->panel_vdd_work, - msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5)); - } -} - -static void ironlake_edp_panel_on(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; - - if (!is_edp(intel_dp)) - return; - - DRM_DEBUG_KMS("Turn eDP power on\n"); - - if (ironlake_edp_have_panel_power(intel_dp)) { - DRM_DEBUG_KMS("eDP power already on\n"); - return; - } - - ironlake_wait_panel_power_cycle(intel_dp); - - pp = ironlake_get_pp_control(dev_priv); - if (IS_GEN5(dev)) { - /* ILK workaround: disable reset around power sequence */ - pp &= ~PANEL_POWER_RESET; - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - } - - pp |= POWER_TARGET_ON; - if (!IS_GEN5(dev)) - pp |= PANEL_POWER_RESET; - - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - - ironlake_wait_panel_on(intel_dp); - - if (IS_GEN5(dev)) { - pp |= PANEL_POWER_RESET; /* restore panel reset bit */ - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - } -} - -static void ironlake_edp_panel_off(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; - - if (!is_edp(intel_dp)) - return; - - DRM_DEBUG_KMS("Turn eDP power off\n"); - - WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); - - pp = ironlake_get_pp_control(dev_priv); - pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - - ironlake_wait_panel_off(intel_dp); -} - -static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; - - if (!is_edp(intel_dp)) - return; - - DRM_DEBUG_KMS("\n"); - /* - * If we enable the backlight right away following a panel power - * on, we may see slight flicker as the panel syncs with the eDP - * link. So delay a bit to make sure the image is solid before - * allowing it to appear. - */ - msleep(intel_dp->backlight_on_delay); - pp = ironlake_get_pp_control(dev_priv); - pp |= EDP_BLC_ENABLE; - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); -} - -static void ironlake_edp_backlight_off(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; - - if (!is_edp(intel_dp)) - return; - - DRM_DEBUG_KMS("\n"); - pp = ironlake_get_pp_control(dev_priv); - pp &= ~EDP_BLC_ENABLE; - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); - msleep(intel_dp->backlight_off_delay); -} - -static void ironlake_edp_pll_on(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpa_ctl; - - DRM_DEBUG_KMS("\n"); - dpa_ctl = I915_READ(DP_A); - dpa_ctl |= DP_PLL_ENABLE; - I915_WRITE(DP_A, dpa_ctl); - POSTING_READ(DP_A); - udelay(200); -} - -static void ironlake_edp_pll_off(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 dpa_ctl; - - dpa_ctl = I915_READ(DP_A); - dpa_ctl &= ~DP_PLL_ENABLE; - I915_WRITE(DP_A, dpa_ctl); - POSTING_READ(DP_A); - udelay(200); -} - -/* If the sink supports it, try to set the power state appropriately */ -static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) -{ - int ret, i; - - /* Should have a valid DPCD by this point */ - if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) - return; - - if (mode != DRM_MODE_DPMS_ON) { - ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER, - DP_SET_POWER_D3); - if (ret != 1) - DRM_DEBUG_DRIVER("failed to write sink power state\n"); - } else { - /* - * When turning on, we need to retry for 1ms to give the sink - * time to wake up. - */ - for (i = 0; i < 3; i++) { - ret = intel_dp_aux_native_write_1(intel_dp, - DP_SET_POWER, - DP_SET_POWER_D0); - if (ret == 1) - break; - msleep(1); - } - } -} - -static void intel_dp_prepare(struct drm_encoder *encoder) -{ - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - - /* Make sure the panel is off before trying to change the mode. But also - * ensure that we have vdd while we switch off the panel. */ - ironlake_edp_panel_vdd_on(intel_dp); - ironlake_edp_backlight_off(intel_dp); - ironlake_edp_panel_off(intel_dp); - - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); - intel_dp_link_down(intel_dp); - ironlake_edp_panel_vdd_off(intel_dp, false); -} - -static void intel_dp_commit(struct drm_encoder *encoder) -{ - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_device *dev = encoder->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); - - ironlake_edp_panel_vdd_on(intel_dp); - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); - intel_dp_start_link_train(intel_dp); - ironlake_edp_panel_on(intel_dp); - ironlake_edp_panel_vdd_off(intel_dp, true); - intel_dp_complete_link_train(intel_dp); - ironlake_edp_backlight_on(intel_dp); - - intel_dp->dpms_mode = DRM_MODE_DPMS_ON; - - if (HAS_PCH_CPT(dev)) - intel_cpt_verify_modeset(dev, intel_crtc->pipe); -} - -static void -intel_dp_dpms(struct drm_encoder *encoder, int mode) -{ - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t dp_reg = I915_READ(intel_dp->output_reg); - - if (mode != DRM_MODE_DPMS_ON) { - /* Switching the panel off requires vdd. */ - ironlake_edp_panel_vdd_on(intel_dp); - ironlake_edp_backlight_off(intel_dp); - ironlake_edp_panel_off(intel_dp); - - intel_dp_sink_dpms(intel_dp, mode); - intel_dp_link_down(intel_dp); - ironlake_edp_panel_vdd_off(intel_dp, false); - - if (is_cpu_edp(intel_dp)) - ironlake_edp_pll_off(encoder); - } else { - if (is_cpu_edp(intel_dp)) - ironlake_edp_pll_on(encoder); - - ironlake_edp_panel_vdd_on(intel_dp); - intel_dp_sink_dpms(intel_dp, mode); - if (!(dp_reg & DP_PORT_EN)) { - intel_dp_start_link_train(intel_dp); - ironlake_edp_panel_on(intel_dp); - ironlake_edp_panel_vdd_off(intel_dp, true); - intel_dp_complete_link_train(intel_dp); - } else - ironlake_edp_panel_vdd_off(intel_dp, false); - ironlake_edp_backlight_on(intel_dp); - } - intel_dp->dpms_mode = mode; -} - -/* - * Native read with retry for link status and receiver capability reads for - * cases where the sink may still be asleep. - */ -static bool -intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, - uint8_t *recv, int recv_bytes) -{ - int ret, i; - - /* - * Sinks are *supposed* to come up within 1ms from an off state, - * but we're also supposed to retry 3 times per the spec. - */ - for (i = 0; i < 3; i++) { - ret = intel_dp_aux_native_read(intel_dp, address, recv, - recv_bytes); - if (ret == recv_bytes) - return true; - msleep(1); - } - - return false; -} - -/* - * Fetch AUX CH registers 0x202 - 0x207 which contain - * link status information - */ -static bool -intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) -{ - return intel_dp_aux_native_read_retry(intel_dp, - DP_LANE0_1_STATUS, - link_status, - DP_LINK_STATUS_SIZE); -} - -static uint8_t -intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], - int r) -{ - return link_status[r - DP_LANE0_1_STATUS]; -} - -static uint8_t -intel_get_adjust_request_voltage(uint8_t adjust_request[2], - int lane) -{ - int s = ((lane & 1) ? - DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : - DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); - uint8_t l = adjust_request[lane>>1]; - - return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; -} - -static uint8_t -intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2], - int lane) -{ - int s = ((lane & 1) ? - DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : - DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); - uint8_t l = adjust_request[lane>>1]; - - return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; -} - - -#if 0 -static char *voltage_names[] = { - "0.4V", "0.6V", "0.8V", "1.2V" -}; -static char *pre_emph_names[] = { - "0dB", "3.5dB", "6dB", "9.5dB" -}; -static char *link_train_names[] = { - "pattern 1", "pattern 2", "idle", "off" -}; -#endif - -/* - * These are source-specific values; current Intel hardware supports - * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB - */ - -static uint8_t -intel_dp_voltage_max(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - - if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) - return DP_TRAIN_VOLTAGE_SWING_800; - else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) - return DP_TRAIN_VOLTAGE_SWING_1200; - else - return DP_TRAIN_VOLTAGE_SWING_800; -} - -static uint8_t -intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) -{ - struct drm_device *dev = intel_dp->base.base.dev; - - if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_600: - case DP_TRAIN_VOLTAGE_SWING_800: - return DP_TRAIN_PRE_EMPHASIS_3_5; - default: - return DP_TRAIN_PRE_EMPHASIS_0; - } - } else { - switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_600: - return DP_TRAIN_PRE_EMPHASIS_6; - case DP_TRAIN_VOLTAGE_SWING_800: - return DP_TRAIN_PRE_EMPHASIS_3_5; - case DP_TRAIN_VOLTAGE_SWING_1200: - default: - return DP_TRAIN_PRE_EMPHASIS_0; - } - } -} - -static void -intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) -{ - uint8_t v = 0; - uint8_t p = 0; - int lane; - uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); - uint8_t voltage_max; - uint8_t preemph_max; - - for (lane = 0; lane < intel_dp->lane_count; lane++) { - uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); - uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane); - - if (this_v > v) - v = this_v; - if (this_p > p) - p = this_p; - } - - voltage_max = intel_dp_voltage_max(intel_dp); - if (v >= voltage_max) - v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; - - preemph_max = intel_dp_pre_emphasis_max(intel_dp, v); - if (p >= preemph_max) - p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - - for (lane = 0; lane < 4; lane++) - intel_dp->train_set[lane] = v | p; -} - -static uint32_t -intel_dp_signal_levels(uint8_t train_set) -{ - uint32_t signal_levels = 0; - - switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { - case DP_TRAIN_VOLTAGE_SWING_400: - default: - signal_levels |= DP_VOLTAGE_0_4; - break; - case DP_TRAIN_VOLTAGE_SWING_600: - signal_levels |= DP_VOLTAGE_0_6; - break; - case DP_TRAIN_VOLTAGE_SWING_800: - signal_levels |= DP_VOLTAGE_0_8; - break; - case DP_TRAIN_VOLTAGE_SWING_1200: - signal_levels |= DP_VOLTAGE_1_2; - break; - } - switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { - case DP_TRAIN_PRE_EMPHASIS_0: - default: - signal_levels |= DP_PRE_EMPHASIS_0; - break; - case DP_TRAIN_PRE_EMPHASIS_3_5: - signal_levels |= DP_PRE_EMPHASIS_3_5; - break; - case DP_TRAIN_PRE_EMPHASIS_6: - signal_levels |= DP_PRE_EMPHASIS_6; - break; - case DP_TRAIN_PRE_EMPHASIS_9_5: - signal_levels |= DP_PRE_EMPHASIS_9_5; - break; - } - return signal_levels; -} - -/* Gen6's DP voltage swing and pre-emphasis control */ -static uint32_t -intel_gen6_edp_signal_levels(uint8_t train_set) -{ - int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | - DP_TRAIN_PRE_EMPHASIS_MASK); - switch (signal_levels) { - case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: - case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0: - return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B; - case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5: - return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B; - case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: - case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6: - return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B; - case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: - case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5: - return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B; - case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: - case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0: - return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B; - default: - DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" - "0x%x\n", signal_levels); - return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B; - } -} - -/* Gen7's DP voltage swing and pre-emphasis control */ -static uint32_t -intel_gen7_edp_signal_levels(uint8_t train_set) -{ - int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | - DP_TRAIN_PRE_EMPHASIS_MASK); - switch (signal_levels) { - case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: - return EDP_LINK_TRAIN_400MV_0DB_IVB; - case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5: - return EDP_LINK_TRAIN_400MV_3_5DB_IVB; - case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: - return EDP_LINK_TRAIN_400MV_6DB_IVB; - - case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0: - return EDP_LINK_TRAIN_600MV_0DB_IVB; - case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: - return EDP_LINK_TRAIN_600MV_3_5DB_IVB; - - case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: - return EDP_LINK_TRAIN_800MV_0DB_IVB; - case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5: - return EDP_LINK_TRAIN_800MV_3_5DB_IVB; - - default: - DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" - "0x%x\n", signal_levels); - return EDP_LINK_TRAIN_500MV_0DB_IVB; - } -} - -static uint8_t -intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int s = (lane & 1) * 4; - uint8_t l = link_status[lane>>1]; - - return (l >> s) & 0xf; -} - -/* Check for clock recovery is done on all channels */ -static bool -intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) -{ - int lane; - uint8_t lane_status; - - for (lane = 0; lane < lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); - if ((lane_status & DP_LANE_CR_DONE) == 0) - return false; - } - return true; -} - -/* Check to see if channel eq is done on all channels */ -#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\ - DP_LANE_CHANNEL_EQ_DONE|\ - DP_LANE_SYMBOL_LOCKED) -static bool -intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) -{ - uint8_t lane_align; - uint8_t lane_status; - int lane; - - lane_align = intel_dp_link_status(link_status, - DP_LANE_ALIGN_STATUS_UPDATED); - if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) - return false; - for (lane = 0; lane < intel_dp->lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); - if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) - return false; - } - return true; -} - -static bool -intel_dp_set_link_train(struct intel_dp *intel_dp, - uint32_t dp_reg_value, - uint8_t dp_train_pat) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - I915_WRITE(intel_dp->output_reg, dp_reg_value); - POSTING_READ(intel_dp->output_reg); - - intel_dp_aux_native_write_1(intel_dp, - DP_TRAINING_PATTERN_SET, - dp_train_pat); - - ret = intel_dp_aux_native_write(intel_dp, - DP_TRAINING_LANE0_SET, - intel_dp->train_set, - intel_dp->lane_count); - if (ret != intel_dp->lane_count) - return false; - - return true; -} - -/* Enable corresponding port and start training pattern 1 */ -static void -intel_dp_start_link_train(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); - int i; - uint8_t voltage; - bool clock_recovery = false; - int voltage_tries, loop_tries; - u32 reg; - uint32_t DP = intel_dp->DP; - - /* - * On CPT we have to enable the port in training pattern 1, which - * will happen below in intel_dp_set_link_train. Otherwise, enable - * the port and wait for it to become active. - */ - if (!HAS_PCH_CPT(dev)) { - I915_WRITE(intel_dp->output_reg, intel_dp->DP); - POSTING_READ(intel_dp->output_reg); - intel_wait_for_vblank(dev, intel_crtc->pipe); - } - - /* Write the link configuration data */ - intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, - intel_dp->link_configuration, - DP_LINK_CONFIGURATION_SIZE); - - DP |= DP_PORT_EN; - - if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) - DP &= ~DP_LINK_TRAIN_MASK_CPT; - else - DP &= ~DP_LINK_TRAIN_MASK; - memset(intel_dp->train_set, 0, 4); - voltage = 0xff; - voltage_tries = 0; - loop_tries = 0; - clock_recovery = false; - for (;;) { - /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ - uint8_t link_status[DP_LINK_STATUS_SIZE]; - uint32_t signal_levels; - - - if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { - signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]); - DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels; - } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { - signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); - DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; - } else { - signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); - DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels); - DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - } - - if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) - reg = DP | DP_LINK_TRAIN_PAT_1_CPT; - else - reg = DP | DP_LINK_TRAIN_PAT_1; - - if (!intel_dp_set_link_train(intel_dp, reg, - DP_TRAINING_PATTERN_1 | - DP_LINK_SCRAMBLING_DISABLE)) - break; - /* Set training pattern 1 */ - - udelay(100); - if (!intel_dp_get_link_status(intel_dp, link_status)) { - DRM_ERROR("failed to get link status\n"); - break; - } - - if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { - DRM_DEBUG_KMS("clock recovery OK\n"); - clock_recovery = true; - break; - } - - /* Check to see if we've tried the max voltage */ - for (i = 0; i < intel_dp->lane_count; i++) - if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) - break; - if (i == intel_dp->lane_count) { - ++loop_tries; - if (loop_tries == 5) { - DRM_DEBUG_KMS("too many full retries, give up\n"); - break; - } - memset(intel_dp->train_set, 0, 4); - voltage_tries = 0; - continue; - } - - /* Check to see if we've tried the same voltage 5 times */ - if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { - ++voltage_tries; - if (voltage_tries == 5) { - DRM_DEBUG_KMS("too many voltage retries, give up\n"); - break; - } - } else - voltage_tries = 0; - voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - - /* Compute new intel_dp->train_set as requested by target */ - intel_get_adjust_train(intel_dp, link_status); - } - - intel_dp->DP = DP; -} - -static void -intel_dp_complete_link_train(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - bool channel_eq = false; - int tries, cr_tries; - u32 reg; - uint32_t DP = intel_dp->DP; - - /* channel equalization */ - tries = 0; - cr_tries = 0; - channel_eq = false; - for (;;) { - /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ - uint32_t signal_levels; - uint8_t link_status[DP_LINK_STATUS_SIZE]; - - if (cr_tries > 5) { - DRM_ERROR("failed to train DP, aborting\n"); - intel_dp_link_down(intel_dp); - break; - } - - if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { - signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]); - DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels; - } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { - signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); - DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; - } else { - signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); - DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - } - - if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) - reg = DP | DP_LINK_TRAIN_PAT_2_CPT; - else - reg = DP | DP_LINK_TRAIN_PAT_2; - - /* channel eq pattern */ - if (!intel_dp_set_link_train(intel_dp, reg, - DP_TRAINING_PATTERN_2 | - DP_LINK_SCRAMBLING_DISABLE)) - break; - - udelay(400); - if (!intel_dp_get_link_status(intel_dp, link_status)) - break; - - /* Make sure clock is still ok */ - if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { - intel_dp_start_link_train(intel_dp); - cr_tries++; - continue; - } - - if (intel_channel_eq_ok(intel_dp, link_status)) { - channel_eq = true; - break; - } - - /* Try 5 times, then try clock recovery if that fails */ - if (tries > 5) { - intel_dp_link_down(intel_dp); - intel_dp_start_link_train(intel_dp); - tries = 0; - cr_tries++; - continue; - } - - /* Compute new intel_dp->train_set as requested by target */ - intel_get_adjust_train(intel_dp, link_status); - ++tries; - } - - if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) - reg = DP | DP_LINK_TRAIN_OFF_CPT; - else - reg = DP | DP_LINK_TRAIN_OFF; - - I915_WRITE(intel_dp->output_reg, reg); - POSTING_READ(intel_dp->output_reg); - intel_dp_aux_native_write_1(intel_dp, - DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); -} - -static void -intel_dp_link_down(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t DP = intel_dp->DP; - - if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) - return; - - DRM_DEBUG_KMS("\n"); - - if (is_edp(intel_dp)) { - DP &= ~DP_PLL_ENABLE; - I915_WRITE(intel_dp->output_reg, DP); - POSTING_READ(intel_dp->output_reg); - udelay(100); - } - - if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) { - DP &= ~DP_LINK_TRAIN_MASK_CPT; - I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); - } else { - DP &= ~DP_LINK_TRAIN_MASK; - I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); - } - POSTING_READ(intel_dp->output_reg); - - msleep(17); - - if (is_edp(intel_dp)) { - if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) - DP |= DP_LINK_TRAIN_OFF_CPT; - else - DP |= DP_LINK_TRAIN_OFF; - } - - if (!HAS_PCH_CPT(dev) && - I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { - struct drm_crtc *crtc = intel_dp->base.base.crtc; - - /* Hardware workaround: leaving our transcoder select - * set to transcoder B while it's off will prevent the - * corresponding HDMI output on transcoder A. - * - * Combine this with another hardware workaround: - * transcoder select bit can only be cleared while the - * port is enabled. - */ - DP &= ~DP_PIPEB_SELECT; - I915_WRITE(intel_dp->output_reg, DP); - - /* Changes to enable or select take place the vblank - * after being written. - */ - if (crtc == NULL) { - /* We can arrive here never having been attached - * to a CRTC, for instance, due to inheriting - * random state from the BIOS. - * - * If the pipe is not running, play safe and - * wait for the clocks to stabilise before - * continuing. - */ - POSTING_READ(intel_dp->output_reg); - msleep(50); - } else - intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); - } - - DP &= ~DP_AUDIO_OUTPUT_ENABLE; - I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); - POSTING_READ(intel_dp->output_reg); - msleep(intel_dp->panel_power_down_delay); -} - -static bool -intel_dp_get_dpcd(struct intel_dp *intel_dp) -{ - if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, - sizeof(intel_dp->dpcd)) && - (intel_dp->dpcd[DP_DPCD_REV] != 0)) { - return true; - } - - return false; -} - -static bool -intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector) -{ - int ret; - - ret = intel_dp_aux_native_read_retry(intel_dp, - DP_DEVICE_SERVICE_IRQ_VECTOR, - sink_irq_vector, 1); - if (!ret) - return false; - - return true; -} - -static void -intel_dp_handle_test_request(struct intel_dp *intel_dp) -{ - /* NAK by default */ - intel_dp_aux_native_write_1(intel_dp, DP_TEST_RESPONSE, DP_TEST_ACK); -} - -/* - * According to DP spec - * 5.1.2: - * 1. Read DPCD - * 2. Configure link according to Receiver Capabilities - * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 - * 4. Check link status on receipt of hot-plug interrupt - */ - -static void -intel_dp_check_link_status(struct intel_dp *intel_dp) -{ - u8 sink_irq_vector; - u8 link_status[DP_LINK_STATUS_SIZE]; - - if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) - return; - - if (!intel_dp->base.base.crtc) - return; - - /* Try to read receiver status if the link appears to be up */ - if (!intel_dp_get_link_status(intel_dp, link_status)) { - intel_dp_link_down(intel_dp); - return; - } - - /* Now read the DPCD to see if it's actually running */ - if (!intel_dp_get_dpcd(intel_dp)) { - intel_dp_link_down(intel_dp); - return; - } - - /* Try to read the source of the interrupt */ - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && - intel_dp_get_sink_irq(intel_dp, &sink_irq_vector)) { - /* Clear interrupt source */ - intel_dp_aux_native_write_1(intel_dp, - DP_DEVICE_SERVICE_IRQ_VECTOR, - sink_irq_vector); - - if (sink_irq_vector & DP_AUTOMATED_TEST_REQUEST) - intel_dp_handle_test_request(intel_dp); - if (sink_irq_vector & (DP_CP_IRQ | DP_SINK_SPECIFIC_IRQ)) - DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); - } - - if (!intel_channel_eq_ok(intel_dp, link_status)) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - drm_get_encoder_name(&intel_dp->base.base)); - intel_dp_start_link_train(intel_dp); - intel_dp_complete_link_train(intel_dp); - } -} - -static enum drm_connector_status -intel_dp_detect_dpcd(struct intel_dp *intel_dp) -{ - if (intel_dp_get_dpcd(intel_dp)) - return connector_status_connected; - return connector_status_disconnected; -} - -static enum drm_connector_status -ironlake_dp_detect(struct intel_dp *intel_dp) -{ - enum drm_connector_status status; - - /* Can't disconnect eDP, but you can close the lid... */ - if (is_edp(intel_dp)) { - status = intel_panel_detect(intel_dp->base.base.dev); - if (status == connector_status_unknown) - status = connector_status_connected; - return status; - } - - return intel_dp_detect_dpcd(intel_dp); -} - -static enum drm_connector_status -g4x_dp_detect(struct intel_dp *intel_dp) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t temp, bit; - - switch (intel_dp->output_reg) { - case DP_B: - bit = DPB_HOTPLUG_INT_STATUS; - break; - case DP_C: - bit = DPC_HOTPLUG_INT_STATUS; - break; - case DP_D: - bit = DPD_HOTPLUG_INT_STATUS; - break; - default: - return connector_status_unknown; - } - - temp = I915_READ(PORT_HOTPLUG_STAT); - - if ((temp & bit) == 0) - return connector_status_disconnected; - - return intel_dp_detect_dpcd(intel_dp); -} - -static struct edid * -intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct edid *edid; - - ironlake_edp_panel_vdd_on(intel_dp); - edid = drm_get_edid(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); - return edid; -} - -static int -intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *adapter) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - int ret; - - ironlake_edp_panel_vdd_on(intel_dp); - ret = intel_ddc_get_modes(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); - return ret; -} - - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. - * - * \return true if DP port is connected. - * \return false if DP port is disconnected. - */ -static enum drm_connector_status -intel_dp_detect(struct drm_connector *connector, bool force) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct drm_device *dev = intel_dp->base.base.dev; - enum drm_connector_status status; - struct edid *edid = NULL; - - intel_dp->has_audio = false; - - if (HAS_PCH_SPLIT(dev)) - status = ironlake_dp_detect(intel_dp); - else - status = g4x_dp_detect(intel_dp); - - DRM_DEBUG_KMS("DPCD: %02hx%02hx%02hx%02hx%02hx%02hx%02hx%02hx\n", - intel_dp->dpcd[0], intel_dp->dpcd[1], intel_dp->dpcd[2], - intel_dp->dpcd[3], intel_dp->dpcd[4], intel_dp->dpcd[5], - intel_dp->dpcd[6], intel_dp->dpcd[7]); - - if (status != connector_status_connected) - return status; - - if (intel_dp->force_audio != HDMI_AUDIO_AUTO) { - intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON); - } else { - edid = intel_dp_get_edid(connector, &intel_dp->adapter); - if (edid) { - intel_dp->has_audio = drm_detect_monitor_audio(edid); - connector->display_info.raw_edid = NULL; - kfree(edid); - } - } - - return connector_status_connected; -} - -static int intel_dp_get_modes(struct drm_connector *connector) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - /* We should parse the EDID data and find out if it has an audio sink - */ - - ret = intel_dp_get_edid_modes(connector, &intel_dp->adapter); - if (ret) { - if (is_edp(intel_dp) && !intel_dp->panel_fixed_mode) { - struct drm_display_mode *newmode; - list_for_each_entry(newmode, &connector->probed_modes, - head) { - if ((newmode->type & DRM_MODE_TYPE_PREFERRED)) { - intel_dp->panel_fixed_mode = - drm_mode_duplicate(dev, newmode); - break; - } - } - } - return ret; - } - - /* if eDP has no EDID, try to use fixed panel mode from VBT */ - if (is_edp(intel_dp)) { - /* initialize panel mode from VBT if available for eDP */ - if (intel_dp->panel_fixed_mode == NULL && dev_priv->lfp_lvds_vbt_mode != NULL) { - intel_dp->panel_fixed_mode = - drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); - if (intel_dp->panel_fixed_mode) { - intel_dp->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - } - } - if (intel_dp->panel_fixed_mode) { - struct drm_display_mode *mode; - mode = drm_mode_duplicate(dev, intel_dp->panel_fixed_mode); - drm_mode_probed_add(connector, mode); - return 1; - } - } - return 0; -} - -static bool -intel_dp_detect_audio(struct drm_connector *connector) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct edid *edid; - bool has_audio = false; - - edid = intel_dp_get_edid(connector, &intel_dp->adapter); - if (edid) { - has_audio = drm_detect_monitor_audio(edid); - - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - return has_audio; -} - -static int -intel_dp_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_dp *intel_dp = intel_attached_dp(connector); - int ret; - - ret = drm_connector_property_set_value(connector, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_dp->force_audio) - return 0; - - intel_dp->force_audio = i; - - if (i == HDMI_AUDIO_AUTO) - has_audio = intel_dp_detect_audio(connector); - else - has_audio = (i == HDMI_AUDIO_ON); - - if (has_audio == intel_dp->has_audio) - return 0; - - intel_dp->has_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - if (val == !!intel_dp->color_range) - return 0; - - intel_dp->color_range = val ? DP_COLOR_RANGE_16_235 : 0; - goto done; - } - - return -EINVAL; - -done: - if (intel_dp->base.base.crtc) { - struct drm_crtc *crtc = intel_dp->base.base.crtc; - drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, - crtc->fb); - } - - return 0; -} - -static void -intel_dp_destroy(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - - if (intel_dpd_is_edp(dev)) - intel_panel_destroy_backlight(dev); - - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static void intel_dp_encoder_destroy(struct drm_encoder *encoder) -{ - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - i2c_del_adapter(&intel_dp->adapter); - drm_encoder_cleanup(encoder); - if (is_edp(intel_dp)) { - cancel_delayed_work_sync(&intel_dp->panel_vdd_work); - ironlake_panel_vdd_off_sync(intel_dp); - } - kfree(intel_dp); -} - -static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { - .dpms = intel_dp_dpms, - .mode_fixup = intel_dp_mode_fixup, - .prepare = intel_dp_prepare, - .mode_set = intel_dp_mode_set, - .commit = intel_dp_commit, -}; - -static const struct drm_connector_funcs intel_dp_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = intel_dp_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_dp_set_property, - .destroy = intel_dp_destroy, -}; - -static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { - .get_modes = intel_dp_get_modes, - .mode_valid = intel_dp_mode_valid, - .best_encoder = intel_best_encoder, -}; - -static const struct drm_encoder_funcs intel_dp_enc_funcs = { - .destroy = intel_dp_encoder_destroy, -}; - -static void -intel_dp_hot_plug(struct intel_encoder *intel_encoder) -{ - struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); - - intel_dp_check_link_status(intel_dp); -} - -/* Return which DP Port should be selected for Transcoder DP control */ -int -intel_trans_dp_port_sel(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_encoder *encoder; - - list_for_each_entry(encoder, &mode_config->encoder_list, head) { - struct intel_dp *intel_dp; - - if (encoder->crtc != crtc) - continue; - - intel_dp = enc_to_intel_dp(encoder); - if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || - intel_dp->base.type == INTEL_OUTPUT_EDP) - return intel_dp->output_reg; - } - - return -1; -} - -/* check the VBT to see whether the eDP is on DP-D port */ -bool intel_dpd_is_edp(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct child_device_config *p_child; - int i; - - if (!dev_priv->child_dev_num) - return false; - - for (i = 0; i < dev_priv->child_dev_num; i++) { - p_child = dev_priv->child_dev + i; - - if (p_child->dvo_port == PORT_IDPD && - p_child->device_type == DEVICE_TYPE_eDP) - return true; - } - return false; -} - -static void -intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) -{ - intel_attach_force_audio_property(connector); - intel_attach_broadcast_rgb_property(connector); -} - -void -intel_dp_init(struct drm_device *dev, int output_reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - struct intel_dp *intel_dp; - struct intel_encoder *intel_encoder; - struct intel_connector *intel_connector; - const char *name = NULL; - int type; - - intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL); - if (!intel_dp) - return; - - intel_dp->output_reg = output_reg; - intel_dp->dpms_mode = -1; - - intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); - if (!intel_connector) { - kfree(intel_dp); - return; - } - intel_encoder = &intel_dp->base; - - if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D) - if (intel_dpd_is_edp(dev)) - intel_dp->is_pch_edp = true; - - if (output_reg == DP_A || is_pch_edp(intel_dp)) { - type = DRM_MODE_CONNECTOR_eDP; - intel_encoder->type = INTEL_OUTPUT_EDP; - } else { - type = DRM_MODE_CONNECTOR_DisplayPort; - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; - } - - connector = &intel_connector->base; - drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); - drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); - - connector->polled = DRM_CONNECTOR_POLL_HPD; - - if (output_reg == DP_B || output_reg == PCH_DP_B) - intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); - else if (output_reg == DP_C || output_reg == PCH_DP_C) - intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); - else if (output_reg == DP_D || output_reg == PCH_DP_D) - intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); - - if (is_edp(intel_dp)) { - intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); - INIT_DELAYED_WORK(&intel_dp->panel_vdd_work, - ironlake_panel_vdd_work); - } - - intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); - connector->interlace_allowed = true; - connector->doublescan_allowed = 0; - - drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs, - DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs); - - intel_connector_attach_encoder(intel_connector, intel_encoder); - drm_sysfs_connector_add(connector); - - /* Set up the DDC bus. */ - switch (output_reg) { - case DP_A: - name = "DPDDC-A"; - break; - case DP_B: - case PCH_DP_B: - dev_priv->hotplug_supported_mask |= - HDMIB_HOTPLUG_INT_STATUS; - name = "DPDDC-B"; - break; - case DP_C: - case PCH_DP_C: - dev_priv->hotplug_supported_mask |= - HDMIC_HOTPLUG_INT_STATUS; - name = "DPDDC-C"; - break; - case DP_D: - case PCH_DP_D: - dev_priv->hotplug_supported_mask |= - HDMID_HOTPLUG_INT_STATUS; - name = "DPDDC-D"; - break; - } - - /* Cache some DPCD data in the eDP case */ - if (is_edp(intel_dp)) { - bool ret; - struct edp_power_seq cur, vbt; - u32 pp_on, pp_off, pp_div; - - pp_on = I915_READ(PCH_PP_ON_DELAYS); - pp_off = I915_READ(PCH_PP_OFF_DELAYS); - pp_div = I915_READ(PCH_PP_DIVISOR); - - /* Pull timing values out of registers */ - cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> - PANEL_POWER_UP_DELAY_SHIFT; - - cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> - PANEL_LIGHT_ON_DELAY_SHIFT; - - cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> - PANEL_LIGHT_OFF_DELAY_SHIFT; - - cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >> - PANEL_POWER_DOWN_DELAY_SHIFT; - - cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >> - PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000; - - DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", - cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12); - - vbt = dev_priv->edp.pps; - - DRM_DEBUG_KMS("vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", - vbt.t1_t3, vbt.t8, vbt.t9, vbt.t10, vbt.t11_t12); - -#define get_delay(field) ((max(cur.field, vbt.field) + 9) / 10) - - intel_dp->panel_power_up_delay = get_delay(t1_t3); - intel_dp->backlight_on_delay = get_delay(t8); - intel_dp->backlight_off_delay = get_delay(t9); - intel_dp->panel_power_down_delay = get_delay(t10); - intel_dp->panel_power_cycle_delay = get_delay(t11_t12); - - DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n", - intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay, - intel_dp->panel_power_cycle_delay); - - DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", - intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); - - ironlake_edp_panel_vdd_on(intel_dp); - ret = intel_dp_get_dpcd(intel_dp); - ironlake_edp_panel_vdd_off(intel_dp, false); - - if (ret) { - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) - dev_priv->no_aux_handshake = - intel_dp->dpcd[DP_MAX_DOWNSPREAD] & - DP_NO_AUX_HANDSHAKE_LINK_TRAINING; - } else { - /* if this fails, presume the device is a ghost */ - DRM_INFO("failed to retrieve link info, disabling eDP\n"); - intel_dp_encoder_destroy(&intel_dp->base.base); - intel_dp_destroy(&intel_connector->base); - return; - } - } - - intel_dp_i2c_init(intel_dp, intel_connector, name); - - intel_encoder->hot_plug = intel_dp_hot_plug; - - if (is_edp(intel_dp)) { - dev_priv->int_edp_connector = connector; - intel_panel_setup_backlight(dev); - } - - intel_dp_add_properties(intel_dp, connector); - - /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written - * 0xd. Failure to do so will result in spurious interrupts being - * generated on the port when a cable is not attached. - */ - if (IS_G4X(dev) && !IS_GM45(dev)) { - u32 temp = I915_READ(PEG_BAND_GAP_DATA); - I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_drv.h deleted file mode 100644 index 715afa15..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_drv.h +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2006 Dave Airlie - * Copyright (c) 2007-2008 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#ifndef __INTEL_DRV_H__ -#define __INTEL_DRV_H__ - -#include -#include "i915_drm.h" -#include "i915_drv.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" - -#define _wait_for(COND, MS, W) ({ \ - unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ - int ret__ = 0; \ - while (!(COND)) { \ - if (time_after(jiffies, timeout__)) { \ - ret__ = -ETIMEDOUT; \ - break; \ - } \ - if (W && drm_can_sleep()) msleep(W); \ - } \ - ret__; \ -}) - -#define wait_for(COND, MS) _wait_for(COND, MS, 1) -#define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0) - -#define KHz(x) (1000*x) -#define MHz(x) KHz(1000*x) - -/* - * Display related stuff - */ - -/* store information about an Ixxx DVO */ -/* The i830->i865 use multiple DVOs with multiple i2cs */ -/* the i915, i945 have a single sDVO i2c bus - which is different */ -#define MAX_OUTPUTS 6 -/* maximum connectors per crtcs in the mode set */ -#define INTELFB_CONN_LIMIT 4 - -#define INTEL_I2C_BUS_DVO 1 -#define INTEL_I2C_BUS_SDVO 2 - -/* these are outputs from the chip - integrated only - external chips are via DVO or SDVO output */ -#define INTEL_OUTPUT_UNUSED 0 -#define INTEL_OUTPUT_ANALOG 1 -#define INTEL_OUTPUT_DVO 2 -#define INTEL_OUTPUT_SDVO 3 -#define INTEL_OUTPUT_LVDS 4 -#define INTEL_OUTPUT_TVOUT 5 -#define INTEL_OUTPUT_HDMI 6 -#define INTEL_OUTPUT_DISPLAYPORT 7 -#define INTEL_OUTPUT_EDP 8 - -/* Intel Pipe Clone Bit */ -#define INTEL_HDMIB_CLONE_BIT 1 -#define INTEL_HDMIC_CLONE_BIT 2 -#define INTEL_HDMID_CLONE_BIT 3 -#define INTEL_HDMIE_CLONE_BIT 4 -#define INTEL_HDMIF_CLONE_BIT 5 -#define INTEL_SDVO_NON_TV_CLONE_BIT 6 -#define INTEL_SDVO_TV_CLONE_BIT 7 -#define INTEL_SDVO_LVDS_CLONE_BIT 8 -#define INTEL_ANALOG_CLONE_BIT 9 -#define INTEL_TV_CLONE_BIT 10 -#define INTEL_DP_B_CLONE_BIT 11 -#define INTEL_DP_C_CLONE_BIT 12 -#define INTEL_DP_D_CLONE_BIT 13 -#define INTEL_LVDS_CLONE_BIT 14 -#define INTEL_DVO_TMDS_CLONE_BIT 15 -#define INTEL_DVO_LVDS_CLONE_BIT 16 -#define INTEL_EDP_CLONE_BIT 17 - -#define INTEL_DVO_CHIP_NONE 0 -#define INTEL_DVO_CHIP_LVDS 1 -#define INTEL_DVO_CHIP_TMDS 2 -#define INTEL_DVO_CHIP_TVOUT 4 - -/* drm_display_mode->private_flags */ -#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) -#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) -#define INTEL_MODE_DP_FORCE_6BPC (0x10) -/* This flag must be set by the encoder's mode_fixup if it changes the crtc - * timings in the mode to prevent the crtc fixup from overwriting them. - * Currently only lvds needs that. */ -#define INTEL_MODE_CRTC_TIMINGS_SET (0x20) - -static inline void -intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, - int multiplier) -{ - mode->clock *= multiplier; - mode->private_flags |= multiplier; -} - -static inline int -intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) -{ - return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT; -} - -struct intel_framebuffer { - struct drm_framebuffer base; - struct drm_i915_gem_object *obj; -}; - -struct intel_fbdev { - struct drm_fb_helper helper; - struct intel_framebuffer ifb; - struct list_head fbdev_list; - struct drm_display_mode *our_mode; -}; - -struct intel_encoder { - struct drm_encoder base; - int type; - bool needs_tv_clock; - void (*hot_plug)(struct intel_encoder *); - int crtc_mask; - int clone_mask; -}; - -struct intel_connector { - struct drm_connector base; - struct intel_encoder *encoder; -}; - -struct intel_crtc { - struct drm_crtc base; - enum pipe pipe; - enum plane plane; - u8 lut_r[256], lut_g[256], lut_b[256]; - int dpms_mode; - bool active; /* is the crtc on? independent of the dpms mode */ - bool busy; /* is scanout buffer being updated frequently? */ - struct timer_list idle_timer; - bool lowfreq_avail; - struct intel_overlay *overlay; - struct intel_unpin_work *unpin_work; - int fdi_lanes; - - struct drm_i915_gem_object *cursor_bo; - uint32_t cursor_addr; - int16_t cursor_x, cursor_y; - int16_t cursor_width, cursor_height; - bool cursor_visible; - unsigned int bpp; - - bool no_pll; /* tertiary pipe for IVB */ - bool use_pll_a; -}; - -struct intel_plane { - struct drm_plane base; - enum pipe pipe; - struct drm_i915_gem_object *obj; - bool primary_disabled; - int max_downscale; - u32 lut_r[1024], lut_g[1024], lut_b[1024]; - void (*update_plane)(struct drm_plane *plane, - struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h); - void (*disable_plane)(struct drm_plane *plane); - int (*update_colorkey)(struct drm_plane *plane, - struct drm_intel_sprite_colorkey *key); - void (*get_colorkey)(struct drm_plane *plane, - struct drm_intel_sprite_colorkey *key); -}; - -#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -#define to_intel_connector(x) container_of(x, struct intel_connector, base) -#define to_intel_encoder(x) container_of(x, struct intel_encoder, base) -#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) -#define to_intel_plane(x) container_of(x, struct intel_plane, base) - -#define DIP_HEADER_SIZE 5 - -#define DIP_TYPE_AVI 0x82 -#define DIP_VERSION_AVI 0x2 -#define DIP_LEN_AVI 13 - -#define DIP_TYPE_SPD 0x83 -#define DIP_VERSION_SPD 0x1 -#define DIP_LEN_SPD 25 -#define DIP_SPD_UNKNOWN 0 -#define DIP_SPD_DSTB 0x1 -#define DIP_SPD_DVDP 0x2 -#define DIP_SPD_DVHS 0x3 -#define DIP_SPD_HDDVR 0x4 -#define DIP_SPD_DVC 0x5 -#define DIP_SPD_DSC 0x6 -#define DIP_SPD_VCD 0x7 -#define DIP_SPD_GAME 0x8 -#define DIP_SPD_PC 0x9 -#define DIP_SPD_BD 0xa -#define DIP_SPD_SCD 0xb - -struct dip_infoframe { - uint8_t type; /* HB0 */ - uint8_t ver; /* HB1 */ - uint8_t len; /* HB2 - body len, not including checksum */ - uint8_t ecc; /* Header ECC */ - uint8_t checksum; /* PB0 */ - union { - struct { - /* PB1 - Y 6:5, A 4:4, B 3:2, S 1:0 */ - uint8_t Y_A_B_S; - /* PB2 - C 7:6, M 5:4, R 3:0 */ - uint8_t C_M_R; - /* PB3 - ITC 7:7, EC 6:4, Q 3:2, SC 1:0 */ - uint8_t ITC_EC_Q_SC; - /* PB4 - VIC 6:0 */ - uint8_t VIC; - /* PB5 - PR 3:0 */ - uint8_t PR; - /* PB6 to PB13 */ - uint16_t top_bar_end; - uint16_t bottom_bar_start; - uint16_t left_bar_end; - uint16_t right_bar_start; - } avi; - struct { - uint8_t vn[8]; - uint8_t pd[16]; - uint8_t sdi; - } spd; - uint8_t payload[27]; - } __attribute__ ((packed)) body; -} __attribute__((packed)); - -static inline struct drm_crtc * -intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - return dev_priv->pipe_to_crtc_mapping[pipe]; -} - -static inline struct drm_crtc * -intel_get_crtc_for_plane(struct drm_device *dev, int plane) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - return dev_priv->plane_to_crtc_mapping[plane]; -} - -struct intel_unpin_work { - struct work_struct work; - struct drm_device *dev; - struct drm_i915_gem_object *old_fb_obj; - struct drm_i915_gem_object *pending_flip_obj; - struct drm_pending_vblank_event *event; - int pending; - bool enable_stall_check; -}; - -struct intel_fbc_work { - struct delayed_work work; - struct drm_crtc *crtc; - struct drm_framebuffer *fb; - int interval; -}; - -int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); -extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus); - -extern void intel_attach_force_audio_property(struct drm_connector *connector); -extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector); - -extern void intel_crt_init(struct drm_device *dev); -extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); -void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); -extern bool intel_sdvo_init(struct drm_device *dev, int output_device); -extern void intel_dvo_init(struct drm_device *dev); -extern void intel_tv_init(struct drm_device *dev); -extern void intel_mark_busy(struct drm_device *dev, - struct drm_i915_gem_object *obj); -extern bool intel_lvds_init(struct drm_device *dev); -extern void intel_dp_init(struct drm_device *dev, int dp_reg); -void -intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -extern bool intel_dpd_is_edp(struct drm_device *dev); -extern void intel_edp_link_config(struct intel_encoder *, int *, int *); -extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); -extern int intel_plane_init(struct drm_device *dev, enum pipe pipe); - -/* intel_panel.c */ -extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, - struct drm_display_mode *adjusted_mode); -extern void intel_pch_panel_fitting(struct drm_device *dev, - int fitting_mode, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -extern u32 intel_panel_get_max_backlight(struct drm_device *dev); -extern u32 intel_panel_get_backlight(struct drm_device *dev); -extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); -extern int intel_panel_setup_backlight(struct drm_device *dev); -extern void intel_panel_enable_backlight(struct drm_device *dev); -extern void intel_panel_disable_backlight(struct drm_device *dev); -extern void intel_panel_destroy_backlight(struct drm_device *dev); -extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); - -extern void intel_crtc_load_lut(struct drm_crtc *crtc); -extern void intel_encoder_prepare(struct drm_encoder *encoder); -extern void intel_encoder_commit(struct drm_encoder *encoder); -extern void intel_encoder_destroy(struct drm_encoder *encoder); - -static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector) -{ - return to_intel_connector(connector)->encoder; -} - -extern void intel_connector_attach_encoder(struct intel_connector *connector, - struct intel_encoder *encoder); -extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector); - -extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, - struct drm_crtc *crtc); -int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); -extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe); - -struct intel_load_detect_pipe { - struct drm_framebuffer *release_fb; - bool load_detect_temp; - int dpms_mode; -}; -extern bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct drm_display_mode *mode, - struct intel_load_detect_pipe *old); -extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, - struct drm_connector *connector, - struct intel_load_detect_pipe *old); - -extern void intelfb_restore(void); -extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno); -extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno); -extern void intel_enable_clock_gating(struct drm_device *dev); -extern void ironlake_enable_drps(struct drm_device *dev); -extern void ironlake_disable_drps(struct drm_device *dev); -extern void gen6_enable_rps(struct drm_i915_private *dev_priv); -extern void gen6_update_ring_freq(struct drm_i915_private *dev_priv); -extern void gen6_disable_rps(struct drm_device *dev); -extern void intel_init_emon(struct drm_device *dev); - -extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, - struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined); -extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj); - -extern int intel_framebuffer_init(struct drm_device *dev, - struct intel_framebuffer *ifb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_i915_gem_object *obj); -extern int intel_fbdev_init(struct drm_device *dev); -extern void intel_fbdev_fini(struct drm_device *dev); -extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); -extern void intel_prepare_page_flip(struct drm_device *dev, int plane); -extern void intel_finish_page_flip(struct drm_device *dev, int pipe); -extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); - -extern void intel_setup_overlay(struct drm_device *dev); -extern void intel_cleanup_overlay(struct drm_device *dev); -extern int intel_overlay_switch_off(struct intel_overlay *overlay); -extern int intel_overlay_put_image(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int intel_overlay_attrs(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern void intel_fb_output_poll_changed(struct drm_device *dev); -extern void intel_fb_restore_mode(struct drm_device *dev); - -extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, - bool state); -#define assert_pipe_enabled(d, p) assert_pipe(d, p, true) -#define assert_pipe_disabled(d, p) assert_pipe(d, p, false) - -extern void intel_init_clock_gating(struct drm_device *dev); -extern void intel_write_eld(struct drm_encoder *encoder, - struct drm_display_mode *mode); -extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe); - -/* For use by IVB LP watermark workaround in intel_sprite.c */ -extern void sandybridge_update_wm(struct drm_device *dev); -extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe, - uint32_t sprite_width, - int pixel_size); - -extern int intel_sprite_set_colorkey(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -#endif /* __INTEL_DRV_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dvo.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dvo.c deleted file mode 100644 index 020a7d7f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_dvo.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright 2006 Dave Airlie - * Copyright © 2006-2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "dvo.h" - -#define SIL164_ADDR 0x38 -#define CH7xxx_ADDR 0x76 -#define TFP410_ADDR 0x38 - -static const struct intel_dvo_device intel_dvo_devices[] = { - { - .type = INTEL_DVO_CHIP_TMDS, - .name = "sil164", - .dvo_reg = DVOC, - .slave_addr = SIL164_ADDR, - .dev_ops = &sil164_ops, - }, - { - .type = INTEL_DVO_CHIP_TMDS, - .name = "ch7xxx", - .dvo_reg = DVOC, - .slave_addr = CH7xxx_ADDR, - .dev_ops = &ch7xxx_ops, - }, - { - .type = INTEL_DVO_CHIP_LVDS, - .name = "ivch", - .dvo_reg = DVOA, - .slave_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */ - .dev_ops = &ivch_ops, - }, - { - .type = INTEL_DVO_CHIP_TMDS, - .name = "tfp410", - .dvo_reg = DVOC, - .slave_addr = TFP410_ADDR, - .dev_ops = &tfp410_ops, - }, - { - .type = INTEL_DVO_CHIP_LVDS, - .name = "ch7017", - .dvo_reg = DVOC, - .slave_addr = 0x75, - .gpio = GMBUS_PORT_DPB, - .dev_ops = &ch7017_ops, - } -}; - -struct intel_dvo { - struct intel_encoder base; - - struct intel_dvo_device dev; - - struct drm_display_mode *panel_fixed_mode; - bool panel_wants_dither; -}; - -static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) -{ - return container_of(encoder, struct intel_dvo, base.base); -} - -static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_dvo, base); -} - -static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_i915_private *dev_priv = encoder->dev->dev_private; - struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); - u32 dvo_reg = intel_dvo->dev.dvo_reg; - u32 temp = I915_READ(dvo_reg); - - if (mode == DRM_MODE_DPMS_ON) { - I915_WRITE(dvo_reg, temp | DVO_ENABLE); - I915_READ(dvo_reg); - intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); - } else { - intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); - I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); - I915_READ(dvo_reg); - } -} - -static int intel_dvo_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_dvo *intel_dvo = intel_attached_dvo(connector); - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* XXX: Validate clock range */ - - if (intel_dvo->panel_fixed_mode) { - if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) - return MODE_PANEL; - } - - return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); -} - -static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); - - /* If we have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - if (intel_dvo->panel_fixed_mode != NULL) { -#define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x - C(hdisplay); - C(hsync_start); - C(hsync_end); - C(htotal); - C(vdisplay); - C(vsync_start); - C(vsync_end); - C(vtotal); - C(clock); -#undef C - } - - if (intel_dvo->dev.dev_ops->mode_fixup) - return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); - - return true; -} - -static void intel_dvo_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); - int pipe = intel_crtc->pipe; - u32 dvo_val; - u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; - int dpll_reg = DPLL(pipe); - - switch (dvo_reg) { - case DVOA: - default: - dvo_srcdim_reg = DVOA_SRCDIM; - break; - case DVOB: - dvo_srcdim_reg = DVOB_SRCDIM; - break; - case DVOC: - dvo_srcdim_reg = DVOC_SRCDIM; - break; - } - - intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); - - /* Save the data order, since I don't know what it should be set to. */ - dvo_val = I915_READ(dvo_reg) & - (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); - dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | - DVO_BLANK_ACTIVE_HIGH; - - if (pipe == 1) - dvo_val |= DVO_PIPE_B_SELECT; - dvo_val |= DVO_PIPE_STALL; - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - dvo_val |= DVO_HSYNC_ACTIVE_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - dvo_val |= DVO_VSYNC_ACTIVE_HIGH; - - I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED); - - /*I915_WRITE(DVOB_SRCDIM, - (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | - (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ - I915_WRITE(dvo_srcdim_reg, - (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | - (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT)); - /*I915_WRITE(DVOB, dvo_val);*/ - I915_WRITE(dvo_reg, dvo_val); -} - -/** - * Detect the output connection on our DVO device. - * - * Unimplemented. - */ -static enum drm_connector_status -intel_dvo_detect(struct drm_connector *connector, bool force) -{ - struct intel_dvo *intel_dvo = intel_attached_dvo(connector); - return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); -} - -static int intel_dvo_get_modes(struct drm_connector *connector) -{ - struct intel_dvo *intel_dvo = intel_attached_dvo(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - - /* We should probably have an i2c driver get_modes function for those - * devices which will have a fixed set of modes determined by the chip - * (TV-out, for example), but for now with just TMDS and LVDS, - * that's not the case. - */ - intel_ddc_get_modes(connector, - &dev_priv->gmbus[GMBUS_PORT_DPC].adapter); - if (!list_empty(&connector->probed_modes)) - return 1; - - if (intel_dvo->panel_fixed_mode != NULL) { - struct drm_display_mode *mode; - mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode); - if (mode) { - drm_mode_probed_add(connector, mode); - return 1; - } - } - - return 0; -} - -static void intel_dvo_destroy(struct drm_connector *connector) -{ - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { - .dpms = intel_dvo_dpms, - .mode_fixup = intel_dvo_mode_fixup, - .prepare = intel_encoder_prepare, - .mode_set = intel_dvo_mode_set, - .commit = intel_encoder_commit, -}; - -static const struct drm_connector_funcs intel_dvo_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = intel_dvo_detect, - .destroy = intel_dvo_destroy, - .fill_modes = drm_helper_probe_single_connector_modes, -}; - -static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { - .mode_valid = intel_dvo_mode_valid, - .get_modes = intel_dvo_get_modes, - .best_encoder = intel_best_encoder, -}; - -static void intel_dvo_enc_destroy(struct drm_encoder *encoder) -{ - struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); - - if (intel_dvo->dev.dev_ops->destroy) - intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); - - kfree(intel_dvo->panel_fixed_mode); - - intel_encoder_destroy(encoder); -} - -static const struct drm_encoder_funcs intel_dvo_enc_funcs = { - .destroy = intel_dvo_enc_destroy, -}; - -/** - * Attempts to get a fixed panel timing for LVDS (currently only the i830). - * - * Other chips with DVO LVDS will need to extend this to deal with the LVDS - * chip being on DVOB/C and having multiple pipes. - */ -static struct drm_display_mode * -intel_dvo_get_current_mode(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dvo *intel_dvo = intel_attached_dvo(connector); - uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); - struct drm_display_mode *mode = NULL; - - /* If the DVO port is active, that'll be the LVDS, so we can pull out - * its timings to get how the BIOS set up the panel. - */ - if (dvo_val & DVO_ENABLE) { - struct drm_crtc *crtc; - int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; - - crtc = intel_get_crtc_for_pipe(dev, pipe); - if (crtc) { - mode = intel_crtc_mode_get(dev, crtc); - if (mode) { - mode->type |= DRM_MODE_TYPE_PREFERRED; - if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - if (dvo_val & DVO_VSYNC_ACTIVE_HIGH) - mode->flags |= DRM_MODE_FLAG_PVSYNC; - } - } - } - - return mode; -} - -void intel_dvo_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_encoder *intel_encoder; - struct intel_dvo *intel_dvo; - struct intel_connector *intel_connector; - int i; - int encoder_type = DRM_MODE_ENCODER_NONE; - - intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL); - if (!intel_dvo) - return; - - intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); - if (!intel_connector) { - kfree(intel_dvo); - return; - } - - intel_encoder = &intel_dvo->base; - drm_encoder_init(dev, &intel_encoder->base, - &intel_dvo_enc_funcs, encoder_type); - - /* Now, try to find a controller */ - for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { - struct drm_connector *connector = &intel_connector->base; - const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; - struct i2c_adapter *i2c; - int gpio; - - /* Allow the I2C driver info to specify the GPIO to be used in - * special cases, but otherwise default to what's defined - * in the spec. - */ - if (dvo->gpio != 0) - gpio = dvo->gpio; - else if (dvo->type == INTEL_DVO_CHIP_LVDS) - gpio = GMBUS_PORT_SSC; - else - gpio = GMBUS_PORT_DPB; - - /* Set up the I2C bus necessary for the chip we're probing. - * It appears that everything is on GPIOE except for panels - * on i830 laptops, which are on GPIOB (DVOA). - */ - i2c = &dev_priv->gmbus[gpio].adapter; - - intel_dvo->dev = *dvo; - if (!dvo->dev_ops->init(&intel_dvo->dev, i2c)) - continue; - - intel_encoder->type = INTEL_OUTPUT_DVO; - intel_encoder->crtc_mask = (1 << 0) | (1 << 1); - switch (dvo->type) { - case INTEL_DVO_CHIP_TMDS: - intel_encoder->clone_mask = - (1 << INTEL_DVO_TMDS_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT); - drm_connector_init(dev, connector, - &intel_dvo_connector_funcs, - DRM_MODE_CONNECTOR_DVII); - encoder_type = DRM_MODE_ENCODER_TMDS; - break; - case INTEL_DVO_CHIP_LVDS: - intel_encoder->clone_mask = - (1 << INTEL_DVO_LVDS_CLONE_BIT); - drm_connector_init(dev, connector, - &intel_dvo_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - encoder_type = DRM_MODE_ENCODER_LVDS; - break; - } - - drm_connector_helper_add(connector, - &intel_dvo_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - drm_encoder_helper_add(&intel_encoder->base, - &intel_dvo_helper_funcs); - - intel_connector_attach_encoder(intel_connector, intel_encoder); - if (dvo->type == INTEL_DVO_CHIP_LVDS) { - /* For our LVDS chipsets, we should hopefully be able - * to dig the fixed panel mode out of the BIOS data. - * However, it's in a different format from the BIOS - * data on chipsets with integrated LVDS (stored in AIM - * headers, likely), so for now, just get the current - * mode being output through DVO. - */ - intel_dvo->panel_fixed_mode = - intel_dvo_get_current_mode(connector); - intel_dvo->panel_wants_dither = true; - } - - drm_sysfs_connector_add(connector); - return; - } - - drm_encoder_cleanup(&intel_encoder->base); - kfree(intel_dvo); - kfree(intel_connector); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_fb.c deleted file mode 100644 index 6e9ee33f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_fb.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright © 2007 David Airlie - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * David Airlie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_fb_helper.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" - -static struct fb_ops intelfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, -}; - -static int intelfb_create(struct intel_fbdev *ifbdev, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_device *dev = ifbdev->helper.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct fb_info *info; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd; - struct drm_i915_gem_object *obj; - struct device *device = &dev->pdev->dev; - int size, ret; - - /* we don't do packed 24bpp */ - if (sizes->surface_bpp == 24) - sizes->surface_bpp = 32; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - - mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((sizes->surface_bpp + 7) / - 8), 64); - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - size = mode_cmd.pitches[0] * mode_cmd.height; - size = ALIGN(size, PAGE_SIZE); - obj = i915_gem_alloc_object(dev, size); - if (!obj) { - DRM_ERROR("failed to allocate framebuffer\n"); - ret = -ENOMEM; - goto out; - } - - mutex_lock(&dev->struct_mutex); - - /* Flush everything out, we'll be doing GTT only from now on */ - ret = intel_pin_and_fence_fb_obj(dev, obj, false); - if (ret) { - DRM_ERROR("failed to pin fb: %d\n", ret); - goto out_unref; - } - - info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; - goto out_unpin; - } - - info->par = ifbdev; - - ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); - if (ret) - goto out_unpin; - - fb = &ifbdev->ifb.base; - - ifbdev->helper.fb = fb; - ifbdev->helper.fbdev = info; - - strcpy(info->fix.id, "inteldrmfb"); - - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; - info->fbops = &intelfb_ops; - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unpin; - } - /* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unpin; - } - info->apertures->ranges[0].base = dev->mode_config.fb_base; - info->apertures->ranges[0].size = - dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - - info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; - info->fix.smem_len = size; - - info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size); - if (!info->screen_base) { - ret = -ENOSPC; - goto out_unpin; - } - info->screen_size = size; - -// memset(info->screen_base, 0, size); - - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); - drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); - - /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - - DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", - fb->width, fb->height, - obj->gtt_offset, obj); - - - mutex_unlock(&dev->struct_mutex); - vga_switcheroo_client_fb_set(dev->pdev, info); - return 0; - -out_unpin: - i915_gem_object_unpin(obj); -out_unref: - drm_gem_object_unreference(&obj->base); - mutex_unlock(&dev->struct_mutex); -out: - return ret; -} - -static int intel_fb_find_or_create_single(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper; - int new_fb = 0; - int ret; - - if (!helper->fb) { - ret = intelfb_create(ifbdev, sizes); - if (ret) - return ret; - new_fb = 1; - } - return new_fb; -} - -static struct drm_fb_helper_funcs intel_fb_helper_funcs = { - .gamma_set = intel_crtc_fb_gamma_set, - .gamma_get = intel_crtc_fb_gamma_get, - .fb_probe = intel_fb_find_or_create_single, -}; - -static void intel_fbdev_destroy(struct drm_device *dev, - struct intel_fbdev *ifbdev) -{ - struct fb_info *info; - struct intel_framebuffer *ifb = &ifbdev->ifb; - - if (ifbdev->helper.fbdev) { - info = ifbdev->helper.fbdev; - unregister_framebuffer(info); - iounmap(info->screen_base); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } - - drm_fb_helper_fini(&ifbdev->helper); - - drm_framebuffer_cleanup(&ifb->base); - if (ifb->obj) { - drm_gem_object_unreference_unlocked(&ifb->obj->base); - ifb->obj = NULL; - } -} - -int intel_fbdev_init(struct drm_device *dev) -{ - struct intel_fbdev *ifbdev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL); - if (!ifbdev) - return -ENOMEM; - - dev_priv->fbdev = ifbdev; - ifbdev->helper.funcs = &intel_fb_helper_funcs; - - ret = drm_fb_helper_init(dev, &ifbdev->helper, - dev_priv->num_pipe, - INTELFB_CONN_LIMIT); - if (ret) { - kfree(ifbdev); - return ret; - } - - drm_fb_helper_single_add_all_connectors(&ifbdev->helper); - drm_fb_helper_initial_config(&ifbdev->helper, 32); - return 0; -} - -void intel_fbdev_fini(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - if (!dev_priv->fbdev) - return; - - intel_fbdev_destroy(dev, dev_priv->fbdev); - kfree(dev_priv->fbdev); - dev_priv->fbdev = NULL; -} - -void intel_fbdev_set_suspend(struct drm_device *dev, int state) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - if (!dev_priv->fbdev) - return; - - fb_set_suspend(dev_priv->fbdev->helper.fbdev, state); -} - -MODULE_LICENSE("GPL and additional rights"); - -void intel_fb_output_poll_changed(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); -} - -void intel_fb_restore_mode(struct drm_device *dev) -{ - int ret; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_mode_config *config = &dev->mode_config; - struct drm_plane *plane; - - mutex_lock(&dev->mode_config.mutex); - - ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); - if (ret) - DRM_DEBUG("failed to restore crtc mode\n"); - - /* Be sure to shut off any planes that may be active */ - list_for_each_entry(plane, &config->plane_list, head) - plane->funcs->disable_plane(plane); - - mutex_unlock(&dev->mode_config.mutex); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_hdmi.c deleted file mode 100644 index 2d7f47b5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_hdmi.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright 2006 Dave Airlie - * Copyright © 2006-2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Jesse Barnes - */ - -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_edid.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" - -struct intel_hdmi { - struct intel_encoder base; - u32 sdvox_reg; - int ddc_bus; - uint32_t color_range; - bool has_hdmi_sink; - bool has_audio; - enum hdmi_force_audio force_audio; - void (*write_infoframe)(struct drm_encoder *encoder, - struct dip_infoframe *frame); -}; - -static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) -{ - return container_of(encoder, struct intel_hdmi, base.base); -} - -static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_hdmi, base); -} - -void intel_dip_infoframe_csum(struct dip_infoframe *frame) -{ - uint8_t *data = (uint8_t *)frame; - uint8_t sum = 0; - unsigned i; - - frame->checksum = 0; - frame->ecc = 0; - - for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++) - sum += data[i]; - - frame->checksum = 0x100 - sum; -} - -static u32 intel_infoframe_index(struct dip_infoframe *frame) -{ - u32 flags = 0; - - switch (frame->type) { - case DIP_TYPE_AVI: - flags |= VIDEO_DIP_SELECT_AVI; - break; - case DIP_TYPE_SPD: - flags |= VIDEO_DIP_SELECT_SPD; - break; - default: - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); - break; - } - - return flags; -} - -static u32 intel_infoframe_flags(struct dip_infoframe *frame) -{ - u32 flags = 0; - - switch (frame->type) { - case DIP_TYPE_AVI: - flags |= VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_FREQ_VSYNC; - break; - case DIP_TYPE_SPD: - flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_VSYNC; - break; - default: - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); - break; - } - - return flags; -} - -static void i9xx_write_infoframe(struct drm_encoder *encoder, - struct dip_infoframe *frame) -{ - uint32_t *data = (uint32_t *)frame; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - u32 port, flags, val = I915_READ(VIDEO_DIP_CTL); - unsigned i, len = DIP_HEADER_SIZE + frame->len; - - - /* XXX first guess at handling video port, is this corrent? */ - if (intel_hdmi->sdvox_reg == SDVOB) - port = VIDEO_DIP_PORT_B; - else if (intel_hdmi->sdvox_reg == SDVOC) - port = VIDEO_DIP_PORT_C; - else - return; - - flags = intel_infoframe_index(frame); - - val &= ~VIDEO_DIP_SELECT_MASK; - - I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); - - for (i = 0; i < len; i += 4) { - I915_WRITE(VIDEO_DIP_DATA, *data); - data++; - } - - flags |= intel_infoframe_flags(frame); - - I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); -} - -static void ironlake_write_infoframe(struct drm_encoder *encoder, - struct dip_infoframe *frame) -{ - uint32_t *data = (uint32_t *)frame; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); - unsigned i, len = DIP_HEADER_SIZE + frame->len; - u32 flags, val = I915_READ(reg); - - intel_wait_for_vblank(dev, intel_crtc->pipe); - - flags = intel_infoframe_index(frame); - - val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ - - I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); - - for (i = 0; i < len; i += 4) { - I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); - data++; - } - - flags |= intel_infoframe_flags(frame); - - I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); -} -static void intel_set_infoframe(struct drm_encoder *encoder, - struct dip_infoframe *frame) -{ - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - - if (!intel_hdmi->has_hdmi_sink) - return; - - intel_dip_infoframe_csum(frame); - intel_hdmi->write_infoframe(encoder, frame); -} - -static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder) -{ - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - - intel_set_infoframe(encoder, &avi_if); -} - -static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) -{ - struct dip_infoframe spd_if; - - memset(&spd_if, 0, sizeof(spd_if)); - spd_if.type = DIP_TYPE_SPD; - spd_if.ver = DIP_VERSION_SPD; - spd_if.len = DIP_LEN_SPD; - strcpy(spd_if.body.spd.vn, "Intel"); - strcpy(spd_if.body.spd.pd, "Integrated gfx"); - spd_if.body.spd.sdi = DIP_SPD_PC; - - intel_set_infoframe(encoder, &spd_if); -} - -static void intel_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - u32 sdvox; - - sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; - if (!HAS_PCH_SPLIT(dev)) - sdvox |= intel_hdmi->color_range; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - sdvox |= SDVO_VSYNC_ACTIVE_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - sdvox |= SDVO_HSYNC_ACTIVE_HIGH; - - if (intel_crtc->bpp > 24) - sdvox |= COLOR_FORMAT_12bpc; - else - sdvox |= COLOR_FORMAT_8bpc; - - /* Required on CPT */ - if (intel_hdmi->has_hdmi_sink && HAS_PCH_CPT(dev)) - sdvox |= HDMI_MODE_SELECT; - - if (intel_hdmi->has_audio) { - DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n", - pipe_name(intel_crtc->pipe)); - sdvox |= SDVO_AUDIO_ENABLE; - sdvox |= SDVO_NULL_PACKETS_DURING_VSYNC; - intel_write_eld(encoder, adjusted_mode); - } - - if (HAS_PCH_CPT(dev)) - sdvox |= PORT_TRANS_SEL_CPT(intel_crtc->pipe); - else if (intel_crtc->pipe == 1) - sdvox |= SDVO_PIPE_B_SELECT; - - I915_WRITE(intel_hdmi->sdvox_reg, sdvox); - POSTING_READ(intel_hdmi->sdvox_reg); - - intel_hdmi_set_avi_infoframe(encoder); - intel_hdmi_set_spd_infoframe(encoder); -} - -static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - u32 temp; - u32 enable_bits = SDVO_ENABLE; - - if (intel_hdmi->has_audio) - enable_bits |= SDVO_AUDIO_ENABLE; - - temp = I915_READ(intel_hdmi->sdvox_reg); - - /* HW workaround, need to toggle enable bit off and on for 12bpc, but - * we do this anyway which shows more stable in testing. - */ - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); - POSTING_READ(intel_hdmi->sdvox_reg); - } - - if (mode != DRM_MODE_DPMS_ON) { - temp &= ~enable_bits; - } else { - temp |= enable_bits; - } - - I915_WRITE(intel_hdmi->sdvox_reg, temp); - POSTING_READ(intel_hdmi->sdvox_reg); - - /* HW workaround, need to write this twice for issue that may result - * in first write getting masked. - */ - if (HAS_PCH_SPLIT(dev)) { - I915_WRITE(intel_hdmi->sdvox_reg, temp); - POSTING_READ(intel_hdmi->sdvox_reg); - } -} - -static int intel_hdmi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - if (mode->clock > 165000) - return MODE_CLOCK_HIGH; - if (mode->clock < 20000) - return MODE_CLOCK_LOW; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - return MODE_OK; -} - -static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) -{ - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct edid *edid; - enum drm_connector_status status = connector_status_disconnected; - - intel_hdmi->has_hdmi_sink = false; - intel_hdmi->has_audio = false; - edid = drm_get_edid(connector, - &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); - - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) - intel_hdmi->has_hdmi_sink = - drm_detect_hdmi_monitor(edid); - intel_hdmi->has_audio = drm_detect_monitor_audio(edid); - } - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - if (status == connector_status_connected) { - if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO) - intel_hdmi->has_audio = - (intel_hdmi->force_audio == HDMI_AUDIO_ON); - } - - return status; -} - -static int intel_hdmi_get_modes(struct drm_connector *connector) -{ - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - - /* We should parse the EDID data and find out if it's an HDMI sink so - * we can send audio to it. - */ - - return intel_ddc_get_modes(connector, - &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); -} - -static bool -intel_hdmi_detect_audio(struct drm_connector *connector) -{ - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct edid *edid; - bool has_audio = false; - - edid = drm_get_edid(connector, - &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - return has_audio; -} - -static int -intel_hdmi_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - int ret; - - ret = drm_connector_property_set_value(connector, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - enum hdmi_force_audio i = val; - bool has_audio; - - if (i == intel_hdmi->force_audio) - return 0; - - intel_hdmi->force_audio = i; - - if (i == HDMI_AUDIO_AUTO) - has_audio = intel_hdmi_detect_audio(connector); - else - has_audio = (i == HDMI_AUDIO_ON); - - if (i == HDMI_AUDIO_OFF_DVI) - intel_hdmi->has_hdmi_sink = 0; - - intel_hdmi->has_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - if (val == !!intel_hdmi->color_range) - return 0; - - intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; - goto done; - } - - return -EINVAL; - -done: - if (intel_hdmi->base.base.crtc) { - struct drm_crtc *crtc = intel_hdmi->base.base.crtc; - drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, - crtc->fb); - } - - return 0; -} - -static void intel_hdmi_destroy(struct drm_connector *connector) -{ - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { - .dpms = intel_hdmi_dpms, - .mode_fixup = intel_hdmi_mode_fixup, - .prepare = intel_encoder_prepare, - .mode_set = intel_hdmi_mode_set, - .commit = intel_encoder_commit, -}; - -static const struct drm_connector_funcs intel_hdmi_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = intel_hdmi_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_hdmi_set_property, - .destroy = intel_hdmi_destroy, -}; - -static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { - .get_modes = intel_hdmi_get_modes, - .mode_valid = intel_hdmi_mode_valid, - .best_encoder = intel_best_encoder, -}; - -static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { - .destroy = intel_encoder_destroy, -}; - -static void -intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) -{ - intel_attach_force_audio_property(connector); - intel_attach_broadcast_rgb_property(connector); -} - -void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - struct intel_encoder *intel_encoder; - struct intel_connector *intel_connector; - struct intel_hdmi *intel_hdmi; - int i; - - intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); - if (!intel_hdmi) - return; - - intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); - if (!intel_connector) { - kfree(intel_hdmi); - return; - } - - intel_encoder = &intel_hdmi->base; - drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs, - DRM_MODE_ENCODER_TMDS); - - connector = &intel_connector->base; - drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); - drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); - - intel_encoder->type = INTEL_OUTPUT_HDMI; - - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->interlace_allowed = 1; - connector->doublescan_allowed = 0; - intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); - - /* Set up the DDC bus. */ - if (sdvox_reg == SDVOB) { - intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); - intel_hdmi->ddc_bus = GMBUS_PORT_DPB; - dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; - } else if (sdvox_reg == SDVOC) { - intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); - intel_hdmi->ddc_bus = GMBUS_PORT_DPC; - dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; - } else if (sdvox_reg == HDMIB) { - intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); - intel_hdmi->ddc_bus = GMBUS_PORT_DPB; - dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; - } else if (sdvox_reg == HDMIC) { - intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); - intel_hdmi->ddc_bus = GMBUS_PORT_DPC; - dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; - } else if (sdvox_reg == HDMID) { - intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); - intel_hdmi->ddc_bus = GMBUS_PORT_DPD; - dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; - } - - intel_hdmi->sdvox_reg = sdvox_reg; - - if (!HAS_PCH_SPLIT(dev)) { - intel_hdmi->write_infoframe = i9xx_write_infoframe; - I915_WRITE(VIDEO_DIP_CTL, 0); - } else { - intel_hdmi->write_infoframe = ironlake_write_infoframe; - for_each_pipe(i) - I915_WRITE(TVIDEO_DIP_CTL(i), 0); - } - - drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); - - intel_hdmi_add_properties(intel_hdmi, connector); - - intel_connector_attach_encoder(intel_connector, intel_encoder); - drm_sysfs_connector_add(connector); - - /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written - * 0xd. Failure to do so will result in spurious interrupts being - * generated on the port when a cable is not attached. - */ - if (IS_G4X(dev) && !IS_GM45(dev)) { - u32 temp = I915_READ(PEG_BAND_GAP_DATA); - I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_i2c.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_i2c.c deleted file mode 100644 index 8fdc9570..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_i2c.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (c) 2006 Dave Airlie - * Copyright © 2006-2008,2010 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Chris Wilson - */ -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/* Intel GPIO access functions */ - -#define I2C_RISEFALL_TIME 10 - -static inline struct intel_gmbus * -to_intel_gmbus(struct i2c_adapter *i2c) -{ - return container_of(i2c, struct intel_gmbus, adapter); -} - -void -intel_i2c_reset(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - if (HAS_PCH_SPLIT(dev)) - I915_WRITE(PCH_GMBUS0, 0); - else - I915_WRITE(GMBUS0, 0); -} - -static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) -{ - u32 val; - - /* When using bit bashing for I2C, this bit needs to be set to 1 */ - if (!IS_PINEVIEW(dev_priv->dev)) - return; - - val = I915_READ(DSPCLK_GATE_D); - if (enable) - val |= DPCUNIT_CLOCK_GATE_DISABLE; - else - val &= ~DPCUNIT_CLOCK_GATE_DISABLE; - I915_WRITE(DSPCLK_GATE_D, val); -} - -static u32 get_reserved(struct intel_gmbus *bus) -{ - struct drm_i915_private *dev_priv = bus->dev_priv; - struct drm_device *dev = dev_priv->dev; - u32 reserved = 0; - - /* On most chips, these bits must be preserved in software. */ - if (!IS_I830(dev) && !IS_845G(dev)) - reserved = I915_READ_NOTRACE(bus->gpio_reg) & - (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); - - return reserved; -} - -static int get_clock(void *data) -{ - struct intel_gmbus *bus = data; - struct drm_i915_private *dev_priv = bus->dev_priv; - u32 reserved = get_reserved(bus); - I915_WRITE_NOTRACE(bus->gpio_reg, reserved | GPIO_CLOCK_DIR_MASK); - I915_WRITE_NOTRACE(bus->gpio_reg, reserved); - return (I915_READ_NOTRACE(bus->gpio_reg) & GPIO_CLOCK_VAL_IN) != 0; -} - -static int get_data(void *data) -{ - struct intel_gmbus *bus = data; - struct drm_i915_private *dev_priv = bus->dev_priv; - u32 reserved = get_reserved(bus); - I915_WRITE_NOTRACE(bus->gpio_reg, reserved | GPIO_DATA_DIR_MASK); - I915_WRITE_NOTRACE(bus->gpio_reg, reserved); - return (I915_READ_NOTRACE(bus->gpio_reg) & GPIO_DATA_VAL_IN) != 0; -} - -static void set_clock(void *data, int state_high) -{ - struct intel_gmbus *bus = data; - struct drm_i915_private *dev_priv = bus->dev_priv; - u32 reserved = get_reserved(bus); - u32 clock_bits; - - if (state_high) - clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; - else - clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | - GPIO_CLOCK_VAL_MASK; - - I915_WRITE_NOTRACE(bus->gpio_reg, reserved | clock_bits); - POSTING_READ(bus->gpio_reg); -} - -static void set_data(void *data, int state_high) -{ - struct intel_gmbus *bus = data; - struct drm_i915_private *dev_priv = bus->dev_priv; - u32 reserved = get_reserved(bus); - u32 data_bits; - - if (state_high) - data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; - else - data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | - GPIO_DATA_VAL_MASK; - - I915_WRITE_NOTRACE(bus->gpio_reg, reserved | data_bits); - POSTING_READ(bus->gpio_reg); -} - -static bool -intel_gpio_setup(struct intel_gmbus *bus, u32 pin) -{ - struct drm_i915_private *dev_priv = bus->dev_priv; - static const int map_pin_to_reg[] = { - 0, - GPIOB, - GPIOA, - GPIOC, - GPIOD, - GPIOE, - 0, - GPIOF, - }; - struct i2c_algo_bit_data *algo; - - if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) - return false; - - algo = &bus->bit_algo; - - bus->gpio_reg = map_pin_to_reg[pin]; - if (HAS_PCH_SPLIT(dev_priv->dev)) - bus->gpio_reg += PCH_GPIOA - GPIOA; - - bus->adapter.algo_data = algo; - algo->setsda = set_data; - algo->setscl = set_clock; - algo->getsda = get_data; - algo->getscl = get_clock; - algo->udelay = I2C_RISEFALL_TIME; - algo->timeout = usecs_to_jiffies(2200); - algo->data = bus; - - return true; -} - -static int -intel_i2c_quirk_xfer(struct intel_gmbus *bus, - struct i2c_msg *msgs, - int num) -{ - struct drm_i915_private *dev_priv = bus->dev_priv; - int ret; - - intel_i2c_reset(dev_priv->dev); - - intel_i2c_quirk_set(dev_priv, true); - set_data(bus, 1); - set_clock(bus, 1); - udelay(I2C_RISEFALL_TIME); - - ret = i2c_bit_algo.master_xfer(&bus->adapter, msgs, num); - - set_data(bus, 1); - set_clock(bus, 1); - intel_i2c_quirk_set(dev_priv, false); - - return ret; -} - -static int -gmbus_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - struct intel_gmbus *bus = container_of(adapter, - struct intel_gmbus, - adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; - int i, reg_offset, ret; - - mutex_lock(&dev_priv->gmbus_mutex); - - if (bus->force_bit) { - ret = intel_i2c_quirk_xfer(bus, msgs, num); - goto out; - } - - reg_offset = HAS_PCH_SPLIT(dev_priv->dev) ? PCH_GMBUS0 - GMBUS0 : 0; - - I915_WRITE(GMBUS0 + reg_offset, bus->reg0); - - for (i = 0; i < num; i++) { - u16 len = msgs[i].len; - u8 *buf = msgs[i].buf; - - if (msgs[i].flags & I2C_M_RD) { - I915_WRITE(GMBUS1 + reg_offset, - GMBUS_CYCLE_WAIT | - (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | - (len << GMBUS_BYTE_COUNT_SHIFT) | - (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | - GMBUS_SLAVE_READ | GMBUS_SW_RDY); - POSTING_READ(GMBUS2+reg_offset); - do { - u32 val, loop = 0; - - if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) - goto timeout; - if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - goto clear_err; - - val = I915_READ(GMBUS3 + reg_offset); - do { - *buf++ = val & 0xff; - val >>= 8; - } while (--len && ++loop < 4); - } while (len); - } else { - u32 val, loop; - - val = loop = 0; - do { - val |= *buf++ << (8 * loop); - } while (--len && ++loop < 4); - - I915_WRITE(GMBUS3 + reg_offset, val); - I915_WRITE(GMBUS1 + reg_offset, - GMBUS_CYCLE_WAIT | - (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | - (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | - (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | - GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); - POSTING_READ(GMBUS2+reg_offset); - - while (len) { - if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) - goto timeout; - if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - goto clear_err; - - val = loop = 0; - do { - val |= *buf++ << (8 * loop); - } while (--len && ++loop < 4); - - I915_WRITE(GMBUS3 + reg_offset, val); - POSTING_READ(GMBUS2+reg_offset); - } - } - - if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) - goto timeout; - if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - goto clear_err; - } - - goto done; - -clear_err: - /* Toggle the Software Clear Interrupt bit. This has the effect - * of resetting the GMBUS controller and so clearing the - * BUS_ERROR raised by the slave's NAK. - */ - I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); - I915_WRITE(GMBUS1 + reg_offset, 0); - -done: - /* Mark the GMBUS interface as disabled after waiting for idle. - * We will re-enable it at the start of the next xfer, - * till then let it sleep. - */ - if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10)) - DRM_INFO("GMBUS timed out waiting for idle\n"); - I915_WRITE(GMBUS0 + reg_offset, 0); - ret = i; - goto out; - -timeout: - DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", - bus->reg0 & 0xff, bus->adapter.name); - I915_WRITE(GMBUS0 + reg_offset, 0); - - /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ - if (!bus->has_gpio) { - ret = -EIO; - } else { - bus->force_bit = true; - ret = intel_i2c_quirk_xfer(bus, msgs, num); - } -out: - mutex_unlock(&dev_priv->gmbus_mutex); - return ret; -} - -static u32 gmbus_func(struct i2c_adapter *adapter) -{ - return i2c_bit_algo.functionality(adapter) & - (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - /* I2C_FUNC_10BIT_ADDR | */ - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL); -} - -static const struct i2c_algorithm gmbus_algorithm = { - .master_xfer = gmbus_xfer, - .functionality = gmbus_func -}; - -/** - * intel_gmbus_setup - instantiate all Intel i2c GMBuses - * @dev: DRM device - */ -int intel_setup_gmbus(struct drm_device *dev) -{ - static const char *names[GMBUS_NUM_PORTS] = { - "disabled", - "ssc", - "vga", - "panel", - "dpc", - "dpb", - "reserved", - "dpd", - }; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret, i; - - dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus), - GFP_KERNEL); - if (dev_priv->gmbus == NULL) - return -ENOMEM; - - mutex_init(&dev_priv->gmbus_mutex); - - for (i = 0; i < GMBUS_NUM_PORTS; i++) { - struct intel_gmbus *bus = &dev_priv->gmbus[i]; - - bus->adapter.owner = THIS_MODULE; - bus->adapter.class = I2C_CLASS_DDC; - snprintf(bus->adapter.name, - sizeof(bus->adapter.name), - "i915 gmbus %s", - names[i]); - - bus->adapter.dev.parent = &dev->pdev->dev; - bus->dev_priv = dev_priv; - - bus->adapter.algo = &gmbus_algorithm; - ret = i2c_add_adapter(&bus->adapter); - if (ret) - goto err; - - /* By default use a conservative clock rate */ - bus->reg0 = i | GMBUS_RATE_100KHZ; - - bus->has_gpio = intel_gpio_setup(bus, i); - - /* XXX force bit banging until GMBUS is fully debugged */ - if (bus->has_gpio) - bus->force_bit = true; - } - - intel_i2c_reset(dev_priv->dev); - - return 0; - -err: - while (--i) { - struct intel_gmbus *bus = &dev_priv->gmbus[i]; - i2c_del_adapter(&bus->adapter); - } - kfree(dev_priv->gmbus); - dev_priv->gmbus = NULL; - return ret; -} - -void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) -{ - struct intel_gmbus *bus = to_intel_gmbus(adapter); - - bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed; -} - -void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) -{ - struct intel_gmbus *bus = to_intel_gmbus(adapter); - - if (bus->has_gpio) - bus->force_bit = force_bit; -} - -void intel_teardown_gmbus(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - if (dev_priv->gmbus == NULL) - return; - - for (i = 0; i < GMBUS_NUM_PORTS; i++) { - struct intel_gmbus *bus = &dev_priv->gmbus[i]; - i2c_del_adapter(&bus->adapter); - } - - kfree(dev_priv->gmbus); - dev_priv->gmbus = NULL; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_lvds.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_lvds.c deleted file mode 100644 index 9fadd643..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_lvds.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * Copyright (c) 2006 Dave Airlie - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Dave Airlie - * Jesse Barnes - */ - -#include -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_edid.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include - -/* Private structure for the integrated LVDS support */ -struct intel_lvds { - struct intel_encoder base; - - struct edid *edid; - - int fitting_mode; - u32 pfit_control; - u32 pfit_pgm_ratios; - bool pfit_dirty; - - struct drm_display_mode *fixed_mode; -}; - -static struct intel_lvds *to_intel_lvds(struct drm_encoder *encoder) -{ - return container_of(encoder, struct intel_lvds, base.base); -} - -static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_lvds, base); -} - -/** - * Sets the power state for the panel. - */ -static void intel_lvds_enable(struct intel_lvds *intel_lvds) -{ - struct drm_device *dev = intel_lvds->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 ctl_reg, lvds_reg, stat_reg; - - if (HAS_PCH_SPLIT(dev)) { - ctl_reg = PCH_PP_CONTROL; - lvds_reg = PCH_LVDS; - stat_reg = PCH_PP_STATUS; - } else { - ctl_reg = PP_CONTROL; - lvds_reg = LVDS; - stat_reg = PP_STATUS; - } - - I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); - - if (intel_lvds->pfit_dirty) { - /* - * Enable automatic panel scaling so that non-native modes - * fill the screen. The panel fitter should only be - * adjusted whilst the pipe is disabled, according to - * register description and PRM. - */ - DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", - intel_lvds->pfit_control, - intel_lvds->pfit_pgm_ratios); - - I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); - I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); - intel_lvds->pfit_dirty = false; - } - - I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); - POSTING_READ(lvds_reg); - if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) - DRM_ERROR("timed out waiting for panel to power on\n"); - - intel_panel_enable_backlight(dev); -} - -static void intel_lvds_disable(struct intel_lvds *intel_lvds) -{ - struct drm_device *dev = intel_lvds->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 ctl_reg, lvds_reg, stat_reg; - - if (HAS_PCH_SPLIT(dev)) { - ctl_reg = PCH_PP_CONTROL; - lvds_reg = PCH_LVDS; - stat_reg = PCH_PP_STATUS; - } else { - ctl_reg = PP_CONTROL; - lvds_reg = LVDS; - stat_reg = PP_STATUS; - } - - intel_panel_disable_backlight(dev); - - I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); - if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) - DRM_ERROR("timed out waiting for panel to power off\n"); - - if (intel_lvds->pfit_control) { - I915_WRITE(PFIT_CONTROL, 0); - intel_lvds->pfit_dirty = true; - } - - I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); - POSTING_READ(lvds_reg); -} - -static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) -{ - struct intel_lvds *intel_lvds = to_intel_lvds(encoder); - - if (mode == DRM_MODE_DPMS_ON) - intel_lvds_enable(intel_lvds); - else - intel_lvds_disable(intel_lvds); - - /* XXX: We never power down the LVDS pairs. */ -} - -static int intel_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_lvds *intel_lvds = intel_attached_lvds(connector); - struct drm_display_mode *fixed_mode = intel_lvds->fixed_mode; - - if (mode->hdisplay > fixed_mode->hdisplay) - return MODE_PANEL; - if (mode->vdisplay > fixed_mode->vdisplay) - return MODE_PANEL; - - return MODE_OK; -} - -static void -centre_horizontally(struct drm_display_mode *mode, - int width) -{ - u32 border, sync_pos, blank_width, sync_width; - - /* keep the hsync and hblank widths constant */ - sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start; - blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start; - sync_pos = (blank_width - sync_width + 1) / 2; - - border = (mode->hdisplay - width + 1) / 2; - border += border & 1; /* make the border even */ - - mode->crtc_hdisplay = width; - mode->crtc_hblank_start = width + border; - mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width; - - mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; - mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; -} - -static void -centre_vertically(struct drm_display_mode *mode, - int height) -{ - u32 border, sync_pos, blank_width, sync_width; - - /* keep the vsync and vblank widths constant */ - sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start; - blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start; - sync_pos = (blank_width - sync_width + 1) / 2; - - border = (mode->vdisplay - height + 1) / 2; - - mode->crtc_vdisplay = height; - mode->crtc_vblank_start = height + border; - mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width; - - mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; - mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; -} - -static inline u32 panel_fitter_scaling(u32 source, u32 target) -{ - /* - * Floating point operation is not supported. So the FACTOR - * is defined, which can avoid the floating point computation - * when calculating the panel ratio. - */ -#define ACCURACY 12 -#define FACTOR (1 << ACCURACY) - u32 ratio = source * FACTOR / target; - return (FACTOR * ratio + FACTOR/2) / FACTOR; -} - -static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - struct intel_lvds *intel_lvds = to_intel_lvds(encoder); - struct drm_encoder *tmp_encoder; - u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; - int pipe; - - /* Should never happen!! */ - if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) { - DRM_ERROR("Can't support LVDS on pipe A\n"); - return false; - } - - /* Should never happen!! */ - list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { - if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { - DRM_ERROR("Can't enable LVDS and another " - "encoder on the same pipe\n"); - return false; - } - } - - /* - * We have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - intel_fixed_panel_mode(intel_lvds->fixed_mode, adjusted_mode); - - if (HAS_PCH_SPLIT(dev)) { - intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, - mode, adjusted_mode); - return true; - } - - /* Native modes don't need fitting */ - if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) - goto out; - - /* 965+ wants fuzzy fitting */ - if (INTEL_INFO(dev)->gen >= 4) - pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | - PFIT_FILTER_FUZZY); - - /* - * Enable automatic panel scaling for non-native modes so that they fill - * the screen. Should be enabled before the pipe is enabled, according - * to register description and PRM. - * Change the value here to see the borders for debugging - */ - for_each_pipe(pipe) - I915_WRITE(BCLRPAT(pipe), 0); - - drm_mode_set_crtcinfo(adjusted_mode, 0); - - switch (intel_lvds->fitting_mode) { - case DRM_MODE_SCALE_CENTER: - /* - * For centered modes, we have to calculate border widths & - * heights and modify the values programmed into the CRTC. - */ - centre_horizontally(adjusted_mode, mode->hdisplay); - centre_vertically(adjusted_mode, mode->vdisplay); - border = LVDS_BORDER_ENABLE; - break; - - case DRM_MODE_SCALE_ASPECT: - /* Scale but preserve the aspect ratio */ - if (INTEL_INFO(dev)->gen >= 4) { - u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; - u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; - - /* 965+ is easy, it does everything in hw */ - if (scaled_width > scaled_height) - pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; - else if (scaled_width < scaled_height) - pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; - else if (adjusted_mode->hdisplay != mode->hdisplay) - pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; - } else { - u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; - u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; - /* - * For earlier chips we have to calculate the scaling - * ratio by hand and program it into the - * PFIT_PGM_RATIO register - */ - if (scaled_width > scaled_height) { /* pillar */ - centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay); - - border = LVDS_BORDER_ENABLE; - if (mode->vdisplay != adjusted_mode->vdisplay) { - u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay); - pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | - bits << PFIT_VERT_SCALE_SHIFT); - pfit_control |= (PFIT_ENABLE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - } else if (scaled_width < scaled_height) { /* letter */ - centre_vertically(adjusted_mode, scaled_width / mode->hdisplay); - - border = LVDS_BORDER_ENABLE; - if (mode->hdisplay != adjusted_mode->hdisplay) { - u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay); - pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT | - bits << PFIT_VERT_SCALE_SHIFT); - pfit_control |= (PFIT_ENABLE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - } else - /* Aspects match, Let hw scale both directions */ - pfit_control |= (PFIT_ENABLE | - VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); - } - break; - - case DRM_MODE_SCALE_FULLSCREEN: - /* - * Full scaling, even if it changes the aspect ratio. - * Fortunately this is all done for us in hw. - */ - if (mode->vdisplay != adjusted_mode->vdisplay || - mode->hdisplay != adjusted_mode->hdisplay) { - pfit_control |= PFIT_ENABLE; - if (INTEL_INFO(dev)->gen >= 4) - pfit_control |= PFIT_SCALING_AUTO; - else - pfit_control |= (VERT_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_AUTO_SCALE | - HORIZ_INTERP_BILINEAR); - } - break; - - default: - break; - } - -out: - /* If not enabling scaling, be consistent and always use 0. */ - if ((pfit_control & PFIT_ENABLE) == 0) { - pfit_control = 0; - pfit_pgm_ratios = 0; - } - - /* Make sure pre-965 set dither correctly */ - if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - - if (pfit_control != intel_lvds->pfit_control || - pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { - intel_lvds->pfit_control = pfit_control; - intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; - intel_lvds->pfit_dirty = true; - } - dev_priv->lvds_border_bits = border; - - /* - * XXX: It would be nice to support lower refresh rates on the - * panels to reduce power consumption, and perhaps match the - * user's requested refresh rate. - */ - - return true; -} - -static void intel_lvds_prepare(struct drm_encoder *encoder) -{ - struct intel_lvds *intel_lvds = to_intel_lvds(encoder); - - /* - * Prior to Ironlake, we must disable the pipe if we want to adjust - * the panel fitter. However at all other times we can just reset - * the registers regardless. - */ - if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) - intel_lvds_disable(intel_lvds); -} - -static void intel_lvds_commit(struct drm_encoder *encoder) -{ - struct intel_lvds *intel_lvds = to_intel_lvds(encoder); - - /* Always do a full power on as we do not know what state - * we were left in. - */ - intel_lvds_enable(intel_lvds); -} - -static void intel_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* - * The LVDS pin pair will already have been turned on in the - * intel_crtc_mode_set since it has a large impact on the DPLL - * settings. - */ -} - -/** - * Detect the LVDS connection. - * - * Since LVDS doesn't have hotlug, we use the lid as a proxy. Open means - * connected and closed means disconnected. We also send hotplug events as - * needed, using lid status notification from the input layer. - */ -static enum drm_connector_status -intel_lvds_detect(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - enum drm_connector_status status; - - status = intel_panel_detect(dev); - if (status != connector_status_unknown) - return status; - - return connector_status_connected; -} - -/** - * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. - */ -static int intel_lvds_get_modes(struct drm_connector *connector) -{ - struct intel_lvds *intel_lvds = intel_attached_lvds(connector); - struct drm_device *dev = connector->dev; - struct drm_display_mode *mode; - - if (intel_lvds->edid) - return drm_add_edid_modes(connector, intel_lvds->edid); - - mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); - if (mode == NULL) - return 0; - - drm_mode_probed_add(connector, mode); - return 1; -} - -static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident); - return 1; -} - -/* The GPU hangs up on these systems if modeset is performed on LID open */ -static const struct dmi_system_id intel_no_modeset_on_lid[] = { - { - .callback = intel_no_modeset_on_lid_dmi_callback, - .ident = "Toshiba Tecra A11", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"), - }, - }, - - { } /* terminating entry */ -}; - -/* - * Lid events. Note the use of 'modeset_on_lid': - * - we set it on lid close, and reset it on open - * - we use it as a "only once" bit (ie we ignore - * duplicate events where it was already properly - * set/reset) - * - the suspend/resume paths will also set it to - * zero, since they restore the mode ("lid open"). - */ -static int intel_lid_notify(struct notifier_block *nb, unsigned long val, - void *unused) -{ - struct drm_i915_private *dev_priv = - container_of(nb, struct drm_i915_private, lid_notifier); - struct drm_device *dev = dev_priv->dev; - struct drm_connector *connector = dev_priv->int_lvds_connector; - - if (dev->switch_power_state != DRM_SWITCH_POWER_ON) - return NOTIFY_OK; - - /* - * check and update the status of LVDS connector after receiving - * the LID nofication event. - */ - if (connector) - connector->status = connector->funcs->detect(connector, - false); - - /* Don't force modeset on machines where it causes a GPU lockup */ - if (dmi_check_system(intel_no_modeset_on_lid)) - return NOTIFY_OK; - if (!acpi_lid_open()) { - dev_priv->modeset_on_lid = 1; - return NOTIFY_OK; - } - - if (!dev_priv->modeset_on_lid) - return NOTIFY_OK; - - dev_priv->modeset_on_lid = 0; - - mutex_lock(&dev->mode_config.mutex); - drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); - - return NOTIFY_OK; -} - -/** - * intel_lvds_destroy - unregister and free LVDS structures - * @connector: connector to free - * - * Unregister the DDC bus for this connector then free the driver private - * structure. - */ -static void intel_lvds_destroy(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - intel_panel_destroy_backlight(dev); - - if (dev_priv->lid_notifier.notifier_call) - acpi_lid_notifier_unregister(&dev_priv->lid_notifier); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static int intel_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct intel_lvds *intel_lvds = intel_attached_lvds(connector); - struct drm_device *dev = connector->dev; - - if (property == dev->mode_config.scaling_mode_property) { - struct drm_crtc *crtc = intel_lvds->base.base.crtc; - - if (value == DRM_MODE_SCALE_NONE) { - DRM_DEBUG_KMS("no scaling not supported\n"); - return -EINVAL; - } - - if (intel_lvds->fitting_mode == value) { - /* the LVDS scaling property is not changed */ - return 0; - } - intel_lvds->fitting_mode = value; - if (crtc && crtc->enabled) { - /* - * If the CRTC is enabled, the display will be changed - * according to the new panel fitting mode. - */ - drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); - } - } - - return 0; -} - -static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { - .dpms = intel_lvds_dpms, - .mode_fixup = intel_lvds_mode_fixup, - .prepare = intel_lvds_prepare, - .mode_set = intel_lvds_mode_set, - .commit = intel_lvds_commit, -}; - -static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { - .get_modes = intel_lvds_get_modes, - .mode_valid = intel_lvds_mode_valid, - .best_encoder = intel_best_encoder, -}; - -static const struct drm_connector_funcs intel_lvds_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = intel_lvds_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_lvds_set_property, - .destroy = intel_lvds_destroy, -}; - -static const struct drm_encoder_funcs intel_lvds_enc_funcs = { - .destroy = intel_encoder_destroy, -}; - -static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident); - return 1; -} - -/* These systems claim to have LVDS, but really don't */ -static const struct dmi_system_id intel_no_lvds[] = { - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Apple Mac Mini (Core series)", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Apple Mac Mini (Core 2 series)", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple"), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "MSI IM-945GSE-A", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MSI"), - DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Dell Studio Hybrid", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Dell OptiPlex FX170", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "AOpen Mini PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "AOpen"), - DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "AOpen Mini PC MP915", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), - DMI_MATCH(DMI_BOARD_NAME, "i915GMx-F"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "AOpen i915GMm-HFS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), - DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "AOpen i45GMx-I", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), - DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Aopen i945GTt-VFA", - .matches = { - DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Clientron U800", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), - DMI_MATCH(DMI_PRODUCT_NAME, "U800"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Clientron E830", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), - DMI_MATCH(DMI_PRODUCT_NAME, "E830"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Asus EeeBox PC EB1007", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Asus AT5NM10T-I", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Hewlett-Packard HP t5740e Thin Client", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Hewlett-Packard t5745", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Hewlett-Packard st5747", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "MSI Wind Box DC500", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), - DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), - }, - }, - - { } /* terminating entry */ -}; - -/** - * intel_find_lvds_downclock - find the reduced downclock for LVDS in EDID - * @dev: drm device - * @connector: LVDS connector - * - * Find the reduced downclock for LVDS in EDID. - */ -static void intel_find_lvds_downclock(struct drm_device *dev, - struct drm_display_mode *fixed_mode, - struct drm_connector *connector) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_display_mode *scan; - int temp_downclock; - - temp_downclock = fixed_mode->clock; - list_for_each_entry(scan, &connector->probed_modes, head) { - /* - * If one mode has the same resolution with the fixed_panel - * mode while they have the different refresh rate, it means - * that the reduced downclock is found for the LVDS. In such - * case we can set the different FPx0/1 to dynamically select - * between low and high frequency. - */ - if (scan->hdisplay == fixed_mode->hdisplay && - scan->hsync_start == fixed_mode->hsync_start && - scan->hsync_end == fixed_mode->hsync_end && - scan->htotal == fixed_mode->htotal && - scan->vdisplay == fixed_mode->vdisplay && - scan->vsync_start == fixed_mode->vsync_start && - scan->vsync_end == fixed_mode->vsync_end && - scan->vtotal == fixed_mode->vtotal) { - if (scan->clock < temp_downclock) { - /* - * The downclock is already found. But we - * expect to find the lower downclock. - */ - temp_downclock = scan->clock; - } - } - } - if (temp_downclock < fixed_mode->clock && i915_lvds_downclock) { - /* We found the downclock for LVDS. */ - dev_priv->lvds_downclock_avail = 1; - dev_priv->lvds_downclock = temp_downclock; - DRM_DEBUG_KMS("LVDS downclock is found in EDID. " - "Normal clock %dKhz, downclock %dKhz\n", - fixed_mode->clock, temp_downclock); - } -} - -/* - * Enumerate the child dev array parsed from VBT to check whether - * the LVDS is present. - * If it is present, return 1. - * If it is not present, return false. - * If no child dev is parsed from VBT, it assumes that the LVDS is present. - */ -static bool lvds_is_present_in_vbt(struct drm_device *dev, - u8 *i2c_pin) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int i; - - if (!dev_priv->child_dev_num) - return true; - - for (i = 0; i < dev_priv->child_dev_num; i++) { - struct child_device_config *child = dev_priv->child_dev + i; - - /* If the device type is not LFP, continue. - * We have to check both the new identifiers as well as the - * old for compatibility with some BIOSes. - */ - if (child->device_type != DEVICE_TYPE_INT_LFP && - child->device_type != DEVICE_TYPE_LFP) - continue; - - if (child->i2c_pin) - *i2c_pin = child->i2c_pin; - - /* However, we cannot trust the BIOS writers to populate - * the VBT correctly. Since LVDS requires additional - * information from AIM blocks, a non-zero addin offset is - * a good indicator that the LVDS is actually present. - */ - if (child->addin_offset) - return true; - - /* But even then some BIOS writers perform some black magic - * and instantiate the device without reference to any - * additional data. Trust that if the VBT was written into - * the OpRegion then they have validated the LVDS's existence. - */ - if (dev_priv->opregion.vbt) - return true; - } - - return false; -} - -static bool intel_lvds_supported(struct drm_device *dev) -{ - /* With the introduction of the PCH we gained a dedicated - * LVDS presence pin, use it. */ - if (HAS_PCH_SPLIT(dev)) - return true; - - /* Otherwise LVDS was only attached to mobile products, - * except for the inglorious 830gm */ - return IS_MOBILE(dev) && !IS_I830(dev); -} - -/** - * intel_lvds_init - setup LVDS connectors on this device - * @dev: drm device - * - * Create the connector, register the LVDS DDC bus, and try to figure out what - * modes we can display on the LVDS panel (if present). - */ -bool intel_lvds_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_lvds *intel_lvds; - struct intel_encoder *intel_encoder; - struct intel_connector *intel_connector; - struct drm_connector *connector; - struct drm_encoder *encoder; - struct drm_display_mode *scan; /* *modes, *bios_mode; */ - struct drm_crtc *crtc; - u32 lvds; - int pipe; - u8 pin; - - if (!intel_lvds_supported(dev)) - return false; - - /* Skip init on machines we know falsely report LVDS */ - if (dmi_check_system(intel_no_lvds)) - return false; - - pin = GMBUS_PORT_PANEL; - if (!lvds_is_present_in_vbt(dev, &pin)) { - DRM_DEBUG_KMS("LVDS is not present in VBT\n"); - return false; - } - - if (HAS_PCH_SPLIT(dev)) { - if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) - return false; - if (dev_priv->edp.support) { - DRM_DEBUG_KMS("disable LVDS for eDP support\n"); - return false; - } - } - - intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); - if (!intel_lvds) { - return false; - } - - intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); - if (!intel_connector) { - kfree(intel_lvds); - return false; - } - - if (!HAS_PCH_SPLIT(dev)) { - intel_lvds->pfit_control = I915_READ(PFIT_CONTROL); - } - - intel_encoder = &intel_lvds->base; - encoder = &intel_encoder->base; - connector = &intel_connector->base; - drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, - DRM_MODE_CONNECTOR_LVDS); - - drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, - DRM_MODE_ENCODER_LVDS); - - intel_connector_attach_encoder(intel_connector, intel_encoder); - intel_encoder->type = INTEL_OUTPUT_LVDS; - - intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); - if (HAS_PCH_SPLIT(dev)) - intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); - else - intel_encoder->crtc_mask = (1 << 1); - - drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); - drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); - connector->display_info.subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /* create the scaling mode property */ - drm_mode_create_scaling_mode_property(dev); - /* - * the initial panel fitting mode will be FULL_SCREEN. - */ - - drm_connector_attach_property(&intel_connector->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_ASPECT); - intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; - /* - * LVDS discovery: - * 1) check for EDID on DDC - * 2) check for VBT data - * 3) check to see if LVDS is already on - * if none of the above, no panel - * 4) make sure lid is open - * if closed, act like it's not there for now - */ - - /* - * Attempt to get the fixed panel mode from DDC. Assume that the - * preferred mode is the right one. - */ - intel_lvds->edid = drm_get_edid(connector, - &dev_priv->gmbus[pin].adapter); - if (intel_lvds->edid) { - if (drm_add_edid_modes(connector, - intel_lvds->edid)) { - drm_mode_connector_update_edid_property(connector, - intel_lvds->edid); - } else { - kfree(intel_lvds->edid); - intel_lvds->edid = NULL; - } - } - if (!intel_lvds->edid) { - /* Didn't get an EDID, so - * Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - connector->display_info.min_vfreq = 0; - connector->display_info.max_vfreq = 200; - connector->display_info.min_hfreq = 0; - connector->display_info.max_hfreq = 200; - } - - list_for_each_entry(scan, &connector->probed_modes, head) { - if (scan->type & DRM_MODE_TYPE_PREFERRED) { - intel_lvds->fixed_mode = - drm_mode_duplicate(dev, scan); - intel_find_lvds_downclock(dev, - intel_lvds->fixed_mode, - connector); - goto out; - } - } - - /* Failed to get EDID, what about VBT? */ - if (dev_priv->lfp_lvds_vbt_mode) { - intel_lvds->fixed_mode = - drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); - if (intel_lvds->fixed_mode) { - intel_lvds->fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; - } - } - - /* - * If we didn't get EDID, try checking if the panel is already turned - * on. If so, assume that whatever is currently programmed is the - * correct mode. - */ - - /* Ironlake: FIXME if still fail, not try pipe mode now */ - if (HAS_PCH_SPLIT(dev)) - goto failed; - - lvds = I915_READ(LVDS); - pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - crtc = intel_get_crtc_for_pipe(dev, pipe); - - if (crtc && (lvds & LVDS_PORT_EN)) { - intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc); - if (intel_lvds->fixed_mode) { - intel_lvds->fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; - goto out; - } - } - - /* If we still don't have a mode after all that, give up. */ - if (!intel_lvds->fixed_mode) - goto failed; - -out: - if (HAS_PCH_SPLIT(dev)) { - u32 pwm; - - pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; - - /* make sure PWM is enabled and locked to the LVDS pipe */ - pwm = I915_READ(BLC_PWM_CPU_CTL2); - if (pipe == 0 && (pwm & PWM_PIPE_B)) - I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); - if (pipe) - pwm |= PWM_PIPE_B; - else - pwm &= ~PWM_PIPE_B; - I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); - - pwm = I915_READ(BLC_PWM_PCH_CTL1); - pwm |= PWM_PCH_ENABLE; - I915_WRITE(BLC_PWM_PCH_CTL1, pwm); - /* - * Unlock registers and just - * leave them unlocked - */ - I915_WRITE(PCH_PP_CONTROL, - I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); - } else { - /* - * Unlock registers and just - * leave them unlocked - */ - I915_WRITE(PP_CONTROL, - I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); - } - dev_priv->lid_notifier.notifier_call = intel_lid_notify; - if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { - DRM_DEBUG_KMS("lid notifier registration failed\n"); - dev_priv->lid_notifier.notifier_call = NULL; - } - /* keep the LVDS connector */ - dev_priv->int_lvds_connector = connector; - drm_sysfs_connector_add(connector); - - intel_panel_setup_backlight(dev); - - return true; - -failed: - DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); - drm_connector_cleanup(connector); - drm_encoder_cleanup(encoder); - kfree(intel_lvds); - kfree(intel_connector); - return false; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_modes.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_modes.c deleted file mode 100644 index d1928e79..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_modes.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2007 Dave Airlie - * Copyright (c) 2007, 2010 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include "drmP.h" -#include "drm_edid.h" -#include "intel_drv.h" -#include "i915_drv.h" - -/** - * intel_ddc_probe - * - */ -bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus) -{ - struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; - u8 out_buf[] = { 0x0, 0x0}; - u8 buf[2]; - struct i2c_msg msgs[] = { - { - .addr = DDC_ADDR, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = DDC_ADDR, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 2) == 2; -} - -/** - * intel_ddc_get_modes - get modelist from monitor - * @connector: DRM connector device to use - * @adapter: i2c adapter - * - * Fetch the EDID information from @connector using the DDC bus. - */ -int intel_ddc_get_modes(struct drm_connector *connector, - struct i2c_adapter *adapter) -{ - struct edid *edid; - int ret = 0; - - edid = drm_get_edid(connector, adapter); - if (edid) { - drm_mode_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - drm_edid_to_eld(connector, edid); - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - return ret; -} - -static const struct drm_prop_enum_list force_audio_names[] = { - { HDMI_AUDIO_OFF_DVI, "force-dvi" }, - { HDMI_AUDIO_OFF, "off" }, - { HDMI_AUDIO_AUTO, "auto" }, - { HDMI_AUDIO_ON, "on" }, -}; - -void -intel_attach_force_audio_property(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_property *prop; - - prop = dev_priv->force_audio_property; - if (prop == NULL) { - prop = drm_property_create_enum(dev, 0, - "audio", - force_audio_names, - ARRAY_SIZE(force_audio_names)); - if (prop == NULL) - return; - - dev_priv->force_audio_property = prop; - } - drm_connector_attach_property(connector, prop, 0); -} - -static const struct drm_prop_enum_list broadcast_rgb_names[] = { - { 0, "Full" }, - { 1, "Limited 16:235" }, -}; - -void -intel_attach_broadcast_rgb_property(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_property *prop; - - prop = dev_priv->broadcast_rgb_property; - if (prop == NULL) { - prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, - "Broadcast RGB", - broadcast_rgb_names, - ARRAY_SIZE(broadcast_rgb_names)); - if (prop == NULL) - return; - - dev_priv->broadcast_rgb_property = prop; - } - - drm_connector_attach_property(connector, prop, 0); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_opregion.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_opregion.c deleted file mode 100644 index 289140bc..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_opregion.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright 2008 Intel Corporation - * Copyright 2008 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include -#include -#include - -#include "drmP.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "intel_drv.h" - -#define PCI_ASLE 0xe4 -#define PCI_ASLS 0xfc - -#define OPREGION_HEADER_OFFSET 0 -#define OPREGION_ACPI_OFFSET 0x100 -#define ACPI_CLID 0x01ac /* current lid state indicator */ -#define ACPI_CDCK 0x01b0 /* current docking state indicator */ -#define OPREGION_SWSCI_OFFSET 0x200 -#define OPREGION_ASLE_OFFSET 0x300 -#define OPREGION_VBT_OFFSET 0x400 - -#define OPREGION_SIGNATURE "IntelGraphicsMem" -#define MBOX_ACPI (1<<0) -#define MBOX_SWSCI (1<<1) -#define MBOX_ASLE (1<<2) - -struct opregion_header { - u8 signature[16]; - u32 size; - u32 opregion_ver; - u8 bios_ver[32]; - u8 vbios_ver[16]; - u8 driver_ver[16]; - u32 mboxes; - u8 reserved[164]; -} __attribute__((packed)); - -/* OpRegion mailbox #1: public ACPI methods */ -struct opregion_acpi { - u32 drdy; /* driver readiness */ - u32 csts; /* notification status */ - u32 cevt; /* current event */ - u8 rsvd1[20]; - u32 didl[8]; /* supported display devices ID list */ - u32 cpdl[8]; /* currently presented display list */ - u32 cadl[8]; /* currently active display list */ - u32 nadl[8]; /* next active devices list */ - u32 aslp; /* ASL sleep time-out */ - u32 tidx; /* toggle table index */ - u32 chpd; /* current hotplug enable indicator */ - u32 clid; /* current lid state*/ - u32 cdck; /* current docking state */ - u32 sxsw; /* Sx state resume */ - u32 evts; /* ASL supported events */ - u32 cnot; /* current OS notification */ - u32 nrdy; /* driver status */ - u8 rsvd2[60]; -} __attribute__((packed)); - -/* OpRegion mailbox #2: SWSCI */ -struct opregion_swsci { - u32 scic; /* SWSCI command|status|data */ - u32 parm; /* command parameters */ - u32 dslp; /* driver sleep time-out */ - u8 rsvd[244]; -} __attribute__((packed)); - -/* OpRegion mailbox #3: ASLE */ -struct opregion_asle { - u32 ardy; /* driver readiness */ - u32 aslc; /* ASLE interrupt command */ - u32 tche; /* technology enabled indicator */ - u32 alsi; /* current ALS illuminance reading */ - u32 bclp; /* backlight brightness to set */ - u32 pfit; /* panel fitting state */ - u32 cblv; /* current brightness level */ - u16 bclm[20]; /* backlight level duty cycle mapping table */ - u32 cpfm; /* current panel fitting mode */ - u32 epfm; /* enabled panel fitting modes */ - u8 plut[74]; /* panel LUT and identifier */ - u32 pfmb; /* PWM freq and min brightness */ - u8 rsvd[102]; -} __attribute__((packed)); - -/* ASLE irq request bits */ -#define ASLE_SET_ALS_ILLUM (1 << 0) -#define ASLE_SET_BACKLIGHT (1 << 1) -#define ASLE_SET_PFIT (1 << 2) -#define ASLE_SET_PWM_FREQ (1 << 3) -#define ASLE_REQ_MSK 0xf - -/* response bits of ASLE irq request */ -#define ASLE_ALS_ILLUM_FAILED (1<<10) -#define ASLE_BACKLIGHT_FAILED (1<<12) -#define ASLE_PFIT_FAILED (1<<14) -#define ASLE_PWM_FREQ_FAILED (1<<16) - -/* ASLE backlight brightness to set */ -#define ASLE_BCLP_VALID (1<<31) -#define ASLE_BCLP_MSK (~(1<<31)) - -/* ASLE panel fitting request */ -#define ASLE_PFIT_VALID (1<<31) -#define ASLE_PFIT_CENTER (1<<0) -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define ASLE_PFIT_STRETCH_GFX (1<<2) - -/* PWM frequency and minimum brightness */ -#define ASLE_PFMB_BRIGHTNESS_MASK (0xff) -#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) -#define ASLE_PFMB_PWM_MASK (0x7ffffe00) -#define ASLE_PFMB_PWM_VALID (1<<31) - -#define ASLE_CBLV_VALID (1<<31) - -#define ACPI_OTHER_OUTPUT (0<<8) -#define ACPI_VGA_OUTPUT (1<<8) -#define ACPI_TV_OUTPUT (2<<8) -#define ACPI_DIGITAL_OUTPUT (3<<8) -#define ACPI_LVDS_OUTPUT (4<<8) - -#ifdef CONFIG_ACPI -static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - u32 max; - - if (!(bclp & ASLE_BCLP_VALID)) - return ASLE_BACKLIGHT_FAILED; - - bclp &= ASLE_BCLP_MSK; - if (bclp > 255) - return ASLE_BACKLIGHT_FAILED; - - max = intel_panel_get_max_backlight(dev); - intel_panel_set_backlight(dev, bclp * max / 255); - asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; - - return 0; -} - -static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) -{ - /* alsi is the current ALS reading in lux. 0 indicates below sensor - range, 0xffff indicates above sensor range. 1-0xfffe are valid */ - return 0; -} - -static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - if (pfmb & ASLE_PFMB_PWM_VALID) { - u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL); - u32 pwm = pfmb & ASLE_PFMB_PWM_MASK; - blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; - pwm = pwm >> 9; - /* FIXME - what do we do with the PWM? */ - } - return 0; -} - -static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) -{ - /* Panel fitting is currently controlled by the X code, so this is a - noop until modesetting support works fully */ - if (!(pfit & ASLE_PFIT_VALID)) - return ASLE_PFIT_FAILED; - return 0; -} - -void intel_opregion_asle_intr(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - u32 asle_stat = 0; - u32 asle_req; - - if (!asle) - return; - - asle_req = asle->aslc & ASLE_REQ_MSK; - - if (!asle_req) { - DRM_DEBUG_DRIVER("non asle set request??\n"); - return; - } - - if (asle_req & ASLE_SET_ALS_ILLUM) - asle_stat |= asle_set_als_illum(dev, asle->alsi); - - if (asle_req & ASLE_SET_BACKLIGHT) - asle_stat |= asle_set_backlight(dev, asle->bclp); - - if (asle_req & ASLE_SET_PFIT) - asle_stat |= asle_set_pfit(dev, asle->pfit); - - if (asle_req & ASLE_SET_PWM_FREQ) - asle_stat |= asle_set_pwm_freq(dev, asle->pfmb); - - asle->aslc = asle_stat; -} - -void intel_opregion_gse_intr(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - u32 asle_stat = 0; - u32 asle_req; - - if (!asle) - return; - - asle_req = asle->aslc & ASLE_REQ_MSK; - - if (!asle_req) { - DRM_DEBUG_DRIVER("non asle set request??\n"); - return; - } - - if (asle_req & ASLE_SET_ALS_ILLUM) { - DRM_DEBUG_DRIVER("Illum is not supported\n"); - asle_stat |= ASLE_ALS_ILLUM_FAILED; - } - - if (asle_req & ASLE_SET_BACKLIGHT) - asle_stat |= asle_set_backlight(dev, asle->bclp); - - if (asle_req & ASLE_SET_PFIT) { - DRM_DEBUG_DRIVER("Pfit is not supported\n"); - asle_stat |= ASLE_PFIT_FAILED; - } - - if (asle_req & ASLE_SET_PWM_FREQ) { - DRM_DEBUG_DRIVER("PWM freq is not supported\n"); - asle_stat |= ASLE_PWM_FREQ_FAILED; - } - - asle->aslc = asle_stat; -} -#define ASLE_ALS_EN (1<<0) -#define ASLE_BLC_EN (1<<1) -#define ASLE_PFIT_EN (1<<2) -#define ASLE_PFMB_EN (1<<3) - -void intel_opregion_enable_asle(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - - if (asle) { - if (IS_MOBILE(dev)) - intel_enable_asle(dev); - - asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | - ASLE_PFMB_EN; - asle->ardy = 1; - } -} - -#define ACPI_EV_DISPLAY_SWITCH (1<<0) -#define ACPI_EV_LID (1<<1) -#define ACPI_EV_DOCK (1<<2) - -static struct intel_opregion *system_opregion; - -static int intel_opregion_video_event(struct notifier_block *nb, - unsigned long val, void *data) -{ - /* The only video events relevant to opregion are 0x80. These indicate - either a docking event, lid switch or display switch request. In - Linux, these are handled by the dock, button and video drivers. - */ - - struct opregion_acpi *acpi; - struct acpi_bus_event *event = data; - int ret = NOTIFY_OK; - - if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) - return NOTIFY_DONE; - - if (!system_opregion) - return NOTIFY_DONE; - - acpi = system_opregion->acpi; - - if (event->type == 0x80 && !(acpi->cevt & 0x1)) - ret = NOTIFY_BAD; - - acpi->csts = 0; - - return ret; -} - -static struct notifier_block intel_opregion_notifier = { - .notifier_call = intel_opregion_video_event, -}; - -/* - * Initialise the DIDL field in opregion. This passes a list of devices to - * the firmware. Values are defined by section B.4.2 of the ACPI specification - * (version 3) - */ - -static void intel_didl_outputs(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - struct drm_connector *connector; - acpi_handle handle; - struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; - unsigned long long device_id; - acpi_status status; - int i = 0; - - handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) - return; - - if (acpi_is_video_device(acpi_dev)) - acpi_video_bus = acpi_dev; - else { - list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { - if (acpi_is_video_device(acpi_cdev)) { - acpi_video_bus = acpi_cdev; - break; - } - } - } - - if (!acpi_video_bus) { - printk(KERN_WARNING "No ACPI video bus found\n"); - return; - } - - list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { - if (i >= 8) { - dev_printk(KERN_ERR, &dev->pdev->dev, - "More than 8 outputs detected\n"); - return; - } - status = - acpi_evaluate_integer(acpi_cdev->handle, "_ADR", - NULL, &device_id); - if (ACPI_SUCCESS(status)) { - if (!device_id) - goto blind_set; - opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f); - i++; - } - } - -end: - /* If fewer than 8 outputs, the list must be null terminated */ - if (i < 8) - opregion->acpi->didl[i] = 0; - return; - -blind_set: - i = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - int output_type = ACPI_OTHER_OUTPUT; - if (i >= 8) { - dev_printk(KERN_ERR, &dev->pdev->dev, - "More than 8 outputs detected\n"); - return; - } - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_VGA: - case DRM_MODE_CONNECTOR_DVIA: - output_type = ACPI_VGA_OUTPUT; - break; - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_9PinDIN: - output_type = ACPI_TV_OUTPUT; - break; - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_DisplayPort: - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_HDMIB: - output_type = ACPI_DIGITAL_OUTPUT; - break; - case DRM_MODE_CONNECTOR_LVDS: - output_type = ACPI_LVDS_OUTPUT; - break; - } - opregion->acpi->didl[i] |= (1<<31) | output_type | i; - i++; - } - goto end; -} - -void intel_opregion_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - - if (!opregion->header) - return; - - if (opregion->acpi) { - if (drm_core_check_feature(dev, DRIVER_MODESET)) - intel_didl_outputs(dev); - - /* Notify BIOS we are ready to handle ACPI video ext notifs. - * Right now, all the events are handled by the ACPI video module. - * We don't actually need to do anything with them. */ - opregion->acpi->csts = 0; - opregion->acpi->drdy = 1; - - system_opregion = opregion; - register_acpi_notifier(&intel_opregion_notifier); - } - - if (opregion->asle) - intel_opregion_enable_asle(dev); -} - -void intel_opregion_fini(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - - if (!opregion->header) - return; - - if (opregion->acpi) { - opregion->acpi->drdy = 0; - - system_opregion = NULL; - unregister_acpi_notifier(&intel_opregion_notifier); - } - - /* just clear all opregion memory pointers now */ - iounmap(opregion->header); - opregion->header = NULL; - opregion->acpi = NULL; - opregion->swsci = NULL; - opregion->asle = NULL; - opregion->vbt = NULL; -} -#endif - -int intel_opregion_setup(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_opregion *opregion = &dev_priv->opregion; - void *base; - u32 asls, mboxes; - int err = 0; - - pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); - DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls); - if (asls == 0) { - DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n"); - return -ENOTSUPP; - } - - base = acpi_os_ioremap(asls, OPREGION_SIZE); - if (!base) - return -ENOMEM; - - if (memcmp(base, OPREGION_SIGNATURE, 16)) { - DRM_DEBUG_DRIVER("opregion signature mismatch\n"); - err = -EINVAL; - goto err_out; - } - opregion->header = base; - opregion->vbt = base + OPREGION_VBT_OFFSET; - - opregion->lid_state = base + ACPI_CLID; - - mboxes = opregion->header->mboxes; - if (mboxes & MBOX_ACPI) { - DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); - opregion->acpi = base + OPREGION_ACPI_OFFSET; - } - - if (mboxes & MBOX_SWSCI) { - DRM_DEBUG_DRIVER("SWSCI supported\n"); - opregion->swsci = base + OPREGION_SWSCI_OFFSET; - } - if (mboxes & MBOX_ASLE) { - DRM_DEBUG_DRIVER("ASLE supported\n"); - opregion->asle = base + OPREGION_ASLE_OFFSET; - } - - return 0; - -err_out: - iounmap(base); - return err; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_overlay.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_overlay.c deleted file mode 100644 index 80b331c3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_overlay.c +++ /dev/null @@ -1,1613 +0,0 @@ -/* - * Copyright © 2009 - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Daniel Vetter - * - * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c - */ -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "i915_reg.h" -#include "intel_drv.h" - -/* Limits for overlay size. According to intel doc, the real limits are: - * Y width: 4095, UV width (planar): 2047, Y height: 2047, - * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use - * the mininum of both. */ -#define IMAGE_MAX_WIDTH 2048 -#define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */ -/* on 830 and 845 these large limits result in the card hanging */ -#define IMAGE_MAX_WIDTH_LEGACY 1024 -#define IMAGE_MAX_HEIGHT_LEGACY 1088 - -/* overlay register definitions */ -/* OCMD register */ -#define OCMD_TILED_SURFACE (0x1<<19) -#define OCMD_MIRROR_MASK (0x3<<17) -#define OCMD_MIRROR_MODE (0x3<<17) -#define OCMD_MIRROR_HORIZONTAL (0x1<<17) -#define OCMD_MIRROR_VERTICAL (0x2<<17) -#define OCMD_MIRROR_BOTH (0x3<<17) -#define OCMD_BYTEORDER_MASK (0x3<<14) /* zero for YUYV or FOURCC YUY2 */ -#define OCMD_UV_SWAP (0x1<<14) /* YVYU */ -#define OCMD_Y_SWAP (0x2<<14) /* UYVY or FOURCC UYVY */ -#define OCMD_Y_AND_UV_SWAP (0x3<<14) /* VYUY */ -#define OCMD_SOURCE_FORMAT_MASK (0xf<<10) -#define OCMD_RGB_888 (0x1<<10) /* not in i965 Intel docs */ -#define OCMD_RGB_555 (0x2<<10) /* not in i965 Intel docs */ -#define OCMD_RGB_565 (0x3<<10) /* not in i965 Intel docs */ -#define OCMD_YUV_422_PACKED (0x8<<10) -#define OCMD_YUV_411_PACKED (0x9<<10) /* not in i965 Intel docs */ -#define OCMD_YUV_420_PLANAR (0xc<<10) -#define OCMD_YUV_422_PLANAR (0xd<<10) -#define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */ -#define OCMD_TVSYNCFLIP_PARITY (0x1<<9) -#define OCMD_TVSYNCFLIP_ENABLE (0x1<<7) -#define OCMD_BUF_TYPE_MASK (0x1<<5) -#define OCMD_BUF_TYPE_FRAME (0x0<<5) -#define OCMD_BUF_TYPE_FIELD (0x1<<5) -#define OCMD_TEST_MODE (0x1<<4) -#define OCMD_BUFFER_SELECT (0x3<<2) -#define OCMD_BUFFER0 (0x0<<2) -#define OCMD_BUFFER1 (0x1<<2) -#define OCMD_FIELD_SELECT (0x1<<2) -#define OCMD_FIELD0 (0x0<<1) -#define OCMD_FIELD1 (0x1<<1) -#define OCMD_ENABLE (0x1<<0) - -/* OCONFIG register */ -#define OCONF_PIPE_MASK (0x1<<18) -#define OCONF_PIPE_A (0x0<<18) -#define OCONF_PIPE_B (0x1<<18) -#define OCONF_GAMMA2_ENABLE (0x1<<16) -#define OCONF_CSC_MODE_BT601 (0x0<<5) -#define OCONF_CSC_MODE_BT709 (0x1<<5) -#define OCONF_CSC_BYPASS (0x1<<4) -#define OCONF_CC_OUT_8BIT (0x1<<3) -#define OCONF_TEST_MODE (0x1<<2) -#define OCONF_THREE_LINE_BUFFER (0x1<<0) -#define OCONF_TWO_LINE_BUFFER (0x0<<0) - -/* DCLRKM (dst-key) register */ -#define DST_KEY_ENABLE (0x1<<31) -#define CLK_RGB24_MASK 0x0 -#define CLK_RGB16_MASK 0x070307 -#define CLK_RGB15_MASK 0x070707 -#define CLK_RGB8I_MASK 0xffffff - -#define RGB16_TO_COLORKEY(c) \ - (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) -#define RGB15_TO_COLORKEY(c) \ - (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3)) - -/* overlay flip addr flag */ -#define OFC_UPDATE 0x1 - -/* polyphase filter coefficients */ -#define N_HORIZ_Y_TAPS 5 -#define N_VERT_Y_TAPS 3 -#define N_HORIZ_UV_TAPS 3 -#define N_VERT_UV_TAPS 3 -#define N_PHASES 17 -#define MAX_TAPS 5 - -/* memory bufferd overlay registers */ -struct overlay_registers { - u32 OBUF_0Y; - u32 OBUF_1Y; - u32 OBUF_0U; - u32 OBUF_0V; - u32 OBUF_1U; - u32 OBUF_1V; - u32 OSTRIDE; - u32 YRGB_VPH; - u32 UV_VPH; - u32 HORZ_PH; - u32 INIT_PHS; - u32 DWINPOS; - u32 DWINSZ; - u32 SWIDTH; - u32 SWIDTHSW; - u32 SHEIGHT; - u32 YRGBSCALE; - u32 UVSCALE; - u32 OCLRC0; - u32 OCLRC1; - u32 DCLRKV; - u32 DCLRKM; - u32 SCLRKVH; - u32 SCLRKVL; - u32 SCLRKEN; - u32 OCONFIG; - u32 OCMD; - u32 RESERVED1; /* 0x6C */ - u32 OSTART_0Y; - u32 OSTART_1Y; - u32 OSTART_0U; - u32 OSTART_0V; - u32 OSTART_1U; - u32 OSTART_1V; - u32 OTILEOFF_0Y; - u32 OTILEOFF_1Y; - u32 OTILEOFF_0U; - u32 OTILEOFF_0V; - u32 OTILEOFF_1U; - u32 OTILEOFF_1V; - u32 FASTHSCALE; /* 0xA0 */ - u32 UVSCALEV; /* 0xA4 */ - u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */ - u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */ - u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES]; - u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */ - u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES]; - u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */ - u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES]; - u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */ - u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; -}; - -struct intel_overlay { - struct drm_device *dev; - struct intel_crtc *crtc; - struct drm_i915_gem_object *vid_bo; - struct drm_i915_gem_object *old_vid_bo; - int active; - int pfit_active; - u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ - u32 color_key; - u32 brightness, contrast, saturation; - u32 old_xscale, old_yscale; - /* register access */ - u32 flip_addr; - struct drm_i915_gem_object *reg_bo; - /* flip handling */ - uint32_t last_flip_req; - void (*flip_tail)(struct intel_overlay *); -}; - -static struct overlay_registers * -intel_overlay_map_regs(struct intel_overlay *overlay) -{ - drm_i915_private_t *dev_priv = overlay->dev->dev_private; - struct overlay_registers *regs; - - if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) - regs = overlay->reg_bo->phys_obj->handle->vaddr; - else - regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping, - overlay->reg_bo->gtt_offset); - - return regs; -} - -static void intel_overlay_unmap_regs(struct intel_overlay *overlay, - struct overlay_registers *regs) -{ - if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) - io_mapping_unmap(regs); -} - -static int intel_overlay_do_wait_request(struct intel_overlay *overlay, - struct drm_i915_gem_request *request, - void (*tail)(struct intel_overlay *)) -{ - struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - BUG_ON(overlay->last_flip_req); - ret = i915_add_request(LP_RING(dev_priv), NULL, request); - if (ret) { - kfree(request); - return ret; - } - overlay->last_flip_req = request->seqno; - overlay->flip_tail = tail; - ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, - true); - if (ret) - return ret; - - overlay->last_flip_req = 0; - return 0; -} - -/* Workaround for i830 bug where pipe a must be enable to change control regs */ -static int -i830_activate_pipe_a(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_crtc *crtc; - struct drm_crtc_helper_funcs *crtc_funcs; - struct drm_display_mode vesa_640x480 = { - DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, - 752, 800, 0, 480, 489, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) - }, *mode; - - crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]); - if (crtc->dpms_mode == DRM_MODE_DPMS_ON) - return 0; - - /* most i8xx have pipe a forced on, so don't trust dpms mode */ - if (I915_READ(_PIPEACONF) & PIPECONF_ENABLE) - return 0; - - crtc_funcs = crtc->base.helper_private; - if (crtc_funcs->dpms == NULL) - return 0; - - DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n"); - - mode = drm_mode_duplicate(dev, &vesa_640x480); - drm_mode_set_crtcinfo(mode, 0); - if (!drm_crtc_helper_set_mode(&crtc->base, mode, - crtc->base.x, crtc->base.y, - crtc->base.fb)) - return 0; - - crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON); - return 1; -} - -static void -i830_deactivate_pipe_a(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0]; - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); -} - -/* overlay needs to be disable in OCMD reg */ -static int intel_overlay_on(struct intel_overlay *overlay) -{ - struct drm_device *dev = overlay->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_request *request; - int pipe_a_quirk = 0; - int ret; - - BUG_ON(overlay->active); - overlay->active = 1; - - if (IS_I830(dev)) { - pipe_a_quirk = i830_activate_pipe_a(dev); - if (pipe_a_quirk < 0) - return pipe_a_quirk; - } - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) { - ret = -ENOMEM; - goto out; - } - - ret = BEGIN_LP_RING(4); - if (ret) { - kfree(request); - goto out; - } - - OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); - OUT_RING(overlay->flip_addr | OFC_UPDATE); - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - - ret = intel_overlay_do_wait_request(overlay, request, NULL); -out: - if (pipe_a_quirk) - i830_deactivate_pipe_a(dev); - - return ret; -} - -/* overlay needs to be enabled in OCMD reg */ -static int intel_overlay_continue(struct intel_overlay *overlay, - bool load_polyphase_filter) -{ - struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_request *request; - u32 flip_addr = overlay->flip_addr; - u32 tmp; - int ret; - - BUG_ON(!overlay->active); - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - if (load_polyphase_filter) - flip_addr |= OFC_UPDATE; - - /* check for underruns */ - tmp = I915_READ(DOVSTA); - if (tmp & (1 << 17)) - DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); - - ret = BEGIN_LP_RING(2); - if (ret) { - kfree(request); - return ret; - } - OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); - OUT_RING(flip_addr); - ADVANCE_LP_RING(); - - ret = i915_add_request(LP_RING(dev_priv), NULL, request); - if (ret) { - kfree(request); - return ret; - } - - overlay->last_flip_req = request->seqno; - return 0; -} - -static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) -{ - struct drm_i915_gem_object *obj = overlay->old_vid_bo; - - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - - overlay->old_vid_bo = NULL; -} - -static void intel_overlay_off_tail(struct intel_overlay *overlay) -{ - struct drm_i915_gem_object *obj = overlay->vid_bo; - - /* never have the overlay hw on without showing a frame */ - BUG_ON(!overlay->vid_bo); - - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - overlay->vid_bo = NULL; - - overlay->crtc->overlay = NULL; - overlay->crtc = NULL; - overlay->active = 0; -} - -/* overlay needs to be disabled in OCMD reg */ -static int intel_overlay_off(struct intel_overlay *overlay) -{ - struct drm_device *dev = overlay->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 flip_addr = overlay->flip_addr; - struct drm_i915_gem_request *request; - int ret; - - BUG_ON(!overlay->active); - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - /* According to intel docs the overlay hw may hang (when switching - * off) without loading the filter coeffs. It is however unclear whether - * this applies to the disabling of the overlay or to the switching off - * of the hw. Do it in both cases */ - flip_addr |= OFC_UPDATE; - - ret = BEGIN_LP_RING(6); - if (ret) { - kfree(request); - return ret; - } - /* wait for overlay to go idle */ - OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); - OUT_RING(flip_addr); - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - /* turn overlay off */ - OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF); - OUT_RING(flip_addr); - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - ADVANCE_LP_RING(); - - return intel_overlay_do_wait_request(overlay, request, - intel_overlay_off_tail); -} - -/* recover from an interruption due to a signal - * We have to be careful not to repeat work forever an make forward progess. */ -static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) -{ - struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - if (overlay->last_flip_req == 0) - return 0; - - ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, - true); - if (ret) - return ret; - - if (overlay->flip_tail) - overlay->flip_tail(overlay); - - overlay->last_flip_req = 0; - return 0; -} - -/* Wait for pending overlay flip and release old frame. - * Needs to be called before the overlay register are changed - * via intel_overlay_(un)map_regs - */ -static int intel_overlay_release_old_vid(struct intel_overlay *overlay) -{ - struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - /* Only wait if there is actually an old frame to release to - * guarantee forward progress. - */ - if (!overlay->old_vid_bo) - return 0; - - if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { - struct drm_i915_gem_request *request; - - /* synchronous slowpath */ - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; - - ret = BEGIN_LP_RING(2); - if (ret) { - kfree(request); - return ret; - } - - OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - - ret = intel_overlay_do_wait_request(overlay, request, - intel_overlay_release_old_vid_tail); - if (ret) - return ret; - } - - intel_overlay_release_old_vid_tail(overlay); - return 0; -} - -struct put_image_params { - int format; - short dst_x; - short dst_y; - short dst_w; - short dst_h; - short src_w; - short src_scan_h; - short src_scan_w; - short src_h; - short stride_Y; - short stride_UV; - int offset_Y; - int offset_U; - int offset_V; -}; - -static int packed_depth_bytes(u32 format) -{ - switch (format & I915_OVERLAY_DEPTH_MASK) { - case I915_OVERLAY_YUV422: - return 4; - case I915_OVERLAY_YUV411: - /* return 6; not implemented */ - default: - return -EINVAL; - } -} - -static int packed_width_bytes(u32 format, short width) -{ - switch (format & I915_OVERLAY_DEPTH_MASK) { - case I915_OVERLAY_YUV422: - return width << 1; - default: - return -EINVAL; - } -} - -static int uv_hsubsampling(u32 format) -{ - switch (format & I915_OVERLAY_DEPTH_MASK) { - case I915_OVERLAY_YUV422: - case I915_OVERLAY_YUV420: - return 2; - case I915_OVERLAY_YUV411: - case I915_OVERLAY_YUV410: - return 4; - default: - return -EINVAL; - } -} - -static int uv_vsubsampling(u32 format) -{ - switch (format & I915_OVERLAY_DEPTH_MASK) { - case I915_OVERLAY_YUV420: - case I915_OVERLAY_YUV410: - return 2; - case I915_OVERLAY_YUV422: - case I915_OVERLAY_YUV411: - return 1; - default: - return -EINVAL; - } -} - -static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width) -{ - u32 mask, shift, ret; - if (IS_GEN2(dev)) { - mask = 0x1f; - shift = 5; - } else { - mask = 0x3f; - shift = 6; - } - ret = ((offset + width + mask) >> shift) - (offset >> shift); - if (!IS_GEN2(dev)) - ret <<= 1; - ret -= 1; - return ret << 2; -} - -static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = { - 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0, - 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440, - 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0, - 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380, - 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320, - 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0, - 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260, - 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200, - 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0, - 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160, - 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120, - 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0, - 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0, - 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, - 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, - 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, - 0xb000, 0x3000, 0x0800, 0x3000, 0xb000 -}; - -static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { - 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, - 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, - 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880, - 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00, - 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0, - 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, - 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, - 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, - 0x3000, 0x0800, 0x3000 -}; - -static void update_polyphase_filter(struct overlay_registers *regs) -{ - memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs)); - memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs)); -} - -static bool update_scaling_factors(struct intel_overlay *overlay, - struct overlay_registers *regs, - struct put_image_params *params) -{ - /* fixed point with a 12 bit shift */ - u32 xscale, yscale, xscale_UV, yscale_UV; -#define FP_SHIFT 12 -#define FRACT_MASK 0xfff - bool scale_changed = false; - int uv_hscale = uv_hsubsampling(params->format); - int uv_vscale = uv_vsubsampling(params->format); - - if (params->dst_w > 1) - xscale = ((params->src_scan_w - 1) << FP_SHIFT) - /(params->dst_w); - else - xscale = 1 << FP_SHIFT; - - if (params->dst_h > 1) - yscale = ((params->src_scan_h - 1) << FP_SHIFT) - /(params->dst_h); - else - yscale = 1 << FP_SHIFT; - - /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ - xscale_UV = xscale/uv_hscale; - yscale_UV = yscale/uv_vscale; - /* make the Y scale to UV scale ratio an exact multiply */ - xscale = xscale_UV * uv_hscale; - yscale = yscale_UV * uv_vscale; - /*} else { - xscale_UV = 0; - yscale_UV = 0; - }*/ - - if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) - scale_changed = true; - overlay->old_xscale = xscale; - overlay->old_yscale = yscale; - - regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) | - ((xscale >> FP_SHIFT) << 16) | - ((xscale & FRACT_MASK) << 3)); - - regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) | - ((xscale_UV >> FP_SHIFT) << 16) | - ((xscale_UV & FRACT_MASK) << 3)); - - regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) | - ((yscale_UV >> FP_SHIFT) << 0))); - - if (scale_changed) - update_polyphase_filter(regs); - - return scale_changed; -} - -static void update_colorkey(struct intel_overlay *overlay, - struct overlay_registers *regs) -{ - u32 key = overlay->color_key; - - switch (overlay->crtc->base.fb->bits_per_pixel) { - case 8: - regs->DCLRKV = 0; - regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; - break; - - case 16: - if (overlay->crtc->base.fb->depth == 15) { - regs->DCLRKV = RGB15_TO_COLORKEY(key); - regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; - } else { - regs->DCLRKV = RGB16_TO_COLORKEY(key); - regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; - } - break; - - case 24: - case 32: - regs->DCLRKV = key; - regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; - break; - } -} - -static u32 overlay_cmd_reg(struct put_image_params *params) -{ - u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0; - - if (params->format & I915_OVERLAY_YUV_PLANAR) { - switch (params->format & I915_OVERLAY_DEPTH_MASK) { - case I915_OVERLAY_YUV422: - cmd |= OCMD_YUV_422_PLANAR; - break; - case I915_OVERLAY_YUV420: - cmd |= OCMD_YUV_420_PLANAR; - break; - case I915_OVERLAY_YUV411: - case I915_OVERLAY_YUV410: - cmd |= OCMD_YUV_410_PLANAR; - break; - } - } else { /* YUV packed */ - switch (params->format & I915_OVERLAY_DEPTH_MASK) { - case I915_OVERLAY_YUV422: - cmd |= OCMD_YUV_422_PACKED; - break; - case I915_OVERLAY_YUV411: - cmd |= OCMD_YUV_411_PACKED; - break; - } - - switch (params->format & I915_OVERLAY_SWAP_MASK) { - case I915_OVERLAY_NO_SWAP: - break; - case I915_OVERLAY_UV_SWAP: - cmd |= OCMD_UV_SWAP; - break; - case I915_OVERLAY_Y_SWAP: - cmd |= OCMD_Y_SWAP; - break; - case I915_OVERLAY_Y_AND_UV_SWAP: - cmd |= OCMD_Y_AND_UV_SWAP; - break; - } - } - - return cmd; -} - -static int intel_overlay_do_put_image(struct intel_overlay *overlay, - struct drm_i915_gem_object *new_bo, - struct put_image_params *params) -{ - int ret, tmp_width; - struct overlay_registers *regs; - bool scale_changed = false; - struct drm_device *dev = overlay->dev; - - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); - BUG_ON(!overlay); - - ret = intel_overlay_release_old_vid(overlay); - if (ret != 0) - return ret; - - ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL); - if (ret != 0) - return ret; - - ret = i915_gem_object_put_fence(new_bo); - if (ret) - goto out_unpin; - - if (!overlay->active) { - regs = intel_overlay_map_regs(overlay); - if (!regs) { - ret = -ENOMEM; - goto out_unpin; - } - regs->OCONFIG = OCONF_CC_OUT_8BIT; - if (IS_GEN4(overlay->dev)) - regs->OCONFIG |= OCONF_CSC_MODE_BT709; - regs->OCONFIG |= overlay->crtc->pipe == 0 ? - OCONF_PIPE_A : OCONF_PIPE_B; - intel_overlay_unmap_regs(overlay, regs); - - ret = intel_overlay_on(overlay); - if (ret != 0) - goto out_unpin; - } - - regs = intel_overlay_map_regs(overlay); - if (!regs) { - ret = -ENOMEM; - goto out_unpin; - } - - regs->DWINPOS = (params->dst_y << 16) | params->dst_x; - regs->DWINSZ = (params->dst_h << 16) | params->dst_w; - - if (params->format & I915_OVERLAY_YUV_PACKED) - tmp_width = packed_width_bytes(params->format, params->src_w); - else - tmp_width = params->src_w; - - regs->SWIDTH = params->src_w; - regs->SWIDTHSW = calc_swidthsw(overlay->dev, - params->offset_Y, tmp_width); - regs->SHEIGHT = params->src_h; - regs->OBUF_0Y = new_bo->gtt_offset + params->offset_Y; - regs->OSTRIDE = params->stride_Y; - - if (params->format & I915_OVERLAY_YUV_PLANAR) { - int uv_hscale = uv_hsubsampling(params->format); - int uv_vscale = uv_vsubsampling(params->format); - u32 tmp_U, tmp_V; - regs->SWIDTH |= (params->src_w/uv_hscale) << 16; - tmp_U = calc_swidthsw(overlay->dev, params->offset_U, - params->src_w/uv_hscale); - tmp_V = calc_swidthsw(overlay->dev, params->offset_V, - params->src_w/uv_hscale); - regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; - regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; - regs->OBUF_0U = new_bo->gtt_offset + params->offset_U; - regs->OBUF_0V = new_bo->gtt_offset + params->offset_V; - regs->OSTRIDE |= params->stride_UV << 16; - } - - scale_changed = update_scaling_factors(overlay, regs, params); - - update_colorkey(overlay, regs); - - regs->OCMD = overlay_cmd_reg(params); - - intel_overlay_unmap_regs(overlay, regs); - - ret = intel_overlay_continue(overlay, scale_changed); - if (ret) - goto out_unpin; - - overlay->old_vid_bo = overlay->vid_bo; - overlay->vid_bo = new_bo; - - return 0; - -out_unpin: - i915_gem_object_unpin(new_bo); - return ret; -} - -int intel_overlay_switch_off(struct intel_overlay *overlay) -{ - struct overlay_registers *regs; - struct drm_device *dev = overlay->dev; - int ret; - - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); - - ret = intel_overlay_recover_from_interrupt(overlay); - if (ret != 0) - return ret; - - if (!overlay->active) - return 0; - - ret = intel_overlay_release_old_vid(overlay); - if (ret != 0) - return ret; - - regs = intel_overlay_map_regs(overlay); - regs->OCMD = 0; - intel_overlay_unmap_regs(overlay, regs); - - ret = intel_overlay_off(overlay); - if (ret != 0) - return ret; - - intel_overlay_off_tail(overlay); - return 0; -} - -static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, - struct intel_crtc *crtc) -{ - drm_i915_private_t *dev_priv = overlay->dev->dev_private; - - if (!crtc->active) - return -EINVAL; - - /* can't use the overlay with double wide pipe */ - if (INTEL_INFO(overlay->dev)->gen < 4 && - (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE) - return -EINVAL; - - return 0; -} - -static void update_pfit_vscale_ratio(struct intel_overlay *overlay) -{ - struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - u32 pfit_control = I915_READ(PFIT_CONTROL); - u32 ratio; - - /* XXX: This is not the same logic as in the xorg driver, but more in - * line with the intel documentation for the i965 - */ - if (INTEL_INFO(dev)->gen >= 4) { - /* on i965 use the PGM reg to read out the autoscaler values */ - ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965; - } else { - if (pfit_control & VERT_AUTO_SCALE) - ratio = I915_READ(PFIT_AUTO_RATIOS); - else - ratio = I915_READ(PFIT_PGM_RATIOS); - ratio >>= PFIT_VERT_SCALE_SHIFT; - } - - overlay->pfit_vscale_ratio = ratio; -} - -static int check_overlay_dst(struct intel_overlay *overlay, - struct drm_intel_overlay_put_image *rec) -{ - struct drm_display_mode *mode = &overlay->crtc->base.mode; - - if (rec->dst_x < mode->hdisplay && - rec->dst_x + rec->dst_width <= mode->hdisplay && - rec->dst_y < mode->vdisplay && - rec->dst_y + rec->dst_height <= mode->vdisplay) - return 0; - else - return -EINVAL; -} - -static int check_overlay_scaling(struct put_image_params *rec) -{ - u32 tmp; - - /* downscaling limit is 8.0 */ - tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16; - if (tmp > 7) - return -EINVAL; - tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16; - if (tmp > 7) - return -EINVAL; - - return 0; -} - -static int check_overlay_src(struct drm_device *dev, - struct drm_intel_overlay_put_image *rec, - struct drm_i915_gem_object *new_bo) -{ - int uv_hscale = uv_hsubsampling(rec->flags); - int uv_vscale = uv_vsubsampling(rec->flags); - u32 stride_mask; - int depth; - u32 tmp; - - /* check src dimensions */ - if (IS_845G(dev) || IS_I830(dev)) { - if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY || - rec->src_width > IMAGE_MAX_WIDTH_LEGACY) - return -EINVAL; - } else { - if (rec->src_height > IMAGE_MAX_HEIGHT || - rec->src_width > IMAGE_MAX_WIDTH) - return -EINVAL; - } - - /* better safe than sorry, use 4 as the maximal subsampling ratio */ - if (rec->src_height < N_VERT_Y_TAPS*4 || - rec->src_width < N_HORIZ_Y_TAPS*4) - return -EINVAL; - - /* check alignment constraints */ - switch (rec->flags & I915_OVERLAY_TYPE_MASK) { - case I915_OVERLAY_RGB: - /* not implemented */ - return -EINVAL; - - case I915_OVERLAY_YUV_PACKED: - if (uv_vscale != 1) - return -EINVAL; - - depth = packed_depth_bytes(rec->flags); - if (depth < 0) - return depth; - - /* ignore UV planes */ - rec->stride_UV = 0; - rec->offset_U = 0; - rec->offset_V = 0; - /* check pixel alignment */ - if (rec->offset_Y % depth) - return -EINVAL; - break; - - case I915_OVERLAY_YUV_PLANAR: - if (uv_vscale < 0 || uv_hscale < 0) - return -EINVAL; - /* no offset restrictions for planar formats */ - break; - - default: - return -EINVAL; - } - - if (rec->src_width % uv_hscale) - return -EINVAL; - - /* stride checking */ - if (IS_I830(dev) || IS_845G(dev)) - stride_mask = 255; - else - stride_mask = 63; - - if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) - return -EINVAL; - if (IS_GEN4(dev) && rec->stride_Y < 512) - return -EINVAL; - - tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? - 4096 : 8192; - if (rec->stride_Y > tmp || rec->stride_UV > 2*1024) - return -EINVAL; - - /* check buffer dimensions */ - switch (rec->flags & I915_OVERLAY_TYPE_MASK) { - case I915_OVERLAY_RGB: - case I915_OVERLAY_YUV_PACKED: - /* always 4 Y values per depth pixels */ - if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y) - return -EINVAL; - - tmp = rec->stride_Y*rec->src_height; - if (rec->offset_Y + tmp > new_bo->base.size) - return -EINVAL; - break; - - case I915_OVERLAY_YUV_PLANAR: - if (rec->src_width > rec->stride_Y) - return -EINVAL; - if (rec->src_width/uv_hscale > rec->stride_UV) - return -EINVAL; - - tmp = rec->stride_Y * rec->src_height; - if (rec->offset_Y + tmp > new_bo->base.size) - return -EINVAL; - - tmp = rec->stride_UV * (rec->src_height / uv_vscale); - if (rec->offset_U + tmp > new_bo->base.size || - rec->offset_V + tmp > new_bo->base.size) - return -EINVAL; - break; - } - - return 0; -} - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int intel_panel_fitter_pipe(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 pfit_control; - - /* i830 doesn't have a panel fitter */ - if (IS_I830(dev)) - return -1; - - pfit_control = I915_READ(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - - /* 965 can place panel fitter on either pipe */ - if (IS_GEN4(dev)) - return (pfit_control >> 29) & 0x3; - - /* older chips can only use pipe 1 */ - return 1; -} - -int intel_overlay_put_image(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_intel_overlay_put_image *put_image_rec = data; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_overlay *overlay; - struct drm_mode_object *drmmode_obj; - struct intel_crtc *crtc; - struct drm_i915_gem_object *new_bo; - struct put_image_params *params; - int ret; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - overlay = dev_priv->overlay; - if (!overlay) { - DRM_DEBUG("userspace bug: no overlay\n"); - return -ENODEV; - } - - if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) { - mutex_lock(&dev->mode_config.mutex); - mutex_lock(&dev->struct_mutex); - - ret = intel_overlay_switch_off(overlay); - - mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->mode_config.mutex); - - return ret; - } - - params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL); - if (!params) - return -ENOMEM; - - drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, - DRM_MODE_OBJECT_CRTC); - if (!drmmode_obj) { - ret = -ENOENT; - goto out_free; - } - crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); - - new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv, - put_image_rec->bo_handle)); - if (&new_bo->base == NULL) { - ret = -ENOENT; - goto out_free; - } - - mutex_lock(&dev->mode_config.mutex); - mutex_lock(&dev->struct_mutex); - - if (new_bo->tiling_mode) { - DRM_ERROR("buffer used for overlay image can not be tiled\n"); - ret = -EINVAL; - goto out_unlock; - } - - ret = intel_overlay_recover_from_interrupt(overlay); - if (ret != 0) - goto out_unlock; - - if (overlay->crtc != crtc) { - struct drm_display_mode *mode = &crtc->base.mode; - ret = intel_overlay_switch_off(overlay); - if (ret != 0) - goto out_unlock; - - ret = check_overlay_possible_on_crtc(overlay, crtc); - if (ret != 0) - goto out_unlock; - - overlay->crtc = crtc; - crtc->overlay = overlay; - - /* line too wide, i.e. one-line-mode */ - if (mode->hdisplay > 1024 && - intel_panel_fitter_pipe(dev) == crtc->pipe) { - overlay->pfit_active = 1; - update_pfit_vscale_ratio(overlay); - } else - overlay->pfit_active = 0; - } - - ret = check_overlay_dst(overlay, put_image_rec); - if (ret != 0) - goto out_unlock; - - if (overlay->pfit_active) { - params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / - overlay->pfit_vscale_ratio); - /* shifting right rounds downwards, so add 1 */ - params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / - overlay->pfit_vscale_ratio) + 1; - } else { - params->dst_y = put_image_rec->dst_y; - params->dst_h = put_image_rec->dst_height; - } - params->dst_x = put_image_rec->dst_x; - params->dst_w = put_image_rec->dst_width; - - params->src_w = put_image_rec->src_width; - params->src_h = put_image_rec->src_height; - params->src_scan_w = put_image_rec->src_scan_width; - params->src_scan_h = put_image_rec->src_scan_height; - if (params->src_scan_h > params->src_h || - params->src_scan_w > params->src_w) { - ret = -EINVAL; - goto out_unlock; - } - - ret = check_overlay_src(dev, put_image_rec, new_bo); - if (ret != 0) - goto out_unlock; - params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK; - params->stride_Y = put_image_rec->stride_Y; - params->stride_UV = put_image_rec->stride_UV; - params->offset_Y = put_image_rec->offset_Y; - params->offset_U = put_image_rec->offset_U; - params->offset_V = put_image_rec->offset_V; - - /* Check scaling after src size to prevent a divide-by-zero. */ - ret = check_overlay_scaling(params); - if (ret != 0) - goto out_unlock; - - ret = intel_overlay_do_put_image(overlay, new_bo, params); - if (ret != 0) - goto out_unlock; - - mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->mode_config.mutex); - - kfree(params); - - return 0; - -out_unlock: - mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->mode_config.mutex); - drm_gem_object_unreference_unlocked(&new_bo->base); -out_free: - kfree(params); - - return ret; -} - -static void update_reg_attrs(struct intel_overlay *overlay, - struct overlay_registers *regs) -{ - regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff); - regs->OCLRC1 = overlay->saturation; -} - -static bool check_gamma_bounds(u32 gamma1, u32 gamma2) -{ - int i; - - if (gamma1 & 0xff000000 || gamma2 & 0xff000000) - return false; - - for (i = 0; i < 3; i++) { - if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) - return false; - } - - return true; -} - -static bool check_gamma5_errata(u32 gamma5) -{ - int i; - - for (i = 0; i < 3; i++) { - if (((gamma5 >> i*8) & 0xff) == 0x80) - return false; - } - - return true; -} - -static int check_gamma(struct drm_intel_overlay_attrs *attrs) -{ - if (!check_gamma_bounds(0, attrs->gamma0) || - !check_gamma_bounds(attrs->gamma0, attrs->gamma1) || - !check_gamma_bounds(attrs->gamma1, attrs->gamma2) || - !check_gamma_bounds(attrs->gamma2, attrs->gamma3) || - !check_gamma_bounds(attrs->gamma3, attrs->gamma4) || - !check_gamma_bounds(attrs->gamma4, attrs->gamma5) || - !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) - return -EINVAL; - - if (!check_gamma5_errata(attrs->gamma5)) - return -EINVAL; - - return 0; -} - -int intel_overlay_attrs(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_intel_overlay_attrs *attrs = data; - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_overlay *overlay; - struct overlay_registers *regs; - int ret; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - overlay = dev_priv->overlay; - if (!overlay) { - DRM_DEBUG("userspace bug: no overlay\n"); - return -ENODEV; - } - - mutex_lock(&dev->mode_config.mutex); - mutex_lock(&dev->struct_mutex); - - ret = -EINVAL; - if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { - attrs->color_key = overlay->color_key; - attrs->brightness = overlay->brightness; - attrs->contrast = overlay->contrast; - attrs->saturation = overlay->saturation; - - if (!IS_GEN2(dev)) { - attrs->gamma0 = I915_READ(OGAMC0); - attrs->gamma1 = I915_READ(OGAMC1); - attrs->gamma2 = I915_READ(OGAMC2); - attrs->gamma3 = I915_READ(OGAMC3); - attrs->gamma4 = I915_READ(OGAMC4); - attrs->gamma5 = I915_READ(OGAMC5); - } - } else { - if (attrs->brightness < -128 || attrs->brightness > 127) - goto out_unlock; - if (attrs->contrast > 255) - goto out_unlock; - if (attrs->saturation > 1023) - goto out_unlock; - - overlay->color_key = attrs->color_key; - overlay->brightness = attrs->brightness; - overlay->contrast = attrs->contrast; - overlay->saturation = attrs->saturation; - - regs = intel_overlay_map_regs(overlay); - if (!regs) { - ret = -ENOMEM; - goto out_unlock; - } - - update_reg_attrs(overlay, regs); - - intel_overlay_unmap_regs(overlay, regs); - - if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { - if (IS_GEN2(dev)) - goto out_unlock; - - if (overlay->active) { - ret = -EBUSY; - goto out_unlock; - } - - ret = check_gamma(attrs); - if (ret) - goto out_unlock; - - I915_WRITE(OGAMC0, attrs->gamma0); - I915_WRITE(OGAMC1, attrs->gamma1); - I915_WRITE(OGAMC2, attrs->gamma2); - I915_WRITE(OGAMC3, attrs->gamma3); - I915_WRITE(OGAMC4, attrs->gamma4); - I915_WRITE(OGAMC5, attrs->gamma5); - } - } - - ret = 0; -out_unlock: - mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->mode_config.mutex); - - return ret; -} - -void intel_setup_overlay(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_overlay *overlay; - struct drm_i915_gem_object *reg_bo; - struct overlay_registers *regs; - int ret; - - if (!HAS_OVERLAY(dev)) - return; - - overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); - if (!overlay) - return; - - mutex_lock(&dev->struct_mutex); - if (WARN_ON(dev_priv->overlay)) - goto out_free; - - overlay->dev = dev; - - reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); - if (!reg_bo) - goto out_free; - overlay->reg_bo = reg_bo; - - if (OVERLAY_NEEDS_PHYSICAL(dev)) { - ret = i915_gem_attach_phys_object(dev, reg_bo, - I915_GEM_PHYS_OVERLAY_REGS, - PAGE_SIZE); - if (ret) { - DRM_ERROR("failed to attach phys overlay regs\n"); - goto out_free_bo; - } - overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; - } else { - ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); - if (ret) { - DRM_ERROR("failed to pin overlay register bo\n"); - goto out_free_bo; - } - overlay->flip_addr = reg_bo->gtt_offset; - - ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); - if (ret) { - DRM_ERROR("failed to move overlay register bo into the GTT\n"); - goto out_unpin_bo; - } - } - - /* init all values */ - overlay->color_key = 0x0101fe; - overlay->brightness = -19; - overlay->contrast = 75; - overlay->saturation = 146; - - regs = intel_overlay_map_regs(overlay); - if (!regs) - goto out_unpin_bo; - - memset(regs, 0, sizeof(struct overlay_registers)); - update_polyphase_filter(regs); - update_reg_attrs(overlay, regs); - - intel_overlay_unmap_regs(overlay, regs); - - dev_priv->overlay = overlay; - mutex_unlock(&dev->struct_mutex); - DRM_INFO("initialized overlay support\n"); - return; - -out_unpin_bo: - if (!OVERLAY_NEEDS_PHYSICAL(dev)) - i915_gem_object_unpin(reg_bo); -out_free_bo: - drm_gem_object_unreference(®_bo->base); -out_free: - mutex_unlock(&dev->struct_mutex); - kfree(overlay); - return; -} - -void intel_cleanup_overlay(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev_priv->overlay) - return; - - /* The bo's should be free'd by the generic code already. - * Furthermore modesetting teardown happens beforehand so the - * hardware should be off already */ - BUG_ON(dev_priv->overlay->active); - - drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base); - kfree(dev_priv->overlay); -} - -#ifdef CONFIG_DEBUG_FS -#include - -struct intel_overlay_error_state { - struct overlay_registers regs; - unsigned long base; - u32 dovsta; - u32 isr; -}; - -static struct overlay_registers * -intel_overlay_map_regs_atomic(struct intel_overlay *overlay) -{ - drm_i915_private_t *dev_priv = overlay->dev->dev_private; - struct overlay_registers *regs; - - if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) - regs = overlay->reg_bo->phys_obj->handle->vaddr; - else - regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - overlay->reg_bo->gtt_offset); - - return regs; -} - -static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay, - struct overlay_registers *regs) -{ - if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) - io_mapping_unmap_atomic(regs); -} - - -struct intel_overlay_error_state * -intel_overlay_capture_error_state(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_overlay *overlay = dev_priv->overlay; - struct intel_overlay_error_state *error; - struct overlay_registers __iomem *regs; - - if (!overlay || !overlay->active) - return NULL; - - error = kmalloc(sizeof(*error), GFP_ATOMIC); - if (error == NULL) - return NULL; - - error->dovsta = I915_READ(DOVSTA); - error->isr = I915_READ(ISR); - if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) - error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; - else - error->base = (long) overlay->reg_bo->gtt_offset; - - regs = intel_overlay_map_regs_atomic(overlay); - if (!regs) - goto err; - - memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); - intel_overlay_unmap_regs_atomic(overlay, regs); - - return error; - -err: - kfree(error); - return NULL; -} - -void -intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) -{ - seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", - error->dovsta, error->isr); - seq_printf(m, " Register file at 0x%08lx:\n", - error->base); - -#define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) - P(OBUF_0Y); - P(OBUF_1Y); - P(OBUF_0U); - P(OBUF_0V); - P(OBUF_1U); - P(OBUF_1V); - P(OSTRIDE); - P(YRGB_VPH); - P(UV_VPH); - P(HORZ_PH); - P(INIT_PHS); - P(DWINPOS); - P(DWINSZ); - P(SWIDTH); - P(SWIDTHSW); - P(SHEIGHT); - P(YRGBSCALE); - P(UVSCALE); - P(OCLRC0); - P(OCLRC1); - P(DCLRKV); - P(DCLRKM); - P(SCLRKVH); - P(SCLRKVL); - P(SCLRKEN); - P(OCONFIG); - P(OCMD); - P(OSTART_0Y); - P(OSTART_1Y); - P(OSTART_0U); - P(OSTART_0V); - P(OSTART_1U); - P(OSTART_1V); - P(OTILEOFF_0Y); - P(OTILEOFF_1Y); - P(OTILEOFF_0U); - P(OTILEOFF_0V); - P(OTILEOFF_1U); - P(OTILEOFF_1V); - P(FASTHSCALE); - P(UVSCALEV); -#undef P -} -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_panel.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_panel.c deleted file mode 100644 index 48177ec4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_panel.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright © 2006-2010 Intel Corporation - * Copyright (c) 2006 Dave Airlie - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Dave Airlie - * Jesse Barnes - * Chris Wilson - */ - -#include "intel_drv.h" - -#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ - -void -intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, - struct drm_display_mode *adjusted_mode) -{ - adjusted_mode->hdisplay = fixed_mode->hdisplay; - adjusted_mode->hsync_start = fixed_mode->hsync_start; - adjusted_mode->hsync_end = fixed_mode->hsync_end; - adjusted_mode->htotal = fixed_mode->htotal; - - adjusted_mode->vdisplay = fixed_mode->vdisplay; - adjusted_mode->vsync_start = fixed_mode->vsync_start; - adjusted_mode->vsync_end = fixed_mode->vsync_end; - adjusted_mode->vtotal = fixed_mode->vtotal; - - adjusted_mode->clock = fixed_mode->clock; -} - -/* adjusted_mode has been preset to be the panel's fixed mode */ -void -intel_pch_panel_fitting(struct drm_device *dev, - int fitting_mode, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int x, y, width, height; - - x = y = width = height = 0; - - /* Native modes don't need fitting */ - if (adjusted_mode->hdisplay == mode->hdisplay && - adjusted_mode->vdisplay == mode->vdisplay) - goto done; - - switch (fitting_mode) { - case DRM_MODE_SCALE_CENTER: - width = mode->hdisplay; - height = mode->vdisplay; - x = (adjusted_mode->hdisplay - width + 1)/2; - y = (adjusted_mode->vdisplay - height + 1)/2; - break; - - case DRM_MODE_SCALE_ASPECT: - /* Scale but preserve the aspect ratio */ - { - u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; - u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; - if (scaled_width > scaled_height) { /* pillar */ - width = scaled_height / mode->vdisplay; - if (width & 1) - width++; - x = (adjusted_mode->hdisplay - width + 1) / 2; - y = 0; - height = adjusted_mode->vdisplay; - } else if (scaled_width < scaled_height) { /* letter */ - height = scaled_width / mode->hdisplay; - if (height & 1) - height++; - y = (adjusted_mode->vdisplay - height + 1) / 2; - x = 0; - width = adjusted_mode->hdisplay; - } else { - x = y = 0; - width = adjusted_mode->hdisplay; - height = adjusted_mode->vdisplay; - } - } - break; - - default: - case DRM_MODE_SCALE_FULLSCREEN: - x = y = 0; - width = adjusted_mode->hdisplay; - height = adjusted_mode->vdisplay; - break; - } - -done: - dev_priv->pch_pf_pos = (x << 16) | y; - dev_priv->pch_pf_size = (width << 16) | height; -} - -static int is_backlight_combination_mode(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen >= 4) - return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE; - - if (IS_GEN2(dev)) - return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE; - - return 0; -} - -static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) -{ - u32 val; - - /* Restore the CTL value if it lost, e.g. GPU reset */ - - if (HAS_PCH_SPLIT(dev_priv->dev)) { - val = I915_READ(BLC_PWM_PCH_CTL2); - if (dev_priv->saveBLC_PWM_CTL2 == 0) { - dev_priv->saveBLC_PWM_CTL2 = val; - } else if (val == 0) { - I915_WRITE(BLC_PWM_PCH_CTL2, - dev_priv->saveBLC_PWM_CTL2); - val = dev_priv->saveBLC_PWM_CTL2; - } - } else { - val = I915_READ(BLC_PWM_CTL); - if (dev_priv->saveBLC_PWM_CTL == 0) { - dev_priv->saveBLC_PWM_CTL = val; - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); - } else if (val == 0) { - I915_WRITE(BLC_PWM_CTL, - dev_priv->saveBLC_PWM_CTL); - I915_WRITE(BLC_PWM_CTL2, - dev_priv->saveBLC_PWM_CTL2); - val = dev_priv->saveBLC_PWM_CTL; - } - } - - return val; -} - -u32 intel_panel_get_max_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 max; - - max = i915_read_blc_pwm_ctl(dev_priv); - if (max == 0) { - /* XXX add code here to query mode clock or hardware clock - * and program max PWM appropriately. - */ - printk_once(KERN_WARNING "fixme: max PWM is zero.\n"); - return 1; - } - - if (HAS_PCH_SPLIT(dev)) { - max >>= 16; - } else { - if (INTEL_INFO(dev)->gen < 4) - max >>= 17; - else - max >>= 16; - - if (is_backlight_combination_mode(dev)) - max *= 0xff; - } - - DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); - return max; -} - -u32 intel_panel_get_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 val; - - if (HAS_PCH_SPLIT(dev)) { - val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - } else { - val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - if (INTEL_INFO(dev)->gen < 4) - val >>= 1; - - if (is_backlight_combination_mode(dev)) { - u8 lbpc; - - pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); - val *= lbpc; - } - } - - DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); - return val; -} - -static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(BLC_PWM_CPU_CTL, val | level); -} - -static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 tmp; - - DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); - - if (HAS_PCH_SPLIT(dev)) - return intel_pch_panel_set_backlight(dev, level); - - if (is_backlight_combination_mode(dev)) { - u32 max = intel_panel_get_max_backlight(dev); - u8 lbpc; - - lbpc = level * 0xfe / max + 1; - level /= lbpc; - pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); - } - - tmp = I915_READ(BLC_PWM_CTL); - if (INTEL_INFO(dev)->gen < 4) - level <<= 1; - tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; - I915_WRITE(BLC_PWM_CTL, tmp | level); -} - -void intel_panel_set_backlight(struct drm_device *dev, u32 level) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->backlight_level = level; - if (dev_priv->backlight_enabled) - intel_panel_actually_set_backlight(dev, level); -} - -void intel_panel_disable_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->backlight_enabled = false; - intel_panel_actually_set_backlight(dev, 0); -} - -void intel_panel_enable_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (dev_priv->backlight_level == 0) - dev_priv->backlight_level = intel_panel_get_max_backlight(dev); - - dev_priv->backlight_enabled = true; - intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); -} - -static void intel_panel_init_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->backlight_level = intel_panel_get_backlight(dev); - dev_priv->backlight_enabled = dev_priv->backlight_level != 0; -} - -enum drm_connector_status -intel_panel_detect(struct drm_device *dev) -{ -#if 0 - struct drm_i915_private *dev_priv = dev->dev_private; -#endif - - if (i915_panel_ignore_lid) - return i915_panel_ignore_lid > 0 ? - connector_status_connected : - connector_status_disconnected; - - /* opregion lid state on HP 2540p is wrong at boot up, - * appears to be either the BIOS or Linux ACPI fault */ -#if 0 - /* Assume that the BIOS does not lie through the OpRegion... */ - if (dev_priv->opregion.lid_state) - return ioread32(dev_priv->opregion.lid_state) & 0x1 ? - connector_status_connected : - connector_status_disconnected; -#endif - - return connector_status_unknown; -} - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE -static int intel_panel_update_status(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(bd); - intel_panel_set_backlight(dev, bd->props.brightness); - return 0; -} - -static int intel_panel_get_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(bd); - struct drm_i915_private *dev_priv = dev->dev_private; - return dev_priv->backlight_level; -} - -static const struct backlight_ops intel_panel_bl_ops = { - .update_status = intel_panel_update_status, - .get_brightness = intel_panel_get_brightness, -}; - -int intel_panel_setup_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct backlight_properties props; - struct drm_connector *connector; - - intel_panel_init_backlight(dev); - - if (dev_priv->int_lvds_connector) - connector = dev_priv->int_lvds_connector; - else if (dev_priv->int_edp_connector) - connector = dev_priv->int_edp_connector; - else - return -ENODEV; - - props.type = BACKLIGHT_RAW; - props.max_brightness = intel_panel_get_max_backlight(dev); - dev_priv->backlight = - backlight_device_register("intel_backlight", - &connector->kdev, dev, - &intel_panel_bl_ops, &props); - - if (IS_ERR(dev_priv->backlight)) { - DRM_ERROR("Failed to register backlight: %ld\n", - PTR_ERR(dev_priv->backlight)); - dev_priv->backlight = NULL; - return -ENODEV; - } - dev_priv->backlight->props.brightness = intel_panel_get_backlight(dev); - return 0; -} - -void intel_panel_destroy_backlight(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - if (dev_priv->backlight) - backlight_device_unregister(dev_priv->backlight); -} -#else -int intel_panel_setup_backlight(struct drm_device *dev) -{ - intel_panel_init_backlight(dev); - return 0; -} - -void intel_panel_destroy_backlight(struct drm_device *dev) -{ - return; -} -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.c deleted file mode 100644 index 302d3d54..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.c +++ /dev/null @@ -1,1583 +0,0 @@ -/* - * Copyright © 2008-2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * Zou Nan hai - * Xiang Hai hao - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drv.h" -#include "i915_drm.h" -#include "i915_trace.h" -#include "intel_drv.h" - -/* - * 965+ support PIPE_CONTROL commands, which provide finer grained control - * over cache flushing. - */ -struct pipe_control { - struct drm_i915_gem_object *obj; - volatile u32 *cpu_page; - u32 gtt_offset; -}; - -static inline int ring_space(struct intel_ring_buffer *ring) -{ - int space = (ring->head & HEAD_ADDR) - (ring->tail + 8); - if (space < 0) - space += ring->size; - return space; -} - -static int -render_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) -{ - struct drm_device *dev = ring->dev; - u32 cmd; - int ret; - - /* - * read/write caches: - * - * I915_GEM_DOMAIN_RENDER is always invalidated, but is - * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is - * also flushed at 2d versus 3d pipeline switches. - * - * read-only caches: - * - * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if - * MI_READ_FLUSH is set, and is always flushed on 965. - * - * I915_GEM_DOMAIN_COMMAND may not exist? - * - * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is - * invalidated when MI_EXE_FLUSH is set. - * - * I915_GEM_DOMAIN_VERTEX, which exists on 965, is - * invalidated with every MI_FLUSH. - * - * TLBs: - * - * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND - * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and - * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER - * are flushed at any MI_FLUSH. - */ - - cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; - if ((invalidate_domains|flush_domains) & - I915_GEM_DOMAIN_RENDER) - cmd &= ~MI_NO_WRITE_FLUSH; - if (INTEL_INFO(dev)->gen < 4) { - /* - * On the 965, the sampler cache always gets flushed - * and this bit is reserved. - */ - if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) - cmd |= MI_READ_FLUSH; - } - if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) - cmd |= MI_EXE_FLUSH; - - if (invalidate_domains & I915_GEM_DOMAIN_COMMAND && - (IS_G4X(dev) || IS_GEN5(dev))) - cmd |= MI_INVALIDATE_ISP; - - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - - return 0; -} - -/** - * Emits a PIPE_CONTROL with a non-zero post-sync operation, for - * implementing two workarounds on gen6. From section 1.4.7.1 - * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1: - * - * [DevSNB-C+{W/A}] Before any depth stall flush (including those - * produced by non-pipelined state commands), software needs to first - * send a PIPE_CONTROL with no bits set except Post-Sync Operation != - * 0. - * - * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable - * =1, a PIPE_CONTROL with any non-zero post-sync-op is required. - * - * And the workaround for these two requires this workaround first: - * - * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent - * BEFORE the pipe-control with a post-sync op and no write-cache - * flushes. - * - * And this last workaround is tricky because of the requirements on - * that bit. From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM - * volume 2 part 1: - * - * "1 of the following must also be set: - * - Render Target Cache Flush Enable ([12] of DW1) - * - Depth Cache Flush Enable ([0] of DW1) - * - Stall at Pixel Scoreboard ([1] of DW1) - * - Depth Stall ([13] of DW1) - * - Post-Sync Operation ([13] of DW1) - * - Notify Enable ([8] of DW1)" - * - * The cache flushes require the workaround flush that triggered this - * one, so we can't use it. Depth stall would trigger the same. - * Post-sync nonzero is what triggered this second workaround, so we - * can't use that one either. Notify enable is IRQs, which aren't - * really our business. That leaves only stall at scoreboard. - */ -static int -intel_emit_post_sync_nonzero_flush(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc = ring->private; - u32 scratch_addr = pc->gtt_offset + 128; - int ret; - - - ret = intel_ring_begin(ring, 6); - if (ret) - return ret; - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); - intel_ring_emit(ring, PIPE_CONTROL_CS_STALL | - PIPE_CONTROL_STALL_AT_SCOREBOARD); - intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ - intel_ring_emit(ring, 0); /* low dword */ - intel_ring_emit(ring, 0); /* high dword */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - - ret = intel_ring_begin(ring, 6); - if (ret) - return ret; - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); - intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE); - intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); /* address */ - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - - return 0; -} - -static int -gen6_render_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, u32 flush_domains) -{ - u32 flags = 0; - struct pipe_control *pc = ring->private; - u32 scratch_addr = pc->gtt_offset + 128; - int ret; - - /* Force SNB workarounds for PIPE_CONTROL flushes */ - intel_emit_post_sync_nonzero_flush(ring); - - /* Just flush everything. Experiments have shown that reducing the - * number of bits based on the write domains has little performance - * impact. - */ - flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; - flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; - flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; - flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; - flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; - flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; - flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; - - ret = intel_ring_begin(ring, 6); - if (ret) - return ret; - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); - intel_ring_emit(ring, flags); - intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, 0); /* lower dword */ - intel_ring_emit(ring, 0); /* uppwer dword */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - - return 0; -} - -static void ring_write_tail(struct intel_ring_buffer *ring, - u32 value) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - I915_WRITE_TAIL(ring, value); -} - -u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - u32 acthd_reg = INTEL_INFO(ring->dev)->gen >= 4 ? - RING_ACTHD(ring->mmio_base) : ACTHD; - - return I915_READ(acthd_reg); -} - -static int init_ring_common(struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - struct drm_i915_gem_object *obj = ring->obj; - u32 head; - - /* Stop the ring if it's running. */ - I915_WRITE_CTL(ring, 0); - I915_WRITE_HEAD(ring, 0); - ring->write_tail(ring, 0); - - /* Initialize the ring. */ - I915_WRITE_START(ring, obj->gtt_offset); - head = I915_READ_HEAD(ring) & HEAD_ADDR; - - /* G45 ring initialization fails to reset head to zero */ - if (head != 0) { - DRM_DEBUG_KMS("%s head not reset to zero " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - - I915_WRITE_HEAD(ring, 0); - - if (I915_READ_HEAD(ring) & HEAD_ADDR) { - DRM_ERROR("failed to set %s head to zero " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - } - } - - I915_WRITE_CTL(ring, - ((ring->size - PAGE_SIZE) & RING_NR_PAGES) - | RING_VALID); - - /* If the head is still not zero, the ring is dead */ - if ((I915_READ_CTL(ring) & RING_VALID) == 0 || - I915_READ_START(ring) != obj->gtt_offset || - (I915_READ_HEAD(ring) & HEAD_ADDR) != 0) { - DRM_ERROR("%s initialization failed " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - return -EIO; - } - - if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) - i915_kernel_lost_context(ring->dev); - else { - ring->head = I915_READ_HEAD(ring); - ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; - ring->space = ring_space(ring); - ring->last_retired_head = -1; - } - - return 0; -} - -static int -init_pipe_control(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc; - struct drm_i915_gem_object *obj; - int ret; - - if (ring->private) - return 0; - - pc = kmalloc(sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; - - obj = i915_gem_alloc_object(ring->dev, 4096); - if (obj == NULL) { - DRM_ERROR("Failed to allocate seqno page\n"); - ret = -ENOMEM; - goto err; - } - - i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret) - goto err_unref; - - pc->gtt_offset = obj->gtt_offset; - pc->cpu_page = kmap(obj->pages[0]); - if (pc->cpu_page == NULL) - goto err_unpin; - - pc->obj = obj; - ring->private = pc; - return 0; - -err_unpin: - i915_gem_object_unpin(obj); -err_unref: - drm_gem_object_unreference(&obj->base); -err: - kfree(pc); - return ret; -} - -static void -cleanup_pipe_control(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc = ring->private; - struct drm_i915_gem_object *obj; - - if (!ring->private) - return; - - obj = pc->obj; - kunmap(obj->pages[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - - kfree(pc); - ring->private = NULL; -} - -static int init_render_ring(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret = init_ring_common(ring); - - if (INTEL_INFO(dev)->gen > 3) { - int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; - I915_WRITE(MI_MODE, mode); - if (IS_GEN7(dev)) - I915_WRITE(GFX_MODE_GEN7, - GFX_MODE_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | - GFX_MODE_ENABLE(GFX_REPLAY_MODE)); - } - - if (INTEL_INFO(dev)->gen >= 5) { - ret = init_pipe_control(ring); - if (ret) - return ret; - } - - - if (IS_GEN6(dev)) { - /* From the Sandybridge PRM, volume 1 part 3, page 24: - * "If this bit is set, STCunit will have LRA as replacement - * policy. [...] This bit must be reset. LRA replacement - * policy is not supported." - */ - I915_WRITE(CACHE_MODE_0, - CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); - } - - if (INTEL_INFO(dev)->gen >= 6) { - I915_WRITE(INSTPM, - INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); - } - - return ret; -} - -static void render_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring->private) - return; - - cleanup_pipe_control(ring); -} - -static void -update_mboxes(struct intel_ring_buffer *ring, - u32 seqno, - u32 mmio_offset) -{ - intel_ring_emit(ring, MI_SEMAPHORE_MBOX | - MI_SEMAPHORE_GLOBAL_GTT | - MI_SEMAPHORE_REGISTER | - MI_SEMAPHORE_UPDATE); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, mmio_offset); -} - -/** - * gen6_add_request - Update the semaphore mailbox registers - * - * @ring - ring that is adding a request - * @seqno - return seqno stuck into the ring - * - * Update the mailbox registers in the *other* rings with the current seqno. - * This acts like a signal in the canonical semaphore. - */ -static int -gen6_add_request(struct intel_ring_buffer *ring, - u32 *seqno) -{ - u32 mbox1_reg; - u32 mbox2_reg; - int ret; - - ret = intel_ring_begin(ring, 10); - if (ret) - return ret; - - mbox1_reg = ring->signal_mbox[0]; - mbox2_reg = ring->signal_mbox[1]; - - *seqno = i915_gem_next_request_seqno(ring); - - update_mboxes(ring, *seqno, mbox1_reg); - update_mboxes(ring, *seqno, mbox2_reg); - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, *seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - - return 0; -} - -/** - * intel_ring_sync - sync the waiter to the signaller on seqno - * - * @waiter - ring that is waiting - * @signaller - ring which has, or will signal - * @seqno - seqno which the waiter will block on - */ -static int -intel_ring_sync(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - int ring, - u32 seqno) -{ - int ret; - u32 dw1 = MI_SEMAPHORE_MBOX | - MI_SEMAPHORE_COMPARE | - MI_SEMAPHORE_REGISTER; - - ret = intel_ring_begin(waiter, 4); - if (ret) - return ret; - - intel_ring_emit(waiter, dw1 | signaller->semaphore_register[ring]); - intel_ring_emit(waiter, seqno); - intel_ring_emit(waiter, 0); - intel_ring_emit(waiter, MI_NOOP); - intel_ring_advance(waiter); - - return 0; -} - -/* VCS->RCS (RVSYNC) or BCS->RCS (RBSYNC) */ -int -render_ring_sync_to(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - u32 seqno) -{ - WARN_ON(signaller->semaphore_register[RCS] == MI_SEMAPHORE_SYNC_INVALID); - return intel_ring_sync(waiter, - signaller, - RCS, - seqno); -} - -/* RCS->VCS (VRSYNC) or BCS->VCS (VBSYNC) */ -int -gen6_bsd_ring_sync_to(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - u32 seqno) -{ - WARN_ON(signaller->semaphore_register[VCS] == MI_SEMAPHORE_SYNC_INVALID); - return intel_ring_sync(waiter, - signaller, - VCS, - seqno); -} - -/* RCS->BCS (BRSYNC) or VCS->BCS (BVSYNC) */ -int -gen6_blt_ring_sync_to(struct intel_ring_buffer *waiter, - struct intel_ring_buffer *signaller, - u32 seqno) -{ - WARN_ON(signaller->semaphore_register[BCS] == MI_SEMAPHORE_SYNC_INVALID); - return intel_ring_sync(waiter, - signaller, - BCS, - seqno); -} - - - -#define PIPE_CONTROL_FLUSH(ring__, addr__) \ -do { \ - intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \ - PIPE_CONTROL_DEPTH_STALL); \ - intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ - intel_ring_emit(ring__, 0); \ - intel_ring_emit(ring__, 0); \ -} while (0) - -static int -pc_render_add_request(struct intel_ring_buffer *ring, - u32 *result) -{ - u32 seqno = i915_gem_next_request_seqno(ring); - struct pipe_control *pc = ring->private; - u32 scratch_addr = pc->gtt_offset + 128; - int ret; - - /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently - * incoherent with writes to memory, i.e. completely fubar, - * so we need to use PIPE_NOTIFY instead. - * - * However, we also need to workaround the qword write - * incoherence by flushing the 6 PIPE_NOTIFY buffers out to - * memory before requesting an interrupt. - */ - ret = intel_ring_begin(ring, 32); - if (ret) - return ret; - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WRITE_FLUSH | - PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WRITE_FLUSH | - PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); - - *result = seqno; - return 0; -} - -static int -render_ring_add_request(struct intel_ring_buffer *ring, - u32 *result) -{ - u32 seqno = i915_gem_next_request_seqno(ring); - int ret; - - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - - *result = seqno; - return 0; -} - -static u32 -gen6_ring_get_seqno(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - - /* Workaround to force correct ordering between irq and seqno writes on - * ivb (and maybe also on snb) by reading from a CS register (like - * ACTHD) before reading the status page. */ - if (IS_GEN6(dev) || IS_GEN7(dev)) - intel_ring_get_active_head(ring); - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); -} - -static u32 -ring_get_seqno(struct intel_ring_buffer *ring) -{ - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); -} - -static u32 -pc_render_get_seqno(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc = ring->private; - return pc->cpu_page[0]; -} - -static void -ironlake_enable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - dev_priv->gt_irq_mask &= ~mask; - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - POSTING_READ(GTIMR); -} - -static void -ironlake_disable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - dev_priv->gt_irq_mask |= mask; - I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - POSTING_READ(GTIMR); -} - -static void -i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - dev_priv->irq_mask &= ~mask; - I915_WRITE(IMR, dev_priv->irq_mask); - POSTING_READ(IMR); -} - -static void -i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) -{ - dev_priv->irq_mask |= mask; - I915_WRITE(IMR, dev_priv->irq_mask); - POSTING_READ(IMR); -} - -static bool -render_ring_get_irq(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev->irq_enabled) - return false; - - spin_lock(&ring->irq_lock); - if (ring->irq_refcount++ == 0) { - if (HAS_PCH_SPLIT(dev)) - ironlake_enable_irq(dev_priv, - GT_PIPE_NOTIFY | GT_USER_INTERRUPT); - else - i915_enable_irq(dev_priv, I915_USER_INTERRUPT); - } - spin_unlock(&ring->irq_lock); - - return true; -} - -static void -render_ring_put_irq(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - spin_lock(&ring->irq_lock); - if (--ring->irq_refcount == 0) { - if (HAS_PCH_SPLIT(dev)) - ironlake_disable_irq(dev_priv, - GT_USER_INTERRUPT | - GT_PIPE_NOTIFY); - else - i915_disable_irq(dev_priv, I915_USER_INTERRUPT); - } - spin_unlock(&ring->irq_lock); -} - -void intel_ring_setup_status_page(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = ring->dev->dev_private; - u32 mmio = 0; - - /* The ring status page addresses are no longer next to the rest of - * the ring registers as of gen7. - */ - if (IS_GEN7(dev)) { - switch (ring->id) { - case RCS: - mmio = RENDER_HWS_PGA_GEN7; - break; - case BCS: - mmio = BLT_HWS_PGA_GEN7; - break; - case VCS: - mmio = BSD_HWS_PGA_GEN7; - break; - } - } else if (IS_GEN6(ring->dev)) { - mmio = RING_HWS_PGA_GEN6(ring->mmio_base); - } else { - mmio = RING_HWS_PGA(ring->mmio_base); - } - - I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); - POSTING_READ(mmio); -} - -static int -bsd_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) -{ - int ret; - - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - intel_ring_emit(ring, MI_FLUSH); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - return 0; -} - -static int -ring_add_request(struct intel_ring_buffer *ring, - u32 *result) -{ - u32 seqno; - int ret; - - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - seqno = i915_gem_next_request_seqno(ring); - - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - - *result = seqno; - return 0; -} - -static bool -gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev->irq_enabled) - return false; - - /* It looks like we need to prevent the gt from suspending while waiting - * for an notifiy irq, otherwise irqs seem to get lost on at least the - * blt/bsd rings on ivb. */ - gen6_gt_force_wake_get(dev_priv); - - spin_lock(&ring->irq_lock); - if (ring->irq_refcount++ == 0) { - ring->irq_mask &= ~rflag; - I915_WRITE_IMR(ring, ring->irq_mask); - ironlake_enable_irq(dev_priv, gflag); - } - spin_unlock(&ring->irq_lock); - - return true; -} - -static void -gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - spin_lock(&ring->irq_lock); - if (--ring->irq_refcount == 0) { - ring->irq_mask |= rflag; - I915_WRITE_IMR(ring, ring->irq_mask); - ironlake_disable_irq(dev_priv, gflag); - } - spin_unlock(&ring->irq_lock); - - gen6_gt_force_wake_put(dev_priv); -} - -static bool -bsd_ring_get_irq(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev->irq_enabled) - return false; - - spin_lock(&ring->irq_lock); - if (ring->irq_refcount++ == 0) { - if (IS_G4X(dev)) - i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT); - else - ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT); - } - spin_unlock(&ring->irq_lock); - - return true; -} -static void -bsd_ring_put_irq(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - spin_lock(&ring->irq_lock); - if (--ring->irq_refcount == 0) { - if (IS_G4X(dev)) - i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT); - else - ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT); - } - spin_unlock(&ring->irq_lock); -} - -static int -ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) -{ - int ret; - - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6) | - MI_BATCH_NON_SECURE_I965); - intel_ring_emit(ring, offset); - intel_ring_advance(ring); - - return 0; -} - -static int -render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, - u32 offset, u32 len) -{ - struct drm_device *dev = ring->dev; - int ret; - - if (IS_I830(dev) || IS_845G(dev)) { - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - intel_ring_emit(ring, MI_BATCH_BUFFER); - intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); - intel_ring_emit(ring, offset + len - 8); - intel_ring_emit(ring, 0); - } else { - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - if (INTEL_INFO(dev)->gen >= 4) { - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6) | - MI_BATCH_NON_SECURE_I965); - intel_ring_emit(ring, offset); - } else { - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6)); - intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); - } - } - intel_ring_advance(ring); - - return 0; -} - -static void cleanup_status_page(struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - struct drm_i915_gem_object *obj; - - obj = ring->status_page.obj; - if (obj == NULL) - return; - - kunmap(obj->pages[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - ring->status_page.obj = NULL; - - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); -} - -static int init_status_page(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int ret; - - obj = i915_gem_alloc_object(dev, 4096); - if (obj == NULL) { - DRM_ERROR("Failed to allocate status page\n"); - ret = -ENOMEM; - goto err; - } - - i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret != 0) { - goto err_unref; - } - - ring->status_page.gfx_addr = obj->gtt_offset; - ring->status_page.page_addr = kmap(obj->pages[0]); - if (ring->status_page.page_addr == NULL) { - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - goto err_unpin; - } - ring->status_page.obj = obj; - memset(ring->status_page.page_addr, 0, PAGE_SIZE); - - intel_ring_setup_status_page(ring); - DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", - ring->name, ring->status_page.gfx_addr); - - return 0; - -err_unpin: - i915_gem_object_unpin(obj); -err_unref: - drm_gem_object_unreference(&obj->base); -err: - return ret; -} - -int intel_init_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - struct drm_i915_gem_object *obj; - int ret; - - ring->dev = dev; - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - INIT_LIST_HEAD(&ring->gpu_write_list); - - init_waitqueue_head(&ring->irq_queue); - spin_lock_init(&ring->irq_lock); - ring->irq_mask = ~0; - - if (I915_NEED_GFX_HWS(dev)) { - ret = init_status_page(ring); - if (ret) - return ret; - } - - obj = i915_gem_alloc_object(dev, ring->size); - if (obj == NULL) { - DRM_ERROR("Failed to allocate ringbuffer\n"); - ret = -ENOMEM; - goto err_hws; - } - - ring->obj = obj; - - ret = i915_gem_object_pin(obj, PAGE_SIZE, true); - if (ret) - goto err_unref; - - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) - goto err_unpin; - - ring->map.size = ring->size; - ring->map.offset = dev->agp->base + obj->gtt_offset; - ring->map.type = 0; - ring->map.flags = 0; - ring->map.mtrr = 0; - - drm_core_ioremap_wc(&ring->map, dev); - if (ring->map.handle == NULL) { - DRM_ERROR("Failed to map ringbuffer.\n"); - ret = -EINVAL; - goto err_unpin; - } - - ring->virtual_start = ring->map.handle; - ret = ring->init(ring); - if (ret) - goto err_unmap; - - /* Workaround an erratum on the i830 which causes a hang if - * the TAIL pointer points to within the last 2 cachelines - * of the buffer. - */ - ring->effective_size = ring->size; - if (IS_I830(ring->dev) || IS_845G(ring->dev)) - ring->effective_size -= 128; - - return 0; - -err_unmap: - drm_core_ioremapfree(&ring->map, dev); -err_unpin: - i915_gem_object_unpin(obj); -err_unref: - drm_gem_object_unreference(&obj->base); - ring->obj = NULL; -err_hws: - cleanup_status_page(ring); - return ret; -} - -void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) -{ - struct drm_i915_private *dev_priv; - int ret; - - if (ring->obj == NULL) - return; - - /* Disable the ring buffer. The ring must be idle at this point */ - dev_priv = ring->dev->dev_private; - ret = intel_wait_ring_idle(ring); - if (ret) - DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", - ring->name, ret); - - I915_WRITE_CTL(ring, 0); - - drm_core_ioremapfree(&ring->map, ring->dev); - - i915_gem_object_unpin(ring->obj); - drm_gem_object_unreference(&ring->obj->base); - ring->obj = NULL; - - if (ring->cleanup) - ring->cleanup(ring); - - cleanup_status_page(ring); -} - -static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) -{ - unsigned int *virt; - int rem = ring->size - ring->tail; - - if (ring->space < rem) { - int ret = intel_wait_ring_buffer(ring, rem); - if (ret) - return ret; - } - - virt = (unsigned int *)(ring->virtual_start + ring->tail); - rem /= 8; - while (rem--) { - *virt++ = MI_NOOP; - *virt++ = MI_NOOP; - } - - ring->tail = 0; - ring->space = ring_space(ring); - - return 0; -} - -static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) -{ - struct drm_i915_private *dev_priv = ring->dev->dev_private; - bool was_interruptible; - int ret; - - /* XXX As we have not yet audited all the paths to check that - * they are ready for ERESTARTSYS from intel_ring_begin, do not - * allow us to be interruptible by a signal. - */ - was_interruptible = dev_priv->mm.interruptible; - dev_priv->mm.interruptible = false; - - ret = i915_wait_request(ring, seqno, true); - - dev_priv->mm.interruptible = was_interruptible; - - return ret; -} - -static int intel_ring_wait_request(struct intel_ring_buffer *ring, int n) -{ - struct drm_i915_gem_request *request; - u32 seqno = 0; - int ret; - - i915_gem_retire_requests_ring(ring); - - if (ring->last_retired_head != -1) { - ring->head = ring->last_retired_head; - ring->last_retired_head = -1; - ring->space = ring_space(ring); - if (ring->space >= n) - return 0; - } - - list_for_each_entry(request, &ring->request_list, list) { - int space; - - if (request->tail == -1) - continue; - - space = request->tail - (ring->tail + 8); - if (space < 0) - space += ring->size; - if (space >= n) { - seqno = request->seqno; - break; - } - - /* Consume this request in case we need more space than - * is available and so need to prevent a race between - * updating last_retired_head and direct reads of - * I915_RING_HEAD. It also provides a nice sanity check. - */ - request->tail = -1; - } - - if (seqno == 0) - return -ENOSPC; - - ret = intel_ring_wait_seqno(ring, seqno); - if (ret) - return ret; - - if (WARN_ON(ring->last_retired_head == -1)) - return -ENOSPC; - - ring->head = ring->last_retired_head; - ring->last_retired_head = -1; - ring->space = ring_space(ring); - if (WARN_ON(ring->space < n)) - return -ENOSPC; - - return 0; -} - -int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) -{ - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long end; - int ret; - - ret = intel_ring_wait_request(ring, n); - if (ret != -ENOSPC) - return ret; - - trace_i915_ring_wait_begin(ring); - if (drm_core_check_feature(dev, DRIVER_GEM)) - /* With GEM the hangcheck timer should kick us out of the loop, - * leaving it early runs the risk of corrupting GEM state (due - * to running on almost untested codepaths). But on resume - * timers don't work yet, so prevent a complete hang in that - * case by choosing an insanely large timeout. */ - end = jiffies + 60 * HZ; - else - end = jiffies + 3 * HZ; - - do { - ring->head = I915_READ_HEAD(ring); - ring->space = ring_space(ring); - if (ring->space >= n) { - trace_i915_ring_wait_end(ring); - return 0; - } - - if (dev->primary->master) { - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - } - - msleep(1); - if (atomic_read(&dev_priv->mm.wedged)) - return -EAGAIN; - } while (!time_after(jiffies, end)); - trace_i915_ring_wait_end(ring); - return -EBUSY; -} - -int intel_ring_begin(struct intel_ring_buffer *ring, - int num_dwords) -{ - struct drm_i915_private *dev_priv = ring->dev->dev_private; - int n = 4*num_dwords; - int ret; - - if (unlikely(atomic_read(&dev_priv->mm.wedged))) - return -EIO; - - if (unlikely(ring->tail + n > ring->effective_size)) { - ret = intel_wrap_ring_buffer(ring); - if (unlikely(ret)) - return ret; - } - - if (unlikely(ring->space < n)) { - ret = intel_wait_ring_buffer(ring, n); - if (unlikely(ret)) - return ret; - } - - ring->space -= n; - return 0; -} - -void intel_ring_advance(struct intel_ring_buffer *ring) -{ - ring->tail &= ring->size - 1; - ring->write_tail(ring, ring->tail); -} - -static const struct intel_ring_buffer render_ring = { - .name = "render ring", - .id = RCS, - .mmio_base = RENDER_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_render_ring, - .write_tail = ring_write_tail, - .flush = render_ring_flush, - .add_request = render_ring_add_request, - .get_seqno = ring_get_seqno, - .irq_get = render_ring_get_irq, - .irq_put = render_ring_put_irq, - .dispatch_execbuffer = render_ring_dispatch_execbuffer, - .cleanup = render_ring_cleanup, - .sync_to = render_ring_sync_to, - .semaphore_register = {MI_SEMAPHORE_SYNC_INVALID, - MI_SEMAPHORE_SYNC_RV, - MI_SEMAPHORE_SYNC_RB}, - .signal_mbox = {GEN6_VRSYNC, GEN6_BRSYNC}, -}; - -/* ring buffer for bit-stream decoder */ - -static const struct intel_ring_buffer bsd_ring = { - .name = "bsd ring", - .id = VCS, - .mmio_base = BSD_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = ring_write_tail, - .flush = bsd_ring_flush, - .add_request = ring_add_request, - .get_seqno = ring_get_seqno, - .irq_get = bsd_ring_get_irq, - .irq_put = bsd_ring_put_irq, - .dispatch_execbuffer = ring_dispatch_execbuffer, -}; - - -static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, - u32 value) -{ - drm_i915_private_t *dev_priv = ring->dev->dev_private; - - /* Every tail move must follow the sequence below */ - I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, - GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | - GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE); - I915_WRITE(GEN6_BSD_RNCID, 0x0); - - if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & - GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0, - 50)) - DRM_ERROR("timed out waiting for IDLE Indicator\n"); - - I915_WRITE_TAIL(ring, value); - I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, - GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK | - GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); -} - -static int gen6_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate, u32 flush) -{ - uint32_t cmd; - int ret; - - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - cmd = MI_FLUSH_DW; - if (invalidate & I915_GEM_GPU_DOMAINS) - cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - return 0; -} - -static int -gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, - u32 offset, u32 len) -{ - int ret; - - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); - /* bit0-7 is the length on GEN6+ */ - intel_ring_emit(ring, offset); - intel_ring_advance(ring); - - return 0; -} - -static bool -gen6_render_ring_get_irq(struct intel_ring_buffer *ring) -{ - return gen6_ring_get_irq(ring, - GT_USER_INTERRUPT, - GEN6_RENDER_USER_INTERRUPT); -} - -static void -gen6_render_ring_put_irq(struct intel_ring_buffer *ring) -{ - return gen6_ring_put_irq(ring, - GT_USER_INTERRUPT, - GEN6_RENDER_USER_INTERRUPT); -} - -static bool -gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring) -{ - return gen6_ring_get_irq(ring, - GT_GEN6_BSD_USER_INTERRUPT, - GEN6_BSD_USER_INTERRUPT); -} - -static void -gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) -{ - return gen6_ring_put_irq(ring, - GT_GEN6_BSD_USER_INTERRUPT, - GEN6_BSD_USER_INTERRUPT); -} - -/* ring buffer for Video Codec for Gen6+ */ -static const struct intel_ring_buffer gen6_bsd_ring = { - .name = "gen6 bsd ring", - .id = VCS, - .mmio_base = GEN6_BSD_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = gen6_bsd_ring_write_tail, - .flush = gen6_ring_flush, - .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, - .irq_get = gen6_bsd_ring_get_irq, - .irq_put = gen6_bsd_ring_put_irq, - .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .sync_to = gen6_bsd_ring_sync_to, - .semaphore_register = {MI_SEMAPHORE_SYNC_VR, - MI_SEMAPHORE_SYNC_INVALID, - MI_SEMAPHORE_SYNC_VB}, - .signal_mbox = {GEN6_RVSYNC, GEN6_BVSYNC}, -}; - -/* Blitter support (SandyBridge+) */ - -static bool -blt_ring_get_irq(struct intel_ring_buffer *ring) -{ - return gen6_ring_get_irq(ring, - GT_BLT_USER_INTERRUPT, - GEN6_BLITTER_USER_INTERRUPT); -} - -static void -blt_ring_put_irq(struct intel_ring_buffer *ring) -{ - gen6_ring_put_irq(ring, - GT_BLT_USER_INTERRUPT, - GEN6_BLITTER_USER_INTERRUPT); -} - -static int blt_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate, u32 flush) -{ - uint32_t cmd; - int ret; - - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; - - cmd = MI_FLUSH_DW; - if (invalidate & I915_GEM_DOMAIN_RENDER) - cmd |= MI_INVALIDATE_TLB; - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - return 0; -} - -static const struct intel_ring_buffer gen6_blt_ring = { - .name = "blt ring", - .id = BCS, - .mmio_base = BLT_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = ring_write_tail, - .flush = blt_ring_flush, - .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, - .irq_get = blt_ring_get_irq, - .irq_put = blt_ring_put_irq, - .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .sync_to = gen6_blt_ring_sync_to, - .semaphore_register = {MI_SEMAPHORE_SYNC_BR, - MI_SEMAPHORE_SYNC_BV, - MI_SEMAPHORE_SYNC_INVALID}, - .signal_mbox = {GEN6_RBSYNC, GEN6_VBSYNC}, -}; - -int intel_init_render_ring_buffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; - - *ring = render_ring; - if (INTEL_INFO(dev)->gen >= 6) { - ring->add_request = gen6_add_request; - ring->flush = gen6_render_ring_flush; - ring->irq_get = gen6_render_ring_get_irq; - ring->irq_put = gen6_render_ring_put_irq; - ring->get_seqno = gen6_ring_get_seqno; - } else if (IS_GEN5(dev)) { - ring->add_request = pc_render_add_request; - ring->get_seqno = pc_render_get_seqno; - } - - if (!I915_NEED_GFX_HWS(dev)) { - ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; - memset(ring->status_page.page_addr, 0, PAGE_SIZE); - } - - return intel_init_ring_buffer(dev, ring); -} - -int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; - - *ring = render_ring; - if (INTEL_INFO(dev)->gen >= 6) { - ring->add_request = gen6_add_request; - ring->irq_get = gen6_render_ring_get_irq; - ring->irq_put = gen6_render_ring_put_irq; - } else if (IS_GEN5(dev)) { - ring->add_request = pc_render_add_request; - ring->get_seqno = pc_render_get_seqno; - } - - if (!I915_NEED_GFX_HWS(dev)) - ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; - - ring->dev = dev; - INIT_LIST_HEAD(&ring->active_list); - INIT_LIST_HEAD(&ring->request_list); - INIT_LIST_HEAD(&ring->gpu_write_list); - - ring->size = size; - ring->effective_size = ring->size; - if (IS_I830(ring->dev)) - ring->effective_size -= 128; - - ring->map.offset = start; - ring->map.size = size; - ring->map.type = 0; - ring->map.flags = 0; - ring->map.mtrr = 0; - - drm_core_ioremap_wc(&ring->map, dev); - if (ring->map.handle == NULL) { - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; - } - - ring->virtual_start = (void __force __iomem *)ring->map.handle; - return 0; -} - -int intel_init_bsd_ring_buffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; - - if (IS_GEN6(dev) || IS_GEN7(dev)) - *ring = gen6_bsd_ring; - else - *ring = bsd_ring; - - return intel_init_ring_buffer(dev, ring); -} - -int intel_init_blt_ring_buffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; - - *ring = gen6_blt_ring; - - return intel_init_ring_buffer(dev, ring); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.h deleted file mode 100644 index bc0365b8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_ringbuffer.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef _INTEL_RINGBUFFER_H_ -#define _INTEL_RINGBUFFER_H_ - -struct intel_hw_status_page { - u32 __iomem *page_addr; - unsigned int gfx_addr; - struct drm_i915_gem_object *obj; -}; - -#define I915_READ_TAIL(ring) I915_READ(RING_TAIL((ring)->mmio_base)) -#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) - -#define I915_READ_START(ring) I915_READ(RING_START((ring)->mmio_base)) -#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) - -#define I915_READ_HEAD(ring) I915_READ(RING_HEAD((ring)->mmio_base)) -#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) - -#define I915_READ_CTL(ring) I915_READ(RING_CTL((ring)->mmio_base)) -#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) - -#define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base)) -#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) - -#define I915_READ_NOPID(ring) I915_READ(RING_NOPID((ring)->mmio_base)) -#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base)) -#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base)) - -struct intel_ring_buffer { - const char *name; - enum intel_ring_id { - RCS = 0x0, - VCS, - BCS, - } id; -#define I915_NUM_RINGS 3 - u32 mmio_base; - void __iomem *virtual_start; - struct drm_device *dev; - struct drm_i915_gem_object *obj; - - u32 head; - u32 tail; - int space; - int size; - int effective_size; - struct intel_hw_status_page status_page; - - /** We track the position of the requests in the ring buffer, and - * when each is retired we increment last_retired_head as the GPU - * must have finished processing the request and so we know we - * can advance the ringbuffer up to that position. - * - * last_retired_head is set to -1 after the value is consumed so - * we can detect new retirements. - */ - u32 last_retired_head; - - spinlock_t irq_lock; - u32 irq_refcount; - u32 irq_mask; - u32 irq_seqno; /* last seq seem at irq time */ - u32 trace_irq_seqno; - u32 waiting_seqno; - u32 sync_seqno[I915_NUM_RINGS-1]; - bool __must_check (*irq_get)(struct intel_ring_buffer *ring); - void (*irq_put)(struct intel_ring_buffer *ring); - - int (*init)(struct intel_ring_buffer *ring); - - void (*write_tail)(struct intel_ring_buffer *ring, - u32 value); - int __must_check (*flush)(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains); - int (*add_request)(struct intel_ring_buffer *ring, - u32 *seqno); - u32 (*get_seqno)(struct intel_ring_buffer *ring); - int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, - u32 offset, u32 length); - void (*cleanup)(struct intel_ring_buffer *ring); - int (*sync_to)(struct intel_ring_buffer *ring, - struct intel_ring_buffer *to, - u32 seqno); - - u32 semaphore_register[3]; /*our mbox written by others */ - u32 signal_mbox[2]; /* mboxes this ring signals to */ - /** - * List of objects currently involved in rendering from the - * ringbuffer. - * - * Includes buffers having the contents of their GPU caches - * flushed, not necessarily primitives. last_rendering_seqno - * represents when the rendering involved will be completed. - * - * A reference is held on the buffer while on this list. - */ - struct list_head active_list; - - /** - * List of breadcrumbs associated with GPU requests currently - * outstanding. - */ - struct list_head request_list; - - /** - * List of objects currently pending a GPU write flush. - * - * All elements on this list will belong to either the - * active_list or flushing_list, last_rendering_seqno can - * be used to differentiate between the two elements. - */ - struct list_head gpu_write_list; - - /** - * Do we have some not yet emitted requests outstanding? - */ - u32 outstanding_lazy_request; - - wait_queue_head_t irq_queue; - drm_local_map_t map; - - void *private; -}; - -static inline unsigned -intel_ring_flag(struct intel_ring_buffer *ring) -{ - return 1 << ring->id; -} - -static inline u32 -intel_ring_sync_index(struct intel_ring_buffer *ring, - struct intel_ring_buffer *other) -{ - int idx; - - /* - * cs -> 0 = vcs, 1 = bcs - * vcs -> 0 = bcs, 1 = cs, - * bcs -> 0 = cs, 1 = vcs. - */ - - idx = (other - ring) - 1; - if (idx < 0) - idx += I915_NUM_RINGS; - - return idx; -} - -static inline u32 -intel_read_status_page(struct intel_ring_buffer *ring, - int reg) -{ - return ioread32(ring->status_page.page_addr + reg); -} - -/** - * Reads a dword out of the status page, which is written to from the command - * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or - * MI_STORE_DATA_IMM. - * - * The following dwords have a reserved meaning: - * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes. - * 0x04: ring 0 head pointer - * 0x05: ring 1 head pointer (915-class) - * 0x06: ring 2 head pointer (915-class) - * 0x10-0x1b: Context status DWords (GM45) - * 0x1f: Last written status offset. (GM45) - * - * The area from dword 0x20 to 0x3ff is available for driver usage. - */ -#define READ_HWSP(dev_priv, reg) intel_read_status_page(LP_RING(dev_priv), reg) -#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) -#define I915_GEM_HWS_INDEX 0x20 -#define I915_BREADCRUMB_INDEX 0x21 - -void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); - -int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); -static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) -{ - return intel_wait_ring_buffer(ring, ring->size - 8); -} - -int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); - -static inline void intel_ring_emit(struct intel_ring_buffer *ring, - u32 data) -{ - iowrite32(data, ring->virtual_start + ring->tail); - ring->tail += 4; -} - -void intel_ring_advance(struct intel_ring_buffer *ring); - -u32 intel_ring_get_seqno(struct intel_ring_buffer *ring); - -int intel_init_render_ring_buffer(struct drm_device *dev); -int intel_init_bsd_ring_buffer(struct drm_device *dev); -int intel_init_blt_ring_buffer(struct drm_device *dev); - -u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); -void intel_ring_setup_status_page(struct intel_ring_buffer *ring); - -static inline u32 intel_ring_get_tail(struct intel_ring_buffer *ring) -{ - return ring->tail; -} - -static inline void i915_trace_irq_get(struct intel_ring_buffer *ring, u32 seqno) -{ - if (ring->trace_irq_seqno == 0 && ring->irq_get(ring)) - ring->trace_irq_seqno = seqno; -} - -/* DRI warts */ -int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size); - -#endif /* _INTEL_RINGBUFFER_H_ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo.c deleted file mode 100644 index eea58c6c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo.c +++ /dev/null @@ -1,2593 +0,0 @@ -/* - * Copyright 2006 Dave Airlie - * Copyright © 2006-2007 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ -#include -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_edid.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" -#include "intel_sdvo_regs.h" - -#define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) -#define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) -#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) -#define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0) - -#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\ - SDVO_TV_MASK) - -#define IS_TV(c) (c->output_flag & SDVO_TV_MASK) -#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) -#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) -#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) -#define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK)) - - -static const char *tv_format_names[] = { - "NTSC_M" , "NTSC_J" , "NTSC_443", - "PAL_B" , "PAL_D" , "PAL_G" , - "PAL_H" , "PAL_I" , "PAL_M" , - "PAL_N" , "PAL_NC" , "PAL_60" , - "SECAM_B" , "SECAM_D" , "SECAM_G" , - "SECAM_K" , "SECAM_K1", "SECAM_L" , - "SECAM_60" -}; - -#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) - -struct intel_sdvo { - struct intel_encoder base; - - struct i2c_adapter *i2c; - u8 slave_addr; - - struct i2c_adapter ddc; - - /* Register for the SDVO device: SDVOB or SDVOC */ - int sdvo_reg; - - /* Active outputs controlled by this SDVO output */ - uint16_t controlled_output; - - /* - * Capabilities of the SDVO device returned by - * i830_sdvo_get_capabilities() - */ - struct intel_sdvo_caps caps; - - /* Pixel clock limitations reported by the SDVO device, in kHz */ - int pixel_clock_min, pixel_clock_max; - - /* - * For multiple function SDVO device, - * this is for current attached outputs. - */ - uint16_t attached_output; - - /* - * Hotplug activation bits for this device - */ - uint8_t hotplug_active[2]; - - /** - * This is used to select the color range of RBG outputs in HDMI mode. - * It is only valid when using TMDS encoding and 8 bit per color mode. - */ - uint32_t color_range; - - /** - * This is set if we're going to treat the device as TV-out. - * - * While we have these nice friendly flags for output types that ought - * to decide this for us, the S-Video output on our HDMI+S-Video card - * shows up as RGB1 (VGA). - */ - bool is_tv; - - /* This is for current tv format name */ - int tv_format_index; - - /** - * This is set if we treat the device as HDMI, instead of DVI. - */ - bool is_hdmi; - bool has_hdmi_monitor; - bool has_hdmi_audio; - - /** - * This is set if we detect output of sdvo device as LVDS and - * have a valid fixed mode to use with the panel. - */ - bool is_lvds; - - /** - * This is sdvo fixed pannel mode pointer - */ - struct drm_display_mode *sdvo_lvds_fixed_mode; - - /* DDC bus used by this SDVO encoder */ - uint8_t ddc_bus; - - /* Input timings for adjusted_mode */ - struct intel_sdvo_dtd input_dtd; -}; - -struct intel_sdvo_connector { - struct intel_connector base; - - /* Mark the type of connector */ - uint16_t output_flag; - - enum hdmi_force_audio force_audio; - - /* This contains all current supported TV format */ - u8 tv_format_supported[TV_FORMAT_NUM]; - int format_supported_num; - struct drm_property *tv_format; - - /* add the property for the SDVO-TV */ - struct drm_property *left; - struct drm_property *right; - struct drm_property *top; - struct drm_property *bottom; - struct drm_property *hpos; - struct drm_property *vpos; - struct drm_property *contrast; - struct drm_property *saturation; - struct drm_property *hue; - struct drm_property *sharpness; - struct drm_property *flicker_filter; - struct drm_property *flicker_filter_adaptive; - struct drm_property *flicker_filter_2d; - struct drm_property *tv_chroma_filter; - struct drm_property *tv_luma_filter; - struct drm_property *dot_crawl; - - /* add the property for the SDVO-TV/LVDS */ - struct drm_property *brightness; - - /* Add variable to record current setting for the above property */ - u32 left_margin, right_margin, top_margin, bottom_margin; - - /* this is to get the range of margin.*/ - u32 max_hscan, max_vscan; - u32 max_hpos, cur_hpos; - u32 max_vpos, cur_vpos; - u32 cur_brightness, max_brightness; - u32 cur_contrast, max_contrast; - u32 cur_saturation, max_saturation; - u32 cur_hue, max_hue; - u32 cur_sharpness, max_sharpness; - u32 cur_flicker_filter, max_flicker_filter; - u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; - u32 cur_flicker_filter_2d, max_flicker_filter_2d; - u32 cur_tv_chroma_filter, max_tv_chroma_filter; - u32 cur_tv_luma_filter, max_tv_luma_filter; - u32 cur_dot_crawl, max_dot_crawl; -}; - -static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) -{ - return container_of(encoder, struct intel_sdvo, base.base); -} - -static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_sdvo, base); -} - -static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) -{ - return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); -} - -static bool -intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); -static bool -intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_connector *intel_sdvo_connector, - int type); -static bool -intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_connector *intel_sdvo_connector); - -/** - * Writes the SDVOB or SDVOC with the given value, but always writes both - * SDVOB and SDVOC to work around apparent hardware issues (according to - * comments in the BIOS). - */ -static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) -{ - struct drm_device *dev = intel_sdvo->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - u32 bval = val, cval = val; - int i; - - if (intel_sdvo->sdvo_reg == PCH_SDVOB) { - I915_WRITE(intel_sdvo->sdvo_reg, val); - I915_READ(intel_sdvo->sdvo_reg); - return; - } - - if (intel_sdvo->sdvo_reg == SDVOB) { - cval = I915_READ(SDVOC); - } else { - bval = I915_READ(SDVOB); - } - /* - * Write the registers twice for luck. Sometimes, - * writing them only once doesn't appear to 'stick'. - * The BIOS does this too. Yay, magic - */ - for (i = 0; i < 2; i++) - { - I915_WRITE(SDVOB, bval); - I915_READ(SDVOB); - I915_WRITE(SDVOC, cval); - I915_READ(SDVOC); - } -} - -static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) -{ - struct i2c_msg msgs[] = { - { - .addr = intel_sdvo->slave_addr, - .flags = 0, - .len = 1, - .buf = &addr, - }, - { - .addr = intel_sdvo->slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = ch, - } - }; - int ret; - - if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2) - return true; - - DRM_DEBUG_KMS("i2c transfer returned %d\n", ret); - return false; -} - -#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} -/** Mapping of command numbers to names, for debug output */ -static const struct _sdvo_cmd_name { - u8 cmd; - const char *name; -} sdvo_cmd_names[] = { - SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), - - /* Add the op code for SDVO enhancements */ - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), - - /* HDMI op code */ - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), -}; - -#define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) -#define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") - -static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, - const void *args, int args_len) -{ - int i; - - DRM_DEBUG_KMS("%s: W: %02X ", - SDVO_NAME(intel_sdvo), cmd); - for (i = 0; i < args_len; i++) - DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); - for (; i < 8; i++) - DRM_LOG_KMS(" "); - for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) { - if (cmd == sdvo_cmd_names[i].cmd) { - DRM_LOG_KMS("(%s)", sdvo_cmd_names[i].name); - break; - } - } - if (i == ARRAY_SIZE(sdvo_cmd_names)) - DRM_LOG_KMS("(%02X)", cmd); - DRM_LOG_KMS("\n"); -} - -static const char *cmd_status_names[] = { - "Power on", - "Success", - "Not supported", - "Invalid arg", - "Pending", - "Target not specified", - "Scaling not supported" -}; - -static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, - const void *args, int args_len) -{ - u8 buf[args_len*2 + 2], status; - struct i2c_msg msgs[args_len + 3]; - int i, ret; - - intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); - - for (i = 0; i < args_len; i++) { - msgs[i].addr = intel_sdvo->slave_addr; - msgs[i].flags = 0; - msgs[i].len = 2; - msgs[i].buf = buf + 2 *i; - buf[2*i + 0] = SDVO_I2C_ARG_0 - i; - buf[2*i + 1] = ((u8*)args)[i]; - } - msgs[i].addr = intel_sdvo->slave_addr; - msgs[i].flags = 0; - msgs[i].len = 2; - msgs[i].buf = buf + 2*i; - buf[2*i + 0] = SDVO_I2C_OPCODE; - buf[2*i + 1] = cmd; - - /* the following two are to read the response */ - status = SDVO_I2C_CMD_STATUS; - msgs[i+1].addr = intel_sdvo->slave_addr; - msgs[i+1].flags = 0; - msgs[i+1].len = 1; - msgs[i+1].buf = &status; - - msgs[i+2].addr = intel_sdvo->slave_addr; - msgs[i+2].flags = I2C_M_RD; - msgs[i+2].len = 1; - msgs[i+2].buf = &status; - - ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3); - if (ret < 0) { - DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); - return false; - } - if (ret != i+3) { - /* failure in I2C transfer */ - DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); - return false; - } - - return true; -} - -static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, - void *response, int response_len) -{ - u8 retry = 5; - u8 status; - int i; - - DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); - - /* - * The documentation states that all commands will be - * processed within 15µs, and that we need only poll - * the status byte a maximum of 3 times in order for the - * command to be complete. - * - * Check 5 times in case the hardware failed to read the docs. - */ - if (!intel_sdvo_read_byte(intel_sdvo, - SDVO_I2C_CMD_STATUS, - &status)) - goto log_fail; - - while (status == SDVO_CMD_STATUS_PENDING && retry--) { - udelay(15); - if (!intel_sdvo_read_byte(intel_sdvo, - SDVO_I2C_CMD_STATUS, - &status)) - goto log_fail; - } - - if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) - DRM_LOG_KMS("(%s)", cmd_status_names[status]); - else - DRM_LOG_KMS("(??? %d)", status); - - if (status != SDVO_CMD_STATUS_SUCCESS) - goto log_fail; - - /* Read the command response */ - for (i = 0; i < response_len; i++) { - if (!intel_sdvo_read_byte(intel_sdvo, - SDVO_I2C_RETURN_0 + i, - &((u8 *)response)[i])) - goto log_fail; - DRM_LOG_KMS(" %02X", ((u8 *)response)[i]); - } - DRM_LOG_KMS("\n"); - return true; - -log_fail: - DRM_LOG_KMS("... failed\n"); - return false; -} - -static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) -{ - if (mode->clock >= 100000) - return 1; - else if (mode->clock >= 50000) - return 2; - else - return 4; -} - -static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, - u8 ddc_bus) -{ - /* This must be the immediately preceding write before the i2c xfer */ - return intel_sdvo_write_cmd(intel_sdvo, - SDVO_CMD_SET_CONTROL_BUS_SWITCH, - &ddc_bus, 1); -} - -static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) -{ - if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) - return false; - - return intel_sdvo_read_response(intel_sdvo, NULL, 0); -} - -static bool -intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len) -{ - if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0)) - return false; - - return intel_sdvo_read_response(intel_sdvo, value, len); -} - -static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo) -{ - struct intel_sdvo_set_target_input_args targets = {0}; - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_TARGET_INPUT, - &targets, sizeof(targets)); -} - -/** - * Return whether each input is trained. - * - * This function is making an assumption about the layout of the response, - * which should be checked against the docs. - */ -static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) -{ - struct intel_sdvo_get_trained_inputs_response response; - - BUILD_BUG_ON(sizeof(response) != 1); - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, - &response, sizeof(response))) - return false; - - *input_1 = response.input0_trained; - *input_2 = response.input1_trained; - return true; -} - -static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, - u16 outputs) -{ - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_ACTIVE_OUTPUTS, - &outputs, sizeof(outputs)); -} - -static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, - int mode) -{ - u8 state = SDVO_ENCODER_STATE_ON; - - switch (mode) { - case DRM_MODE_DPMS_ON: - state = SDVO_ENCODER_STATE_ON; - break; - case DRM_MODE_DPMS_STANDBY: - state = SDVO_ENCODER_STATE_STANDBY; - break; - case DRM_MODE_DPMS_SUSPEND: - state = SDVO_ENCODER_STATE_SUSPEND; - break; - case DRM_MODE_DPMS_OFF: - state = SDVO_ENCODER_STATE_OFF; - break; - } - - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); -} - -static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, - int *clock_min, - int *clock_max) -{ - struct intel_sdvo_pixel_clock_range clocks; - - BUILD_BUG_ON(sizeof(clocks) != 4); - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, - &clocks, sizeof(clocks))) - return false; - - /* Convert the values from units of 10 kHz to kHz. */ - *clock_min = clocks.min * 10; - *clock_max = clocks.max * 10; - return true; -} - -static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, - u16 outputs) -{ - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_TARGET_OUTPUT, - &outputs, sizeof(outputs)); -} - -static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, - struct intel_sdvo_dtd *dtd) -{ - return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && - intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); -} - -static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_dtd *dtd) -{ - return intel_sdvo_set_timing(intel_sdvo, - SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); -} - -static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_dtd *dtd) -{ - return intel_sdvo_set_timing(intel_sdvo, - SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); -} - -static bool -intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, - uint16_t clock, - uint16_t width, - uint16_t height) -{ - struct intel_sdvo_preferred_input_timing_args args; - - memset(&args, 0, sizeof(args)); - args.clock = clock; - args.width = width; - args.height = height; - args.interlace = 0; - - if (intel_sdvo->is_lvds && - (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || - intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) - args.scaled = 1; - - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, - &args, sizeof(args)); -} - -static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_dtd *dtd) -{ - BUILD_BUG_ON(sizeof(dtd->part1) != 8); - BUILD_BUG_ON(sizeof(dtd->part2) != 8); - return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, - &dtd->part1, sizeof(dtd->part1)) && - intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, - &dtd->part2, sizeof(dtd->part2)); -} - -static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) -{ - return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); -} - -static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, - const struct drm_display_mode *mode) -{ - uint16_t width, height; - uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; - uint16_t h_sync_offset, v_sync_offset; - int mode_clock; - - width = mode->crtc_hdisplay; - height = mode->crtc_vdisplay; - - /* do some mode translations */ - h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; - h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; - - v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; - v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; - - h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; - v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - - mode_clock = mode->clock; - mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; - mode_clock /= 10; - dtd->part1.clock = mode_clock; - - dtd->part1.h_active = width & 0xff; - dtd->part1.h_blank = h_blank_len & 0xff; - dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | - ((h_blank_len >> 8) & 0xf); - dtd->part1.v_active = height & 0xff; - dtd->part1.v_blank = v_blank_len & 0xff; - dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | - ((v_blank_len >> 8) & 0xf); - - dtd->part2.h_sync_off = h_sync_offset & 0xff; - dtd->part2.h_sync_width = h_sync_len & 0xff; - dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | - (v_sync_len & 0xf); - dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | - ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | - ((v_sync_len & 0x30) >> 4); - - dtd->part2.dtd_flags = 0x18; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE; - if (mode->flags & DRM_MODE_FLAG_PHSYNC) - dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE; - if (mode->flags & DRM_MODE_FLAG_PVSYNC) - dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; - - dtd->part2.sdvo_flags = 0; - dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; - dtd->part2.reserved = 0; -} - -static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, - const struct intel_sdvo_dtd *dtd) -{ - mode->hdisplay = dtd->part1.h_active; - mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; - mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; - mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; - mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; - mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; - mode->htotal = mode->hdisplay + dtd->part1.h_blank; - mode->htotal += (dtd->part1.h_high & 0xf) << 8; - - mode->vdisplay = dtd->part1.v_active; - mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; - mode->vsync_start = mode->vdisplay; - mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; - mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; - mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; - mode->vsync_end = mode->vsync_start + - (dtd->part2.v_sync_off_width & 0xf); - mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; - mode->vtotal = mode->vdisplay + dtd->part1.v_blank; - mode->vtotal += (dtd->part1.v_high & 0xf) << 8; - - mode->clock = dtd->part1.clock * 10; - - mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); - if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) - mode->flags |= DRM_MODE_FLAG_INTERLACE; - if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) - mode->flags |= DRM_MODE_FLAG_PHSYNC; - if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) - mode->flags |= DRM_MODE_FLAG_PVSYNC; -} - -static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) -{ - struct intel_sdvo_encode encode; - - BUILD_BUG_ON(sizeof(encode) != 2); - return intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_SUPP_ENCODE, - &encode, sizeof(encode)); -} - -static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, - uint8_t mode) -{ - return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); -} - -static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, - uint8_t mode) -{ - return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); -} - -#if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) -{ - int i, j; - uint8_t set_buf_index[2]; - uint8_t av_split; - uint8_t buf_size; - uint8_t buf[48]; - uint8_t *pos; - - intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); - - for (i = 0; i <= av_split; i++) { - set_buf_index[0] = i; set_buf_index[1] = 0; - intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2); - intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); - intel_sdvo_read_response(encoder, &buf_size, 1); - - pos = buf; - for (j = 0; j <= buf_size; j += 8) { - intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA, - NULL, 0); - intel_sdvo_read_response(encoder, pos, 8); - pos += 8; - } - } -} -#endif - -static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) -{ - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; - uint8_t set_buf_index[2] = { 1, 0 }; - uint64_t *data = (uint64_t *)&avi_if; - unsigned i; - - intel_dip_infoframe_csum(&avi_if); - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2)) - return false; - - for (i = 0; i < sizeof(avi_if); i += 8) { - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_DATA, - data, 8)) - return false; - data++; - } - - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_TXRATE, - &tx_rate, 1); -} - -static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) -{ - struct intel_sdvo_tv_format format; - uint32_t format_map; - - format_map = 1 << intel_sdvo->tv_format_index; - memset(&format, 0, sizeof(format)); - memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); - - BUILD_BUG_ON(sizeof(format) != 6); - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_TV_FORMAT, - &format, sizeof(format)); -} - -static bool -intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, - struct drm_display_mode *mode) -{ - struct intel_sdvo_dtd output_dtd; - - if (!intel_sdvo_set_target_output(intel_sdvo, - intel_sdvo->attached_output)) - return false; - - intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) - return false; - - return true; -} - -static bool -intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* Reset the input timing to the screen. Assume always input 0. */ - if (!intel_sdvo_set_target_input(intel_sdvo)) - return false; - - if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, - mode->clock / 10, - mode->hdisplay, - mode->vdisplay)) - return false; - - if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, - &intel_sdvo->input_dtd)) - return false; - - intel_sdvo_get_mode_from_dtd(adjusted_mode, &intel_sdvo->input_dtd); - - return true; -} - -static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); - int multiplier; - - /* We need to construct preferred input timings based on our - * output timings. To do that, we have to set the output - * timings, even though this isn't really the right place in - * the sequence to do it. Oh well. - */ - if (intel_sdvo->is_tv) { - if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) - return false; - - (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, - mode, - adjusted_mode); - } else if (intel_sdvo->is_lvds) { - if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, - intel_sdvo->sdvo_lvds_fixed_mode)) - return false; - - (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, - mode, - adjusted_mode); - } - - /* Make the CRTC code factor in the SDVO pixel multiplier. The - * SDVO device will factor out the multiplier during mode_set. - */ - multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode); - intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); - - return true; -} - -static void intel_sdvo_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); - u32 sdvox; - struct intel_sdvo_in_out_map in_out; - struct intel_sdvo_dtd input_dtd, output_dtd; - int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); - int rate; - - if (!mode) - return; - - /* First, set the input mapping for the first input to our controlled - * output. This is only correct if we're a single-input device, in - * which case the first input is the output from the appropriate SDVO - * channel on the motherboard. In a two-input device, the first input - * will be SDVOB and the second SDVOC. - */ - in_out.in0 = intel_sdvo->attached_output; - in_out.in1 = 0; - - intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_IN_OUT_MAP, - &in_out, sizeof(in_out)); - - /* Set the output timings to the screen */ - if (!intel_sdvo_set_target_output(intel_sdvo, - intel_sdvo->attached_output)) - return; - - /* lvds has a special fixed output timing. */ - if (intel_sdvo->is_lvds) - intel_sdvo_get_dtd_from_mode(&output_dtd, - intel_sdvo->sdvo_lvds_fixed_mode); - else - intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); - - /* Set the input timing to the screen. Assume always input 0. */ - if (!intel_sdvo_set_target_input(intel_sdvo)) - return; - - if (intel_sdvo->has_hdmi_monitor) { - intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); - intel_sdvo_set_colorimetry(intel_sdvo, - SDVO_COLORIMETRY_RGB256); - intel_sdvo_set_avi_infoframe(intel_sdvo); - } else - intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI); - - if (intel_sdvo->is_tv && - !intel_sdvo_set_tv_format(intel_sdvo)) - return; - - /* We have tried to get input timing in mode_fixup, and filled into - * adjusted_mode. - */ - intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); - (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); - - switch (pixel_multiplier) { - default: - case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; - case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; - case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; - } - if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate)) - return; - - /* Set the SDVO control regs. */ - if (INTEL_INFO(dev)->gen >= 4) { - /* The real mode polarity is set by the SDVO commands, using - * struct intel_sdvo_dtd. */ - sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; - if (intel_sdvo->is_hdmi) - sdvox |= intel_sdvo->color_range; - if (INTEL_INFO(dev)->gen < 5) - sdvox |= SDVO_BORDER_ENABLE; - } else { - sdvox = I915_READ(intel_sdvo->sdvo_reg); - switch (intel_sdvo->sdvo_reg) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; - } - - if (INTEL_PCH_TYPE(dev) >= PCH_CPT) - sdvox |= TRANSCODER_CPT(intel_crtc->pipe); - else - sdvox |= TRANSCODER(intel_crtc->pipe); - - if (intel_sdvo->has_hdmi_audio) - sdvox |= SDVO_AUDIO_ENABLE; - - if (INTEL_INFO(dev)->gen >= 4) { - /* done in crtc_mode_set as the dpll_md reg must be written early */ - } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { - /* done in crtc_mode_set as it lives inside the dpll register */ - } else { - sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; - } - - if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL && - INTEL_INFO(dev)->gen < 5) - sdvox |= SDVO_STALL_SELECT; - intel_sdvo_write_sdvox(intel_sdvo, sdvox); -} - -static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - u32 temp; - - if (mode != DRM_MODE_DPMS_ON) { - intel_sdvo_set_active_outputs(intel_sdvo, 0); - if (0) - intel_sdvo_set_encoder_power_state(intel_sdvo, mode); - - if (mode == DRM_MODE_DPMS_OFF) { - temp = I915_READ(intel_sdvo->sdvo_reg); - if ((temp & SDVO_ENABLE) != 0) { - intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); - } - } - } else { - bool input1, input2; - int i; - u8 status; - - temp = I915_READ(intel_sdvo->sdvo_reg); - if ((temp & SDVO_ENABLE) == 0) - intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); - for (i = 0; i < 2; i++) - intel_wait_for_vblank(dev, intel_crtc->pipe); - - status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); - /* Warn if the device reported failure to sync. - * A lot of SDVO devices fail to notify of sync, but it's - * a given it the status is a success, we succeeded. - */ - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { - DRM_DEBUG_KMS("First %s output reported failure to " - "sync\n", SDVO_NAME(intel_sdvo)); - } - - if (0) - intel_sdvo_set_encoder_power_state(intel_sdvo, mode); - intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); - } - return; -} - -static int intel_sdvo_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (intel_sdvo->pixel_clock_min > mode->clock) - return MODE_CLOCK_LOW; - - if (intel_sdvo->pixel_clock_max < mode->clock) - return MODE_CLOCK_HIGH; - - if (intel_sdvo->is_lvds) { - if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) - return MODE_PANEL; - - if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) - return MODE_PANEL; - } - - return MODE_OK; -} - -static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) -{ - BUILD_BUG_ON(sizeof(*caps) != 8); - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_DEVICE_CAPS, - caps, sizeof(*caps))) - return false; - - DRM_DEBUG_KMS("SDVO capabilities:\n" - " vendor_id: %d\n" - " device_id: %d\n" - " device_rev_id: %d\n" - " sdvo_version_major: %d\n" - " sdvo_version_minor: %d\n" - " sdvo_inputs_mask: %d\n" - " smooth_scaling: %d\n" - " sharp_scaling: %d\n" - " up_scaling: %d\n" - " down_scaling: %d\n" - " stall_support: %d\n" - " output_flags: %d\n", - caps->vendor_id, - caps->device_id, - caps->device_rev_id, - caps->sdvo_version_major, - caps->sdvo_version_minor, - caps->sdvo_inputs_mask, - caps->smooth_scaling, - caps->sharp_scaling, - caps->up_scaling, - caps->down_scaling, - caps->stall_support, - caps->output_flags); - - return true; -} - -static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) -{ - struct drm_device *dev = intel_sdvo->base.base.dev; - u8 response[2]; - - /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise - * on the line. */ - if (IS_I945G(dev) || IS_I945GM(dev)) - return false; - - return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, - &response, 2) && response[0]; -} - -static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) -{ - struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); - - intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2); -} - -static bool -intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) -{ - /* Is there more than one type of output? */ - return hweight16(intel_sdvo->caps.output_flags) > 1; -} - -static struct edid * -intel_sdvo_get_edid(struct drm_connector *connector) -{ - struct intel_sdvo *sdvo = intel_attached_sdvo(connector); - return drm_get_edid(connector, &sdvo->ddc); -} - -/* Mac mini hack -- use the same DDC as the analog connector */ -static struct edid * -intel_sdvo_get_analog_edid(struct drm_connector *connector) -{ - struct drm_i915_private *dev_priv = connector->dev->dev_private; - - return drm_get_edid(connector, - &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); -} - -enum drm_connector_status -intel_sdvo_tmds_sink_detect(struct drm_connector *connector) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - enum drm_connector_status status; - struct edid *edid; - - edid = intel_sdvo_get_edid(connector); - - if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { - u8 ddc, saved_ddc = intel_sdvo->ddc_bus; - - /* - * Don't use the 1 as the argument of DDC bus switch to get - * the EDID. It is used for SDVO SPD ROM. - */ - for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { - intel_sdvo->ddc_bus = ddc; - edid = intel_sdvo_get_edid(connector); - if (edid) - break; - } - /* - * If we found the EDID on the other bus, - * assume that is the correct DDC bus. - */ - if (edid == NULL) - intel_sdvo->ddc_bus = saved_ddc; - } - - /* - * When there is no edid and no monitor is connected with VGA - * port, try to use the CRT ddc to read the EDID for DVI-connector. - */ - if (edid == NULL) - edid = intel_sdvo_get_analog_edid(connector); - - status = connector_status_unknown; - if (edid != NULL) { - /* DDC bus is shared, match EDID to connector type */ - if (edid->input & DRM_EDID_INPUT_DIGITAL) { - status = connector_status_connected; - if (intel_sdvo->is_hdmi) { - intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); - intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); - } - } else - status = connector_status_disconnected; - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - if (status == connector_status_connected) { - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - if (intel_sdvo_connector->force_audio != HDMI_AUDIO_AUTO) - intel_sdvo->has_hdmi_audio = (intel_sdvo_connector->force_audio == HDMI_AUDIO_ON); - } - - return status; -} - -static bool -intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo, - struct edid *edid) -{ - bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); - bool connector_is_digital = !!IS_DIGITAL(sdvo); - - DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n", - connector_is_digital, monitor_is_digital); - return connector_is_digital == monitor_is_digital; -} - -static enum drm_connector_status -intel_sdvo_detect(struct drm_connector *connector, bool force) -{ - uint16_t response; - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - enum drm_connector_status ret; - - if (!intel_sdvo_write_cmd(intel_sdvo, - SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) - return connector_status_unknown; - - /* add 30ms delay when the output type might be TV */ - if (intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0)) - mdelay(30); - - if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) - return connector_status_unknown; - - DRM_DEBUG_KMS("SDVO response %d %d [%x]\n", - response & 0xff, response >> 8, - intel_sdvo_connector->output_flag); - - if (response == 0) - return connector_status_disconnected; - - intel_sdvo->attached_output = response; - - intel_sdvo->has_hdmi_monitor = false; - intel_sdvo->has_hdmi_audio = false; - - if ((intel_sdvo_connector->output_flag & response) == 0) - ret = connector_status_disconnected; - else if (IS_TMDS(intel_sdvo_connector)) - ret = intel_sdvo_tmds_sink_detect(connector); - else { - struct edid *edid; - - /* if we have an edid check it matches the connection */ - edid = intel_sdvo_get_edid(connector); - if (edid == NULL) - edid = intel_sdvo_get_analog_edid(connector); - if (edid != NULL) { - if (intel_sdvo_connector_matches_edid(intel_sdvo_connector, - edid)) - ret = connector_status_connected; - else - ret = connector_status_disconnected; - - connector->display_info.raw_edid = NULL; - kfree(edid); - } else - ret = connector_status_connected; - } - - /* May update encoder flag for like clock for SDVO TV, etc.*/ - if (ret == connector_status_connected) { - intel_sdvo->is_tv = false; - intel_sdvo->is_lvds = false; - intel_sdvo->base.needs_tv_clock = false; - - if (response & SDVO_TV_MASK) { - intel_sdvo->is_tv = true; - intel_sdvo->base.needs_tv_clock = true; - } - if (response & SDVO_LVDS_MASK) - intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; - } - - return ret; -} - -static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) -{ - struct edid *edid; - - /* set the bus switch and get the modes */ - edid = intel_sdvo_get_edid(connector); - - /* - * Mac mini hack. On this device, the DVI-I connector shares one DDC - * link between analog and digital outputs. So, if the regular SDVO - * DDC fails, check to see if the analog output is disconnected, in - * which case we'll look there for the digital DDC data. - */ - if (edid == NULL) - edid = intel_sdvo_get_analog_edid(connector); - - if (edid != NULL) { - if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector), - edid)) { - drm_mode_connector_update_edid_property(connector, edid); - drm_add_edid_modes(connector, edid); - } - - connector->display_info.raw_edid = NULL; - kfree(edid); - } -} - -/* - * Set of SDVO TV modes. - * Note! This is in reply order (see loop in get_tv_modes). - * XXX: all 60Hz refresh? - */ -static const struct drm_display_mode sdvo_tv_modes[] = { - { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384, - 416, 0, 200, 201, 232, 233, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384, - 416, 0, 240, 241, 272, 273, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464, - 496, 0, 300, 301, 332, 333, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704, - 736, 0, 350, 351, 382, 383, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704, - 736, 0, 400, 401, 432, 433, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704, - 736, 0, 480, 481, 512, 513, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768, - 800, 0, 480, 481, 512, 513, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768, - 800, 0, 576, 577, 608, 609, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784, - 816, 0, 350, 351, 382, 383, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784, - 816, 0, 400, 401, 432, 433, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784, - 816, 0, 480, 481, 512, 513, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784, - 816, 0, 540, 541, 572, 573, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784, - 816, 0, 576, 577, 608, 609, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832, - 864, 0, 576, 577, 608, 609, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864, - 896, 0, 600, 601, 632, 633, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896, - 928, 0, 624, 625, 656, 657, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984, - 1016, 0, 766, 767, 798, 799, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088, - 1120, 0, 768, 769, 800, 801, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344, - 1376, 0, 1024, 1025, 1056, 1057, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -}; - -static void intel_sdvo_get_tv_modes(struct drm_connector *connector) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct intel_sdvo_sdtv_resolution_request tv_res; - uint32_t reply = 0, format_map = 0; - int i; - - /* Read the list of supported input resolutions for the selected TV - * format. - */ - format_map = 1 << intel_sdvo->tv_format_index; - memcpy(&tv_res, &format_map, - min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); - - if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output)) - return; - - BUILD_BUG_ON(sizeof(tv_res) != 3); - if (!intel_sdvo_write_cmd(intel_sdvo, - SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, - &tv_res, sizeof(tv_res))) - return; - if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) - return; - - for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) - if (reply & (1 << i)) { - struct drm_display_mode *nmode; - nmode = drm_mode_duplicate(connector->dev, - &sdvo_tv_modes[i]); - if (nmode) - drm_mode_probed_add(connector, nmode); - } -} - -static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct drm_display_mode *newmode; - - /* - * Attempt to get the mode list from DDC. - * Assume that the preferred modes are - * arranged in priority order. - */ - intel_ddc_get_modes(connector, intel_sdvo->i2c); - if (list_empty(&connector->probed_modes) == false) - goto end; - - /* Fetch modes from VBT */ - if (dev_priv->sdvo_lvds_vbt_mode != NULL) { - newmode = drm_mode_duplicate(connector->dev, - dev_priv->sdvo_lvds_vbt_mode); - if (newmode != NULL) { - /* Guarantee the mode is preferred */ - newmode->type = (DRM_MODE_TYPE_PREFERRED | - DRM_MODE_TYPE_DRIVER); - drm_mode_probed_add(connector, newmode); - } - } - -end: - list_for_each_entry(newmode, &connector->probed_modes, head) { - if (newmode->type & DRM_MODE_TYPE_PREFERRED) { - intel_sdvo->sdvo_lvds_fixed_mode = - drm_mode_duplicate(connector->dev, newmode); - - drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, - 0); - - intel_sdvo->is_lvds = true; - break; - } - } - -} - -static int intel_sdvo_get_modes(struct drm_connector *connector) -{ - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - - if (IS_TV(intel_sdvo_connector)) - intel_sdvo_get_tv_modes(connector); - else if (IS_LVDS(intel_sdvo_connector)) - intel_sdvo_get_lvds_modes(connector); - else - intel_sdvo_get_ddc_modes(connector); - - return !list_empty(&connector->probed_modes); -} - -static void -intel_sdvo_destroy_enhance_property(struct drm_connector *connector) -{ - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - struct drm_device *dev = connector->dev; - - if (intel_sdvo_connector->left) - drm_property_destroy(dev, intel_sdvo_connector->left); - if (intel_sdvo_connector->right) - drm_property_destroy(dev, intel_sdvo_connector->right); - if (intel_sdvo_connector->top) - drm_property_destroy(dev, intel_sdvo_connector->top); - if (intel_sdvo_connector->bottom) - drm_property_destroy(dev, intel_sdvo_connector->bottom); - if (intel_sdvo_connector->hpos) - drm_property_destroy(dev, intel_sdvo_connector->hpos); - if (intel_sdvo_connector->vpos) - drm_property_destroy(dev, intel_sdvo_connector->vpos); - if (intel_sdvo_connector->saturation) - drm_property_destroy(dev, intel_sdvo_connector->saturation); - if (intel_sdvo_connector->contrast) - drm_property_destroy(dev, intel_sdvo_connector->contrast); - if (intel_sdvo_connector->hue) - drm_property_destroy(dev, intel_sdvo_connector->hue); - if (intel_sdvo_connector->sharpness) - drm_property_destroy(dev, intel_sdvo_connector->sharpness); - if (intel_sdvo_connector->flicker_filter) - drm_property_destroy(dev, intel_sdvo_connector->flicker_filter); - if (intel_sdvo_connector->flicker_filter_2d) - drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d); - if (intel_sdvo_connector->flicker_filter_adaptive) - drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive); - if (intel_sdvo_connector->tv_luma_filter) - drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter); - if (intel_sdvo_connector->tv_chroma_filter) - drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter); - if (intel_sdvo_connector->dot_crawl) - drm_property_destroy(dev, intel_sdvo_connector->dot_crawl); - if (intel_sdvo_connector->brightness) - drm_property_destroy(dev, intel_sdvo_connector->brightness); -} - -static void intel_sdvo_destroy(struct drm_connector *connector) -{ - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - - if (intel_sdvo_connector->tv_format) - drm_property_destroy(connector->dev, - intel_sdvo_connector->tv_format); - - intel_sdvo_destroy_enhance_property(connector); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct edid *edid; - bool has_audio = false; - - if (!intel_sdvo->is_hdmi) - return false; - - edid = intel_sdvo_get_edid(connector); - if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - - return has_audio; -} - -static int -intel_sdvo_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - uint16_t temp_value; - uint8_t cmd; - int ret; - - ret = drm_connector_property_set_value(connector, property, val); - if (ret) - return ret; - - if (property == dev_priv->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_sdvo_connector->force_audio) - return 0; - - intel_sdvo_connector->force_audio = i; - - if (i == HDMI_AUDIO_AUTO) - has_audio = intel_sdvo_detect_hdmi_audio(connector); - else - has_audio = (i == HDMI_AUDIO_ON); - - if (has_audio == intel_sdvo->has_hdmi_audio) - return 0; - - intel_sdvo->has_hdmi_audio = has_audio; - goto done; - } - - if (property == dev_priv->broadcast_rgb_property) { - if (val == !!intel_sdvo->color_range) - return 0; - - intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; - goto done; - } - -#define CHECK_PROPERTY(name, NAME) \ - if (intel_sdvo_connector->name == property) { \ - if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ - if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ - cmd = SDVO_CMD_SET_##NAME; \ - intel_sdvo_connector->cur_##name = temp_value; \ - goto set_value; \ - } - - if (property == intel_sdvo_connector->tv_format) { - if (val >= TV_FORMAT_NUM) - return -EINVAL; - - if (intel_sdvo->tv_format_index == - intel_sdvo_connector->tv_format_supported[val]) - return 0; - - intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val]; - goto done; - } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { - temp_value = val; - if (intel_sdvo_connector->left == property) { - drm_connector_property_set_value(connector, - intel_sdvo_connector->right, val); - if (intel_sdvo_connector->left_margin == temp_value) - return 0; - - intel_sdvo_connector->left_margin = temp_value; - intel_sdvo_connector->right_margin = temp_value; - temp_value = intel_sdvo_connector->max_hscan - - intel_sdvo_connector->left_margin; - cmd = SDVO_CMD_SET_OVERSCAN_H; - goto set_value; - } else if (intel_sdvo_connector->right == property) { - drm_connector_property_set_value(connector, - intel_sdvo_connector->left, val); - if (intel_sdvo_connector->right_margin == temp_value) - return 0; - - intel_sdvo_connector->left_margin = temp_value; - intel_sdvo_connector->right_margin = temp_value; - temp_value = intel_sdvo_connector->max_hscan - - intel_sdvo_connector->left_margin; - cmd = SDVO_CMD_SET_OVERSCAN_H; - goto set_value; - } else if (intel_sdvo_connector->top == property) { - drm_connector_property_set_value(connector, - intel_sdvo_connector->bottom, val); - if (intel_sdvo_connector->top_margin == temp_value) - return 0; - - intel_sdvo_connector->top_margin = temp_value; - intel_sdvo_connector->bottom_margin = temp_value; - temp_value = intel_sdvo_connector->max_vscan - - intel_sdvo_connector->top_margin; - cmd = SDVO_CMD_SET_OVERSCAN_V; - goto set_value; - } else if (intel_sdvo_connector->bottom == property) { - drm_connector_property_set_value(connector, - intel_sdvo_connector->top, val); - if (intel_sdvo_connector->bottom_margin == temp_value) - return 0; - - intel_sdvo_connector->top_margin = temp_value; - intel_sdvo_connector->bottom_margin = temp_value; - temp_value = intel_sdvo_connector->max_vscan - - intel_sdvo_connector->top_margin; - cmd = SDVO_CMD_SET_OVERSCAN_V; - goto set_value; - } - CHECK_PROPERTY(hpos, HPOS) - CHECK_PROPERTY(vpos, VPOS) - CHECK_PROPERTY(saturation, SATURATION) - CHECK_PROPERTY(contrast, CONTRAST) - CHECK_PROPERTY(hue, HUE) - CHECK_PROPERTY(brightness, BRIGHTNESS) - CHECK_PROPERTY(sharpness, SHARPNESS) - CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) - CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) - CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) - CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) - CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) - CHECK_PROPERTY(dot_crawl, DOT_CRAWL) - } - - return -EINVAL; /* unknown property */ - -set_value: - if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) - return -EIO; - - -done: - if (intel_sdvo->base.base.crtc) { - struct drm_crtc *crtc = intel_sdvo->base.base.crtc; - drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, - crtc->y, crtc->fb); - } - - return 0; -#undef CHECK_PROPERTY -} - -static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { - .dpms = intel_sdvo_dpms, - .mode_fixup = intel_sdvo_mode_fixup, - .prepare = intel_encoder_prepare, - .mode_set = intel_sdvo_mode_set, - .commit = intel_encoder_commit, -}; - -static const struct drm_connector_funcs intel_sdvo_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = intel_sdvo_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = intel_sdvo_set_property, - .destroy = intel_sdvo_destroy, -}; - -static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = { - .get_modes = intel_sdvo_get_modes, - .mode_valid = intel_sdvo_mode_valid, - .best_encoder = intel_best_encoder, -}; - -static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) -{ - struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); - - if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) - drm_mode_destroy(encoder->dev, - intel_sdvo->sdvo_lvds_fixed_mode); - - i2c_del_adapter(&intel_sdvo->ddc); - intel_encoder_destroy(encoder); -} - -static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { - .destroy = intel_sdvo_enc_destroy, -}; - -static void -intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) -{ - uint16_t mask = 0; - unsigned int num_bits; - - /* Make a mask of outputs less than or equal to our own priority in the - * list. - */ - switch (sdvo->controlled_output) { - case SDVO_OUTPUT_LVDS1: - mask |= SDVO_OUTPUT_LVDS1; - case SDVO_OUTPUT_LVDS0: - mask |= SDVO_OUTPUT_LVDS0; - case SDVO_OUTPUT_TMDS1: - mask |= SDVO_OUTPUT_TMDS1; - case SDVO_OUTPUT_TMDS0: - mask |= SDVO_OUTPUT_TMDS0; - case SDVO_OUTPUT_RGB1: - mask |= SDVO_OUTPUT_RGB1; - case SDVO_OUTPUT_RGB0: - mask |= SDVO_OUTPUT_RGB0; - break; - } - - /* Count bits to find what number we are in the priority list. */ - mask &= sdvo->caps.output_flags; - num_bits = hweight16(mask); - /* If more than 3 outputs, default to DDC bus 3 for now. */ - if (num_bits > 3) - num_bits = 3; - - /* Corresponds to SDVO_CONTROL_BUS_DDCx */ - sdvo->ddc_bus = 1 << num_bits; -} - -/** - * Choose the appropriate DDC bus for control bus switch command for this - * SDVO output based on the controlled output. - * - * DDC bus number assignment is in a priority order of RGB outputs, then TMDS - * outputs, then LVDS outputs. - */ -static void -intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, - struct intel_sdvo *sdvo, u32 reg) -{ - struct sdvo_device_mapping *mapping; - - if (IS_SDVOB(reg)) - mapping = &(dev_priv->sdvo_mappings[0]); - else - mapping = &(dev_priv->sdvo_mappings[1]); - - if (mapping->initialized) - sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); - else - intel_sdvo_guess_ddc_bus(sdvo); -} - -static void -intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, - struct intel_sdvo *sdvo, u32 reg) -{ - struct sdvo_device_mapping *mapping; - u8 pin; - - if (IS_SDVOB(reg)) - mapping = &dev_priv->sdvo_mappings[0]; - else - mapping = &dev_priv->sdvo_mappings[1]; - - pin = GMBUS_PORT_DPB; - if (mapping->initialized) - pin = mapping->i2c_pin; - - if (pin < GMBUS_NUM_PORTS) { - sdvo->i2c = &dev_priv->gmbus[pin].adapter; - intel_gmbus_set_speed(sdvo->i2c, GMBUS_RATE_1MHZ); - intel_gmbus_force_bit(sdvo->i2c, true); - } else { - sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; - } -} - -static bool -intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device) -{ - return intel_sdvo_check_supp_encode(intel_sdvo); -} - -static u8 -intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct sdvo_device_mapping *my_mapping, *other_mapping; - - if (IS_SDVOB(sdvo_reg)) { - my_mapping = &dev_priv->sdvo_mappings[0]; - other_mapping = &dev_priv->sdvo_mappings[1]; - } else { - my_mapping = &dev_priv->sdvo_mappings[1]; - other_mapping = &dev_priv->sdvo_mappings[0]; - } - - /* If the BIOS described our SDVO device, take advantage of it. */ - if (my_mapping->slave_addr) - return my_mapping->slave_addr; - - /* If the BIOS only described a different SDVO device, use the - * address that it isn't using. - */ - if (other_mapping->slave_addr) { - if (other_mapping->slave_addr == 0x70) - return 0x72; - else - return 0x70; - } - - /* No SDVO device info is found for another DVO port, - * so use mapping assumption we had before BIOS parsing. - */ - if (IS_SDVOB(sdvo_reg)) - return 0x70; - else - return 0x72; -} - -static void -intel_sdvo_connector_init(struct intel_sdvo_connector *connector, - struct intel_sdvo *encoder) -{ - drm_connector_init(encoder->base.base.dev, - &connector->base.base, - &intel_sdvo_connector_funcs, - connector->base.base.connector_type); - - drm_connector_helper_add(&connector->base.base, - &intel_sdvo_connector_helper_funcs); - - connector->base.base.interlace_allowed = 1; - connector->base.base.doublescan_allowed = 0; - connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; - - intel_connector_attach_encoder(&connector->base, &encoder->base); - drm_sysfs_connector_add(&connector->base.base); -} - -static void -intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector) -{ - struct drm_device *dev = connector->base.base.dev; - - intel_attach_force_audio_property(&connector->base.base); - if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) - intel_attach_broadcast_rgb_property(&connector->base.base); -} - -static bool -intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) -{ - struct drm_encoder *encoder = &intel_sdvo->base.base; - struct drm_connector *connector; - struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - struct intel_connector *intel_connector; - struct intel_sdvo_connector *intel_sdvo_connector; - - intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); - if (!intel_sdvo_connector) - return false; - - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; - intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; - intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; - } - - intel_connector = &intel_sdvo_connector->base; - connector = &intel_connector->base; - if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) { - connector->polled = DRM_CONNECTOR_POLL_HPD; - intel_sdvo->hotplug_active[0] |= 1 << device; - /* Some SDVO devices have one-shot hotplug interrupts. - * Ensure that they get re-enabled when an interrupt happens. - */ - intel_encoder->hot_plug = intel_sdvo_enable_hotplug; - intel_sdvo_enable_hotplug(intel_encoder); - } - else - connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - encoder->encoder_type = DRM_MODE_ENCODER_TMDS; - connector->connector_type = DRM_MODE_CONNECTOR_DVID; - - if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { - connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; - intel_sdvo->is_hdmi = true; - } - intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT)); - - intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); - if (intel_sdvo->is_hdmi) - intel_sdvo_add_hdmi_properties(intel_sdvo_connector); - - return true; -} - -static bool -intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) -{ - struct drm_encoder *encoder = &intel_sdvo->base.base; - struct drm_connector *connector; - struct intel_connector *intel_connector; - struct intel_sdvo_connector *intel_sdvo_connector; - - intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); - if (!intel_sdvo_connector) - return false; - - intel_connector = &intel_sdvo_connector->base; - connector = &intel_connector->base; - encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; - connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; - - intel_sdvo->controlled_output |= type; - intel_sdvo_connector->output_flag = type; - - intel_sdvo->is_tv = true; - intel_sdvo->base.needs_tv_clock = true; - intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; - - intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); - - if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) - goto err; - - if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) - goto err; - - return true; - -err: - intel_sdvo_destroy(connector); - return false; -} - -static bool -intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) -{ - struct drm_encoder *encoder = &intel_sdvo->base.base; - struct drm_connector *connector; - struct intel_connector *intel_connector; - struct intel_sdvo_connector *intel_sdvo_connector; - - intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); - if (!intel_sdvo_connector) - return false; - - intel_connector = &intel_sdvo_connector->base; - connector = &intel_connector->base; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - encoder->encoder_type = DRM_MODE_ENCODER_DAC; - connector->connector_type = DRM_MODE_CONNECTOR_VGA; - - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; - intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; - intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; - } - - intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT)); - - intel_sdvo_connector_init(intel_sdvo_connector, - intel_sdvo); - return true; -} - -static bool -intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) -{ - struct drm_encoder *encoder = &intel_sdvo->base.base; - struct drm_connector *connector; - struct intel_connector *intel_connector; - struct intel_sdvo_connector *intel_sdvo_connector; - - intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); - if (!intel_sdvo_connector) - return false; - - intel_connector = &intel_sdvo_connector->base; - connector = &intel_connector->base; - encoder->encoder_type = DRM_MODE_ENCODER_LVDS; - connector->connector_type = DRM_MODE_CONNECTOR_LVDS; - - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; - intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; - intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; - } - - intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | - (1 << INTEL_SDVO_LVDS_CLONE_BIT)); - - intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); - if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) - goto err; - - return true; - -err: - intel_sdvo_destroy(connector); - return false; -} - -static bool -intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) -{ - intel_sdvo->is_tv = false; - intel_sdvo->base.needs_tv_clock = false; - intel_sdvo->is_lvds = false; - - /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ - - if (flags & SDVO_OUTPUT_TMDS0) - if (!intel_sdvo_dvi_init(intel_sdvo, 0)) - return false; - - if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) - if (!intel_sdvo_dvi_init(intel_sdvo, 1)) - return false; - - /* TV has no XXX1 function block */ - if (flags & SDVO_OUTPUT_SVID0) - if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0)) - return false; - - if (flags & SDVO_OUTPUT_CVBS0) - if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) - return false; - - if (flags & SDVO_OUTPUT_RGB0) - if (!intel_sdvo_analog_init(intel_sdvo, 0)) - return false; - - if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) - if (!intel_sdvo_analog_init(intel_sdvo, 1)) - return false; - - if (flags & SDVO_OUTPUT_LVDS0) - if (!intel_sdvo_lvds_init(intel_sdvo, 0)) - return false; - - if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) - if (!intel_sdvo_lvds_init(intel_sdvo, 1)) - return false; - - if ((flags & SDVO_OUTPUT_MASK) == 0) { - unsigned char bytes[2]; - - intel_sdvo->controlled_output = 0; - memcpy(bytes, &intel_sdvo->caps.output_flags, 2); - DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", - SDVO_NAME(intel_sdvo), - bytes[0], bytes[1]); - return false; - } - intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); - - return true; -} - -static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_connector *intel_sdvo_connector, - int type) -{ - struct drm_device *dev = intel_sdvo->base.base.dev; - struct intel_sdvo_tv_format format; - uint32_t format_map, i; - - if (!intel_sdvo_set_target_output(intel_sdvo, type)) - return false; - - BUILD_BUG_ON(sizeof(format) != 6); - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_SUPPORTED_TV_FORMATS, - &format, sizeof(format))) - return false; - - memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); - - if (format_map == 0) - return false; - - intel_sdvo_connector->format_supported_num = 0; - for (i = 0 ; i < TV_FORMAT_NUM; i++) - if (format_map & (1 << i)) - intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i; - - - intel_sdvo_connector->tv_format = - drm_property_create(dev, DRM_MODE_PROP_ENUM, - "mode", intel_sdvo_connector->format_supported_num); - if (!intel_sdvo_connector->tv_format) - return false; - - for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) - drm_property_add_enum( - intel_sdvo_connector->tv_format, i, - i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]); - - intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0]; - drm_connector_attach_property(&intel_sdvo_connector->base.base, - intel_sdvo_connector->tv_format, 0); - return true; - -} - -#define ENHANCEMENT(name, NAME) do { \ - if (enhancements.name) { \ - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ - !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ - return false; \ - intel_sdvo_connector->max_##name = data_value[0]; \ - intel_sdvo_connector->cur_##name = response; \ - intel_sdvo_connector->name = \ - drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ - if (!intel_sdvo_connector->name) return false; \ - drm_connector_attach_property(connector, \ - intel_sdvo_connector->name, \ - intel_sdvo_connector->cur_##name); \ - DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ - data_value[0], data_value[1], response); \ - } \ -} while (0) - -static bool -intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_connector *intel_sdvo_connector, - struct intel_sdvo_enhancements_reply enhancements) -{ - struct drm_device *dev = intel_sdvo->base.base.dev; - struct drm_connector *connector = &intel_sdvo_connector->base.base; - uint16_t response, data_value[2]; - - /* when horizontal overscan is supported, Add the left/right property */ - if (enhancements.overscan_h) { - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_MAX_OVERSCAN_H, - &data_value, 4)) - return false; - - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_OVERSCAN_H, - &response, 2)) - return false; - - intel_sdvo_connector->max_hscan = data_value[0]; - intel_sdvo_connector->left_margin = data_value[0] - response; - intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; - intel_sdvo_connector->left = - drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); - if (!intel_sdvo_connector->left) - return false; - - drm_connector_attach_property(connector, - intel_sdvo_connector->left, - intel_sdvo_connector->left_margin); - - intel_sdvo_connector->right = - drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); - if (!intel_sdvo_connector->right) - return false; - - drm_connector_attach_property(connector, - intel_sdvo_connector->right, - intel_sdvo_connector->right_margin); - DRM_DEBUG_KMS("h_overscan: max %d, " - "default %d, current %d\n", - data_value[0], data_value[1], response); - } - - if (enhancements.overscan_v) { - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_MAX_OVERSCAN_V, - &data_value, 4)) - return false; - - if (!intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_OVERSCAN_V, - &response, 2)) - return false; - - intel_sdvo_connector->max_vscan = data_value[0]; - intel_sdvo_connector->top_margin = data_value[0] - response; - intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; - intel_sdvo_connector->top = - drm_property_create_range(dev, 0, - "top_margin", 0, data_value[0]); - if (!intel_sdvo_connector->top) - return false; - - drm_connector_attach_property(connector, - intel_sdvo_connector->top, - intel_sdvo_connector->top_margin); - - intel_sdvo_connector->bottom = - drm_property_create_range(dev, 0, - "bottom_margin", 0, data_value[0]); - if (!intel_sdvo_connector->bottom) - return false; - - drm_connector_attach_property(connector, - intel_sdvo_connector->bottom, - intel_sdvo_connector->bottom_margin); - DRM_DEBUG_KMS("v_overscan: max %d, " - "default %d, current %d\n", - data_value[0], data_value[1], response); - } - - ENHANCEMENT(hpos, HPOS); - ENHANCEMENT(vpos, VPOS); - ENHANCEMENT(saturation, SATURATION); - ENHANCEMENT(contrast, CONTRAST); - ENHANCEMENT(hue, HUE); - ENHANCEMENT(sharpness, SHARPNESS); - ENHANCEMENT(brightness, BRIGHTNESS); - ENHANCEMENT(flicker_filter, FLICKER_FILTER); - ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); - ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); - ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); - ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); - - if (enhancements.dot_crawl) { - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) - return false; - - intel_sdvo_connector->max_dot_crawl = 1; - intel_sdvo_connector->cur_dot_crawl = response & 0x1; - intel_sdvo_connector->dot_crawl = - drm_property_create_range(dev, 0, "dot_crawl", 0, 1); - if (!intel_sdvo_connector->dot_crawl) - return false; - - drm_connector_attach_property(connector, - intel_sdvo_connector->dot_crawl, - intel_sdvo_connector->cur_dot_crawl); - DRM_DEBUG_KMS("dot crawl: current %d\n", response); - } - - return true; -} - -static bool -intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_connector *intel_sdvo_connector, - struct intel_sdvo_enhancements_reply enhancements) -{ - struct drm_device *dev = intel_sdvo->base.base.dev; - struct drm_connector *connector = &intel_sdvo_connector->base.base; - uint16_t response, data_value[2]; - - ENHANCEMENT(brightness, BRIGHTNESS); - - return true; -} -#undef ENHANCEMENT - -static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, - struct intel_sdvo_connector *intel_sdvo_connector) -{ - union { - struct intel_sdvo_enhancements_reply reply; - uint16_t response; - } enhancements; - - BUILD_BUG_ON(sizeof(enhancements) != 2); - - enhancements.response = 0; - intel_sdvo_get_value(intel_sdvo, - SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, - &enhancements, sizeof(enhancements)); - if (enhancements.response == 0) { - DRM_DEBUG_KMS("No enhancement is supported\n"); - return true; - } - - if (IS_TV(intel_sdvo_connector)) - return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply); - else if (IS_LVDS(intel_sdvo_connector)) - return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); - else - return true; -} - -static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) -{ - struct intel_sdvo *sdvo = adapter->algo_data; - - if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus)) - return -EIO; - - return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num); -} - -static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter) -{ - struct intel_sdvo *sdvo = adapter->algo_data; - return sdvo->i2c->algo->functionality(sdvo->i2c); -} - -static const struct i2c_algorithm intel_sdvo_ddc_proxy = { - .master_xfer = intel_sdvo_ddc_proxy_xfer, - .functionality = intel_sdvo_ddc_proxy_func -}; - -static bool -intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo, - struct drm_device *dev) -{ - sdvo->ddc.owner = THIS_MODULE; - sdvo->ddc.class = I2C_CLASS_DDC; - snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy"); - sdvo->ddc.dev.parent = &dev->pdev->dev; - sdvo->ddc.algo_data = sdvo; - sdvo->ddc.algo = &intel_sdvo_ddc_proxy; - - return i2c_add_adapter(&sdvo->ddc) == 0; -} - -bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_encoder *intel_encoder; - struct intel_sdvo *intel_sdvo; - int i; - - intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); - if (!intel_sdvo) - return false; - - intel_sdvo->sdvo_reg = sdvo_reg; - intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1; - intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg); - if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) { - kfree(intel_sdvo); - return false; - } - - /* encoder type will be decided later */ - intel_encoder = &intel_sdvo->base; - intel_encoder->type = INTEL_OUTPUT_SDVO; - drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); - - /* Read the regs to test if we can talk to the device */ - for (i = 0; i < 0x40; i++) { - u8 byte; - - if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) { - DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", - IS_SDVOB(sdvo_reg) ? 'B' : 'C'); - goto err; - } - } - - if (IS_SDVOB(sdvo_reg)) - dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; - else - dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; - - drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); - - /* In default case sdvo lvds is false */ - if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) - goto err; - - /* Set up hotplug command - note paranoia about contents of reply. - * We assume that the hardware is in a sane state, and only touch - * the bits we think we understand. - */ - intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, - &intel_sdvo->hotplug_active, 2); - intel_sdvo->hotplug_active[0] &= ~0x3; - - if (intel_sdvo_output_setup(intel_sdvo, - intel_sdvo->caps.output_flags) != true) { - DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", - IS_SDVOB(sdvo_reg) ? 'B' : 'C'); - goto err; - } - - intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); - - /* Set the input timing to the screen. Assume always input 0. */ - if (!intel_sdvo_set_target_input(intel_sdvo)) - goto err; - - if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, - &intel_sdvo->pixel_clock_min, - &intel_sdvo->pixel_clock_max)) - goto err; - - DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " - "clock range %dMHz - %dMHz, " - "input 1: %c, input 2: %c, " - "output 1: %c, output 2: %c\n", - SDVO_NAME(intel_sdvo), - intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id, - intel_sdvo->caps.device_rev_id, - intel_sdvo->pixel_clock_min / 1000, - intel_sdvo->pixel_clock_max / 1000, - (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', - (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', - /* check currently supported outputs */ - intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', - intel_sdvo->caps.output_flags & - (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); - return true; - -err: - drm_encoder_cleanup(&intel_encoder->base); - i2c_del_adapter(&intel_sdvo->ddc); - kfree(intel_sdvo); - - return false; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo_regs.h b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo_regs.h deleted file mode 100644 index 9d030142..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ /dev/null @@ -1,728 +0,0 @@ -/* - * Copyright © 2006-2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - */ - -/** - * @file SDVO command definitions and structures. - */ - -#define SDVO_OUTPUT_FIRST (0) -#define SDVO_OUTPUT_TMDS0 (1 << 0) -#define SDVO_OUTPUT_RGB0 (1 << 1) -#define SDVO_OUTPUT_CVBS0 (1 << 2) -#define SDVO_OUTPUT_SVID0 (1 << 3) -#define SDVO_OUTPUT_YPRPB0 (1 << 4) -#define SDVO_OUTPUT_SCART0 (1 << 5) -#define SDVO_OUTPUT_LVDS0 (1 << 6) -#define SDVO_OUTPUT_TMDS1 (1 << 8) -#define SDVO_OUTPUT_RGB1 (1 << 9) -#define SDVO_OUTPUT_CVBS1 (1 << 10) -#define SDVO_OUTPUT_SVID1 (1 << 11) -#define SDVO_OUTPUT_YPRPB1 (1 << 12) -#define SDVO_OUTPUT_SCART1 (1 << 13) -#define SDVO_OUTPUT_LVDS1 (1 << 14) -#define SDVO_OUTPUT_LAST (14) - -struct intel_sdvo_caps { - u8 vendor_id; - u8 device_id; - u8 device_rev_id; - u8 sdvo_version_major; - u8 sdvo_version_minor; - unsigned int sdvo_inputs_mask:2; - unsigned int smooth_scaling:1; - unsigned int sharp_scaling:1; - unsigned int up_scaling:1; - unsigned int down_scaling:1; - unsigned int stall_support:1; - unsigned int pad:1; - u16 output_flags; -} __attribute__((packed)); - -/* Note: SDVO detailed timing flags match EDID misc flags. */ -#define DTD_FLAG_HSYNC_POSITIVE (1 << 1) -#define DTD_FLAG_VSYNC_POSITIVE (1 << 2) -#define DTD_FLAG_INTERLACE (1 << 7) - -/** This matches the EDID DTD structure, more or less */ -struct intel_sdvo_dtd { - struct { - u16 clock; /**< pixel clock, in 10kHz units */ - u8 h_active; /**< lower 8 bits (pixels) */ - u8 h_blank; /**< lower 8 bits (pixels) */ - u8 h_high; /**< upper 4 bits each h_active, h_blank */ - u8 v_active; /**< lower 8 bits (lines) */ - u8 v_blank; /**< lower 8 bits (lines) */ - u8 v_high; /**< upper 4 bits each v_active, v_blank */ - } part1; - - struct { - u8 h_sync_off; /**< lower 8 bits, from hblank start */ - u8 h_sync_width; /**< lower 8 bits (pixels) */ - /** lower 4 bits each vsync offset, vsync width */ - u8 v_sync_off_width; - /** - * 2 high bits of hsync offset, 2 high bits of hsync width, - * bits 4-5 of vsync offset, and 2 high bits of vsync width. - */ - u8 sync_off_width_high; - u8 dtd_flags; - u8 sdvo_flags; - /** bits 6-7 of vsync offset at bits 6-7 */ - u8 v_sync_off_high; - u8 reserved; - } part2; -} __attribute__((packed)); - -struct intel_sdvo_pixel_clock_range { - u16 min; /**< pixel clock, in 10kHz units */ - u16 max; /**< pixel clock, in 10kHz units */ -} __attribute__((packed)); - -struct intel_sdvo_preferred_input_timing_args { - u16 clock; - u16 width; - u16 height; - u8 interlace:1; - u8 scaled:1; - u8 pad:6; -} __attribute__((packed)); - -/* I2C registers for SDVO */ -#define SDVO_I2C_ARG_0 0x07 -#define SDVO_I2C_ARG_1 0x06 -#define SDVO_I2C_ARG_2 0x05 -#define SDVO_I2C_ARG_3 0x04 -#define SDVO_I2C_ARG_4 0x03 -#define SDVO_I2C_ARG_5 0x02 -#define SDVO_I2C_ARG_6 0x01 -#define SDVO_I2C_ARG_7 0x00 -#define SDVO_I2C_OPCODE 0x08 -#define SDVO_I2C_CMD_STATUS 0x09 -#define SDVO_I2C_RETURN_0 0x0a -#define SDVO_I2C_RETURN_1 0x0b -#define SDVO_I2C_RETURN_2 0x0c -#define SDVO_I2C_RETURN_3 0x0d -#define SDVO_I2C_RETURN_4 0x0e -#define SDVO_I2C_RETURN_5 0x0f -#define SDVO_I2C_RETURN_6 0x10 -#define SDVO_I2C_RETURN_7 0x11 -#define SDVO_I2C_VENDOR_BEGIN 0x20 - -/* Status results */ -#define SDVO_CMD_STATUS_POWER_ON 0x0 -#define SDVO_CMD_STATUS_SUCCESS 0x1 -#define SDVO_CMD_STATUS_NOTSUPP 0x2 -#define SDVO_CMD_STATUS_INVALID_ARG 0x3 -#define SDVO_CMD_STATUS_PENDING 0x4 -#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5 -#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6 - -/* SDVO commands, argument/result registers */ - -#define SDVO_CMD_RESET 0x01 - -/** Returns a struct intel_sdvo_caps */ -#define SDVO_CMD_GET_DEVICE_CAPS 0x02 - -#define SDVO_CMD_GET_FIRMWARE_REV 0x86 -# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0 -# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1 -# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2 - -/** - * Reports which inputs are trained (managed to sync). - * - * Devices must have trained within 2 vsyncs of a mode change. - */ -#define SDVO_CMD_GET_TRAINED_INPUTS 0x03 -struct intel_sdvo_get_trained_inputs_response { - unsigned int input0_trained:1; - unsigned int input1_trained:1; - unsigned int pad:6; -} __attribute__((packed)); - -/** Returns a struct intel_sdvo_output_flags of active outputs. */ -#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 - -/** - * Sets the current set of active outputs. - * - * Takes a struct intel_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP - * on multi-output devices. - */ -#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 - -/** - * Returns the current mapping of SDVO inputs to outputs on the device. - * - * Returns two struct intel_sdvo_output_flags structures. - */ -#define SDVO_CMD_GET_IN_OUT_MAP 0x06 -struct intel_sdvo_in_out_map { - u16 in0, in1; -}; - -/** - * Sets the current mapping of SDVO inputs to outputs on the device. - * - * Takes two struct i380_sdvo_output_flags structures. - */ -#define SDVO_CMD_SET_IN_OUT_MAP 0x07 - -/** - * Returns a struct intel_sdvo_output_flags of attached displays. - */ -#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b - -/** - * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging. - */ -#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c - -/** - * Takes a struct intel_sdvo_output_flags. - */ -#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d - -/** - * Returns a struct intel_sdvo_output_flags of displays with hot plug - * interrupts enabled. - */ -#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e - -#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f -struct intel_sdvo_get_interrupt_event_source_response { - u16 interrupt_status; - unsigned int ambient_light_interrupt:1; - unsigned int hdmi_audio_encrypt_change:1; - unsigned int pad:6; -} __attribute__((packed)); - -/** - * Selects which input is affected by future input commands. - * - * Commands affected include SET_INPUT_TIMINGS_PART[12], - * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12], - * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS. - */ -#define SDVO_CMD_SET_TARGET_INPUT 0x10 -struct intel_sdvo_set_target_input_args { - unsigned int target_1:1; - unsigned int pad:7; -} __attribute__((packed)); - -/** - * Takes a struct intel_sdvo_output_flags of which outputs are targeted by - * future output commands. - * - * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], - * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE. - */ -#define SDVO_CMD_SET_TARGET_OUTPUT 0x11 - -#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12 -#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19 -/* Part 1 */ -# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2 -# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3 -# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4 -# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5 -# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6 -# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7 -/* Part 2 */ -# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0 -# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1 -# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2 -# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4 -# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7) -# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5) -# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3) -# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1) -# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5 -# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7) -# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6) -# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6) -# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4) -# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6 - -/** - * Generates a DTD based on the given width, height, and flags. - * - * This will be supported by any device supporting scaling or interlaced - * modes. - */ -#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0) -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1) - -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c - -/** Returns a struct intel_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d -/** Returns a struct intel_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e - -/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ -#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f - -/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20 -/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21 -# define SDVO_CLOCK_RATE_MULT_1X (1 << 0) -# define SDVO_CLOCK_RATE_MULT_2X (1 << 1) -# define SDVO_CLOCK_RATE_MULT_4X (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 -/** 6 bytes of bit flags for TV formats shared by all TV format functions */ -struct intel_sdvo_tv_format { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:3; -} __attribute__((packed)); - -#define SDVO_CMD_GET_TV_FORMAT 0x28 - -#define SDVO_CMD_SET_TV_FORMAT 0x29 - -/** Returns the resolutiosn that can be used with the given TV format */ -#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 -struct intel_sdvo_sdtv_resolution_request { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int pad:5; -} __attribute__((packed)); - -struct intel_sdvo_sdtv_resolution_reply { - unsigned int res_320x200:1; - unsigned int res_320x240:1; - unsigned int res_400x300:1; - unsigned int res_640x350:1; - unsigned int res_640x400:1; - unsigned int res_640x480:1; - unsigned int res_704x480:1; - unsigned int res_704x576:1; - - unsigned int res_720x350:1; - unsigned int res_720x400:1; - unsigned int res_720x480:1; - unsigned int res_720x540:1; - unsigned int res_720x576:1; - unsigned int res_768x576:1; - unsigned int res_800x600:1; - unsigned int res_832x624:1; - - unsigned int res_920x766:1; - unsigned int res_1024x768:1; - unsigned int res_1280x1024:1; - unsigned int pad:5; -} __attribute__((packed)); - -/* Get supported resolution with squire pixel aspect ratio that can be - scaled for the requested HDTV format */ -#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85 - -struct intel_sdvo_hdtv_resolution_request { - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:6; -} __attribute__((packed)); - -struct intel_sdvo_hdtv_resolution_reply { - unsigned int res_640x480:1; - unsigned int res_800x600:1; - unsigned int res_1024x768:1; - unsigned int res_1280x960:1; - unsigned int res_1400x1050:1; - unsigned int res_1600x1200:1; - unsigned int res_1920x1440:1; - unsigned int res_2048x1536:1; - - unsigned int res_2560x1920:1; - unsigned int res_3200x2400:1; - unsigned int res_3840x2880:1; - unsigned int pad1:5; - - unsigned int res_848x480:1; - unsigned int res_1064x600:1; - unsigned int res_1280x720:1; - unsigned int res_1360x768:1; - unsigned int res_1704x960:1; - unsigned int res_1864x1050:1; - unsigned int res_1920x1080:1; - unsigned int res_2128x1200:1; - - unsigned int res_2560x1400:1; - unsigned int res_2728x1536:1; - unsigned int res_3408x1920:1; - unsigned int res_4264x2400:1; - unsigned int res_5120x2880:1; - unsigned int pad2:3; - - unsigned int res_768x480:1; - unsigned int res_960x600:1; - unsigned int res_1152x720:1; - unsigned int res_1124x768:1; - unsigned int res_1536x960:1; - unsigned int res_1680x1050:1; - unsigned int res_1728x1080:1; - unsigned int res_1920x1200:1; - - unsigned int res_2304x1440:1; - unsigned int res_2456x1536:1; - unsigned int res_3072x1920:1; - unsigned int res_3840x2400:1; - unsigned int res_4608x2880:1; - unsigned int pad3:3; - - unsigned int res_1280x1024:1; - unsigned int pad4:7; - - unsigned int res_1280x768:1; - unsigned int pad5:7; -} __attribute__((packed)); - -/* Get supported power state returns info for encoder and monitor, rely on - last SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a -/* Get power state returns info for encoder and monitor, rely on last - SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_POWER_STATE 0x2b -#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b -#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c -# define SDVO_ENCODER_STATE_ON (1 << 0) -# define SDVO_ENCODER_STATE_STANDBY (1 << 1) -# define SDVO_ENCODER_STATE_SUSPEND (1 << 2) -# define SDVO_ENCODER_STATE_OFF (1 << 3) -# define SDVO_MONITOR_STATE_ON (1 << 4) -# define SDVO_MONITOR_STATE_STANDBY (1 << 5) -# define SDVO_MONITOR_STATE_SUSPEND (1 << 6) -# define SDVO_MONITOR_STATE_OFF (1 << 7) - -#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d -#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e -#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f -/** - * The panel power sequencing parameters are in units of milliseconds. - * The high fields are bits 8:9 of the 10-bit values. - */ -struct sdvo_panel_power_sequencing { - u8 t0; - u8 t1; - u8 t2; - u8 t3; - u8 t4; - - unsigned int t0_high:2; - unsigned int t1_high:2; - unsigned int t2_high:2; - unsigned int t3_high:2; - - unsigned int t4_high:2; - unsigned int pad:6; -} __attribute__((packed)); - -#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30 -struct sdvo_max_backlight_reply { - u8 max_value; - u8 default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31 -#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32 - -#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33 -struct sdvo_get_ambient_light_reply { - u16 trip_low; - u16 trip_high; - u16 value; -} __attribute__((packed)); -#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34 -struct sdvo_set_ambient_light_reply { - u16 trip_low; - u16 trip_high; - unsigned int enable:1; - unsigned int pad:7; -} __attribute__((packed)); - -/* Set display power state */ -#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d -# define SDVO_DISPLAY_STATE_ON (1 << 0) -# define SDVO_DISPLAY_STATE_STANDBY (1 << 1) -# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2) -# define SDVO_DISPLAY_STATE_OFF (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 -struct intel_sdvo_enhancements_reply { - unsigned int flicker_filter:1; - unsigned int flicker_filter_adaptive:1; - unsigned int flicker_filter_2d:1; - unsigned int saturation:1; - unsigned int hue:1; - unsigned int brightness:1; - unsigned int contrast:1; - unsigned int overscan_h:1; - - unsigned int overscan_v:1; - unsigned int hpos:1; - unsigned int vpos:1; - unsigned int sharpness:1; - unsigned int dot_crawl:1; - unsigned int dither:1; - unsigned int tv_chroma_filter:1; - unsigned int tv_luma_filter:1; -} __attribute__((packed)); - -/* Picture enhancement limits below are dependent on the current TV format, - * and thus need to be queried and set after it. - */ -#define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d -#define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b -#define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 -#define SDVO_CMD_GET_MAX_SATURATION 0x55 -#define SDVO_CMD_GET_MAX_HUE 0x58 -#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b -#define SDVO_CMD_GET_MAX_CONTRAST 0x5e -#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 -#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 -#define SDVO_CMD_GET_MAX_HPOS 0x67 -#define SDVO_CMD_GET_MAX_VPOS 0x6a -#define SDVO_CMD_GET_MAX_SHARPNESS 0x6d -#define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 -#define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 -struct intel_sdvo_enhancement_limits_reply { - u16 max_value; - u16 default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f -#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80 -# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0) -# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0) -# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2) -# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2) -# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4) -# define SDVO_LVDS_DUAL_CHANNEL (1 << 4) - -#define SDVO_CMD_GET_FLICKER_FILTER 0x4e -#define SDVO_CMD_SET_FLICKER_FILTER 0x4f -#define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 -#define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 -#define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 -#define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 -#define SDVO_CMD_GET_SATURATION 0x56 -#define SDVO_CMD_SET_SATURATION 0x57 -#define SDVO_CMD_GET_HUE 0x59 -#define SDVO_CMD_SET_HUE 0x5a -#define SDVO_CMD_GET_BRIGHTNESS 0x5c -#define SDVO_CMD_SET_BRIGHTNESS 0x5d -#define SDVO_CMD_GET_CONTRAST 0x5f -#define SDVO_CMD_SET_CONTRAST 0x60 -#define SDVO_CMD_GET_OVERSCAN_H 0x62 -#define SDVO_CMD_SET_OVERSCAN_H 0x63 -#define SDVO_CMD_GET_OVERSCAN_V 0x65 -#define SDVO_CMD_SET_OVERSCAN_V 0x66 -#define SDVO_CMD_GET_HPOS 0x68 -#define SDVO_CMD_SET_HPOS 0x69 -#define SDVO_CMD_GET_VPOS 0x6b -#define SDVO_CMD_SET_VPOS 0x6c -#define SDVO_CMD_GET_SHARPNESS 0x6e -#define SDVO_CMD_SET_SHARPNESS 0x6f -#define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 -#define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 -#define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 -#define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 -struct intel_sdvo_enhancements_arg { - u16 value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_DOT_CRAWL 0x70 -#define SDVO_CMD_SET_DOT_CRAWL 0x71 -# define SDVO_DOT_CRAWL_ON (1 << 0) -# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_GET_DITHER 0x72 -#define SDVO_CMD_SET_DITHER 0x73 -# define SDVO_DITHER_ON (1 << 0) -# define SDVO_DITHER_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a -# define SDVO_CONTROL_BUS_PROM (1 << 0) -# define SDVO_CONTROL_BUS_DDC1 (1 << 1) -# define SDVO_CONTROL_BUS_DDC2 (1 << 2) -# define SDVO_CONTROL_BUS_DDC3 (1 << 3) - -/* HDMI op codes */ -#define SDVO_CMD_GET_SUPP_ENCODE 0x9d -#define SDVO_CMD_GET_ENCODE 0x9e -#define SDVO_CMD_SET_ENCODE 0x9f - #define SDVO_ENCODE_DVI 0x0 - #define SDVO_ENCODE_HDMI 0x1 -#define SDVO_CMD_SET_PIXEL_REPLI 0x8b -#define SDVO_CMD_GET_PIXEL_REPLI 0x8c -#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d -#define SDVO_CMD_SET_COLORIMETRY 0x8e - #define SDVO_COLORIMETRY_RGB256 0x0 - #define SDVO_COLORIMETRY_RGB220 0x1 - #define SDVO_COLORIMETRY_YCrCb422 0x3 - #define SDVO_COLORIMETRY_YCrCb444 0x4 -#define SDVO_CMD_GET_COLORIMETRY 0x8f -#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 -#define SDVO_CMD_SET_AUDIO_STAT 0x91 -#define SDVO_CMD_GET_AUDIO_STAT 0x92 -#define SDVO_CMD_SET_HBUF_INDEX 0x93 -#define SDVO_CMD_GET_HBUF_INDEX 0x94 -#define SDVO_CMD_GET_HBUF_INFO 0x95 -#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 -#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 -#define SDVO_CMD_SET_HBUF_DATA 0x98 -#define SDVO_CMD_GET_HBUF_DATA 0x99 -#define SDVO_CMD_SET_HBUF_TXRATE 0x9a -#define SDVO_CMD_GET_HBUF_TXRATE 0x9b - #define SDVO_HBUF_TX_DISABLED (0 << 6) - #define SDVO_HBUF_TX_ONCE (2 << 6) - #define SDVO_HBUF_TX_VSYNC (3 << 6) -#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c -#define SDVO_NEED_TO_STALL (1 << 7) - -struct intel_sdvo_encode { - u8 dvi_rev; - u8 hdmi_rev; -} __attribute__ ((packed)); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sprite.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sprite.c deleted file mode 100644 index e90dfb62..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_sprite.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Jesse Barnes - * - * New plane/sprite handling. - * - * The older chips had a separate interface for programming plane related - * registers; newer ones are much simpler and we can use the new DRM plane - * support. - */ -#include "drmP.h" -#include "drm_crtc.h" -#include "drm_fourcc.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" - -static void -ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane = to_intel_plane(plane); - int pipe = intel_plane->pipe; - u32 sprctl, sprscale = 0; - int pixel_size; - - sprctl = I915_READ(SPRCTL(pipe)); - - /* Mask out pixel format bits in case we change it */ - sprctl &= ~SPRITE_PIXFORMAT_MASK; - sprctl &= ~SPRITE_RGB_ORDER_RGBX; - sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; - - switch (fb->pixel_format) { - case DRM_FORMAT_XBGR8888: - sprctl |= SPRITE_FORMAT_RGBX888; - pixel_size = 4; - break; - case DRM_FORMAT_XRGB8888: - sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; - pixel_size = 4; - break; - case DRM_FORMAT_YUYV: - sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; - pixel_size = 2; - break; - case DRM_FORMAT_YVYU: - sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; - pixel_size = 2; - break; - case DRM_FORMAT_UYVY: - sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; - pixel_size = 2; - break; - case DRM_FORMAT_VYUY: - sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; - pixel_size = 2; - break; - default: - DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); - sprctl |= DVS_FORMAT_RGBX888; - pixel_size = 4; - break; - } - - if (obj->tiling_mode != I915_TILING_NONE) - sprctl |= SPRITE_TILED; - - /* must disable */ - sprctl |= SPRITE_TRICKLE_FEED_DISABLE; - sprctl |= SPRITE_ENABLE; - - /* Sizes are 0 based */ - src_w--; - src_h--; - crtc_w--; - crtc_h--; - - intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); - - /* - * IVB workaround: must disable low power watermarks for at least - * one frame before enabling scaling. LP watermarks can be re-enabled - * when scaling is disabled. - */ - if (crtc_w != src_w || crtc_h != src_h) { - dev_priv->sprite_scaling_enabled = true; - sandybridge_update_wm(dev); - intel_wait_for_vblank(dev, pipe); - sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; - } else { - dev_priv->sprite_scaling_enabled = false; - /* potentially re-enable LP watermarks */ - sandybridge_update_wm(dev); - } - - I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); - I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); - if (obj->tiling_mode != I915_TILING_NONE) { - I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); - } else { - unsigned long offset; - - offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); - I915_WRITE(SPRLINOFF(pipe), offset); - } - I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); - I915_WRITE(SPRSCALE(pipe), sprscale); - I915_WRITE(SPRCTL(pipe), sprctl); - I915_WRITE(SPRSURF(pipe), obj->gtt_offset); - POSTING_READ(SPRSURF(pipe)); -} - -static void -ivb_disable_plane(struct drm_plane *plane) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane = to_intel_plane(plane); - int pipe = intel_plane->pipe; - - I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); - /* Can't leave the scaler enabled... */ - I915_WRITE(SPRSCALE(pipe), 0); - /* Activate double buffered register update */ - I915_WRITE(SPRSURF(pipe), 0); - POSTING_READ(SPRSURF(pipe)); -} - -static int -ivb_update_colorkey(struct drm_plane *plane, - struct drm_intel_sprite_colorkey *key) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane; - u32 sprctl; - int ret = 0; - - intel_plane = to_intel_plane(plane); - - I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); - I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); - I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); - - sprctl = I915_READ(SPRCTL(intel_plane->pipe)); - sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); - if (key->flags & I915_SET_COLORKEY_DESTINATION) - sprctl |= SPRITE_DEST_KEY; - else if (key->flags & I915_SET_COLORKEY_SOURCE) - sprctl |= SPRITE_SOURCE_KEY; - I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); - - POSTING_READ(SPRKEYMSK(intel_plane->pipe)); - - return ret; -} - -static void -ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane; - u32 sprctl; - - intel_plane = to_intel_plane(plane); - - key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe)); - key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe)); - key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe)); - key->flags = 0; - - sprctl = I915_READ(SPRCTL(intel_plane->pipe)); - - if (sprctl & SPRITE_DEST_KEY) - key->flags = I915_SET_COLORKEY_DESTINATION; - else if (sprctl & SPRITE_SOURCE_KEY) - key->flags = I915_SET_COLORKEY_SOURCE; - else - key->flags = I915_SET_COLORKEY_NONE; -} - -static void -snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, - struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t x, uint32_t y, - uint32_t src_w, uint32_t src_h) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane = to_intel_plane(plane); - int pipe = intel_plane->pipe, pixel_size; - u32 dvscntr, dvsscale = 0; - - dvscntr = I915_READ(DVSCNTR(pipe)); - - /* Mask out pixel format bits in case we change it */ - dvscntr &= ~DVS_PIXFORMAT_MASK; - dvscntr &= ~DVS_RGB_ORDER_XBGR; - dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; - - switch (fb->pixel_format) { - case DRM_FORMAT_XBGR8888: - dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; - pixel_size = 4; - break; - case DRM_FORMAT_XRGB8888: - dvscntr |= DVS_FORMAT_RGBX888; - pixel_size = 4; - break; - case DRM_FORMAT_YUYV: - dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; - pixel_size = 2; - break; - case DRM_FORMAT_YVYU: - dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; - pixel_size = 2; - break; - case DRM_FORMAT_UYVY: - dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; - pixel_size = 2; - break; - case DRM_FORMAT_VYUY: - dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; - pixel_size = 2; - break; - default: - DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); - dvscntr |= DVS_FORMAT_RGBX888; - pixel_size = 4; - break; - } - - if (obj->tiling_mode != I915_TILING_NONE) - dvscntr |= DVS_TILED; - - /* must disable */ - dvscntr |= DVS_TRICKLE_FEED_DISABLE; - dvscntr |= DVS_ENABLE; - - /* Sizes are 0 based */ - src_w--; - src_h--; - crtc_w--; - crtc_h--; - - intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); - - if (crtc_w != src_w || crtc_h != src_h) - dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; - - I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); - I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); - if (obj->tiling_mode != I915_TILING_NONE) { - I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); - } else { - unsigned long offset; - - offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8); - I915_WRITE(DVSLINOFF(pipe), offset); - } - I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); - I915_WRITE(DVSSCALE(pipe), dvsscale); - I915_WRITE(DVSCNTR(pipe), dvscntr); - I915_WRITE(DVSSURF(pipe), obj->gtt_offset); - POSTING_READ(DVSSURF(pipe)); -} - -static void -snb_disable_plane(struct drm_plane *plane) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane = to_intel_plane(plane); - int pipe = intel_plane->pipe; - - I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); - /* Disable the scaler */ - I915_WRITE(DVSSCALE(pipe), 0); - /* Flush double buffered register updates */ - I915_WRITE(DVSSURF(pipe), 0); - POSTING_READ(DVSSURF(pipe)); -} - -static void -intel_enable_primary(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int reg = DSPCNTR(intel_crtc->plane); - - I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); -} - -static void -intel_disable_primary(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int reg = DSPCNTR(intel_crtc->plane); - - I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); -} - -static int -snb_update_colorkey(struct drm_plane *plane, - struct drm_intel_sprite_colorkey *key) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane; - u32 dvscntr; - int ret = 0; - - intel_plane = to_intel_plane(plane); - - I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); - I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); - I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); - - dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); - dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY); - if (key->flags & I915_SET_COLORKEY_DESTINATION) - dvscntr |= DVS_DEST_KEY; - else if (key->flags & I915_SET_COLORKEY_SOURCE) - dvscntr |= DVS_SOURCE_KEY; - I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); - - POSTING_READ(DVSKEYMSK(intel_plane->pipe)); - - return ret; -} - -static void -snb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane; - u32 dvscntr; - - intel_plane = to_intel_plane(plane); - - key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe)); - key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe)); - key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe)); - key->flags = 0; - - dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); - - if (dvscntr & DVS_DEST_KEY) - key->flags = I915_SET_COLORKEY_DESTINATION; - else if (dvscntr & DVS_SOURCE_KEY) - key->flags = I915_SET_COLORKEY_SOURCE; - else - key->flags = I915_SET_COLORKEY_NONE; -} - -static int -intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) -{ - struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_plane *intel_plane = to_intel_plane(plane); - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj, *old_obj; - int pipe = intel_plane->pipe; - int ret = 0; - int x = src_x >> 16, y = src_y >> 16; - int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay; - bool disable_primary = false; - - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - - old_obj = intel_plane->obj; - - src_w = src_w >> 16; - src_h = src_h >> 16; - - /* Pipe must be running... */ - if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE)) - return -EINVAL; - - if (crtc_x >= primary_w || crtc_y >= primary_h) - return -EINVAL; - - /* Don't modify another pipe's plane */ - if (intel_plane->pipe != intel_crtc->pipe) - return -EINVAL; - - /* - * Clamp the width & height into the visible area. Note we don't - * try to scale the source if part of the visible region is offscreen. - * The caller must handle that by adjusting source offset and size. - */ - if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) { - crtc_w += crtc_x; - crtc_x = 0; - } - if ((crtc_x + crtc_w) <= 0) /* Nothing to display */ - goto out; - if ((crtc_x + crtc_w) > primary_w) - crtc_w = primary_w - crtc_x; - - if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) { - crtc_h += crtc_y; - crtc_y = 0; - } - if ((crtc_y + crtc_h) <= 0) /* Nothing to display */ - goto out; - if (crtc_y + crtc_h > primary_h) - crtc_h = primary_h - crtc_y; - - if (!crtc_w || !crtc_h) /* Again, nothing to display */ - goto out; - - /* - * We can take a larger source and scale it down, but - * only so much... 16x is the max on SNB. - */ - if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale) - return -EINVAL; - - /* - * If the sprite is completely covering the primary plane, - * we can disable the primary and save power. - */ - if ((crtc_x == 0) && (crtc_y == 0) && - (crtc_w == primary_w) && (crtc_h == primary_h)) - disable_primary = true; - - mutex_lock(&dev->struct_mutex); - - ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - if (ret) - goto out_unlock; - - intel_plane->obj = obj; - - /* - * Be sure to re-enable the primary before the sprite is no longer - * covering it fully. - */ - if (!disable_primary && intel_plane->primary_disabled) { - intel_enable_primary(crtc); - intel_plane->primary_disabled = false; - } - - intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, - crtc_w, crtc_h, x, y, src_w, src_h); - - if (disable_primary) { - intel_disable_primary(crtc); - intel_plane->primary_disabled = true; - } - - /* Unpin old obj after new one is active to avoid ugliness */ - if (old_obj) { - /* - * It's fairly common to simply update the position of - * an existing object. In that case, we don't need to - * wait for vblank to avoid ugliness, we only need to - * do the pin & ref bookkeeping. - */ - if (old_obj != obj) { - mutex_unlock(&dev->struct_mutex); - intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); - mutex_lock(&dev->struct_mutex); - } - intel_unpin_fb_obj(old_obj); - } - -out_unlock: - mutex_unlock(&dev->struct_mutex); -out: - return ret; -} - -static int -intel_disable_plane(struct drm_plane *plane) -{ - struct drm_device *dev = plane->dev; - struct intel_plane *intel_plane = to_intel_plane(plane); - int ret = 0; - - if (intel_plane->primary_disabled) { - intel_enable_primary(plane->crtc); - intel_plane->primary_disabled = false; - } - - intel_plane->disable_plane(plane); - - if (!intel_plane->obj) - goto out; - - mutex_lock(&dev->struct_mutex); - intel_unpin_fb_obj(intel_plane->obj); - intel_plane->obj = NULL; - mutex_unlock(&dev->struct_mutex); -out: - - return ret; -} - -static void intel_destroy_plane(struct drm_plane *plane) -{ - struct intel_plane *intel_plane = to_intel_plane(plane); - intel_disable_plane(plane); - drm_plane_cleanup(plane); - kfree(intel_plane); -} - -int intel_sprite_set_colorkey(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_intel_sprite_colorkey *set = data; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_object *obj; - struct drm_plane *plane; - struct intel_plane *intel_plane; - int ret = 0; - - if (!dev_priv) - return -EINVAL; - - /* Make sure we don't try to enable both src & dest simultaneously */ - if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); - if (!obj) { - ret = -EINVAL; - goto out_unlock; - } - - plane = obj_to_plane(obj); - intel_plane = to_intel_plane(plane); - ret = intel_plane->update_colorkey(plane, set); - -out_unlock: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -int intel_sprite_get_colorkey(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_intel_sprite_colorkey *get = data; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_object *obj; - struct drm_plane *plane; - struct intel_plane *intel_plane; - int ret = 0; - - if (!dev_priv) - return -EINVAL; - - mutex_lock(&dev->mode_config.mutex); - - obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); - if (!obj) { - ret = -EINVAL; - goto out_unlock; - } - - plane = obj_to_plane(obj); - intel_plane = to_intel_plane(plane); - intel_plane->get_colorkey(plane, get); - -out_unlock: - mutex_unlock(&dev->mode_config.mutex); - return ret; -} - -static const struct drm_plane_funcs intel_plane_funcs = { - .update_plane = intel_update_plane, - .disable_plane = intel_disable_plane, - .destroy = intel_destroy_plane, -}; - -static uint32_t snb_plane_formats[] = { - DRM_FORMAT_XBGR8888, - DRM_FORMAT_XRGB8888, - DRM_FORMAT_YUYV, - DRM_FORMAT_YVYU, - DRM_FORMAT_UYVY, - DRM_FORMAT_VYUY, -}; - -int -intel_plane_init(struct drm_device *dev, enum pipe pipe) -{ - struct intel_plane *intel_plane; - unsigned long possible_crtcs; - int ret; - - if (!(IS_GEN6(dev) || IS_GEN7(dev))) - return -ENODEV; - - intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); - if (!intel_plane) - return -ENOMEM; - - if (IS_GEN6(dev)) { - intel_plane->max_downscale = 16; - intel_plane->update_plane = snb_update_plane; - intel_plane->disable_plane = snb_disable_plane; - intel_plane->update_colorkey = snb_update_colorkey; - intel_plane->get_colorkey = snb_get_colorkey; - } else if (IS_GEN7(dev)) { - intel_plane->max_downscale = 2; - intel_plane->update_plane = ivb_update_plane; - intel_plane->disable_plane = ivb_disable_plane; - intel_plane->update_colorkey = ivb_update_colorkey; - intel_plane->get_colorkey = ivb_get_colorkey; - } - - intel_plane->pipe = pipe; - possible_crtcs = (1 << pipe); - ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, - &intel_plane_funcs, snb_plane_formats, - ARRAY_SIZE(snb_plane_formats), false); - if (ret) - kfree(intel_plane); - - return ret; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_tv.c b/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_tv.c deleted file mode 100644 index c82b1d4f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/i915/intel_tv.c +++ /dev/null @@ -1,1662 +0,0 @@ -/* - * Copyright © 2006-2008 Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -/** @file - * Integrated TV-out support for the 915GM and 945GM. - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_edid.h" -#include "intel_drv.h" -#include "i915_drm.h" -#include "i915_drv.h" - -enum tv_margin { - TV_MARGIN_LEFT, TV_MARGIN_TOP, - TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM -}; - -/** Private structure for the integrated TV support */ -struct intel_tv { - struct intel_encoder base; - - int type; - const char *tv_format; - int margin[4]; - u32 save_TV_H_CTL_1; - u32 save_TV_H_CTL_2; - u32 save_TV_H_CTL_3; - u32 save_TV_V_CTL_1; - u32 save_TV_V_CTL_2; - u32 save_TV_V_CTL_3; - u32 save_TV_V_CTL_4; - u32 save_TV_V_CTL_5; - u32 save_TV_V_CTL_6; - u32 save_TV_V_CTL_7; - u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3; - - u32 save_TV_CSC_Y; - u32 save_TV_CSC_Y2; - u32 save_TV_CSC_U; - u32 save_TV_CSC_U2; - u32 save_TV_CSC_V; - u32 save_TV_CSC_V2; - u32 save_TV_CLR_KNOBS; - u32 save_TV_CLR_LEVEL; - u32 save_TV_WIN_POS; - u32 save_TV_WIN_SIZE; - u32 save_TV_FILTER_CTL_1; - u32 save_TV_FILTER_CTL_2; - u32 save_TV_FILTER_CTL_3; - - u32 save_TV_H_LUMA[60]; - u32 save_TV_H_CHROMA[60]; - u32 save_TV_V_LUMA[43]; - u32 save_TV_V_CHROMA[43]; - - u32 save_TV_DAC; - u32 save_TV_CTL; -}; - -struct video_levels { - int blank, black, burst; -}; - -struct color_conversion { - u16 ry, gy, by, ay; - u16 ru, gu, bu, au; - u16 rv, gv, bv, av; -}; - -static const u32 filter_table[] = { - 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, - 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, - 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, - 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, - 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, - 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, - 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, - 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, - 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, - 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, - 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, - 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, - 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, - 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, - 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, - 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, - 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, - 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, - 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, - 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, - 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, - 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, - 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, - 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, - 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, - 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, - 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, - 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, - 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, - 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, - 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0, - 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, - 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, - 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, - 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, - 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, - 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, - 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, - 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, - 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, - 0x28003100, 0x28002F00, 0x00003100, 0x36403000, - 0x2D002CC0, 0x30003640, 0x2D0036C0, - 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, - 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, - 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, - 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, - 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, - 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, - 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, - 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, - 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, - 0x28003100, 0x28002F00, 0x00003100, -}; - -/* - * Color conversion values have 3 separate fixed point formats: - * - * 10 bit fields (ay, au) - * 1.9 fixed point (b.bbbbbbbbb) - * 11 bit fields (ry, by, ru, gu, gv) - * exp.mantissa (ee.mmmmmmmmm) - * ee = 00 = 10^-1 (0.mmmmmmmmm) - * ee = 01 = 10^-2 (0.0mmmmmmmmm) - * ee = 10 = 10^-3 (0.00mmmmmmmmm) - * ee = 11 = 10^-4 (0.000mmmmmmmmm) - * 12 bit fields (gy, rv, bu) - * exp.mantissa (eee.mmmmmmmmm) - * eee = 000 = 10^-1 (0.mmmmmmmmm) - * eee = 001 = 10^-2 (0.0mmmmmmmmm) - * eee = 010 = 10^-3 (0.00mmmmmmmmm) - * eee = 011 = 10^-4 (0.000mmmmmmmmm) - * eee = 100 = reserved - * eee = 101 = reserved - * eee = 110 = reserved - * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation) - * - * Saturation and contrast are 8 bits, with their own representation: - * 8 bit field (saturation, contrast) - * exp.mantissa (ee.mmmmmm) - * ee = 00 = 10^-1 (0.mmmmmm) - * ee = 01 = 10^0 (m.mmmmm) - * ee = 10 = 10^1 (mm.mmmm) - * ee = 11 = 10^2 (mmm.mmm) - * - * Simple conversion function: - * - * static u32 - * float_to_csc_11(float f) - * { - * u32 exp; - * u32 mant; - * u32 ret; - * - * if (f < 0) - * f = -f; - * - * if (f >= 1) { - * exp = 0x7; - * mant = 1 << 8; - * } else { - * for (exp = 0; exp < 3 && f < 0.5; exp++) - * f *= 2.0; - * mant = (f * (1 << 9) + 0.5); - * if (mant >= (1 << 9)) - * mant = (1 << 9) - 1; - * } - * ret = (exp << 9) | mant; - * return ret; - * } - */ - -/* - * Behold, magic numbers! If we plant them they might grow a big - * s-video cable to the sky... or something. - * - * Pre-converted to appropriate hex value. - */ - -/* - * PAL & NTSC values for composite & s-video connections - */ -static const struct color_conversion ntsc_m_csc_composite = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, - .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, - .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, -}; - -static const struct video_levels ntsc_m_levels_composite = { - .blank = 225, .black = 267, .burst = 113, -}; - -static const struct color_conversion ntsc_m_csc_svideo = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, - .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, - .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, -}; - -static const struct video_levels ntsc_m_levels_svideo = { - .blank = 266, .black = 316, .burst = 133, -}; - -static const struct color_conversion ntsc_j_csc_composite = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119, - .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200, - .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200, -}; - -static const struct video_levels ntsc_j_levels_composite = { - .blank = 225, .black = 225, .burst = 113, -}; - -static const struct color_conversion ntsc_j_csc_svideo = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c, - .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200, - .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200, -}; - -static const struct video_levels ntsc_j_levels_svideo = { - .blank = 266, .black = 266, .burst = 133, -}; - -static const struct color_conversion pal_csc_composite = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113, - .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200, - .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200, -}; - -static const struct video_levels pal_levels_composite = { - .blank = 237, .black = 237, .burst = 118, -}; - -static const struct color_conversion pal_csc_svideo = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, - .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200, - .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200, -}; - -static const struct video_levels pal_levels_svideo = { - .blank = 280, .black = 280, .burst = 139, -}; - -static const struct color_conversion pal_m_csc_composite = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, - .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, - .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, -}; - -static const struct video_levels pal_m_levels_composite = { - .blank = 225, .black = 267, .burst = 113, -}; - -static const struct color_conversion pal_m_csc_svideo = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, - .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, - .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, -}; - -static const struct video_levels pal_m_levels_svideo = { - .blank = 266, .black = 316, .burst = 133, -}; - -static const struct color_conversion pal_n_csc_composite = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104, - .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200, - .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200, -}; - -static const struct video_levels pal_n_levels_composite = { - .blank = 225, .black = 267, .burst = 118, -}; - -static const struct color_conversion pal_n_csc_svideo = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133, - .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200, - .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200, -}; - -static const struct video_levels pal_n_levels_svideo = { - .blank = 266, .black = 316, .burst = 139, -}; - -/* - * Component connections - */ -static const struct color_conversion sdtv_csc_yprpb = { - .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145, - .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200, - .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200, -}; - -static const struct color_conversion sdtv_csc_rgb = { - .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166, - .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166, - .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166, -}; - -static const struct color_conversion hdtv_csc_yprpb = { - .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145, - .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200, - .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200, -}; - -static const struct color_conversion hdtv_csc_rgb = { - .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166, - .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166, - .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166, -}; - -static const struct video_levels component_levels = { - .blank = 279, .black = 279, .burst = 0, -}; - - -struct tv_mode { - const char *name; - int clock; - int refresh; /* in millihertz (for precision) */ - u32 oversample; - int hsync_end, hblank_start, hblank_end, htotal; - bool progressive, trilevel_sync, component_only; - int vsync_start_f1, vsync_start_f2, vsync_len; - bool veq_ena; - int veq_start_f1, veq_start_f2, veq_len; - int vi_end_f1, vi_end_f2, nbr_end; - bool burst_ena; - int hburst_start, hburst_len; - int vburst_start_f1, vburst_end_f1; - int vburst_start_f2, vburst_end_f2; - int vburst_start_f3, vburst_end_f3; - int vburst_start_f4, vburst_end_f4; - /* - * subcarrier programming - */ - int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc; - u32 sc_reset; - bool pal_burst; - /* - * blank/black levels - */ - const struct video_levels *composite_levels, *svideo_levels; - const struct color_conversion *composite_color, *svideo_color; - const u32 *filter_table; - int max_srcw; -}; - - -/* - * Sub carrier DDA - * - * I think this works as follows: - * - * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096 - * - * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value - * - * So, - * dda1_ideal = subcarrier/pixel * 4096 - * dda1_inc = floor (dda1_ideal) - * dda2 = dda1_ideal - dda1_inc - * - * then pick a ratio for dda2 that gives the closest approximation. If - * you can't get close enough, you can play with dda3 as well. This - * seems likely to happen when dda2 is small as the jumps would be larger - * - * To invert this, - * - * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size) - * - * The constants below were all computed using a 107.520MHz clock - */ - -/** - * Register programming values for TV modes. - * - * These values account for -1s required. - */ - -static const struct tv_mode tv_modes[] = { - { - .name = "NTSC-M", - .clock = 108000, - .refresh = 59940, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ - - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = false, .trilevel_sync = false, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = true, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = true, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 3.5800000 actual 3.5800000 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 20800, .dda2_size = 27456, - .dda3_inc = 0, .dda3_size = 0, - .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = false, - - .composite_levels = &ntsc_m_levels_composite, - .composite_color = &ntsc_m_csc_composite, - .svideo_levels = &ntsc_m_levels_svideo, - .svideo_color = &ntsc_m_csc_svideo, - - .filter_table = filter_table, - }, - { - .name = "NTSC-443", - .clock = 108000, - .refresh = 59940, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = false, .trilevel_sync = false, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = true, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = true, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 4.4336180 actual 4.4336180 clock 107.52 */ - .dda1_inc = 168, - .dda2_inc = 4093, .dda2_size = 27456, - .dda3_inc = 310, .dda3_size = 525, - .sc_reset = TV_SC_RESET_NEVER, - .pal_burst = false, - - .composite_levels = &ntsc_m_levels_composite, - .composite_color = &ntsc_m_csc_composite, - .svideo_levels = &ntsc_m_levels_svideo, - .svideo_color = &ntsc_m_csc_svideo, - - .filter_table = filter_table, - }, - { - .name = "NTSC-J", - .clock = 108000, - .refresh = 59940, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = false, .trilevel_sync = false, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = true, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = true, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 3.5800000 actual 3.5800000 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 20800, .dda2_size = 27456, - .dda3_inc = 0, .dda3_size = 0, - .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = false, - - .composite_levels = &ntsc_j_levels_composite, - .composite_color = &ntsc_j_csc_composite, - .svideo_levels = &ntsc_j_levels_svideo, - .svideo_color = &ntsc_j_csc_svideo, - - .filter_table = filter_table, - }, - { - .name = "PAL-M", - .clock = 108000, - .refresh = 59940, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = false, .trilevel_sync = false, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = true, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = true, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 3.5800000 actual 3.5800000 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 16704, .dda2_size = 27456, - .dda3_inc = 0, .dda3_size = 0, - .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = true, - - .composite_levels = &pal_m_levels_composite, - .composite_color = &pal_m_csc_composite, - .svideo_levels = &pal_m_levels_svideo, - .svideo_color = &pal_m_csc_svideo, - - .filter_table = filter_table, - }, - { - /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ - .name = "PAL-N", - .clock = 108000, - .refresh = 50000, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - .hsync_end = 64, .hblank_end = 128, - .hblank_start = 844, .htotal = 863, - - .progressive = false, .trilevel_sync = false, - - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = true, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 24, .vi_end_f2 = 25, - .nbr_end = 286, - - .burst_ena = true, - .hburst_start = 73, .hburst_len = 34, - .vburst_start_f1 = 8, .vburst_end_f1 = 285, - .vburst_start_f2 = 8, .vburst_end_f2 = 286, - .vburst_start_f3 = 9, .vburst_end_f3 = 286, - .vburst_start_f4 = 9, .vburst_end_f4 = 285, - - - /* desired 4.4336180 actual 4.4336180 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 23578, .dda2_size = 27648, - .dda3_inc = 134, .dda3_size = 625, - .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = true, - - .composite_levels = &pal_n_levels_composite, - .composite_color = &pal_n_csc_composite, - .svideo_levels = &pal_n_levels_svideo, - .svideo_color = &pal_n_csc_svideo, - - .filter_table = filter_table, - }, - { - /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ - .name = "PAL", - .clock = 108000, - .refresh = 50000, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - .hsync_end = 64, .hblank_end = 142, - .hblank_start = 844, .htotal = 863, - - .progressive = false, .trilevel_sync = false, - - .vsync_start_f1 = 5, .vsync_start_f2 = 6, - .vsync_len = 5, - - .veq_ena = true, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 15, - - .vi_end_f1 = 24, .vi_end_f2 = 25, - .nbr_end = 286, - - .burst_ena = true, - .hburst_start = 73, .hburst_len = 32, - .vburst_start_f1 = 8, .vburst_end_f1 = 285, - .vburst_start_f2 = 8, .vburst_end_f2 = 286, - .vburst_start_f3 = 9, .vburst_end_f3 = 286, - .vburst_start_f4 = 9, .vburst_end_f4 = 285, - - /* desired 4.4336180 actual 4.4336180 clock 107.52 */ - .dda1_inc = 168, - .dda2_inc = 4122, .dda2_size = 27648, - .dda3_inc = 67, .dda3_size = 625, - .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = true, - - .composite_levels = &pal_levels_composite, - .composite_color = &pal_csc_composite, - .svideo_levels = &pal_levels_svideo, - .svideo_color = &pal_csc_svideo, - - .filter_table = filter_table, - }, - { - .name = "480p", - .clock = 107520, - .refresh = 59940, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 122, - .hblank_start = 842, .htotal = 857, - - .progressive = true, .trilevel_sync = false, - - .vsync_start_f1 = 12, .vsync_start_f2 = 12, - .vsync_len = 12, - - .veq_ena = false, - - .vi_end_f1 = 44, .vi_end_f2 = 44, - .nbr_end = 479, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { - .name = "576p", - .clock = 107520, - .refresh = 50000, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 139, - .hblank_start = 859, .htotal = 863, - - .progressive = true, .trilevel_sync = false, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = false, - - .vi_end_f1 = 48, .vi_end_f2 = 48, - .nbr_end = 575, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { - .name = "720p@60Hz", - .clock = 148800, - .refresh = 60000, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 80, .hblank_end = 300, - .hblank_start = 1580, .htotal = 1649, - - .progressive = true, .trilevel_sync = true, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = false, - - .vi_end_f1 = 29, .vi_end_f2 = 29, - .nbr_end = 719, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { - .name = "720p@50Hz", - .clock = 148800, - .refresh = 50000, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 80, .hblank_end = 300, - .hblank_start = 1580, .htotal = 1979, - - .progressive = true, .trilevel_sync = true, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = false, - - .vi_end_f1 = 29, .vi_end_f2 = 29, - .nbr_end = 719, - - .burst_ena = false, - - .filter_table = filter_table, - .max_srcw = 800 - }, - { - .name = "1080i@50Hz", - .clock = 148800, - .refresh = 50000, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 88, .hblank_end = 235, - .hblank_start = 2155, .htotal = 2639, - - .progressive = false, .trilevel_sync = true, - - .vsync_start_f1 = 4, .vsync_start_f2 = 5, - .vsync_len = 10, - - .veq_ena = true, .veq_start_f1 = 4, - .veq_start_f2 = 4, .veq_len = 10, - - - .vi_end_f1 = 21, .vi_end_f2 = 22, - .nbr_end = 539, - - .burst_ena = false, - - .filter_table = filter_table, - }, - { - .name = "1080i@60Hz", - .clock = 148800, - .refresh = 60000, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 88, .hblank_end = 235, - .hblank_start = 2155, .htotal = 2199, - - .progressive = false, .trilevel_sync = true, - - .vsync_start_f1 = 4, .vsync_start_f2 = 5, - .vsync_len = 10, - - .veq_ena = true, .veq_start_f1 = 4, - .veq_start_f2 = 4, .veq_len = 10, - - - .vi_end_f1 = 21, .vi_end_f2 = 22, - .nbr_end = 539, - - .burst_ena = false, - - .filter_table = filter_table, - }, -}; - -static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) -{ - return container_of(encoder, struct intel_tv, base.base); -} - -static struct intel_tv *intel_attached_tv(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_tv, - base); -} - -static void -intel_tv_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - switch (mode) { - case DRM_MODE_DPMS_ON: - I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); - break; - } -} - -static const struct tv_mode * -intel_tv_mode_lookup(const char *tv_format) -{ - int i; - - for (i = 0; i < sizeof(tv_modes) / sizeof(tv_modes[0]); i++) { - const struct tv_mode *tv_mode = &tv_modes[i]; - - if (!strcmp(tv_format, tv_mode->name)) - return tv_mode; - } - return NULL; -} - -static const struct tv_mode * -intel_tv_mode_find(struct intel_tv *intel_tv) -{ - return intel_tv_mode_lookup(intel_tv->tv_format); -} - -static enum drm_mode_status -intel_tv_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct intel_tv *intel_tv = intel_attached_tv(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); - - /* Ensure TV refresh is close to desired refresh */ - if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) - < 1000) - return MODE_OK; - - return MODE_CLOCK_RANGE; -} - - -static bool -intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_mode_config *drm_config = &dev->mode_config; - struct intel_tv *intel_tv = enc_to_intel_tv(encoder); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); - struct drm_encoder *other_encoder; - - if (!tv_mode) - return false; - - /* FIXME: lock encoder list */ - list_for_each_entry(other_encoder, &drm_config->encoder_list, head) { - if (other_encoder != encoder && - other_encoder->crtc == encoder->crtc) - return false; - } - - adjusted_mode->clock = tv_mode->clock; - return true; -} - -static void -intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_tv *intel_tv = enc_to_intel_tv(encoder); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); - u32 tv_ctl; - u32 hctl1, hctl2, hctl3; - u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; - u32 scctl1, scctl2, scctl3; - int i, j; - const struct video_levels *video_levels; - const struct color_conversion *color_conversion; - bool burst_ena; - int pipe = intel_crtc->pipe; - - if (!tv_mode) - return; /* can't happen (mode_prepare prevents this) */ - - tv_ctl = I915_READ(TV_CTL); - tv_ctl &= TV_CTL_SAVE; - - switch (intel_tv->type) { - default: - case DRM_MODE_CONNECTOR_Unknown: - case DRM_MODE_CONNECTOR_Composite: - tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; - video_levels = tv_mode->composite_levels; - color_conversion = tv_mode->composite_color; - burst_ena = tv_mode->burst_ena; - break; - case DRM_MODE_CONNECTOR_Component: - tv_ctl |= TV_ENC_OUTPUT_COMPONENT; - video_levels = &component_levels; - if (tv_mode->burst_ena) - color_conversion = &sdtv_csc_yprpb; - else - color_conversion = &hdtv_csc_yprpb; - burst_ena = false; - break; - case DRM_MODE_CONNECTOR_SVIDEO: - tv_ctl |= TV_ENC_OUTPUT_SVIDEO; - video_levels = tv_mode->svideo_levels; - color_conversion = tv_mode->svideo_color; - burst_ena = tv_mode->burst_ena; - break; - } - hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) | - (tv_mode->htotal << TV_HTOTAL_SHIFT); - - hctl2 = (tv_mode->hburst_start << 16) | - (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT); - - if (burst_ena) - hctl2 |= TV_BURST_ENA; - - hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) | - (tv_mode->hblank_end << TV_HBLANK_END_SHIFT); - - vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) | - (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) | - (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT); - - vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) | - (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) | - (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT); - - vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) | - (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) | - (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT); - - if (tv_mode->veq_ena) - vctl3 |= TV_EQUAL_ENA; - - vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) | - (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT); - - vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) | - (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT); - - vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) | - (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT); - - vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) | - (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT); - - if (intel_crtc->pipe == 1) - tv_ctl |= TV_ENC_PIPEB_SELECT; - tv_ctl |= tv_mode->oversample; - - if (tv_mode->progressive) - tv_ctl |= TV_PROGRESSIVE; - if (tv_mode->trilevel_sync) - tv_ctl |= TV_TRILEVEL_SYNC; - if (tv_mode->pal_burst) - tv_ctl |= TV_PAL_BURST; - - scctl1 = 0; - if (tv_mode->dda1_inc) - scctl1 |= TV_SC_DDA1_EN; - if (tv_mode->dda2_inc) - scctl1 |= TV_SC_DDA2_EN; - if (tv_mode->dda3_inc) - scctl1 |= TV_SC_DDA3_EN; - scctl1 |= tv_mode->sc_reset; - if (video_levels) - scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; - scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; - - scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | - tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT; - - scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT | - tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT; - - /* Enable two fixes for the chips that need them. */ - if (dev->pci_device < 0x2772) - tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX; - - I915_WRITE(TV_H_CTL_1, hctl1); - I915_WRITE(TV_H_CTL_2, hctl2); - I915_WRITE(TV_H_CTL_3, hctl3); - I915_WRITE(TV_V_CTL_1, vctl1); - I915_WRITE(TV_V_CTL_2, vctl2); - I915_WRITE(TV_V_CTL_3, vctl3); - I915_WRITE(TV_V_CTL_4, vctl4); - I915_WRITE(TV_V_CTL_5, vctl5); - I915_WRITE(TV_V_CTL_6, vctl6); - I915_WRITE(TV_V_CTL_7, vctl7); - I915_WRITE(TV_SC_CTL_1, scctl1); - I915_WRITE(TV_SC_CTL_2, scctl2); - I915_WRITE(TV_SC_CTL_3, scctl3); - - if (color_conversion) { - I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) | - color_conversion->gy); - I915_WRITE(TV_CSC_Y2, (color_conversion->by << 16) | - color_conversion->ay); - I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) | - color_conversion->gu); - I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) | - color_conversion->au); - I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) | - color_conversion->gv); - I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) | - color_conversion->av); - } - - if (INTEL_INFO(dev)->gen >= 4) - I915_WRITE(TV_CLR_KNOBS, 0x00404000); - else - I915_WRITE(TV_CLR_KNOBS, 0x00606000); - - if (video_levels) - I915_WRITE(TV_CLR_LEVEL, - ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | - (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); - { - int pipeconf_reg = PIPECONF(pipe); - int dspcntr_reg = DSPCNTR(intel_crtc->plane); - int pipeconf = I915_READ(pipeconf_reg); - int dspcntr = I915_READ(dspcntr_reg); - int dspbase_reg = DSPADDR(intel_crtc->plane); - int xpos = 0x0, ypos = 0x0; - unsigned int xsize, ysize; - /* Pipe must be off here */ - I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); - - /* Wait for vblank for the disable to take effect */ - if (IS_GEN2(dev)) - intel_wait_for_vblank(dev, intel_crtc->pipe); - - I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE); - /* Wait for vblank for the disable to take effect. */ - intel_wait_for_pipe_off(dev, intel_crtc->pipe); - - /* Filter ctl must be set before TV_WIN_SIZE */ - I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); - xsize = tv_mode->hblank_start - tv_mode->hblank_end; - if (tv_mode->progressive) - ysize = tv_mode->nbr_end + 1; - else - ysize = 2*tv_mode->nbr_end + 1; - - xpos += intel_tv->margin[TV_MARGIN_LEFT]; - ypos += intel_tv->margin[TV_MARGIN_TOP]; - xsize -= (intel_tv->margin[TV_MARGIN_LEFT] + - intel_tv->margin[TV_MARGIN_RIGHT]); - ysize -= (intel_tv->margin[TV_MARGIN_TOP] + - intel_tv->margin[TV_MARGIN_BOTTOM]); - I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); - I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); - - I915_WRITE(pipeconf_reg, pipeconf); - I915_WRITE(dspcntr_reg, dspcntr); - /* Flush the plane changes */ - I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); - } - - j = 0; - for (i = 0; i < 60; i++) - I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); - for (i = 0; i < 60; i++) - I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); - for (i = 0; i < 43; i++) - I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); - for (i = 0; i < 43; i++) - I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); - I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE); - I915_WRITE(TV_CTL, tv_ctl); -} - -static const struct drm_display_mode reported_modes[] = { - { - .name = "NTSC 480i", - .clock = 107520, - .hdisplay = 1280, - .hsync_start = 1368, - .hsync_end = 1496, - .htotal = 1712, - - .vdisplay = 1024, - .vsync_start = 1027, - .vsync_end = 1034, - .vtotal = 1104, - .type = DRM_MODE_TYPE_DRIVER, - }, -}; - -/** - * Detects TV presence by checking for load. - * - * Requires that the current pipe's DPLL is active. - - * \return true if TV is connected. - * \return false if TV is disconnected. - */ -static int -intel_tv_detect_type(struct intel_tv *intel_tv, - struct drm_connector *connector) -{ - struct drm_encoder *encoder = &intel_tv->base.base; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - unsigned long irqflags; - u32 tv_ctl, save_tv_ctl; - u32 tv_dac, save_tv_dac; - int type; - - /* Disable TV interrupts around load detect or we'll recurse */ - if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, 0, - PIPE_HOTPLUG_INTERRUPT_ENABLE | - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - } - - save_tv_dac = tv_dac = I915_READ(TV_DAC); - save_tv_ctl = tv_ctl = I915_READ(TV_CTL); - - /* Poll for TV detection */ - tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK); - tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; - if (intel_crtc->pipe == 1) - tv_ctl |= TV_ENC_PIPEB_SELECT; - else - tv_ctl &= ~TV_ENC_PIPEB_SELECT; - - tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK); - tv_dac |= (TVDAC_STATE_CHG_EN | - TVDAC_A_SENSE_CTL | - TVDAC_B_SENSE_CTL | - TVDAC_C_SENSE_CTL | - DAC_CTL_OVERRIDE | - DAC_A_0_7_V | - DAC_B_0_7_V | - DAC_C_0_7_V); - - I915_WRITE(TV_CTL, tv_ctl); - I915_WRITE(TV_DAC, tv_dac); - POSTING_READ(TV_DAC); - - intel_wait_for_vblank(intel_tv->base.base.dev, - to_intel_crtc(intel_tv->base.base.crtc)->pipe); - - type = -1; - tv_dac = I915_READ(TV_DAC); - DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac); - /* - * A B C - * 0 1 1 Composite - * 1 0 X svideo - * 0 0 0 Component - */ - if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { - DRM_DEBUG_KMS("Detected Composite TV connection\n"); - type = DRM_MODE_CONNECTOR_Composite; - } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { - DRM_DEBUG_KMS("Detected S-Video TV connection\n"); - type = DRM_MODE_CONNECTOR_SVIDEO; - } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { - DRM_DEBUG_KMS("Detected Component TV connection\n"); - type = DRM_MODE_CONNECTOR_Component; - } else { - DRM_DEBUG_KMS("Unrecognised TV connection\n"); - type = -1; - } - - I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); - I915_WRITE(TV_CTL, save_tv_ctl); - POSTING_READ(TV_CTL); - - /* For unknown reasons the hw barfs if we don't do this vblank wait. */ - intel_wait_for_vblank(intel_tv->base.base.dev, - to_intel_crtc(intel_tv->base.base.crtc)->pipe); - - /* Restore interrupt config */ - if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, 0, - PIPE_HOTPLUG_INTERRUPT_ENABLE | - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - } - - return type; -} - -/* - * Here we set accurate tv format according to connector type - * i.e Component TV should not be assigned by NTSC or PAL - */ -static void intel_tv_find_better_format(struct drm_connector *connector) -{ - struct intel_tv *intel_tv = intel_attached_tv(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); - int i; - - if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == - tv_mode->component_only) - return; - - - for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { - tv_mode = tv_modes + i; - - if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == - tv_mode->component_only) - break; - } - - intel_tv->tv_format = tv_mode->name; - drm_connector_property_set_value(connector, - connector->dev->mode_config.tv_mode_property, i); -} - -/** - * Detect the TV connection. - * - * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure - * we have a pipe programmed in order to probe the TV. - */ -static enum drm_connector_status -intel_tv_detect(struct drm_connector *connector, bool force) -{ - struct drm_display_mode mode; - struct intel_tv *intel_tv = intel_attached_tv(connector); - int type; - - mode = reported_modes[0]; - drm_mode_set_crtcinfo(&mode, 0); - - if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { - type = intel_tv_detect_type(intel_tv, connector); - } else if (force) { - struct intel_load_detect_pipe tmp; - - if (intel_get_load_detect_pipe(&intel_tv->base, connector, - &mode, &tmp)) { - type = intel_tv_detect_type(intel_tv, connector); - intel_release_load_detect_pipe(&intel_tv->base, - connector, - &tmp); - } else - return connector_status_unknown; - } else - return connector->status; - - if (type < 0) - return connector_status_disconnected; - - intel_tv->type = type; - intel_tv_find_better_format(connector); - - return connector_status_connected; -} - -static const struct input_res { - const char *name; - int w, h; -} input_res_table[] = { - {"640x480", 640, 480}, - {"800x600", 800, 600}, - {"1024x768", 1024, 768}, - {"1280x1024", 1280, 1024}, - {"848x480", 848, 480}, - {"1280x720", 1280, 720}, - {"1920x1080", 1920, 1080}, -}; - -/* - * Chose preferred mode according to line number of TV format - */ -static void -intel_tv_chose_preferred_modes(struct drm_connector *connector, - struct drm_display_mode *mode_ptr) -{ - struct intel_tv *intel_tv = intel_attached_tv(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); - - if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) - mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; - else if (tv_mode->nbr_end > 480) { - if (tv_mode->progressive == true && tv_mode->nbr_end < 720) { - if (mode_ptr->vdisplay == 720) - mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; - } else if (mode_ptr->vdisplay == 1080) - mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; - } -} - -/** - * Stub get_modes function. - * - * This should probably return a set of fixed modes, unless we can figure out - * how to probe modes off of TV connections. - */ - -static int -intel_tv_get_modes(struct drm_connector *connector) -{ - struct drm_display_mode *mode_ptr; - struct intel_tv *intel_tv = intel_attached_tv(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); - int j, count = 0; - u64 tmp; - - for (j = 0; j < ARRAY_SIZE(input_res_table); - j++) { - const struct input_res *input = &input_res_table[j]; - unsigned int hactive_s = input->w; - unsigned int vactive_s = input->h; - - if (tv_mode->max_srcw && input->w > tv_mode->max_srcw) - continue; - - if (input->w > 1024 && (!tv_mode->progressive - && !tv_mode->component_only)) - continue; - - mode_ptr = drm_mode_create(connector->dev); - if (!mode_ptr) - continue; - strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN); - - mode_ptr->hdisplay = hactive_s; - mode_ptr->hsync_start = hactive_s + 1; - mode_ptr->hsync_end = hactive_s + 64; - if (mode_ptr->hsync_end <= mode_ptr->hsync_start) - mode_ptr->hsync_end = mode_ptr->hsync_start + 1; - mode_ptr->htotal = hactive_s + 96; - - mode_ptr->vdisplay = vactive_s; - mode_ptr->vsync_start = vactive_s + 1; - mode_ptr->vsync_end = vactive_s + 32; - if (mode_ptr->vsync_end <= mode_ptr->vsync_start) - mode_ptr->vsync_end = mode_ptr->vsync_start + 1; - mode_ptr->vtotal = vactive_s + 33; - - tmp = (u64) tv_mode->refresh * mode_ptr->vtotal; - tmp *= mode_ptr->htotal; - tmp = div_u64(tmp, 1000000); - mode_ptr->clock = (int) tmp; - - mode_ptr->type = DRM_MODE_TYPE_DRIVER; - intel_tv_chose_preferred_modes(connector, mode_ptr); - drm_mode_probed_add(connector, mode_ptr); - count++; - } - - return count; -} - -static void -intel_tv_destroy(struct drm_connector *connector) -{ - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - - -static int -intel_tv_set_property(struct drm_connector *connector, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = connector->dev; - struct intel_tv *intel_tv = intel_attached_tv(connector); - struct drm_crtc *crtc = intel_tv->base.base.crtc; - int ret = 0; - bool changed = false; - - ret = drm_connector_property_set_value(connector, property, val); - if (ret < 0) - goto out; - - if (property == dev->mode_config.tv_left_margin_property && - intel_tv->margin[TV_MARGIN_LEFT] != val) { - intel_tv->margin[TV_MARGIN_LEFT] = val; - changed = true; - } else if (property == dev->mode_config.tv_right_margin_property && - intel_tv->margin[TV_MARGIN_RIGHT] != val) { - intel_tv->margin[TV_MARGIN_RIGHT] = val; - changed = true; - } else if (property == dev->mode_config.tv_top_margin_property && - intel_tv->margin[TV_MARGIN_TOP] != val) { - intel_tv->margin[TV_MARGIN_TOP] = val; - changed = true; - } else if (property == dev->mode_config.tv_bottom_margin_property && - intel_tv->margin[TV_MARGIN_BOTTOM] != val) { - intel_tv->margin[TV_MARGIN_BOTTOM] = val; - changed = true; - } else if (property == dev->mode_config.tv_mode_property) { - if (val >= ARRAY_SIZE(tv_modes)) { - ret = -EINVAL; - goto out; - } - if (!strcmp(intel_tv->tv_format, tv_modes[val].name)) - goto out; - - intel_tv->tv_format = tv_modes[val].name; - changed = true; - } else { - ret = -EINVAL; - goto out; - } - - if (changed && crtc) - drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, - crtc->y, crtc->fb); -out: - return ret; -} - -static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { - .dpms = intel_tv_dpms, - .mode_fixup = intel_tv_mode_fixup, - .prepare = intel_encoder_prepare, - .mode_set = intel_tv_mode_set, - .commit = intel_encoder_commit, -}; - -static const struct drm_connector_funcs intel_tv_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = intel_tv_detect, - .destroy = intel_tv_destroy, - .set_property = intel_tv_set_property, - .fill_modes = drm_helper_probe_single_connector_modes, -}; - -static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { - .mode_valid = intel_tv_mode_valid, - .get_modes = intel_tv_get_modes, - .best_encoder = intel_best_encoder, -}; - -static const struct drm_encoder_funcs intel_tv_enc_funcs = { - .destroy = intel_encoder_destroy, -}; - -/* - * Enumerate the child dev array parsed from VBT to check whether - * the integrated TV is present. - * If it is present, return 1. - * If it is not present, return false. - * If no child dev is parsed from VBT, it assumes that the TV is present. - */ -static int tv_is_present_in_vbt(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct child_device_config *p_child; - int i, ret; - - if (!dev_priv->child_dev_num) - return 1; - - ret = 0; - for (i = 0; i < dev_priv->child_dev_num; i++) { - p_child = dev_priv->child_dev + i; - /* - * If the device type is not TV, continue. - */ - if (p_child->device_type != DEVICE_TYPE_INT_TV && - p_child->device_type != DEVICE_TYPE_TV) - continue; - /* Only when the addin_offset is non-zero, it is regarded - * as present. - */ - if (p_child->addin_offset) { - ret = 1; - break; - } - } - return ret; -} - -void -intel_tv_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - struct intel_tv *intel_tv; - struct intel_encoder *intel_encoder; - struct intel_connector *intel_connector; - u32 tv_dac_on, tv_dac_off, save_tv_dac; - char *tv_format_names[ARRAY_SIZE(tv_modes)]; - int i, initial_mode = 0; - - if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) - return; - - if (!tv_is_present_in_vbt(dev)) { - DRM_DEBUG_KMS("Integrated TV is not present.\n"); - return; - } - /* Even if we have an encoder we may not have a connector */ - if (!dev_priv->int_tv_support) - return; - - /* - * Sanity check the TV output by checking to see if the - * DAC register holds a value - */ - save_tv_dac = I915_READ(TV_DAC); - - I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN); - tv_dac_on = I915_READ(TV_DAC); - - I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); - tv_dac_off = I915_READ(TV_DAC); - - I915_WRITE(TV_DAC, save_tv_dac); - - /* - * If the register does not hold the state change enable - * bit, (either as a 0 or a 1), assume it doesn't really - * exist - */ - if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 || - (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) - return; - - intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL); - if (!intel_tv) { - return; - } - - intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); - if (!intel_connector) { - kfree(intel_tv); - return; - } - - intel_encoder = &intel_tv->base; - connector = &intel_connector->base; - - /* The documentation, for the older chipsets at least, recommend - * using a polling method rather than hotplug detection for TVs. - * This is because in order to perform the hotplug detection, the PLLs - * for the TV must be kept alive increasing power drain and starving - * bandwidth from other encoders. Notably for instance, it causes - * pipe underruns on Crestline when this encoder is supposedly idle. - * - * More recent chipsets favour HDMI rather than integrated S-Video. - */ - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - - drm_connector_init(dev, connector, &intel_tv_connector_funcs, - DRM_MODE_CONNECTOR_SVIDEO); - - drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs, - DRM_MODE_ENCODER_TVDAC); - - intel_connector_attach_encoder(intel_connector, intel_encoder); - intel_encoder->type = INTEL_OUTPUT_TVOUT; - intel_encoder->crtc_mask = (1 << 0) | (1 << 1); - intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); - intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1)); - intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT); - intel_tv->type = DRM_MODE_CONNECTOR_Unknown; - - /* BIOS margin values */ - intel_tv->margin[TV_MARGIN_LEFT] = 54; - intel_tv->margin[TV_MARGIN_TOP] = 36; - intel_tv->margin[TV_MARGIN_RIGHT] = 46; - intel_tv->margin[TV_MARGIN_BOTTOM] = 37; - - intel_tv->tv_format = tv_modes[initial_mode].name; - - drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs); - drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - /* Create TV properties then attach current values */ - for (i = 0; i < ARRAY_SIZE(tv_modes); i++) - tv_format_names[i] = (char *)tv_modes[i].name; - drm_mode_create_tv_properties(dev, - ARRAY_SIZE(tv_modes), - tv_format_names); - - drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, - initial_mode); - drm_connector_attach_property(connector, - dev->mode_config.tv_left_margin_property, - intel_tv->margin[TV_MARGIN_LEFT]); - drm_connector_attach_property(connector, - dev->mode_config.tv_top_margin_property, - intel_tv->margin[TV_MARGIN_TOP]); - drm_connector_attach_property(connector, - dev->mode_config.tv_right_margin_property, - intel_tv->margin[TV_MARGIN_RIGHT]); - drm_connector_attach_property(connector, - dev->mode_config.tv_bottom_margin_property, - intel_tv->margin[TV_MARGIN_BOTTOM]); - drm_sysfs_connector_add(connector); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/mga/Makefile deleted file mode 100644 index 60684785..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -mga-y := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o - -mga-$(CONFIG_COMPAT) += mga_ioc32.o - -obj-$(CONFIG_DRM_MGA) += mga.o - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_dma.c b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_dma.c deleted file mode 100644 index 507aa3df..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_dma.c +++ /dev/null @@ -1,1156 +0,0 @@ -/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file mga_dma.c - * DMA support for MGA G200 / G400. - * - * \author Rickard E. (Rik) Faith - * \author Jeff Hartmann - * \author Keith Whitwell - * \author Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "mga_drm.h" -#include "mga_drv.h" - -#define MGA_DEFAULT_USEC_TIMEOUT 10000 -#define MGA_FREELIST_DEBUG 0 - -#define MINIMAL_CLEANUP 0 -#define FULL_CLEANUP 1 -static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup); - -/* ================================================================ - * Engine control - */ - -int mga_do_wait_for_idle(drm_mga_private_t *dev_priv) -{ - u32 status = 0; - int i; - DRM_DEBUG("\n"); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; - if (status == MGA_ENDPRDMASTS) { - MGA_WRITE8(MGA_CRTC_INDEX, 0); - return 0; - } - DRM_UDELAY(1); - } - -#if MGA_DMA_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x\n", status); -#endif - return -EBUSY; -} - -static int mga_do_dma_reset(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - - DRM_DEBUG("\n"); - - /* The primary DMA stream should look like new right about now. - */ - primary->tail = 0; - primary->space = primary->size; - primary->last_flush = 0; - - sarea_priv->last_wrap = 0; - - /* FIXME: Reset counters, buffer ages etc... - */ - - /* FIXME: What else do we need to reinitialize? WARP stuff? - */ - - return 0; -} - -/* ================================================================ - * Primary DMA stream - */ - -void mga_do_dma_flush(drm_mga_private_t *dev_priv) -{ - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - u32 head, tail; - u32 status = 0; - int i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - /* We need to wait so that we can do an safe flush */ - for (i = 0; i < dev_priv->usec_timeout; i++) { - status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; - if (status == MGA_ENDPRDMASTS) - break; - DRM_UDELAY(1); - } - - if (primary->tail == primary->last_flush) { - DRM_DEBUG(" bailing out...\n"); - return; - } - - tail = primary->tail + dev_priv->primary->offset; - - /* We need to pad the stream between flushes, as the card - * actually (partially?) reads the first of these commands. - * See page 4-16 in the G400 manual, middle of the page or so. - */ - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); - - primary->last_flush = primary->tail; - - head = MGA_READ(MGA_PRIMADDRESS); - - if (head <= tail) - primary->space = primary->size - primary->tail; - else - primary->space = head - tail; - - DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); - DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset)); - DRM_DEBUG(" space = 0x%06x\n", primary->space); - - mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); - - DRM_DEBUG("done.\n"); -} - -void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv) -{ - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - u32 head, tail; - DMA_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_DMA_WRAP(); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); - - tail = primary->tail + dev_priv->primary->offset; - - primary->tail = 0; - primary->last_flush = 0; - primary->last_wrap++; - - head = MGA_READ(MGA_PRIMADDRESS); - - if (head == dev_priv->primary->offset) - primary->space = primary->size; - else - primary->space = head - dev_priv->primary->offset; - - DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset)); - DRM_DEBUG(" tail = 0x%06x\n", primary->tail); - DRM_DEBUG(" wrap = %d\n", primary->last_wrap); - DRM_DEBUG(" space = 0x%06x\n", primary->space); - - mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access); - - set_bit(0, &primary->wrapped); - DRM_DEBUG("done.\n"); -} - -void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv) -{ - drm_mga_primary_buffer_t *primary = &dev_priv->prim; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 head = dev_priv->primary->offset; - DRM_DEBUG("\n"); - - sarea_priv->last_wrap++; - DRM_DEBUG(" wrap = %d\n", sarea_priv->last_wrap); - - mga_flush_write_combine(); - MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL); - - clear_bit(0, &primary->wrapped); - DRM_DEBUG("done.\n"); -} - -/* ================================================================ - * Freelist management - */ - -#define MGA_BUFFER_USED (~0) -#define MGA_BUFFER_FREE 0 - -#if MGA_FREELIST_DEBUG -static void mga_freelist_print(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_freelist_t *entry; - - DRM_INFO("\n"); - DRM_INFO("current dispatch: last=0x%x done=0x%x\n", - dev_priv->sarea_priv->last_dispatch, - (unsigned int)(MGA_READ(MGA_PRIMADDRESS) - - dev_priv->primary->offset)); - DRM_INFO("current freelist:\n"); - - for (entry = dev_priv->head->next; entry; entry = entry->next) { - DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n", - entry, entry->buf->idx, entry->age.head, - (unsigned long)(entry->age.head - dev_priv->primary->offset)); - } - DRM_INFO("\n"); -} -#endif - -static int mga_freelist_init(struct drm_device *dev, drm_mga_private_t *dev_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_freelist_t *entry; - int i; - DRM_DEBUG("count=%d\n", dma->buf_count); - - dev_priv->head = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL); - if (dev_priv->head == NULL) - return -ENOMEM; - - SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - - entry = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL); - if (entry == NULL) - return -ENOMEM; - - entry->next = dev_priv->head->next; - entry->prev = dev_priv->head; - SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); - entry->buf = buf; - - if (dev_priv->head->next != NULL) - dev_priv->head->next->prev = entry; - if (entry->next == NULL) - dev_priv->tail = entry; - - buf_priv->list_entry = entry; - buf_priv->discard = 0; - buf_priv->dispatched = 0; - - dev_priv->head->next = entry; - } - - return 0; -} - -static void mga_freelist_cleanup(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_freelist_t *entry; - drm_mga_freelist_t *next; - DRM_DEBUG("\n"); - - entry = dev_priv->head; - while (entry) { - next = entry->next; - kfree(entry); - entry = next; - } - - dev_priv->head = dev_priv->tail = NULL; -} - -#if 0 -/* FIXME: Still needed? - */ -static void mga_freelist_reset(struct drm_device *dev) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - int i; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0); - } -} -#endif - -static struct drm_buf *mga_freelist_get(struct drm_device * dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_freelist_t *next; - drm_mga_freelist_t *prev; - drm_mga_freelist_t *tail = dev_priv->tail; - u32 head, wrap; - DRM_DEBUG("\n"); - - head = MGA_READ(MGA_PRIMADDRESS); - wrap = dev_priv->sarea_priv->last_wrap; - - DRM_DEBUG(" tail=0x%06lx %d\n", - tail->age.head ? - (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0, - tail->age.wrap); - DRM_DEBUG(" head=0x%06lx %d\n", - (unsigned long)(head - dev_priv->primary->offset), wrap); - - if (TEST_AGE(&tail->age, head, wrap)) { - prev = dev_priv->tail->prev; - next = dev_priv->tail; - prev->next = NULL; - next->prev = next->next = NULL; - dev_priv->tail = prev; - SET_AGE(&next->age, MGA_BUFFER_USED, 0); - return next->buf; - } - - DRM_DEBUG("returning NULL!\n"); - return NULL; -} - -int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_freelist_t *head, *entry, *prev; - - DRM_DEBUG("age=0x%06lx wrap=%d\n", - (unsigned long)(buf_priv->list_entry->age.head - - dev_priv->primary->offset), - buf_priv->list_entry->age.wrap); - - entry = buf_priv->list_entry; - head = dev_priv->head; - - if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) { - SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); - prev = dev_priv->tail; - prev->next = entry; - entry->prev = prev; - entry->next = NULL; - } else { - prev = head->next; - head->next = entry; - prev->prev = entry; - entry->prev = head; - entry->next = prev; - } - - return 0; -} - -/* ================================================================ - * DMA initialization, cleanup - */ - -int mga_driver_load(struct drm_device *dev, unsigned long flags) -{ - drm_mga_private_t *dev_priv; - int ret; - - dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL); - if (!dev_priv) - return -ENOMEM; - - dev->dev_private = (void *)dev_priv; - - dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; - dev_priv->chipset = flags; - - pci_set_master(dev->pdev); - - dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); - dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); - - dev->counters += 3; - dev->types[6] = _DRM_STAT_IRQ; - dev->types[7] = _DRM_STAT_PRIMARY; - dev->types[8] = _DRM_STAT_SECONDARY; - - ret = drm_vblank_init(dev, 1); - - if (ret) { - (void) mga_driver_unload(dev); - return ret; - } - - return 0; -} - -#if __OS_HAS_AGP -/** - * Bootstrap the driver for AGP DMA. - * - * \todo - * Investigate whether there is any benefit to storing the WARP microcode in - * AGP memory. If not, the microcode may as well always be put in PCI - * memory. - * - * \todo - * This routine needs to set dma_bs->agp_mode to the mode actually configured - * in the hardware. Looking just at the Linux AGP driver code, I don't see - * an easy way to determine this. - * - * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap - */ -static int mga_do_agp_dma_bootstrap(struct drm_device *dev, - drm_mga_dma_bootstrap_t *dma_bs) -{ - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - unsigned int warp_size = MGA_WARP_UCODE_SIZE; - int err; - unsigned offset; - const unsigned secondary_size = dma_bs->secondary_bin_count - * dma_bs->secondary_bin_size; - const unsigned agp_size = (dma_bs->agp_size << 20); - struct drm_buf_desc req; - struct drm_agp_mode mode; - struct drm_agp_info info; - struct drm_agp_buffer agp_req; - struct drm_agp_binding bind_req; - - /* Acquire AGP. */ - err = drm_agp_acquire(dev); - if (err) { - DRM_ERROR("Unable to acquire AGP: %d\n", err); - return err; - } - - err = drm_agp_info(dev, &info); - if (err) { - DRM_ERROR("Unable to get AGP info: %d\n", err); - return err; - } - - mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode; - err = drm_agp_enable(dev, mode); - if (err) { - DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); - return err; - } - - /* In addition to the usual AGP mode configuration, the G200 AGP cards - * need to have the AGP mode "manually" set. - */ - - if (dev_priv->chipset == MGA_CARD_TYPE_G200) { - if (mode.mode & 0x02) - MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE); - else - MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE); - } - - /* Allocate and bind AGP memory. */ - agp_req.size = agp_size; - agp_req.type = 0; - err = drm_agp_alloc(dev, &agp_req); - if (err) { - dev_priv->agp_size = 0; - DRM_ERROR("Unable to allocate %uMB AGP memory\n", - dma_bs->agp_size); - return err; - } - - dev_priv->agp_size = agp_size; - dev_priv->agp_handle = agp_req.handle; - - bind_req.handle = agp_req.handle; - bind_req.offset = 0; - err = drm_agp_bind(dev, &bind_req); - if (err) { - DRM_ERROR("Unable to bind AGP memory: %d\n", err); - return err; - } - - /* Make drm_addbufs happy by not trying to create a mapping for less - * than a page. - */ - if (warp_size < PAGE_SIZE) - warp_size = PAGE_SIZE; - - offset = 0; - err = drm_addmap(dev, offset, warp_size, - _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); - if (err) { - DRM_ERROR("Unable to map WARP microcode: %d\n", err); - return err; - } - - offset += warp_size; - err = drm_addmap(dev, offset, dma_bs->primary_size, - _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); - if (err) { - DRM_ERROR("Unable to map primary DMA region: %d\n", err); - return err; - } - - offset += dma_bs->primary_size; - err = drm_addmap(dev, offset, secondary_size, - _DRM_AGP, 0, &dev->agp_buffer_map); - if (err) { - DRM_ERROR("Unable to map secondary DMA region: %d\n", err); - return err; - } - - (void)memset(&req, 0, sizeof(req)); - req.count = dma_bs->secondary_bin_count; - req.size = dma_bs->secondary_bin_size; - req.flags = _DRM_AGP_BUFFER; - req.agp_start = offset; - - err = drm_addbufs_agp(dev, &req); - if (err) { - DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); - return err; - } - - { - struct drm_map_list *_entry; - unsigned long agp_token = 0; - - list_for_each_entry(_entry, &dev->maplist, head) { - if (_entry->map == dev->agp_buffer_map) - agp_token = _entry->user_token; - } - if (!agp_token) - return -EFAULT; - - dev->agp_buffer_token = agp_token; - } - - offset += secondary_size; - err = drm_addmap(dev, offset, agp_size - offset, - _DRM_AGP, 0, &dev_priv->agp_textures); - if (err) { - DRM_ERROR("Unable to map AGP texture region %d\n", err); - return err; - } - - drm_core_ioremap(dev_priv->warp, dev); - drm_core_ioremap(dev_priv->primary, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); - - if (!dev_priv->warp->handle || - !dev_priv->primary->handle || !dev->agp_buffer_map->handle) { - DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n", - dev_priv->warp->handle, dev_priv->primary->handle, - dev->agp_buffer_map->handle); - return -ENOMEM; - } - - dev_priv->dma_access = MGA_PAGPXFER; - dev_priv->wagp_enable = MGA_WAGP_ENABLE; - - DRM_INFO("Initialized card for AGP DMA.\n"); - return 0; -} -#else -static int mga_do_agp_dma_bootstrap(struct drm_device *dev, - drm_mga_dma_bootstrap_t *dma_bs) -{ - return -EINVAL; -} -#endif - -/** - * Bootstrap the driver for PCI DMA. - * - * \todo - * The algorithm for decreasing the size of the primary DMA buffer could be - * better. The size should be rounded up to the nearest page size, then - * decrease the request size by a single page each pass through the loop. - * - * \todo - * Determine whether the maximum address passed to drm_pci_alloc is correct. - * The same goes for drm_addbufs_pci. - * - * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap - */ -static int mga_do_pci_dma_bootstrap(struct drm_device *dev, - drm_mga_dma_bootstrap_t *dma_bs) -{ - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - unsigned int warp_size = MGA_WARP_UCODE_SIZE; - unsigned int primary_size; - unsigned int bin_count; - int err; - struct drm_buf_desc req; - - if (dev->dma == NULL) { - DRM_ERROR("dev->dma is NULL\n"); - return -EFAULT; - } - - /* Make drm_addbufs happy by not trying to create a mapping for less - * than a page. - */ - if (warp_size < PAGE_SIZE) - warp_size = PAGE_SIZE; - - /* The proper alignment is 0x100 for this mapping */ - err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, - _DRM_READ_ONLY, &dev_priv->warp); - if (err != 0) { - DRM_ERROR("Unable to create mapping for WARP microcode: %d\n", - err); - return err; - } - - /* Other than the bottom two bits being used to encode other - * information, there don't appear to be any restrictions on the - * alignment of the primary or secondary DMA buffers. - */ - - for (primary_size = dma_bs->primary_size; primary_size != 0; - primary_size >>= 1) { - /* The proper alignment for this mapping is 0x04 */ - err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT, - _DRM_READ_ONLY, &dev_priv->primary); - if (!err) - break; - } - - if (err != 0) { - DRM_ERROR("Unable to allocate primary DMA region: %d\n", err); - return -ENOMEM; - } - - if (dev_priv->primary->size != dma_bs->primary_size) { - DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n", - dma_bs->primary_size, - (unsigned)dev_priv->primary->size); - dma_bs->primary_size = dev_priv->primary->size; - } - - for (bin_count = dma_bs->secondary_bin_count; bin_count > 0; - bin_count--) { - (void)memset(&req, 0, sizeof(req)); - req.count = bin_count; - req.size = dma_bs->secondary_bin_size; - - err = drm_addbufs_pci(dev, &req); - if (!err) - break; - } - - if (bin_count == 0) { - DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err); - return err; - } - - if (bin_count != dma_bs->secondary_bin_count) { - DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u " - "to %u.\n", dma_bs->secondary_bin_count, bin_count); - - dma_bs->secondary_bin_count = bin_count; - } - - dev_priv->dma_access = 0; - dev_priv->wagp_enable = 0; - - dma_bs->agp_mode = 0; - - DRM_INFO("Initialized card for PCI DMA.\n"); - return 0; -} - -static int mga_do_dma_bootstrap(struct drm_device *dev, - drm_mga_dma_bootstrap_t *dma_bs) -{ - const int is_agp = (dma_bs->agp_mode != 0) && drm_pci_device_is_agp(dev); - int err; - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - dev_priv->used_new_dma_init = 1; - - /* The first steps are the same for both PCI and AGP based DMA. Map - * the cards MMIO registers and map a status page. - */ - err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, - _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); - if (err) { - DRM_ERROR("Unable to map MMIO region: %d\n", err); - return err; - } - - err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, - _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, - &dev_priv->status); - if (err) { - DRM_ERROR("Unable to map status region: %d\n", err); - return err; - } - - /* The DMA initialization procedure is slightly different for PCI and - * AGP cards. AGP cards just allocate a large block of AGP memory and - * carve off portions of it for internal uses. The remaining memory - * is returned to user-mode to be used for AGP textures. - */ - if (is_agp) - err = mga_do_agp_dma_bootstrap(dev, dma_bs); - - /* If we attempted to initialize the card for AGP DMA but failed, - * clean-up any mess that may have been created. - */ - - if (err) - mga_do_cleanup_dma(dev, MINIMAL_CLEANUP); - - /* Not only do we want to try and initialized PCI cards for PCI DMA, - * but we also try to initialized AGP cards that could not be - * initialized for AGP DMA. This covers the case where we have an AGP - * card in a system with an unsupported AGP chipset. In that case the - * card will be detected as AGP, but we won't be able to allocate any - * AGP memory, etc. - */ - - if (!is_agp || err) - err = mga_do_pci_dma_bootstrap(dev, dma_bs); - - return err; -} - -int mga_dma_bootstrap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_dma_bootstrap_t *bootstrap = data; - int err; - static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; - const drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - err = mga_do_dma_bootstrap(dev, bootstrap); - if (err) { - mga_do_cleanup_dma(dev, FULL_CLEANUP); - return err; - } - - if (dev_priv->agp_textures != NULL) { - bootstrap->texture_handle = dev_priv->agp_textures->offset; - bootstrap->texture_size = dev_priv->agp_textures->size; - } else { - bootstrap->texture_handle = 0; - bootstrap->texture_size = 0; - } - - bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07]; - - return err; -} - -static int mga_do_init_dma(struct drm_device *dev, drm_mga_init_t *init) -{ - drm_mga_private_t *dev_priv; - int ret; - DRM_DEBUG("\n"); - - dev_priv = dev->dev_private; - - if (init->sgram) - dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; - else - dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; - dev_priv->maccess = init->maccess; - - dev_priv->fb_cpp = init->fb_cpp; - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - dev_priv->depth_cpp = init->depth_cpp; - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - - /* FIXME: Need to support AGP textures... - */ - dev_priv->texture_offset = init->texture_offset[0]; - dev_priv->texture_size = init->texture_size[0]; - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("failed to find sarea!\n"); - return -EINVAL; - } - - if (!dev_priv->used_new_dma_init) { - - dev_priv->dma_access = MGA_PAGPXFER; - dev_priv->wagp_enable = MGA_WAGP_ENABLE; - - dev_priv->status = drm_core_findmap(dev, init->status_offset); - if (!dev_priv->status) { - DRM_ERROR("failed to find status page!\n"); - return -EINVAL; - } - dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio) { - DRM_ERROR("failed to find mmio region!\n"); - return -EINVAL; - } - dev_priv->warp = drm_core_findmap(dev, init->warp_offset); - if (!dev_priv->warp) { - DRM_ERROR("failed to find warp microcode region!\n"); - return -EINVAL; - } - dev_priv->primary = drm_core_findmap(dev, init->primary_offset); - if (!dev_priv->primary) { - DRM_ERROR("failed to find primary dma region!\n"); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = - drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("failed to find dma buffer region!\n"); - return -EINVAL; - } - - drm_core_ioremap(dev_priv->warp, dev); - drm_core_ioremap(dev_priv->primary, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); - } - - dev_priv->sarea_priv = - (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - - if (!dev_priv->warp->handle || - !dev_priv->primary->handle || - ((dev_priv->dma_access != 0) && - ((dev->agp_buffer_map == NULL) || - (dev->agp_buffer_map->handle == NULL)))) { - DRM_ERROR("failed to ioremap agp regions!\n"); - return -ENOMEM; - } - - ret = mga_warp_install_microcode(dev_priv); - if (ret < 0) { - DRM_ERROR("failed to install WARP ucode!: %d\n", ret); - return ret; - } - - ret = mga_warp_init(dev_priv); - if (ret < 0) { - DRM_ERROR("failed to init WARP engine!: %d\n", ret); - return ret; - } - - dev_priv->prim.status = (u32 *) dev_priv->status->handle; - - mga_do_wait_for_idle(dev_priv); - - /* Init the primary DMA registers. - */ - MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL); -#if 0 - MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ - MGA_PRIMPTREN1); /* DWGSYNC */ -#endif - - dev_priv->prim.start = (u8 *) dev_priv->primary->handle; - dev_priv->prim.end = ((u8 *) dev_priv->primary->handle - + dev_priv->primary->size); - dev_priv->prim.size = dev_priv->primary->size; - - dev_priv->prim.tail = 0; - dev_priv->prim.space = dev_priv->prim.size; - dev_priv->prim.wrapped = 0; - - dev_priv->prim.last_flush = 0; - dev_priv->prim.last_wrap = 0; - - dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; - - dev_priv->prim.status[0] = dev_priv->primary->offset; - dev_priv->prim.status[1] = 0; - - dev_priv->sarea_priv->last_wrap = 0; - dev_priv->sarea_priv->last_frame.head = 0; - dev_priv->sarea_priv->last_frame.wrap = 0; - - if (mga_freelist_init(dev, dev_priv) < 0) { - DRM_ERROR("could not initialize freelist\n"); - return -ENOMEM; - } - - return 0; -} - -static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup) -{ - int err = 0; - DRM_DEBUG("\n"); - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - drm_mga_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->warp != NULL) - && (dev_priv->warp->type != _DRM_CONSISTENT)) - drm_core_ioremapfree(dev_priv->warp, dev); - - if ((dev_priv->primary != NULL) - && (dev_priv->primary->type != _DRM_CONSISTENT)) - drm_core_ioremapfree(dev_priv->primary, dev); - - if (dev->agp_buffer_map != NULL) - drm_core_ioremapfree(dev->agp_buffer_map, dev); - - if (dev_priv->used_new_dma_init) { -#if __OS_HAS_AGP - if (dev_priv->agp_handle != 0) { - struct drm_agp_binding unbind_req; - struct drm_agp_buffer free_req; - - unbind_req.handle = dev_priv->agp_handle; - drm_agp_unbind(dev, &unbind_req); - - free_req.handle = dev_priv->agp_handle; - drm_agp_free(dev, &free_req); - - dev_priv->agp_textures = NULL; - dev_priv->agp_size = 0; - dev_priv->agp_handle = 0; - } - - if ((dev->agp != NULL) && dev->agp->acquired) - err = drm_agp_release(dev); -#endif - } - - dev_priv->warp = NULL; - dev_priv->primary = NULL; - dev_priv->sarea = NULL; - dev_priv->sarea_priv = NULL; - dev->agp_buffer_map = NULL; - - if (full_cleanup) { - dev_priv->mmio = NULL; - dev_priv->status = NULL; - dev_priv->used_new_dma_init = 0; - } - - memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); - dev_priv->warp_pipe = 0; - memset(dev_priv->warp_pipe_phys, 0, - sizeof(dev_priv->warp_pipe_phys)); - - if (dev_priv->head != NULL) - mga_freelist_cleanup(dev); - } - - return err; -} - -int mga_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_init_t *init = data; - int err; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - switch (init->func) { - case MGA_INIT_DMA: - err = mga_do_init_dma(dev, init); - if (err) - (void)mga_do_cleanup_dma(dev, FULL_CLEANUP); - return err; - case MGA_CLEANUP_DMA: - return mga_do_cleanup_dma(dev, FULL_CLEANUP); - } - - return -EINVAL; -} - -/* ================================================================ - * Primary DMA stream management - */ - -int mga_dma_flush(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - struct drm_lock *lock = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("%s%s%s\n", - (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "", - (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", - (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : ""); - - WRAP_WAIT_WITH_RETURN(dev_priv); - - if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) - mga_do_dma_flush(dev_priv); - - if (lock->flags & _DRM_LOCK_QUIESCENT) { -#if MGA_DMA_DEBUG - int ret = mga_do_wait_for_idle(dev_priv); - if (ret < 0) - DRM_INFO("-EBUSY\n"); - return ret; -#else - return mga_do_wait_for_idle(dev_priv); -#endif - } else { - return 0; - } -} - -int mga_dma_reset(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - return mga_do_dma_reset(dev_priv); -} - -/* ================================================================ - * DMA buffer management - */ - -static int mga_dma_get_buffers(struct drm_device *dev, - struct drm_file *file_priv, struct drm_dma *d) -{ - struct drm_buf *buf; - int i; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = mga_freelist_get(dev); - if (!buf) - return -EAGAIN; - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], - &buf->idx, sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], - &buf->total, sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int mga_dma_buffers(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - struct drm_dma *d = data; - int ret = 0; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - d->granted_count = 0; - - if (d->request_count) - ret = mga_dma_get_buffers(dev, file_priv, d); - - return ret; -} - -/** - * Called just before the module is unloaded. - */ -int mga_driver_unload(struct drm_device *dev) -{ - kfree(dev->dev_private); - dev->dev_private = NULL; - - return 0; -} - -/** - * Called when the last opener of the device is closed. - */ -void mga_driver_lastclose(struct drm_device *dev) -{ - mga_do_cleanup_dma(dev, FULL_CLEANUP); -} - -int mga_driver_dma_quiescent(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - return mga_do_wait_for_idle(dev_priv); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.c deleted file mode 100644 index f9a925d5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.c +++ /dev/null @@ -1,145 +0,0 @@ -/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - */ - -#include - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -#include "drm_pciids.h" - -static int mga_driver_device_is_agp(struct drm_device *dev); - -static struct pci_device_id pciidlist[] = { - mga_PCI_IDS -}; - -static const struct file_operations mga_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = mga_compat_ioctl, -#endif - .llseek = noop_llseek, -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, - .dev_priv_size = sizeof(drm_mga_buf_priv_t), - .load = mga_driver_load, - .unload = mga_driver_unload, - .lastclose = mga_driver_lastclose, - .dma_quiescent = mga_driver_dma_quiescent, - .device_is_agp = mga_driver_device_is_agp, - .get_vblank_counter = mga_get_vblank_counter, - .enable_vblank = mga_enable_vblank, - .disable_vblank = mga_disable_vblank, - .irq_preinstall = mga_driver_irq_preinstall, - .irq_postinstall = mga_driver_irq_postinstall, - .irq_uninstall = mga_driver_irq_uninstall, - .irq_handler = mga_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .ioctls = mga_ioctls, - .dma_ioctl = mga_dma_buffers, - .fops = &mga_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct pci_driver mga_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, -}; - -static int __init mga_init(void) -{ - driver.num_ioctls = mga_max_ioctl; - return drm_pci_init(&driver, &mga_pci_driver); -} - -static void __exit mga_exit(void) -{ - drm_pci_exit(&driver, &mga_pci_driver); -} - -module_init(mga_init); -module_exit(mga_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); - -/** - * Determine if the device really is AGP or not. - * - * In addition to the usual tests performed by \c drm_device_is_agp, this - * function detects PCI G450 cards that appear to the system exactly like - * AGP G450 cards. - * - * \param dev The device to be tested. - * - * \returns - * If the device is a PCI G450, zero is returned. Otherwise 2 is returned. - */ -static int mga_driver_device_is_agp(struct drm_device *dev) -{ - const struct pci_dev *const pdev = dev->pdev; - - /* There are PCI versions of the G450. These cards have the - * same PCI ID as the AGP G450, but have an additional PCI-to-PCI - * bridge chip. We detect these cards, which are not currently - * supported by this driver, by looking at the device ID of the - * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the - * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the - * device. - */ - - if ((pdev->device == 0x0525) && pdev->bus->self - && (pdev->bus->self->vendor == 0x3388) - && (pdev->bus->self->device == 0x0021)) { - return 0; - } - - return 2; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.h deleted file mode 100644 index 54558a01..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_drv.h +++ /dev/null @@ -1,666 +0,0 @@ -/* mga_drv.h -- Private header for the Matrox G200/G400 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#ifndef __MGA_DRV_H__ -#define __MGA_DRV_H__ - -/* General customization: - */ - -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "mga" -#define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20051102" - -#define DRIVER_MAJOR 3 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 - -typedef struct drm_mga_primary_buffer { - u8 *start; - u8 *end; - int size; - - u32 tail; - int space; - volatile long wrapped; - - volatile u32 *status; - - u32 last_flush; - u32 last_wrap; - - u32 high_mark; -} drm_mga_primary_buffer_t; - -typedef struct drm_mga_freelist { - struct drm_mga_freelist *next; - struct drm_mga_freelist *prev; - drm_mga_age_t age; - struct drm_buf *buf; -} drm_mga_freelist_t; - -typedef struct { - drm_mga_freelist_t *list_entry; - int discard; - int dispatched; -} drm_mga_buf_priv_t; - -typedef struct drm_mga_private { - drm_mga_primary_buffer_t prim; - drm_mga_sarea_t *sarea_priv; - - drm_mga_freelist_t *head; - drm_mga_freelist_t *tail; - - unsigned int warp_pipe; - unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES]; - - int chipset; - int usec_timeout; - - /** - * If set, the new DMA initialization sequence was used. This is - * primarilly used to select how the driver should uninitialized its - * internal DMA structures. - */ - int used_new_dma_init; - - /** - * If AGP memory is used for DMA buffers, this will be the value - * \c MGA_PAGPXFER. Otherwise, it will be zero (for a PCI transfer). - */ - u32 dma_access; - - /** - * If AGP memory is used for DMA buffers, this will be the value - * \c MGA_WAGP_ENABLE. Otherwise, it will be zero (for a PCI - * transfer). - */ - u32 wagp_enable; - - /** - * \name MMIO region parameters. - * - * \sa drm_mga_private_t::mmio - */ - /*@{ */ - resource_size_t mmio_base; /**< Bus address of base of MMIO. */ - resource_size_t mmio_size; /**< Size of the MMIO region. */ - /*@} */ - - u32 clear_cmd; - u32 maccess; - - atomic_t vbl_received; /**< Number of vblanks received. */ - wait_queue_head_t fence_queue; - atomic_t last_fence_retired; - u32 next_fence_to_post; - - unsigned int fb_cpp; - unsigned int front_offset; - unsigned int front_pitch; - unsigned int back_offset; - unsigned int back_pitch; - - unsigned int depth_cpp; - unsigned int depth_offset; - unsigned int depth_pitch; - - unsigned int texture_offset; - unsigned int texture_size; - - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *status; - drm_local_map_t *warp; - drm_local_map_t *primary; - drm_local_map_t *agp_textures; - - unsigned long agp_handle; - unsigned int agp_size; -} drm_mga_private_t; - -extern struct drm_ioctl_desc mga_ioctls[]; -extern int mga_max_ioctl; - - /* mga_dma.c */ -extern int mga_dma_bootstrap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_init(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_flush(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_reset(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_dma_buffers(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int mga_driver_load(struct drm_device *dev, unsigned long flags); -extern int mga_driver_unload(struct drm_device *dev); -extern void mga_driver_lastclose(struct drm_device *dev); -extern int mga_driver_dma_quiescent(struct drm_device *dev); - -extern int mga_do_wait_for_idle(drm_mga_private_t *dev_priv); - -extern void mga_do_dma_flush(drm_mga_private_t *dev_priv); -extern void mga_do_dma_wrap_start(drm_mga_private_t *dev_priv); -extern void mga_do_dma_wrap_end(drm_mga_private_t *dev_priv); - -extern int mga_freelist_put(struct drm_device *dev, struct drm_buf *buf); - - /* mga_warp.c */ -extern int mga_warp_install_microcode(drm_mga_private_t *dev_priv); -extern int mga_warp_init(drm_mga_private_t *dev_priv); - - /* mga_irq.c */ -extern int mga_enable_vblank(struct drm_device *dev, int crtc); -extern void mga_disable_vblank(struct drm_device *dev, int crtc); -extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc); -extern int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence); -extern int mga_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence); -extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS); -extern void mga_driver_irq_preinstall(struct drm_device *dev); -extern int mga_driver_irq_postinstall(struct drm_device *dev); -extern void mga_driver_irq_uninstall(struct drm_device *dev); -extern long mga_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER() - -#define MGA_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) -#define MGA_READ(reg) DRM_READ32(dev_priv->mmio, (reg)) -#define MGA_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) -#define MGA_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio, (reg), (val)) - -#define DWGREG0 0x1c00 -#define DWGREG0_END 0x1dff -#define DWGREG1 0x2c00 -#define DWGREG1_END 0x2dff - -#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) -#define DMAREG0(r) (u8)((r - DWGREG0) >> 2) -#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) -#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) - -/* ================================================================ - * Helper macross... - */ - -#define MGA_EMIT_STATE(dev_priv, dirty) \ -do { \ - if ((dirty) & ~MGA_UPLOAD_CLIPRECTS) { \ - if (dev_priv->chipset >= MGA_CARD_TYPE_G400) \ - mga_g400_emit_state(dev_priv); \ - else \ - mga_g200_emit_state(dev_priv); \ - } \ -} while (0) - -#define WRAP_TEST_WITH_RETURN(dev_priv) \ -do { \ - if (test_bit(0, &dev_priv->prim.wrapped)) { \ - if (mga_is_idle(dev_priv)) { \ - mga_do_dma_wrap_end(dev_priv); \ - } else if (dev_priv->prim.space < \ - dev_priv->prim.high_mark) { \ - if (MGA_DMA_DEBUG) \ - DRM_INFO("wrap...\n"); \ - return -EBUSY; \ - } \ - } \ -} while (0) - -#define WRAP_WAIT_WITH_RETURN(dev_priv) \ -do { \ - if (test_bit(0, &dev_priv->prim.wrapped)) { \ - if (mga_do_wait_for_idle(dev_priv) < 0) { \ - if (MGA_DMA_DEBUG) \ - DRM_INFO("wrap...\n"); \ - return -EBUSY; \ - } \ - mga_do_dma_wrap_end(dev_priv); \ - } \ -} while (0) - -/* ================================================================ - * Primary DMA command stream - */ - -#define MGA_VERBOSE 0 - -#define DMA_LOCALS unsigned int write; volatile u8 *prim; - -#define DMA_BLOCK_SIZE (5 * sizeof(u32)) - -#define BEGIN_DMA(n) \ -do { \ - if (MGA_VERBOSE) { \ - DRM_INFO("BEGIN_DMA(%d)\n", (n)); \ - DRM_INFO(" space=0x%x req=0x%Zx\n", \ - dev_priv->prim.space, (n) * DMA_BLOCK_SIZE); \ - } \ - prim = dev_priv->prim.start; \ - write = dev_priv->prim.tail; \ -} while (0) - -#define BEGIN_DMA_WRAP() \ -do { \ - if (MGA_VERBOSE) { \ - DRM_INFO("BEGIN_DMA()\n"); \ - DRM_INFO(" space=0x%x\n", dev_priv->prim.space); \ - } \ - prim = dev_priv->prim.start; \ - write = dev_priv->prim.tail; \ -} while (0) - -#define ADVANCE_DMA() \ -do { \ - dev_priv->prim.tail = write; \ - if (MGA_VERBOSE) \ - DRM_INFO("ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \ - write, dev_priv->prim.space); \ -} while (0) - -#define FLUSH_DMA() \ -do { \ - if (0) { \ - DRM_INFO("\n"); \ - DRM_INFO(" tail=0x%06x head=0x%06lx\n", \ - dev_priv->prim.tail, \ - (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \ - dev_priv->primary->offset)); \ - } \ - if (!test_bit(0, &dev_priv->prim.wrapped)) { \ - if (dev_priv->prim.space < dev_priv->prim.high_mark) \ - mga_do_dma_wrap_start(dev_priv); \ - else \ - mga_do_dma_flush(dev_priv); \ - } \ -} while (0) - -/* Never use this, always use DMA_BLOCK(...) for primary DMA output. - */ -#define DMA_WRITE(offset, val) \ -do { \ - if (MGA_VERBOSE) \ - DRM_INFO(" DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ - (u32)(val), write + (offset) * sizeof(u32)); \ - *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ -} while (0) - -#define DMA_BLOCK(reg0, val0, reg1, val1, reg2, val2, reg3, val3) \ -do { \ - DMA_WRITE(0, ((DMAREG(reg0) << 0) | \ - (DMAREG(reg1) << 8) | \ - (DMAREG(reg2) << 16) | \ - (DMAREG(reg3) << 24))); \ - DMA_WRITE(1, val0); \ - DMA_WRITE(2, val1); \ - DMA_WRITE(3, val2); \ - DMA_WRITE(4, val3); \ - write += DMA_BLOCK_SIZE; \ -} while (0) - -/* Buffer aging via primary DMA stream head pointer. - */ - -#define SET_AGE(age, h, w) \ -do { \ - (age)->head = h; \ - (age)->wrap = w; \ -} while (0) - -#define TEST_AGE(age, h, w) ((age)->wrap < w || \ - ((age)->wrap == w && \ - (age)->head < h)) - -#define AGE_BUFFER(buf_priv) \ -do { \ - drm_mga_freelist_t *entry = (buf_priv)->list_entry; \ - if ((buf_priv)->dispatched) { \ - entry->age.head = (dev_priv->prim.tail + \ - dev_priv->primary->offset); \ - entry->age.wrap = dev_priv->sarea_priv->last_wrap; \ - } else { \ - entry->age.head = 0; \ - entry->age.wrap = 0; \ - } \ -} while (0) - -#define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \ - MGA_DWGENGSTS | \ - MGA_ENDPRDMASTS) -#define MGA_DMA_IDLE_MASK (MGA_SOFTRAPEN | \ - MGA_ENDPRDMASTS) - -#define MGA_DMA_DEBUG 0 - -/* A reduced set of the mga registers. - */ -#define MGA_CRTC_INDEX 0x1fd4 -#define MGA_CRTC_DATA 0x1fd5 - -/* CRTC11 */ -#define MGA_VINTCLR (1 << 4) -#define MGA_VINTEN (1 << 5) - -#define MGA_ALPHACTRL 0x2c7c -#define MGA_AR0 0x1c60 -#define MGA_AR1 0x1c64 -#define MGA_AR2 0x1c68 -#define MGA_AR3 0x1c6c -#define MGA_AR4 0x1c70 -#define MGA_AR5 0x1c74 -#define MGA_AR6 0x1c78 - -#define MGA_CXBNDRY 0x1c80 -#define MGA_CXLEFT 0x1ca0 -#define MGA_CXRIGHT 0x1ca4 - -#define MGA_DMAPAD 0x1c54 -#define MGA_DSTORG 0x2cb8 -#define MGA_DWGCTL 0x1c00 -# define MGA_OPCOD_MASK (15 << 0) -# define MGA_OPCOD_TRAP (4 << 0) -# define MGA_OPCOD_TEXTURE_TRAP (6 << 0) -# define MGA_OPCOD_BITBLT (8 << 0) -# define MGA_OPCOD_ILOAD (9 << 0) -# define MGA_ATYPE_MASK (7 << 4) -# define MGA_ATYPE_RPL (0 << 4) -# define MGA_ATYPE_RSTR (1 << 4) -# define MGA_ATYPE_ZI (3 << 4) -# define MGA_ATYPE_BLK (4 << 4) -# define MGA_ATYPE_I (7 << 4) -# define MGA_LINEAR (1 << 7) -# define MGA_ZMODE_MASK (7 << 8) -# define MGA_ZMODE_NOZCMP (0 << 8) -# define MGA_ZMODE_ZE (2 << 8) -# define MGA_ZMODE_ZNE (3 << 8) -# define MGA_ZMODE_ZLT (4 << 8) -# define MGA_ZMODE_ZLTE (5 << 8) -# define MGA_ZMODE_ZGT (6 << 8) -# define MGA_ZMODE_ZGTE (7 << 8) -# define MGA_SOLID (1 << 11) -# define MGA_ARZERO (1 << 12) -# define MGA_SGNZERO (1 << 13) -# define MGA_SHIFTZERO (1 << 14) -# define MGA_BOP_MASK (15 << 16) -# define MGA_BOP_ZERO (0 << 16) -# define MGA_BOP_DST (10 << 16) -# define MGA_BOP_SRC (12 << 16) -# define MGA_BOP_ONE (15 << 16) -# define MGA_TRANS_SHIFT 20 -# define MGA_TRANS_MASK (15 << 20) -# define MGA_BLTMOD_MASK (15 << 25) -# define MGA_BLTMOD_BMONOLEF (0 << 25) -# define MGA_BLTMOD_BMONOWF (4 << 25) -# define MGA_BLTMOD_PLAN (1 << 25) -# define MGA_BLTMOD_BFCOL (2 << 25) -# define MGA_BLTMOD_BU32BGR (3 << 25) -# define MGA_BLTMOD_BU32RGB (7 << 25) -# define MGA_BLTMOD_BU24BGR (11 << 25) -# define MGA_BLTMOD_BU24RGB (15 << 25) -# define MGA_PATTERN (1 << 29) -# define MGA_TRANSC (1 << 30) -# define MGA_CLIPDIS (1 << 31) -#define MGA_DWGSYNC 0x2c4c - -#define MGA_FCOL 0x1c24 -#define MGA_FIFOSTATUS 0x1e10 -#define MGA_FOGCOL 0x1cf4 -#define MGA_FXBNDRY 0x1c84 -#define MGA_FXLEFT 0x1ca8 -#define MGA_FXRIGHT 0x1cac - -#define MGA_ICLEAR 0x1e18 -# define MGA_SOFTRAPICLR (1 << 0) -# define MGA_VLINEICLR (1 << 5) -#define MGA_IEN 0x1e1c -# define MGA_SOFTRAPIEN (1 << 0) -# define MGA_VLINEIEN (1 << 5) - -#define MGA_LEN 0x1c5c - -#define MGA_MACCESS 0x1c04 - -#define MGA_PITCH 0x1c8c -#define MGA_PLNWT 0x1c1c -#define MGA_PRIMADDRESS 0x1e58 -# define MGA_DMA_GENERAL (0 << 0) -# define MGA_DMA_BLIT (1 << 0) -# define MGA_DMA_VECTOR (2 << 0) -# define MGA_DMA_VERTEX (3 << 0) -#define MGA_PRIMEND 0x1e5c -# define MGA_PRIMNOSTART (1 << 0) -# define MGA_PAGPXFER (1 << 1) -#define MGA_PRIMPTR 0x1e50 -# define MGA_PRIMPTREN0 (1 << 0) -# define MGA_PRIMPTREN1 (1 << 1) - -#define MGA_RST 0x1e40 -# define MGA_SOFTRESET (1 << 0) -# define MGA_SOFTEXTRST (1 << 1) - -#define MGA_SECADDRESS 0x2c40 -#define MGA_SECEND 0x2c44 -#define MGA_SETUPADDRESS 0x2cd0 -#define MGA_SETUPEND 0x2cd4 -#define MGA_SGN 0x1c58 -#define MGA_SOFTRAP 0x2c48 -#define MGA_SRCORG 0x2cb4 -# define MGA_SRMMAP_MASK (1 << 0) -# define MGA_SRCMAP_FB (0 << 0) -# define MGA_SRCMAP_SYSMEM (1 << 0) -# define MGA_SRCACC_MASK (1 << 1) -# define MGA_SRCACC_PCI (0 << 1) -# define MGA_SRCACC_AGP (1 << 1) -#define MGA_STATUS 0x1e14 -# define MGA_SOFTRAPEN (1 << 0) -# define MGA_VSYNCPEN (1 << 4) -# define MGA_VLINEPEN (1 << 5) -# define MGA_DWGENGSTS (1 << 16) -# define MGA_ENDPRDMASTS (1 << 17) -#define MGA_STENCIL 0x2cc8 -#define MGA_STENCILCTL 0x2ccc - -#define MGA_TDUALSTAGE0 0x2cf8 -#define MGA_TDUALSTAGE1 0x2cfc -#define MGA_TEXBORDERCOL 0x2c5c -#define MGA_TEXCTL 0x2c30 -#define MGA_TEXCTL2 0x2c3c -# define MGA_DUALTEX (1 << 7) -# define MGA_G400_TC2_MAGIC (1 << 15) -# define MGA_MAP1_ENABLE (1 << 31) -#define MGA_TEXFILTER 0x2c58 -#define MGA_TEXHEIGHT 0x2c2c -#define MGA_TEXORG 0x2c24 -# define MGA_TEXORGMAP_MASK (1 << 0) -# define MGA_TEXORGMAP_FB (0 << 0) -# define MGA_TEXORGMAP_SYSMEM (1 << 0) -# define MGA_TEXORGACC_MASK (1 << 1) -# define MGA_TEXORGACC_PCI (0 << 1) -# define MGA_TEXORGACC_AGP (1 << 1) -#define MGA_TEXORG1 0x2ca4 -#define MGA_TEXORG2 0x2ca8 -#define MGA_TEXORG3 0x2cac -#define MGA_TEXORG4 0x2cb0 -#define MGA_TEXTRANS 0x2c34 -#define MGA_TEXTRANSHIGH 0x2c38 -#define MGA_TEXWIDTH 0x2c28 - -#define MGA_WACCEPTSEQ 0x1dd4 -#define MGA_WCODEADDR 0x1e6c -#define MGA_WFLAG 0x1dc4 -#define MGA_WFLAG1 0x1de0 -#define MGA_WFLAGNB 0x1e64 -#define MGA_WFLAGNB1 0x1e08 -#define MGA_WGETMSB 0x1dc8 -#define MGA_WIADDR 0x1dc0 -#define MGA_WIADDR2 0x1dd8 -# define MGA_WMODE_SUSPEND (0 << 0) -# define MGA_WMODE_RESUME (1 << 0) -# define MGA_WMODE_JUMP (2 << 0) -# define MGA_WMODE_START (3 << 0) -# define MGA_WAGP_ENABLE (1 << 2) -#define MGA_WMISC 0x1e70 -# define MGA_WUCODECACHE_ENABLE (1 << 0) -# define MGA_WMASTER_ENABLE (1 << 1) -# define MGA_WCACHEFLUSH_ENABLE (1 << 3) -#define MGA_WVRTXSZ 0x1dcc - -#define MGA_YBOT 0x1c9c -#define MGA_YDST 0x1c90 -#define MGA_YDSTLEN 0x1c88 -#define MGA_YDSTORG 0x1c94 -#define MGA_YTOP 0x1c98 - -#define MGA_ZORG 0x1c0c - -/* This finishes the current batch of commands - */ -#define MGA_EXEC 0x0100 - -/* AGP PLL encoding (for G200 only). - */ -#define MGA_AGP_PLL 0x1e4c -# define MGA_AGP2XPLL_DISABLE (0 << 0) -# define MGA_AGP2XPLL_ENABLE (1 << 0) - -/* Warp registers - */ -#define MGA_WR0 0x2d00 -#define MGA_WR1 0x2d04 -#define MGA_WR2 0x2d08 -#define MGA_WR3 0x2d0c -#define MGA_WR4 0x2d10 -#define MGA_WR5 0x2d14 -#define MGA_WR6 0x2d18 -#define MGA_WR7 0x2d1c -#define MGA_WR8 0x2d20 -#define MGA_WR9 0x2d24 -#define MGA_WR10 0x2d28 -#define MGA_WR11 0x2d2c -#define MGA_WR12 0x2d30 -#define MGA_WR13 0x2d34 -#define MGA_WR14 0x2d38 -#define MGA_WR15 0x2d3c -#define MGA_WR16 0x2d40 -#define MGA_WR17 0x2d44 -#define MGA_WR18 0x2d48 -#define MGA_WR19 0x2d4c -#define MGA_WR20 0x2d50 -#define MGA_WR21 0x2d54 -#define MGA_WR22 0x2d58 -#define MGA_WR23 0x2d5c -#define MGA_WR24 0x2d60 -#define MGA_WR25 0x2d64 -#define MGA_WR26 0x2d68 -#define MGA_WR27 0x2d6c -#define MGA_WR28 0x2d70 -#define MGA_WR29 0x2d74 -#define MGA_WR30 0x2d78 -#define MGA_WR31 0x2d7c -#define MGA_WR32 0x2d80 -#define MGA_WR33 0x2d84 -#define MGA_WR34 0x2d88 -#define MGA_WR35 0x2d8c -#define MGA_WR36 0x2d90 -#define MGA_WR37 0x2d94 -#define MGA_WR38 0x2d98 -#define MGA_WR39 0x2d9c -#define MGA_WR40 0x2da0 -#define MGA_WR41 0x2da4 -#define MGA_WR42 0x2da8 -#define MGA_WR43 0x2dac -#define MGA_WR44 0x2db0 -#define MGA_WR45 0x2db4 -#define MGA_WR46 0x2db8 -#define MGA_WR47 0x2dbc -#define MGA_WR48 0x2dc0 -#define MGA_WR49 0x2dc4 -#define MGA_WR50 0x2dc8 -#define MGA_WR51 0x2dcc -#define MGA_WR52 0x2dd0 -#define MGA_WR53 0x2dd4 -#define MGA_WR54 0x2dd8 -#define MGA_WR55 0x2ddc -#define MGA_WR56 0x2de0 -#define MGA_WR57 0x2de4 -#define MGA_WR58 0x2de8 -#define MGA_WR59 0x2dec -#define MGA_WR60 0x2df0 -#define MGA_WR61 0x2df4 -#define MGA_WR62 0x2df8 -#define MGA_WR63 0x2dfc -# define MGA_G400_WR_MAGIC (1 << 6) -# define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */ - -#define MGA_ILOAD_ALIGN 64 -#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1) - -#define MGA_DWGCTL_FLUSH (MGA_OPCOD_TEXTURE_TRAP | \ - MGA_ATYPE_I | \ - MGA_ZMODE_NOZCMP | \ - MGA_ARZERO | \ - MGA_SGNZERO | \ - MGA_BOP_SRC | \ - (15 << MGA_TRANS_SHIFT)) - -#define MGA_DWGCTL_CLEAR (MGA_OPCOD_TRAP | \ - MGA_ZMODE_NOZCMP | \ - MGA_SOLID | \ - MGA_ARZERO | \ - MGA_SGNZERO | \ - MGA_SHIFTZERO | \ - MGA_BOP_SRC | \ - (0 << MGA_TRANS_SHIFT) | \ - MGA_BLTMOD_BMONOLEF | \ - MGA_TRANSC | \ - MGA_CLIPDIS) - -#define MGA_DWGCTL_COPY (MGA_OPCOD_BITBLT | \ - MGA_ATYPE_RPL | \ - MGA_SGNZERO | \ - MGA_SHIFTZERO | \ - MGA_BOP_SRC | \ - (0 << MGA_TRANS_SHIFT) | \ - MGA_BLTMOD_BFCOL | \ - MGA_CLIPDIS) - -/* Simple idle test. - */ -static __inline__ int mga_is_idle(drm_mga_private_t *dev_priv) -{ - u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK; - return (status == MGA_ENDPRDMASTS); -} - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_ioc32.c b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_ioc32.c deleted file mode 100644 index c1f877b7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_ioc32.c +++ /dev/null @@ -1,226 +0,0 @@ -/** - * \file mga_ioc32.c - * - * 32-bit ioctl compatibility routines for the MGA DRM. - * - * \author Dave Airlie with code from patches by Egbert Eich - * - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Egbert Eich 2003,2004 - * Copyright (C) Dave Airlie 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" - -typedef struct drm32_mga_init { - int func; - u32 sarea_priv_offset; - int chipset; - int sgram; - unsigned int maccess; - unsigned int fb_cpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_cpp; - unsigned int depth_offset, depth_pitch; - unsigned int texture_offset[MGA_NR_TEX_HEAPS]; - unsigned int texture_size[MGA_NR_TEX_HEAPS]; - u32 fb_offset; - u32 mmio_offset; - u32 status_offset; - u32 warp_offset; - u32 primary_offset; - u32 buffers_offset; -} drm_mga_init32_t; - -static int compat_mga_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_mga_init32_t init32; - drm_mga_init_t __user *init; - int err = 0, i; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.chipset, &init->chipset) - || __put_user(init32.sgram, &init->sgram) - || __put_user(init32.maccess, &init->maccess) - || __put_user(init32.fb_cpp, &init->fb_cpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_cpp, &init->depth_cpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.status_offset, &init->status_offset) - || __put_user(init32.warp_offset, &init->warp_offset) - || __put_user(init32.primary_offset, &init->primary_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset)) - return -EFAULT; - - for (i = 0; i < MGA_NR_TEX_HEAPS; i++) { - err |= - __put_user(init32.texture_offset[i], - &init->texture_offset[i]); - err |= - __put_user(init32.texture_size[i], &init->texture_size[i]); - } - if (err) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init); -} - -typedef struct drm_mga_getparam32 { - int param; - u32 value; -} drm_mga_getparam32_t; - -static int compat_mga_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_mga_getparam32_t getparam32; - drm_mga_getparam_t __user *getparam; - - if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) - return -EFAULT; - - getparam = compat_alloc_user_space(sizeof(*getparam)); - if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) - || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, - &getparam->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); -} - -typedef struct drm_mga_drm_bootstrap32 { - u32 texture_handle; - u32 texture_size; - u32 primary_size; - u32 secondary_bin_count; - u32 secondary_bin_size; - u32 agp_mode; - u8 agp_size; -} drm_mga_dma_bootstrap32_t; - -static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_mga_dma_bootstrap32_t dma_bootstrap32; - drm_mga_dma_bootstrap_t __user *dma_bootstrap; - int err; - - if (copy_from_user(&dma_bootstrap32, (void __user *)arg, - sizeof(dma_bootstrap32))) - return -EFAULT; - - dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap)); - if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap)) - || __put_user(dma_bootstrap32.texture_handle, - &dma_bootstrap->texture_handle) - || __put_user(dma_bootstrap32.texture_size, - &dma_bootstrap->texture_size) - || __put_user(dma_bootstrap32.primary_size, - &dma_bootstrap->primary_size) - || __put_user(dma_bootstrap32.secondary_bin_count, - &dma_bootstrap->secondary_bin_count) - || __put_user(dma_bootstrap32.secondary_bin_size, - &dma_bootstrap->secondary_bin_size) - || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) - || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) - return -EFAULT; - - err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP, - (unsigned long)dma_bootstrap); - if (err) - return err; - - if (__get_user(dma_bootstrap32.texture_handle, - &dma_bootstrap->texture_handle) - || __get_user(dma_bootstrap32.texture_size, - &dma_bootstrap->texture_size) - || __get_user(dma_bootstrap32.primary_size, - &dma_bootstrap->primary_size) - || __get_user(dma_bootstrap32.secondary_bin_count, - &dma_bootstrap->secondary_bin_count) - || __get_user(dma_bootstrap32.secondary_bin_size, - &dma_bootstrap->secondary_bin_size) - || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode) - || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) - return -EFAULT; - - if (copy_to_user((void __user *)arg, &dma_bootstrap32, - sizeof(dma_bootstrap32))) - return -EFAULT; - - return 0; -} - -drm_ioctl_compat_t *mga_compat_ioctls[] = { - [DRM_MGA_INIT] = compat_mga_init, - [DRM_MGA_GETPARAM] = compat_mga_getparam, - [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) - fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_irq.c deleted file mode 100644 index 25812022..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_irq.c +++ /dev/null @@ -1,174 +0,0 @@ -/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*- - */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - * Eric Anholt - */ - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -u32 mga_get_vblank_counter(struct drm_device *dev, int crtc) -{ - const drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; - - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); -} - - -irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - int status; - int handled = 0; - - status = MGA_READ(MGA_STATUS); - - /* VBLANK interrupt */ - if (status & MGA_VLINEPEN) { - MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); - atomic_inc(&dev_priv->vbl_received); - drm_handle_vblank(dev, 0); - handled = 1; - } - - /* SOFTRAP interrupt */ - if (status & MGA_SOFTRAPEN) { - const u32 prim_start = MGA_READ(MGA_PRIMADDRESS); - const u32 prim_end = MGA_READ(MGA_PRIMEND); - - - MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR); - - /* In addition to clearing the interrupt-pending bit, we - * have to write to MGA_PRIMEND to re-start the DMA operation. - */ - if ((prim_start & ~0x03) != (prim_end & ~0x03)) - MGA_WRITE(MGA_PRIMEND, prim_end); - - atomic_inc(&dev_priv->last_fence_retired); - DRM_WAKEUP(&dev_priv->fence_queue); - handled = 1; - } - - if (handled) - return IRQ_HANDLED; - return IRQ_NONE; -} - -int mga_enable_vblank(struct drm_device *dev, int crtc) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - if (crtc != 0) { - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return 0; - } - - MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); - return 0; -} - - -void mga_disable_vblank(struct drm_device *dev, int crtc) -{ - if (crtc != 0) { - DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", - crtc); - } - - /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have - * a nice hardware counter that tracks the number of refreshes when - * the interrupt is disabled, and the kernel doesn't know the refresh - * rate to calculate an estimate. - */ - /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */ -} - -int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - unsigned int cur_fence; - int ret = 0; - - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using fences. - */ - DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ, - (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) - - *sequence) <= (1 << 23))); - - *sequence = cur_fence; - - return ret; -} - -void mga_driver_irq_preinstall(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - /* Disable *all* interrupts */ - MGA_WRITE(MGA_IEN, 0); - /* Clear bits if they're already high */ - MGA_WRITE(MGA_ICLEAR, ~0); -} - -int mga_driver_irq_postinstall(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - - DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); - - /* Turn on soft trap interrupt. Vertical blank interrupts are enabled - * in mga_enable_vblank. - */ - MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN); - return 0; -} - -void mga_driver_irq_uninstall(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - if (!dev_priv) - return; - - /* Disable *all* interrupts */ - MGA_WRITE(MGA_IEN, 0); - - dev->irq_enabled = 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_state.c b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_state.c deleted file mode 100644 index 9ce2827f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_state.c +++ /dev/null @@ -1,1103 +0,0 @@ -/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*- - * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jeff Hartmann - * Keith Whitwell - * - * Rewritten by: - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -/* ================================================================ - * DMA hardware state programming functions - */ - -static void mga_emit_clip_rect(drm_mga_private_t *dev_priv, - struct drm_clip_rect *box) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - unsigned int pitch = dev_priv->front_pitch; - DMA_LOCALS; - - BEGIN_DMA(2); - - /* Force reset of DWGCTL on G400 (eliminates clip disable bit). - */ - if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { - DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl, - MGA_LEN + MGA_EXEC, 0x80000000, - MGA_DWGCTL, ctx->dwgctl, - MGA_LEN + MGA_EXEC, 0x80000000); - } - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1, - MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - DMA_LOCALS; - - BEGIN_DMA(3); - - DMA_BLOCK(MGA_DSTORG, ctx->dstorg, - MGA_MACCESS, ctx->maccess, - MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - - DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, - MGA_FOGCOL, ctx->fogcolor, - MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); - - DMA_BLOCK(MGA_FCOL, ctx->fcol, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - DMA_LOCALS; - - BEGIN_DMA(4); - - DMA_BLOCK(MGA_DSTORG, ctx->dstorg, - MGA_MACCESS, ctx->maccess, - MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - - DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl, - MGA_FOGCOL, ctx->fogcolor, - MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset); - - DMA_BLOCK(MGA_WFLAG1, ctx->wflag, - MGA_TDUALSTAGE0, ctx->tdualstage0, - MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol); - - DMA_BLOCK(MGA_STENCIL, ctx->stencil, - MGA_STENCILCTL, ctx->stencilctl, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; - DMA_LOCALS; - - BEGIN_DMA(4); - - DMA_BLOCK(MGA_TEXCTL2, tex->texctl2, - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol); - - DMA_BLOCK(MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - - DMA_BLOCK(MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth); - - DMA_BLOCK(MGA_WR34, tex->texheight, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_tex0(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; - DMA_LOCALS; - -/* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */ -/* tex->texctl, tex->texctl2); */ - - BEGIN_DMA(6); - - DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol); - - DMA_BLOCK(MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - - DMA_BLOCK(MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); - - DMA_BLOCK(MGA_WR57, 0x00000000, - MGA_WR53, 0x00000000, - MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC); - - DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC, - MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, - MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, - MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_tex1(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; - DMA_LOCALS; - -/* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */ -/* tex->texctl, tex->texctl2); */ - - BEGIN_DMA(5); - - DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 | - MGA_MAP1_ENABLE | - MGA_G400_TC2_MAGIC), - MGA_TEXCTL, tex->texctl, - MGA_TEXFILTER, tex->texfilter, - MGA_TEXBORDERCOL, tex->texbordercol); - - DMA_BLOCK(MGA_TEXORG, tex->texorg, - MGA_TEXORG1, tex->texorg1, - MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3); - - DMA_BLOCK(MGA_TEXORG4, tex->texorg4, - MGA_TEXWIDTH, tex->texwidth, - MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000); - - DMA_BLOCK(MGA_WR57, 0x00000000, - MGA_WR53, 0x00000000, - MGA_WR61, 0x00000000, - MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC); - - DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, - MGA_TEXTRANS, 0x0000ffff, - MGA_TEXTRANSHIGH, 0x0000ffff, - MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g200_emit_pipe(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int pipe = sarea_priv->warp_pipe; - DMA_LOCALS; - - BEGIN_DMA(3); - - DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND, - MGA_WVRTXSZ, 0x00000007, - MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000); - - DMA_BLOCK(MGA_WR25, 0x00000100, - MGA_WR34, 0x00000000, - MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff); - - /* Padding required due to hardware bug. - */ - DMA_BLOCK(MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | - MGA_WMODE_START | dev_priv->wagp_enable)); - - ADVANCE_DMA(); -} - -static __inline__ void mga_g400_emit_pipe(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int pipe = sarea_priv->warp_pipe; - DMA_LOCALS; - -/* printk("mga_g400_emit_pipe %x\n", pipe); */ - - BEGIN_DMA(10); - - DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - if (pipe & MGA_T2) { - DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x1e000000); - } else { - if (dev_priv->warp_pipe & MGA_T2) { - /* Flush the WARP pipe */ - DMA_BLOCK(MGA_YDST, 0x00000000, - MGA_FXLEFT, 0x00000000, - MGA_FXRIGHT, 0x00000001, - MGA_DWGCTL, MGA_DWGCTL_FLUSH); - - DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001, - MGA_DWGSYNC, 0x00007000, - MGA_TEXCTL2, MGA_G400_TC2_MAGIC, - MGA_LEN + MGA_EXEC, 0x00000000); - - DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX | - MGA_G400_TC2_MAGIC), - MGA_LEN + MGA_EXEC, 0x00000000, - MGA_TEXCTL2, MGA_G400_TC2_MAGIC, - MGA_DMAPAD, 0x00000000); - } - - DMA_BLOCK(MGA_WVRTXSZ, 0x00001807, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x00000000, - MGA_WACCEPTSEQ, 0x18000000); - } - - DMA_BLOCK(MGA_WFLAG, 0x00000000, - MGA_WFLAG1, 0x00000000, - MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000); - - DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0 */ - MGA_WR57, 0x00000000, /* tex0 */ - MGA_WR53, 0x00000000, /* tex1 */ - MGA_WR61, 0x00000000); /* tex1 */ - - DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ - MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ - MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ - MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height */ - - /* Padding required due to hardware bug */ - DMA_BLOCK(MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_DMAPAD, 0xffffffff, - MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | - MGA_WMODE_START | dev_priv->wagp_enable)); - - ADVANCE_DMA(); -} - -static void mga_g200_emit_state(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { - mga_g200_emit_pipe(dev_priv); - dev_priv->warp_pipe = sarea_priv->warp_pipe; - } - - if (dirty & MGA_UPLOAD_CONTEXT) { - mga_g200_emit_context(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; - } - - if (dirty & MGA_UPLOAD_TEX0) { - mga_g200_emit_tex0(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; - } -} - -static void mga_g400_emit_state(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - int multitex = sarea_priv->warp_pipe & MGA_T2; - - if (sarea_priv->warp_pipe != dev_priv->warp_pipe) { - mga_g400_emit_pipe(dev_priv); - dev_priv->warp_pipe = sarea_priv->warp_pipe; - } - - if (dirty & MGA_UPLOAD_CONTEXT) { - mga_g400_emit_context(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; - } - - if (dirty & MGA_UPLOAD_TEX0) { - mga_g400_emit_tex0(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; - } - - if ((dirty & MGA_UPLOAD_TEX1) && multitex) { - mga_g400_emit_tex1(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; - } -} - -/* ================================================================ - * SAREA state verification - */ - -/* Disallow all write destinations except the front and backbuffer. - */ -static int mga_verify_context(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - - if (ctx->dstorg != dev_priv->front_offset && - ctx->dstorg != dev_priv->back_offset) { - DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n", - ctx->dstorg, dev_priv->front_offset, - dev_priv->back_offset); - ctx->dstorg = 0; - return -EINVAL; - } - - return 0; -} - -/* Disallow texture reads from PCI space. - */ -static int mga_verify_tex(drm_mga_private_t *dev_priv, int unit) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; - unsigned int org; - - org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK); - - if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) { - DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit); - tex->texorg = 0; - return -EINVAL; - } - - return 0; -} - -static int mga_verify_state(drm_mga_private_t *dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - int ret = 0; - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - if (dirty & MGA_UPLOAD_CONTEXT) - ret |= mga_verify_context(dev_priv); - - if (dirty & MGA_UPLOAD_TEX0) - ret |= mga_verify_tex(dev_priv, 0); - - if (dev_priv->chipset >= MGA_CARD_TYPE_G400) { - if (dirty & MGA_UPLOAD_TEX1) - ret |= mga_verify_tex(dev_priv, 1); - - if (dirty & MGA_UPLOAD_PIPE) - ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES); - } else { - if (dirty & MGA_UPLOAD_PIPE) - ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES); - } - - return (ret == 0); -} - -static int mga_verify_iload(drm_mga_private_t *dev_priv, - unsigned int dstorg, unsigned int length) -{ - if (dstorg < dev_priv->texture_offset || - dstorg + length > (dev_priv->texture_offset + - dev_priv->texture_size)) { - DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg); - return -EINVAL; - } - - if (length & MGA_ILOAD_MASK) { - DRM_ERROR("*** bad iload length: 0x%x\n", - length & MGA_ILOAD_MASK); - return -EINVAL; - } - - return 0; -} - -static int mga_verify_blit(drm_mga_private_t *dev_priv, - unsigned int srcorg, unsigned int dstorg) -{ - if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || - (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) { - DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg); - return -EINVAL; - } - return 0; -} - -/* ================================================================ - * - */ - -static void mga_dma_dispatch_clear(struct drm_device *dev, drm_mga_clear_t *clear) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - int i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - ADVANCE_DMA(); - - for (i = 0; i < nbox; i++) { - struct drm_clip_rect *box = &pbox[i]; - u32 height = box->y2 - box->y1; - - DRM_DEBUG(" from=%d,%d to=%d,%d\n", - box->x1, box->y1, box->x2, box->y2); - - if (clear->flags & MGA_FRONT) { - BEGIN_DMA(2); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->color_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_color, - MGA_DSTORG, dev_priv->front_offset, - MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); - - ADVANCE_DMA(); - } - - if (clear->flags & MGA_BACK) { - BEGIN_DMA(2); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->color_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_color, - MGA_DSTORG, dev_priv->back_offset, - MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); - - ADVANCE_DMA(); - } - - if (clear->flags & MGA_DEPTH) { - BEGIN_DMA(2); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, clear->depth_mask, - MGA_YDSTLEN, (box->y1 << 16) | height, - MGA_FXBNDRY, (box->x2 << 16) | box->x1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_FCOL, clear->clear_depth, - MGA_DSTORG, dev_priv->depth_offset, - MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd); - - ADVANCE_DMA(); - } - - } - - BEGIN_DMA(1); - - /* Force reset of DWGCTL */ - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl); - - ADVANCE_DMA(); - - FLUSH_DMA(); -} - -static void mga_dma_dispatch_swap(struct drm_device *dev) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - int i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - sarea_priv->last_frame.head = dev_priv->prim.tail; - sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; - - BEGIN_DMA(4 + nbox); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset, - MGA_MACCESS, dev_priv->maccess, - MGA_SRCORG, dev_priv->back_offset, - MGA_AR5, dev_priv->front_pitch); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY); - - for (i = 0; i < nbox; i++) { - struct drm_clip_rect *box = &pbox[i]; - u32 height = box->y2 - box->y1; - u32 start = box->y1 * dev_priv->front_pitch; - - DRM_DEBUG(" from=%d,%d to=%d,%d\n", - box->x1, box->y1, box->x2, box->y2); - - DMA_BLOCK(MGA_AR0, start + box->x2 - 1, - MGA_AR3, start + box->x1, - MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, - MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height); - } - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl); - - ADVANCE_DMA(); - - FLUSH_DMA(); - - DRM_DEBUG("... done.\n"); -} - -static void mga_dma_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 address = (u32) buf->bus_address; - u32 length = (u32) buf->used; - int i = 0; - DMA_LOCALS; - DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); - - if (buf->used) { - buf_priv->dispatched = 1; - - MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); - - do { - if (i < sarea_priv->nbox) { - mga_emit_clip_rect(dev_priv, - &sarea_priv->boxes[i]); - } - - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_SECADDRESS, (address | - MGA_DMA_VERTEX), - MGA_SECEND, ((address + length) | - dev_priv->dma_access)); - - ADVANCE_DMA(); - } while (++i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - AGE_BUFFER(buf_priv); - buf->pending = 0; - buf->used = 0; - buf_priv->dispatched = 0; - - mga_freelist_put(dev, buf); - } - - FLUSH_DMA(); -} - -static void mga_dma_dispatch_indices(struct drm_device *dev, struct drm_buf *buf, - unsigned int start, unsigned int end) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - u32 address = (u32) buf->bus_address; - int i = 0; - DMA_LOCALS; - DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end); - - if (start != end) { - buf_priv->dispatched = 1; - - MGA_EMIT_STATE(dev_priv, sarea_priv->dirty); - - do { - if (i < sarea_priv->nbox) { - mga_emit_clip_rect(dev_priv, - &sarea_priv->boxes[i]); - } - - BEGIN_DMA(1); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_SETUPADDRESS, address + start, - MGA_SETUPEND, ((address + end) | - dev_priv->dma_access)); - - ADVANCE_DMA(); - } while (++i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - AGE_BUFFER(buf_priv); - buf->pending = 0; - buf->used = 0; - buf_priv->dispatched = 0; - - mga_freelist_put(dev, buf); - } - - FLUSH_DMA(); -} - -/* This copies a 64 byte aligned agp region to the frambuffer with a - * standard blit, the ioctl needs to do checking. - */ -static void mga_dma_dispatch_iload(struct drm_device *dev, struct drm_buf *buf, - unsigned int dstorg, unsigned int length) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_buf_priv_t *buf_priv = buf->dev_private; - drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; - u32 srcorg = - buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM; - u32 y2; - DMA_LOCALS; - DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used); - - y2 = length / 64; - - BEGIN_DMA(5); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - DMA_BLOCK(MGA_DSTORG, dstorg, - MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64); - - DMA_BLOCK(MGA_PITCH, 64, - MGA_PLNWT, 0xffffffff, - MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY); - - DMA_BLOCK(MGA_AR0, 63, - MGA_AR3, 0, - MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2); - - DMA_BLOCK(MGA_PLNWT, ctx->plnwt, - MGA_SRCORG, dev_priv->front_offset, - MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000); - - ADVANCE_DMA(); - - AGE_BUFFER(buf_priv); - - buf->pending = 0; - buf->used = 0; - buf_priv->dispatched = 0; - - mga_freelist_put(dev, buf); - - FLUSH_DMA(); -} - -static void mga_dma_dispatch_blit(struct drm_device *dev, drm_mga_blit_t *blit) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_context_regs_t *ctx = &sarea_priv->context_state; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - u32 scandir = 0, i; - DMA_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_DMA(4 + nbox); - - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000); - - DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY, - MGA_PLNWT, blit->planemask, - MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg); - - DMA_BLOCK(MGA_SGN, scandir, - MGA_MACCESS, dev_priv->maccess, - MGA_AR5, blit->ydir * blit->src_pitch, - MGA_PITCH, blit->dst_pitch); - - for (i = 0; i < nbox; i++) { - int srcx = pbox[i].x1 + blit->delta_sx; - int srcy = pbox[i].y1 + blit->delta_sy; - int dstx = pbox[i].x1 + blit->delta_dx; - int dsty = pbox[i].y1 + blit->delta_dy; - int h = pbox[i].y2 - pbox[i].y1; - int w = pbox[i].x2 - pbox[i].x1 - 1; - int start; - - if (blit->ydir == -1) - srcy = blit->height - srcy - 1; - - start = srcy * blit->src_pitch + srcx; - - DMA_BLOCK(MGA_AR0, start + w, - MGA_AR3, start, - MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), - MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h); - } - - /* Do something to flush AGP? - */ - - /* Force reset of DWGCTL */ - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_PLNWT, ctx->plnwt, - MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl); - - ADVANCE_DMA(); -} - -/* ================================================================ - * - */ - -static int mga_dma_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_clear_t *clear = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_clear(dev, clear); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_swap(dev); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (vertex->idx < 0 || vertex->idx > dma->buf_count) - return -EINVAL; - buf = dma->buflist[vertex->idx]; - buf_priv = buf->dev_private; - - buf->used = vertex->used; - buf_priv->discard = vertex->discard; - - if (!mga_verify_state(dev_priv)) { - if (vertex->discard) { - if (buf_priv->dispatched == 1) - AGE_BUFFER(buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_vertex(dev, buf); - - return 0; -} - -static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_indices_t *indices = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (indices->idx < 0 || indices->idx > dma->buf_count) - return -EINVAL; - - buf = dma->buflist[indices->idx]; - buf_priv = buf->dev_private; - - buf_priv->discard = indices->discard; - - if (!mga_verify_state(dev_priv)) { - if (indices->discard) { - if (buf_priv->dispatched == 1) - AGE_BUFFER(buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_indices(dev, buf, indices->start, indices->end); - - return 0; -} - -static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_mga_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - drm_mga_buf_priv_t *buf_priv; - drm_mga_iload_t *iload = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -#if 0 - if (mga_do_wait_for_idle(dev_priv) < 0) { - if (MGA_DMA_DEBUG) - DRM_INFO("-EBUSY\n"); - return -EBUSY; - } -#endif - if (iload->idx < 0 || iload->idx > dma->buf_count) - return -EINVAL; - - buf = dma->buflist[iload->idx]; - buf_priv = buf->dev_private; - - if (mga_verify_iload(dev_priv, iload->dstorg, iload->length)) { - mga_freelist_put(dev, buf); - return -EINVAL; - } - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_iload(dev, buf, iload->dstorg, iload->length); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_blit_t *blit = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - - if (mga_verify_blit(dev_priv, blit->srcorg, blit->dstorg)) - return -EINVAL; - - WRAP_TEST_WITH_RETURN(dev_priv); - - mga_dma_dispatch_blit(dev, blit); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - - return 0; -} - -static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_getparam_t *param = data; - int value; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - switch (param->param) { - case MGA_PARAM_IRQ_NR: - value = drm_dev_to_irq(dev); - break; - case MGA_PARAM_CARD_TYPE: - value = dev_priv->chipset; - break; - default: - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - u32 *fence = data; - DMA_LOCALS; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - /* I would normal do this assignment in the declaration of fence, - * but dev_priv may be NULL. - */ - - *fence = dev_priv->next_fence_to_post; - dev_priv->next_fence_to_post++; - - BEGIN_DMA(1); - DMA_BLOCK(MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, - MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000); - ADVANCE_DMA(); - - return 0; -} - -static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file * -file_priv) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - u32 *fence = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - mga_driver_fence_wait(dev, fence); - return 0; -} - -struct drm_ioctl_desc mga_ioctls[] = { - DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), - DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -}; - -int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_warp.c b/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_warp.c deleted file mode 100644 index 722a91b6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/mga/mga_warp.c +++ /dev/null @@ -1,170 +0,0 @@ -/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*- - * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com - * - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "mga_drm.h" -#include "mga_drv.h" - -#define FIRMWARE_G200 "matrox/g200_warp.fw" -#define FIRMWARE_G400 "matrox/g400_warp.fw" - -MODULE_FIRMWARE(FIRMWARE_G200); -MODULE_FIRMWARE(FIRMWARE_G400); - -#define MGA_WARP_CODE_ALIGN 256 /* in bytes */ - -#define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) - -int mga_warp_install_microcode(drm_mga_private_t *dev_priv) -{ - unsigned char *vcbase = dev_priv->warp->handle; - unsigned long pcbase = dev_priv->warp->offset; - const char *firmware_name; - struct platform_device *pdev; - const struct firmware *fw = NULL; - const struct ihex_binrec *rec; - unsigned int size; - int n_pipes, where; - int rc = 0; - - switch (dev_priv->chipset) { - case MGA_CARD_TYPE_G400: - case MGA_CARD_TYPE_G550: - firmware_name = FIRMWARE_G400; - n_pipes = MGA_MAX_G400_PIPES; - break; - case MGA_CARD_TYPE_G200: - firmware_name = FIRMWARE_G200; - n_pipes = MGA_MAX_G200_PIPES; - break; - default: - return -EINVAL; - } - - pdev = platform_device_register_simple("mga_warp", 0, NULL, 0); - if (IS_ERR(pdev)) { - DRM_ERROR("mga: Failed to register microcode\n"); - return PTR_ERR(pdev); - } - rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); - platform_device_unregister(pdev); - if (rc) { - DRM_ERROR("mga: Failed to load microcode \"%s\"\n", - firmware_name); - return rc; - } - - size = 0; - where = 0; - for (rec = (const struct ihex_binrec *)fw->data; - rec; - rec = ihex_next_binrec(rec)) { - size += WARP_UCODE_SIZE(be16_to_cpu(rec->len)); - where++; - } - - if (where != n_pipes) { - DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name); - rc = -EINVAL; - goto out; - } - size = PAGE_ALIGN(size); - DRM_DEBUG("MGA ucode size = %d bytes\n", size); - if (size > dev_priv->warp->size) { - DRM_ERROR("microcode too large! (%u > %lu)\n", - size, dev_priv->warp->size); - rc = -ENOMEM; - goto out; - } - - memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); - - where = 0; - for (rec = (const struct ihex_binrec *)fw->data; - rec; - rec = ihex_next_binrec(rec)) { - unsigned int src_size, dst_size; - - DRM_DEBUG(" pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase); - dev_priv->warp_pipe_phys[where] = pcbase; - src_size = be16_to_cpu(rec->len); - dst_size = WARP_UCODE_SIZE(src_size); - memcpy(vcbase, rec->data, src_size); - pcbase += dst_size; - vcbase += dst_size; - where++; - } - -out: - release_firmware(fw); - return rc; -} - -#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) - -int mga_warp_init(drm_mga_private_t *dev_priv) -{ - u32 wmisc; - - /* FIXME: Get rid of these damned magic numbers... - */ - switch (dev_priv->chipset) { - case MGA_CARD_TYPE_G400: - case MGA_CARD_TYPE_G550: - MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND); - MGA_WRITE(MGA_WGETMSB, 0x00000E00); - MGA_WRITE(MGA_WVRTXSZ, 0x00001807); - MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000); - break; - case MGA_CARD_TYPE_G200: - MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND); - MGA_WRITE(MGA_WGETMSB, 0x1606); - MGA_WRITE(MGA_WVRTXSZ, 7); - break; - default: - return -EINVAL; - } - - MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE | - MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE)); - wmisc = MGA_READ(MGA_WMISC); - if (wmisc != WMISC_EXPECTED) { - DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n", - wmisc, WMISC_EXPECTED); - return -EINVAL; - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/Kconfig b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/Kconfig deleted file mode 100644 index 97a81260..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/Kconfig +++ /dev/null @@ -1,57 +0,0 @@ -config DRM_NOUVEAU - tristate "Nouveau (nVidia) cards" - depends on DRM && PCI - select FW_LOADER - select DRM_KMS_HELPER - select DRM_TTM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB - select FRAMEBUFFER_CONSOLE if !EXPERT - select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT - select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT - select ACPI_WMI if ACPI - select MXM_WMI if ACPI - select POWER_SUPPLY - help - Choose this option for open-source nVidia support. - -config DRM_NOUVEAU_BACKLIGHT - bool "Support for backlight control" - depends on DRM_NOUVEAU - default y - help - Say Y here if you want to control the backlight of your display - (e.g. a laptop panel). - -config DRM_NOUVEAU_DEBUG - bool "Build in Nouveau's debugfs support" - depends on DRM_NOUVEAU && DEBUG_FS - default y - help - Say Y here if you want Nouveau to output debugging information - via debugfs. - -menu "I2C encoder or helper chips" - depends on DRM && DRM_KMS_HELPER && I2C - -config DRM_I2C_CH7006 - tristate "Chrontel ch7006 TV encoder" - default m if DRM_NOUVEAU - help - Support for Chrontel ch7006 and similar TV encoders, found - on some nVidia video cards. - - This driver is currently only useful if you're also using - the nouveau driver. - -config DRM_I2C_SIL164 - tristate "Silicon Image sil164 TMDS transmitter" - default m if DRM_NOUVEAU - help - Support for sil164 and similar single-link (or dual-link - when used in pairs) TMDS transmitters, used in some nVidia - video cards. - -endmenu diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/Makefile deleted file mode 100644 index 1a2ad7eb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ - nouveau_object.o nouveau_irq.o nouveau_notifier.o \ - nouveau_sgdma.o nouveau_dma.o nouveau_util.o \ - nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ - nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ - nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ - nouveau_hdmi.o nouveau_dp.o nouveau_ramht.o \ - nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \ - nouveau_mm.o nouveau_vm.o nouveau_mxm.o nouveau_gpio.o \ - nv04_timer.o \ - nv04_mc.o nv40_mc.o nv50_mc.o \ - nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \ - nv50_fb.o nvc0_fb.o \ - nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \ - nv04_graph.o nv10_graph.o nv20_graph.o \ - nv40_graph.o nv50_graph.o nvc0_graph.o \ - nv40_grctx.o nv50_grctx.o nvc0_grctx.o \ - nv84_crypt.o nv98_crypt.o \ - nva3_copy.o nvc0_copy.o \ - nv31_mpeg.o nv50_mpeg.o \ - nv84_bsp.o \ - nv84_vp.o \ - nv98_ppp.o \ - nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ - nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ - nv04_crtc.o nv04_display.o nv04_cursor.o \ - nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \ - nv50_cursor.o nv50_display.o \ - nvd0_display.o \ - nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o \ - nv10_gpio.o nv50_gpio.o \ - nv50_calc.o \ - nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o \ - nv50_vram.o nvc0_vram.o \ - nv50_vm.o nvc0_vm.o - -nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o -nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o -nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o -nouveau-$(CONFIG_ACPI) += nouveau_acpi.o - -obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_acpi.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_acpi.c deleted file mode 100644 index 284bd25d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ /dev/null @@ -1,430 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "drm_crtc_helper.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nv50_display.h" -#include "nouveau_connector.h" - -#include - -#define NOUVEAU_DSM_LED 0x02 -#define NOUVEAU_DSM_LED_STATE 0x00 -#define NOUVEAU_DSM_LED_OFF 0x10 -#define NOUVEAU_DSM_LED_STAMINA 0x11 -#define NOUVEAU_DSM_LED_SPEED 0x12 - -#define NOUVEAU_DSM_POWER 0x03 -#define NOUVEAU_DSM_POWER_STATE 0x00 -#define NOUVEAU_DSM_POWER_SPEED 0x01 -#define NOUVEAU_DSM_POWER_STAMINA 0x02 - -#define NOUVEAU_DSM_OPTIMUS_FN 0x1A -#define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001 - -static struct nouveau_dsm_priv { - bool dsm_detected; - bool optimus_detected; - acpi_handle dhandle; - acpi_handle rom_handle; -} nouveau_dsm_priv; - -#define NOUVEAU_DSM_HAS_MUX 0x1 -#define NOUVEAU_DSM_HAS_OPT 0x2 - -static const char nouveau_dsm_muid[] = { - 0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D, - 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4, -}; - -static const char nouveau_op_dsm_muid[] = { - 0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47, - 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0, -}; - -static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result) -{ - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_object_list input; - union acpi_object params[4]; - union acpi_object *obj; - int i, err; - char args_buff[4]; - - input.count = 4; - input.pointer = params; - params[0].type = ACPI_TYPE_BUFFER; - params[0].buffer.length = sizeof(nouveau_op_dsm_muid); - params[0].buffer.pointer = (char *)nouveau_op_dsm_muid; - params[1].type = ACPI_TYPE_INTEGER; - params[1].integer.value = 0x00000100; - params[2].type = ACPI_TYPE_INTEGER; - params[2].integer.value = func; - params[3].type = ACPI_TYPE_BUFFER; - params[3].buffer.length = 4; - /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ - for (i = 0; i < 4; i++) - args_buff[i] = (arg >> i * 8) & 0xFF; - params[3].buffer.pointer = args_buff; - - err = acpi_evaluate_object(handle, "_DSM", &input, &output); - if (err) { - printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); - return err; - } - - obj = (union acpi_object *)output.pointer; - - if (obj->type == ACPI_TYPE_INTEGER) - if (obj->integer.value == 0x80000002) { - return -ENODEV; - } - - if (obj->type == ACPI_TYPE_BUFFER) { - if (obj->buffer.length == 4 && result) { - *result = 0; - *result |= obj->buffer.pointer[0]; - *result |= (obj->buffer.pointer[1] << 8); - *result |= (obj->buffer.pointer[2] << 16); - *result |= (obj->buffer.pointer[3] << 24); - } - } - - kfree(output.pointer); - return 0; -} - -static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) -{ - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_object_list input; - union acpi_object params[4]; - union acpi_object *obj; - int err; - - input.count = 4; - input.pointer = params; - params[0].type = ACPI_TYPE_BUFFER; - params[0].buffer.length = sizeof(nouveau_dsm_muid); - params[0].buffer.pointer = (char *)nouveau_dsm_muid; - params[1].type = ACPI_TYPE_INTEGER; - params[1].integer.value = 0x00000102; - params[2].type = ACPI_TYPE_INTEGER; - params[2].integer.value = func; - params[3].type = ACPI_TYPE_INTEGER; - params[3].integer.value = arg; - - err = acpi_evaluate_object(handle, "_DSM", &input, &output); - if (err) { - printk(KERN_INFO "failed to evaluate _DSM: %d\n", err); - return err; - } - - obj = (union acpi_object *)output.pointer; - - if (obj->type == ACPI_TYPE_INTEGER) - if (obj->integer.value == 0x80000002) - return -ENODEV; - - if (obj->type == ACPI_TYPE_BUFFER) { - if (obj->buffer.length == 4 && result) { - *result = 0; - *result |= obj->buffer.pointer[0]; - *result |= (obj->buffer.pointer[1] << 8); - *result |= (obj->buffer.pointer[2] << 16); - *result |= (obj->buffer.pointer[3] << 24); - } - } - - kfree(output.pointer); - return 0; -} - -/* Returns 1 if a DSM function is usable and 0 otherwise */ -static int nouveau_test_dsm(acpi_handle test_handle, - int (*dsm_func)(acpi_handle, int, int, uint32_t *), - int sfnc) -{ - u32 result = 0; - - /* Function 0 returns a Buffer containing available functions. The args - * parameter is ignored for function 0, so just put 0 in it */ - if (dsm_func(test_handle, 0, 0, &result)) - return 0; - - /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If - * the n-th bit is enabled, function n is supported */ - return result & 1 && result & (1 << sfnc); -} - -static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) -{ - mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); - mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); - return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL); -} - -static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switcheroo_state state) -{ - int arg; - if (state == VGA_SWITCHEROO_ON) - arg = NOUVEAU_DSM_POWER_SPEED; - else - arg = NOUVEAU_DSM_POWER_STAMINA; - nouveau_dsm(handle, NOUVEAU_DSM_POWER, arg, NULL); - return 0; -} - -static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) -{ - /* perhaps the _DSM functions are mutually exclusive, but prepare for - * the future */ - if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected) - return 0; - if (id == VGA_SWITCHEROO_IGD) - return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); - else - return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED); -} - -static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, - enum vga_switcheroo_state state) -{ - if (id == VGA_SWITCHEROO_IGD) - return 0; - - /* Optimus laptops have the card already disabled in - * nouveau_switcheroo_set_state */ - if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected) - return 0; - - return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); -} - -static int nouveau_dsm_init(void) -{ - return 0; -} - -static int nouveau_dsm_get_client_id(struct pci_dev *pdev) -{ - /* easy option one - intel vendor ID means Integrated */ - if (pdev->vendor == PCI_VENDOR_ID_INTEL) - return VGA_SWITCHEROO_IGD; - - /* is this device on Bus 0? - this may need improving */ - if (pdev->bus->number == 0) - return VGA_SWITCHEROO_IGD; - - return VGA_SWITCHEROO_DIS; -} - -static struct vga_switcheroo_handler nouveau_dsm_handler = { - .switchto = nouveau_dsm_switchto, - .power_state = nouveau_dsm_power_state, - .init = nouveau_dsm_init, - .get_client_id = nouveau_dsm_get_client_id, -}; - -static int nouveau_dsm_pci_probe(struct pci_dev *pdev) -{ - acpi_handle dhandle, nvidia_handle; - acpi_status status; - int retval = 0; - - dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); - if (!dhandle) - return false; - - status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); - if (ACPI_FAILURE(status)) { - return false; - } - - if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) - retval |= NOUVEAU_DSM_HAS_MUX; - - if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, - NOUVEAU_DSM_OPTIMUS_FN)) - retval |= NOUVEAU_DSM_HAS_OPT; - - if (retval) - nouveau_dsm_priv.dhandle = dhandle; - - return retval; -} - -static bool nouveau_dsm_detect(void) -{ - char acpi_method_name[255] = { 0 }; - struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; - struct pci_dev *pdev = NULL; - int has_dsm = 0; - int has_optimus = 0; - int vga_count = 0; - bool guid_valid; - int retval; - bool ret = false; - - /* lookup the MXM GUID */ - guid_valid = mxm_wmi_supported(); - - if (guid_valid) - printk("MXM: GUID detected in BIOS\n"); - - /* now do DSM detection */ - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { - vga_count++; - - retval = nouveau_dsm_pci_probe(pdev); - if (retval & NOUVEAU_DSM_HAS_MUX) - has_dsm |= 1; - if (retval & NOUVEAU_DSM_HAS_OPT) - has_optimus = 1; - } - - if (vga_count == 2 && has_dsm && guid_valid) { - acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, - &buffer); - printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", - acpi_method_name); - nouveau_dsm_priv.dsm_detected = true; - ret = true; - } - - if (has_optimus == 1) { - acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, - &buffer); - printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n", - acpi_method_name); - nouveau_dsm_priv.optimus_detected = true; - ret = true; - } - - return ret; -} - -void nouveau_register_dsm_handler(void) -{ - bool r; - - r = nouveau_dsm_detect(); - if (!r) - return; - - vga_switcheroo_register_handler(&nouveau_dsm_handler); -} - -/* Must be called for Optimus models before the card can be turned off */ -void nouveau_switcheroo_optimus_dsm(void) -{ - u32 result = 0; - if (!nouveau_dsm_priv.optimus_detected) - return; - - nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN, - NOUVEAU_DSM_OPTIMUS_ARGS, &result); -} - -void nouveau_unregister_dsm_handler(void) -{ - vga_switcheroo_unregister_handler(); -} - -/* retrieve the ROM in 4k blocks */ -static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, - int offset, int len) -{ - acpi_status status; - union acpi_object rom_arg_elements[2], *obj; - struct acpi_object_list rom_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - - rom_arg.count = 2; - rom_arg.pointer = &rom_arg_elements[0]; - - rom_arg_elements[0].type = ACPI_TYPE_INTEGER; - rom_arg_elements[0].integer.value = offset; - - rom_arg_elements[1].type = ACPI_TYPE_INTEGER; - rom_arg_elements[1].integer.value = len; - - status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status)); - return -ENODEV; - } - obj = (union acpi_object *)buffer.pointer; - memcpy(bios+offset, obj->buffer.pointer, len); - kfree(buffer.pointer); - return len; -} - -bool nouveau_acpi_rom_supported(struct pci_dev *pdev) -{ - acpi_status status; - acpi_handle dhandle, rom_handle; - - if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected) - return false; - - dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); - if (!dhandle) - return false; - - status = acpi_get_handle(dhandle, "_ROM", &rom_handle); - if (ACPI_FAILURE(status)) - return false; - - nouveau_dsm_priv.rom_handle = rom_handle; - return true; -} - -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) -{ - return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); -} - -int -nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct acpi_device *acpidev; - acpi_handle handle; - int type, ret; - void *edid; - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_LVDS: - case DRM_MODE_CONNECTOR_eDP: - type = ACPI_VIDEO_DISPLAY_LCD; - break; - default: - return -EINVAL; - } - - handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); - if (!handle) - return -ENODEV; - - ret = acpi_bus_get_device(handle, &acpidev); - if (ret) - return -ENODEV; - - ret = acpi_video_get_edid(acpidev, type, -1, &edid); - if (ret < 0) - return ret; - - nv_connector->edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_backlight.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_backlight.c deleted file mode 100644 index fa22b28e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* - * Authors: - * Matthew Garrett - * - * Register locations derived from NVClock by Roderick Colenbrander - */ - -#include -#include - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_reg.h" -#include "nouveau_encoder.h" - -static int -nv40_get_intensity(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(bd); - int val = (nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK) - >> 16; - - return val; -} - -static int -nv40_set_intensity(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(bd); - int val = bd->props.brightness; - int reg = nv_rd32(dev, NV40_PMC_BACKLIGHT); - - nv_wr32(dev, NV40_PMC_BACKLIGHT, - (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK)); - - return 0; -} - -static const struct backlight_ops nv40_bl_ops = { - .options = BL_CORE_SUSPENDRESUME, - .get_brightness = nv40_get_intensity, - .update_status = nv40_set_intensity, -}; - -static int -nv40_backlight_init(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct backlight_properties props; - struct backlight_device *bd; - - if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) - return 0; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - props.max_brightness = 31; - bd = backlight_device_register("nv_backlight", &connector->kdev, dev, - &nv40_bl_ops, &props); - if (IS_ERR(bd)) - return PTR_ERR(bd); - - dev_priv->backlight = bd; - bd->props.brightness = nv40_get_intensity(bd); - backlight_update_status(bd); - - return 0; -} - -static int -nv50_get_intensity(struct backlight_device *bd) -{ - struct nouveau_encoder *nv_encoder = bl_get_data(bd); - struct drm_device *dev = nv_encoder->base.base.dev; - int or = nv_encoder->or; - u32 div = 1025; - u32 val; - - val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or)); - val &= NV50_PDISP_SOR_PWM_CTL_VAL; - return ((val * 100) + (div / 2)) / div; -} - -static int -nv50_set_intensity(struct backlight_device *bd) -{ - struct nouveau_encoder *nv_encoder = bl_get_data(bd); - struct drm_device *dev = nv_encoder->base.base.dev; - int or = nv_encoder->or; - u32 div = 1025; - u32 val = (bd->props.brightness * div) / 100; - - nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), - NV50_PDISP_SOR_PWM_CTL_NEW | val); - return 0; -} - -static const struct backlight_ops nv50_bl_ops = { - .options = BL_CORE_SUSPENDRESUME, - .get_brightness = nv50_get_intensity, - .update_status = nv50_set_intensity, -}; - -static int -nva3_get_intensity(struct backlight_device *bd) -{ - struct nouveau_encoder *nv_encoder = bl_get_data(bd); - struct drm_device *dev = nv_encoder->base.base.dev; - int or = nv_encoder->or; - u32 div, val; - - div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or)); - val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or)); - val &= NVA3_PDISP_SOR_PWM_CTL_VAL; - if (div && div >= val) - return ((val * 100) + (div / 2)) / div; - - return 100; -} - -static int -nva3_set_intensity(struct backlight_device *bd) -{ - struct nouveau_encoder *nv_encoder = bl_get_data(bd); - struct drm_device *dev = nv_encoder->base.base.dev; - int or = nv_encoder->or; - u32 div, val; - - div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or)); - val = (bd->props.brightness * div) / 100; - if (div) { - nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), val | - NV50_PDISP_SOR_PWM_CTL_NEW | - NVA3_PDISP_SOR_PWM_CTL_UNK); - return 0; - } - - return -EINVAL; -} - -static const struct backlight_ops nva3_bl_ops = { - .options = BL_CORE_SUSPENDRESUME, - .get_brightness = nva3_get_intensity, - .update_status = nva3_set_intensity, -}; - -static int -nv50_backlight_init(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_encoder *nv_encoder; - struct backlight_properties props; - struct backlight_device *bd; - const struct backlight_ops *ops; - - nv_encoder = find_encoder(connector, OUTPUT_LVDS); - if (!nv_encoder) { - nv_encoder = find_encoder(connector, OUTPUT_DP); - if (!nv_encoder) - return -ENODEV; - } - - if (!nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or))) - return 0; - - if (dev_priv->chipset <= 0xa0 || - dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) - ops = &nv50_bl_ops; - else - ops = &nva3_bl_ops; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_RAW; - props.max_brightness = 100; - bd = backlight_device_register("nv_backlight", &connector->kdev, - nv_encoder, ops, &props); - if (IS_ERR(bd)) - return PTR_ERR(bd); - - dev_priv->backlight = bd; - bd->props.brightness = bd->ops->get_brightness(bd); - backlight_update_status(bd); - return 0; -} - -int -nouveau_backlight_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_connector *connector; - -#ifdef CONFIG_ACPI - if (acpi_video_backlight_support()) { - NV_INFO(dev, "ACPI backlight interface available, " - "not registering our own\n"); - return 0; - } -#endif - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && - connector->connector_type != DRM_MODE_CONNECTOR_eDP) - continue; - - switch (dev_priv->card_type) { - case NV_40: - return nv40_backlight_init(connector); - case NV_50: - return nv50_backlight_init(connector); - default: - break; - } - } - - - return 0; -} - -void -nouveau_backlight_exit(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->backlight) { - backlight_device_unregister(dev_priv->backlight); - dev_priv->backlight = NULL; - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.c deleted file mode 100644 index 0be4a815..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.c +++ /dev/null @@ -1,6546 +0,0 @@ -/* - * Copyright 2005-2006 Erik Waling - * Copyright 2006 Stephane Marchesin - * Copyright 2007-2009 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "drmP.h" -#define NV_DEBUG_NOTRACE -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_encoder.h" -#include "nouveau_gpio.h" - -#include - -/* these defines are made up */ -#define NV_CIO_CRE_44_HEADA 0x0 -#define NV_CIO_CRE_44_HEADB 0x3 -#define FEATURE_MOBILE 0x10 /* also FEATURE_QUADRO for BMP */ - -#define EDID1_LEN 128 - -#define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip->dev, fmt, ##arg) -#define LOG_OLD_VALUE(x) - -struct init_exec { - bool execute; - bool repeat; -}; - -static bool nv_cksum(const uint8_t *data, unsigned int length) -{ - /* - * There's a few checksums in the BIOS, so here's a generic checking - * function. - */ - int i; - uint8_t sum = 0; - - for (i = 0; i < length; i++) - sum += data[i]; - - if (sum) - return true; - - return false; -} - -static int -score_vbios(struct nvbios *bios, const bool writeable) -{ - if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) { - NV_TRACEWARN(bios->dev, "... BIOS signature not found\n"); - return 0; - } - - if (nv_cksum(bios->data, bios->data[2] * 512)) { - NV_TRACEWARN(bios->dev, "... BIOS checksum invalid\n"); - /* if a ro image is somewhat bad, it's probably all rubbish */ - return writeable ? 2 : 1; - } - - NV_TRACE(bios->dev, "... appears to be valid\n"); - return 3; -} - -static void -bios_shadow_prom(struct nvbios *bios) -{ - struct drm_device *dev = bios->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 pcireg, access; - u16 pcir; - int i; - - /* enable access to rom */ - if (dev_priv->card_type >= NV_50) - pcireg = 0x088050; - else - pcireg = NV_PBUS_PCI_NV_20; - access = nv_mask(dev, pcireg, 0x00000001, 0x00000000); - - /* bail if no rom signature, with a workaround for a PROM reading - * issue on some chipsets. the first read after a period of - * inactivity returns the wrong result, so retry the first header - * byte a few times before giving up as a workaround - */ - i = 16; - do { - if (nv_rd08(dev, NV_PROM_OFFSET + 0) == 0x55) - break; - } while (i--); - - if (!i || nv_rd08(dev, NV_PROM_OFFSET + 1) != 0xaa) - goto out; - - /* additional check (see note below) - read PCI record header */ - pcir = nv_rd08(dev, NV_PROM_OFFSET + 0x18) | - nv_rd08(dev, NV_PROM_OFFSET + 0x19) << 8; - if (nv_rd08(dev, NV_PROM_OFFSET + pcir + 0) != 'P' || - nv_rd08(dev, NV_PROM_OFFSET + pcir + 1) != 'C' || - nv_rd08(dev, NV_PROM_OFFSET + pcir + 2) != 'I' || - nv_rd08(dev, NV_PROM_OFFSET + pcir + 3) != 'R') - goto out; - - /* read entire bios image to system memory */ - bios->length = nv_rd08(dev, NV_PROM_OFFSET + 2) * 512; - bios->data = kmalloc(bios->length, GFP_KERNEL); - if (bios->data) { - for (i = 0; i < bios->length; i++) - bios->data[i] = nv_rd08(dev, NV_PROM_OFFSET + i); - } - -out: - /* disable access to rom */ - nv_wr32(dev, pcireg, access); -} - -static void -bios_shadow_pramin(struct nvbios *bios) -{ - struct drm_device *dev = bios->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 bar0 = 0; - int i; - - if (dev_priv->card_type >= NV_50) { - u64 addr = (u64)(nv_rd32(dev, 0x619f04) & 0xffffff00) << 8; - if (!addr) { - addr = (u64)nv_rd32(dev, 0x001700) << 16; - addr += 0xf0000; - } - - bar0 = nv_mask(dev, 0x001700, 0xffffffff, addr >> 16); - } - - /* bail if no rom signature */ - if (nv_rd08(dev, NV_PRAMIN_OFFSET + 0) != 0x55 || - nv_rd08(dev, NV_PRAMIN_OFFSET + 1) != 0xaa) - goto out; - - bios->length = nv_rd08(dev, NV_PRAMIN_OFFSET + 2) * 512; - bios->data = kmalloc(bios->length, GFP_KERNEL); - if (bios->data) { - for (i = 0; i < bios->length; i++) - bios->data[i] = nv_rd08(dev, NV_PRAMIN_OFFSET + i); - } - -out: - if (dev_priv->card_type >= NV_50) - nv_wr32(dev, 0x001700, bar0); -} - -static void -bios_shadow_pci(struct nvbios *bios) -{ - struct pci_dev *pdev = bios->dev->pdev; - size_t length; - - if (!pci_enable_rom(pdev)) { - void __iomem *rom = pci_map_rom(pdev, &length); - if (rom && length) { - bios->data = kmalloc(length, GFP_KERNEL); - if (bios->data) { - memcpy_fromio(bios->data, rom, length); - bios->length = length; - } - } - if (rom) - pci_unmap_rom(pdev, rom); - - pci_disable_rom(pdev); - } -} - -static void -bios_shadow_acpi(struct nvbios *bios) -{ - struct pci_dev *pdev = bios->dev->pdev; - int ptr, len, ret; - u8 data[3]; - - if (!nouveau_acpi_rom_supported(pdev)) - return; - - ret = nouveau_acpi_get_bios_chunk(data, 0, sizeof(data)); - if (ret != sizeof(data)) - return; - - bios->length = min(data[2] * 512, 65536); - bios->data = kmalloc(bios->length, GFP_KERNEL); - if (!bios->data) - return; - - len = bios->length; - ptr = 0; - while (len) { - int size = (len > ROM_BIOS_PAGE) ? ROM_BIOS_PAGE : len; - - ret = nouveau_acpi_get_bios_chunk(bios->data, ptr, size); - if (ret != size) { - kfree(bios->data); - bios->data = NULL; - return; - } - - len -= size; - ptr += size; - } -} - -struct methods { - const char desc[8]; - void (*shadow)(struct nvbios *); - const bool rw; - int score; - u32 size; - u8 *data; -}; - -static bool -bios_shadow(struct drm_device *dev) -{ - struct methods shadow_methods[] = { - { "PRAMIN", bios_shadow_pramin, true, 0, 0, NULL }, - { "PROM", bios_shadow_prom, false, 0, 0, NULL }, - { "ACPI", bios_shadow_acpi, true, 0, 0, NULL }, - { "PCIROM", bios_shadow_pci, true, 0, 0, NULL }, - {} - }; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct methods *mthd, *best; - - if (nouveau_vbios) { - mthd = shadow_methods; - do { - if (strcasecmp(nouveau_vbios, mthd->desc)) - continue; - NV_INFO(dev, "VBIOS source: %s\n", mthd->desc); - - mthd->shadow(bios); - mthd->score = score_vbios(bios, mthd->rw); - if (mthd->score) - return true; - } while ((++mthd)->shadow); - - NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios); - } - - mthd = shadow_methods; - do { - NV_TRACE(dev, "Checking %s for VBIOS\n", mthd->desc); - mthd->shadow(bios); - mthd->score = score_vbios(bios, mthd->rw); - mthd->size = bios->length; - mthd->data = bios->data; - } while (mthd->score != 3 && (++mthd)->shadow); - - mthd = shadow_methods; - best = mthd; - do { - if (mthd->score > best->score) { - kfree(best->data); - best = mthd; - } - } while ((++mthd)->shadow); - - if (best->score) { - NV_TRACE(dev, "Using VBIOS from %s\n", best->desc); - bios->length = best->size; - bios->data = best->data; - return true; - } - - NV_ERROR(dev, "No valid VBIOS image found\n"); - return false; -} - -struct init_tbl_entry { - char *name; - uint8_t id; - /* Return: - * > 0: success, length of opcode - * 0: success, but abort further parsing of table (INIT_DONE etc) - * < 0: failure, table parsing will be aborted - */ - int (*handler)(struct nvbios *, uint16_t, struct init_exec *); -}; - -static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *); - -#define MACRO_INDEX_SIZE 2 -#define MACRO_SIZE 8 -#define CONDITION_SIZE 12 -#define IO_FLAG_CONDITION_SIZE 9 -#define IO_CONDITION_SIZE 5 -#define MEM_INIT_SIZE 66 - -static void still_alive(void) -{ -#if 0 - sync(); - mdelay(2); -#endif -} - -static uint32_t -munge_reg(struct nvbios *bios, uint32_t reg) -{ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - struct dcb_entry *dcbent = bios->display.output; - - if (dev_priv->card_type < NV_50) - return reg; - - if (reg & 0x80000000) { - BUG_ON(bios->display.crtc < 0); - reg += bios->display.crtc * 0x800; - } - - if (reg & 0x40000000) { - BUG_ON(!dcbent); - - reg += (ffs(dcbent->or) - 1) * 0x800; - if ((reg & 0x20000000) && !(dcbent->sorconf.link & 1)) - reg += 0x00000080; - } - - reg &= ~0xe0000000; - return reg; -} - -static int -valid_reg(struct nvbios *bios, uint32_t reg) -{ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - struct drm_device *dev = bios->dev; - - /* C51 has misaligned regs on purpose. Marvellous */ - if (reg & 0x2 || - (reg & 0x1 && dev_priv->vbios.chip_version != 0x51)) - NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg); - - /* warn on C51 regs that haven't been verified accessible in tracing */ - if (reg & 0x1 && dev_priv->vbios.chip_version == 0x51 && - reg != 0x130d && reg != 0x1311 && reg != 0x60081d) - NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n", - reg); - - if (reg >= (8*1024*1024)) { - NV_ERROR(dev, "=== reg 0x%08x out of mapped bounds ===\n", reg); - return 0; - } - - return 1; -} - -static bool -valid_idx_port(struct nvbios *bios, uint16_t port) -{ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - struct drm_device *dev = bios->dev; - - /* - * If adding more ports here, the read/write functions below will need - * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is - * used for the port in question - */ - if (dev_priv->card_type < NV_50) { - if (port == NV_CIO_CRX__COLOR) - return true; - if (port == NV_VIO_SRX) - return true; - } else { - if (port == NV_CIO_CRX__COLOR) - return true; - } - - NV_ERROR(dev, "========== unknown indexed io port 0x%04X ==========\n", - port); - - return false; -} - -static bool -valid_port(struct nvbios *bios, uint16_t port) -{ - struct drm_device *dev = bios->dev; - - /* - * If adding more ports here, the read/write functions below will need - * updating so that the correct mmio range (PRMCIO, PRMDIO, PRMVIO) is - * used for the port in question - */ - if (port == NV_VIO_VSE2) - return true; - - NV_ERROR(dev, "========== unknown io port 0x%04X ==========\n", port); - - return false; -} - -static uint32_t -bios_rd32(struct nvbios *bios, uint32_t reg) -{ - uint32_t data; - - reg = munge_reg(bios, reg); - if (!valid_reg(bios, reg)) - return 0; - - /* - * C51 sometimes uses regs with bit0 set in the address. For these - * cases there should exist a translation in a BIOS table to an IO - * port address which the BIOS uses for accessing the reg - * - * These only seem to appear for the power control regs to a flat panel, - * and the GPIO regs at 0x60081*. In C51 mmio traces the normal regs - * for 0x1308 and 0x1310 are used - hence the mask below. An S3 - * suspend-resume mmio trace from a C51 will be required to see if this - * is true for the power microcode in 0x14.., or whether the direct IO - * port access method is needed - */ - if (reg & 0x1) - reg &= ~0x1; - - data = nv_rd32(bios->dev, reg); - - BIOSLOG(bios, " Read: Reg: 0x%08X, Data: 0x%08X\n", reg, data); - - return data; -} - -static void -bios_wr32(struct nvbios *bios, uint32_t reg, uint32_t data) -{ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - - reg = munge_reg(bios, reg); - if (!valid_reg(bios, reg)) - return; - - /* see note in bios_rd32 */ - if (reg & 0x1) - reg &= 0xfffffffe; - - LOG_OLD_VALUE(bios_rd32(bios, reg)); - BIOSLOG(bios, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); - - if (dev_priv->vbios.execute) { - still_alive(); - nv_wr32(bios->dev, reg, data); - } -} - -static uint8_t -bios_idxprt_rd(struct nvbios *bios, uint16_t port, uint8_t index) -{ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - struct drm_device *dev = bios->dev; - uint8_t data; - - if (!valid_idx_port(bios, port)) - return 0; - - if (dev_priv->card_type < NV_50) { - if (port == NV_VIO_SRX) - data = NVReadVgaSeq(dev, bios->state.crtchead, index); - else /* assume NV_CIO_CRX__COLOR */ - data = NVReadVgaCrtc(dev, bios->state.crtchead, index); - } else { - uint32_t data32; - - data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3)); - data = (data32 >> ((index & 3) << 3)) & 0xff; - } - - BIOSLOG(bios, " Indexed IO read: Port: 0x%04X, Index: 0x%02X, " - "Head: 0x%02X, Data: 0x%02X\n", - port, index, bios->state.crtchead, data); - return data; -} - -static void -bios_idxprt_wr(struct nvbios *bios, uint16_t port, uint8_t index, uint8_t data) -{ - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - struct drm_device *dev = bios->dev; - - if (!valid_idx_port(bios, port)) - return; - - /* - * The current head is maintained in the nvbios member state.crtchead. - * We trap changes to CR44 and update the head variable and hence the - * register set written. - * As CR44 only exists on CRTC0, we update crtchead to head0 in advance - * of the write, and to head1 after the write - */ - if (port == NV_CIO_CRX__COLOR && index == NV_CIO_CRE_44 && - data != NV_CIO_CRE_44_HEADB) - bios->state.crtchead = 0; - - LOG_OLD_VALUE(bios_idxprt_rd(bios, port, index)); - BIOSLOG(bios, " Indexed IO write: Port: 0x%04X, Index: 0x%02X, " - "Head: 0x%02X, Data: 0x%02X\n", - port, index, bios->state.crtchead, data); - - if (bios->execute && dev_priv->card_type < NV_50) { - still_alive(); - if (port == NV_VIO_SRX) - NVWriteVgaSeq(dev, bios->state.crtchead, index, data); - else /* assume NV_CIO_CRX__COLOR */ - NVWriteVgaCrtc(dev, bios->state.crtchead, index, data); - } else - if (bios->execute) { - uint32_t data32, shift = (index & 3) << 3; - - still_alive(); - - data32 = bios_rd32(bios, NV50_PDISPLAY_VGACRTC(index & ~3)); - data32 &= ~(0xff << shift); - data32 |= (data << shift); - bios_wr32(bios, NV50_PDISPLAY_VGACRTC(index & ~3), data32); - } - - if (port == NV_CIO_CRX__COLOR && - index == NV_CIO_CRE_44 && data == NV_CIO_CRE_44_HEADB) - bios->state.crtchead = 1; -} - -static uint8_t -bios_port_rd(struct nvbios *bios, uint16_t port) -{ - uint8_t data, head = bios->state.crtchead; - - if (!valid_port(bios, port)) - return 0; - - data = NVReadPRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port); - - BIOSLOG(bios, " IO read: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", - port, head, data); - - return data; -} - -static void -bios_port_wr(struct nvbios *bios, uint16_t port, uint8_t data) -{ - int head = bios->state.crtchead; - - if (!valid_port(bios, port)) - return; - - LOG_OLD_VALUE(bios_port_rd(bios, port)); - BIOSLOG(bios, " IO write: Port: 0x%04X, Head: 0x%02X, Data: 0x%02X\n", - port, head, data); - - if (!bios->execute) - return; - - still_alive(); - NVWritePRMVIO(bios->dev, head, NV_PRMVIO0_OFFSET + port, data); -} - -static bool -io_flag_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond) -{ - /* - * The IO flag condition entry has 2 bytes for the CRTC port; 1 byte - * for the CRTC index; 1 byte for the mask to apply to the value - * retrieved from the CRTC; 1 byte for the shift right to apply to the - * masked CRTC value; 2 bytes for the offset to the flag array, to - * which the shifted value is added; 1 byte for the mask applied to the - * value read from the flag array; and 1 byte for the value to compare - * against the masked byte from the flag table. - */ - - uint16_t condptr = bios->io_flag_condition_tbl_ptr + cond * IO_FLAG_CONDITION_SIZE; - uint16_t crtcport = ROM16(bios->data[condptr]); - uint8_t crtcindex = bios->data[condptr + 2]; - uint8_t mask = bios->data[condptr + 3]; - uint8_t shift = bios->data[condptr + 4]; - uint16_t flagarray = ROM16(bios->data[condptr + 5]); - uint8_t flagarraymask = bios->data[condptr + 7]; - uint8_t cmpval = bios->data[condptr + 8]; - uint8_t data; - - BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " - "Shift: 0x%02X, FlagArray: 0x%04X, FAMask: 0x%02X, " - "Cmpval: 0x%02X\n", - offset, crtcport, crtcindex, mask, shift, flagarray, flagarraymask, cmpval); - - data = bios_idxprt_rd(bios, crtcport, crtcindex); - - data = bios->data[flagarray + ((data & mask) >> shift)]; - data &= flagarraymask; - - BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n", - offset, data, cmpval); - - return (data == cmpval); -} - -static bool -bios_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond) -{ - /* - * The condition table entry has 4 bytes for the address of the - * register to check, 4 bytes for a mask to apply to the register and - * 4 for a test comparison value - */ - - uint16_t condptr = bios->condition_tbl_ptr + cond * CONDITION_SIZE; - uint32_t reg = ROM32(bios->data[condptr]); - uint32_t mask = ROM32(bios->data[condptr + 4]); - uint32_t cmpval = ROM32(bios->data[condptr + 8]); - uint32_t data; - - BIOSLOG(bios, "0x%04X: Cond: 0x%02X, Reg: 0x%08X, Mask: 0x%08X\n", - offset, cond, reg, mask); - - data = bios_rd32(bios, reg) & mask; - - BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", - offset, data, cmpval); - - return (data == cmpval); -} - -static bool -io_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond) -{ - /* - * The IO condition entry has 2 bytes for the IO port address; 1 byte - * for the index to write to io_port; 1 byte for the mask to apply to - * the byte read from io_port+1; and 1 byte for the value to compare - * against the masked byte. - */ - - uint16_t condptr = bios->io_condition_tbl_ptr + cond * IO_CONDITION_SIZE; - uint16_t io_port = ROM16(bios->data[condptr]); - uint8_t port_index = bios->data[condptr + 2]; - uint8_t mask = bios->data[condptr + 3]; - uint8_t cmpval = bios->data[condptr + 4]; - - uint8_t data = bios_idxprt_rd(bios, io_port, port_index) & mask; - - BIOSLOG(bios, "0x%04X: Checking if 0x%02X equals 0x%02X\n", - offset, data, cmpval); - - return (data == cmpval); -} - -static int -nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pll_vals pll; - struct pll_lims pll_limits; - u32 ctrl, mask, coef; - int ret; - - ret = get_pll_limits(dev, reg, &pll_limits); - if (ret) - return ret; - - clk = nouveau_calc_pll_mnp(dev, &pll_limits, clk, &pll); - if (!clk) - return -ERANGE; - - coef = pll.N1 << 8 | pll.M1; - ctrl = pll.log2P << 16; - mask = 0x00070000; - if (reg == 0x004008) { - mask |= 0x01f80000; - ctrl |= (pll_limits.log2p_bias << 19); - ctrl |= (pll.log2P << 22); - } - - if (!dev_priv->vbios.execute) - return 0; - - nv_mask(dev, reg + 0, mask, ctrl); - nv_wr32(dev, reg + 4, coef); - return 0; -} - -static int -setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk) -{ - struct drm_device *dev = bios->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - /* clk in kHz */ - struct pll_lims pll_lim; - struct nouveau_pll_vals pllvals; - int ret; - - if (dev_priv->card_type >= NV_50) - return nv50_pll_set(dev, reg, clk); - - /* high regs (such as in the mac g5 table) are not -= 4 */ - ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim); - if (ret) - return ret; - - clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals); - if (!clk) - return -ERANGE; - - if (bios->execute) { - still_alive(); - nouveau_hw_setpll(dev, reg, &pllvals); - } - - return 0; -} - -static int dcb_entry_idx_from_crtchead(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - - /* - * For the results of this function to be correct, CR44 must have been - * set (using bios_idxprt_wr to set crtchead), CR58 set for CR57 = 0, - * and the DCB table parsed, before the script calling the function is - * run. run_digital_op_script is example of how to do such setup - */ - - uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0); - - if (dcb_entry > bios->dcb.entries) { - NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently " - "(%02X)\n", dcb_entry); - dcb_entry = 0x7f; /* unused / invalid marker */ - } - - return dcb_entry; -} - -static struct nouveau_i2c_chan * -init_i2c_device_find(struct drm_device *dev, int i2c_index) -{ - if (i2c_index == 0xff) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_table *dcb = &dev_priv->vbios.dcb; - /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ - int idx = dcb_entry_idx_from_crtchead(dev); - - i2c_index = NV_I2C_DEFAULT(0); - if (idx != 0x7f && dcb->entry[idx].i2c_upper_default) - i2c_index = NV_I2C_DEFAULT(1); - } - - return nouveau_i2c_find(dev, i2c_index); -} - -static uint32_t -get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) -{ - /* - * For mlv < 0x80, it is an index into a table of TMDS base addresses. - * For mlv == 0x80 use the "or" value of the dcb_entry indexed by - * CR58 for CR57 = 0 to index a table of offsets to the basic - * 0x6808b0 address. - * For mlv == 0x81 use the "or" value of the dcb_entry indexed by - * CR58 for CR57 = 0 to index a table of offsets to the basic - * 0x6808b0 address, and then flip the offset by 8. - */ - - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - const int pramdac_offset[13] = { - 0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 }; - const uint32_t pramdac_table[4] = { - 0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8 }; - - if (mlv >= 0x80) { - int dcb_entry, dacoffset; - - /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ - dcb_entry = dcb_entry_idx_from_crtchead(dev); - if (dcb_entry == 0x7f) - return 0; - dacoffset = pramdac_offset[bios->dcb.entry[dcb_entry].or]; - if (mlv == 0x81) - dacoffset ^= 8; - return 0x6808b0 + dacoffset; - } else { - if (mlv >= ARRAY_SIZE(pramdac_table)) { - NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n", - mlv); - return 0; - } - return pramdac_table[mlv]; - } -} - -static int -init_io_restrict_prog(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_IO_RESTRICT_PROG opcode: 0x32 ('2') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): CRTC port - * offset + 3 (8 bit): CRTC index - * offset + 4 (8 bit): mask - * offset + 5 (8 bit): shift - * offset + 6 (8 bit): count - * offset + 7 (32 bit): register - * offset + 11 (32 bit): configuration 1 - * ... - * - * Starting at offset + 11 there are "count" 32 bit values. - * To find out which value to use read index "CRTC index" on "CRTC - * port", AND this value with "mask" and then bit shift right "shift" - * bits. Read the appropriate value using this index and write to - * "register" - */ - - uint16_t crtcport = ROM16(bios->data[offset + 1]); - uint8_t crtcindex = bios->data[offset + 3]; - uint8_t mask = bios->data[offset + 4]; - uint8_t shift = bios->data[offset + 5]; - uint8_t count = bios->data[offset + 6]; - uint32_t reg = ROM32(bios->data[offset + 7]); - uint8_t config; - uint32_t configval; - int len = 11 + count * 4; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " - "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", - offset, crtcport, crtcindex, mask, shift, count, reg); - - config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift; - if (config > count) { - NV_ERROR(bios->dev, - "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", - offset, config, count); - return len; - } - - configval = ROM32(bios->data[offset + 11 + config * 4]); - - BIOSLOG(bios, "0x%04X: Writing config %02X\n", offset, config); - - bios_wr32(bios, reg, configval); - - return len; -} - -static int -init_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_REPEAT opcode: 0x33 ('3') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): count - * - * Execute script following this opcode up to INIT_REPEAT_END - * "count" times - */ - - uint8_t count = bios->data[offset + 1]; - uint8_t i; - - /* no iexec->execute check by design */ - - BIOSLOG(bios, "0x%04X: Repeating following segment %d times\n", - offset, count); - - iexec->repeat = true; - - /* - * count - 1, as the script block will execute once when we leave this - * opcode -- this is compatible with bios behaviour as: - * a) the block is always executed at least once, even if count == 0 - * b) the bios interpreter skips to the op following INIT_END_REPEAT, - * while we don't - */ - for (i = 0; i < count - 1; i++) - parse_init_table(bios, offset + 2, iexec); - - iexec->repeat = false; - - return 2; -} - -static int -init_io_restrict_pll(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_IO_RESTRICT_PLL opcode: 0x34 ('4') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): CRTC port - * offset + 3 (8 bit): CRTC index - * offset + 4 (8 bit): mask - * offset + 5 (8 bit): shift - * offset + 6 (8 bit): IO flag condition index - * offset + 7 (8 bit): count - * offset + 8 (32 bit): register - * offset + 12 (16 bit): frequency 1 - * ... - * - * Starting at offset + 12 there are "count" 16 bit frequencies (10kHz). - * Set PLL register "register" to coefficients for frequency n, - * selected by reading index "CRTC index" of "CRTC port" ANDed with - * "mask" and shifted right by "shift". - * - * If "IO flag condition index" > 0, and condition met, double - * frequency before setting it. - */ - - uint16_t crtcport = ROM16(bios->data[offset + 1]); - uint8_t crtcindex = bios->data[offset + 3]; - uint8_t mask = bios->data[offset + 4]; - uint8_t shift = bios->data[offset + 5]; - int8_t io_flag_condition_idx = bios->data[offset + 6]; - uint8_t count = bios->data[offset + 7]; - uint32_t reg = ROM32(bios->data[offset + 8]); - uint8_t config; - uint16_t freq; - int len = 12 + count * 2; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " - "Shift: 0x%02X, IO Flag Condition: 0x%02X, " - "Count: 0x%02X, Reg: 0x%08X\n", - offset, crtcport, crtcindex, mask, shift, - io_flag_condition_idx, count, reg); - - config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift; - if (config > count) { - NV_ERROR(bios->dev, - "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", - offset, config, count); - return len; - } - - freq = ROM16(bios->data[offset + 12 + config * 2]); - - if (io_flag_condition_idx > 0) { - if (io_flag_condition_met(bios, offset, io_flag_condition_idx)) { - BIOSLOG(bios, "0x%04X: Condition fulfilled -- " - "frequency doubled\n", offset); - freq *= 2; - } else - BIOSLOG(bios, "0x%04X: Condition not fulfilled -- " - "frequency unchanged\n", offset); - } - - BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n", - offset, reg, config, freq); - - setPLL(bios, reg, freq * 10); - - return len; -} - -static int -init_end_repeat(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_END_REPEAT opcode: 0x36 ('6') - * - * offset (8 bit): opcode - * - * Marks the end of the block for INIT_REPEAT to repeat - */ - - /* no iexec->execute check by design */ - - /* - * iexec->repeat flag necessary to go past INIT_END_REPEAT opcode when - * we're not in repeat mode - */ - if (iexec->repeat) - return 0; - - return 1; -} - -static int -init_copy(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_COPY opcode: 0x37 ('7') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (8 bit): shift - * offset + 6 (8 bit): srcmask - * offset + 7 (16 bit): CRTC port - * offset + 9 (8 bit): CRTC index - * offset + 10 (8 bit): mask - * - * Read index "CRTC index" on "CRTC port", AND with "mask", OR with - * (REGVAL("register") >> "shift" & "srcmask") and write-back to CRTC - * port - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint8_t shift = bios->data[offset + 5]; - uint8_t srcmask = bios->data[offset + 6]; - uint16_t crtcport = ROM16(bios->data[offset + 7]); - uint8_t crtcindex = bios->data[offset + 9]; - uint8_t mask = bios->data[offset + 10]; - uint32_t data; - uint8_t crtcdata; - - if (!iexec->execute) - return 11; - - BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%02X, " - "Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X\n", - offset, reg, shift, srcmask, crtcport, crtcindex, mask); - - data = bios_rd32(bios, reg); - - if (shift < 0x80) - data >>= shift; - else - data <<= (0x100 - shift); - - data &= srcmask; - - crtcdata = bios_idxprt_rd(bios, crtcport, crtcindex) & mask; - crtcdata |= (uint8_t)data; - bios_idxprt_wr(bios, crtcport, crtcindex, crtcdata); - - return 11; -} - -static int -init_not(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_NOT opcode: 0x38 ('8') - * - * offset (8 bit): opcode - * - * Invert the current execute / no-execute condition (i.e. "else") - */ - if (iexec->execute) - BIOSLOG(bios, "0x%04X: ------ Skipping following commands ------\n", offset); - else - BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", offset); - - iexec->execute = !iexec->execute; - return 1; -} - -static int -init_io_flag_condition(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_IO_FLAG_CONDITION opcode: 0x39 ('9') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): condition number - * - * Check condition "condition number" in the IO flag condition table. - * If condition not met skip subsequent opcodes until condition is - * inverted (INIT_NOT), or we hit INIT_RESUME - */ - - uint8_t cond = bios->data[offset + 1]; - - if (!iexec->execute) - return 2; - - if (io_flag_condition_met(bios, offset, cond)) - BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); - else { - BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); - iexec->execute = false; - } - - return 2; -} - -static int -init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_DP_CONDITION opcode: 0x3A ('') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): "sub" opcode - * offset + 2 (8 bit): unknown - * - */ - - struct dcb_entry *dcb = bios->display.output; - struct drm_device *dev = bios->dev; - uint8_t cond = bios->data[offset + 1]; - uint8_t *table, *entry; - - BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond); - - if (!iexec->execute) - return 3; - - table = nouveau_dp_bios_data(dev, dcb, &entry); - if (!table) - return 3; - - switch (cond) { - case 0: - entry = dcb_conn(dev, dcb->connector); - if (!entry || entry[0] != DCB_CONNECTOR_eDP) - iexec->execute = false; - break; - case 1: - case 2: - if ((table[0] < 0x40 && !(entry[5] & cond)) || - (table[0] == 0x40 && !(entry[4] & cond))) - iexec->execute = false; - break; - case 5: - { - struct nouveau_i2c_chan *auxch; - int ret; - - auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index); - if (!auxch) { - NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset); - return 3; - } - - ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1); - if (ret) { - NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret); - return 3; - } - - if (!(cond & 1)) - iexec->execute = false; - } - break; - default: - NV_WARN(dev, "0x%04X: unknown INIT_3A op: %d\n", offset, cond); - break; - } - - if (iexec->execute) - BIOSLOG(bios, "0x%04X: continuing to execute\n", offset); - else - BIOSLOG(bios, "0x%04X: skipping following commands\n", offset); - - return 3; -} - -static int -init_op_3b(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_3B opcode: 0x3B ('') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): crtc index - * - */ - - uint8_t or = ffs(bios->display.output->or) - 1; - uint8_t index = bios->data[offset + 1]; - uint8_t data; - - if (!iexec->execute) - return 2; - - data = bios_idxprt_rd(bios, 0x3d4, index); - bios_idxprt_wr(bios, 0x3d4, index, data & ~(1 << or)); - return 2; -} - -static int -init_op_3c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_3C opcode: 0x3C ('') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): crtc index - * - */ - - uint8_t or = ffs(bios->display.output->or) - 1; - uint8_t index = bios->data[offset + 1]; - uint8_t data; - - if (!iexec->execute) - return 2; - - data = bios_idxprt_rd(bios, 0x3d4, index); - bios_idxprt_wr(bios, 0x3d4, index, data | (1 << or)); - return 2; -} - -static int -init_idx_addr_latched(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_INDEX_ADDRESS_LATCHED opcode: 0x49 ('I') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): control register - * offset + 5 (32 bit): data register - * offset + 9 (32 bit): mask - * offset + 13 (32 bit): data - * offset + 17 (8 bit): count - * offset + 18 (8 bit): address 1 - * offset + 19 (8 bit): data 1 - * ... - * - * For each of "count" address and data pairs, write "data n" to - * "data register", read the current value of "control register", - * and write it back once ANDed with "mask", ORed with "data", - * and ORed with "address n" - */ - - uint32_t controlreg = ROM32(bios->data[offset + 1]); - uint32_t datareg = ROM32(bios->data[offset + 5]); - uint32_t mask = ROM32(bios->data[offset + 9]); - uint32_t data = ROM32(bios->data[offset + 13]); - uint8_t count = bios->data[offset + 17]; - int len = 18 + count * 2; - uint32_t value; - int i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: ControlReg: 0x%08X, DataReg: 0x%08X, " - "Mask: 0x%08X, Data: 0x%08X, Count: 0x%02X\n", - offset, controlreg, datareg, mask, data, count); - - for (i = 0; i < count; i++) { - uint8_t instaddress = bios->data[offset + 18 + i * 2]; - uint8_t instdata = bios->data[offset + 19 + i * 2]; - - BIOSLOG(bios, "0x%04X: Address: 0x%02X, Data: 0x%02X\n", - offset, instaddress, instdata); - - bios_wr32(bios, datareg, instdata); - value = bios_rd32(bios, controlreg) & mask; - value |= data; - value |= instaddress; - bios_wr32(bios, controlreg, value); - } - - return len; -} - -static int -init_io_restrict_pll2(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_IO_RESTRICT_PLL2 opcode: 0x4A ('J') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): CRTC port - * offset + 3 (8 bit): CRTC index - * offset + 4 (8 bit): mask - * offset + 5 (8 bit): shift - * offset + 6 (8 bit): count - * offset + 7 (32 bit): register - * offset + 11 (32 bit): frequency 1 - * ... - * - * Starting at offset + 11 there are "count" 32 bit frequencies (kHz). - * Set PLL register "register" to coefficients for frequency n, - * selected by reading index "CRTC index" of "CRTC port" ANDed with - * "mask" and shifted right by "shift". - */ - - uint16_t crtcport = ROM16(bios->data[offset + 1]); - uint8_t crtcindex = bios->data[offset + 3]; - uint8_t mask = bios->data[offset + 4]; - uint8_t shift = bios->data[offset + 5]; - uint8_t count = bios->data[offset + 6]; - uint32_t reg = ROM32(bios->data[offset + 7]); - int len = 11 + count * 4; - uint8_t config; - uint32_t freq; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " - "Shift: 0x%02X, Count: 0x%02X, Reg: 0x%08X\n", - offset, crtcport, crtcindex, mask, shift, count, reg); - - if (!reg) - return len; - - config = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) >> shift; - if (config > count) { - NV_ERROR(bios->dev, - "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n", - offset, config, count); - return len; - } - - freq = ROM32(bios->data[offset + 11 + config * 4]); - - BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n", - offset, reg, config, freq); - - setPLL(bios, reg, freq); - - return len; -} - -static int -init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_PLL2 opcode: 0x4B ('K') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (32 bit): freq - * - * Set PLL register "register" to coefficients for frequency "freq" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint32_t freq = ROM32(bios->data[offset + 5]); - - if (!iexec->execute) - return 9; - - BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", - offset, reg, freq); - - setPLL(bios, reg, freq); - return 9; -} - -static int -init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_I2C_BYTE opcode: 0x4C ('L') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): DCB I2C table entry index - * offset + 2 (8 bit): I2C slave address - * offset + 3 (8 bit): count - * offset + 4 (8 bit): I2C register 1 - * offset + 5 (8 bit): mask 1 - * offset + 6 (8 bit): data 1 - * ... - * - * For each of "count" registers given by "I2C register n" on the device - * addressed by "I2C slave address" on the I2C bus given by - * "DCB I2C table entry index", read the register, AND the result with - * "mask n" and OR it with "data n" before writing it back to the device - */ - - struct drm_device *dev = bios->dev; - uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2] >> 1; - uint8_t count = bios->data[offset + 3]; - struct nouveau_i2c_chan *chan; - int len = 4 + count * 3; - int ret, i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " - "Count: 0x%02X\n", - offset, i2c_index, i2c_address, count); - - chan = init_i2c_device_find(dev, i2c_index); - if (!chan) { - NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); - return len; - } - - for (i = 0; i < count; i++) { - uint8_t reg = bios->data[offset + 4 + i * 3]; - uint8_t mask = bios->data[offset + 5 + i * 3]; - uint8_t data = bios->data[offset + 6 + i * 3]; - union i2c_smbus_data val; - - ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, - I2C_SMBUS_READ, reg, - I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) { - NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret); - return len; - } - - BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " - "Mask: 0x%02X, Data: 0x%02X\n", - offset, reg, val.byte, mask, data); - - if (!bios->execute) - continue; - - val.byte &= mask; - val.byte |= data; - ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, - I2C_SMBUS_WRITE, reg, - I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) { - NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); - return len; - } - } - - return len; -} - -static int -init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_I2C_BYTE opcode: 0x4D ('M') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): DCB I2C table entry index - * offset + 2 (8 bit): I2C slave address - * offset + 3 (8 bit): count - * offset + 4 (8 bit): I2C register 1 - * offset + 5 (8 bit): data 1 - * ... - * - * For each of "count" registers given by "I2C register n" on the device - * addressed by "I2C slave address" on the I2C bus given by - * "DCB I2C table entry index", set the register to "data n" - */ - - struct drm_device *dev = bios->dev; - uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2] >> 1; - uint8_t count = bios->data[offset + 3]; - struct nouveau_i2c_chan *chan; - int len = 4 + count * 2; - int ret, i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " - "Count: 0x%02X\n", - offset, i2c_index, i2c_address, count); - - chan = init_i2c_device_find(dev, i2c_index); - if (!chan) { - NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); - return len; - } - - for (i = 0; i < count; i++) { - uint8_t reg = bios->data[offset + 4 + i * 2]; - union i2c_smbus_data val; - - val.byte = bios->data[offset + 5 + i * 2]; - - BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n", - offset, reg, val.byte); - - if (!bios->execute) - continue; - - ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, - I2C_SMBUS_WRITE, reg, - I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) { - NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); - return len; - } - } - - return len; -} - -static int -init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_I2C opcode: 0x4E ('N') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): DCB I2C table entry index - * offset + 2 (8 bit): I2C slave address - * offset + 3 (8 bit): count - * offset + 4 (8 bit): data 1 - * ... - * - * Send "count" bytes ("data n") to the device addressed by "I2C slave - * address" on the I2C bus given by "DCB I2C table entry index" - */ - - struct drm_device *dev = bios->dev; - uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2] >> 1; - uint8_t count = bios->data[offset + 3]; - int len = 4 + count; - struct nouveau_i2c_chan *chan; - struct i2c_msg msg; - uint8_t data[256]; - int ret, i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X, " - "Count: 0x%02X\n", - offset, i2c_index, i2c_address, count); - - chan = init_i2c_device_find(dev, i2c_index); - if (!chan) { - NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset); - return len; - } - - for (i = 0; i < count; i++) { - data[i] = bios->data[offset + 4 + i]; - - BIOSLOG(bios, "0x%04X: Data: 0x%02X\n", offset, data[i]); - } - - if (bios->execute) { - msg.addr = i2c_address; - msg.flags = 0; - msg.len = count; - msg.buf = data; - ret = i2c_transfer(&chan->adapter, &msg, 1); - if (ret != 1) { - NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret); - return len; - } - } - - return len; -} - -static int -init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_TMDS opcode: 0x4F ('O') (non-canon name) - * - * offset (8 bit): opcode - * offset + 1 (8 bit): magic lookup value - * offset + 2 (8 bit): TMDS address - * offset + 3 (8 bit): mask - * offset + 4 (8 bit): data - * - * Read the data reg for TMDS address "TMDS address", AND it with mask - * and OR it with data, then write it back - * "magic lookup value" determines which TMDS base address register is - * used -- see get_tmds_index_reg() - */ - - struct drm_device *dev = bios->dev; - uint8_t mlv = bios->data[offset + 1]; - uint32_t tmdsaddr = bios->data[offset + 2]; - uint8_t mask = bios->data[offset + 3]; - uint8_t data = bios->data[offset + 4]; - uint32_t reg, value; - - if (!iexec->execute) - return 5; - - BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, TMDSAddr: 0x%02X, " - "Mask: 0x%02X, Data: 0x%02X\n", - offset, mlv, tmdsaddr, mask, data); - - reg = get_tmds_index_reg(bios->dev, mlv); - if (!reg) { - NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); - return 5; - } - - bios_wr32(bios, reg, - tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE); - value = (bios_rd32(bios, reg + 4) & mask) | data; - bios_wr32(bios, reg + 4, value); - bios_wr32(bios, reg, tmdsaddr); - - return 5; -} - -static int -init_zm_tmds_group(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_ZM_TMDS_GROUP opcode: 0x50 ('P') (non-canon name) - * - * offset (8 bit): opcode - * offset + 1 (8 bit): magic lookup value - * offset + 2 (8 bit): count - * offset + 3 (8 bit): addr 1 - * offset + 4 (8 bit): data 1 - * ... - * - * For each of "count" TMDS address and data pairs write "data n" to - * "addr n". "magic lookup value" determines which TMDS base address - * register is used -- see get_tmds_index_reg() - */ - - struct drm_device *dev = bios->dev; - uint8_t mlv = bios->data[offset + 1]; - uint8_t count = bios->data[offset + 2]; - int len = 3 + count * 2; - uint32_t reg; - int i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: MagicLookupValue: 0x%02X, Count: 0x%02X\n", - offset, mlv, count); - - reg = get_tmds_index_reg(bios->dev, mlv); - if (!reg) { - NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset); - return len; - } - - for (i = 0; i < count; i++) { - uint8_t tmdsaddr = bios->data[offset + 3 + i * 2]; - uint8_t tmdsdata = bios->data[offset + 4 + i * 2]; - - bios_wr32(bios, reg + 4, tmdsdata); - bios_wr32(bios, reg, tmdsaddr); - } - - return len; -} - -static int -init_cr_idx_adr_latch(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_CR_INDEX_ADDRESS_LATCHED opcode: 0x51 ('Q') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): CRTC index1 - * offset + 2 (8 bit): CRTC index2 - * offset + 3 (8 bit): baseaddr - * offset + 4 (8 bit): count - * offset + 5 (8 bit): data 1 - * ... - * - * For each of "count" address and data pairs, write "baseaddr + n" to - * "CRTC index1" and "data n" to "CRTC index2" - * Once complete, restore initial value read from "CRTC index1" - */ - uint8_t crtcindex1 = bios->data[offset + 1]; - uint8_t crtcindex2 = bios->data[offset + 2]; - uint8_t baseaddr = bios->data[offset + 3]; - uint8_t count = bios->data[offset + 4]; - int len = 5 + count; - uint8_t oldaddr, data; - int i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: Index1: 0x%02X, Index2: 0x%02X, " - "BaseAddr: 0x%02X, Count: 0x%02X\n", - offset, crtcindex1, crtcindex2, baseaddr, count); - - oldaddr = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex1); - - for (i = 0; i < count; i++) { - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, - baseaddr + i); - data = bios->data[offset + 5 + i]; - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex2, data); - } - - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex1, oldaddr); - - return len; -} - -static int -init_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_CR opcode: 0x52 ('R') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): CRTC index - * offset + 2 (8 bit): mask - * offset + 3 (8 bit): data - * - * Assign the value of at "CRTC index" ANDed with mask and ORed with - * data back to "CRTC index" - */ - - uint8_t crtcindex = bios->data[offset + 1]; - uint8_t mask = bios->data[offset + 2]; - uint8_t data = bios->data[offset + 3]; - uint8_t value; - - if (!iexec->execute) - return 4; - - BIOSLOG(bios, "0x%04X: Index: 0x%02X, Mask: 0x%02X, Data: 0x%02X\n", - offset, crtcindex, mask, data); - - value = bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, crtcindex) & mask; - value |= data; - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, value); - - return 4; -} - -static int -init_zm_cr(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_CR opcode: 0x53 ('S') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): CRTC index - * offset + 2 (8 bit): value - * - * Assign "value" to CRTC register with index "CRTC index". - */ - - uint8_t crtcindex = ROM32(bios->data[offset + 1]); - uint8_t data = bios->data[offset + 2]; - - if (!iexec->execute) - return 3; - - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, crtcindex, data); - - return 3; -} - -static int -init_zm_cr_group(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_CR_GROUP opcode: 0x54 ('T') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): count - * offset + 2 (8 bit): CRTC index 1 - * offset + 3 (8 bit): value 1 - * ... - * - * For "count", assign "value n" to CRTC register with index - * "CRTC index n". - */ - - uint8_t count = bios->data[offset + 1]; - int len = 2 + count * 2; - int i; - - if (!iexec->execute) - return len; - - for (i = 0; i < count; i++) - init_zm_cr(bios, offset + 2 + 2 * i - 1, iexec); - - return len; -} - -static int -init_condition_time(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_CONDITION_TIME opcode: 0x56 ('V') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): condition number - * offset + 2 (8 bit): retries / 50 - * - * Check condition "condition number" in the condition table. - * Bios code then sleeps for 2ms if the condition is not met, and - * repeats up to "retries" times, but on one C51 this has proved - * insufficient. In mmiotraces the driver sleeps for 20ms, so we do - * this, and bail after "retries" times, or 2s, whichever is less. - * If still not met after retries, clear execution flag for this table. - */ - - uint8_t cond = bios->data[offset + 1]; - uint16_t retries = bios->data[offset + 2] * 50; - unsigned cnt; - - if (!iexec->execute) - return 3; - - if (retries > 100) - retries = 100; - - BIOSLOG(bios, "0x%04X: Condition: 0x%02X, Retries: 0x%02X\n", - offset, cond, retries); - - if (!bios->execute) /* avoid 2s delays when "faking" execution */ - retries = 1; - - for (cnt = 0; cnt < retries; cnt++) { - if (bios_condition_met(bios, offset, cond)) { - BIOSLOG(bios, "0x%04X: Condition met, continuing\n", - offset); - break; - } else { - BIOSLOG(bios, "0x%04X: " - "Condition not met, sleeping for 20ms\n", - offset); - mdelay(20); - } - } - - if (!bios_condition_met(bios, offset, cond)) { - NV_WARN(bios->dev, - "0x%04X: Condition still not met after %dms, " - "skipping following opcodes\n", offset, 20 * retries); - iexec->execute = false; - } - - return 3; -} - -static int -init_ltime(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_LTIME opcode: 0x57 ('V') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): time - * - * Sleep for "time" milliseconds. - */ - - unsigned time = ROM16(bios->data[offset + 1]); - - if (!iexec->execute) - return 3; - - BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X milliseconds\n", - offset, time); - - mdelay(time); - - return 3; -} - -static int -init_zm_reg_sequence(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_ZM_REG_SEQUENCE opcode: 0x58 ('X') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): base register - * offset + 5 (8 bit): count - * offset + 6 (32 bit): value 1 - * ... - * - * Starting at offset + 6 there are "count" 32 bit values. - * For "count" iterations set "base register" + 4 * current_iteration - * to "value current_iteration" - */ - - uint32_t basereg = ROM32(bios->data[offset + 1]); - uint32_t count = bios->data[offset + 5]; - int len = 6 + count * 4; - int i; - - if (!iexec->execute) - return len; - - BIOSLOG(bios, "0x%04X: BaseReg: 0x%08X, Count: 0x%02X\n", - offset, basereg, count); - - for (i = 0; i < count; i++) { - uint32_t reg = basereg + i * 4; - uint32_t data = ROM32(bios->data[offset + 6 + i * 4]); - - bios_wr32(bios, reg, data); - } - - return len; -} - -static int -init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_SUB_DIRECT opcode: 0x5B ('[') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): subroutine offset (in bios) - * - * Calls a subroutine that will execute commands until INIT_DONE - * is found. - */ - - uint16_t sub_offset = ROM16(bios->data[offset + 1]); - - if (!iexec->execute) - return 3; - - BIOSLOG(bios, "0x%04X: Executing subroutine at 0x%04X\n", - offset, sub_offset); - - parse_init_table(bios, sub_offset, iexec); - - BIOSLOG(bios, "0x%04X: End of 0x%04X subroutine\n", offset, sub_offset); - - return 3; -} - -static int -init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_JUMP opcode: 0x5C ('\') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): offset (in bios) - * - * Continue execution of init table from 'offset' - */ - - uint16_t jmp_offset = ROM16(bios->data[offset + 1]); - - if (!iexec->execute) - return 3; - - BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset); - return jmp_offset - offset; -} - -static int -init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_I2C_IF opcode: 0x5E ('^') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): DCB I2C table entry index - * offset + 2 (8 bit): I2C slave address - * offset + 3 (8 bit): I2C register - * offset + 4 (8 bit): mask - * offset + 5 (8 bit): data - * - * Read the register given by "I2C register" on the device addressed - * by "I2C slave address" on the I2C bus given by "DCB I2C table - * entry index". Compare the result AND "mask" to "data". - * If they're not equal, skip subsequent opcodes until condition is - * inverted (INIT_NOT), or we hit INIT_RESUME - */ - - uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2] >> 1; - uint8_t reg = bios->data[offset + 3]; - uint8_t mask = bios->data[offset + 4]; - uint8_t data = bios->data[offset + 5]; - struct nouveau_i2c_chan *chan; - union i2c_smbus_data val; - int ret; - - /* no execute check by design */ - - BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n", - offset, i2c_index, i2c_address); - - chan = init_i2c_device_find(bios->dev, i2c_index); - if (!chan) - return -ENODEV; - - ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, - I2C_SMBUS_READ, reg, - I2C_SMBUS_BYTE_DATA, &val); - if (ret < 0) { - BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: [no device], " - "Mask: 0x%02X, Data: 0x%02X\n", - offset, reg, mask, data); - iexec->execute = 0; - return 6; - } - - BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " - "Mask: 0x%02X, Data: 0x%02X\n", - offset, reg, val.byte, mask, data); - - iexec->execute = ((val.byte & mask) == data); - - return 6; -} - -static int -init_copy_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_COPY_NV_REG opcode: 0x5F ('_') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): src reg - * offset + 5 (8 bit): shift - * offset + 6 (32 bit): src mask - * offset + 10 (32 bit): xor - * offset + 14 (32 bit): dst reg - * offset + 18 (32 bit): dst mask - * - * Shift REGVAL("src reg") right by (signed) "shift", AND result with - * "src mask", then XOR with "xor". Write this OR'd with - * (REGVAL("dst reg") AND'd with "dst mask") to "dst reg" - */ - - uint32_t srcreg = *((uint32_t *)(&bios->data[offset + 1])); - uint8_t shift = bios->data[offset + 5]; - uint32_t srcmask = *((uint32_t *)(&bios->data[offset + 6])); - uint32_t xor = *((uint32_t *)(&bios->data[offset + 10])); - uint32_t dstreg = *((uint32_t *)(&bios->data[offset + 14])); - uint32_t dstmask = *((uint32_t *)(&bios->data[offset + 18])); - uint32_t srcvalue, dstvalue; - - if (!iexec->execute) - return 22; - - BIOSLOG(bios, "0x%04X: SrcReg: 0x%08X, Shift: 0x%02X, SrcMask: 0x%08X, " - "Xor: 0x%08X, DstReg: 0x%08X, DstMask: 0x%08X\n", - offset, srcreg, shift, srcmask, xor, dstreg, dstmask); - - srcvalue = bios_rd32(bios, srcreg); - - if (shift < 0x80) - srcvalue >>= shift; - else - srcvalue <<= (0x100 - shift); - - srcvalue = (srcvalue & srcmask) ^ xor; - - dstvalue = bios_rd32(bios, dstreg) & dstmask; - - bios_wr32(bios, dstreg, dstvalue | srcvalue); - - return 22; -} - -static int -init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_INDEX_IO opcode: 0x62 ('b') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): CRTC port - * offset + 3 (8 bit): CRTC index - * offset + 4 (8 bit): data - * - * Write "data" to index "CRTC index" of "CRTC port" - */ - uint16_t crtcport = ROM16(bios->data[offset + 1]); - uint8_t crtcindex = bios->data[offset + 3]; - uint8_t data = bios->data[offset + 4]; - - if (!iexec->execute) - return 5; - - bios_idxprt_wr(bios, crtcport, crtcindex, data); - - return 5; -} - -static inline void -bios_md32(struct nvbios *bios, uint32_t reg, - uint32_t mask, uint32_t val) -{ - bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val); -} - -static uint32_t -peek_fb(struct drm_device *dev, struct io_mapping *fb, - uint32_t off) -{ - uint32_t val = 0; - - if (off < pci_resource_len(dev->pdev, 1)) { - uint8_t __iomem *p = - io_mapping_map_atomic_wc(fb, off & PAGE_MASK); - - val = ioread32(p + (off & ~PAGE_MASK)); - - io_mapping_unmap_atomic(p); - } - - return val; -} - -static void -poke_fb(struct drm_device *dev, struct io_mapping *fb, - uint32_t off, uint32_t val) -{ - if (off < pci_resource_len(dev->pdev, 1)) { - uint8_t __iomem *p = - io_mapping_map_atomic_wc(fb, off & PAGE_MASK); - - iowrite32(val, p + (off & ~PAGE_MASK)); - wmb(); - - io_mapping_unmap_atomic(p); - } -} - -static inline bool -read_back_fb(struct drm_device *dev, struct io_mapping *fb, - uint32_t off, uint32_t val) -{ - poke_fb(dev, fb, off, val); - return val == peek_fb(dev, fb, off); -} - -static int -nv04_init_compute_mem(struct nvbios *bios) -{ - struct drm_device *dev = bios->dev; - uint32_t patt = 0xdeadbeef; - struct io_mapping *fb; - int i; - - /* Map the framebuffer aperture */ - fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1)); - if (!fb) - return -ENOMEM; - - /* Sequencer and refresh off */ - NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); - bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF); - - bios_md32(bios, NV04_PFB_BOOT_0, ~0, - NV04_PFB_BOOT_0_RAM_AMOUNT_16MB | - NV04_PFB_BOOT_0_RAM_WIDTH_128 | - NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT); - - for (i = 0; i < 4; i++) - poke_fb(dev, fb, 4 * i, patt); - - poke_fb(dev, fb, 0x400000, patt + 1); - - if (peek_fb(dev, fb, 0) == patt + 1) { - bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, - NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT); - bios_md32(bios, NV04_PFB_DEBUG_0, - NV04_PFB_DEBUG_0_REFRESH_OFF, 0); - - for (i = 0; i < 4; i++) - poke_fb(dev, fb, 4 * i, patt); - - if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff)) - bios_md32(bios, NV04_PFB_BOOT_0, - NV04_PFB_BOOT_0_RAM_WIDTH_128 | - NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); - - } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) != - (patt & 0xffff0000)) { - bios_md32(bios, NV04_PFB_BOOT_0, - NV04_PFB_BOOT_0_RAM_WIDTH_128 | - NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); - - } else if (peek_fb(dev, fb, 0) != patt) { - if (read_back_fb(dev, fb, 0x800000, patt)) - bios_md32(bios, NV04_PFB_BOOT_0, - NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); - else - bios_md32(bios, NV04_PFB_BOOT_0, - NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); - - bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, - NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT); - - } else if (!read_back_fb(dev, fb, 0x800000, patt)) { - bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); - - } - - /* Refresh on, sequencer on */ - bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); - NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); - - io_mapping_free(fb); - return 0; -} - -static const uint8_t * -nv05_memory_config(struct nvbios *bios) -{ - /* Defaults for BIOSes lacking a memory config table */ - static const uint8_t default_config_tab[][2] = { - { 0x24, 0x00 }, - { 0x28, 0x00 }, - { 0x24, 0x01 }, - { 0x1f, 0x00 }, - { 0x0f, 0x00 }, - { 0x17, 0x00 }, - { 0x06, 0x00 }, - { 0x00, 0x00 } - }; - int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & - NV_PEXTDEV_BOOT_0_RAMCFG) >> 2; - - if (bios->legacy.mem_init_tbl_ptr) - return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i]; - else - return default_config_tab[i]; -} - -static int -nv05_init_compute_mem(struct nvbios *bios) -{ - struct drm_device *dev = bios->dev; - const uint8_t *ramcfg = nv05_memory_config(bios); - uint32_t patt = 0xdeadbeef; - struct io_mapping *fb; - int i, v; - - /* Map the framebuffer aperture */ - fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1)); - if (!fb) - return -ENOMEM; - - /* Sequencer off */ - NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); - - if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE) - goto out; - - bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); - - /* If present load the hardcoded scrambling table */ - if (bios->legacy.mem_init_tbl_ptr) { - uint32_t *scramble_tab = (uint32_t *)&bios->data[ - bios->legacy.mem_init_tbl_ptr + 0x10]; - - for (i = 0; i < 8; i++) - bios_wr32(bios, NV04_PFB_SCRAMBLE(i), - ROM32(scramble_tab[i])); - } - - /* Set memory type/width/length defaults depending on the straps */ - bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]); - - if (ramcfg[1] & 0x80) - bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE); - - bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20); - bios_md32(bios, NV04_PFB_CFG1, 0, 1); - - /* Probe memory bus width */ - for (i = 0; i < 4; i++) - poke_fb(dev, fb, 4 * i, patt); - - if (peek_fb(dev, fb, 0xc) != patt) - bios_md32(bios, NV04_PFB_BOOT_0, - NV04_PFB_BOOT_0_RAM_WIDTH_128, 0); - - /* Probe memory length */ - v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT; - - if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB && - (!read_back_fb(dev, fb, 0x1000000, ++patt) || - !read_back_fb(dev, fb, 0, ++patt))) - bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_16MB); - - if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB && - !read_back_fb(dev, fb, 0x800000, ++patt)) - bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); - - if (!read_back_fb(dev, fb, 0x400000, ++patt)) - bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, - NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); - -out: - /* Sequencer on */ - NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); - - io_mapping_free(fb); - return 0; -} - -static int -nv10_init_compute_mem(struct nvbios *bios) -{ - struct drm_device *dev = bios->dev; - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - const int mem_width[] = { 0x10, 0x00, 0x20 }; - const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2); - uint32_t patt = 0xdeadbeef; - struct io_mapping *fb; - int i, j, k; - - /* Map the framebuffer aperture */ - fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1)); - if (!fb) - return -ENOMEM; - - bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); - - /* Probe memory bus width */ - for (i = 0; i < mem_width_count; i++) { - bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]); - - for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) - poke_fb(dev, fb, 0x1c, 0); - - poke_fb(dev, fb, 0x1c, patt); - poke_fb(dev, fb, 0x3c, 0); - - if (peek_fb(dev, fb, 0x1c) == patt) - goto mem_width_found; - } - } - -mem_width_found: - patt <<= 1; - - /* Probe amount of installed memory */ - for (i = 0; i < 4; i++) { - int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000; - - poke_fb(dev, fb, off, patt); - poke_fb(dev, fb, 0, 0); - - peek_fb(dev, fb, 0); - peek_fb(dev, fb, 0); - peek_fb(dev, fb, 0); - peek_fb(dev, fb, 0); - - if (peek_fb(dev, fb, off) == patt) - goto amount_found; - } - - /* IC missing - disable the upper half memory space. */ - bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0); - -amount_found: - io_mapping_free(fb); - return 0; -} - -static int -nv20_init_compute_mem(struct nvbios *bios) -{ - struct drm_device *dev = bios->dev; - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900); - uint32_t amount, off; - struct io_mapping *fb; - - /* Map the framebuffer aperture */ - fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1)); - if (!fb) - return -ENOMEM; - - bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); - - /* Allow full addressing */ - bios_md32(bios, NV04_PFB_CFG0, 0, mask); - - amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); - for (off = amount; off > 0x2000000; off -= 0x2000000) - poke_fb(dev, fb, off - 4, off); - - amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); - if (amount != peek_fb(dev, fb, amount - 4)) - /* IC missing - disable the upper half memory space. */ - bios_md32(bios, NV04_PFB_CFG0, mask, 0); - - io_mapping_free(fb); - return 0; -} - -static int -init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_COMPUTE_MEM opcode: 0x63 ('c') - * - * offset (8 bit): opcode - * - * This opcode is meant to set the PFB memory config registers - * appropriately so that we can correctly calculate how much VRAM it - * has (on nv10 and better chipsets the amount of installed VRAM is - * subsequently reported in NV_PFB_CSTATUS (0x10020C)). - * - * The implementation of this opcode in general consists of several - * parts: - * - * 1) Determination of memory type and density. Only necessary for - * really old chipsets, the memory type reported by the strap bits - * (0x101000) is assumed to be accurate on nv05 and newer. - * - * 2) Determination of the memory bus width. Usually done by a cunning - * combination of writes to offsets 0x1c and 0x3c in the fb, and - * seeing whether the written values are read back correctly. - * - * Only necessary on nv0x-nv1x and nv34, on the other cards we can - * trust the straps. - * - * 3) Determination of how many of the card's RAM pads have ICs - * attached, usually done by a cunning combination of writes to an - * offset slightly less than the maximum memory reported by - * NV_PFB_CSTATUS, then seeing if the test pattern can be read back. - * - * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io - * logs of the VBIOS and kmmio traces of the binary driver POSTing the - * card show nothing being done for this opcode. Why is it still listed - * in the table?! - */ - - /* no iexec->execute check by design */ - - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - int ret; - - if (dev_priv->chipset >= 0x40 || - dev_priv->chipset == 0x1a || - dev_priv->chipset == 0x1f) - ret = 0; - else if (dev_priv->chipset >= 0x20 && - dev_priv->chipset != 0x34) - ret = nv20_init_compute_mem(bios); - else if (dev_priv->chipset >= 0x10) - ret = nv10_init_compute_mem(bios); - else if (dev_priv->chipset >= 0x5) - ret = nv05_init_compute_mem(bios); - else - ret = nv04_init_compute_mem(bios); - - if (ret) - return ret; - - return 1; -} - -static int -init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_RESET opcode: 0x65 ('e') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (32 bit): value1 - * offset + 9 (32 bit): value2 - * - * Assign "value1" to "register", then assign "value2" to "register" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint32_t value1 = ROM32(bios->data[offset + 5]); - uint32_t value2 = ROM32(bios->data[offset + 9]); - uint32_t pci_nv_19, pci_nv_20; - - /* no iexec->execute check by design */ - - pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19); - bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00); - - bios_wr32(bios, reg, value1); - - udelay(10); - - bios_wr32(bios, reg, value2); - bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19); - - pci_nv_20 = bios_rd32(bios, NV_PBUS_PCI_NV_20); - pci_nv_20 &= ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED; /* 0xfffffffe */ - bios_wr32(bios, NV_PBUS_PCI_NV_20, pci_nv_20); - - return 13; -} - -static int -init_configure_mem(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_CONFIGURE_MEM opcode: 0x66 ('f') - * - * offset (8 bit): opcode - * - * Equivalent to INIT_DONE on bios version 3 or greater. - * For early bios versions, sets up the memory registers, using values - * taken from the memory init table - */ - - /* no iexec->execute check by design */ - - uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4); - uint16_t seqtbloffs = bios->legacy.sdr_seq_tbl_ptr, meminitdata = meminitoffs + 6; - uint32_t reg, data; - - if (bios->major_version > 2) - return 0; - - bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd( - bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20); - - if (bios->data[meminitoffs] & 1) - seqtbloffs = bios->legacy.ddr_seq_tbl_ptr; - - for (reg = ROM32(bios->data[seqtbloffs]); - reg != 0xffffffff; - reg = ROM32(bios->data[seqtbloffs += 4])) { - - switch (reg) { - case NV04_PFB_PRE: - data = NV04_PFB_PRE_CMD_PRECHARGE; - break; - case NV04_PFB_PAD: - data = NV04_PFB_PAD_CKE_NORMAL; - break; - case NV04_PFB_REF: - data = NV04_PFB_REF_CMD_REFRESH; - break; - default: - data = ROM32(bios->data[meminitdata]); - meminitdata += 4; - if (data == 0xffffffff) - continue; - } - - bios_wr32(bios, reg, data); - } - - return 1; -} - -static int -init_configure_clk(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_CONFIGURE_CLK opcode: 0x67 ('g') - * - * offset (8 bit): opcode - * - * Equivalent to INIT_DONE on bios version 3 or greater. - * For early bios versions, sets up the NVClk and MClk PLLs, using - * values taken from the memory init table - */ - - /* no iexec->execute check by design */ - - uint16_t meminitoffs = bios->legacy.mem_init_tbl_ptr + MEM_INIT_SIZE * (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_SCRATCH4__INDEX) >> 4); - int clock; - - if (bios->major_version > 2) - return 0; - - clock = ROM16(bios->data[meminitoffs + 4]) * 10; - setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); - - clock = ROM16(bios->data[meminitoffs + 2]) * 10; - if (bios->data[meminitoffs] & 1) /* DDR */ - clock *= 2; - setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock); - - return 1; -} - -static int -init_configure_preinit(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_CONFIGURE_PREINIT opcode: 0x68 ('h') - * - * offset (8 bit): opcode - * - * Equivalent to INIT_DONE on bios version 3 or greater. - * For early bios versions, does early init, loading ram and crystal - * configuration from straps into CR3C - */ - - /* no iexec->execute check by design */ - - uint32_t straps = bios_rd32(bios, NV_PEXTDEV_BOOT_0); - uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & 0x40) >> 6; - - if (bios->major_version > 2) - return 0; - - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, - NV_CIO_CRE_SCRATCH4__INDEX, cr3c); - - return 1; -} - -static int -init_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_IO opcode: 0x69 ('i') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): CRTC port - * offset + 3 (8 bit): mask - * offset + 4 (8 bit): data - * - * Assign ((IOVAL("crtc port") & "mask") | "data") to "crtc port" - */ - - struct drm_nouveau_private *dev_priv = bios->dev->dev_private; - uint16_t crtcport = ROM16(bios->data[offset + 1]); - uint8_t mask = bios->data[offset + 3]; - uint8_t data = bios->data[offset + 4]; - - if (!iexec->execute) - return 5; - - BIOSLOG(bios, "0x%04X: Port: 0x%04X, Mask: 0x%02X, Data: 0x%02X\n", - offset, crtcport, mask, data); - - /* - * I have no idea what this does, but NVIDIA do this magic sequence - * in the places where this INIT_IO happens.. - */ - if (dev_priv->card_type >= NV_50 && crtcport == 0x3c3 && data == 1) { - int i; - - bios_wr32(bios, 0x614100, (bios_rd32( - bios, 0x614100) & 0x0fffffff) | 0x00800000); - - bios_wr32(bios, 0x00e18c, bios_rd32( - bios, 0x00e18c) | 0x00020000); - - bios_wr32(bios, 0x614900, (bios_rd32( - bios, 0x614900) & 0x0fffffff) | 0x00800000); - - bios_wr32(bios, 0x000200, bios_rd32( - bios, 0x000200) & ~0x40000000); - - mdelay(10); - - bios_wr32(bios, 0x00e18c, bios_rd32( - bios, 0x00e18c) & ~0x00020000); - - bios_wr32(bios, 0x000200, bios_rd32( - bios, 0x000200) | 0x40000000); - - bios_wr32(bios, 0x614100, 0x00800018); - bios_wr32(bios, 0x614900, 0x00800018); - - mdelay(10); - - bios_wr32(bios, 0x614100, 0x10000018); - bios_wr32(bios, 0x614900, 0x10000018); - - for (i = 0; i < 3; i++) - bios_wr32(bios, 0x614280 + (i*0x800), bios_rd32( - bios, 0x614280 + (i*0x800)) & 0xf0f0f0f0); - - for (i = 0; i < 2; i++) - bios_wr32(bios, 0x614300 + (i*0x800), bios_rd32( - bios, 0x614300 + (i*0x800)) & 0xfffff0f0); - - for (i = 0; i < 3; i++) - bios_wr32(bios, 0x614380 + (i*0x800), bios_rd32( - bios, 0x614380 + (i*0x800)) & 0xfffff0f0); - - for (i = 0; i < 2; i++) - bios_wr32(bios, 0x614200 + (i*0x800), bios_rd32( - bios, 0x614200 + (i*0x800)) & 0xfffffff0); - - for (i = 0; i < 2; i++) - bios_wr32(bios, 0x614108 + (i*0x800), bios_rd32( - bios, 0x614108 + (i*0x800)) & 0x0fffffff); - return 5; - } - - bios_port_wr(bios, crtcport, (bios_port_rd(bios, crtcport) & mask) | - data); - return 5; -} - -static int -init_sub(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_SUB opcode: 0x6B ('k') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): script number - * - * Execute script number "script number", as a subroutine - */ - - uint8_t sub = bios->data[offset + 1]; - - if (!iexec->execute) - return 2; - - BIOSLOG(bios, "0x%04X: Calling script %d\n", offset, sub); - - parse_init_table(bios, - ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]), - iexec); - - BIOSLOG(bios, "0x%04X: End of script %d\n", offset, sub); - - return 2; -} - -static int -init_ram_condition(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_RAM_CONDITION opcode: 0x6D ('m') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): mask - * offset + 2 (8 bit): cmpval - * - * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval". - * If condition not met skip subsequent opcodes until condition is - * inverted (INIT_NOT), or we hit INIT_RESUME - */ - - uint8_t mask = bios->data[offset + 1]; - uint8_t cmpval = bios->data[offset + 2]; - uint8_t data; - - if (!iexec->execute) - return 3; - - data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask; - - BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n", - offset, data, cmpval); - - if (data == cmpval) - BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); - else { - BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); - iexec->execute = false; - } - - return 3; -} - -static int -init_nv_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_NV_REG opcode: 0x6E ('n') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (32 bit): mask - * offset + 9 (32 bit): data - * - * Assign ((REGVAL("register") & "mask") | "data") to "register" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint32_t mask = ROM32(bios->data[offset + 5]); - uint32_t data = ROM32(bios->data[offset + 9]); - - if (!iexec->execute) - return 13; - - BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Mask: 0x%08X, Data: 0x%08X\n", - offset, reg, mask, data); - - bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | data); - - return 13; -} - -static int -init_macro(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_MACRO opcode: 0x6F ('o') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): macro number - * - * Look up macro index "macro number" in the macro index table. - * The macro index table entry has 1 byte for the index in the macro - * table, and 1 byte for the number of times to repeat the macro. - * The macro table entry has 4 bytes for the register address and - * 4 bytes for the value to write to that register - */ - - uint8_t macro_index_tbl_idx = bios->data[offset + 1]; - uint16_t tmp = bios->macro_index_tbl_ptr + (macro_index_tbl_idx * MACRO_INDEX_SIZE); - uint8_t macro_tbl_idx = bios->data[tmp]; - uint8_t count = bios->data[tmp + 1]; - uint32_t reg, data; - int i; - - if (!iexec->execute) - return 2; - - BIOSLOG(bios, "0x%04X: Macro: 0x%02X, MacroTableIndex: 0x%02X, " - "Count: 0x%02X\n", - offset, macro_index_tbl_idx, macro_tbl_idx, count); - - for (i = 0; i < count; i++) { - uint16_t macroentryptr = bios->macro_tbl_ptr + (macro_tbl_idx + i) * MACRO_SIZE; - - reg = ROM32(bios->data[macroentryptr]); - data = ROM32(bios->data[macroentryptr + 4]); - - bios_wr32(bios, reg, data); - } - - return 2; -} - -static int -init_done(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_DONE opcode: 0x71 ('q') - * - * offset (8 bit): opcode - * - * End the current script - */ - - /* mild retval abuse to stop parsing this table */ - return 0; -} - -static int -init_resume(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_RESUME opcode: 0x72 ('r') - * - * offset (8 bit): opcode - * - * End the current execute / no-execute condition - */ - - if (iexec->execute) - return 1; - - iexec->execute = true; - BIOSLOG(bios, "0x%04X: ---- Executing following commands ----\n", offset); - - return 1; -} - -static int -init_time(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_TIME opcode: 0x74 ('t') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): time - * - * Sleep for "time" microseconds. - */ - - unsigned time = ROM16(bios->data[offset + 1]); - - if (!iexec->execute) - return 3; - - BIOSLOG(bios, "0x%04X: Sleeping for 0x%04X microseconds\n", - offset, time); - - if (time < 1000) - udelay(time); - else - mdelay((time + 900) / 1000); - - return 3; -} - -static int -init_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_CONDITION opcode: 0x75 ('u') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): condition number - * - * Check condition "condition number" in the condition table. - * If condition not met skip subsequent opcodes until condition is - * inverted (INIT_NOT), or we hit INIT_RESUME - */ - - uint8_t cond = bios->data[offset + 1]; - - if (!iexec->execute) - return 2; - - BIOSLOG(bios, "0x%04X: Condition: 0x%02X\n", offset, cond); - - if (bios_condition_met(bios, offset, cond)) - BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); - else { - BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); - iexec->execute = false; - } - - return 2; -} - -static int -init_io_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_IO_CONDITION opcode: 0x76 - * - * offset (8 bit): opcode - * offset + 1 (8 bit): condition number - * - * Check condition "condition number" in the io condition table. - * If condition not met skip subsequent opcodes until condition is - * inverted (INIT_NOT), or we hit INIT_RESUME - */ - - uint8_t cond = bios->data[offset + 1]; - - if (!iexec->execute) - return 2; - - BIOSLOG(bios, "0x%04X: IO condition: 0x%02X\n", offset, cond); - - if (io_condition_met(bios, offset, cond)) - BIOSLOG(bios, "0x%04X: Condition fulfilled -- continuing to execute\n", offset); - else { - BIOSLOG(bios, "0x%04X: Condition not fulfilled -- skipping following commands\n", offset); - iexec->execute = false; - } - - return 2; -} - -static int -init_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_INDEX_IO opcode: 0x78 ('x') - * - * offset (8 bit): opcode - * offset + 1 (16 bit): CRTC port - * offset + 3 (8 bit): CRTC index - * offset + 4 (8 bit): mask - * offset + 5 (8 bit): data - * - * Read value at index "CRTC index" on "CRTC port", AND with "mask", - * OR with "data", write-back - */ - - uint16_t crtcport = ROM16(bios->data[offset + 1]); - uint8_t crtcindex = bios->data[offset + 3]; - uint8_t mask = bios->data[offset + 4]; - uint8_t data = bios->data[offset + 5]; - uint8_t value; - - if (!iexec->execute) - return 6; - - BIOSLOG(bios, "0x%04X: Port: 0x%04X, Index: 0x%02X, Mask: 0x%02X, " - "Data: 0x%02X\n", - offset, crtcport, crtcindex, mask, data); - - value = (bios_idxprt_rd(bios, crtcport, crtcindex) & mask) | data; - bios_idxprt_wr(bios, crtcport, crtcindex, value); - - return 6; -} - -static int -init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_PLL opcode: 0x79 ('y') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (16 bit): freq - * - * Set PLL register "register" to coefficients for frequency (10kHz) - * "freq" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint16_t freq = ROM16(bios->data[offset + 5]); - - if (!iexec->execute) - return 7; - - BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); - - setPLL(bios, reg, freq * 10); - - return 7; -} - -static int -init_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_REG opcode: 0x7A ('z') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (32 bit): value - * - * Assign "value" to "register" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint32_t value = ROM32(bios->data[offset + 5]); - - if (!iexec->execute) - return 9; - - if (reg == 0x000200) - value |= 1; - - bios_wr32(bios, reg, value); - - return 9; -} - -static int -init_ram_restrict_pll(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_RAM_RESTRICT_PLL opcode: 0x87 ('') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): PLL type - * offset + 2 (32 bit): frequency 0 - * - * Uses the RAMCFG strap of PEXTDEV_BOOT as an index into the table at - * ram_restrict_table_ptr. The value read from there is used to select - * a frequency from the table starting at 'frequency 0' to be - * programmed into the PLL corresponding to 'type'. - * - * The PLL limits table on cards using this opcode has a mapping of - * 'type' to the relevant registers. - */ - - struct drm_device *dev = bios->dev; - uint32_t strap = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2; - uint8_t index = bios->data[bios->ram_restrict_tbl_ptr + strap]; - uint8_t type = bios->data[offset + 1]; - uint32_t freq = ROM32(bios->data[offset + 2 + (index * 4)]); - uint8_t *pll_limits = &bios->data[bios->pll_limit_tbl_ptr], *entry; - int len = 2 + bios->ram_restrict_group_count * 4; - int i; - - if (!iexec->execute) - return len; - - if (!bios->pll_limit_tbl_ptr || (pll_limits[0] & 0xf0) != 0x30) { - NV_ERROR(dev, "PLL limits table not version 3.x\n"); - return len; /* deliberate, allow default clocks to remain */ - } - - entry = pll_limits + pll_limits[1]; - for (i = 0; i < pll_limits[3]; i++, entry += pll_limits[2]) { - if (entry[0] == type) { - uint32_t reg = ROM32(entry[3]); - - BIOSLOG(bios, "0x%04X: " - "Type %02x Reg 0x%08x Freq %dKHz\n", - offset, type, reg, freq); - - setPLL(bios, reg, freq); - return len; - } - } - - NV_ERROR(dev, "PLL type 0x%02x not found in PLL limits table", type); - return len; -} - -static int -init_8c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_8C opcode: 0x8C ('') - * - * NOP so far.... - * - */ - - return 1; -} - -static int -init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_8D opcode: 0x8D ('') - * - * NOP so far.... - * - */ - - return 1; -} - -static int -init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_GPIO opcode: 0x8E ('') - * - * offset (8 bit): opcode - * - * Loop over all entries in the DCB GPIO table, and initialise - * each GPIO according to various values listed in each entry - */ - - if (iexec->execute && bios->execute) - nouveau_gpio_reset(bios->dev); - - return 1; -} - -static int -init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_RAM_RESTRICT_ZM_REG_GROUP opcode: 0x8F ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): reg - * offset + 5 (8 bit): regincrement - * offset + 6 (8 bit): count - * offset + 7 (32 bit): value 1,1 - * ... - * - * Use the RAMCFG strap of PEXTDEV_BOOT as an index into the table at - * ram_restrict_table_ptr. The value read from here is 'n', and - * "value 1,n" gets written to "reg". This repeats "count" times and on - * each iteration 'm', "reg" increases by "regincrement" and - * "value m,n" is used. The extent of n is limited by a number read - * from the 'M' BIT table, herein called "blocklen" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint8_t regincrement = bios->data[offset + 5]; - uint8_t count = bios->data[offset + 6]; - uint32_t strap_ramcfg, data; - /* previously set by 'M' BIT table */ - uint16_t blocklen = bios->ram_restrict_group_count * 4; - int len = 7 + count * blocklen; - uint8_t index; - int i; - - /* critical! to know the length of the opcode */; - if (!blocklen) { - NV_ERROR(bios->dev, - "0x%04X: Zero block length - has the M table " - "been parsed?\n", offset); - return -EINVAL; - } - - if (!iexec->execute) - return len; - - strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf; - index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg]; - - BIOSLOG(bios, "0x%04X: Reg: 0x%08X, RegIncrement: 0x%02X, " - "Count: 0x%02X, StrapRamCfg: 0x%02X, Index: 0x%02X\n", - offset, reg, regincrement, count, strap_ramcfg, index); - - for (i = 0; i < count; i++) { - data = ROM32(bios->data[offset + 7 + index * 4 + blocklen * i]); - - bios_wr32(bios, reg, data); - - reg += regincrement; - } - - return len; -} - -static int -init_copy_zm_reg(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_COPY_ZM_REG opcode: 0x90 ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): src reg - * offset + 5 (32 bit): dst reg - * - * Put contents of "src reg" into "dst reg" - */ - - uint32_t srcreg = ROM32(bios->data[offset + 1]); - uint32_t dstreg = ROM32(bios->data[offset + 5]); - - if (!iexec->execute) - return 9; - - bios_wr32(bios, dstreg, bios_rd32(bios, srcreg)); - - return 9; -} - -static int -init_zm_reg_group_addr_latched(struct nvbios *bios, uint16_t offset, - struct init_exec *iexec) -{ - /* - * INIT_ZM_REG_GROUP_ADDRESS_LATCHED opcode: 0x91 ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): dst reg - * offset + 5 (8 bit): count - * offset + 6 (32 bit): data 1 - * ... - * - * For each of "count" values write "data n" to "dst reg" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint8_t count = bios->data[offset + 5]; - int len = 6 + count * 4; - int i; - - if (!iexec->execute) - return len; - - for (i = 0; i < count; i++) { - uint32_t data = ROM32(bios->data[offset + 6 + 4 * i]); - bios_wr32(bios, reg, data); - } - - return len; -} - -static int -init_reserved(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_RESERVED opcode: 0x92 ('') - * - * offset (8 bit): opcode - * - * Seemingly does nothing - */ - - return 1; -} - -static int -init_96(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_96 opcode: 0x96 ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): sreg - * offset + 5 (8 bit): sshift - * offset + 6 (8 bit): smask - * offset + 7 (8 bit): index - * offset + 8 (32 bit): reg - * offset + 12 (32 bit): mask - * offset + 16 (8 bit): shift - * - */ - - uint16_t xlatptr = bios->init96_tbl_ptr + (bios->data[offset + 7] * 2); - uint32_t reg = ROM32(bios->data[offset + 8]); - uint32_t mask = ROM32(bios->data[offset + 12]); - uint32_t val; - - val = bios_rd32(bios, ROM32(bios->data[offset + 1])); - if (bios->data[offset + 5] < 0x80) - val >>= bios->data[offset + 5]; - else - val <<= (0x100 - bios->data[offset + 5]); - val &= bios->data[offset + 6]; - - val = bios->data[ROM16(bios->data[xlatptr]) + val]; - val <<= bios->data[offset + 16]; - - if (!iexec->execute) - return 17; - - bios_wr32(bios, reg, (bios_rd32(bios, reg) & mask) | val); - return 17; -} - -static int -init_97(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_97 opcode: 0x97 ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): register - * offset + 5 (32 bit): mask - * offset + 9 (32 bit): value - * - * Adds "value" to "register" preserving the fields specified - * by "mask" - */ - - uint32_t reg = ROM32(bios->data[offset + 1]); - uint32_t mask = ROM32(bios->data[offset + 5]); - uint32_t add = ROM32(bios->data[offset + 9]); - uint32_t val; - - val = bios_rd32(bios, reg); - val = (val & mask) | ((val + add) & ~mask); - - if (!iexec->execute) - return 13; - - bios_wr32(bios, reg, val); - return 13; -} - -static int -init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_AUXCH opcode: 0x98 ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): address - * offset + 5 (8 bit): count - * offset + 6 (8 bit): mask 0 - * offset + 7 (8 bit): data 0 - * ... - * - */ - - struct drm_device *dev = bios->dev; - struct nouveau_i2c_chan *auxch; - uint32_t addr = ROM32(bios->data[offset + 1]); - uint8_t count = bios->data[offset + 5]; - int len = 6 + count * 2; - int ret, i; - - if (!bios->display.output) { - NV_ERROR(dev, "INIT_AUXCH: no active output\n"); - return len; - } - - auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); - if (!auxch) { - NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n", - bios->display.output->i2c_index); - return len; - } - - if (!iexec->execute) - return len; - - offset += 6; - for (i = 0; i < count; i++, offset += 2) { - uint8_t data; - - ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1); - if (ret) { - NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret); - return len; - } - - data &= bios->data[offset + 0]; - data |= bios->data[offset + 1]; - - ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1); - if (ret) { - NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret); - return len; - } - } - - return len; -} - -static int -init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_ZM_AUXCH opcode: 0x99 ('') - * - * offset (8 bit): opcode - * offset + 1 (32 bit): address - * offset + 5 (8 bit): count - * offset + 6 (8 bit): data 0 - * ... - * - */ - - struct drm_device *dev = bios->dev; - struct nouveau_i2c_chan *auxch; - uint32_t addr = ROM32(bios->data[offset + 1]); - uint8_t count = bios->data[offset + 5]; - int len = 6 + count; - int ret, i; - - if (!bios->display.output) { - NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n"); - return len; - } - - auxch = init_i2c_device_find(dev, bios->display.output->i2c_index); - if (!auxch) { - NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n", - bios->display.output->i2c_index); - return len; - } - - if (!iexec->execute) - return len; - - offset += 6; - for (i = 0; i < count; i++, offset++) { - ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1); - if (ret) { - NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret); - return len; - } - } - - return len; -} - -static int -init_i2c_long_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * INIT_I2C_LONG_IF opcode: 0x9A ('') - * - * offset (8 bit): opcode - * offset + 1 (8 bit): DCB I2C table entry index - * offset + 2 (8 bit): I2C slave address - * offset + 3 (16 bit): I2C register - * offset + 5 (8 bit): mask - * offset + 6 (8 bit): data - * - * Read the register given by "I2C register" on the device addressed - * by "I2C slave address" on the I2C bus given by "DCB I2C table - * entry index". Compare the result AND "mask" to "data". - * If they're not equal, skip subsequent opcodes until condition is - * inverted (INIT_NOT), or we hit INIT_RESUME - */ - - uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2] >> 1; - uint8_t reglo = bios->data[offset + 3]; - uint8_t reghi = bios->data[offset + 4]; - uint8_t mask = bios->data[offset + 5]; - uint8_t data = bios->data[offset + 6]; - struct nouveau_i2c_chan *chan; - uint8_t buf0[2] = { reghi, reglo }; - uint8_t buf1[1]; - struct i2c_msg msg[2] = { - { i2c_address, 0, 1, buf0 }, - { i2c_address, I2C_M_RD, 1, buf1 }, - }; - int ret; - - /* no execute check by design */ - - BIOSLOG(bios, "0x%04X: DCBI2CIndex: 0x%02X, I2CAddress: 0x%02X\n", - offset, i2c_index, i2c_address); - - chan = init_i2c_device_find(bios->dev, i2c_index); - if (!chan) - return -ENODEV; - - - ret = i2c_transfer(&chan->adapter, msg, 2); - if (ret < 0) { - BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: [no device], " - "Mask: 0x%02X, Data: 0x%02X\n", - offset, reghi, reglo, mask, data); - iexec->execute = 0; - return 7; - } - - BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X:0x%02X, Value: 0x%02X, " - "Mask: 0x%02X, Data: 0x%02X\n", - offset, reghi, reglo, buf1[0], mask, data); - - iexec->execute = ((buf1[0] & mask) == data); - - return 7; -} - -static struct init_tbl_entry itbl_entry[] = { - /* command name , id , length , offset , mult , command handler */ - /* INIT_PROG (0x31, 15, 10, 4) removed due to no example of use */ - { "INIT_IO_RESTRICT_PROG" , 0x32, init_io_restrict_prog }, - { "INIT_REPEAT" , 0x33, init_repeat }, - { "INIT_IO_RESTRICT_PLL" , 0x34, init_io_restrict_pll }, - { "INIT_END_REPEAT" , 0x36, init_end_repeat }, - { "INIT_COPY" , 0x37, init_copy }, - { "INIT_NOT" , 0x38, init_not }, - { "INIT_IO_FLAG_CONDITION" , 0x39, init_io_flag_condition }, - { "INIT_DP_CONDITION" , 0x3A, init_dp_condition }, - { "INIT_OP_3B" , 0x3B, init_op_3b }, - { "INIT_OP_3C" , 0x3C, init_op_3c }, - { "INIT_INDEX_ADDRESS_LATCHED" , 0x49, init_idx_addr_latched }, - { "INIT_IO_RESTRICT_PLL2" , 0x4A, init_io_restrict_pll2 }, - { "INIT_PLL2" , 0x4B, init_pll2 }, - { "INIT_I2C_BYTE" , 0x4C, init_i2c_byte }, - { "INIT_ZM_I2C_BYTE" , 0x4D, init_zm_i2c_byte }, - { "INIT_ZM_I2C" , 0x4E, init_zm_i2c }, - { "INIT_TMDS" , 0x4F, init_tmds }, - { "INIT_ZM_TMDS_GROUP" , 0x50, init_zm_tmds_group }, - { "INIT_CR_INDEX_ADDRESS_LATCHED" , 0x51, init_cr_idx_adr_latch }, - { "INIT_CR" , 0x52, init_cr }, - { "INIT_ZM_CR" , 0x53, init_zm_cr }, - { "INIT_ZM_CR_GROUP" , 0x54, init_zm_cr_group }, - { "INIT_CONDITION_TIME" , 0x56, init_condition_time }, - { "INIT_LTIME" , 0x57, init_ltime }, - { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, - /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ - { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, - { "INIT_JUMP" , 0x5C, init_jump }, - { "INIT_I2C_IF" , 0x5E, init_i2c_if }, - { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, - { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, - { "INIT_COMPUTE_MEM" , 0x63, init_compute_mem }, - { "INIT_RESET" , 0x65, init_reset }, - { "INIT_CONFIGURE_MEM" , 0x66, init_configure_mem }, - { "INIT_CONFIGURE_CLK" , 0x67, init_configure_clk }, - { "INIT_CONFIGURE_PREINIT" , 0x68, init_configure_preinit }, - { "INIT_IO" , 0x69, init_io }, - { "INIT_SUB" , 0x6B, init_sub }, - { "INIT_RAM_CONDITION" , 0x6D, init_ram_condition }, - { "INIT_NV_REG" , 0x6E, init_nv_reg }, - { "INIT_MACRO" , 0x6F, init_macro }, - { "INIT_DONE" , 0x71, init_done }, - { "INIT_RESUME" , 0x72, init_resume }, - /* INIT_RAM_CONDITION2 (0x73, 9, 0, 0) removed due to no example of use */ - { "INIT_TIME" , 0x74, init_time }, - { "INIT_CONDITION" , 0x75, init_condition }, - { "INIT_IO_CONDITION" , 0x76, init_io_condition }, - { "INIT_INDEX_IO" , 0x78, init_index_io }, - { "INIT_PLL" , 0x79, init_pll }, - { "INIT_ZM_REG" , 0x7A, init_zm_reg }, - { "INIT_RAM_RESTRICT_PLL" , 0x87, init_ram_restrict_pll }, - { "INIT_8C" , 0x8C, init_8c }, - { "INIT_8D" , 0x8D, init_8d }, - { "INIT_GPIO" , 0x8E, init_gpio }, - { "INIT_RAM_RESTRICT_ZM_REG_GROUP" , 0x8F, init_ram_restrict_zm_reg_group }, - { "INIT_COPY_ZM_REG" , 0x90, init_copy_zm_reg }, - { "INIT_ZM_REG_GROUP_ADDRESS_LATCHED" , 0x91, init_zm_reg_group_addr_latched }, - { "INIT_RESERVED" , 0x92, init_reserved }, - { "INIT_96" , 0x96, init_96 }, - { "INIT_97" , 0x97, init_97 }, - { "INIT_AUXCH" , 0x98, init_auxch }, - { "INIT_ZM_AUXCH" , 0x99, init_zm_auxch }, - { "INIT_I2C_LONG_IF" , 0x9A, init_i2c_long_if }, - { NULL , 0 , NULL } -}; - -#define MAX_TABLE_OPS 1000 - -static int -parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) -{ - /* - * Parses all commands in an init table. - * - * We start out executing all commands found in the init table. Some - * opcodes may change the status of iexec->execute to SKIP, which will - * cause the following opcodes to perform no operation until the value - * is changed back to EXECUTE. - */ - - int count = 0, i, ret; - uint8_t id; - - /* catch NULL script pointers */ - if (offset == 0) - return 0; - - /* - * Loop until INIT_DONE causes us to break out of the loop - * (or until offset > bios length just in case... ) - * (and no more than MAX_TABLE_OPS iterations, just in case... ) - */ - while ((offset < bios->length) && (count++ < MAX_TABLE_OPS)) { - id = bios->data[offset]; - - /* Find matching id in itbl_entry */ - for (i = 0; itbl_entry[i].name && (itbl_entry[i].id != id); i++) - ; - - if (!itbl_entry[i].name) { - NV_ERROR(bios->dev, - "0x%04X: Init table command not found: " - "0x%02X\n", offset, id); - return -ENOENT; - } - - BIOSLOG(bios, "0x%04X: [ (0x%02X) - %s ]\n", offset, - itbl_entry[i].id, itbl_entry[i].name); - - /* execute eventual command handler */ - ret = (*itbl_entry[i].handler)(bios, offset, iexec); - if (ret < 0) { - NV_ERROR(bios->dev, "0x%04X: Failed parsing init " - "table opcode: %s %d\n", offset, - itbl_entry[i].name, ret); - } - - if (ret <= 0) - break; - - /* - * Add the offset of the current command including all data - * of that command. The offset will then be pointing on the - * next op code. - */ - offset += ret; - } - - if (offset >= bios->length) - NV_WARN(bios->dev, - "Offset 0x%04X greater than known bios image length. " - "Corrupt image?\n", offset); - if (count >= MAX_TABLE_OPS) - NV_WARN(bios->dev, - "More than %d opcodes to a table is unlikely, " - "is the bios image corrupt?\n", MAX_TABLE_OPS); - - return 0; -} - -static void -parse_init_tables(struct nvbios *bios) -{ - /* Loops and calls parse_init_table() for each present table. */ - - int i = 0; - uint16_t table; - struct init_exec iexec = {true, false}; - - if (bios->old_style_init) { - if (bios->init_script_tbls_ptr) - parse_init_table(bios, bios->init_script_tbls_ptr, &iexec); - if (bios->extra_init_script_tbl_ptr) - parse_init_table(bios, bios->extra_init_script_tbl_ptr, &iexec); - - return; - } - - while ((table = ROM16(bios->data[bios->init_script_tbls_ptr + i]))) { - NV_INFO(bios->dev, - "Parsing VBIOS init table %d at offset 0x%04X\n", - i / 2, table); - BIOSLOG(bios, "0x%04X: ------ Executing following commands ------\n", table); - - parse_init_table(bios, table, &iexec); - i += 2; - } -} - -static uint16_t clkcmptable(struct nvbios *bios, uint16_t clktable, int pxclk) -{ - int compare_record_len, i = 0; - uint16_t compareclk, scriptptr = 0; - - if (bios->major_version < 5) /* pre BIT */ - compare_record_len = 3; - else - compare_record_len = 4; - - do { - compareclk = ROM16(bios->data[clktable + compare_record_len * i]); - if (pxclk >= compareclk * 10) { - if (bios->major_version < 5) { - uint8_t tmdssub = bios->data[clktable + 2 + compare_record_len * i]; - scriptptr = ROM16(bios->data[bios->init_script_tbls_ptr + tmdssub * 2]); - } else - scriptptr = ROM16(bios->data[clktable + 2 + compare_record_len * i]); - break; - } - i++; - } while (compareclk); - - return scriptptr; -} - -static void -run_digital_op_script(struct drm_device *dev, uint16_t scriptptr, - struct dcb_entry *dcbent, int head, bool dl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct init_exec iexec = {true, false}; - - NV_TRACE(dev, "0x%04X: Parsing digital output script table\n", - scriptptr); - bios_idxprt_wr(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_44, - head ? NV_CIO_CRE_44_HEADB : NV_CIO_CRE_44_HEADA); - /* note: if dcb entries have been merged, index may be misleading */ - NVWriteVgaCrtc5758(dev, head, 0, dcbent->index); - parse_init_table(bios, scriptptr, &iexec); - - nv04_dfp_bind_head(dev, dcbent, head, dl); -} - -static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0); - uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]); - - if (!bios->fp.xlated_entry || !sub || !scriptofs) - return -EINVAL; - - run_digital_op_script(dev, scriptofs, dcbent, head, bios->fp.dual_link); - - if (script == LVDS_PANEL_OFF) { - /* off-on delay in ms */ - mdelay(ROM16(bios->data[bios->fp.xlated_entry + 7])); - } -#ifdef __powerpc__ - /* Powerbook specific quirks */ - if (script == LVDS_RESET && - (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || - dev->pci_device == 0x0329)) - nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); -#endif - - return 0; -} - -static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk) -{ - /* - * The BIT LVDS table's header has the information to setup the - * necessary registers. Following the standard 4 byte header are: - * A bitmask byte and a dual-link transition pxclk value for use in - * selecting the init script when not using straps; 4 script pointers - * for panel power, selected by output and on/off; and 8 table pointers - * for panel init, the needed one determined by output, and bits in the - * conf byte. These tables are similar to the TMDS tables, consisting - * of a list of pxclks and script pointers. - */ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - unsigned int outputset = (dcbent->or == 4) ? 1 : 0; - uint16_t scriptptr = 0, clktable; - - /* - * For now we assume version 3.0 table - g80 support will need some - * changes - */ - - switch (script) { - case LVDS_INIT: - return -ENOSYS; - case LVDS_BACKLIGHT_ON: - case LVDS_PANEL_ON: - scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 7 + outputset * 2]); - break; - case LVDS_BACKLIGHT_OFF: - case LVDS_PANEL_OFF: - scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]); - break; - case LVDS_RESET: - clktable = bios->fp.lvdsmanufacturerpointer + 15; - if (dcbent->or == 4) - clktable += 8; - - if (dcbent->lvdsconf.use_straps_for_mode) { - if (bios->fp.dual_link) - clktable += 4; - if (bios->fp.if_is_24bit) - clktable += 2; - } else { - /* using EDID */ - int cmpval_24bit = (dcbent->or == 4) ? 4 : 1; - - if (bios->fp.dual_link) { - clktable += 4; - cmpval_24bit <<= 1; - } - - if (bios->fp.strapless_is_24bit & cmpval_24bit) - clktable += 2; - } - - clktable = ROM16(bios->data[clktable]); - if (!clktable) { - NV_ERROR(dev, "Pixel clock comparison table not found\n"); - return -ENOENT; - } - scriptptr = clkcmptable(bios, clktable, pxclk); - } - - if (!scriptptr) { - NV_ERROR(dev, "LVDS output init script not found\n"); - return -ENOENT; - } - run_digital_op_script(dev, scriptptr, dcbent, head, bios->fp.dual_link); - - return 0; -} - -int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script, int pxclk) -{ - /* - * LVDS operations are multiplexed in an effort to present a single API - * which works with two vastly differing underlying structures. - * This acts as the demux - */ - - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; - uint32_t sel_clk_binding, sel_clk; - int ret; - - if (bios->fp.last_script_invoc == (script << 1 | head) || !lvds_ver || - (lvds_ver >= 0x30 && script == LVDS_INIT)) - return 0; - - if (!bios->fp.lvds_init_run) { - bios->fp.lvds_init_run = true; - call_lvds_script(dev, dcbent, head, LVDS_INIT, pxclk); - } - - if (script == LVDS_PANEL_ON && bios->fp.reset_after_pclk_change) - call_lvds_script(dev, dcbent, head, LVDS_RESET, pxclk); - if (script == LVDS_RESET && bios->fp.power_off_for_reset) - call_lvds_script(dev, dcbent, head, LVDS_PANEL_OFF, pxclk); - - NV_TRACE(dev, "Calling LVDS script %d:\n", script); - - /* don't let script change pll->head binding */ - sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000; - - if (lvds_ver < 0x30) - ret = call_lvds_manufacturer_script(dev, dcbent, head, script); - else - ret = run_lvds_table(dev, dcbent, head, script, pxclk); - - bios->fp.last_script_invoc = (script << 1 | head); - - sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000; - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding); - /* some scripts set a value in NV_PBUS_POWERCTRL_2 and break video overlay */ - nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0); - - return ret; -} - -struct lvdstableheader { - uint8_t lvds_ver, headerlen, recordlen; -}; - -static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct nvbios *bios, struct lvdstableheader *lth) -{ - /* - * BMP version (0xa) LVDS table has a simple header of version and - * record length. The BIT LVDS table has the typical BIT table header: - * version byte, header length byte, record length byte, and a byte for - * the maximum number of records that can be held in the table. - */ - - uint8_t lvds_ver, headerlen, recordlen; - - memset(lth, 0, sizeof(struct lvdstableheader)); - - if (bios->fp.lvdsmanufacturerpointer == 0x0) { - NV_ERROR(dev, "Pointer to LVDS manufacturer table invalid\n"); - return -EINVAL; - } - - lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; - - switch (lvds_ver) { - case 0x0a: /* pre NV40 */ - headerlen = 2; - recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1]; - break; - case 0x30: /* NV4x */ - headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1]; - if (headerlen < 0x1f) { - NV_ERROR(dev, "LVDS table header not understood\n"); - return -EINVAL; - } - recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2]; - break; - case 0x40: /* G80/G90 */ - headerlen = bios->data[bios->fp.lvdsmanufacturerpointer + 1]; - if (headerlen < 0x7) { - NV_ERROR(dev, "LVDS table header not understood\n"); - return -EINVAL; - } - recordlen = bios->data[bios->fp.lvdsmanufacturerpointer + 2]; - break; - default: - NV_ERROR(dev, - "LVDS table revision %d.%d not currently supported\n", - lvds_ver >> 4, lvds_ver & 0xf); - return -ENOSYS; - } - - lth->lvds_ver = lvds_ver; - lth->headerlen = headerlen; - lth->recordlen = recordlen; - - return 0; -} - -static int -get_fp_strap(struct drm_device *dev, struct nvbios *bios) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* - * The fp strap is normally dictated by the "User Strap" in - * PEXTDEV_BOOT_0[20:16], but on BMP cards when bit 2 of the - * Internal_Flags struct at 0x48 is set, the user strap gets overriden - * by the PCI subsystem ID during POST, but not before the previous user - * strap has been committed to CR58 for CR57=0xf on head A, which may be - * read and used instead - */ - - if (bios->major_version < 5 && bios->data[0x48] & 0x4) - return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf; - - if (dev_priv->card_type >= NV_50) - return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 24) & 0xf; - else - return (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 16) & 0xf; -} - -static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) -{ - uint8_t *fptable; - uint8_t fptable_ver, headerlen = 0, recordlen, fpentries = 0xf, fpindex; - int ret, ofs, fpstrapping; - struct lvdstableheader lth; - - if (bios->fp.fptablepointer == 0x0) { - /* Apple cards don't have the fp table; the laptops use DDC */ - /* The table is also missing on some x86 IGPs */ -#ifndef __powerpc__ - NV_ERROR(dev, "Pointer to flat panel table invalid\n"); -#endif - bios->digital_min_front_porch = 0x4b; - return 0; - } - - fptable = &bios->data[bios->fp.fptablepointer]; - fptable_ver = fptable[0]; - - switch (fptable_ver) { - /* - * BMP version 0x5.0x11 BIOSen have version 1 like tables, but no - * version field, and miss one of the spread spectrum/PWM bytes. - * This could affect early GF2Go parts (not seen any appropriate ROMs - * though). Here we assume that a version of 0x05 matches this case - * (combining with a BMP version check would be better), as the - * common case for the panel type field is 0x0005, and that is in - * fact what we are reading the first byte of. - */ - case 0x05: /* some NV10, 11, 15, 16 */ - recordlen = 42; - ofs = -1; - break; - case 0x10: /* some NV15/16, and NV11+ */ - recordlen = 44; - ofs = 0; - break; - case 0x20: /* NV40+ */ - headerlen = fptable[1]; - recordlen = fptable[2]; - fpentries = fptable[3]; - /* - * fptable[4] is the minimum - * RAMDAC_FP_HCRTC -> RAMDAC_FP_HSYNC_START gap - */ - bios->digital_min_front_porch = fptable[4]; - ofs = -7; - break; - default: - NV_ERROR(dev, - "FP table revision %d.%d not currently supported\n", - fptable_ver >> 4, fptable_ver & 0xf); - return -ENOSYS; - } - - if (!bios->is_mobile) /* !mobile only needs digital_min_front_porch */ - return 0; - - ret = parse_lvds_manufacturer_table_header(dev, bios, <h); - if (ret) - return ret; - - if (lth.lvds_ver == 0x30 || lth.lvds_ver == 0x40) { - bios->fp.fpxlatetableptr = bios->fp.lvdsmanufacturerpointer + - lth.headerlen + 1; - bios->fp.xlatwidth = lth.recordlen; - } - if (bios->fp.fpxlatetableptr == 0x0) { - NV_ERROR(dev, "Pointer to flat panel xlat table invalid\n"); - return -EINVAL; - } - - fpstrapping = get_fp_strap(dev, bios); - - fpindex = bios->data[bios->fp.fpxlatetableptr + - fpstrapping * bios->fp.xlatwidth]; - - if (fpindex > fpentries) { - NV_ERROR(dev, "Bad flat panel table index\n"); - return -ENOENT; - } - - /* nv4x cards need both a strap value and fpindex of 0xf to use DDC */ - if (lth.lvds_ver > 0x10) - bios->fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf; - - /* - * If either the strap or xlated fpindex value are 0xf there is no - * panel using a strap-derived bios mode present. this condition - * includes, but is different from, the DDC panel indicator above - */ - if (fpstrapping == 0xf || fpindex == 0xf) - return 0; - - bios->fp.mode_ptr = bios->fp.fptablepointer + headerlen + - recordlen * fpindex + ofs; - - NV_TRACE(dev, "BIOS FP mode: %dx%d (%dkHz pixel clock)\n", - ROM16(bios->data[bios->fp.mode_ptr + 11]) + 1, - ROM16(bios->data[bios->fp.mode_ptr + 25]) + 1, - ROM16(bios->data[bios->fp.mode_ptr + 7]) * 10); - - return 0; -} - -bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr]; - - if (!mode) /* just checking whether we can produce a mode */ - return bios->fp.mode_ptr; - - memset(mode, 0, sizeof(struct drm_display_mode)); - /* - * For version 1.0 (version in byte 0): - * bytes 1-2 are "panel type", including bits on whether Colour/mono, - * single/dual link, and type (TFT etc.) - * bytes 3-6 are bits per colour in RGBX - */ - mode->clock = ROM16(mode_entry[7]) * 10; - /* bytes 9-10 is HActive */ - mode->hdisplay = ROM16(mode_entry[11]) + 1; - /* - * bytes 13-14 is HValid Start - * bytes 15-16 is HValid End - */ - mode->hsync_start = ROM16(mode_entry[17]) + 1; - mode->hsync_end = ROM16(mode_entry[19]) + 1; - mode->htotal = ROM16(mode_entry[21]) + 1; - /* bytes 23-24, 27-30 similarly, but vertical */ - mode->vdisplay = ROM16(mode_entry[25]) + 1; - mode->vsync_start = ROM16(mode_entry[31]) + 1; - mode->vsync_end = ROM16(mode_entry[33]) + 1; - mode->vtotal = ROM16(mode_entry[35]) + 1; - mode->flags |= (mode_entry[37] & 0x10) ? - DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; - mode->flags |= (mode_entry[37] & 0x1) ? - DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; - /* - * bytes 38-39 relate to spread spectrum settings - * bytes 40-43 are something to do with PWM - */ - - mode->status = MODE_OK; - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_set_name(mode); - return bios->fp.mode_ptr; -} - -int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, bool *if_is_24bit) -{ - /* - * The LVDS table header is (mostly) described in - * parse_lvds_manufacturer_table_header(): the BIT header additionally - * contains the dual-link transition pxclk (in 10s kHz), at byte 5 - if - * straps are not being used for the panel, this specifies the frequency - * at which modes should be set up in the dual link style. - * - * Following the header, the BMP (ver 0xa) table has several records, - * indexed by a separate xlat table, indexed in turn by the fp strap in - * EXTDEV_BOOT. Each record had a config byte, followed by 6 script - * numbers for use by INIT_SUB which controlled panel init and power, - * and finally a dword of ms to sleep between power off and on - * operations. - * - * In the BIT versions, the table following the header serves as an - * integrated config and xlat table: the records in the table are - * indexed by the FP strap nibble in EXTDEV_BOOT, and each record has - * two bytes - the first as a config byte, the second for indexing the - * fp mode table pointed to by the BIT 'D' table - * - * DDC is not used until after card init, so selecting the correct table - * entry and setting the dual link flag for EDID equipped panels, - * requiring tests against the native-mode pixel clock, cannot be done - * until later, when this function should be called with non-zero pxclk - */ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0; - struct lvdstableheader lth; - uint16_t lvdsofs; - int ret, chip_version = bios->chip_version; - - ret = parse_lvds_manufacturer_table_header(dev, bios, <h); - if (ret) - return ret; - - switch (lth.lvds_ver) { - case 0x0a: /* pre NV40 */ - lvdsmanufacturerindex = bios->data[ - bios->fp.fpxlatemanufacturertableptr + - fpstrapping]; - - /* we're done if this isn't the EDID panel case */ - if (!pxclk) - break; - - if (chip_version < 0x25) { - /* nv17 behaviour - * - * It seems the old style lvds script pointer is reused - * to select 18/24 bit colour depth for EDID panels. - */ - lvdsmanufacturerindex = - (bios->legacy.lvds_single_a_script_ptr & 1) ? - 2 : 0; - if (pxclk >= bios->fp.duallink_transition_clk) - lvdsmanufacturerindex++; - } else if (chip_version < 0x30) { - /* nv28 behaviour (off-chip encoder) - * - * nv28 does a complex dance of first using byte 121 of - * the EDID to choose the lvdsmanufacturerindex, then - * later attempting to match the EDID manufacturer and - * product IDs in a table (signature 'pidt' (panel id - * table?)), setting an lvdsmanufacturerindex of 0 and - * an fp strap of the match index (or 0xf if none) - */ - lvdsmanufacturerindex = 0; - } else { - /* nv31, nv34 behaviour */ - lvdsmanufacturerindex = 0; - if (pxclk >= bios->fp.duallink_transition_clk) - lvdsmanufacturerindex = 2; - if (pxclk >= 140000) - lvdsmanufacturerindex = 3; - } - - /* - * nvidia set the high nibble of (cr57=f, cr58) to - * lvdsmanufacturerindex in this case; we don't - */ - break; - case 0x30: /* NV4x */ - case 0x40: /* G80/G90 */ - lvdsmanufacturerindex = fpstrapping; - break; - default: - NV_ERROR(dev, "LVDS table revision not currently supported\n"); - return -ENOSYS; - } - - lvdsofs = bios->fp.xlated_entry = bios->fp.lvdsmanufacturerpointer + lth.headerlen + lth.recordlen * lvdsmanufacturerindex; - switch (lth.lvds_ver) { - case 0x0a: - bios->fp.power_off_for_reset = bios->data[lvdsofs] & 1; - bios->fp.reset_after_pclk_change = bios->data[lvdsofs] & 2; - bios->fp.dual_link = bios->data[lvdsofs] & 4; - bios->fp.link_c_increment = bios->data[lvdsofs] & 8; - *if_is_24bit = bios->data[lvdsofs] & 16; - break; - case 0x30: - case 0x40: - /* - * No sign of the "power off for reset" or "reset for panel - * on" bits, but it's safer to assume we should - */ - bios->fp.power_off_for_reset = true; - bios->fp.reset_after_pclk_change = true; - - /* - * It's ok lvdsofs is wrong for nv4x edid case; dual_link is - * over-written, and if_is_24bit isn't used - */ - bios->fp.dual_link = bios->data[lvdsofs] & 1; - bios->fp.if_is_24bit = bios->data[lvdsofs] & 2; - bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; - bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; - break; - } - - /* set dual_link flag for EDID case */ - if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) - bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk); - - *dl = bios->fp.dual_link; - - return 0; -} - -/* BIT 'U'/'d' table encoder subtables have hashes matching them to - * a particular set of encoders. - * - * This function returns true if a particular DCB entry matches. - */ -bool -bios_encoder_match(struct dcb_entry *dcb, u32 hash) -{ - if ((hash & 0x000000f0) != (dcb->location << 4)) - return false; - if ((hash & 0x0000000f) != dcb->type) - return false; - if (!(hash & (dcb->or << 16))) - return false; - - switch (dcb->type) { - case OUTPUT_TMDS: - case OUTPUT_LVDS: - case OUTPUT_DP: - if (hash & 0x00c00000) { - if (!(hash & (dcb->sorconf.link << 22))) - return false; - } - default: - return true; - } -} - -int -nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, - struct dcb_entry *dcbent, int crtc) -{ - /* - * The display script table is located by the BIT 'U' table. - * - * It contains an array of pointers to various tables describing - * a particular output type. The first 32-bits of the output - * tables contains similar information to a DCB entry, and is - * used to decide whether that particular table is suitable for - * the output you want to access. - * - * The "record header length" field here seems to indicate the - * offset of the first configuration entry in the output tables. - * This is 10 on most cards I've seen, but 12 has been witnessed - * on DP cards, and there's another script pointer within the - * header. - * - * offset + 0 ( 8 bits): version - * offset + 1 ( 8 bits): header length - * offset + 2 ( 8 bits): record length - * offset + 3 ( 8 bits): number of records - * offset + 4 ( 8 bits): record header length - * offset + 5 (16 bits): pointer to first output script table - */ - - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - uint8_t *table = &bios->data[bios->display.script_table_ptr]; - uint8_t *otable = NULL; - uint16_t script; - int i; - - if (!bios->display.script_table_ptr) { - NV_ERROR(dev, "No pointer to output script table\n"); - return 1; - } - - /* - * Nothing useful has been in any of the pre-2.0 tables I've seen, - * so until they are, we really don't need to care. - */ - if (table[0] < 0x20) - return 1; - - if (table[0] != 0x20 && table[0] != 0x21) { - NV_ERROR(dev, "Output script table version 0x%02x unknown\n", - table[0]); - return 1; - } - - /* - * The output script tables describing a particular output type - * look as follows: - * - * offset + 0 (32 bits): output this table matches (hash of DCB) - * offset + 4 ( 8 bits): unknown - * offset + 5 ( 8 bits): number of configurations - * offset + 6 (16 bits): pointer to some script - * offset + 8 (16 bits): pointer to some script - * - * headerlen == 10 - * offset + 10 : configuration 0 - * - * headerlen == 12 - * offset + 10 : pointer to some script - * offset + 12 : configuration 0 - * - * Each config entry is as follows: - * - * offset + 0 (16 bits): unknown, assumed to be a match value - * offset + 2 (16 bits): pointer to script table (clock set?) - * offset + 4 (16 bits): pointer to script table (reset?) - * - * There doesn't appear to be a count value to say how many - * entries exist in each script table, instead, a 0 value in - * the first 16-bit word seems to indicate both the end of the - * list and the default entry. The second 16-bit word in the - * script tables is a pointer to the script to execute. - */ - - NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", - dcbent->type, dcbent->location, dcbent->or); - for (i = 0; i < table[3]; i++) { - otable = ROMPTR(dev, table[table[1] + (i * table[2])]); - if (otable && bios_encoder_match(dcbent, ROM32(otable[0]))) - break; - } - - if (!otable) { - NV_DEBUG_KMS(dev, "failed to match any output table\n"); - return 1; - } - - if (pclk < -2 || pclk > 0) { - /* Try to find matching script table entry */ - for (i = 0; i < otable[5]; i++) { - if (ROM16(otable[table[4] + i*6]) == type) - break; - } - - if (i == otable[5]) { - NV_ERROR(dev, "Table 0x%04x not found for %d/%d, " - "using first\n", - type, dcbent->type, dcbent->or); - i = 0; - } - } - - if (pclk == 0) { - script = ROM16(otable[6]); - if (!script) { - NV_DEBUG_KMS(dev, "output script 0 not found\n"); - return 1; - } - - NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); - nouveau_bios_run_init_table(dev, script, dcbent, crtc); - } else - if (pclk == -1) { - script = ROM16(otable[8]); - if (!script) { - NV_DEBUG_KMS(dev, "output script 1 not found\n"); - return 1; - } - - NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); - nouveau_bios_run_init_table(dev, script, dcbent, crtc); - } else - if (pclk == -2) { - if (table[4] >= 12) - script = ROM16(otable[10]); - else - script = 0; - if (!script) { - NV_DEBUG_KMS(dev, "output script 2 not found\n"); - return 1; - } - - NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); - nouveau_bios_run_init_table(dev, script, dcbent, crtc); - } else - if (pclk > 0) { - script = ROM16(otable[table[4] + i*6 + 2]); - if (script) - script = clkcmptable(bios, script, pclk); - if (!script) { - NV_DEBUG_KMS(dev, "clock script 0 not found\n"); - return 1; - } - - NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); - nouveau_bios_run_init_table(dev, script, dcbent, crtc); - } else - if (pclk < 0) { - script = ROM16(otable[table[4] + i*6 + 4]); - if (script) - script = clkcmptable(bios, script, -pclk); - if (!script) { - NV_DEBUG_KMS(dev, "clock script 1 not found\n"); - return 1; - } - - NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); - nouveau_bios_run_init_table(dev, script, dcbent, crtc); - } - - return 0; -} - - -int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, int pxclk) -{ - /* - * the pxclk parameter is in kHz - * - * This runs the TMDS regs setting code found on BIT bios cards - * - * For ffs(or) == 1 use the first table, for ffs(or) == 2 and - * ffs(or) == 3, use the second. - */ - - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - int cv = bios->chip_version; - uint16_t clktable = 0, scriptptr; - uint32_t sel_clk_binding, sel_clk; - - /* pre-nv17 off-chip tmds uses scripts, post nv17 doesn't */ - if (cv >= 0x17 && cv != 0x1a && cv != 0x20 && - dcbent->location != DCB_LOC_ON_CHIP) - return 0; - - switch (ffs(dcbent->or)) { - case 1: - clktable = bios->tmds.output0_script_ptr; - break; - case 2: - case 3: - clktable = bios->tmds.output1_script_ptr; - break; - } - - if (!clktable) { - NV_ERROR(dev, "Pixel clock comparison table not found\n"); - return -EINVAL; - } - - scriptptr = clkcmptable(bios, clktable, pxclk); - - if (!scriptptr) { - NV_ERROR(dev, "TMDS output init script not found\n"); - return -ENOENT; - } - - /* don't let script change pll->head binding */ - sel_clk_binding = bios_rd32(bios, NV_PRAMDAC_SEL_CLK) & 0x50000; - run_digital_op_script(dev, scriptptr, dcbent, head, pxclk >= 165000); - sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK) & ~0x50000; - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, sel_clk | sel_clk_binding); - - return 0; -} - -struct pll_mapping { - u8 type; - u32 reg; -}; - -static struct pll_mapping nv04_pll_mapping[] = { - { PLL_CORE , NV_PRAMDAC_NVPLL_COEFF }, - { PLL_MEMORY, NV_PRAMDAC_MPLL_COEFF }, - { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF }, - { PLL_VPLL1 , NV_RAMDAC_VPLL2 }, - {} -}; - -static struct pll_mapping nv40_pll_mapping[] = { - { PLL_CORE , 0x004000 }, - { PLL_MEMORY, 0x004020 }, - { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF }, - { PLL_VPLL1 , NV_RAMDAC_VPLL2 }, - {} -}; - -static struct pll_mapping nv50_pll_mapping[] = { - { PLL_CORE , 0x004028 }, - { PLL_SHADER, 0x004020 }, - { PLL_UNK03 , 0x004000 }, - { PLL_MEMORY, 0x004008 }, - { PLL_UNK40 , 0x00e810 }, - { PLL_UNK41 , 0x00e818 }, - { PLL_UNK42 , 0x00e824 }, - { PLL_VPLL0 , 0x614100 }, - { PLL_VPLL1 , 0x614900 }, - {} -}; - -static struct pll_mapping nv84_pll_mapping[] = { - { PLL_CORE , 0x004028 }, - { PLL_SHADER, 0x004020 }, - { PLL_MEMORY, 0x004008 }, - { PLL_VDEC , 0x004030 }, - { PLL_UNK41 , 0x00e818 }, - { PLL_VPLL0 , 0x614100 }, - { PLL_VPLL1 , 0x614900 }, - {} -}; - -u32 -get_pll_register(struct drm_device *dev, enum pll_types type) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct pll_mapping *map; - int i; - - if (dev_priv->card_type < NV_40) - map = nv04_pll_mapping; - else - if (dev_priv->card_type < NV_50) - map = nv40_pll_mapping; - else { - u8 *plim = &bios->data[bios->pll_limit_tbl_ptr]; - - if (plim[0] >= 0x30) { - u8 *entry = plim + plim[1]; - for (i = 0; i < plim[3]; i++, entry += plim[2]) { - if (entry[0] == type) - return ROM32(entry[3]); - } - - return 0; - } - - if (dev_priv->chipset == 0x50) - map = nv50_pll_mapping; - else - map = nv84_pll_mapping; - } - - while (map->reg) { - if (map->type == type) - return map->reg; - map++; - } - - return 0; -} - -int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim) -{ - /* - * PLL limits table - * - * Version 0x10: NV30, NV31 - * One byte header (version), one record of 24 bytes - * Version 0x11: NV36 - Not implemented - * Seems to have same record style as 0x10, but 3 records rather than 1 - * Version 0x20: Found on Geforce 6 cards - * Trivial 4 byte BIT header. 31 (0x1f) byte record length - * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards - * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record - * length in general, some (integrated) have an extra configuration byte - * Version 0x30: Found on Geforce 8, separates the register mapping - * from the limits tables. - */ - - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - int cv = bios->chip_version, pllindex = 0; - uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0; - uint32_t crystal_strap_mask, crystal_straps; - - if (!bios->pll_limit_tbl_ptr) { - if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || - cv >= 0x40) { - NV_ERROR(dev, "Pointer to PLL limits table invalid\n"); - return -EINVAL; - } - } else - pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr]; - - crystal_strap_mask = 1 << 6; - /* open coded dev->twoHeads test */ - if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20) - crystal_strap_mask |= 1 << 22; - crystal_straps = nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & - crystal_strap_mask; - - switch (pll_lim_ver) { - /* - * We use version 0 to indicate a pre limit table bios (single stage - * pll) and load the hard coded limits instead. - */ - case 0: - break; - case 0x10: - case 0x11: - /* - * Strictly v0x11 has 3 entries, but the last two don't seem - * to get used. - */ - headerlen = 1; - recordlen = 0x18; - entries = 1; - pllindex = 0; - break; - case 0x20: - case 0x21: - case 0x30: - case 0x40: - headerlen = bios->data[bios->pll_limit_tbl_ptr + 1]; - recordlen = bios->data[bios->pll_limit_tbl_ptr + 2]; - entries = bios->data[bios->pll_limit_tbl_ptr + 3]; - break; - default: - NV_ERROR(dev, "PLL limits table revision 0x%X not currently " - "supported\n", pll_lim_ver); - return -ENOSYS; - } - - /* initialize all members to zero */ - memset(pll_lim, 0, sizeof(struct pll_lims)); - - /* if we were passed a type rather than a register, figure - * out the register and store it - */ - if (limit_match > PLL_MAX) - pll_lim->reg = limit_match; - else { - pll_lim->reg = get_pll_register(dev, limit_match); - if (!pll_lim->reg) - return -ENOENT; - } - - if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) { - uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex]; - - pll_lim->vco1.minfreq = ROM32(pll_rec[0]); - pll_lim->vco1.maxfreq = ROM32(pll_rec[4]); - pll_lim->vco2.minfreq = ROM32(pll_rec[8]); - pll_lim->vco2.maxfreq = ROM32(pll_rec[12]); - pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]); - pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]); - pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX; - - /* these values taken from nv30/31/36 */ - pll_lim->vco1.min_n = 0x1; - if (cv == 0x36) - pll_lim->vco1.min_n = 0x5; - pll_lim->vco1.max_n = 0xff; - pll_lim->vco1.min_m = 0x1; - pll_lim->vco1.max_m = 0xd; - pll_lim->vco2.min_n = 0x4; - /* - * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this - * table version (apart from nv35)), N2 is compared to - * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and - * save a comparison - */ - pll_lim->vco2.max_n = 0x28; - if (cv == 0x30 || cv == 0x35) - /* only 5 bits available for N2 on nv30/35 */ - pll_lim->vco2.max_n = 0x1f; - pll_lim->vco2.min_m = 0x1; - pll_lim->vco2.max_m = 0x4; - pll_lim->max_log2p = 0x7; - pll_lim->max_usable_log2p = 0x6; - } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) { - uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen; - uint8_t *pll_rec; - int i; - - /* - * First entry is default match, if nothing better. warn if - * reg field nonzero - */ - if (ROM32(bios->data[plloffs])) - NV_WARN(dev, "Default PLL limit entry has non-zero " - "register field\n"); - - for (i = 1; i < entries; i++) - if (ROM32(bios->data[plloffs + recordlen * i]) == pll_lim->reg) { - pllindex = i; - break; - } - - if ((dev_priv->card_type >= NV_50) && (pllindex == 0)) { - NV_ERROR(dev, "Register 0x%08x not found in PLL " - "limits table", pll_lim->reg); - return -ENOENT; - } - - pll_rec = &bios->data[plloffs + recordlen * pllindex]; - - BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n", - pllindex ? pll_lim->reg : 0); - - /* - * Frequencies are stored in tables in MHz, kHz are more - * useful, so we convert. - */ - - /* What output frequencies can each VCO generate? */ - pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000; - pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000; - pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000; - pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000; - - /* What input frequencies they accept (past the m-divider)? */ - pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000; - pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000; - pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000; - pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000; - - /* What values are accepted as multiplier and divider? */ - pll_lim->vco1.min_n = pll_rec[20]; - pll_lim->vco1.max_n = pll_rec[21]; - pll_lim->vco1.min_m = pll_rec[22]; - pll_lim->vco1.max_m = pll_rec[23]; - pll_lim->vco2.min_n = pll_rec[24]; - pll_lim->vco2.max_n = pll_rec[25]; - pll_lim->vco2.min_m = pll_rec[26]; - pll_lim->vco2.max_m = pll_rec[27]; - - pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29]; - if (pll_lim->max_log2p > 0x7) - /* pll decoding in nv_hw.c assumes never > 7 */ - NV_WARN(dev, "Max log2 P value greater than 7 (%d)\n", - pll_lim->max_log2p); - if (cv < 0x60) - pll_lim->max_usable_log2p = 0x6; - pll_lim->log2p_bias = pll_rec[30]; - - if (recordlen > 0x22) - pll_lim->refclk = ROM32(pll_rec[31]); - - if (recordlen > 0x23 && pll_rec[35]) - NV_WARN(dev, - "Bits set in PLL configuration byte (%x)\n", - pll_rec[35]); - - /* C51 special not seen elsewhere */ - if (cv == 0x51 && !pll_lim->refclk) { - uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK); - - if ((pll_lim->reg == NV_PRAMDAC_VPLL_COEFF && sel_clk & 0x20) || - (pll_lim->reg == NV_RAMDAC_VPLL2 && sel_clk & 0x80)) { - if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3) - pll_lim->refclk = 200000; - else - pll_lim->refclk = 25000; - } - } - } else if (pll_lim_ver == 0x30) { /* ver 0x30 */ - uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen]; - uint8_t *record = NULL; - int i; - - BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n", - pll_lim->reg); - - for (i = 0; i < entries; i++, entry += recordlen) { - if (ROM32(entry[3]) == pll_lim->reg) { - record = &bios->data[ROM16(entry[1])]; - break; - } - } - - if (!record) { - NV_ERROR(dev, "Register 0x%08x not found in PLL " - "limits table", pll_lim->reg); - return -ENOENT; - } - - pll_lim->vco1.minfreq = ROM16(record[0]) * 1000; - pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000; - pll_lim->vco2.minfreq = ROM16(record[4]) * 1000; - pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000; - pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000; - pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000; - pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000; - pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000; - pll_lim->vco1.min_n = record[16]; - pll_lim->vco1.max_n = record[17]; - pll_lim->vco1.min_m = record[18]; - pll_lim->vco1.max_m = record[19]; - pll_lim->vco2.min_n = record[20]; - pll_lim->vco2.max_n = record[21]; - pll_lim->vco2.min_m = record[22]; - pll_lim->vco2.max_m = record[23]; - pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25]; - pll_lim->log2p_bias = record[27]; - pll_lim->refclk = ROM32(record[28]); - } else if (pll_lim_ver) { /* ver 0x40 */ - uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen]; - uint8_t *record = NULL; - int i; - - BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n", - pll_lim->reg); - - for (i = 0; i < entries; i++, entry += recordlen) { - if (ROM32(entry[3]) == pll_lim->reg) { - record = &bios->data[ROM16(entry[1])]; - break; - } - } - - if (!record) { - NV_ERROR(dev, "Register 0x%08x not found in PLL " - "limits table", pll_lim->reg); - return -ENOENT; - } - - pll_lim->vco1.minfreq = ROM16(record[0]) * 1000; - pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000; - pll_lim->vco1.min_inputfreq = ROM16(record[4]) * 1000; - pll_lim->vco1.max_inputfreq = ROM16(record[6]) * 1000; - pll_lim->vco1.min_m = record[8]; - pll_lim->vco1.max_m = record[9]; - pll_lim->vco1.min_n = record[10]; - pll_lim->vco1.max_n = record[11]; - pll_lim->min_p = record[12]; - pll_lim->max_p = record[13]; - pll_lim->refclk = ROM16(entry[9]) * 1000; - } - - /* - * By now any valid limit table ought to have set a max frequency for - * vco1, so if it's zero it's either a pre limit table bios, or one - * with an empty limit table (seen on nv18) - */ - if (!pll_lim->vco1.maxfreq) { - pll_lim->vco1.minfreq = bios->fminvco; - pll_lim->vco1.maxfreq = bios->fmaxvco; - pll_lim->vco1.min_inputfreq = 0; - pll_lim->vco1.max_inputfreq = INT_MAX; - pll_lim->vco1.min_n = 0x1; - pll_lim->vco1.max_n = 0xff; - pll_lim->vco1.min_m = 0x1; - if (crystal_straps == 0) { - /* nv05 does this, nv11 doesn't, nv10 unknown */ - if (cv < 0x11) - pll_lim->vco1.min_m = 0x7; - pll_lim->vco1.max_m = 0xd; - } else { - if (cv < 0x11) - pll_lim->vco1.min_m = 0x8; - pll_lim->vco1.max_m = 0xe; - } - if (cv < 0x17 || cv == 0x1a || cv == 0x20) - pll_lim->max_log2p = 4; - else - pll_lim->max_log2p = 5; - pll_lim->max_usable_log2p = pll_lim->max_log2p; - } - - if (!pll_lim->refclk) - switch (crystal_straps) { - case 0: - pll_lim->refclk = 13500; - break; - case (1 << 6): - pll_lim->refclk = 14318; - break; - case (1 << 22): - pll_lim->refclk = 27000; - break; - case (1 << 22 | 1 << 6): - pll_lim->refclk = 25000; - break; - } - - NV_DEBUG(dev, "pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq); - NV_DEBUG(dev, "pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq); - NV_DEBUG(dev, "pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq); - NV_DEBUG(dev, "pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq); - NV_DEBUG(dev, "pll.vco1.min_n: %d\n", pll_lim->vco1.min_n); - NV_DEBUG(dev, "pll.vco1.max_n: %d\n", pll_lim->vco1.max_n); - NV_DEBUG(dev, "pll.vco1.min_m: %d\n", pll_lim->vco1.min_m); - NV_DEBUG(dev, "pll.vco1.max_m: %d\n", pll_lim->vco1.max_m); - if (pll_lim->vco2.maxfreq) { - NV_DEBUG(dev, "pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq); - NV_DEBUG(dev, "pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq); - NV_DEBUG(dev, "pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq); - NV_DEBUG(dev, "pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq); - NV_DEBUG(dev, "pll.vco2.min_n: %d\n", pll_lim->vco2.min_n); - NV_DEBUG(dev, "pll.vco2.max_n: %d\n", pll_lim->vco2.max_n); - NV_DEBUG(dev, "pll.vco2.min_m: %d\n", pll_lim->vco2.min_m); - NV_DEBUG(dev, "pll.vco2.max_m: %d\n", pll_lim->vco2.max_m); - } - if (!pll_lim->max_p) { - NV_DEBUG(dev, "pll.max_log2p: %d\n", pll_lim->max_log2p); - NV_DEBUG(dev, "pll.log2p_bias: %d\n", pll_lim->log2p_bias); - } else { - NV_DEBUG(dev, "pll.min_p: %d\n", pll_lim->min_p); - NV_DEBUG(dev, "pll.max_p: %d\n", pll_lim->max_p); - } - NV_DEBUG(dev, "pll.refclk: %d\n", pll_lim->refclk); - - return 0; -} - -static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset) -{ - /* - * offset + 0 (8 bits): Micro version - * offset + 1 (8 bits): Minor version - * offset + 2 (8 bits): Chip version - * offset + 3 (8 bits): Major version - */ - - bios->major_version = bios->data[offset + 3]; - bios->chip_version = bios->data[offset + 2]; - NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n", - bios->data[offset + 3], bios->data[offset + 2], - bios->data[offset + 1], bios->data[offset]); -} - -static void parse_script_table_pointers(struct nvbios *bios, uint16_t offset) -{ - /* - * Parses the init table segment for pointers used in script execution. - * - * offset + 0 (16 bits): init script tables pointer - * offset + 2 (16 bits): macro index table pointer - * offset + 4 (16 bits): macro table pointer - * offset + 6 (16 bits): condition table pointer - * offset + 8 (16 bits): io condition table pointer - * offset + 10 (16 bits): io flag condition table pointer - * offset + 12 (16 bits): init function table pointer - */ - - bios->init_script_tbls_ptr = ROM16(bios->data[offset]); - bios->macro_index_tbl_ptr = ROM16(bios->data[offset + 2]); - bios->macro_tbl_ptr = ROM16(bios->data[offset + 4]); - bios->condition_tbl_ptr = ROM16(bios->data[offset + 6]); - bios->io_condition_tbl_ptr = ROM16(bios->data[offset + 8]); - bios->io_flag_condition_tbl_ptr = ROM16(bios->data[offset + 10]); - bios->init_function_tbl_ptr = ROM16(bios->data[offset + 12]); -} - -static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * Parses the load detect values for g80 cards. - * - * offset + 0 (16 bits): loadval table pointer - */ - - uint16_t load_table_ptr; - uint8_t version, headerlen, entrylen, num_entries; - - if (bitentry->length != 3) { - NV_ERROR(dev, "Do not understand BIT A table\n"); - return -EINVAL; - } - - load_table_ptr = ROM16(bios->data[bitentry->offset]); - - if (load_table_ptr == 0x0) { - NV_DEBUG(dev, "Pointer to BIT loadval table invalid\n"); - return -EINVAL; - } - - version = bios->data[load_table_ptr]; - - if (version != 0x10) { - NV_ERROR(dev, "BIT loadval table version %d.%d not supported\n", - version >> 4, version & 0xF); - return -ENOSYS; - } - - headerlen = bios->data[load_table_ptr + 1]; - entrylen = bios->data[load_table_ptr + 2]; - num_entries = bios->data[load_table_ptr + 3]; - - if (headerlen != 4 || entrylen != 4 || num_entries != 2) { - NV_ERROR(dev, "Do not understand BIT loadval table\n"); - return -EINVAL; - } - - /* First entry is normal dac, 2nd tv-out perhaps? */ - bios->dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff; - - return 0; -} - -static int parse_bit_C_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * offset + 8 (16 bits): PLL limits table pointer - * - * There's more in here, but that's unknown. - */ - - if (bitentry->length < 10) { - NV_ERROR(dev, "Do not understand BIT C table\n"); - return -EINVAL; - } - - bios->pll_limit_tbl_ptr = ROM16(bios->data[bitentry->offset + 8]); - - return 0; -} - -static int parse_bit_display_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * Parses the flat panel table segment that the bit entry points to. - * Starting at bitentry->offset: - * - * offset + 0 (16 bits): ??? table pointer - seems to have 18 byte - * records beginning with a freq. - * offset + 2 (16 bits): mode table pointer - */ - - if (bitentry->length != 4) { - NV_ERROR(dev, "Do not understand BIT display table\n"); - return -EINVAL; - } - - bios->fp.fptablepointer = ROM16(bios->data[bitentry->offset + 2]); - - return 0; -} - -static int parse_bit_init_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * Parses the init table segment that the bit entry points to. - * - * See parse_script_table_pointers for layout - */ - - if (bitentry->length < 14) { - NV_ERROR(dev, "Do not understand init table\n"); - return -EINVAL; - } - - parse_script_table_pointers(bios, bitentry->offset); - - if (bitentry->length >= 16) - bios->some_script_ptr = ROM16(bios->data[bitentry->offset + 14]); - if (bitentry->length >= 18) - bios->init96_tbl_ptr = ROM16(bios->data[bitentry->offset + 16]); - - return 0; -} - -static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * BIT 'i' (info?) table - * - * offset + 0 (32 bits): BIOS version dword (as in B table) - * offset + 5 (8 bits): BIOS feature byte (same as for BMP?) - * offset + 13 (16 bits): pointer to table containing DAC load - * detection comparison values - * - * There's other things in the table, purpose unknown - */ - - uint16_t daccmpoffset; - uint8_t dacver, dacheaderlen; - - if (bitentry->length < 6) { - NV_ERROR(dev, "BIT i table too short for needed information\n"); - return -EINVAL; - } - - parse_bios_version(dev, bios, bitentry->offset); - - /* - * bit 4 seems to indicate a mobile bios (doesn't suffer from BMP's - * Quadro identity crisis), other bits possibly as for BMP feature byte - */ - bios->feature_byte = bios->data[bitentry->offset + 5]; - bios->is_mobile = bios->feature_byte & FEATURE_MOBILE; - - if (bitentry->length < 15) { - NV_WARN(dev, "BIT i table not long enough for DAC load " - "detection comparison table\n"); - return -EINVAL; - } - - daccmpoffset = ROM16(bios->data[bitentry->offset + 13]); - - /* doesn't exist on g80 */ - if (!daccmpoffset) - return 0; - - /* - * The first value in the table, following the header, is the - * comparison value, the second entry is a comparison value for - * TV load detection. - */ - - dacver = bios->data[daccmpoffset]; - dacheaderlen = bios->data[daccmpoffset + 1]; - - if (dacver != 0x00 && dacver != 0x10) { - NV_WARN(dev, "DAC load detection comparison table version " - "%d.%d not known\n", dacver >> 4, dacver & 0xf); - return -ENOSYS; - } - - bios->dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]); - bios->tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]); - - return 0; -} - -static int parse_bit_lvds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * Parses the LVDS table segment that the bit entry points to. - * Starting at bitentry->offset: - * - * offset + 0 (16 bits): LVDS strap xlate table pointer - */ - - if (bitentry->length != 2) { - NV_ERROR(dev, "Do not understand BIT LVDS table\n"); - return -EINVAL; - } - - /* - * No idea if it's still called the LVDS manufacturer table, but - * the concept's close enough. - */ - bios->fp.lvdsmanufacturerpointer = ROM16(bios->data[bitentry->offset]); - - return 0; -} - -static int -parse_bit_M_tbl_entry(struct drm_device *dev, struct nvbios *bios, - struct bit_entry *bitentry) -{ - /* - * offset + 2 (8 bits): number of options in an - * INIT_RAM_RESTRICT_ZM_REG_GROUP opcode option set - * offset + 3 (16 bits): pointer to strap xlate table for RAM - * restrict option selection - * - * There's a bunch of bits in this table other than the RAM restrict - * stuff that we don't use - their use currently unknown - */ - - /* - * Older bios versions don't have a sufficiently long table for - * what we want - */ - if (bitentry->length < 0x5) - return 0; - - if (bitentry->version < 2) { - bios->ram_restrict_group_count = bios->data[bitentry->offset + 2]; - bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 3]); - } else { - bios->ram_restrict_group_count = bios->data[bitentry->offset + 0]; - bios->ram_restrict_tbl_ptr = ROM16(bios->data[bitentry->offset + 1]); - } - - return 0; -} - -static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, struct bit_entry *bitentry) -{ - /* - * Parses the pointer to the TMDS table - * - * Starting at bitentry->offset: - * - * offset + 0 (16 bits): TMDS table pointer - * - * The TMDS table is typically found just before the DCB table, with a - * characteristic signature of 0x11,0x13 (1.1 being version, 0x13 being - * length?) - * - * At offset +7 is a pointer to a script, which I don't know how to - * run yet. - * At offset +9 is a pointer to another script, likewise - * Offset +11 has a pointer to a table where the first word is a pxclk - * frequency and the second word a pointer to a script, which should be - * run if the comparison pxclk frequency is less than the pxclk desired. - * This repeats for decreasing comparison frequencies - * Offset +13 has a pointer to a similar table - * The selection of table (and possibly +7/+9 script) is dictated by - * "or" from the DCB. - */ - - uint16_t tmdstableptr, script1, script2; - - if (bitentry->length != 2) { - NV_ERROR(dev, "Do not understand BIT TMDS table\n"); - return -EINVAL; - } - - tmdstableptr = ROM16(bios->data[bitentry->offset]); - if (!tmdstableptr) { - NV_ERROR(dev, "Pointer to TMDS table invalid\n"); - return -EINVAL; - } - - NV_INFO(dev, "TMDS table version %d.%d\n", - bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); - - /* nv50+ has v2.0, but we don't parse it atm */ - if (bios->data[tmdstableptr] != 0x11) - return -ENOSYS; - - /* - * These two scripts are odd: they don't seem to get run even when - * they are not stubbed. - */ - script1 = ROM16(bios->data[tmdstableptr + 7]); - script2 = ROM16(bios->data[tmdstableptr + 9]); - if (bios->data[script1] != 'q' || bios->data[script2] != 'q') - NV_WARN(dev, "TMDS table script pointers not stubbed\n"); - - bios->tmds.output0_script_ptr = ROM16(bios->data[tmdstableptr + 11]); - bios->tmds.output1_script_ptr = ROM16(bios->data[tmdstableptr + 13]); - - return 0; -} - -static int -parse_bit_U_tbl_entry(struct drm_device *dev, struct nvbios *bios, - struct bit_entry *bitentry) -{ - /* - * Parses the pointer to the G80 output script tables - * - * Starting at bitentry->offset: - * - * offset + 0 (16 bits): output script table pointer - */ - - uint16_t outputscripttableptr; - - if (bitentry->length != 3) { - NV_ERROR(dev, "Do not understand BIT U table\n"); - return -EINVAL; - } - - outputscripttableptr = ROM16(bios->data[bitentry->offset]); - bios->display.script_table_ptr = outputscripttableptr; - return 0; -} - -struct bit_table { - const char id; - int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *); -}; - -#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry }) - -int -bit_table(struct drm_device *dev, u8 id, struct bit_entry *bit) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - u8 entries, *entry; - - if (bios->type != NVBIOS_BIT) - return -ENODEV; - - entries = bios->data[bios->offset + 10]; - entry = &bios->data[bios->offset + 12]; - while (entries--) { - if (entry[0] == id) { - bit->id = entry[0]; - bit->version = entry[1]; - bit->length = ROM16(entry[2]); - bit->offset = ROM16(entry[4]); - bit->data = ROMPTR(dev, entry[4]); - return 0; - } - - entry += bios->data[bios->offset + 9]; - } - - return -ENOENT; -} - -static int -parse_bit_table(struct nvbios *bios, const uint16_t bitoffset, - struct bit_table *table) -{ - struct drm_device *dev = bios->dev; - struct bit_entry bitentry; - - if (bit_table(dev, table->id, &bitentry) == 0) - return table->parse_fn(dev, bios, &bitentry); - - NV_INFO(dev, "BIT table '%c' not found\n", table->id); - return -ENOSYS; -} - -static int -parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset) -{ - int ret; - - /* - * The only restriction on parsing order currently is having 'i' first - * for use of bios->*_version or bios->feature_byte while parsing; - * functions shouldn't be actually *doing* anything apart from pulling - * data from the image into the bios struct, thus no interdependencies - */ - ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('i', i)); - if (ret) /* info? */ - return ret; - if (bios->major_version >= 0x60) /* g80+ */ - parse_bit_table(bios, bitoffset, &BIT_TABLE('A', A)); - ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('C', C)); - if (ret) - return ret; - parse_bit_table(bios, bitoffset, &BIT_TABLE('D', display)); - ret = parse_bit_table(bios, bitoffset, &BIT_TABLE('I', init)); - if (ret) - return ret; - parse_bit_table(bios, bitoffset, &BIT_TABLE('M', M)); /* memory? */ - parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds)); - parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds)); - parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U)); - - return 0; -} - -static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsigned int offset) -{ - /* - * Parses the BMP structure for useful things, but does not act on them - * - * offset + 5: BMP major version - * offset + 6: BMP minor version - * offset + 9: BMP feature byte - * offset + 10: BCD encoded BIOS version - * - * offset + 18: init script table pointer (for bios versions < 5.10h) - * offset + 20: extra init script table pointer (for bios - * versions < 5.10h) - * - * offset + 24: memory init table pointer (used on early bios versions) - * offset + 26: SDR memory sequencing setup data table - * offset + 28: DDR memory sequencing setup data table - * - * offset + 54: index of I2C CRTC pair to use for CRT output - * offset + 55: index of I2C CRTC pair to use for TV output - * offset + 56: index of I2C CRTC pair to use for flat panel output - * offset + 58: write CRTC index for I2C pair 0 - * offset + 59: read CRTC index for I2C pair 0 - * offset + 60: write CRTC index for I2C pair 1 - * offset + 61: read CRTC index for I2C pair 1 - * - * offset + 67: maximum internal PLL frequency (single stage PLL) - * offset + 71: minimum internal PLL frequency (single stage PLL) - * - * offset + 75: script table pointers, as described in - * parse_script_table_pointers - * - * offset + 89: TMDS single link output A table pointer - * offset + 91: TMDS single link output B table pointer - * offset + 95: LVDS single link output A table pointer - * offset + 105: flat panel timings table pointer - * offset + 107: flat panel strapping translation table pointer - * offset + 117: LVDS manufacturer panel config table pointer - * offset + 119: LVDS manufacturer strapping translation table pointer - * - * offset + 142: PLL limits table pointer - * - * offset + 156: minimum pixel clock for LVDS dual link - */ - - uint8_t *bmp = &bios->data[offset], bmp_version_major, bmp_version_minor; - uint16_t bmplength; - uint16_t legacy_scripts_offset, legacy_i2c_offset; - - /* load needed defaults in case we can't parse this info */ - bios->digital_min_front_porch = 0x4b; - bios->fmaxvco = 256000; - bios->fminvco = 128000; - bios->fp.duallink_transition_clk = 90000; - - bmp_version_major = bmp[5]; - bmp_version_minor = bmp[6]; - - NV_TRACE(dev, "BMP version %d.%d\n", - bmp_version_major, bmp_version_minor); - - /* - * Make sure that 0x36 is blank and can't be mistaken for a DCB - * pointer on early versions - */ - if (bmp_version_major < 5) - *(uint16_t *)&bios->data[0x36] = 0; - - /* - * Seems that the minor version was 1 for all major versions prior - * to 5. Version 6 could theoretically exist, but I suspect BIT - * happened instead. - */ - if ((bmp_version_major < 5 && bmp_version_minor != 1) || bmp_version_major > 5) { - NV_ERROR(dev, "You have an unsupported BMP version. " - "Please send in your bios\n"); - return -ENOSYS; - } - - if (bmp_version_major == 0) - /* nothing that's currently useful in this version */ - return 0; - else if (bmp_version_major == 1) - bmplength = 44; /* exact for 1.01 */ - else if (bmp_version_major == 2) - bmplength = 48; /* exact for 2.01 */ - else if (bmp_version_major == 3) - bmplength = 54; - /* guessed - mem init tables added in this version */ - else if (bmp_version_major == 4 || bmp_version_minor < 0x1) - /* don't know if 5.0 exists... */ - bmplength = 62; - /* guessed - BMP I2C indices added in version 4*/ - else if (bmp_version_minor < 0x6) - bmplength = 67; /* exact for 5.01 */ - else if (bmp_version_minor < 0x10) - bmplength = 75; /* exact for 5.06 */ - else if (bmp_version_minor == 0x10) - bmplength = 89; /* exact for 5.10h */ - else if (bmp_version_minor < 0x14) - bmplength = 118; /* exact for 5.11h */ - else if (bmp_version_minor < 0x24) - /* - * Not sure of version where pll limits came in; - * certainly exist by 0x24 though. - */ - /* length not exact: this is long enough to get lvds members */ - bmplength = 123; - else if (bmp_version_minor < 0x27) - /* - * Length not exact: this is long enough to get pll limit - * member - */ - bmplength = 144; - else - /* - * Length not exact: this is long enough to get dual link - * transition clock. - */ - bmplength = 158; - - /* checksum */ - if (nv_cksum(bmp, 8)) { - NV_ERROR(dev, "Bad BMP checksum\n"); - return -EINVAL; - } - - /* - * Bit 4 seems to indicate either a mobile bios or a quadro card -- - * mobile behaviour consistent (nv11+), quadro only seen nv18gl-nv36gl - * (not nv10gl), bit 5 that the flat panel tables are present, and - * bit 6 a tv bios. - */ - bios->feature_byte = bmp[9]; - - parse_bios_version(dev, bios, offset + 10); - - if (bmp_version_major < 5 || bmp_version_minor < 0x10) - bios->old_style_init = true; - legacy_scripts_offset = 18; - if (bmp_version_major < 2) - legacy_scripts_offset -= 4; - bios->init_script_tbls_ptr = ROM16(bmp[legacy_scripts_offset]); - bios->extra_init_script_tbl_ptr = ROM16(bmp[legacy_scripts_offset + 2]); - - if (bmp_version_major > 2) { /* appears in BMP 3 */ - bios->legacy.mem_init_tbl_ptr = ROM16(bmp[24]); - bios->legacy.sdr_seq_tbl_ptr = ROM16(bmp[26]); - bios->legacy.ddr_seq_tbl_ptr = ROM16(bmp[28]); - } - - legacy_i2c_offset = 0x48; /* BMP version 2 & 3 */ - if (bmplength > 61) - legacy_i2c_offset = offset + 54; - bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; - bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; - bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; - - if (bmplength > 74) { - bios->fmaxvco = ROM32(bmp[67]); - bios->fminvco = ROM32(bmp[71]); - } - if (bmplength > 88) - parse_script_table_pointers(bios, offset + 75); - if (bmplength > 94) { - bios->tmds.output0_script_ptr = ROM16(bmp[89]); - bios->tmds.output1_script_ptr = ROM16(bmp[91]); - /* - * Never observed in use with lvds scripts, but is reused for - * 18/24 bit panel interface default for EDID equipped panels - * (if_is_24bit not set directly to avoid any oscillation). - */ - bios->legacy.lvds_single_a_script_ptr = ROM16(bmp[95]); - } - if (bmplength > 108) { - bios->fp.fptablepointer = ROM16(bmp[105]); - bios->fp.fpxlatetableptr = ROM16(bmp[107]); - bios->fp.xlatwidth = 1; - } - if (bmplength > 120) { - bios->fp.lvdsmanufacturerpointer = ROM16(bmp[117]); - bios->fp.fpxlatemanufacturertableptr = ROM16(bmp[119]); - } - if (bmplength > 143) - bios->pll_limit_tbl_ptr = ROM16(bmp[142]); - - if (bmplength > 157) - bios->fp.duallink_transition_clk = ROM16(bmp[156]) * 10; - - return 0; -} - -static uint16_t findstr(uint8_t *data, int n, const uint8_t *str, int len) -{ - int i, j; - - for (i = 0; i <= (n - len); i++) { - for (j = 0; j < len; j++) - if (data[i + j] != str[j]) - break; - if (j == len) - return i; - } - - return 0; -} - -void * -dcb_table(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u8 *dcb = NULL; - - if (dev_priv->card_type > NV_04) - dcb = ROMPTR(dev, dev_priv->vbios.data[0x36]); - if (!dcb) { - NV_WARNONCE(dev, "No DCB data found in VBIOS\n"); - return NULL; - } - - if (dcb[0] >= 0x41) { - NV_WARNONCE(dev, "DCB version 0x%02x unknown\n", dcb[0]); - return NULL; - } else - if (dcb[0] >= 0x30) { - if (ROM32(dcb[6]) == 0x4edcbdcb) - return dcb; - } else - if (dcb[0] >= 0x20) { - if (ROM32(dcb[4]) == 0x4edcbdcb) - return dcb; - } else - if (dcb[0] >= 0x15) { - if (!memcmp(&dcb[-7], "DEV_REC", 7)) - return dcb; - } else { - /* - * v1.4 (some NV15/16, NV11+) seems the same as v1.5, but - * always has the same single (crt) entry, even when tv-out - * present, so the conclusion is this version cannot really - * be used. - * - * v1.2 tables (some NV6/10, and NV15+) normally have the - * same 5 entries, which are not specific to the card and so - * no use. - * - * v1.2 does have an I2C table that read_dcb_i2c_table can - * handle, but cards exist (nv11 in #14821) with a bad i2c - * table pointer, so use the indices parsed in - * parse_bmp_structure. - * - * v1.1 (NV5+, maybe some NV4) is entirely unhelpful - */ - NV_WARNONCE(dev, "No useful DCB data in VBIOS\n"); - return NULL; - } - - NV_WARNONCE(dev, "DCB header validation failed\n"); - return NULL; -} - -void * -dcb_outp(struct drm_device *dev, u8 idx) -{ - u8 *dcb = dcb_table(dev); - if (dcb && dcb[0] >= 0x30) { - if (idx < dcb[2]) - return dcb + dcb[1] + (idx * dcb[3]); - } else - if (dcb && dcb[0] >= 0x20) { - u8 *i2c = ROMPTR(dev, dcb[2]); - u8 *ent = dcb + 8 + (idx * 8); - if (i2c && ent < i2c) - return ent; - } else - if (dcb && dcb[0] >= 0x15) { - u8 *i2c = ROMPTR(dev, dcb[2]); - u8 *ent = dcb + 4 + (idx * 10); - if (i2c && ent < i2c) - return ent; - } - - return NULL; -} - -int -dcb_outp_foreach(struct drm_device *dev, void *data, - int (*exec)(struct drm_device *, void *, int idx, u8 *outp)) -{ - int ret, idx = -1; - u8 *outp = NULL; - while ((outp = dcb_outp(dev, ++idx))) { - if (ROM32(outp[0]) == 0x00000000) - break; /* seen on an NV11 with DCB v1.5 */ - if (ROM32(outp[0]) == 0xffffffff) - break; /* seen on an NV17 with DCB v2.0 */ - - if ((outp[0] & 0x0f) == OUTPUT_UNUSED) - continue; - if ((outp[0] & 0x0f) == OUTPUT_EOL) - break; - - ret = exec(dev, data, idx, outp); - if (ret) - return ret; - } - - return 0; -} - -u8 * -dcb_conntab(struct drm_device *dev) -{ - u8 *dcb = dcb_table(dev); - if (dcb && dcb[0] >= 0x30 && dcb[1] >= 0x16) { - u8 *conntab = ROMPTR(dev, dcb[0x14]); - if (conntab && conntab[0] >= 0x30 && conntab[0] <= 0x40) - return conntab; - } - return NULL; -} - -u8 * -dcb_conn(struct drm_device *dev, u8 idx) -{ - u8 *conntab = dcb_conntab(dev); - if (conntab && idx < conntab[2]) - return conntab + conntab[1] + (idx * conntab[3]); - return NULL; -} - -static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb) -{ - struct dcb_entry *entry = &dcb->entry[dcb->entries]; - - memset(entry, 0, sizeof(struct dcb_entry)); - entry->index = dcb->entries++; - - return entry; -} - -static void fabricate_dcb_output(struct dcb_table *dcb, int type, int i2c, - int heads, int or) -{ - struct dcb_entry *entry = new_dcb_entry(dcb); - - entry->type = type; - entry->i2c_index = i2c; - entry->heads = heads; - if (type != OUTPUT_ANALOG) - entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ - entry->or = or; -} - -static bool -parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, - uint32_t conn, uint32_t conf, struct dcb_entry *entry) -{ - entry->type = conn & 0xf; - entry->i2c_index = (conn >> 4) & 0xf; - entry->heads = (conn >> 8) & 0xf; - entry->connector = (conn >> 12) & 0xf; - entry->bus = (conn >> 16) & 0xf; - entry->location = (conn >> 20) & 0x3; - entry->or = (conn >> 24) & 0xf; - - switch (entry->type) { - case OUTPUT_ANALOG: - /* - * Although the rest of a CRT conf dword is usually - * zeros, mac biosen have stuff there so we must mask - */ - entry->crtconf.maxfreq = (dcb->version < 0x30) ? - (conf & 0xffff) * 10 : - (conf & 0xff) * 10000; - break; - case OUTPUT_LVDS: - { - uint32_t mask; - if (conf & 0x1) - entry->lvdsconf.use_straps_for_mode = true; - if (dcb->version < 0x22) { - mask = ~0xd; - /* - * The laptop in bug 14567 lies and claims to not use - * straps when it does, so assume all DCB 2.0 laptops - * use straps, until a broken EDID using one is produced - */ - entry->lvdsconf.use_straps_for_mode = true; - /* - * Both 0x4 and 0x8 show up in v2.0 tables; assume they - * mean the same thing (probably wrong, but might work) - */ - if (conf & 0x4 || conf & 0x8) - entry->lvdsconf.use_power_scripts = true; - } else { - mask = ~0x7; - if (conf & 0x2) - entry->lvdsconf.use_acpi_for_edid = true; - if (conf & 0x4) - entry->lvdsconf.use_power_scripts = true; - entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4; - } - if (conf & mask) { - /* - * Until we even try to use these on G8x, it's - * useless reporting unknown bits. They all are. - */ - if (dcb->version >= 0x40) - break; - - NV_ERROR(dev, "Unknown LVDS configuration bits, " - "please report\n"); - } - break; - } - case OUTPUT_TV: - { - if (dcb->version >= 0x30) - entry->tvconf.has_component_output = conf & (0x8 << 4); - else - entry->tvconf.has_component_output = false; - - break; - } - case OUTPUT_DP: - entry->dpconf.sor.link = (conf & 0x00000030) >> 4; - switch ((conf & 0x00e00000) >> 21) { - case 0: - entry->dpconf.link_bw = 162000; - break; - default: - entry->dpconf.link_bw = 270000; - break; - } - switch ((conf & 0x0f000000) >> 24) { - case 0xf: - entry->dpconf.link_nr = 4; - break; - case 0x3: - entry->dpconf.link_nr = 2; - break; - default: - entry->dpconf.link_nr = 1; - break; - } - break; - case OUTPUT_TMDS: - if (dcb->version >= 0x40) - entry->tmdsconf.sor.link = (conf & 0x00000030) >> 4; - else if (dcb->version >= 0x30) - entry->tmdsconf.slave_addr = (conf & 0x00000700) >> 8; - else if (dcb->version >= 0x22) - entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; - - break; - case OUTPUT_EOL: - /* weird g80 mobile type that "nv" treats as a terminator */ - dcb->entries--; - return false; - default: - break; - } - - if (dcb->version < 0x40) { - /* Normal entries consist of a single bit, but dual link has - * the next most significant bit set too - */ - entry->duallink_possible = - ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); - } else { - entry->duallink_possible = (entry->sorconf.link == 3); - } - - /* unsure what DCB version introduces this, 3.0? */ - if (conf & 0x100000) - entry->i2c_upper_default = true; - - return true; -} - -static bool -parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, - uint32_t conn, uint32_t conf, struct dcb_entry *entry) -{ - switch (conn & 0x0000000f) { - case 0: - entry->type = OUTPUT_ANALOG; - break; - case 1: - entry->type = OUTPUT_TV; - break; - case 2: - case 4: - if (conn & 0x10) - entry->type = OUTPUT_LVDS; - else - entry->type = OUTPUT_TMDS; - break; - case 3: - entry->type = OUTPUT_LVDS; - break; - default: - NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); - return false; - } - - entry->i2c_index = (conn & 0x0003c000) >> 14; - entry->heads = ((conn & 0x001c0000) >> 18) + 1; - entry->or = entry->heads; /* same as heads, hopefully safe enough */ - entry->location = (conn & 0x01e00000) >> 21; - entry->bus = (conn & 0x0e000000) >> 25; - entry->duallink_possible = false; - - switch (entry->type) { - case OUTPUT_ANALOG: - entry->crtconf.maxfreq = (conf & 0xffff) * 10; - break; - case OUTPUT_TV: - entry->tvconf.has_component_output = false; - break; - case OUTPUT_LVDS: - if ((conn & 0x00003f00) >> 8 != 0x10) - entry->lvdsconf.use_straps_for_mode = true; - entry->lvdsconf.use_power_scripts = true; - break; - default: - break; - } - - return true; -} - -static -void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb) -{ - /* - * DCB v2.0 lists each output combination separately. - * Here we merge compatible entries to have fewer outputs, with - * more options - */ - - int i, newentries = 0; - - for (i = 0; i < dcb->entries; i++) { - struct dcb_entry *ient = &dcb->entry[i]; - int j; - - for (j = i + 1; j < dcb->entries; j++) { - struct dcb_entry *jent = &dcb->entry[j]; - - if (jent->type == 100) /* already merged entry */ - continue; - - /* merge heads field when all other fields the same */ - if (jent->i2c_index == ient->i2c_index && - jent->type == ient->type && - jent->location == ient->location && - jent->or == ient->or) { - NV_TRACE(dev, "Merging DCB entries %d and %d\n", - i, j); - ient->heads |= jent->heads; - jent->type = 100; /* dummy value */ - } - } - } - - /* Compact entries merged into others out of dcb */ - for (i = 0; i < dcb->entries; i++) { - if (dcb->entry[i].type == 100) - continue; - - if (newentries != i) { - dcb->entry[newentries] = dcb->entry[i]; - dcb->entry[newentries].index = newentries; - } - newentries++; - } - - dcb->entries = newentries; -} - -static bool -apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_table *dcb = &dev_priv->vbios.dcb; - - /* Dell Precision M6300 - * DCB entry 2: 02025312 00000010 - * DCB entry 3: 02026312 00000020 - * - * Identical, except apparently a different connector on a - * different SOR link. Not a clue how we're supposed to know - * which one is in use if it even shares an i2c line... - * - * Ignore the connector on the second SOR link to prevent - * nasty problems until this is sorted (assuming it's not a - * VBIOS bug). - */ - if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { - if (*conn == 0x02026312 && *conf == 0x00000020) - return false; - } - - /* GeForce3 Ti 200 - * - * DCB reports an LVDS output that should be TMDS: - * DCB entry 1: f2005014 ffffffff - */ - if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) { - if (*conn == 0xf2005014 && *conf == 0xffffffff) { - fabricate_dcb_output(dcb, OUTPUT_TMDS, 1, 1, 1); - return false; - } - } - - /* XFX GT-240X-YA - * - * So many things wrong here, replace the entire encoder table.. - */ - if (nv_match_device(dev, 0x0ca3, 0x1682, 0x3003)) { - if (idx == 0) { - *conn = 0x02001300; /* VGA, connector 1 */ - *conf = 0x00000028; - } else - if (idx == 1) { - *conn = 0x01010312; /* DVI, connector 0 */ - *conf = 0x00020030; - } else - if (idx == 2) { - *conn = 0x01010310; /* VGA, connector 0 */ - *conf = 0x00000028; - } else - if (idx == 3) { - *conn = 0x02022362; /* HDMI, connector 2 */ - *conf = 0x00020010; - } else { - *conn = 0x0000000e; /* EOL */ - *conf = 0x00000000; - } - } - - /* Some other twisted XFX board (rhbz#694914) - * - * The DVI/VGA encoder combo that's supposed to represent the - * DVI-I connector actually point at two different ones, and - * the HDMI connector ends up paired with the VGA instead. - * - * Connector table is missing anything for VGA at all, pointing it - * an invalid conntab entry 2 so we figure it out ourself. - */ - if (nv_match_device(dev, 0x0615, 0x1682, 0x2605)) { - if (idx == 0) { - *conn = 0x02002300; /* VGA, connector 2 */ - *conf = 0x00000028; - } else - if (idx == 1) { - *conn = 0x01010312; /* DVI, connector 0 */ - *conf = 0x00020030; - } else - if (idx == 2) { - *conn = 0x04020310; /* VGA, connector 0 */ - *conf = 0x00000028; - } else - if (idx == 3) { - *conn = 0x02021322; /* HDMI, connector 1 */ - *conf = 0x00020010; - } else { - *conn = 0x0000000e; /* EOL */ - *conf = 0x00000000; - } - } - - return true; -} - -static void -fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios) -{ - struct dcb_table *dcb = &bios->dcb; - int all_heads = (nv_two_heads(dev) ? 3 : 1); - -#ifdef __powerpc__ - /* Apple iMac G4 NV17 */ - if (of_machine_is_compatible("PowerMac4,5")) { - fabricate_dcb_output(dcb, OUTPUT_TMDS, 0, all_heads, 1); - fabricate_dcb_output(dcb, OUTPUT_ANALOG, 1, all_heads, 2); - return; - } -#endif - - /* Make up some sane defaults */ - fabricate_dcb_output(dcb, OUTPUT_ANALOG, - bios->legacy.i2c_indices.crt, 1, 1); - - if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) - fabricate_dcb_output(dcb, OUTPUT_TV, - bios->legacy.i2c_indices.tv, - all_heads, 0); - - else if (bios->tmds.output0_script_ptr || - bios->tmds.output1_script_ptr) - fabricate_dcb_output(dcb, OUTPUT_TMDS, - bios->legacy.i2c_indices.panel, - all_heads, 1); -} - -static int -parse_dcb_entry(struct drm_device *dev, void *data, int idx, u8 *outp) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_table *dcb = &dev_priv->vbios.dcb; - u32 conf = (dcb->version >= 0x20) ? ROM32(outp[4]) : ROM32(outp[6]); - u32 conn = ROM32(outp[0]); - bool ret; - - if (apply_dcb_encoder_quirks(dev, idx, &conn, &conf)) { - struct dcb_entry *entry = new_dcb_entry(dcb); - - NV_TRACEWARN(dev, "DCB outp %02d: %08x %08x\n", idx, conn, conf); - - if (dcb->version >= 0x20) - ret = parse_dcb20_entry(dev, dcb, conn, conf, entry); - else - ret = parse_dcb15_entry(dev, dcb, conn, conf, entry); - if (!ret) - return 1; /* stop parsing */ - - /* Ignore the I2C index for on-chip TV-out, as there - * are cards with bogus values (nv31m in bug 23212), - * and it's otherwise useless. - */ - if (entry->type == OUTPUT_TV && - entry->location == DCB_LOC_ON_CHIP) - entry->i2c_index = 0x0f; - } - - return 0; -} - -static void -dcb_fake_connectors(struct nvbios *bios) -{ - struct dcb_table *dcbt = &bios->dcb; - u8 map[16] = { }; - int i, idx = 0; - - /* heuristic: if we ever get a non-zero connector field, assume - * that all the indices are valid and we don't need fake them. - * - * and, as usual, a blacklist of boards with bad bios data.. - */ - if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) { - for (i = 0; i < dcbt->entries; i++) { - if (dcbt->entry[i].connector) - return; - } - } - - /* no useful connector info available, we need to make it up - * ourselves. the rule here is: anything on the same i2c bus - * is considered to be on the same connector. any output - * without an associated i2c bus is assigned its own unique - * connector index. - */ - for (i = 0; i < dcbt->entries; i++) { - u8 i2c = dcbt->entry[i].i2c_index; - if (i2c == 0x0f) { - dcbt->entry[i].connector = idx++; - } else { - if (!map[i2c]) - map[i2c] = ++idx; - dcbt->entry[i].connector = map[i2c] - 1; - } - } - - /* if we created more than one connector, destroy the connector - * table - just in case it has random, rather than stub, entries. - */ - if (i > 1) { - u8 *conntab = dcb_conntab(bios->dev); - if (conntab) - conntab[0] = 0x00; - } -} - -static int -parse_dcb_table(struct drm_device *dev, struct nvbios *bios) -{ - struct dcb_table *dcb = &bios->dcb; - u8 *dcbt, *conn; - int idx; - - dcbt = dcb_table(dev); - if (!dcbt) { - /* handle pre-DCB boards */ - if (bios->type == NVBIOS_BMP) { - fabricate_dcb_encoder_table(dev, bios); - return 0; - } - - return -EINVAL; - } - - NV_TRACE(dev, "DCB version %d.%d\n", dcbt[0] >> 4, dcbt[0] & 0xf); - - dcb->version = dcbt[0]; - dcb_outp_foreach(dev, NULL, parse_dcb_entry); - - /* - * apart for v2.1+ not being known for requiring merging, this - * guarantees dcbent->index is the index of the entry in the rom image - */ - if (dcb->version < 0x21) - merge_like_dcb_entries(dev, dcb); - - if (!dcb->entries) - return -ENXIO; - - /* dump connector table entries to log, if any exist */ - idx = -1; - while ((conn = dcb_conn(dev, ++idx))) { - if (conn[0] != 0xff) { - NV_TRACE(dev, "DCB conn %02d: ", idx); - if (dcb_conntab(dev)[3] < 4) - printk("%04x\n", ROM16(conn[0])); - else - printk("%08x\n", ROM32(conn[0])); - } - } - dcb_fake_connectors(bios); - return 0; -} - -static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bios, uint16_t hwsq_offset, int entry) -{ - /* - * The header following the "HWSQ" signature has the number of entries, - * and the entry size - * - * An entry consists of a dword to write to the sequencer control reg - * (0x00001304), followed by the ucode bytes, written sequentially, - * starting at reg 0x00001400 - */ - - uint8_t bytes_to_write; - uint16_t hwsq_entry_offset; - int i; - - if (bios->data[hwsq_offset] <= entry) { - NV_ERROR(dev, "Too few entries in HW sequencer table for " - "requested entry\n"); - return -ENOENT; - } - - bytes_to_write = bios->data[hwsq_offset + 1]; - - if (bytes_to_write != 36) { - NV_ERROR(dev, "Unknown HW sequencer entry size\n"); - return -EINVAL; - } - - NV_TRACE(dev, "Loading NV17 power sequencing microcode\n"); - - hwsq_entry_offset = hwsq_offset + 2 + entry * bytes_to_write; - - /* set sequencer control */ - bios_wr32(bios, 0x00001304, ROM32(bios->data[hwsq_entry_offset])); - bytes_to_write -= 4; - - /* write ucode */ - for (i = 0; i < bytes_to_write; i += 4) - bios_wr32(bios, 0x00001400 + i, ROM32(bios->data[hwsq_entry_offset + i + 4])); - - /* twiddle NV_PBUS_DEBUG_4 */ - bios_wr32(bios, NV_PBUS_DEBUG_4, bios_rd32(bios, NV_PBUS_DEBUG_4) | 0x18); - - return 0; -} - -static int load_nv17_hw_sequencer_ucode(struct drm_device *dev, - struct nvbios *bios) -{ - /* - * BMP based cards, from NV17, need a microcode loading to correctly - * control the GPIO etc for LVDS panels - * - * BIT based cards seem to do this directly in the init scripts - * - * The microcode entries are found by the "HWSQ" signature. - */ - - const uint8_t hwsq_signature[] = { 'H', 'W', 'S', 'Q' }; - const int sz = sizeof(hwsq_signature); - int hwsq_offset; - - hwsq_offset = findstr(bios->data, bios->length, hwsq_signature, sz); - if (!hwsq_offset) - return 0; - - /* always use entry 0? */ - return load_nv17_hwsq_ucode_entry(dev, bios, hwsq_offset + sz, 0); -} - -uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - const uint8_t edid_sig[] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; - uint16_t offset = 0; - uint16_t newoffset; - int searchlen = NV_PROM_SIZE; - - if (bios->fp.edid) - return bios->fp.edid; - - while (searchlen) { - newoffset = findstr(&bios->data[offset], searchlen, - edid_sig, 8); - if (!newoffset) - return NULL; - offset += newoffset; - if (!nv_cksum(&bios->data[offset], EDID1_LEN)) - break; - - searchlen -= offset; - offset++; - } - - NV_TRACE(dev, "Found EDID in BIOS\n"); - - return bios->fp.edid = &bios->data[offset]; -} - -void -nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, - struct dcb_entry *dcbent, int crtc) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct init_exec iexec = { true, false }; - - spin_lock_bh(&bios->lock); - bios->display.output = dcbent; - bios->display.crtc = crtc; - parse_init_table(bios, table, &iexec); - bios->display.output = NULL; - spin_unlock_bh(&bios->lock); -} - -void -nouveau_bios_init_exec(struct drm_device *dev, uint16_t table) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct init_exec iexec = { true, false }; - - parse_init_table(bios, table, &iexec); -} - -static bool NVInitVBIOS(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - - memset(bios, 0, sizeof(struct nvbios)); - spin_lock_init(&bios->lock); - bios->dev = dev; - - return bios_shadow(dev); -} - -static int nouveau_parse_vbios_struct(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; - const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 }; - int offset; - - offset = findstr(bios->data, bios->length, - bit_signature, sizeof(bit_signature)); - if (offset) { - NV_TRACE(dev, "BIT BIOS found\n"); - bios->type = NVBIOS_BIT; - bios->offset = offset; - return parse_bit_structure(bios, offset + 6); - } - - offset = findstr(bios->data, bios->length, - bmp_signature, sizeof(bmp_signature)); - if (offset) { - NV_TRACE(dev, "BMP BIOS found\n"); - bios->type = NVBIOS_BMP; - bios->offset = offset; - return parse_bmp_structure(dev, bios, offset); - } - - NV_ERROR(dev, "No known BIOS signature found\n"); - return -ENODEV; -} - -int -nouveau_run_vbios_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - int i, ret = 0; - - /* Reset the BIOS head to 0. */ - bios->state.crtchead = 0; - - if (bios->major_version < 5) /* BMP only */ - load_nv17_hw_sequencer_ucode(dev, bios); - - if (bios->execute) { - bios->fp.last_script_invoc = 0; - bios->fp.lvds_init_run = false; - } - - parse_init_tables(bios); - - /* - * Runs some additional script seen on G8x VBIOSen. The VBIOS' - * parser will run this right after the init tables, the binary - * driver appears to run it at some point later. - */ - if (bios->some_script_ptr) { - struct init_exec iexec = {true, false}; - - NV_INFO(dev, "Parsing VBIOS init table at offset 0x%04X\n", - bios->some_script_ptr); - parse_init_table(bios, bios->some_script_ptr, &iexec); - } - - if (dev_priv->card_type >= NV_50) { - for (i = 0; i < bios->dcb.entries; i++) { - nouveau_bios_run_display_table(dev, 0, 0, - &bios->dcb.entry[i], -1); - } - } - - return ret; -} - -static bool -nouveau_bios_posted(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned htotal; - - if (dev_priv->card_type >= NV_50) { - if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && - NVReadVgaCrtc(dev, 0, 0x1a) == 0) - return false; - return true; - } - - htotal = NVReadVgaCrtc(dev, 0, 0x06); - htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; - htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; - htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; - htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; - - return (htotal != 0); -} - -int -nouveau_bios_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - int ret; - - if (!NVInitVBIOS(dev)) - return -ENODEV; - - ret = nouveau_parse_vbios_struct(dev); - if (ret) - return ret; - - ret = nouveau_i2c_init(dev); - if (ret) - return ret; - - ret = nouveau_mxm_init(dev); - if (ret) - return ret; - - ret = parse_dcb_table(dev, bios); - if (ret) - return ret; - - if (!bios->major_version) /* we don't run version 0 bios */ - return 0; - - /* init script execution disabled */ - bios->execute = false; - - /* ... unless card isn't POSTed already */ - if (!nouveau_bios_posted(dev)) { - NV_INFO(dev, "Adaptor not initialised, " - "running VBIOS init tables.\n"); - bios->execute = true; - } - if (nouveau_force_post) - bios->execute = true; - - ret = nouveau_run_vbios_init(dev); - if (ret) - return ret; - - /* feature_byte on BMP is poor, but init always sets CR4B */ - if (bios->major_version < 5) - bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40; - - /* all BIT systems need p_f_m_t for digital_min_front_porch */ - if (bios->is_mobile || bios->major_version >= 5) - ret = parse_fp_mode_table(dev, bios); - - /* allow subsequent scripts to execute */ - bios->execute = true; - - return 0; -} - -void -nouveau_bios_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nouveau_mxm_fini(dev); - nouveau_i2c_fini(dev); - - kfree(dev_priv->vbios.data); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.h deleted file mode 100644 index 298a3af4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bios.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2007-2008 Nouveau Project - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef __NOUVEAU_BIOS_H__ -#define __NOUVEAU_BIOS_H__ - -#include "nvreg.h" -#include "nouveau_i2c.h" - -#define DCB_MAX_NUM_ENTRIES 16 -#define DCB_MAX_NUM_I2C_ENTRIES 16 -#define DCB_MAX_NUM_GPIO_ENTRIES 32 -#define DCB_MAX_NUM_CONNECTOR_ENTRIES 16 - -#define DCB_LOC_ON_CHIP 0 - -#define ROM16(x) le16_to_cpu(*(u16 *)&(x)) -#define ROM32(x) le32_to_cpu(*(u32 *)&(x)) -#define ROM48(x) ({ u8 *p = &(x); (u64)ROM16(p[4]) << 32 | ROM32(p[0]); }) -#define ROM64(x) le64_to_cpu(*(u64 *)&(x)) -#define ROMPTR(d,x) ({ \ - struct drm_nouveau_private *dev_priv = (d)->dev_private; \ - ROM16(x) ? &dev_priv->vbios.data[ROM16(x)] : NULL; \ -}) - -struct bit_entry { - uint8_t id; - uint8_t version; - uint16_t length; - uint16_t offset; - uint8_t *data; -}; - -int bit_table(struct drm_device *, u8 id, struct bit_entry *); - -enum dcb_gpio_tag { - DCB_GPIO_PANEL_POWER = 0x01, - DCB_GPIO_TVDAC0 = 0x0c, - DCB_GPIO_TVDAC1 = 0x2d, - DCB_GPIO_PWM_FAN = 0x09, - DCB_GPIO_FAN_SENSE = 0x3d, - DCB_GPIO_UNUSED = 0xff -}; - -enum dcb_connector_type { - DCB_CONNECTOR_VGA = 0x00, - DCB_CONNECTOR_TV_0 = 0x10, - DCB_CONNECTOR_TV_1 = 0x11, - DCB_CONNECTOR_TV_3 = 0x13, - DCB_CONNECTOR_DVI_I = 0x30, - DCB_CONNECTOR_DVI_D = 0x31, - DCB_CONNECTOR_DMS59_0 = 0x38, - DCB_CONNECTOR_DMS59_1 = 0x39, - DCB_CONNECTOR_LVDS = 0x40, - DCB_CONNECTOR_LVDS_SPWG = 0x41, - DCB_CONNECTOR_DP = 0x46, - DCB_CONNECTOR_eDP = 0x47, - DCB_CONNECTOR_HDMI_0 = 0x60, - DCB_CONNECTOR_HDMI_1 = 0x61, - DCB_CONNECTOR_DMS59_DP0 = 0x64, - DCB_CONNECTOR_DMS59_DP1 = 0x65, - DCB_CONNECTOR_NONE = 0xff -}; - -enum dcb_type { - OUTPUT_ANALOG = 0, - OUTPUT_TV = 1, - OUTPUT_TMDS = 2, - OUTPUT_LVDS = 3, - OUTPUT_DP = 6, - OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ - OUTPUT_UNUSED = 15, - OUTPUT_ANY = -1 -}; - -struct dcb_entry { - int index; /* may not be raw dcb index if merging has happened */ - enum dcb_type type; - uint8_t i2c_index; - uint8_t heads; - uint8_t connector; - uint8_t bus; - uint8_t location; - uint8_t or; - bool duallink_possible; - union { - struct sor_conf { - int link; - } sorconf; - struct { - int maxfreq; - } crtconf; - struct { - struct sor_conf sor; - bool use_straps_for_mode; - bool use_acpi_for_edid; - bool use_power_scripts; - } lvdsconf; - struct { - bool has_component_output; - } tvconf; - struct { - struct sor_conf sor; - int link_nr; - int link_bw; - } dpconf; - struct { - struct sor_conf sor; - int slave_addr; - } tmdsconf; - }; - bool i2c_upper_default; -}; - -struct dcb_table { - uint8_t version; - int entries; - struct dcb_entry entry[DCB_MAX_NUM_ENTRIES]; -}; - -enum nouveau_or { - OUTPUT_A = (1 << 0), - OUTPUT_B = (1 << 1), - OUTPUT_C = (1 << 2) -}; - -enum LVDS_script { - /* Order *does* matter here */ - LVDS_INIT = 1, - LVDS_RESET, - LVDS_BACKLIGHT_ON, - LVDS_BACKLIGHT_OFF, - LVDS_PANEL_ON, - LVDS_PANEL_OFF -}; - -/* these match types in pll limits table version 0x40, - * nouveau uses them on all chipsets internally where a - * specific pll needs to be referenced, but the exact - * register isn't known. - */ -enum pll_types { - PLL_CORE = 0x01, - PLL_SHADER = 0x02, - PLL_UNK03 = 0x03, - PLL_MEMORY = 0x04, - PLL_VDEC = 0x05, - PLL_UNK40 = 0x40, - PLL_UNK41 = 0x41, - PLL_UNK42 = 0x42, - PLL_VPLL0 = 0x80, - PLL_VPLL1 = 0x81, - PLL_MAX = 0xff -}; - -struct pll_lims { - u32 reg; - - struct { - int minfreq; - int maxfreq; - int min_inputfreq; - int max_inputfreq; - - uint8_t min_m; - uint8_t max_m; - uint8_t min_n; - uint8_t max_n; - } vco1, vco2; - - uint8_t max_log2p; - /* - * for most pre nv50 cards setting a log2P of 7 (the common max_log2p - * value) is no different to 6 (at least for vplls) so allowing the MNP - * calc to use 7 causes the generated clock to be out by a factor of 2. - * however, max_log2p cannot be fixed-up during parsing as the - * unmodified max_log2p value is still needed for setting mplls, hence - * an additional max_usable_log2p member - */ - uint8_t max_usable_log2p; - uint8_t log2p_bias; - - uint8_t min_p; - uint8_t max_p; - - int refclk; -}; - -struct nvbios { - struct drm_device *dev; - enum { - NVBIOS_BMP, - NVBIOS_BIT - } type; - uint16_t offset; - uint32_t length; - uint8_t *data; - - uint8_t chip_version; - - uint32_t dactestval; - uint32_t tvdactestval; - uint8_t digital_min_front_porch; - bool fp_no_ddc; - - spinlock_t lock; - - bool execute; - - uint8_t major_version; - uint8_t feature_byte; - bool is_mobile; - - uint32_t fmaxvco, fminvco; - - bool old_style_init; - uint16_t init_script_tbls_ptr; - uint16_t extra_init_script_tbl_ptr; - uint16_t macro_index_tbl_ptr; - uint16_t macro_tbl_ptr; - uint16_t condition_tbl_ptr; - uint16_t io_condition_tbl_ptr; - uint16_t io_flag_condition_tbl_ptr; - uint16_t init_function_tbl_ptr; - - uint16_t pll_limit_tbl_ptr; - uint16_t ram_restrict_tbl_ptr; - uint8_t ram_restrict_group_count; - - uint16_t some_script_ptr; /* BIT I + 14 */ - uint16_t init96_tbl_ptr; /* BIT I + 16 */ - - struct dcb_table dcb; - - struct { - int crtchead; - } state; - - struct { - struct dcb_entry *output; - int crtc; - uint16_t script_table_ptr; - } display; - - struct { - uint16_t fptablepointer; /* also used by tmds */ - uint16_t fpxlatetableptr; - int xlatwidth; - uint16_t lvdsmanufacturerpointer; - uint16_t fpxlatemanufacturertableptr; - uint16_t mode_ptr; - uint16_t xlated_entry; - bool power_off_for_reset; - bool reset_after_pclk_change; - bool dual_link; - bool link_c_increment; - bool if_is_24bit; - int duallink_transition_clk; - uint8_t strapless_is_24bit; - uint8_t *edid; - - /* will need resetting after suspend */ - int last_script_invoc; - bool lvds_init_run; - } fp; - - struct { - uint16_t output0_script_ptr; - uint16_t output1_script_ptr; - } tmds; - - struct { - uint16_t mem_init_tbl_ptr; - uint16_t sdr_seq_tbl_ptr; - uint16_t ddr_seq_tbl_ptr; - - struct { - uint8_t crt, tv, panel; - } i2c_indices; - - uint16_t lvds_single_a_script_ptr; - } legacy; -}; - -void *dcb_table(struct drm_device *); -void *dcb_outp(struct drm_device *, u8 idx); -int dcb_outp_foreach(struct drm_device *, void *data, - int (*)(struct drm_device *, void *, int idx, u8 *outp)); -u8 *dcb_conntab(struct drm_device *); -u8 *dcb_conn(struct drm_device *, u8 idx); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bo.c deleted file mode 100644 index 12ce044f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_bo.c +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * Copyright 2007 Dave Airlied - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -/* - * Authors: Dave Airlied - * Ben Skeggs - * Jeremy Kolb - */ - -#include "drmP.h" -#include "ttm/ttm_page_alloc.h" - -#include "nouveau_drm.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_mm.h" -#include "nouveau_vm.h" - -#include -#include - -static void -nouveau_bo_del_ttm(struct ttm_buffer_object *bo) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct drm_device *dev = dev_priv->dev; - struct nouveau_bo *nvbo = nouveau_bo(bo); - - if (unlikely(nvbo->gem)) - DRM_ERROR("bo %p still attached to GEM object\n", bo); - - nv10_mem_put_tile_region(dev, nvbo->tile, NULL); - kfree(nvbo); -} - -static void -nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags, - int *align, int *size) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); - - if (dev_priv->card_type < NV_50) { - if (nvbo->tile_mode) { - if (dev_priv->chipset >= 0x40) { - *align = 65536; - *size = roundup(*size, 64 * nvbo->tile_mode); - - } else if (dev_priv->chipset >= 0x30) { - *align = 32768; - *size = roundup(*size, 64 * nvbo->tile_mode); - - } else if (dev_priv->chipset >= 0x20) { - *align = 16384; - *size = roundup(*size, 64 * nvbo->tile_mode); - - } else if (dev_priv->chipset >= 0x10) { - *align = 16384; - *size = roundup(*size, 32 * nvbo->tile_mode); - } - } - } else { - *size = roundup(*size, (1 << nvbo->page_shift)); - *align = max((1 << nvbo->page_shift), *align); - } - - *size = roundup(*size, PAGE_SIZE); -} - -int -nouveau_bo_new(struct drm_device *dev, int size, int align, - uint32_t flags, uint32_t tile_mode, uint32_t tile_flags, - struct nouveau_bo **pnvbo) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *nvbo; - size_t acc_size; - int ret; - - nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); - if (!nvbo) - return -ENOMEM; - INIT_LIST_HEAD(&nvbo->head); - INIT_LIST_HEAD(&nvbo->entry); - INIT_LIST_HEAD(&nvbo->vma_list); - nvbo->tile_mode = tile_mode; - nvbo->tile_flags = tile_flags; - nvbo->bo.bdev = &dev_priv->ttm.bdev; - - nvbo->page_shift = 12; - if (dev_priv->bar1_vm) { - if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024) - nvbo->page_shift = dev_priv->bar1_vm->lpg_shift; - } - - nouveau_bo_fixup_align(nvbo, flags, &align, &size); - nvbo->bo.mem.num_pages = size >> PAGE_SHIFT; - nouveau_bo_placement_set(nvbo, flags, 0); - - acc_size = ttm_bo_dma_acc_size(&dev_priv->ttm.bdev, size, - sizeof(struct nouveau_bo)); - - ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, - ttm_bo_type_device, &nvbo->placement, - align >> PAGE_SHIFT, 0, false, NULL, acc_size, - nouveau_bo_del_ttm); - if (ret) { - /* ttm will call nouveau_bo_del_ttm if it fails.. */ - return ret; - } - - *pnvbo = nvbo; - return 0; -} - -static void -set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags) -{ - *n = 0; - - if (type & TTM_PL_FLAG_VRAM) - pl[(*n)++] = TTM_PL_FLAG_VRAM | flags; - if (type & TTM_PL_FLAG_TT) - pl[(*n)++] = TTM_PL_FLAG_TT | flags; - if (type & TTM_PL_FLAG_SYSTEM) - pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; -} - -static void -set_placement_range(struct nouveau_bo *nvbo, uint32_t type) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); - int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; - - if (dev_priv->card_type == NV_10 && - nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && - nvbo->bo.mem.num_pages < vram_pages / 4) { - /* - * Make sure that the color and depth buffers are handled - * by independent memory controller units. Up to a 9x - * speed up when alpha-blending and depth-test are enabled - * at the same time. - */ - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { - nvbo->placement.fpfn = vram_pages / 2; - nvbo->placement.lpfn = ~0; - } else { - nvbo->placement.fpfn = 0; - nvbo->placement.lpfn = vram_pages / 2; - } - } -} - -void -nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) -{ - struct ttm_placement *pl = &nvbo->placement; - uint32_t flags = TTM_PL_MASK_CACHING | - (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0); - - pl->placement = nvbo->placements; - set_placement_list(nvbo->placements, &pl->num_placement, - type, flags); - - pl->busy_placement = nvbo->busy_placements; - set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, - type | busy, flags); - - set_placement_range(nvbo, type); -} - -int -nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); - struct ttm_buffer_object *bo = &nvbo->bo; - int ret; - - if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { - NV_ERROR(nouveau_bdev(bo->bdev)->dev, - "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo, - 1 << bo->mem.mem_type, memtype); - return -EINVAL; - } - - if (nvbo->pin_refcnt++) - return 0; - - ret = ttm_bo_reserve(bo, false, false, false, 0); - if (ret) - goto out; - - nouveau_bo_placement_set(nvbo, memtype, 0); - - ret = nouveau_bo_validate(nvbo, false, false, false); - if (ret == 0) { - switch (bo->mem.mem_type) { - case TTM_PL_VRAM: - dev_priv->fb_aper_free -= bo->mem.size; - break; - case TTM_PL_TT: - dev_priv->gart_info.aper_free -= bo->mem.size; - break; - default: - break; - } - } - ttm_bo_unreserve(bo); -out: - if (unlikely(ret)) - nvbo->pin_refcnt--; - return ret; -} - -int -nouveau_bo_unpin(struct nouveau_bo *nvbo) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); - struct ttm_buffer_object *bo = &nvbo->bo; - int ret; - - if (--nvbo->pin_refcnt) - return 0; - - ret = ttm_bo_reserve(bo, false, false, false, 0); - if (ret) - return ret; - - nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); - - ret = nouveau_bo_validate(nvbo, false, false, false); - if (ret == 0) { - switch (bo->mem.mem_type) { - case TTM_PL_VRAM: - dev_priv->fb_aper_free += bo->mem.size; - break; - case TTM_PL_TT: - dev_priv->gart_info.aper_free += bo->mem.size; - break; - default: - break; - } - } - - ttm_bo_unreserve(bo); - return ret; -} - -int -nouveau_bo_map(struct nouveau_bo *nvbo) -{ - int ret; - - ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0); - if (ret) - return ret; - - ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap); - ttm_bo_unreserve(&nvbo->bo); - return ret; -} - -void -nouveau_bo_unmap(struct nouveau_bo *nvbo) -{ - if (nvbo) - ttm_bo_kunmap(&nvbo->kmap); -} - -int -nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible, - bool no_wait_reserve, bool no_wait_gpu) -{ - int ret; - - ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, interruptible, - no_wait_reserve, no_wait_gpu); - if (ret) - return ret; - - return 0; -} - -u16 -nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index) -{ - bool is_iomem; - u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); - mem = &mem[index]; - if (is_iomem) - return ioread16_native((void __force __iomem *)mem); - else - return *mem; -} - -void -nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val) -{ - bool is_iomem; - u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); - mem = &mem[index]; - if (is_iomem) - iowrite16_native(val, (void __force __iomem *)mem); - else - *mem = val; -} - -u32 -nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index) -{ - bool is_iomem; - u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); - mem = &mem[index]; - if (is_iomem) - return ioread32_native((void __force __iomem *)mem); - else - return *mem; -} - -void -nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val) -{ - bool is_iomem; - u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem); - mem = &mem[index]; - if (is_iomem) - iowrite32_native(val, (void __force __iomem *)mem); - else - *mem = val; -} - -static struct ttm_tt * -nouveau_ttm_tt_create(struct ttm_bo_device *bdev, - unsigned long size, uint32_t page_flags, - struct page *dummy_read_page) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); - struct drm_device *dev = dev_priv->dev; - - switch (dev_priv->gart_info.type) { -#if __OS_HAS_AGP - case NOUVEAU_GART_AGP: - return ttm_agp_tt_create(bdev, dev->agp->bridge, - size, page_flags, dummy_read_page); -#endif - case NOUVEAU_GART_PDMA: - case NOUVEAU_GART_HW: - return nouveau_sgdma_create_ttm(bdev, size, page_flags, - dummy_read_page); - default: - NV_ERROR(dev, "Unknown GART type %d\n", - dev_priv->gart_info.type); - break; - } - - return NULL; -} - -static int -nouveau_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - /* We'll do this from user space. */ - return 0; -} - -static int -nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); - struct drm_device *dev = dev_priv->dev; - - switch (type) { - case TTM_PL_SYSTEM: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_VRAM: - if (dev_priv->card_type >= NV_50) { - man->func = &nouveau_vram_manager; - man->io_reserve_fastpath = false; - man->use_io_reserve_lru = true; - } else { - man->func = &ttm_bo_manager_func; - } - man->flags = TTM_MEMTYPE_FLAG_FIXED | - TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - case TTM_PL_TT: - if (dev_priv->card_type >= NV_50) - man->func = &nouveau_gart_manager; - else - man->func = &ttm_bo_manager_func; - switch (dev_priv->gart_info.type) { - case NOUVEAU_GART_AGP: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - case NOUVEAU_GART_PDMA: - case NOUVEAU_GART_HW: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_CMA; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - default: - NV_ERROR(dev, "Unknown GART type: %d\n", - dev_priv->gart_info.type); - return -EINVAL; - } - break; - default: - NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type); - return -EINVAL; - } - return 0; -} - -static void -nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) -{ - struct nouveau_bo *nvbo = nouveau_bo(bo); - - switch (bo->mem.mem_type) { - case TTM_PL_VRAM: - nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT, - TTM_PL_FLAG_SYSTEM); - break; - default: - nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0); - break; - } - - *pl = nvbo->placement; -} - - -/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access - * TTM_PL_{VRAM,TT} directly. - */ - -static int -nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, - struct nouveau_bo *nvbo, bool evict, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - struct nouveau_fence *fence = NULL; - int ret; - - ret = nouveau_fence_new(chan, &fence, true); - if (ret) - return ret; - - ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, evict, - no_wait_reserve, no_wait_gpu, new_mem); - nouveau_fence_unref(&fence); - return ret; -} - -static int -nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, - struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) -{ - struct nouveau_mem *node = old_mem->mm_node; - u64 src_offset = node->vma[0].offset; - u64 dst_offset = node->vma[1].offset; - u32 page_count = new_mem->num_pages; - int ret; - - page_count = new_mem->num_pages; - while (page_count) { - int line_count = (page_count > 2047) ? 2047 : page_count; - - ret = RING_SPACE(chan, 12); - if (ret) - return ret; - - BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0238, 2); - OUT_RING (chan, upper_32_bits(dst_offset)); - OUT_RING (chan, lower_32_bits(dst_offset)); - BEGIN_NVC0(chan, 2, NvSubM2MF, 0x030c, 6); - OUT_RING (chan, upper_32_bits(src_offset)); - OUT_RING (chan, lower_32_bits(src_offset)); - OUT_RING (chan, PAGE_SIZE); /* src_pitch */ - OUT_RING (chan, PAGE_SIZE); /* dst_pitch */ - OUT_RING (chan, PAGE_SIZE); /* line_length */ - OUT_RING (chan, line_count); - BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0300, 1); - OUT_RING (chan, 0x00100110); - - page_count -= line_count; - src_offset += (PAGE_SIZE * line_count); - dst_offset += (PAGE_SIZE * line_count); - } - - return 0; -} - -static int -nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, - struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) -{ - struct nouveau_mem *node = old_mem->mm_node; - struct nouveau_bo *nvbo = nouveau_bo(bo); - u64 length = (new_mem->num_pages << PAGE_SHIFT); - u64 src_offset = node->vma[0].offset; - u64 dst_offset = node->vma[1].offset; - int ret; - - while (length) { - u32 amount, stride, height; - - amount = min(length, (u64)(4 * 1024 * 1024)); - stride = 16 * 4; - height = amount / stride; - - if (new_mem->mem_type == TTM_PL_VRAM && - nouveau_bo_tile_layout(nvbo)) { - ret = RING_SPACE(chan, 8); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, 0x0200, 7); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, stride); - OUT_RING (chan, height); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - } else { - ret = RING_SPACE(chan, 2); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); - OUT_RING (chan, 1); - } - if (old_mem->mem_type == TTM_PL_VRAM && - nouveau_bo_tile_layout(nvbo)) { - ret = RING_SPACE(chan, 8); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, 0x021c, 7); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, stride); - OUT_RING (chan, height); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - } else { - ret = RING_SPACE(chan, 2); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, 0x021c, 1); - OUT_RING (chan, 1); - } - - ret = RING_SPACE(chan, 14); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, 0x0238, 2); - OUT_RING (chan, upper_32_bits(src_offset)); - OUT_RING (chan, upper_32_bits(dst_offset)); - BEGIN_RING(chan, NvSubM2MF, 0x030c, 8); - OUT_RING (chan, lower_32_bits(src_offset)); - OUT_RING (chan, lower_32_bits(dst_offset)); - OUT_RING (chan, stride); - OUT_RING (chan, stride); - OUT_RING (chan, stride); - OUT_RING (chan, height); - OUT_RING (chan, 0x00000101); - OUT_RING (chan, 0x00000000); - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1); - OUT_RING (chan, 0); - - length -= amount; - src_offset += amount; - dst_offset += amount; - } - - return 0; -} - -static inline uint32_t -nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo, - struct nouveau_channel *chan, struct ttm_mem_reg *mem) -{ - if (mem->mem_type == TTM_PL_TT) - return chan->gart_handle; - return chan->vram_handle; -} - -static int -nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, - struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) -{ - u32 src_offset = old_mem->start << PAGE_SHIFT; - u32 dst_offset = new_mem->start << PAGE_SHIFT; - u32 page_count = new_mem->num_pages; - int ret; - - ret = RING_SPACE(chan, 3); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2); - OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, old_mem)); - OUT_RING (chan, nouveau_bo_mem_ctxdma(bo, chan, new_mem)); - - page_count = new_mem->num_pages; - while (page_count) { - int line_count = (page_count > 2047) ? 2047 : page_count; - - ret = RING_SPACE(chan, 11); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubM2MF, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RING (chan, src_offset); - OUT_RING (chan, dst_offset); - OUT_RING (chan, PAGE_SIZE); /* src_pitch */ - OUT_RING (chan, PAGE_SIZE); /* dst_pitch */ - OUT_RING (chan, PAGE_SIZE); /* line_length */ - OUT_RING (chan, line_count); - OUT_RING (chan, 0x00000101); - OUT_RING (chan, 0x00000000); - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1); - OUT_RING (chan, 0); - - page_count -= line_count; - src_offset += (PAGE_SIZE * line_count); - dst_offset += (PAGE_SIZE * line_count); - } - - return 0; -} - -static int -nouveau_vma_getmap(struct nouveau_channel *chan, struct nouveau_bo *nvbo, - struct ttm_mem_reg *mem, struct nouveau_vma *vma) -{ - struct nouveau_mem *node = mem->mm_node; - int ret; - - ret = nouveau_vm_get(chan->vm, mem->num_pages << PAGE_SHIFT, - node->page_shift, NV_MEM_ACCESS_RO, vma); - if (ret) - return ret; - - if (mem->mem_type == TTM_PL_VRAM) - nouveau_vm_map(vma, node); - else - nouveau_vm_map_sg(vma, 0, mem->num_pages << PAGE_SHIFT, node); - - return 0; -} - -static int -nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct nouveau_channel *chan = chan = dev_priv->channel; - struct nouveau_bo *nvbo = nouveau_bo(bo); - struct ttm_mem_reg *old_mem = &bo->mem; - int ret; - - mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX); - - /* create temporary vmas for the transfer and attach them to the - * old nouveau_mem node, these will get cleaned up after ttm has - * destroyed the ttm_mem_reg - */ - if (dev_priv->card_type >= NV_50) { - struct nouveau_mem *node = old_mem->mm_node; - - ret = nouveau_vma_getmap(chan, nvbo, old_mem, &node->vma[0]); - if (ret) - goto out; - - ret = nouveau_vma_getmap(chan, nvbo, new_mem, &node->vma[1]); - if (ret) - goto out; - } - - if (dev_priv->card_type < NV_50) - ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); - else - if (dev_priv->card_type < NV_C0) - ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); - else - ret = nvc0_bo_move_m2mf(chan, bo, &bo->mem, new_mem); - if (ret == 0) { - ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict, - no_wait_reserve, - no_wait_gpu, new_mem); - } - -out: - mutex_unlock(&chan->mutex); - return ret; -} - -static int -nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; - struct ttm_placement placement; - struct ttm_mem_reg tmp_mem; - int ret; - - placement.fpfn = placement.lpfn = 0; - placement.num_placement = placement.num_busy_placement = 1; - placement.placement = placement.busy_placement = &placement_memtype; - - tmp_mem = *new_mem; - tmp_mem.mm_node = NULL; - ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait_reserve, no_wait_gpu); - if (ret) - return ret; - - ret = ttm_tt_bind(bo->ttm, &tmp_mem); - if (ret) - goto out; - - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, &tmp_mem); - if (ret) - goto out; - - ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, new_mem); -out: - ttm_bo_mem_put(bo, &tmp_mem); - return ret; -} - -static int -nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; - struct ttm_placement placement; - struct ttm_mem_reg tmp_mem; - int ret; - - placement.fpfn = placement.lpfn = 0; - placement.num_placement = placement.num_busy_placement = 1; - placement.placement = placement.busy_placement = &placement_memtype; - - tmp_mem = *new_mem; - tmp_mem.mm_node = NULL; - ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait_reserve, no_wait_gpu); - if (ret) - return ret; - - ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem); - if (ret) - goto out; - - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, new_mem); - if (ret) - goto out; - -out: - ttm_bo_mem_put(bo, &tmp_mem); - return ret; -} - -static void -nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) -{ - struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nouveau_vma *vma; - - /* ttm can now (stupidly) pass the driver bos it didn't create... */ - if (bo->destroy != nouveau_bo_del_ttm) - return; - - list_for_each_entry(vma, &nvbo->vma_list, head) { - if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { - nouveau_vm_map(vma, new_mem->mm_node); - } else - if (new_mem && new_mem->mem_type == TTM_PL_TT && - nvbo->page_shift == vma->vm->spg_shift) { - nouveau_vm_map_sg(vma, 0, new_mem-> - num_pages << PAGE_SHIFT, - new_mem->mm_node); - } else { - nouveau_vm_unmap(vma); - } - } -} - -static int -nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, - struct nouveau_tile_reg **new_tile) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct drm_device *dev = dev_priv->dev; - struct nouveau_bo *nvbo = nouveau_bo(bo); - u64 offset = new_mem->start << PAGE_SHIFT; - - *new_tile = NULL; - if (new_mem->mem_type != TTM_PL_VRAM) - return 0; - - if (dev_priv->card_type >= NV_10) { - *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size, - nvbo->tile_mode, - nvbo->tile_flags); - } - - return 0; -} - -static void -nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, - struct nouveau_tile_reg *new_tile, - struct nouveau_tile_reg **old_tile) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct drm_device *dev = dev_priv->dev; - - nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj); - *old_tile = new_tile; -} - -static int -nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct nouveau_bo *nvbo = nouveau_bo(bo); - struct ttm_mem_reg *old_mem = &bo->mem; - struct nouveau_tile_reg *new_tile = NULL; - int ret = 0; - - if (dev_priv->card_type < NV_50) { - ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile); - if (ret) - return ret; - } - - /* Fake bo copy. */ - if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) { - BUG_ON(bo->mem.mm_node != NULL); - bo->mem = *new_mem; - new_mem->mm_node = NULL; - goto out; - } - - /* Software copy if the card isn't up and running yet. */ - if (!dev_priv->channel) { - ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); - goto out; - } - - /* Hardware assisted copy. */ - if (new_mem->mem_type == TTM_PL_SYSTEM) - ret = nouveau_bo_move_flipd(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); - else if (old_mem->mem_type == TTM_PL_SYSTEM) - ret = nouveau_bo_move_flips(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); - else - ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); - - if (!ret) - goto out; - - /* Fallback to software copy. */ - ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); - -out: - if (dev_priv->card_type < NV_50) { - if (ret) - nouveau_bo_vm_cleanup(bo, NULL, &new_tile); - else - nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile); - } - - return ret; -} - -static int -nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) -{ - return 0; -} - -static int -nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); - struct drm_device *dev = dev_priv->dev; - int ret; - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* System memory */ - return 0; - case TTM_PL_TT: -#if __OS_HAS_AGP - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = dev_priv->gart_info.aper_base; - mem->bus.is_iomem = true; - } -#endif - break; - case TTM_PL_VRAM: - { - struct nouveau_mem *node = mem->mm_node; - u8 page_shift; - - if (!dev_priv->bar1_vm) { - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = pci_resource_start(dev->pdev, 1); - mem->bus.is_iomem = true; - break; - } - - if (dev_priv->card_type >= NV_C0) - page_shift = node->page_shift; - else - page_shift = 12; - - ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, - page_shift, NV_MEM_ACCESS_RW, - &node->bar_vma); - if (ret) - return ret; - - nouveau_vm_map(&node->bar_vma, node); - if (ret) { - nouveau_vm_put(&node->bar_vma); - return ret; - } - - mem->bus.offset = node->bar_vma.offset; - if (dev_priv->card_type == NV_50) /*XXX*/ - mem->bus.offset -= 0x0020000000ULL; - mem->bus.base = pci_resource_start(dev->pdev, 1); - mem->bus.is_iomem = true; - } - break; - default: - return -EINVAL; - } - return 0; -} - -static void -nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); - struct nouveau_mem *node = mem->mm_node; - - if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM) - return; - - if (!node->bar_vma.node) - return; - - nouveau_vm_unmap(&node->bar_vma); - nouveau_vm_put(&node->bar_vma); -} - -static int -nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct nouveau_bo *nvbo = nouveau_bo(bo); - - /* as long as the bo isn't in vram, and isn't tiled, we've got - * nothing to do here. - */ - if (bo->mem.mem_type != TTM_PL_VRAM) { - if (dev_priv->card_type < NV_50 || - !nouveau_bo_tile_layout(nvbo)) - return 0; - } - - /* make sure bo is in mappable vram */ - if (bo->mem.start + bo->mem.num_pages < dev_priv->fb_mappable_pages) - return 0; - - - nvbo->placement.fpfn = 0; - nvbo->placement.lpfn = dev_priv->fb_mappable_pages; - nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_VRAM, 0); - return nouveau_bo_validate(nvbo, false, true, false); -} - -void -nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence) -{ - struct nouveau_fence *old_fence; - - if (likely(fence)) - nouveau_fence_ref(fence); - - spin_lock(&nvbo->bo.bdev->fence_lock); - old_fence = nvbo->bo.sync_obj; - nvbo->bo.sync_obj = fence; - spin_unlock(&nvbo->bo.bdev->fence_lock); - - nouveau_fence_unref(&old_fence); -} - -static int -nouveau_ttm_tt_populate(struct ttm_tt *ttm) -{ - struct ttm_dma_tt *ttm_dma = (void *)ttm; - struct drm_nouveau_private *dev_priv; - struct drm_device *dev; - unsigned i; - int r; - - if (ttm->state != tt_unpopulated) - return 0; - - dev_priv = nouveau_bdev(ttm->bdev); - dev = dev_priv->dev; - -#if __OS_HAS_AGP - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { - return ttm_agp_tt_populate(ttm); - } -#endif - -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { - return ttm_dma_populate((void *)ttm, dev->dev); - } -#endif - - r = ttm_pool_populate(ttm); - if (r) { - return r; - } - - for (i = 0; i < ttm->num_pages; i++) { - ttm_dma->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i], - 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, ttm_dma->dma_address[i])) { - while (--i) { - pci_unmap_page(dev->pdev, ttm_dma->dma_address[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - ttm_dma->dma_address[i] = 0; - } - ttm_pool_unpopulate(ttm); - return -EFAULT; - } - } - return 0; -} - -static void -nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) -{ - struct ttm_dma_tt *ttm_dma = (void *)ttm; - struct drm_nouveau_private *dev_priv; - struct drm_device *dev; - unsigned i; - - dev_priv = nouveau_bdev(ttm->bdev); - dev = dev_priv->dev; - -#if __OS_HAS_AGP - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { - ttm_agp_tt_unpopulate(ttm); - return; - } -#endif - -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { - ttm_dma_unpopulate((void *)ttm, dev->dev); - return; - } -#endif - - for (i = 0; i < ttm->num_pages; i++) { - if (ttm_dma->dma_address[i]) { - pci_unmap_page(dev->pdev, ttm_dma->dma_address[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - } - } - - ttm_pool_unpopulate(ttm); -} - -struct ttm_bo_driver nouveau_bo_driver = { - .ttm_tt_create = &nouveau_ttm_tt_create, - .ttm_tt_populate = &nouveau_ttm_tt_populate, - .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate, - .invalidate_caches = nouveau_bo_invalidate_caches, - .init_mem_type = nouveau_bo_init_mem_type, - .evict_flags = nouveau_bo_evict_flags, - .move_notify = nouveau_bo_move_ntfy, - .move = nouveau_bo_move, - .verify_access = nouveau_bo_verify_access, - .sync_obj_signaled = __nouveau_fence_signalled, - .sync_obj_wait = __nouveau_fence_wait, - .sync_obj_flush = __nouveau_fence_flush, - .sync_obj_unref = __nouveau_fence_unref, - .sync_obj_ref = __nouveau_fence_ref, - .fault_reserve_notify = &nouveau_ttm_fault_reserve_notify, - .io_mem_reserve = &nouveau_ttm_io_mem_reserve, - .io_mem_free = &nouveau_ttm_io_mem_free, -}; - -struct nouveau_vma * -nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nouveau_vm *vm) -{ - struct nouveau_vma *vma; - list_for_each_entry(vma, &nvbo->vma_list, head) { - if (vma->vm == vm) - return vma; - } - - return NULL; -} - -int -nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm, - struct nouveau_vma *vma) -{ - const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT; - struct nouveau_mem *node = nvbo->bo.mem.mm_node; - int ret; - - ret = nouveau_vm_get(vm, size, nvbo->page_shift, - NV_MEM_ACCESS_RW, vma); - if (ret) - return ret; - - if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) - nouveau_vm_map(vma, nvbo->bo.mem.mm_node); - else - if (nvbo->bo.mem.mem_type == TTM_PL_TT) - nouveau_vm_map_sg(vma, 0, size, node); - - list_add_tail(&vma->head, &nvbo->vma_list); - vma->refcount = 1; - return 0; -} - -void -nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nouveau_vma *vma) -{ - if (vma->node) { - if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM) { - spin_lock(&nvbo->bo.bdev->fence_lock); - ttm_bo_wait(&nvbo->bo, false, false, false); - spin_unlock(&nvbo->bo.bdev->fence_lock); - nouveau_vm_unmap(vma); - } - - nouveau_vm_put(vma); - list_del(&vma->head); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_calc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_calc.c deleted file mode 100644 index dad96cce..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_calc.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 1993-2003 NVIDIA, Corporation - * Copyright 2007-2009 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" - -/****************************************************************************\ -* * -* The video arbitration routines calculate some "magic" numbers. Fixes * -* the snow seen when accessing the framebuffer without it. * -* It just works (I hope). * -* * -\****************************************************************************/ - -struct nv_fifo_info { - int lwm; - int burst; -}; - -struct nv_sim_state { - int pclk_khz; - int mclk_khz; - int nvclk_khz; - int bpp; - int mem_page_miss; - int mem_latency; - int memory_type; - int memory_width; - int two_heads; -}; - -static void -nv04_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb) -{ - int pagemiss, cas, width, bpp; - int nvclks, mclks, pclks, crtpagemiss; - int found, mclk_extra, mclk_loop, cbs, m1, p1; - int mclk_freq, pclk_freq, nvclk_freq; - int us_m, us_n, us_p, crtc_drain_rate; - int cpm_us, us_crt, clwm; - - pclk_freq = arb->pclk_khz; - mclk_freq = arb->mclk_khz; - nvclk_freq = arb->nvclk_khz; - pagemiss = arb->mem_page_miss; - cas = arb->mem_latency; - width = arb->memory_width >> 6; - bpp = arb->bpp; - cbs = 128; - - pclks = 2; - nvclks = 10; - mclks = 13 + cas; - mclk_extra = 3; - found = 0; - - while (!found) { - found = 1; - - mclk_loop = mclks + mclk_extra; - us_m = mclk_loop * 1000 * 1000 / mclk_freq; - us_n = nvclks * 1000 * 1000 / nvclk_freq; - us_p = nvclks * 1000 * 1000 / pclk_freq; - - crtc_drain_rate = pclk_freq * bpp / 8; - crtpagemiss = 2; - crtpagemiss += 1; - cpm_us = crtpagemiss * pagemiss * 1000 * 1000 / mclk_freq; - us_crt = cpm_us + us_m + us_n + us_p; - clwm = us_crt * crtc_drain_rate / (1000 * 1000); - clwm++; - - m1 = clwm + cbs - 512; - p1 = m1 * pclk_freq / mclk_freq; - p1 = p1 * bpp / 8; - if ((p1 < m1 && m1 > 0) || clwm > 519) { - found = !mclk_extra; - mclk_extra--; - } - if (clwm < 384) - clwm = 384; - - fifo->lwm = clwm; - fifo->burst = cbs; - } -} - -static void -nv10_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb) -{ - int fill_rate, drain_rate; - int pclks, nvclks, mclks, xclks; - int pclk_freq, nvclk_freq, mclk_freq; - int fill_lat, extra_lat; - int max_burst_o, max_burst_l; - int fifo_len, min_lwm, max_lwm; - const int burst_lat = 80; /* Maximum allowable latency due - * to the CRTC FIFO burst. (ns) */ - - pclk_freq = arb->pclk_khz; - nvclk_freq = arb->nvclk_khz; - mclk_freq = arb->mclk_khz; - - fill_rate = mclk_freq * arb->memory_width / 8; /* kB/s */ - drain_rate = pclk_freq * arb->bpp / 8; /* kB/s */ - - fifo_len = arb->two_heads ? 1536 : 1024; /* B */ - - /* Fixed FIFO refill latency. */ - - pclks = 4; /* lwm detect. */ - - nvclks = 3 /* lwm -> sync. */ - + 2 /* fbi bus cycles (1 req + 1 busy) */ - + 1 /* 2 edge sync. may be very close to edge so - * just put one. */ - + 1 /* fbi_d_rdv_n */ - + 1 /* Fbi_d_rdata */ - + 1; /* crtfifo load */ - - mclks = 1 /* 2 edge sync. may be very close to edge so - * just put one. */ - + 1 /* arb_hp_req */ - + 5 /* tiling pipeline */ - + 2 /* latency fifo */ - + 2 /* memory request to fbio block */ - + 7; /* data returned from fbio block */ - - /* Need to accumulate 256 bits for read */ - mclks += (arb->memory_type == 0 ? 2 : 1) - * arb->memory_width / 32; - - fill_lat = mclks * 1000 * 1000 / mclk_freq /* minimum mclk latency */ - + nvclks * 1000 * 1000 / nvclk_freq /* nvclk latency */ - + pclks * 1000 * 1000 / pclk_freq; /* pclk latency */ - - /* Conditional FIFO refill latency. */ - - xclks = 2 * arb->mem_page_miss + mclks /* Extra latency due to - * the overlay. */ - + 2 * arb->mem_page_miss /* Extra pagemiss latency. */ - + (arb->bpp == 32 ? 8 : 4); /* Margin of error. */ - - extra_lat = xclks * 1000 * 1000 / mclk_freq; - - if (arb->two_heads) - /* Account for another CRTC. */ - extra_lat += fill_lat + extra_lat + burst_lat; - - /* FIFO burst */ - - /* Max burst not leading to overflows. */ - max_burst_o = (1 + fifo_len - extra_lat * drain_rate / (1000 * 1000)) - * (fill_rate / 1000) / ((fill_rate - drain_rate) / 1000); - fifo->burst = min(max_burst_o, 1024); - - /* Max burst value with an acceptable latency. */ - max_burst_l = burst_lat * fill_rate / (1000 * 1000); - fifo->burst = min(max_burst_l, fifo->burst); - - fifo->burst = rounddown_pow_of_two(fifo->burst); - - /* FIFO low watermark */ - - min_lwm = (fill_lat + extra_lat) * drain_rate / (1000 * 1000) + 1; - max_lwm = fifo_len - fifo->burst - + fill_lat * drain_rate / (1000 * 1000) - + fifo->burst * drain_rate / fill_rate; - - fifo->lwm = min_lwm + 10 * (max_lwm - min_lwm) / 100; /* Empirical. */ -} - -static void -nv04_update_arb(struct drm_device *dev, int VClk, int bpp, - int *burst, int *lwm) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv_fifo_info fifo_data; - struct nv_sim_state sim_data; - int MClk = nouveau_hw_get_clock(dev, PLL_MEMORY); - int NVClk = nouveau_hw_get_clock(dev, PLL_CORE); - uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1); - - sim_data.pclk_khz = VClk; - sim_data.mclk_khz = MClk; - sim_data.nvclk_khz = NVClk; - sim_data.bpp = bpp; - sim_data.two_heads = nv_two_heads(dev); - if ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ || - (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) { - uint32_t type; - - pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type); - - sim_data.memory_type = (type >> 12) & 1; - sim_data.memory_width = 64; - sim_data.mem_latency = 3; - sim_data.mem_page_miss = 10; - } else { - sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1; - sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64; - sim_data.mem_latency = cfg1 & 0xf; - sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1); - } - - if (dev_priv->card_type == NV_04) - nv04_calc_arb(&fifo_data, &sim_data); - else - nv10_calc_arb(&fifo_data, &sim_data); - - *burst = ilog2(fifo_data.burst >> 4); - *lwm = fifo_data.lwm >> 3; -} - -static void -nv20_update_arb(int *burst, int *lwm) -{ - unsigned int fifo_size, burst_size, graphics_lwm; - - fifo_size = 2048; - burst_size = 512; - graphics_lwm = fifo_size - burst_size; - - *burst = ilog2(burst_size >> 5); - *lwm = graphics_lwm >> 3; -} - -void -nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->card_type < NV_20) - nv04_update_arb(dev, vclk, bpp, burst, lwm); - else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ || - (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) { - *burst = 128; - *lwm = 0x0480; - } else - nv20_update_arb(burst, lwm); -} - -static int -getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk, - struct nouveau_pll_vals *bestpv) -{ - /* Find M, N and P for a single stage PLL - * - * Note that some bioses (NV3x) have lookup tables of precomputed MNP - * values, but we're too lazy to use those atm - * - * "clk" parameter in kHz - * returns calculated clock - */ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int cv = dev_priv->vbios.chip_version; - int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq; - int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m; - int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n; - int minU = pll_lim->vco1.min_inputfreq; - int maxU = pll_lim->vco1.max_inputfreq; - int minP = pll_lim->max_p ? pll_lim->min_p : 0; - int maxP = pll_lim->max_p ? pll_lim->max_p : pll_lim->max_usable_log2p; - int crystal = pll_lim->refclk; - int M, N, thisP, P; - int clkP, calcclk; - int delta, bestdelta = INT_MAX; - int bestclk = 0; - - /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */ - /* possibly correlated with introduction of 27MHz crystal */ - if (dev_priv->card_type < NV_50) { - if (cv < 0x17 || cv == 0x1a || cv == 0x20) { - if (clk > 250000) - maxM = 6; - if (clk > 340000) - maxM = 2; - } else if (cv < 0x40) { - if (clk > 150000) - maxM = 6; - if (clk > 200000) - maxM = 4; - if (clk > 340000) - maxM = 2; - } - } - - P = pll_lim->max_p ? maxP : (1 << maxP); - if ((clk * P) < minvco) { - minvco = clk * maxP; - maxvco = minvco * 2; - } - - if (clk + clk/200 > maxvco) /* +0.5% */ - maxvco = clk + clk/200; - - /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */ - for (thisP = minP; thisP <= maxP; thisP++) { - P = pll_lim->max_p ? thisP : (1 << thisP); - clkP = clk * P; - - if (clkP < minvco) - continue; - if (clkP > maxvco) - return bestclk; - - for (M = minM; M <= maxM; M++) { - if (crystal/M < minU) - return bestclk; - if (crystal/M > maxU) - continue; - - /* add crystal/2 to round better */ - N = (clkP * M + crystal/2) / crystal; - - if (N < minN) - continue; - if (N > maxN) - break; - - /* more rounding additions */ - calcclk = ((N * crystal + P/2) / P + M/2) / M; - delta = abs(calcclk - clk); - /* we do an exhaustive search rather than terminating - * on an optimality condition... - */ - if (delta < bestdelta) { - bestdelta = delta; - bestclk = calcclk; - bestpv->N1 = N; - bestpv->M1 = M; - bestpv->log2P = thisP; - if (delta == 0) /* except this one */ - return bestclk; - } - } - } - - return bestclk; -} - -static int -getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk, - struct nouveau_pll_vals *bestpv) -{ - /* Find M, N and P for a two stage PLL - * - * Note that some bioses (NV30+) have lookup tables of precomputed MNP - * values, but we're too lazy to use those atm - * - * "clk" parameter in kHz - * returns calculated clock - */ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chip_version = dev_priv->vbios.chip_version; - int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq; - int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq; - int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq; - int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq; - int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m; - int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n; - int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m; - int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n; - int maxlog2P = pll_lim->max_usable_log2p; - int crystal = pll_lim->refclk; - bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2); - int M1, N1, M2, N2, log2P; - int clkP, calcclk1, calcclk2, calcclkout; - int delta, bestdelta = INT_MAX; - int bestclk = 0; - - int vco2 = (maxvco2 - maxvco2/200) / 2; - for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++) - ; - clkP = clk << log2P; - - if (maxvco2 < clk + clk/200) /* +0.5% */ - maxvco2 = clk + clk/200; - - for (M1 = minM1; M1 <= maxM1; M1++) { - if (crystal/M1 < minU1) - return bestclk; - if (crystal/M1 > maxU1) - continue; - - for (N1 = minN1; N1 <= maxN1; N1++) { - calcclk1 = crystal * N1 / M1; - if (calcclk1 < minvco1) - continue; - if (calcclk1 > maxvco1) - break; - - for (M2 = minM2; M2 <= maxM2; M2++) { - if (calcclk1/M2 < minU2) - break; - if (calcclk1/M2 > maxU2) - continue; - - /* add calcclk1/2 to round better */ - N2 = (clkP * M2 + calcclk1/2) / calcclk1; - if (N2 < minN2) - continue; - if (N2 > maxN2) - break; - - if (!fixedgain2) { - if (chip_version < 0x60) - if (N2/M2 < 4 || N2/M2 > 10) - continue; - - calcclk2 = calcclk1 * N2 / M2; - if (calcclk2 < minvco2) - break; - if (calcclk2 > maxvco2) - continue; - } else - calcclk2 = calcclk1; - - calcclkout = calcclk2 >> log2P; - delta = abs(calcclkout - clk); - /* we do an exhaustive search rather than terminating - * on an optimality condition... - */ - if (delta < bestdelta) { - bestdelta = delta; - bestclk = calcclkout; - bestpv->N1 = N1; - bestpv->M1 = M1; - bestpv->N2 = N2; - bestpv->M2 = M2; - bestpv->log2P = log2P; - if (delta == 0) /* except this one */ - return bestclk; - } - } - } - } - - return bestclk; -} - -int -nouveau_calc_pll_mnp(struct drm_device *dev, struct pll_lims *pll_lim, int clk, - struct nouveau_pll_vals *pv) -{ - int outclk; - - if (!pll_lim->vco2.maxfreq) - outclk = getMNP_single(dev, pll_lim, clk, pv); - else - outclk = getMNP_double(dev, pll_lim, clk, pv); - - if (!outclk) - NV_ERROR(dev, "Could not find a compatible set of PLL values\n"); - - return outclk; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_channel.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_channel.c deleted file mode 100644 index 846afb0b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_channel.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright 2005-2006 Stephane Marchesin - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_dma.h" -#include "nouveau_ramht.h" - -static int -nouveau_channel_pushbuf_init(struct nouveau_channel *chan) -{ - u32 mem = nouveau_vram_pushbuf ? TTM_PL_FLAG_VRAM : TTM_PL_FLAG_TT; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int ret; - - /* allocate buffer object */ - ret = nouveau_bo_new(dev, 65536, 0, mem, 0, 0, &chan->pushbuf_bo); - if (ret) - goto out; - - ret = nouveau_bo_pin(chan->pushbuf_bo, mem); - if (ret) - goto out; - - ret = nouveau_bo_map(chan->pushbuf_bo); - if (ret) - goto out; - - /* create DMA object covering the entire memtype where the push - * buffer resides, userspace can submit its own push buffers from - * anywhere within the same memtype. - */ - chan->pushbuf_base = chan->pushbuf_bo->bo.offset; - if (dev_priv->card_type >= NV_50) { - ret = nouveau_bo_vma_add(chan->pushbuf_bo, chan->vm, - &chan->pushbuf_vma); - if (ret) - goto out; - - if (dev_priv->card_type < NV_C0) { - ret = nouveau_gpuobj_dma_new(chan, - NV_CLASS_DMA_IN_MEMORY, 0, - (1ULL << 40), - NV_MEM_ACCESS_RO, - NV_MEM_TARGET_VM, - &chan->pushbuf); - } - chan->pushbuf_base = chan->pushbuf_vma.offset; - } else - if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_TT) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, - dev_priv->gart_info.aper_size, - NV_MEM_ACCESS_RO, - NV_MEM_TARGET_GART, - &chan->pushbuf); - } else - if (dev_priv->card_type != NV_04) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, - dev_priv->fb_available_size, - NV_MEM_ACCESS_RO, - NV_MEM_TARGET_VRAM, - &chan->pushbuf); - } else { - /* NV04 cmdbuf hack, from original ddx.. not sure of it's - * exact reason for existing :) PCI access to cmdbuf in - * VRAM. - */ - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - pci_resource_start(dev->pdev, 1), - dev_priv->fb_available_size, - NV_MEM_ACCESS_RO, - NV_MEM_TARGET_PCI, - &chan->pushbuf); - } - -out: - if (ret) { - NV_ERROR(dev, "error initialising pushbuf: %d\n", ret); - nouveau_bo_vma_del(chan->pushbuf_bo, &chan->pushbuf_vma); - nouveau_gpuobj_ref(NULL, &chan->pushbuf); - if (chan->pushbuf_bo) { - nouveau_bo_unmap(chan->pushbuf_bo); - nouveau_bo_ref(NULL, &chan->pushbuf_bo); - } - } - - return 0; -} - -/* allocates and initializes a fifo for user space consumption */ -int -nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, - struct drm_file *file_priv, - uint32_t vram_handle, uint32_t gart_handle) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); - struct nouveau_channel *chan; - unsigned long flags; - int ret, i; - - /* allocate and lock channel structure */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) - return -ENOMEM; - chan->dev = dev; - chan->file_priv = file_priv; - chan->vram_handle = vram_handle; - chan->gart_handle = gart_handle; - - kref_init(&chan->ref); - atomic_set(&chan->users, 1); - mutex_init(&chan->mutex); - mutex_lock(&chan->mutex); - - /* allocate hw channel id */ - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (chan->id = 0; chan->id < pfifo->channels; chan->id++) { - if (!dev_priv->channels.ptr[chan->id]) { - nouveau_channel_ref(chan, &dev_priv->channels.ptr[chan->id]); - break; - } - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - - if (chan->id == pfifo->channels) { - mutex_unlock(&chan->mutex); - kfree(chan); - return -ENODEV; - } - - NV_DEBUG(dev, "initialising channel %d\n", chan->id); - INIT_LIST_HEAD(&chan->nvsw.vbl_wait); - INIT_LIST_HEAD(&chan->nvsw.flip); - INIT_LIST_HEAD(&chan->fence.pending); - spin_lock_init(&chan->fence.lock); - - /* setup channel's memory and vm */ - ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); - if (ret) { - NV_ERROR(dev, "gpuobj %d\n", ret); - nouveau_channel_put(&chan); - return ret; - } - - /* Allocate space for per-channel fixed notifier memory */ - ret = nouveau_notifier_init_channel(chan); - if (ret) { - NV_ERROR(dev, "ntfy %d\n", ret); - nouveau_channel_put(&chan); - return ret; - } - - /* Allocate DMA push buffer */ - ret = nouveau_channel_pushbuf_init(chan); - if (ret) { - NV_ERROR(dev, "pushbuf %d\n", ret); - nouveau_channel_put(&chan); - return ret; - } - - nouveau_dma_init(chan); - chan->user_put = 0x40; - chan->user_get = 0x44; - if (dev_priv->card_type >= NV_50) - chan->user_get_hi = 0x60; - - /* disable the fifo caches */ - pfifo->reassign(dev, false); - - /* Construct initial RAMFC for new channel */ - ret = pfifo->create_context(chan); - if (ret) { - nouveau_channel_put(&chan); - return ret; - } - - pfifo->reassign(dev, true); - - /* Insert NOPs for NOUVEAU_DMA_SKIPS */ - ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); - if (ret) { - nouveau_channel_put(&chan); - return ret; - } - - for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) - OUT_RING (chan, 0x00000000); - FIRE_RING(chan); - - ret = nouveau_fence_channel_init(chan); - if (ret) { - nouveau_channel_put(&chan); - return ret; - } - - nouveau_debugfs_channel_init(chan); - - NV_DEBUG(dev, "channel %d initialised\n", chan->id); - if (fpriv) { - spin_lock(&fpriv->lock); - list_add(&chan->list, &fpriv->channels); - spin_unlock(&fpriv->lock); - } - *chan_ret = chan; - return 0; -} - -struct nouveau_channel * -nouveau_channel_get_unlocked(struct nouveau_channel *ref) -{ - struct nouveau_channel *chan = NULL; - - if (likely(ref && atomic_inc_not_zero(&ref->users))) - nouveau_channel_ref(ref, &chan); - - return chan; -} - -struct nouveau_channel * -nouveau_channel_get(struct drm_file *file_priv, int id) -{ - struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); - struct nouveau_channel *chan; - - spin_lock(&fpriv->lock); - list_for_each_entry(chan, &fpriv->channels, list) { - if (chan->id == id) { - chan = nouveau_channel_get_unlocked(chan); - spin_unlock(&fpriv->lock); - mutex_lock(&chan->mutex); - return chan; - } - } - spin_unlock(&fpriv->lock); - - return ERR_PTR(-EINVAL); -} - -void -nouveau_channel_put_unlocked(struct nouveau_channel **pchan) -{ - struct nouveau_channel *chan = *pchan; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - unsigned long flags; - int i; - - /* decrement the refcount, and we're done if there's still refs */ - if (likely(!atomic_dec_and_test(&chan->users))) { - nouveau_channel_ref(NULL, pchan); - return; - } - - /* no one wants the channel anymore */ - NV_DEBUG(dev, "freeing channel %d\n", chan->id); - nouveau_debugfs_channel_fini(chan); - - /* give it chance to idle */ - nouveau_channel_idle(chan); - - /* ensure all outstanding fences are signaled. they should be if the - * above attempts at idling were OK, but if we failed this'll tell TTM - * we're done with the buffers. - */ - nouveau_fence_channel_fini(chan); - - /* boot it off the hardware */ - pfifo->reassign(dev, false); - - /* destroy the engine specific contexts */ - pfifo->destroy_context(chan); - for (i = 0; i < NVOBJ_ENGINE_NR; i++) { - if (chan->engctx[i]) - dev_priv->eng[i]->context_del(chan, i); - } - - pfifo->reassign(dev, true); - - /* aside from its resources, the channel should now be dead, - * remove it from the channel list - */ - spin_lock_irqsave(&dev_priv->channels.lock, flags); - nouveau_channel_ref(NULL, &dev_priv->channels.ptr[chan->id]); - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - - /* destroy any resources the channel owned */ - nouveau_gpuobj_ref(NULL, &chan->pushbuf); - if (chan->pushbuf_bo) { - nouveau_bo_vma_del(chan->pushbuf_bo, &chan->pushbuf_vma); - nouveau_bo_unmap(chan->pushbuf_bo); - nouveau_bo_unpin(chan->pushbuf_bo); - nouveau_bo_ref(NULL, &chan->pushbuf_bo); - } - nouveau_ramht_ref(NULL, &chan->ramht, chan); - nouveau_notifier_takedown_channel(chan); - nouveau_gpuobj_channel_takedown(chan); - - nouveau_channel_ref(NULL, pchan); -} - -void -nouveau_channel_put(struct nouveau_channel **pchan) -{ - mutex_unlock(&(*pchan)->mutex); - nouveau_channel_put_unlocked(pchan); -} - -static void -nouveau_channel_del(struct kref *ref) -{ - struct nouveau_channel *chan = - container_of(ref, struct nouveau_channel, ref); - - kfree(chan); -} - -void -nouveau_channel_ref(struct nouveau_channel *chan, - struct nouveau_channel **pchan) -{ - if (chan) - kref_get(&chan->ref); - - if (*pchan) - kref_put(&(*pchan)->ref, nouveau_channel_del); - - *pchan = chan; -} - -void -nouveau_channel_idle(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct nouveau_fence *fence = NULL; - int ret; - - nouveau_fence_update(chan); - - if (chan->fence.sequence != chan->fence.sequence_ack) { - ret = nouveau_fence_new(chan, &fence, true); - if (!ret) { - ret = nouveau_fence_wait(fence, false, false); - nouveau_fence_unref(&fence); - } - - if (ret) - NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); - } -} - -/* cleans up all the fifos from file_priv */ -void -nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - struct nouveau_channel *chan; - int i; - - NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); - for (i = 0; i < engine->fifo.channels; i++) { - chan = nouveau_channel_get(file_priv, i); - if (IS_ERR(chan)) - continue; - - list_del(&chan->list); - atomic_dec(&chan->users); - nouveau_channel_put(&chan); - } -} - - -/*********************************** - * ioctls wrapping the functions - ***********************************/ - -static int -nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_channel_alloc *init = data; - struct nouveau_channel *chan; - int ret; - - if (!dev_priv->eng[NVOBJ_ENGINE_GR]) - return -ENODEV; - - if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) - return -EINVAL; - - ret = nouveau_channel_alloc(dev, &chan, file_priv, - init->fb_ctxdma_handle, - init->tt_ctxdma_handle); - if (ret) - return ret; - init->channel = chan->id; - - if (nouveau_vram_pushbuf == 0) { - if (chan->dma.ib_max) - init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | - NOUVEAU_GEM_DOMAIN_GART; - else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM) - init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; - else - init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; - } else { - init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; - } - - if (dev_priv->card_type < NV_C0) { - init->subchan[0].handle = 0x00000000; - init->subchan[0].grclass = 0x0000; - init->subchan[1].handle = NvSw; - init->subchan[1].grclass = NV_SW; - init->nr_subchan = 2; - } - - /* Named memory object area */ - ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, - &init->notifier_handle); - - if (ret == 0) - atomic_inc(&chan->users); /* userspace reference */ - nouveau_channel_put(&chan); - return ret; -} - -static int -nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_channel_free *req = data; - struct nouveau_channel *chan; - - chan = nouveau_channel_get(file_priv, req->channel); - if (IS_ERR(chan)) - return PTR_ERR(chan); - - list_del(&chan->list); - atomic_dec(&chan->users); - nouveau_channel_put(&chan); - return 0; -} - -/*********************************** - * finally, the ioctl table - ***********************************/ - -struct drm_ioctl_desc nouveau_ioctls[] = { - DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH), -}; - -int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.c deleted file mode 100644 index 7b11edb0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include - -#include "drmP.h" -#include "drm_edid.h" -#include "drm_crtc_helper.h" - -#include "nouveau_reg.h" -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" -#include "nouveau_connector.h" -#include "nouveau_gpio.h" -#include "nouveau_hw.h" - -static void nouveau_connector_hotplug(void *, int); - -struct nouveau_encoder * -find_encoder(struct drm_connector *connector, int type) -{ - struct drm_device *dev = connector->dev; - struct nouveau_encoder *nv_encoder; - struct drm_mode_object *obj; - int i, id; - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - id = connector->encoder_ids[i]; - if (!id) - break; - - obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - nv_encoder = nouveau_encoder(obj_to_encoder(obj)); - - if (type == OUTPUT_ANY || nv_encoder->dcb->type == type) - return nv_encoder; - } - - return NULL; -} - -struct nouveau_connector * -nouveau_encoder_connector_get(struct nouveau_encoder *encoder) -{ - struct drm_device *dev = to_drm_encoder(encoder)->dev; - struct drm_connector *drm_connector; - - list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { - if (drm_connector->encoder == to_drm_encoder(encoder)) - return nouveau_connector(drm_connector); - } - - return NULL; -} - -static void -nouveau_connector_destroy(struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct drm_nouveau_private *dev_priv; - struct drm_device *dev; - - if (!nv_connector) - return; - - dev = nv_connector->base.dev; - dev_priv = dev->dev_private; - NV_DEBUG_KMS(dev, "\n"); - - if (nv_connector->hpd != DCB_GPIO_UNUSED) { - nouveau_gpio_isr_del(dev, 0, nv_connector->hpd, 0xff, - nouveau_connector_hotplug, connector); - } - - kfree(nv_connector->edid); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static struct nouveau_i2c_chan * -nouveau_connector_ddc_detect(struct drm_connector *connector, - struct nouveau_encoder **pnv_encoder) -{ - struct drm_device *dev = connector->dev; - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - struct nouveau_i2c_chan *i2c = NULL; - struct nouveau_encoder *nv_encoder; - struct drm_mode_object *obj; - int id; - - id = connector->encoder_ids[i]; - if (!id) - break; - - obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - nv_encoder = nouveau_encoder(obj_to_encoder(obj)); - - if (nv_encoder->dcb->i2c_index < 0xf) - i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); - - if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { - *pnv_encoder = nv_encoder; - return i2c; - } - } - - return NULL; -} - -static struct nouveau_encoder * -nouveau_connector_of_detect(struct drm_connector *connector) -{ -#ifdef __powerpc__ - struct drm_device *dev = connector->dev; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder; - struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev); - - if (!dn || - !((nv_encoder = find_encoder(connector, OUTPUT_TMDS)) || - (nv_encoder = find_encoder(connector, OUTPUT_ANALOG)))) - return NULL; - - for_each_child_of_node(dn, cn) { - const char *name = of_get_property(cn, "name", NULL); - const void *edid = of_get_property(cn, "EDID", NULL); - int idx = name ? name[strlen(name) - 1] - 'A' : 0; - - if (nv_encoder->dcb->i2c_index == idx && edid) { - nv_connector->edid = - kmemdup(edid, EDID_LENGTH, GFP_KERNEL); - of_node_put(cn); - return nv_encoder; - } - } -#endif - return NULL; -} - -static void -nouveau_connector_set_encoder(struct drm_connector *connector, - struct nouveau_encoder *nv_encoder) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; - struct drm_device *dev = connector->dev; - - if (nv_connector->detected_encoder == nv_encoder) - return; - nv_connector->detected_encoder = nv_encoder; - - if (dev_priv->card_type >= NV_50) { - connector->interlace_allowed = true; - connector->doublescan_allowed = true; - } else - if (nv_encoder->dcb->type == OUTPUT_LVDS || - nv_encoder->dcb->type == OUTPUT_TMDS) { - connector->doublescan_allowed = false; - connector->interlace_allowed = false; - } else { - connector->doublescan_allowed = true; - if (dev_priv->card_type == NV_20 || - (dev_priv->card_type == NV_10 && - (dev->pci_device & 0x0ff0) != 0x0100 && - (dev->pci_device & 0x0ff0) != 0x0150)) - /* HW is broken */ - connector->interlace_allowed = false; - else - connector->interlace_allowed = true; - } - - if (nv_connector->type == DCB_CONNECTOR_DVI_I) { - drm_connector_property_set_value(connector, - dev->mode_config.dvi_i_subconnector_property, - nv_encoder->dcb->type == OUTPUT_TMDS ? - DRM_MODE_SUBCONNECTOR_DVID : - DRM_MODE_SUBCONNECTOR_DVIA); - } -} - -static enum drm_connector_status -nouveau_connector_detect(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder = NULL; - struct nouveau_encoder *nv_partner; - struct nouveau_i2c_chan *i2c; - int type; - - /* Cleanup the previous EDID block. */ - if (nv_connector->edid) { - drm_mode_connector_update_edid_property(connector, NULL); - kfree(nv_connector->edid); - nv_connector->edid = NULL; - } - - i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); - if (i2c) { - nv_connector->edid = drm_get_edid(connector, &i2c->adapter); - drm_mode_connector_update_edid_property(connector, - nv_connector->edid); - if (!nv_connector->edid) { - NV_ERROR(dev, "DDC responded, but no EDID for %s\n", - drm_get_connector_name(connector)); - goto detect_analog; - } - - if (nv_encoder->dcb->type == OUTPUT_DP && - !nouveau_dp_detect(to_drm_encoder(nv_encoder))) { - NV_ERROR(dev, "Detected %s, but failed init\n", - drm_get_connector_name(connector)); - return connector_status_disconnected; - } - - /* Override encoder type for DVI-I based on whether EDID - * says the display is digital or analog, both use the - * same i2c channel so the value returned from ddc_detect - * isn't necessarily correct. - */ - nv_partner = NULL; - if (nv_encoder->dcb->type == OUTPUT_TMDS) - nv_partner = find_encoder(connector, OUTPUT_ANALOG); - if (nv_encoder->dcb->type == OUTPUT_ANALOG) - nv_partner = find_encoder(connector, OUTPUT_TMDS); - - if (nv_partner && ((nv_encoder->dcb->type == OUTPUT_ANALOG && - nv_partner->dcb->type == OUTPUT_TMDS) || - (nv_encoder->dcb->type == OUTPUT_TMDS && - nv_partner->dcb->type == OUTPUT_ANALOG))) { - if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) - type = OUTPUT_TMDS; - else - type = OUTPUT_ANALOG; - - nv_encoder = find_encoder(connector, type); - } - - nouveau_connector_set_encoder(connector, nv_encoder); - return connector_status_connected; - } - - nv_encoder = nouveau_connector_of_detect(connector); - if (nv_encoder) { - nouveau_connector_set_encoder(connector, nv_encoder); - return connector_status_connected; - } - -detect_analog: - nv_encoder = find_encoder(connector, OUTPUT_ANALOG); - if (!nv_encoder && !nouveau_tv_disable) - nv_encoder = find_encoder(connector, OUTPUT_TV); - if (nv_encoder && force) { - struct drm_encoder *encoder = to_drm_encoder(nv_encoder); - struct drm_encoder_helper_funcs *helper = - encoder->helper_private; - - if (helper->detect(encoder, connector) == - connector_status_connected) { - nouveau_connector_set_encoder(connector, nv_encoder); - return connector_status_connected; - } - - } - - return connector_status_disconnected; -} - -static enum drm_connector_status -nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder = NULL; - enum drm_connector_status status = connector_status_disconnected; - - /* Cleanup the previous EDID block. */ - if (nv_connector->edid) { - drm_mode_connector_update_edid_property(connector, NULL); - kfree(nv_connector->edid); - nv_connector->edid = NULL; - } - - nv_encoder = find_encoder(connector, OUTPUT_LVDS); - if (!nv_encoder) - return connector_status_disconnected; - - /* Try retrieving EDID via DDC */ - if (!dev_priv->vbios.fp_no_ddc) { - status = nouveau_connector_detect(connector, force); - if (status == connector_status_connected) - goto out; - } - - /* On some laptops (Sony, i'm looking at you) there appears to - * be no direct way of accessing the panel's EDID. The only - * option available to us appears to be to ask ACPI for help.. - * - * It's important this check's before trying straps, one of the - * said manufacturer's laptops are configured in such a way - * the nouveau decides an entry in the VBIOS FP mode table is - * valid - it's not (rh#613284) - */ - if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { - if (!nouveau_acpi_edid(dev, connector)) { - status = connector_status_connected; - goto out; - } - } - - /* If no EDID found above, and the VBIOS indicates a hardcoded - * modeline is avalilable for the panel, set it as the panel's - * native mode and exit. - */ - if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc || - nv_encoder->dcb->lvdsconf.use_straps_for_mode)) { - status = connector_status_connected; - goto out; - } - - /* Still nothing, some VBIOS images have a hardcoded EDID block - * stored for the panel stored in them. - */ - if (!dev_priv->vbios.fp_no_ddc) { - struct edid *edid = - (struct edid *)nouveau_bios_embedded_edid(dev); - if (edid) { - nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - *(nv_connector->edid) = *edid; - status = connector_status_connected; - } - } - -out: -#if defined(CONFIG_ACPI_BUTTON) || \ - (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) - if (status == connector_status_connected && - !nouveau_ignorelid && !acpi_lid_open()) - status = connector_status_unknown; -#endif - - drm_mode_connector_update_edid_property(connector, nv_connector->edid); - nouveau_connector_set_encoder(connector, nv_encoder); - return status; -} - -static void -nouveau_connector_force(struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder; - int type; - - if (nv_connector->type == DCB_CONNECTOR_DVI_I) { - if (connector->force == DRM_FORCE_ON_DIGITAL) - type = OUTPUT_TMDS; - else - type = OUTPUT_ANALOG; - } else - type = OUTPUT_ANY; - - nv_encoder = find_encoder(connector, type); - if (!nv_encoder) { - NV_ERROR(connector->dev, "can't find encoder to force %s on!\n", - drm_get_connector_name(connector)); - connector->status = connector_status_disconnected; - return; - } - - nouveau_connector_set_encoder(connector, nv_encoder); -} - -static int -nouveau_connector_set_property(struct drm_connector *connector, - struct drm_property *property, uint64_t value) -{ - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; - struct nouveau_display_engine *disp = &dev_priv->engine.display; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; - struct drm_encoder *encoder = to_drm_encoder(nv_encoder); - struct drm_device *dev = connector->dev; - struct nouveau_crtc *nv_crtc; - int ret; - - nv_crtc = NULL; - if (connector->encoder && connector->encoder->crtc) - nv_crtc = nouveau_crtc(connector->encoder->crtc); - - /* Scaling mode */ - if (property == dev->mode_config.scaling_mode_property) { - bool modeset = false; - - switch (value) { - case DRM_MODE_SCALE_NONE: - case DRM_MODE_SCALE_FULLSCREEN: - case DRM_MODE_SCALE_CENTER: - case DRM_MODE_SCALE_ASPECT: - break; - default: - return -EINVAL; - } - - /* LVDS always needs gpu scaling */ - if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && - value == DRM_MODE_SCALE_NONE) - return -EINVAL; - - /* Changing between GPU and panel scaling requires a full - * modeset - */ - if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) || - (value == DRM_MODE_SCALE_NONE)) - modeset = true; - nv_connector->scaling_mode = value; - - if (!nv_crtc) - return 0; - - if (modeset || !nv_crtc->set_scale) { - ret = drm_crtc_helper_set_mode(&nv_crtc->base, - &nv_crtc->base.mode, - nv_crtc->base.x, - nv_crtc->base.y, NULL); - if (!ret) - return -EINVAL; - } else { - ret = nv_crtc->set_scale(nv_crtc, true); - if (ret) - return ret; - } - - return 0; - } - - /* Underscan */ - if (property == disp->underscan_property) { - if (nv_connector->underscan != value) { - nv_connector->underscan = value; - if (!nv_crtc || !nv_crtc->set_scale) - return 0; - - return nv_crtc->set_scale(nv_crtc, true); - } - - return 0; - } - - if (property == disp->underscan_hborder_property) { - if (nv_connector->underscan_hborder != value) { - nv_connector->underscan_hborder = value; - if (!nv_crtc || !nv_crtc->set_scale) - return 0; - - return nv_crtc->set_scale(nv_crtc, true); - } - - return 0; - } - - if (property == disp->underscan_vborder_property) { - if (nv_connector->underscan_vborder != value) { - nv_connector->underscan_vborder = value; - if (!nv_crtc || !nv_crtc->set_scale) - return 0; - - return nv_crtc->set_scale(nv_crtc, true); - } - - return 0; - } - - /* Dithering */ - if (property == disp->dithering_mode) { - nv_connector->dithering_mode = value; - if (!nv_crtc || !nv_crtc->set_dither) - return 0; - - return nv_crtc->set_dither(nv_crtc, true); - } - - if (property == disp->dithering_depth) { - nv_connector->dithering_depth = value; - if (!nv_crtc || !nv_crtc->set_dither) - return 0; - - return nv_crtc->set_dither(nv_crtc, true); - } - - if (nv_crtc && nv_crtc->set_color_vibrance) { - /* Hue */ - if (property == disp->vibrant_hue_property) { - nv_crtc->vibrant_hue = value - 90; - return nv_crtc->set_color_vibrance(nv_crtc, true); - } - /* Saturation */ - if (property == disp->color_vibrance_property) { - nv_crtc->color_vibrance = value - 100; - return nv_crtc->set_color_vibrance(nv_crtc, true); - } - } - - if (nv_encoder && nv_encoder->dcb->type == OUTPUT_TV) - return get_slave_funcs(encoder)->set_property( - encoder, connector, property, value); - - return -EINVAL; -} - -static struct drm_display_mode * -nouveau_connector_native_mode(struct drm_connector *connector) -{ - struct drm_connector_helper_funcs *helper = connector->helper_private; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct drm_device *dev = connector->dev; - struct drm_display_mode *mode, *largest = NULL; - int high_w = 0, high_h = 0, high_v = 0; - - list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { - mode->vrefresh = drm_mode_vrefresh(mode); - if (helper->mode_valid(connector, mode) != MODE_OK || - (mode->flags & DRM_MODE_FLAG_INTERLACE)) - continue; - - /* Use preferred mode if there is one.. */ - if (mode->type & DRM_MODE_TYPE_PREFERRED) { - NV_DEBUG_KMS(dev, "native mode from preferred\n"); - return drm_mode_duplicate(dev, mode); - } - - /* Otherwise, take the resolution with the largest width, then - * height, then vertical refresh - */ - if (mode->hdisplay < high_w) - continue; - - if (mode->hdisplay == high_w && mode->vdisplay < high_h) - continue; - - if (mode->hdisplay == high_w && mode->vdisplay == high_h && - mode->vrefresh < high_v) - continue; - - high_w = mode->hdisplay; - high_h = mode->vdisplay; - high_v = mode->vrefresh; - largest = mode; - } - - NV_DEBUG_KMS(dev, "native mode from largest: %dx%d@%d\n", - high_w, high_h, high_v); - return largest ? drm_mode_duplicate(dev, largest) : NULL; -} - -struct moderec { - int hdisplay; - int vdisplay; -}; - -static struct moderec scaler_modes[] = { - { 1920, 1200 }, - { 1920, 1080 }, - { 1680, 1050 }, - { 1600, 1200 }, - { 1400, 1050 }, - { 1280, 1024 }, - { 1280, 960 }, - { 1152, 864 }, - { 1024, 768 }, - { 800, 600 }, - { 720, 400 }, - { 640, 480 }, - { 640, 400 }, - { 640, 350 }, - {} -}; - -static int -nouveau_connector_scaler_modes_add(struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct drm_display_mode *native = nv_connector->native_mode, *m; - struct drm_device *dev = connector->dev; - struct moderec *mode = &scaler_modes[0]; - int modes = 0; - - if (!native) - return 0; - - while (mode->hdisplay) { - if (mode->hdisplay <= native->hdisplay && - mode->vdisplay <= native->vdisplay) { - m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay, - drm_mode_vrefresh(native), false, - false, false); - if (!m) - continue; - - m->type |= DRM_MODE_TYPE_DRIVER; - - drm_mode_probed_add(connector, m); - modes++; - } - - mode++; - } - - return modes; -} - -static void -nouveau_connector_detect_depth(struct drm_connector *connector) -{ - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; - struct nvbios *bios = &dev_priv->vbios; - struct drm_display_mode *mode = nv_connector->native_mode; - bool duallink; - - /* if the edid is feeling nice enough to provide this info, use it */ - if (nv_connector->edid && connector->display_info.bpc) - return; - - /* EDID 1.4 is *supposed* to be supported on eDP, but, Apple... */ - if (nv_connector->type == DCB_CONNECTOR_eDP) { - connector->display_info.bpc = 6; - return; - } - - /* we're out of options unless we're LVDS, default to 8bpc */ - if (nv_encoder->dcb->type != OUTPUT_LVDS) { - connector->display_info.bpc = 8; - return; - } - - connector->display_info.bpc = 6; - - /* LVDS: panel straps */ - if (bios->fp_no_ddc) { - if (bios->fp.if_is_24bit) - connector->display_info.bpc = 8; - return; - } - - /* LVDS: DDC panel, need to first determine the number of links to - * know which if_is_24bit flag to check... - */ - if (nv_connector->edid && - nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) - duallink = ((u8 *)nv_connector->edid)[121] == 2; - else - duallink = mode->clock >= bios->fp.duallink_transition_clk; - - if ((!duallink && (bios->fp.strapless_is_24bit & 1)) || - ( duallink && (bios->fp.strapless_is_24bit & 2))) - connector->display_info.bpc = 8; -} - -static int -nouveau_connector_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; - struct drm_encoder *encoder = to_drm_encoder(nv_encoder); - int ret = 0; - - /* destroy the native mode, the attached monitor could have changed. - */ - if (nv_connector->native_mode) { - drm_mode_destroy(dev, nv_connector->native_mode); - nv_connector->native_mode = NULL; - } - - if (nv_connector->edid) - ret = drm_add_edid_modes(connector, nv_connector->edid); - else - if (nv_encoder->dcb->type == OUTPUT_LVDS && - (nv_encoder->dcb->lvdsconf.use_straps_for_mode || - dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { - struct drm_display_mode mode; - - nouveau_bios_fp_mode(dev, &mode); - nv_connector->native_mode = drm_mode_duplicate(dev, &mode); - } - - /* Determine display colour depth for everything except LVDS now, - * DP requires this before mode_valid() is called. - */ - if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) - nouveau_connector_detect_depth(connector); - - /* Find the native mode if this is a digital panel, if we didn't - * find any modes through DDC previously add the native mode to - * the list of modes. - */ - if (!nv_connector->native_mode) - nv_connector->native_mode = - nouveau_connector_native_mode(connector); - if (ret == 0 && nv_connector->native_mode) { - struct drm_display_mode *mode; - - mode = drm_mode_duplicate(dev, nv_connector->native_mode); - drm_mode_probed_add(connector, mode); - ret = 1; - } - - /* Determine LVDS colour depth, must happen after determining - * "native" mode as some VBIOS tables require us to use the - * pixel clock as part of the lookup... - */ - if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) - nouveau_connector_detect_depth(connector); - - if (nv_encoder->dcb->type == OUTPUT_TV) - ret = get_slave_funcs(encoder)->get_modes(encoder, connector); - - if (nv_connector->type == DCB_CONNECTOR_LVDS || - nv_connector->type == DCB_CONNECTOR_LVDS_SPWG || - nv_connector->type == DCB_CONNECTOR_eDP) - ret += nouveau_connector_scaler_modes_add(connector); - - return ret; -} - -static unsigned -get_tmds_link_bandwidth(struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct drm_nouveau_private *dev_priv = connector->dev->dev_private; - struct dcb_entry *dcb = nv_connector->detected_encoder->dcb; - - if (dcb->location != DCB_LOC_ON_CHIP || - dev_priv->chipset >= 0x46) - return 165000; - else if (dev_priv->chipset >= 0x40) - return 155000; - else if (dev_priv->chipset >= 0x18) - return 135000; - else - return 112000; -} - -static int -nouveau_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; - struct drm_encoder *encoder = to_drm_encoder(nv_encoder); - unsigned min_clock = 25000, max_clock = min_clock; - unsigned clock = mode->clock; - - switch (nv_encoder->dcb->type) { - case OUTPUT_LVDS: - if (nv_connector->native_mode && - (mode->hdisplay > nv_connector->native_mode->hdisplay || - mode->vdisplay > nv_connector->native_mode->vdisplay)) - return MODE_PANEL; - - min_clock = 0; - max_clock = 400000; - break; - case OUTPUT_TMDS: - max_clock = get_tmds_link_bandwidth(connector); - if (nouveau_duallink && nv_encoder->dcb->duallink_possible) - max_clock *= 2; - break; - case OUTPUT_ANALOG: - max_clock = nv_encoder->dcb->crtconf.maxfreq; - if (!max_clock) - max_clock = 350000; - break; - case OUTPUT_TV: - return get_slave_funcs(encoder)->mode_valid(encoder, mode); - case OUTPUT_DP: - max_clock = nv_encoder->dp.link_nr; - max_clock *= nv_encoder->dp.link_bw; - clock = clock * (connector->display_info.bpc * 3) / 10; - break; - default: - BUG_ON(1); - return MODE_BAD; - } - - if (clock < min_clock) - return MODE_CLOCK_LOW; - - if (clock > max_clock) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static struct drm_encoder * -nouveau_connector_best_encoder(struct drm_connector *connector) -{ - struct nouveau_connector *nv_connector = nouveau_connector(connector); - - if (nv_connector->detected_encoder) - return to_drm_encoder(nv_connector->detected_encoder); - - return NULL; -} - -static const struct drm_connector_helper_funcs -nouveau_connector_helper_funcs = { - .get_modes = nouveau_connector_get_modes, - .mode_valid = nouveau_connector_mode_valid, - .best_encoder = nouveau_connector_best_encoder, -}; - -static const struct drm_connector_funcs -nouveau_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .save = NULL, - .restore = NULL, - .detect = nouveau_connector_detect, - .destroy = nouveau_connector_destroy, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = nouveau_connector_set_property, - .force = nouveau_connector_force -}; - -static const struct drm_connector_funcs -nouveau_connector_funcs_lvds = { - .dpms = drm_helper_connector_dpms, - .save = NULL, - .restore = NULL, - .detect = nouveau_connector_detect_lvds, - .destroy = nouveau_connector_destroy, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = nouveau_connector_set_property, - .force = nouveau_connector_force -}; - -static int -drm_conntype_from_dcb(enum dcb_connector_type dcb) -{ - switch (dcb) { - case DCB_CONNECTOR_VGA : return DRM_MODE_CONNECTOR_VGA; - case DCB_CONNECTOR_TV_0 : - case DCB_CONNECTOR_TV_1 : - case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV; - case DCB_CONNECTOR_DMS59_0 : - case DCB_CONNECTOR_DMS59_1 : - case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII; - case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID; - case DCB_CONNECTOR_LVDS : - case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS; - case DCB_CONNECTOR_DMS59_DP0: - case DCB_CONNECTOR_DMS59_DP1: - case DCB_CONNECTOR_DP : return DRM_MODE_CONNECTOR_DisplayPort; - case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP; - case DCB_CONNECTOR_HDMI_0 : - case DCB_CONNECTOR_HDMI_1 : return DRM_MODE_CONNECTOR_HDMIA; - default: - break; - } - - return DRM_MODE_CONNECTOR_Unknown; -} - -struct drm_connector * -nouveau_connector_create(struct drm_device *dev, int index) -{ - const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_display_engine *disp = &dev_priv->engine.display; - struct nouveau_connector *nv_connector = NULL; - struct drm_connector *connector; - int type, ret = 0; - bool dummy; - - NV_DEBUG_KMS(dev, "\n"); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - nv_connector = nouveau_connector(connector); - if (nv_connector->index == index) - return connector; - } - - nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); - if (!nv_connector) - return ERR_PTR(-ENOMEM); - - connector = &nv_connector->base; - nv_connector->index = index; - - /* attempt to parse vbios connector type and hotplug gpio */ - nv_connector->dcb = dcb_conn(dev, index); - if (nv_connector->dcb) { - static const u8 hpd[16] = { - 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60, - }; - - u32 entry = ROM16(nv_connector->dcb[0]); - if (dcb_conntab(dev)[3] >= 4) - entry |= (u32)ROM16(nv_connector->dcb[2]) << 16; - - nv_connector->hpd = ffs((entry & 0x07033000) >> 12); - nv_connector->hpd = hpd[nv_connector->hpd]; - - nv_connector->type = nv_connector->dcb[0]; - if (drm_conntype_from_dcb(nv_connector->type) == - DRM_MODE_CONNECTOR_Unknown) { - NV_WARN(dev, "unknown connector type %02x\n", - nv_connector->type); - nv_connector->type = DCB_CONNECTOR_NONE; - } - - /* Gigabyte NX85T */ - if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { - if (nv_connector->type == DCB_CONNECTOR_HDMI_1) - nv_connector->type = DCB_CONNECTOR_DVI_I; - } - - /* Gigabyte GV-NX86T512H */ - if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) { - if (nv_connector->type == DCB_CONNECTOR_HDMI_1) - nv_connector->type = DCB_CONNECTOR_DVI_I; - } - } else { - nv_connector->type = DCB_CONNECTOR_NONE; - nv_connector->hpd = DCB_GPIO_UNUSED; - } - - /* no vbios data, or an unknown dcb connector type - attempt to - * figure out something suitable ourselves - */ - if (nv_connector->type == DCB_CONNECTOR_NONE) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_table *dcbt = &dev_priv->vbios.dcb; - u32 encoders = 0; - int i; - - for (i = 0; i < dcbt->entries; i++) { - if (dcbt->entry[i].connector == nv_connector->index) - encoders |= (1 << dcbt->entry[i].type); - } - - if (encoders & (1 << OUTPUT_DP)) { - if (encoders & (1 << OUTPUT_TMDS)) - nv_connector->type = DCB_CONNECTOR_DP; - else - nv_connector->type = DCB_CONNECTOR_eDP; - } else - if (encoders & (1 << OUTPUT_TMDS)) { - if (encoders & (1 << OUTPUT_ANALOG)) - nv_connector->type = DCB_CONNECTOR_DVI_I; - else - nv_connector->type = DCB_CONNECTOR_DVI_D; - } else - if (encoders & (1 << OUTPUT_ANALOG)) { - nv_connector->type = DCB_CONNECTOR_VGA; - } else - if (encoders & (1 << OUTPUT_LVDS)) { - nv_connector->type = DCB_CONNECTOR_LVDS; - } else - if (encoders & (1 << OUTPUT_TV)) { - nv_connector->type = DCB_CONNECTOR_TV_0; - } - } - - type = drm_conntype_from_dcb(nv_connector->type); - if (type == DRM_MODE_CONNECTOR_LVDS) { - ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); - if (ret) { - NV_ERROR(dev, "Error parsing LVDS table, disabling\n"); - kfree(nv_connector); - return ERR_PTR(ret); - } - - funcs = &nouveau_connector_funcs_lvds; - } else { - funcs = &nouveau_connector_funcs; - } - - /* defaults, will get overridden in detect() */ - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - - drm_connector_init(dev, connector, funcs, type); - drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); - - /* Init DVI-I specific properties */ - if (nv_connector->type == DCB_CONNECTOR_DVI_I) - drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0); - - /* Add overscan compensation options to digital outputs */ - if (disp->underscan_property && - (type == DRM_MODE_CONNECTOR_DVID || - type == DRM_MODE_CONNECTOR_DVII || - type == DRM_MODE_CONNECTOR_HDMIA || - type == DRM_MODE_CONNECTOR_DisplayPort)) { - drm_connector_attach_property(connector, - disp->underscan_property, - UNDERSCAN_OFF); - drm_connector_attach_property(connector, - disp->underscan_hborder_property, - 0); - drm_connector_attach_property(connector, - disp->underscan_vborder_property, - 0); - } - - /* Add hue and saturation options */ - if (disp->vibrant_hue_property) - drm_connector_attach_property(connector, - disp->vibrant_hue_property, - 90); - if (disp->color_vibrance_property) - drm_connector_attach_property(connector, - disp->color_vibrance_property, - 150); - - switch (nv_connector->type) { - case DCB_CONNECTOR_VGA: - if (dev_priv->card_type >= NV_50) { - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - nv_connector->scaling_mode); - } - /* fall-through */ - case DCB_CONNECTOR_TV_0: - case DCB_CONNECTOR_TV_1: - case DCB_CONNECTOR_TV_3: - nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; - break; - default: - nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; - - drm_connector_attach_property(connector, - dev->mode_config.scaling_mode_property, - nv_connector->scaling_mode); - if (disp->dithering_mode) { - nv_connector->dithering_mode = DITHERING_MODE_AUTO; - drm_connector_attach_property(connector, - disp->dithering_mode, - nv_connector->dithering_mode); - } - if (disp->dithering_depth) { - nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; - drm_connector_attach_property(connector, - disp->dithering_depth, - nv_connector->dithering_depth); - } - break; - } - - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - if (nv_connector->hpd != DCB_GPIO_UNUSED) { - ret = nouveau_gpio_isr_add(dev, 0, nv_connector->hpd, 0xff, - nouveau_connector_hotplug, - connector); - if (ret == 0) - connector->polled = DRM_CONNECTOR_POLL_HPD; - } - - drm_sysfs_connector_add(connector); - return connector; -} - -static void -nouveau_connector_hotplug(void *data, int plugged) -{ - struct drm_connector *connector = data; - struct drm_device *dev = connector->dev; - - NV_DEBUG(dev, "%splugged %s\n", plugged ? "" : "un", - drm_get_connector_name(connector)); - - if (plugged) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - else - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - - drm_helper_hpd_irq_event(dev); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.h deleted file mode 100644 index e4857021..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_connector.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_CONNECTOR_H__ -#define __NOUVEAU_CONNECTOR_H__ - -#include "drm_edid.h" -#include "nouveau_i2c.h" - -enum nouveau_underscan_type { - UNDERSCAN_OFF, - UNDERSCAN_ON, - UNDERSCAN_AUTO, -}; - -/* the enum values specifically defined here match nv50/nvd0 hw values, and - * the code relies on this - */ -enum nouveau_dithering_mode { - DITHERING_MODE_OFF = 0x00, - DITHERING_MODE_ON = 0x01, - DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, - DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, - DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, - DITHERING_MODE_AUTO -}; - -enum nouveau_dithering_depth { - DITHERING_DEPTH_6BPC = 0x00, - DITHERING_DEPTH_8BPC = 0x02, - DITHERING_DEPTH_AUTO -}; - -struct nouveau_connector { - struct drm_connector base; - enum dcb_connector_type type; - u8 index; - u8 *dcb; - u8 hpd; - - int dithering_mode; - int dithering_depth; - int scaling_mode; - enum nouveau_underscan_type underscan; - u32 underscan_hborder; - u32 underscan_vborder; - - struct nouveau_encoder *detected_encoder; - struct edid *edid; - struct drm_display_mode *native_mode; -}; - -static inline struct nouveau_connector *nouveau_connector( - struct drm_connector *con) -{ - return container_of(con, struct nouveau_connector, base); -} - -struct drm_connector * -nouveau_connector_create(struct drm_device *, int index); - -int -nouveau_connector_bpp(struct drm_connector *); - -#endif /* __NOUVEAU_CONNECTOR_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_crtc.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_crtc.h deleted file mode 100644 index e6d0d1eb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_CRTC_H__ -#define __NOUVEAU_CRTC_H__ - -struct nouveau_crtc { - struct drm_crtc base; - - int index; - - uint32_t dpms_saved_fp_control; - uint32_t fp_users; - int saturation; - int color_vibrance; - int vibrant_hue; - int sharpness; - int last_dpms; - - int cursor_saved_x, cursor_saved_y; - - struct { - int cpp; - bool blanked; - uint32_t offset; - uint32_t tile_flags; - } fb; - - struct { - struct nouveau_bo *nvbo; - bool visible; - uint32_t offset; - void (*set_offset)(struct nouveau_crtc *, uint32_t offset); - void (*set_pos)(struct nouveau_crtc *, int x, int y); - void (*hide)(struct nouveau_crtc *, bool update); - void (*show)(struct nouveau_crtc *, bool update); - } cursor; - - struct { - struct nouveau_bo *nvbo; - uint16_t r[256]; - uint16_t g[256]; - uint16_t b[256]; - int depth; - } lut; - - int (*set_dither)(struct nouveau_crtc *crtc, bool update); - int (*set_scale)(struct nouveau_crtc *crtc, bool update); - int (*set_color_vibrance)(struct nouveau_crtc *crtc, bool update); -}; - -static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc) -{ - return container_of(crtc, struct nouveau_crtc, base); -} - -static inline struct drm_crtc *to_drm_crtc(struct nouveau_crtc *crtc) -{ - return &crtc->base; -} - -int nv50_crtc_create(struct drm_device *dev, int index); -int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv, - uint32_t buffer_handle, uint32_t width, - uint32_t height); -int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y); - -int nv04_cursor_init(struct nouveau_crtc *); -int nv50_cursor_init(struct nouveau_crtc *); - -struct nouveau_connector * -nouveau_crtc_connector_get(struct nouveau_crtc *crtc); - -#endif /* __NOUVEAU_CRTC_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_debugfs.c deleted file mode 100644 index fa2ec491..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2009 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* - * Authors: - * Ben Skeggs - */ - -#include - -#include "drmP.h" -#include "nouveau_drv.h" - -#include - -static int -nouveau_debugfs_channel_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct nouveau_channel *chan = node->info_ent->data; - - seq_printf(m, "channel id : %d\n", chan->id); - - seq_printf(m, "cpu fifo state:\n"); - seq_printf(m, " base: 0x%10llx\n", chan->pushbuf_base); - seq_printf(m, " max: 0x%08x\n", chan->dma.max << 2); - seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); - seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2); - seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2); - if (chan->dma.ib_max) { - seq_printf(m, " ib max: 0x%08x\n", chan->dma.ib_max); - seq_printf(m, " ib put: 0x%08x\n", chan->dma.ib_put); - seq_printf(m, " ib free: 0x%08x\n", chan->dma.ib_free); - } - - seq_printf(m, "gpu fifo state:\n"); - seq_printf(m, " get: 0x%08x\n", - nvchan_rd32(chan, chan->user_get)); - seq_printf(m, " put: 0x%08x\n", - nvchan_rd32(chan, chan->user_put)); - if (chan->dma.ib_max) { - seq_printf(m, " ib get: 0x%08x\n", - nvchan_rd32(chan, 0x88)); - seq_printf(m, " ib put: 0x%08x\n", - nvchan_rd32(chan, 0x8c)); - } - - seq_printf(m, "last fence : %d\n", chan->fence.sequence); - seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack); - return 0; -} - -int -nouveau_debugfs_channel_init(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_minor *minor = chan->dev->primary; - int ret; - - if (!dev_priv->debugfs.channel_root) { - dev_priv->debugfs.channel_root = - debugfs_create_dir("channel", minor->debugfs_root); - if (!dev_priv->debugfs.channel_root) - return -ENOENT; - } - - snprintf(chan->debugfs.name, 32, "%d", chan->id); - chan->debugfs.info.name = chan->debugfs.name; - chan->debugfs.info.show = nouveau_debugfs_channel_info; - chan->debugfs.info.driver_features = 0; - chan->debugfs.info.data = chan; - - ret = drm_debugfs_create_files(&chan->debugfs.info, 1, - dev_priv->debugfs.channel_root, - chan->dev->primary); - if (ret == 0) - chan->debugfs.active = true; - return ret; -} - -void -nouveau_debugfs_channel_fini(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - - if (!chan->debugfs.active) - return; - - drm_debugfs_remove_files(&chan->debugfs.info, 1, chan->dev->primary); - chan->debugfs.active = false; - - if (chan == dev_priv->channel) { - debugfs_remove(dev_priv->debugfs.channel_root); - dev_priv->debugfs.channel_root = NULL; - } -} - -static int -nouveau_debugfs_chipset_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_minor *minor = node->minor; - struct drm_device *dev = minor->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t ppci_0; - - ppci_0 = nv_rd32(dev, dev_priv->chipset >= 0x40 ? 0x88000 : 0x1800); - - seq_printf(m, "PMC_BOOT_0: 0x%08x\n", nv_rd32(dev, NV03_PMC_BOOT_0)); - seq_printf(m, "PCI ID : 0x%04x:0x%04x\n", - ppci_0 & 0xffff, ppci_0 >> 16); - return 0; -} - -static int -nouveau_debugfs_memory_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_minor *minor = node->minor; - struct drm_nouveau_private *dev_priv = minor->dev->dev_private; - - seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10)); - return 0; -} - -static int -nouveau_debugfs_vbios_image(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private; - int i; - - for (i = 0; i < dev_priv->vbios.length; i++) - seq_printf(m, "%c", dev_priv->vbios.data[i]); - return 0; -} - -static int -nouveau_debugfs_evict_vram(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private; - int ret; - - ret = ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); - if (ret) - seq_printf(m, "failed: %d", ret); - else - seq_printf(m, "succeeded\n"); - return 0; -} - -static struct drm_info_list nouveau_debugfs_list[] = { - { "evict_vram", nouveau_debugfs_evict_vram, 0, NULL }, - { "chipset", nouveau_debugfs_chipset_info, 0, NULL }, - { "memory", nouveau_debugfs_memory_info, 0, NULL }, - { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, - { "ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL }, - { "ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL }, -}; -#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) - -int -nouveau_debugfs_init(struct drm_minor *minor) -{ - drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES, - minor->debugfs_root, minor); - return 0; -} - -void -nouveau_debugfs_takedown(struct drm_minor *minor) -{ - drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES, - minor); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_display.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_display.c deleted file mode 100644 index a85e1128..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_display.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "nouveau_drv.h" -#include "nouveau_fb.h" -#include "nouveau_fbcon.h" -#include "nouveau_hw.h" -#include "nouveau_crtc.h" -#include "nouveau_dma.h" -#include "nouveau_connector.h" -#include "nouveau_gpio.h" -#include "nv50_display.h" - -static void -nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); - - if (fb->nvbo) - drm_gem_object_unreference_unlocked(fb->nvbo->gem); - - drm_framebuffer_cleanup(drm_fb); - kfree(fb); -} - -static int -nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); - - return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle); -} - -static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { - .destroy = nouveau_user_framebuffer_destroy, - .create_handle = nouveau_user_framebuffer_create_handle, -}; - -int -nouveau_framebuffer_init(struct drm_device *dev, - struct nouveau_framebuffer *nv_fb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct nouveau_bo *nvbo) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_framebuffer *fb = &nv_fb->base; - int ret; - - ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); - if (ret) { - return ret; - } - - drm_helper_mode_fill_fb_struct(fb, mode_cmd); - nv_fb->nvbo = nvbo; - - if (dev_priv->card_type >= NV_50) { - u32 tile_flags = nouveau_bo_tile_layout(nvbo); - if (tile_flags == 0x7a00 || - tile_flags == 0xfe00) - nv_fb->r_dma = NvEvoFB32; - else - if (tile_flags == 0x7000) - nv_fb->r_dma = NvEvoFB16; - else - nv_fb->r_dma = NvEvoVRAM_LP; - - switch (fb->depth) { - case 8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break; - case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break; - case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break; - case 24: - case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break; - case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break; - default: - NV_ERROR(dev, "unknown depth %d\n", fb->depth); - return -EINVAL; - } - - if (dev_priv->chipset == 0x50) - nv_fb->r_format |= (tile_flags << 8); - - if (!tile_flags) { - if (dev_priv->card_type < NV_D0) - nv_fb->r_pitch = 0x00100000 | fb->pitches[0]; - else - nv_fb->r_pitch = 0x01000000 | fb->pitches[0]; - } else { - u32 mode = nvbo->tile_mode; - if (dev_priv->card_type >= NV_C0) - mode >>= 4; - nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode; - } - } - - return 0; -} - -static struct drm_framebuffer * -nouveau_user_framebuffer_create(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct nouveau_framebuffer *nouveau_fb; - struct drm_gem_object *gem; - int ret; - - gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); - if (!gem) - return ERR_PTR(-ENOENT); - - nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); - if (!nouveau_fb) - return ERR_PTR(-ENOMEM); - - ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); - if (ret) { - drm_gem_object_unreference(gem); - return ERR_PTR(ret); - } - - return &nouveau_fb->base; -} - -static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { - .fb_create = nouveau_user_framebuffer_create, - .output_poll_changed = nouveau_fbcon_output_poll_changed, -}; - - -struct nouveau_drm_prop_enum_list { - u8 gen_mask; - int type; - char *name; -}; - -static struct nouveau_drm_prop_enum_list underscan[] = { - { 6, UNDERSCAN_AUTO, "auto" }, - { 6, UNDERSCAN_OFF, "off" }, - { 6, UNDERSCAN_ON, "on" }, - {} -}; - -static struct nouveau_drm_prop_enum_list dither_mode[] = { - { 7, DITHERING_MODE_AUTO, "auto" }, - { 7, DITHERING_MODE_OFF, "off" }, - { 1, DITHERING_MODE_ON, "on" }, - { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, - { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, - { 4, DITHERING_MODE_TEMPORAL, "temporal" }, - {} -}; - -static struct nouveau_drm_prop_enum_list dither_depth[] = { - { 6, DITHERING_DEPTH_AUTO, "auto" }, - { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, - { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, - {} -}; - -#define PROP_ENUM(p,gen,n,list) do { \ - struct nouveau_drm_prop_enum_list *l = (list); \ - int c = 0; \ - while (l->gen_mask) { \ - if (l->gen_mask & (1 << (gen))) \ - c++; \ - l++; \ - } \ - if (c) { \ - p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ - l = (list); \ - c = 0; \ - while (p && l->gen_mask) { \ - if (l->gen_mask & (1 << (gen))) { \ - drm_property_add_enum(p, c, l->type, l->name); \ - c++; \ - } \ - l++; \ - } \ - } \ -} while(0) - -int -nouveau_display_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_display_engine *disp = &dev_priv->engine.display; - struct drm_connector *connector; - int ret; - - ret = disp->init(dev); - if (ret) - return ret; - - /* power on internal panel if it's not already. the init tables of - * some vbios default this to off for some reason, causing the - * panel to not work after resume - */ - if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) { - nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true); - msleep(300); - } - - /* enable polling for external displays */ - drm_kms_helper_poll_enable(dev); - - /* enable hotplug interrupts */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct nouveau_connector *conn = nouveau_connector(connector); - nouveau_gpio_irq(dev, 0, conn->hpd, 0xff, true); - } - - return ret; -} - -void -nouveau_display_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_display_engine *disp = &dev_priv->engine.display; - struct drm_connector *connector; - - /* disable hotplug interrupts */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct nouveau_connector *conn = nouveau_connector(connector); - nouveau_gpio_irq(dev, 0, conn->hpd, 0xff, false); - } - - drm_kms_helper_poll_disable(dev); - disp->fini(dev); -} - -int -nouveau_display_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_display_engine *disp = &dev_priv->engine.display; - int ret, gen; - - drm_mode_config_init(dev); - drm_mode_create_scaling_mode_property(dev); - drm_mode_create_dvi_i_properties(dev); - - if (dev_priv->card_type < NV_50) - gen = 0; - else - if (dev_priv->card_type < NV_D0) - gen = 1; - else - gen = 2; - - PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); - PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); - PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); - - disp->underscan_hborder_property = - drm_property_create_range(dev, 0, "underscan hborder", 0, 128); - - disp->underscan_vborder_property = - drm_property_create_range(dev, 0, "underscan vborder", 0, 128); - - if (gen == 1) { - disp->vibrant_hue_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "vibrant hue", 2); - disp->vibrant_hue_property->values[0] = 0; - disp->vibrant_hue_property->values[1] = 180; /* -90..+90 */ - - disp->color_vibrance_property = - drm_property_create(dev, DRM_MODE_PROP_RANGE, - "color vibrance", 2); - disp->color_vibrance_property->values[0] = 0; - disp->color_vibrance_property->values[1] = 200; /* -100..+100 */ - } - - dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; - dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); - - dev->mode_config.min_width = 0; - dev->mode_config.min_height = 0; - if (dev_priv->card_type < NV_10) { - dev->mode_config.max_width = 2048; - dev->mode_config.max_height = 2048; - } else - if (dev_priv->card_type < NV_50) { - dev->mode_config.max_width = 4096; - dev->mode_config.max_height = 4096; - } else { - dev->mode_config.max_width = 8192; - dev->mode_config.max_height = 8192; - } - - dev->mode_config.preferred_depth = 24; - dev->mode_config.prefer_shadow = 1; - - drm_kms_helper_poll_init(dev); - drm_kms_helper_poll_disable(dev); - - ret = disp->create(dev); - if (ret) - return ret; - - if (dev->mode_config.num_crtc) { - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret) - return ret; - } - - return ret; -} - -void -nouveau_display_destroy(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_display_engine *disp = &dev_priv->engine.display; - - drm_vblank_cleanup(dev); - - disp->destroy(dev); - - drm_kms_helper_poll_fini(dev); - drm_mode_config_cleanup(dev); -} - -int -nouveau_vblank_enable(struct drm_device *dev, int crtc) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->card_type >= NV_50) - nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0, - NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc)); - else - NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, - NV_PCRTC_INTR_0_VBLANK); - - return 0; -} - -void -nouveau_vblank_disable(struct drm_device *dev, int crtc) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->card_type >= NV_50) - nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, - NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0); - else - NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0); -} - -static int -nouveau_page_flip_reserve(struct nouveau_bo *old_bo, - struct nouveau_bo *new_bo) -{ - int ret; - - ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); - if (ret) - return ret; - - ret = ttm_bo_reserve(&new_bo->bo, false, false, false, 0); - if (ret) - goto fail; - - ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); - if (ret) - goto fail_unreserve; - - return 0; - -fail_unreserve: - ttm_bo_unreserve(&new_bo->bo); -fail: - nouveau_bo_unpin(new_bo); - return ret; -} - -static void -nouveau_page_flip_unreserve(struct nouveau_bo *old_bo, - struct nouveau_bo *new_bo, - struct nouveau_fence *fence) -{ - nouveau_bo_fence(new_bo, fence); - ttm_bo_unreserve(&new_bo->bo); - - nouveau_bo_fence(old_bo, fence); - ttm_bo_unreserve(&old_bo->bo); - - nouveau_bo_unpin(old_bo); -} - -static int -nouveau_page_flip_emit(struct nouveau_channel *chan, - struct nouveau_bo *old_bo, - struct nouveau_bo *new_bo, - struct nouveau_page_flip_state *s, - struct nouveau_fence **pfence) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - unsigned long flags; - int ret; - - /* Queue it to the pending list */ - spin_lock_irqsave(&dev->event_lock, flags); - list_add_tail(&s->head, &chan->nvsw.flip); - spin_unlock_irqrestore(&dev->event_lock, flags); - - /* Synchronize with the old framebuffer */ - ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan); - if (ret) - goto fail; - - /* Emit the pageflip */ - ret = RING_SPACE(chan, 3); - if (ret) - goto fail; - - if (dev_priv->card_type < NV_C0) { - BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); - OUT_RING (chan, 0x00000000); - OUT_RING (chan, 0x00000000); - } else { - BEGIN_NVC0(chan, 2, 0, NV10_SUBCHAN_REF_CNT, 1); - OUT_RING (chan, ++chan->fence.sequence); - BEGIN_NVC0(chan, 8, 0, NVSW_SUBCHAN_PAGE_FLIP, 0x0000); - } - FIRE_RING (chan); - - ret = nouveau_fence_new(chan, pfence, true); - if (ret) - goto fail; - - return 0; -fail: - spin_lock_irqsave(&dev->event_lock, flags); - list_del(&s->head); - spin_unlock_irqrestore(&dev->event_lock, flags); - return ret; -} - -int -nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event) -{ - struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; - struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; - struct nouveau_page_flip_state *s; - struct nouveau_channel *chan; - struct nouveau_fence *fence; - int ret; - - if (!dev_priv->channel) - return -ENODEV; - - s = kzalloc(sizeof(*s), GFP_KERNEL); - if (!s) - return -ENOMEM; - - /* Don't let the buffers go away while we flip */ - ret = nouveau_page_flip_reserve(old_bo, new_bo); - if (ret) - goto fail_free; - - /* Initialize a page flip struct */ - *s = (struct nouveau_page_flip_state) - { { }, event, nouveau_crtc(crtc)->index, - fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, - new_bo->bo.offset }; - - /* Choose the channel the flip will be handled in */ - chan = nouveau_fence_channel(new_bo->bo.sync_obj); - if (!chan) - chan = nouveau_channel_get_unlocked(dev_priv->channel); - mutex_lock(&chan->mutex); - - /* Emit a page flip */ - if (dev_priv->card_type >= NV_50) { - if (dev_priv->card_type >= NV_D0) - ret = nvd0_display_flip_next(crtc, fb, chan, 0); - else - ret = nv50_display_flip_next(crtc, fb, chan); - if (ret) { - nouveau_channel_put(&chan); - goto fail_unreserve; - } - } - - ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); - nouveau_channel_put(&chan); - if (ret) - goto fail_unreserve; - - /* Update the crtc struct and cleanup */ - crtc->fb = fb; - - nouveau_page_flip_unreserve(old_bo, new_bo, fence); - nouveau_fence_unref(&fence); - return 0; - -fail_unreserve: - nouveau_page_flip_unreserve(old_bo, new_bo, NULL); -fail_free: - kfree(s); - return ret; -} - -int -nouveau_finish_page_flip(struct nouveau_channel *chan, - struct nouveau_page_flip_state *ps) -{ - struct drm_device *dev = chan->dev; - struct nouveau_page_flip_state *s; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - - if (list_empty(&chan->nvsw.flip)) { - NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id); - spin_unlock_irqrestore(&dev->event_lock, flags); - return -EINVAL; - } - - s = list_first_entry(&chan->nvsw.flip, - struct nouveau_page_flip_state, head); - if (s->event) { - struct drm_pending_vblank_event *e = s->event; - struct timeval now; - - do_gettimeofday(&now); - e->event.sequence = 0; - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - list_add_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - - list_del(&s->head); - if (ps) - *ps = *s; - kfree(s); - - spin_unlock_irqrestore(&dev->event_lock, flags); - return 0; -} - -int -nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - struct nouveau_bo *bo; - int ret; - - args->pitch = roundup(args->width * (args->bpp / 8), 256); - args->size = args->pitch * args->height; - args->size = roundup(args->size, PAGE_SIZE); - - ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); - if (ret) - return ret; - - ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle); - drm_gem_object_unreference_unlocked(bo->gem); - return ret; -} - -int -nouveau_display_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, - uint32_t handle) -{ - return drm_gem_handle_delete(file_priv, handle); -} - -int -nouveau_display_dumb_map_offset(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle, uint64_t *poffset) -{ - struct drm_gem_object *gem; - - gem = drm_gem_object_lookup(dev, file_priv, handle); - if (gem) { - struct nouveau_bo *bo = gem->driver_private; - *poffset = bo->bo.addr_space_offset; - drm_gem_object_unreference_unlocked(gem); - return 0; - } - - return -ENOENT; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.c deleted file mode 100644 index 295932e6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_ramht.h" - -void -nouveau_dma_init(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_bo *pushbuf = chan->pushbuf_bo; - - if (dev_priv->card_type >= NV_50) { - const int ib_size = pushbuf->bo.mem.size / 2; - - chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2; - chan->dma.ib_max = (ib_size / 8) - 1; - chan->dma.ib_put = 0; - chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put; - - chan->dma.max = (pushbuf->bo.mem.size - ib_size) >> 2; - } else { - chan->dma.max = (pushbuf->bo.mem.size >> 2) - 2; - } - - chan->dma.put = 0; - chan->dma.cur = chan->dma.put; - chan->dma.free = chan->dma.max - chan->dma.cur; -} - -void -OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords) -{ - bool is_iomem; - u32 *mem = ttm_kmap_obj_virtual(&chan->pushbuf_bo->kmap, &is_iomem); - mem = &mem[chan->dma.cur]; - if (is_iomem) - memcpy_toio((void __force __iomem *)mem, data, nr_dwords * 4); - else - memcpy(mem, data, nr_dwords * 4); - chan->dma.cur += nr_dwords; -} - -/* Fetch and adjust GPU GET pointer - * - * Returns: - * value >= 0, the adjusted GET pointer - * -EINVAL if GET pointer currently outside main push buffer - * -EBUSY if timeout exceeded - */ -static inline int -READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) -{ - uint64_t val; - - val = nvchan_rd32(chan, chan->user_get); - if (chan->user_get_hi) - val |= (uint64_t)nvchan_rd32(chan, chan->user_get_hi) << 32; - - /* reset counter as long as GET is still advancing, this is - * to avoid misdetecting a GPU lockup if the GPU happens to - * just be processing an operation that takes a long time - */ - if (val != *prev_get) { - *prev_get = val; - *timeout = 0; - } - - if ((++*timeout & 0xff) == 0) { - DRM_UDELAY(1); - if (*timeout > 100000) - return -EBUSY; - } - - if (val < chan->pushbuf_base || - val > chan->pushbuf_base + (chan->dma.max << 2)) - return -EINVAL; - - return (val - chan->pushbuf_base) >> 2; -} - -void -nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, - int delta, int length) -{ - struct nouveau_bo *pb = chan->pushbuf_bo; - struct nouveau_vma *vma; - int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; - u64 offset; - - vma = nouveau_bo_vma_find(bo, chan->vm); - BUG_ON(!vma); - offset = vma->offset + delta; - - BUG_ON(chan->dma.ib_free < 1); - nouveau_bo_wr32(pb, ip++, lower_32_bits(offset)); - nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8); - - chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; - - DRM_MEMORYBARRIER(); - /* Flush writes. */ - nouveau_bo_rd32(pb, 0); - - nvchan_wr32(chan, 0x8c, chan->dma.ib_put); - chan->dma.ib_free--; -} - -static int -nv50_dma_push_wait(struct nouveau_channel *chan, int count) -{ - uint32_t cnt = 0, prev_get = 0; - - while (chan->dma.ib_free < count) { - uint32_t get = nvchan_rd32(chan, 0x88); - if (get != prev_get) { - prev_get = get; - cnt = 0; - } - - if ((++cnt & 0xff) == 0) { - DRM_UDELAY(1); - if (cnt > 100000) - return -EBUSY; - } - - chan->dma.ib_free = get - chan->dma.ib_put; - if (chan->dma.ib_free <= 0) - chan->dma.ib_free += chan->dma.ib_max; - } - - return 0; -} - -static int -nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) -{ - uint64_t prev_get = 0; - int ret, cnt = 0; - - ret = nv50_dma_push_wait(chan, slots + 1); - if (unlikely(ret)) - return ret; - - while (chan->dma.free < count) { - int get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - - return get; - } - - if (get <= chan->dma.cur) { - chan->dma.free = chan->dma.max - chan->dma.cur; - if (chan->dma.free >= count) - break; - - FIRE_RING(chan); - do { - get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get < 0)) { - if (get == -EINVAL) - continue; - return get; - } - } while (get == 0); - chan->dma.cur = 0; - chan->dma.put = 0; - } - - chan->dma.free = get - chan->dma.cur - 1; - } - - return 0; -} - -int -nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) -{ - uint64_t prev_get = 0; - int cnt = 0, get; - - if (chan->dma.ib_max) - return nv50_dma_wait(chan, slots, size); - - while (chan->dma.free < size) { - get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get == -EBUSY)) - return -EBUSY; - - /* loop until we have a usable GET pointer. the value - * we read from the GPU may be outside the main ring if - * PFIFO is processing a buffer called from the main ring, - * discard these values until something sensible is seen. - * - * the other case we discard GET is while the GPU is fetching - * from the SKIPS area, so the code below doesn't have to deal - * with some fun corner cases. - */ - if (unlikely(get == -EINVAL) || get < NOUVEAU_DMA_SKIPS) - continue; - - if (get <= chan->dma.cur) { - /* engine is fetching behind us, or is completely - * idle (GET == PUT) so we have free space up until - * the end of the push buffer - * - * we can only hit that path once per call due to - * looping back to the beginning of the push buffer, - * we'll hit the fetching-ahead-of-us path from that - * point on. - * - * the *one* exception to that rule is if we read - * GET==PUT, in which case the below conditional will - * always succeed and break us out of the wait loop. - */ - chan->dma.free = chan->dma.max - chan->dma.cur; - if (chan->dma.free >= size) - break; - - /* not enough space left at the end of the push buffer, - * instruct the GPU to jump back to the start right - * after processing the currently pending commands. - */ - OUT_RING(chan, chan->pushbuf_base | 0x20000000); - - /* wait for GET to depart from the skips area. - * prevents writing GET==PUT and causing a race - * condition that causes us to think the GPU is - * idle when it's not. - */ - do { - get = READ_GET(chan, &prev_get, &cnt); - if (unlikely(get == -EBUSY)) - return -EBUSY; - if (unlikely(get == -EINVAL)) - continue; - } while (get <= NOUVEAU_DMA_SKIPS); - WRITE_PUT(NOUVEAU_DMA_SKIPS); - - /* we're now submitting commands at the start of - * the push buffer. - */ - chan->dma.cur = - chan->dma.put = NOUVEAU_DMA_SKIPS; - } - - /* engine fetching ahead of us, we have space up until the - * current GET pointer. the "- 1" is to ensure there's - * space left to emit a jump back to the beginning of the - * push buffer if we require it. we can never get GET == PUT - * here, so this is safe. - */ - chan->dma.free = get - chan->dma.cur - 1; - } - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.h deleted file mode 100644 index 23d4edf9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dma.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_DMA_H__ -#define __NOUVEAU_DMA_H__ - -#ifndef NOUVEAU_DMA_DEBUG -#define NOUVEAU_DMA_DEBUG 0 -#endif - -void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *, - int delta, int length); - -/* - * There's a hw race condition where you can't jump to your PUT offset, - * to avoid this we jump to offset + SKIPS and fill the difference with - * NOPs. - * - * xf86-video-nv configures the DMA fetch size to 32 bytes, and uses - * a SKIPS value of 8. Lets assume that the race condition is to do - * with writing into the fetch area, we configure a fetch size of 128 - * bytes so we need a larger SKIPS value. - */ -#define NOUVEAU_DMA_SKIPS (128 / 4) - -/* Hardcoded object assignments to subchannels (subchannel id). */ -enum { - NvSubM2MF = 0, - NvSubSw = 1, - NvSub2D = 2, - NvSubCtxSurf2D = 2, - NvSubGdiRect = 3, - NvSubImageBlit = 4 -}; - -/* Object handles. */ -enum { - NvM2MF = 0x80000001, - NvDmaFB = 0x80000002, - NvDmaTT = 0x80000003, - NvNotify0 = 0x80000006, - Nv2D = 0x80000007, - NvCtxSurf2D = 0x80000008, - NvRop = 0x80000009, - NvImagePatt = 0x8000000a, - NvClipRect = 0x8000000b, - NvGdiRect = 0x8000000c, - NvImageBlit = 0x8000000d, - NvSw = 0x8000000e, - NvSema = 0x8000000f, - NvEvoSema0 = 0x80000010, - NvEvoSema1 = 0x80000011, - - /* G80+ display objects */ - NvEvoVRAM = 0x01000000, - NvEvoFB16 = 0x01000001, - NvEvoFB32 = 0x01000002, - NvEvoVRAM_LP = 0x01000003, - NvEvoSync = 0xcafe0000 -}; - -#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 -#define NV_MEMORY_TO_MEMORY_FORMAT_NAME 0x00000000 -#define NV_MEMORY_TO_MEMORY_FORMAT_SET_REF 0x00000050 -#define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 -#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 -#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE 0x00000000 -#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY_STYLE_WRITE_LE_AWAKEN 0x00000001 -#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 -#define NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE 0x00000184 -#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c - -#define NV50_MEMORY_TO_MEMORY_FORMAT 0x00005039 -#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK200 0x00000200 -#define NV50_MEMORY_TO_MEMORY_FORMAT_UNK21C 0x0000021c -#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH 0x00000238 -#define NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT_HIGH 0x0000023c - -static __must_check inline int -RING_SPACE(struct nouveau_channel *chan, int size) -{ - int ret; - - ret = nouveau_dma_wait(chan, 1, size); - if (ret) - return ret; - - chan->dma.free -= size; - return 0; -} - -static inline void -OUT_RING(struct nouveau_channel *chan, int data) -{ - if (NOUVEAU_DMA_DEBUG) { - NV_INFO(chan->dev, "Ch%d/0x%08x: 0x%08x\n", - chan->id, chan->dma.cur << 2, data); - } - - nouveau_bo_wr32(chan->pushbuf_bo, chan->dma.cur++, data); -} - -extern void -OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords); - -static inline void -BEGIN_NVC0(struct nouveau_channel *chan, int op, int subc, int mthd, int size) -{ - OUT_RING(chan, (op << 28) | (size << 16) | (subc << 13) | (mthd >> 2)); -} - -static inline void -BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size) -{ - OUT_RING(chan, (subc << 13) | (size << 18) | mthd); -} - -#define WRITE_PUT(val) do { \ - DRM_MEMORYBARRIER(); \ - nouveau_bo_rd32(chan->pushbuf_bo, 0); \ - nvchan_wr32(chan, chan->user_put, ((val) << 2) + chan->pushbuf_base); \ -} while (0) - -static inline void -FIRE_RING(struct nouveau_channel *chan) -{ - if (NOUVEAU_DMA_DEBUG) { - NV_INFO(chan->dev, "Ch%d/0x%08x: PUSH!\n", - chan->id, chan->dma.cur << 2); - } - - if (chan->dma.cur == chan->dma.put) - return; - chan->accel_done = true; - - if (chan->dma.ib_max) { - nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2, - (chan->dma.cur - chan->dma.put) << 2); - } else { - WRITE_PUT(chan->dma.cur); - } - - chan->dma.put = chan->dma.cur; -} - -static inline void -WIND_RING(struct nouveau_channel *chan) -{ - chan->dma.cur = chan->dma.put; -} - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dp.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dp.c deleted file mode 100644 index d996134b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_dp.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_i2c.h" -#include "nouveau_connector.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" -#include "nouveau_gpio.h" - -/****************************************************************************** - * aux channel util functions - *****************************************************************************/ -#define AUX_DBG(fmt, args...) do { \ - if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_AUXCH) { \ - NV_PRINTK(KERN_DEBUG, dev, "AUXCH(%d): " fmt, ch, ##args); \ - } \ -} while (0) -#define AUX_ERR(fmt, args...) NV_ERROR(dev, "AUXCH(%d): " fmt, ch, ##args) - -static void -auxch_fini(struct drm_device *dev, int ch) -{ - nv_mask(dev, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000); -} - -static int -auxch_init(struct drm_device *dev, int ch) -{ - const u32 unksel = 1; /* nfi which to use, or if it matters.. */ - const u32 ureq = unksel ? 0x00100000 : 0x00200000; - const u32 urep = unksel ? 0x01000000 : 0x02000000; - u32 ctrl, timeout; - - /* wait up to 1ms for any previous transaction to be done... */ - timeout = 1000; - do { - ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50)); - udelay(1); - if (!timeout--) { - AUX_ERR("begin idle timeout 0x%08x", ctrl); - return -EBUSY; - } - } while (ctrl & 0x03010000); - - /* set some magic, and wait up to 1ms for it to appear */ - nv_mask(dev, 0x00e4e4 + (ch * 0x50), 0x00300000, ureq); - timeout = 1000; - do { - ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50)); - udelay(1); - if (!timeout--) { - AUX_ERR("magic wait 0x%08x\n", ctrl); - auxch_fini(dev, ch); - return -EBUSY; - } - } while ((ctrl & 0x03000000) != urep); - - return 0; -} - -static int -auxch_tx(struct drm_device *dev, int ch, u8 type, u32 addr, u8 *data, u8 size) -{ - u32 ctrl, stat, timeout, retries; - u32 xbuf[4] = {}; - int ret, i; - - AUX_DBG("%d: 0x%08x %d\n", type, addr, size); - - ret = auxch_init(dev, ch); - if (ret) - goto out; - - stat = nv_rd32(dev, 0x00e4e8 + (ch * 0x50)); - if (!(stat & 0x10000000)) { - AUX_DBG("sink not detected\n"); - ret = -ENXIO; - goto out; - } - - if (!(type & 1)) { - memcpy(xbuf, data, size); - for (i = 0; i < 16; i += 4) { - AUX_DBG("wr 0x%08x\n", xbuf[i / 4]); - nv_wr32(dev, 0x00e4c0 + (ch * 0x50) + i, xbuf[i / 4]); - } - } - - ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50)); - ctrl &= ~0x0001f0ff; - ctrl |= type << 12; - ctrl |= size - 1; - nv_wr32(dev, 0x00e4e0 + (ch * 0x50), addr); - - /* retry transaction a number of times on failure... */ - ret = -EREMOTEIO; - for (retries = 0; retries < 32; retries++) { - /* reset, and delay a while if this is a retry */ - nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl); - nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl); - if (retries) - udelay(400); - - /* transaction request, wait up to 1ms for it to complete */ - nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x00010000 | ctrl); - - timeout = 1000; - do { - ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50)); - udelay(1); - if (!timeout--) { - AUX_ERR("tx req timeout 0x%08x\n", ctrl); - goto out; - } - } while (ctrl & 0x00010000); - - /* read status, and check if transaction completed ok */ - stat = nv_mask(dev, 0x00e4e8 + (ch * 0x50), 0, 0); - if (!(stat & 0x000f0f00)) { - ret = 0; - break; - } - - AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat); - } - - if (type & 1) { - for (i = 0; i < 16; i += 4) { - xbuf[i / 4] = nv_rd32(dev, 0x00e4d0 + (ch * 0x50) + i); - AUX_DBG("rd 0x%08x\n", xbuf[i / 4]); - } - memcpy(data, xbuf, size); - } - -out: - auxch_fini(dev, ch); - return ret; -} - -u8 * -nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry) -{ - struct bit_entry d; - u8 *table; - int i; - - if (bit_table(dev, 'd', &d)) { - NV_ERROR(dev, "BIT 'd' table not found\n"); - return NULL; - } - - if (d.version != 1) { - NV_ERROR(dev, "BIT 'd' table version %d unknown\n", d.version); - return NULL; - } - - table = ROMPTR(dev, d.data[0]); - if (!table) { - NV_ERROR(dev, "displayport table pointer invalid\n"); - return NULL; - } - - switch (table[0]) { - case 0x20: - case 0x21: - case 0x30: - case 0x40: - break; - default: - NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]); - return NULL; - } - - for (i = 0; i < table[3]; i++) { - *entry = ROMPTR(dev, table[table[1] + (i * table[2])]); - if (*entry && bios_encoder_match(dcb, ROM32((*entry)[0]))) - return table; - } - - NV_ERROR(dev, "displayport encoder table not found\n"); - return NULL; -} - -/****************************************************************************** - * link training - *****************************************************************************/ -struct dp_state { - struct dp_train_func *func; - struct dcb_entry *dcb; - int auxch; - int crtc; - u8 *dpcd; - int link_nr; - u32 link_bw; - u8 stat[6]; - u8 conf[4]; -}; - -static void -dp_set_link_config(struct drm_device *dev, struct dp_state *dp) -{ - u8 sink[2]; - - NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); - - /* set desired link configuration on the source */ - dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw, - dp->dpcd[2] & DP_ENHANCED_FRAME_CAP); - - /* inform the sink of the new configuration */ - sink[0] = dp->link_bw / 27000; - sink[1] = dp->link_nr; - if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) - sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - - auxch_tx(dev, dp->auxch, 8, DP_LINK_BW_SET, sink, 2); -} - -static void -dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) -{ - u8 sink_tp; - - NV_DEBUG_KMS(dev, "training pattern %d\n", pattern); - - dp->func->train_set(dev, dp->dcb, pattern); - - auxch_tx(dev, dp->auxch, 9, DP_TRAINING_PATTERN_SET, &sink_tp, 1); - sink_tp &= ~DP_TRAINING_PATTERN_MASK; - sink_tp |= pattern; - auxch_tx(dev, dp->auxch, 8, DP_TRAINING_PATTERN_SET, &sink_tp, 1); -} - -static int -dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) -{ - int i; - - for (i = 0; i < dp->link_nr; i++) { - u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; - u8 lpre = (lane & 0x0c) >> 2; - u8 lvsw = (lane & 0x03) >> 0; - - dp->conf[i] = (lpre << 3) | lvsw; - if (lvsw == DP_TRAIN_VOLTAGE_SWING_1200) - dp->conf[i] |= DP_TRAIN_MAX_SWING_REACHED; - if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5) - dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - - NV_DEBUG_KMS(dev, "config lane %d %02x\n", i, dp->conf[i]); - dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); - } - - return auxch_tx(dev, dp->auxch, 8, DP_TRAINING_LANE0_SET, dp->conf, 4); -} - -static int -dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay) -{ - int ret; - - udelay(delay); - - ret = auxch_tx(dev, dp->auxch, 9, DP_LANE0_1_STATUS, dp->stat, 6); - if (ret) - return ret; - - NV_DEBUG_KMS(dev, "status %02x %02x %02x %02x %02x %02x\n", - dp->stat[0], dp->stat[1], dp->stat[2], dp->stat[3], - dp->stat[4], dp->stat[5]); - return 0; -} - -static int -dp_link_train_cr(struct drm_device *dev, struct dp_state *dp) -{ - bool cr_done = false, abort = false; - int voltage = dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - int tries = 0, i; - - dp_set_training_pattern(dev, dp, DP_TRAINING_PATTERN_1); - - do { - if (dp_link_train_commit(dev, dp) || - dp_link_train_update(dev, dp, 100)) - break; - - cr_done = true; - for (i = 0; i < dp->link_nr; i++) { - u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; - if (!(lane & DP_LANE_CR_DONE)) { - cr_done = false; - if (dp->conf[i] & DP_TRAIN_MAX_SWING_REACHED) - abort = true; - break; - } - } - - if ((dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { - voltage = dp->conf[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - tries = 0; - } - } while (!cr_done && !abort && ++tries < 5); - - return cr_done ? 0 : -1; -} - -static int -dp_link_train_eq(struct drm_device *dev, struct dp_state *dp) -{ - bool eq_done, cr_done = true; - int tries = 0, i; - - dp_set_training_pattern(dev, dp, DP_TRAINING_PATTERN_2); - - do { - if (dp_link_train_update(dev, dp, 400)) - break; - - eq_done = !!(dp->stat[2] & DP_INTERLANE_ALIGN_DONE); - for (i = 0; i < dp->link_nr && eq_done; i++) { - u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf; - if (!(lane & DP_LANE_CR_DONE)) - cr_done = false; - if (!(lane & DP_LANE_CHANNEL_EQ_DONE) || - !(lane & DP_LANE_SYMBOL_LOCKED)) - eq_done = false; - } - - if (dp_link_train_commit(dev, dp)) - break; - } while (!eq_done && cr_done && ++tries <= 5); - - return eq_done ? 0 : -1; -} - -static void -dp_set_downspread(struct drm_device *dev, struct dp_state *dp, bool enable) -{ - u16 script = 0x0000; - u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); - if (table) { - if (table[0] >= 0x20 && table[0] <= 0x30) { - if (enable) script = ROM16(entry[12]); - else script = ROM16(entry[14]); - } else - if (table[0] == 0x40) { - if (enable) script = ROM16(entry[11]); - else script = ROM16(entry[13]); - } - } - - nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); -} - -static void -dp_link_train_init(struct drm_device *dev, struct dp_state *dp) -{ - u16 script = 0x0000; - u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); - if (table) { - if (table[0] >= 0x20 && table[0] <= 0x30) - script = ROM16(entry[6]); - else - if (table[0] == 0x40) - script = ROM16(entry[5]); - } - - nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); -} - -static void -dp_link_train_fini(struct drm_device *dev, struct dp_state *dp) -{ - u16 script = 0x0000; - u8 *entry, *table = nouveau_dp_bios_data(dev, dp->dcb, &entry); - if (table) { - if (table[0] >= 0x20 && table[0] <= 0x30) - script = ROM16(entry[8]); - else - if (table[0] == 0x40) - script = ROM16(entry[7]); - } - - nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); -} - -bool -nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, - struct dp_train_func *func) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nouveau_connector *nv_connector = - nouveau_encoder_connector_get(nv_encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_i2c_chan *auxch; - const u32 bw_list[] = { 270000, 162000, 0 }; - const u32 *link_bw = bw_list; - struct dp_state dp; - - auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); - if (!auxch) - return false; - - dp.func = func; - dp.dcb = nv_encoder->dcb; - dp.crtc = nv_crtc->index; - dp.auxch = auxch->drive; - dp.dpcd = nv_encoder->dp.dpcd; - - /* adjust required bandwidth for 8B/10B coding overhead */ - datarate = (datarate / 8) * 10; - - /* some sinks toggle hotplug in response to some of the actions - * we take during link training (DP_SET_POWER is one), we need - * to ignore them for the moment to avoid races. - */ - nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false); - - /* enable down-spreading, if possible */ - dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); - - /* execute pre-train script from vbios */ - dp_link_train_init(dev, &dp); - - /* start off at highest link rate supported by encoder and display */ - while (*link_bw > nv_encoder->dp.link_bw) - link_bw++; - - while (link_bw[0]) { - /* find minimum required lane count at this link rate */ - dp.link_nr = nv_encoder->dp.link_nr; - while ((dp.link_nr >> 1) * link_bw[0] > datarate) - dp.link_nr >>= 1; - - /* drop link rate to minimum with this lane count */ - while ((link_bw[1] * dp.link_nr) > datarate) - link_bw++; - dp.link_bw = link_bw[0]; - - /* program selected link configuration */ - dp_set_link_config(dev, &dp); - - /* attempt to train the link at this configuration */ - memset(dp.stat, 0x00, sizeof(dp.stat)); - if (!dp_link_train_cr(dev, &dp) && - !dp_link_train_eq(dev, &dp)) - break; - - /* retry at lower rate */ - link_bw++; - } - - /* finish link training */ - dp_set_training_pattern(dev, &dp, DP_TRAINING_PATTERN_DISABLE); - - /* execute post-train script from vbios */ - dp_link_train_fini(dev, &dp); - - /* re-enable hotplug detect */ - nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true); - return true; -} - -void -nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, - struct dp_train_func *func) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_i2c_chan *auxch; - u8 status; - - auxch = nouveau_i2c_find(encoder->dev, nv_encoder->dcb->i2c_index); - if (!auxch) - return; - - if (mode == DRM_MODE_DPMS_ON) - status = DP_SET_POWER_D0; - else - status = DP_SET_POWER_D3; - - nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); - - if (mode == DRM_MODE_DPMS_ON) - nouveau_dp_link_train(encoder, datarate, func); -} - -bool -nouveau_dp_detect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_i2c_chan *auxch; - u8 *dpcd = nv_encoder->dp.dpcd; - int ret; - - auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); - if (!auxch) - return false; - - ret = auxch_tx(dev, auxch->drive, 9, DP_DPCD_REV, dpcd, 8); - if (ret) - return false; - - nv_encoder->dp.link_bw = 27000 * dpcd[1]; - nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; - - NV_DEBUG_KMS(dev, "display: %dx%d dpcd 0x%02x\n", - nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); - NV_DEBUG_KMS(dev, "encoder: %dx%d\n", - nv_encoder->dcb->dpconf.link_nr, - nv_encoder->dcb->dpconf.link_bw); - - if (nv_encoder->dcb->dpconf.link_nr < nv_encoder->dp.link_nr) - nv_encoder->dp.link_nr = nv_encoder->dcb->dpconf.link_nr; - if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) - nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; - - NV_DEBUG_KMS(dev, "maximum: %dx%d\n", - nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); - - return true; -} - -int -nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, - uint8_t *data, int data_nr) -{ - return auxch_tx(auxch->dev, auxch->drive, cmd, addr, data, data_nr); -} - -static int -nouveau_dp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) -{ - struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adap; - struct i2c_msg *msg = msgs; - int ret, mcnt = num; - - while (mcnt--) { - u8 remaining = msg->len; - u8 *ptr = msg->buf; - - while (remaining) { - u8 cnt = (remaining > 16) ? 16 : remaining; - u8 cmd; - - if (msg->flags & I2C_M_RD) - cmd = AUX_I2C_READ; - else - cmd = AUX_I2C_WRITE; - - if (mcnt || remaining > 16) - cmd |= AUX_I2C_MOT; - - ret = nouveau_dp_auxch(auxch, cmd, msg->addr, ptr, cnt); - if (ret < 0) - return ret; - - ptr += cnt; - remaining -= cnt; - } - - msg++; - } - - return num; -} - -static u32 -nouveau_dp_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -const struct i2c_algorithm nouveau_dp_i2c_algo = { - .master_xfer = nouveau_dp_i2c_xfer, - .functionality = nouveau_dp_i2c_func -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.c deleted file mode 100644 index 4f2030bd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright 2005 Stephane Marchesin. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc_helper.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_fb.h" -#include "nouveau_fbcon.h" -#include "nouveau_pm.h" -#include "nv50_display.h" - -#include "drm_pciids.h" - -MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)"); -int nouveau_agpmode = -1; -module_param_named(agpmode, nouveau_agpmode, int, 0400); - -MODULE_PARM_DESC(modeset, "Enable kernel modesetting"); -int nouveau_modeset = -1; -module_param_named(modeset, nouveau_modeset, int, 0400); - -MODULE_PARM_DESC(vbios, "Override default VBIOS location"); -char *nouveau_vbios; -module_param_named(vbios, nouveau_vbios, charp, 0400); - -MODULE_PARM_DESC(vram_pushbuf, "Force DMA push buffers to be in VRAM"); -int nouveau_vram_pushbuf; -module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); - -MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); -int nouveau_vram_notify = 0; -module_param_named(vram_notify, nouveau_vram_notify, int, 0400); - -MODULE_PARM_DESC(vram_type, "Override detected VRAM type"); -char *nouveau_vram_type; -module_param_named(vram_type, nouveau_vram_type, charp, 0400); - -MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); -int nouveau_duallink = 1; -module_param_named(duallink, nouveau_duallink, int, 0400); - -MODULE_PARM_DESC(uscript_lvds, "LVDS output script table ID (>=GeForce 8)"); -int nouveau_uscript_lvds = -1; -module_param_named(uscript_lvds, nouveau_uscript_lvds, int, 0400); - -MODULE_PARM_DESC(uscript_tmds, "TMDS output script table ID (>=GeForce 8)"); -int nouveau_uscript_tmds = -1; -module_param_named(uscript_tmds, nouveau_uscript_tmds, int, 0400); - -MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status"); -int nouveau_ignorelid = 0; -module_param_named(ignorelid, nouveau_ignorelid, int, 0400); - -MODULE_PARM_DESC(noaccel, "Disable all acceleration"); -int nouveau_noaccel = -1; -module_param_named(noaccel, nouveau_noaccel, int, 0400); - -MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); -int nouveau_nofbaccel = 0; -module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); - -MODULE_PARM_DESC(force_post, "Force POST"); -int nouveau_force_post = 0; -module_param_named(force_post, nouveau_force_post, int, 0400); - -MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type"); -int nouveau_override_conntype = 0; -module_param_named(override_conntype, nouveau_override_conntype, int, 0400); - -MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); -int nouveau_tv_disable = 0; -module_param_named(tv_disable, nouveau_tv_disable, int, 0400); - -MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" - "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" - "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" - "\t\tDefault: PAL\n" - "\t\t*NOTE* Ignored for cards with external TV encoders."); -char *nouveau_tv_norm; -module_param_named(tv_norm, nouveau_tv_norm, charp, 0400); - -MODULE_PARM_DESC(reg_debug, "Register access debug bitmask:\n" - "\t\t0x1 mc, 0x2 video, 0x4 fb, 0x8 extdev,\n" - "\t\t0x10 crtc, 0x20 ramdac, 0x40 vgacrtc, 0x80 rmvio,\n" - "\t\t0x100 vgaattr, 0x200 EVO (G80+)"); -int nouveau_reg_debug; -module_param_named(reg_debug, nouveau_reg_debug, int, 0600); - -MODULE_PARM_DESC(perflvl, "Performance level (default: boot)"); -char *nouveau_perflvl; -module_param_named(perflvl, nouveau_perflvl, charp, 0400); - -MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)"); -int nouveau_perflvl_wr; -module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400); - -MODULE_PARM_DESC(msi, "Enable MSI (default: off)"); -int nouveau_msi; -module_param_named(msi, nouveau_msi, int, 0400); - -MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)"); -int nouveau_ctxfw; -module_param_named(ctxfw, nouveau_ctxfw, int, 0400); - -MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS"); -int nouveau_mxmdcb = 1; -module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); - -int nouveau_fbpercrtc; -#if 0 -module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); -#endif - -static struct pci_device_id pciidlist[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), - .class = PCI_BASE_CLASS_DISPLAY << 16, - .class_mask = 0xff << 16, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID), - .class = PCI_BASE_CLASS_DISPLAY << 16, - .class_mask = 0xff << 16, - }, - {} -}; - -MODULE_DEVICE_TABLE(pci, pciidlist); - -static struct drm_driver driver; - -static int __devinit -nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - return drm_get_pci_dev(pdev, ent, &driver); -} - -static void -nouveau_pci_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - drm_put_dev(dev); -} - -int -nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_channel *chan; - struct drm_crtc *crtc; - int ret, i, e; - - if (pm_state.event == PM_EVENT_PRETHAW) - return 0; - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - NV_INFO(dev, "Disabling display...\n"); - nouveau_display_fini(dev); - - NV_INFO(dev, "Disabling fbcon...\n"); - nouveau_fbcon_set_suspend(dev, 1); - - NV_INFO(dev, "Unpinning framebuffer(s)...\n"); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_framebuffer *nouveau_fb; - - nouveau_fb = nouveau_framebuffer(crtc->fb); - if (!nouveau_fb || !nouveau_fb->nvbo) - continue; - - nouveau_bo_unpin(nouveau_fb->nvbo); - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nouveau_bo_unmap(nv_crtc->cursor.nvbo); - nouveau_bo_unpin(nv_crtc->cursor.nvbo); - } - - NV_INFO(dev, "Evicting buffers...\n"); - ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); - - NV_INFO(dev, "Idling channels...\n"); - for (i = 0; i < pfifo->channels; i++) { - chan = dev_priv->channels.ptr[i]; - - if (chan && chan->pushbuf_bo) - nouveau_channel_idle(chan); - } - - pfifo->reassign(dev, false); - pfifo->disable(dev); - pfifo->unload_context(dev); - - for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { - if (!dev_priv->eng[e]) - continue; - - ret = dev_priv->eng[e]->fini(dev, e, true); - if (ret) { - NV_ERROR(dev, "... engine %d failed: %d\n", e, ret); - goto out_abort; - } - } - - ret = pinstmem->suspend(dev); - if (ret) { - NV_ERROR(dev, "... failed: %d\n", ret); - goto out_abort; - } - - NV_INFO(dev, "Suspending GPU objects...\n"); - ret = nouveau_gpuobj_suspend(dev); - if (ret) { - NV_ERROR(dev, "... failed: %d\n", ret); - pinstmem->resume(dev); - goto out_abort; - } - - NV_INFO(dev, "And we're gone!\n"); - pci_save_state(pdev); - if (pm_state.event == PM_EVENT_SUSPEND) { - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - } - - return 0; - -out_abort: - NV_INFO(dev, "Re-enabling acceleration..\n"); - for (e = e + 1; e < NVOBJ_ENGINE_NR; e++) { - if (dev_priv->eng[e]) - dev_priv->eng[e]->init(dev, e); - } - pfifo->enable(dev); - pfifo->reassign(dev, true); - return ret; -} - -int -nouveau_pci_resume(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - struct drm_crtc *crtc; - int ret, i; - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - NV_INFO(dev, "We're back, enabling device...\n"); - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - if (pci_enable_device(pdev)) - return -1; - pci_set_master(dev->pdev); - - /* Make sure the AGP controller is in a consistent state */ - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) - nouveau_mem_reset_agp(dev); - - /* Make the CRTCs accessible */ - engine->display.early_init(dev); - - NV_INFO(dev, "POSTing device...\n"); - ret = nouveau_run_vbios_init(dev); - if (ret) - return ret; - - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { - ret = nouveau_mem_init_agp(dev); - if (ret) { - NV_ERROR(dev, "error reinitialising AGP: %d\n", ret); - return ret; - } - } - - NV_INFO(dev, "Restoring GPU objects...\n"); - nouveau_gpuobj_resume(dev); - - NV_INFO(dev, "Reinitialising engines...\n"); - engine->instmem.resume(dev); - engine->mc.init(dev); - engine->timer.init(dev); - engine->fb.init(dev); - for (i = 0; i < NVOBJ_ENGINE_NR; i++) { - if (dev_priv->eng[i]) - dev_priv->eng[i]->init(dev, i); - } - engine->fifo.init(dev); - - nouveau_irq_postinstall(dev); - - /* Re-write SKIPS, they'll have been lost over the suspend */ - if (nouveau_vram_pushbuf) { - struct nouveau_channel *chan; - int j; - - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->pushbuf_bo) - continue; - - for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) - nouveau_bo_wr32(chan->pushbuf_bo, i, 0); - } - } - - nouveau_pm_resume(dev); - - NV_INFO(dev, "Restoring mode...\n"); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_framebuffer *nouveau_fb; - - nouveau_fb = nouveau_framebuffer(crtc->fb); - if (!nouveau_fb || !nouveau_fb->nvbo) - continue; - - nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(nv_crtc->cursor.nvbo); - if (ret) - NV_ERROR(dev, "Could not pin/map cursor.\n"); - } - - nouveau_fbcon_set_suspend(dev, 0); - nouveau_fbcon_zfill_all(dev); - - nouveau_display_init(dev); - - /* Force CLUT to get re-loaded during modeset */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nv_crtc->lut.depth = 0; - } - - drm_helper_resume_force_mode(dev); - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - u32 offset = nv_crtc->cursor.nvbo->bo.offset; - - nv_crtc->cursor.set_offset(nv_crtc, offset); - nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, - nv_crtc->cursor_saved_y); - } - - return 0; -} - -static const struct file_operations nouveau_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = nouveau_ttm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, -#if defined(CONFIG_COMPAT) - .compat_ioctl = nouveau_compat_ioctl, -#endif - .llseek = noop_llseek, -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | - DRIVER_MODESET, - .load = nouveau_load, - .firstopen = nouveau_firstopen, - .lastclose = nouveau_lastclose, - .unload = nouveau_unload, - .open = nouveau_open, - .preclose = nouveau_preclose, - .postclose = nouveau_postclose, -#if defined(CONFIG_DRM_NOUVEAU_DEBUG) - .debugfs_init = nouveau_debugfs_init, - .debugfs_cleanup = nouveau_debugfs_takedown, -#endif - .irq_preinstall = nouveau_irq_preinstall, - .irq_postinstall = nouveau_irq_postinstall, - .irq_uninstall = nouveau_irq_uninstall, - .irq_handler = nouveau_irq_handler, - .get_vblank_counter = drm_vblank_count, - .enable_vblank = nouveau_vblank_enable, - .disable_vblank = nouveau_vblank_disable, - .reclaim_buffers = drm_core_reclaim_buffers, - .ioctls = nouveau_ioctls, - .fops = &nouveau_driver_fops, - .gem_init_object = nouveau_gem_object_new, - .gem_free_object = nouveau_gem_object_del, - .gem_open_object = nouveau_gem_object_open, - .gem_close_object = nouveau_gem_object_close, - - .dumb_create = nouveau_display_dumb_create, - .dumb_map_offset = nouveau_display_dumb_map_offset, - .dumb_destroy = nouveau_display_dumb_destroy, - - .name = DRIVER_NAME, - .desc = DRIVER_DESC, -#ifdef GIT_REVISION - .date = GIT_REVISION, -#else - .date = DRIVER_DATE, -#endif - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct pci_driver nouveau_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = nouveau_pci_probe, - .remove = nouveau_pci_remove, - .suspend = nouveau_pci_suspend, - .resume = nouveau_pci_resume -}; - -static int __init nouveau_init(void) -{ - driver.num_ioctls = nouveau_max_ioctl; - - if (nouveau_modeset == -1) { -#ifdef CONFIG_VGA_CONSOLE - if (vgacon_text_force()) - nouveau_modeset = 0; - else -#endif - nouveau_modeset = 1; - } - - if (!nouveau_modeset) - return 0; - - nouveau_register_dsm_handler(); - return drm_pci_init(&driver, &nouveau_pci_driver); -} - -static void __exit nouveau_exit(void) -{ - if (!nouveau_modeset) - return; - - drm_pci_exit(&driver, &nouveau_pci_driver); - nouveau_unregister_dsm_handler(); -} - -module_init(nouveau_init); -module_exit(nouveau_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.h deleted file mode 100644 index 3aef353a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_drv.h +++ /dev/null @@ -1,1793 +0,0 @@ -/* - * Copyright 2005 Stephane Marchesin. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __NOUVEAU_DRV_H__ -#define __NOUVEAU_DRV_H__ - -#define DRIVER_AUTHOR "Stephane Marchesin" -#define DRIVER_EMAIL "nouveau@lists.freedesktop.org" - -#define DRIVER_NAME "nouveau" -#define DRIVER_DESC "nVidia Riva/TNT/GeForce" -#define DRIVER_DATE "20120316" - -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 0 - -#define NOUVEAU_FAMILY 0x0000FFFF -#define NOUVEAU_FLAGS 0xFFFF0000 - -#include "ttm/ttm_bo_api.h" -#include "ttm/ttm_bo_driver.h" -#include "ttm/ttm_placement.h" -#include "ttm/ttm_memory.h" -#include "ttm/ttm_module.h" - -struct nouveau_fpriv { - spinlock_t lock; - struct list_head channels; - struct nouveau_vm *vm; -}; - -static inline struct nouveau_fpriv * -nouveau_fpriv(struct drm_file *file_priv) -{ - return file_priv ? file_priv->driver_priv : NULL; -} - -#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - -#include "nouveau_drm.h" -#include "nouveau_reg.h" -#include "nouveau_bios.h" -#include "nouveau_util.h" - -struct nouveau_grctx; -struct nouveau_mem; -#include "nouveau_vm.h" - -#define MAX_NUM_DCB_ENTRIES 16 - -#define NOUVEAU_MAX_CHANNEL_NR 128 -#define NOUVEAU_MAX_TILE_NR 15 - -struct nouveau_mem { - struct drm_device *dev; - - struct nouveau_vma bar_vma; - struct nouveau_vma vma[2]; - u8 page_shift; - - struct drm_mm_node *tag; - struct list_head regions; - dma_addr_t *pages; - u32 memtype; - u64 offset; - u64 size; -}; - -struct nouveau_tile_reg { - bool used; - uint32_t addr; - uint32_t limit; - uint32_t pitch; - uint32_t zcomp; - struct drm_mm_node *tag_mem; - struct nouveau_fence *fence; -}; - -struct nouveau_bo { - struct ttm_buffer_object bo; - struct ttm_placement placement; - u32 valid_domains; - u32 placements[3]; - u32 busy_placements[3]; - struct ttm_bo_kmap_obj kmap; - struct list_head head; - - /* protected by ttm_bo_reserve() */ - struct drm_file *reserved_by; - struct list_head entry; - int pbbo_index; - bool validate_mapped; - - struct list_head vma_list; - unsigned page_shift; - - uint32_t tile_mode; - uint32_t tile_flags; - struct nouveau_tile_reg *tile; - - struct drm_gem_object *gem; - int pin_refcnt; -}; - -#define nouveau_bo_tile_layout(nvbo) \ - ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) - -static inline struct nouveau_bo * -nouveau_bo(struct ttm_buffer_object *bo) -{ - return container_of(bo, struct nouveau_bo, bo); -} - -static inline struct nouveau_bo * -nouveau_gem_object(struct drm_gem_object *gem) -{ - return gem ? gem->driver_private : NULL; -} - -/* TODO: submit equivalent to TTM generic API upstream? */ -static inline void __iomem * -nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo) -{ - bool is_iomem; - void __iomem *ioptr = (void __force __iomem *)ttm_kmap_obj_virtual( - &nvbo->kmap, &is_iomem); - WARN_ON_ONCE(ioptr && !is_iomem); - return ioptr; -} - -enum nouveau_flags { - NV_NFORCE = 0x10000000, - NV_NFORCE2 = 0x20000000 -}; - -#define NVOBJ_ENGINE_SW 0 -#define NVOBJ_ENGINE_GR 1 -#define NVOBJ_ENGINE_CRYPT 2 -#define NVOBJ_ENGINE_COPY0 3 -#define NVOBJ_ENGINE_COPY1 4 -#define NVOBJ_ENGINE_MPEG 5 -#define NVOBJ_ENGINE_PPP NVOBJ_ENGINE_MPEG -#define NVOBJ_ENGINE_BSP 6 -#define NVOBJ_ENGINE_VP 7 -#define NVOBJ_ENGINE_DISPLAY 15 -#define NVOBJ_ENGINE_NR 16 - -#define NVOBJ_FLAG_DONT_MAP (1 << 0) -#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) -#define NVOBJ_FLAG_ZERO_FREE (1 << 2) -#define NVOBJ_FLAG_VM (1 << 3) -#define NVOBJ_FLAG_VM_USER (1 << 4) - -#define NVOBJ_CINST_GLOBAL 0xdeadbeef - -struct nouveau_gpuobj { - struct drm_device *dev; - struct kref refcount; - struct list_head list; - - void *node; - u32 *suspend; - - uint32_t flags; - - u32 size; - u32 pinst; /* PRAMIN BAR offset */ - u32 cinst; /* Channel offset */ - u64 vinst; /* VRAM address */ - u64 linst; /* VM address */ - - uint32_t engine; - uint32_t class; - - void (*dtor)(struct drm_device *, struct nouveau_gpuobj *); - void *priv; -}; - -struct nouveau_page_flip_state { - struct list_head head; - struct drm_pending_vblank_event *event; - int crtc, bpp, pitch, x, y; - uint64_t offset; -}; - -enum nouveau_channel_mutex_class { - NOUVEAU_UCHANNEL_MUTEX, - NOUVEAU_KCHANNEL_MUTEX -}; - -struct nouveau_channel { - struct drm_device *dev; - struct list_head list; - int id; - - /* references to the channel data structure */ - struct kref ref; - /* users of the hardware channel resources, the hardware - * context will be kicked off when it reaches zero. */ - atomic_t users; - struct mutex mutex; - - /* owner of this fifo */ - struct drm_file *file_priv; - /* mapping of the fifo itself */ - struct drm_local_map *map; - - /* mapping of the regs controlling the fifo */ - void __iomem *user; - uint32_t user_get; - uint32_t user_get_hi; - uint32_t user_put; - - /* Fencing */ - struct { - /* lock protects the pending list only */ - spinlock_t lock; - struct list_head pending; - uint32_t sequence; - uint32_t sequence_ack; - atomic_t last_sequence_irq; - struct nouveau_vma vma; - } fence; - - /* DMA push buffer */ - struct nouveau_gpuobj *pushbuf; - struct nouveau_bo *pushbuf_bo; - struct nouveau_vma pushbuf_vma; - uint64_t pushbuf_base; - - /* Notifier memory */ - struct nouveau_bo *notifier_bo; - struct nouveau_vma notifier_vma; - struct drm_mm notifier_heap; - - /* PFIFO context */ - struct nouveau_gpuobj *ramfc; - struct nouveau_gpuobj *cache; - void *fifo_priv; - - /* Execution engine contexts */ - void *engctx[NVOBJ_ENGINE_NR]; - - /* NV50 VM */ - struct nouveau_vm *vm; - struct nouveau_gpuobj *vm_pd; - - /* Objects */ - struct nouveau_gpuobj *ramin; /* Private instmem */ - struct drm_mm ramin_heap; /* Private PRAMIN heap */ - struct nouveau_ramht *ramht; /* Hash table */ - - /* GPU object info for stuff used in-kernel (mm_enabled) */ - uint32_t m2mf_ntfy; - uint32_t vram_handle; - uint32_t gart_handle; - bool accel_done; - - /* Push buffer state (only for drm's channel on !mm_enabled) */ - struct { - int max; - int free; - int cur; - int put; - /* access via pushbuf_bo */ - - int ib_base; - int ib_max; - int ib_free; - int ib_put; - } dma; - - uint32_t sw_subchannel[8]; - - struct nouveau_vma dispc_vma[4]; - struct { - struct nouveau_gpuobj *vblsem; - uint32_t vblsem_head; - uint32_t vblsem_offset; - uint32_t vblsem_rval; - struct list_head vbl_wait; - struct list_head flip; - } nvsw; - - struct { - bool active; - char name[32]; - struct drm_info_list info; - } debugfs; -}; - -struct nouveau_exec_engine { - void (*destroy)(struct drm_device *, int engine); - int (*init)(struct drm_device *, int engine); - int (*fini)(struct drm_device *, int engine, bool suspend); - int (*context_new)(struct nouveau_channel *, int engine); - void (*context_del)(struct nouveau_channel *, int engine); - int (*object_new)(struct nouveau_channel *, int engine, - u32 handle, u16 class); - void (*set_tile_region)(struct drm_device *dev, int i); - void (*tlb_flush)(struct drm_device *, int engine); -}; - -struct nouveau_instmem_engine { - void *priv; - - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - int (*suspend)(struct drm_device *dev); - void (*resume)(struct drm_device *dev); - - int (*get)(struct nouveau_gpuobj *, struct nouveau_channel *, - u32 size, u32 align); - void (*put)(struct nouveau_gpuobj *); - int (*map)(struct nouveau_gpuobj *); - void (*unmap)(struct nouveau_gpuobj *); - - void (*flush)(struct drm_device *); -}; - -struct nouveau_mc_engine { - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); -}; - -struct nouveau_timer_engine { - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - uint64_t (*read)(struct drm_device *dev); -}; - -struct nouveau_fb_engine { - int num_tiles; - struct drm_mm tag_heap; - void *priv; - - int (*init)(struct drm_device *dev); - void (*takedown)(struct drm_device *dev); - - void (*init_tile_region)(struct drm_device *dev, int i, - uint32_t addr, uint32_t size, - uint32_t pitch, uint32_t flags); - void (*set_tile_region)(struct drm_device *dev, int i); - void (*free_tile_region)(struct drm_device *dev, int i); -}; - -struct nouveau_fifo_engine { - void *priv; - int channels; - - struct nouveau_gpuobj *playlist[2]; - int cur_playlist; - - int (*init)(struct drm_device *); - void (*takedown)(struct drm_device *); - - void (*disable)(struct drm_device *); - void (*enable)(struct drm_device *); - bool (*reassign)(struct drm_device *, bool enable); - bool (*cache_pull)(struct drm_device *dev, bool enable); - - int (*channel_id)(struct drm_device *); - - int (*create_context)(struct nouveau_channel *); - void (*destroy_context)(struct nouveau_channel *); - int (*load_context)(struct nouveau_channel *); - int (*unload_context)(struct drm_device *); - void (*tlb_flush)(struct drm_device *dev); -}; - -struct nouveau_display_engine { - void *priv; - int (*early_init)(struct drm_device *); - void (*late_takedown)(struct drm_device *); - int (*create)(struct drm_device *); - void (*destroy)(struct drm_device *); - int (*init)(struct drm_device *); - void (*fini)(struct drm_device *); - - struct drm_property *dithering_mode; - struct drm_property *dithering_depth; - struct drm_property *underscan_property; - struct drm_property *underscan_hborder_property; - struct drm_property *underscan_vborder_property; - /* not really hue and saturation: */ - struct drm_property *vibrant_hue_property; - struct drm_property *color_vibrance_property; -}; - -struct nouveau_gpio_engine { - spinlock_t lock; - struct list_head isr; - int (*init)(struct drm_device *); - void (*fini)(struct drm_device *); - int (*drive)(struct drm_device *, int line, int dir, int out); - int (*sense)(struct drm_device *, int line); - void (*irq_enable)(struct drm_device *, int line, bool); -}; - -struct nouveau_pm_voltage_level { - u32 voltage; /* microvolts */ - u8 vid; -}; - -struct nouveau_pm_voltage { - bool supported; - u8 version; - u8 vid_mask; - - struct nouveau_pm_voltage_level *level; - int nr_level; -}; - -/* Exclusive upper limits */ -#define NV_MEM_CL_DDR2_MAX 8 -#define NV_MEM_WR_DDR2_MAX 9 -#define NV_MEM_CL_DDR3_MAX 17 -#define NV_MEM_WR_DDR3_MAX 17 -#define NV_MEM_CL_GDDR3_MAX 16 -#define NV_MEM_WR_GDDR3_MAX 18 -#define NV_MEM_CL_GDDR5_MAX 21 -#define NV_MEM_WR_GDDR5_MAX 20 - -struct nouveau_pm_memtiming { - int id; - - u32 reg[9]; - u32 mr[4]; - - u8 tCWL; - - u8 odt; - u8 drive_strength; -}; - -struct nouveau_pm_tbl_header { - u8 version; - u8 header_len; - u8 entry_cnt; - u8 entry_len; -}; - -struct nouveau_pm_tbl_entry { - u8 tWR; - u8 tWTR; - u8 tCL; - u8 tRC; - u8 empty_4; - u8 tRFC; /* Byte 5 */ - u8 empty_6; - u8 tRAS; /* Byte 7 */ - u8 empty_8; - u8 tRP; /* Byte 9 */ - u8 tRCDRD; - u8 tRCDWR; - u8 tRRD; - u8 tUNK_13; - u8 RAM_FT1; /* 14, a bitmask of random RAM features */ - u8 empty_15; - u8 tUNK_16; - u8 empty_17; - u8 tUNK_18; - u8 tCWL; - u8 tUNK_20, tUNK_21; -}; - -struct nouveau_pm_profile; -struct nouveau_pm_profile_func { - void (*destroy)(struct nouveau_pm_profile *); - void (*init)(struct nouveau_pm_profile *); - void (*fini)(struct nouveau_pm_profile *); - struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *); -}; - -struct nouveau_pm_profile { - const struct nouveau_pm_profile_func *func; - struct list_head head; - char name[8]; -}; - -#define NOUVEAU_PM_MAX_LEVEL 8 -struct nouveau_pm_level { - struct nouveau_pm_profile profile; - struct device_attribute dev_attr; - char name[32]; - int id; - - struct nouveau_pm_memtiming timing; - u32 memory; - u16 memscript; - - u32 core; - u32 shader; - u32 rop; - u32 copy; - u32 daemon; - u32 vdec; - u32 dom6; - u32 unka0; /* nva3:nvc0 */ - u32 hub01; /* nvc0- */ - u32 hub06; /* nvc0- */ - u32 hub07; /* nvc0- */ - - u32 volt_min; /* microvolts */ - u32 volt_max; - u8 fanspeed; -}; - -struct nouveau_pm_temp_sensor_constants { - u16 offset_constant; - s16 offset_mult; - s16 offset_div; - s16 slope_mult; - s16 slope_div; -}; - -struct nouveau_pm_threshold_temp { - s16 critical; - s16 down_clock; - s16 fan_boost; -}; - -struct nouveau_pm_fan { - u32 percent; - u32 min_duty; - u32 max_duty; - u32 pwm_freq; - u32 pwm_divisor; -}; - -struct nouveau_pm_engine { - struct nouveau_pm_voltage voltage; - struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL]; - int nr_perflvl; - struct nouveau_pm_temp_sensor_constants sensor_constants; - struct nouveau_pm_threshold_temp threshold_temp; - struct nouveau_pm_fan fan; - - struct nouveau_pm_profile *profile_ac; - struct nouveau_pm_profile *profile_dc; - struct nouveau_pm_profile *profile; - struct list_head profiles; - - struct nouveau_pm_level boot; - struct nouveau_pm_level *cur; - - struct device *hwmon; - struct notifier_block acpi_nb; - - int (*clocks_get)(struct drm_device *, struct nouveau_pm_level *); - void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *); - int (*clocks_set)(struct drm_device *, void *); - - int (*voltage_get)(struct drm_device *); - int (*voltage_set)(struct drm_device *, int voltage); - int (*pwm_get)(struct drm_device *, int line, u32*, u32*); - int (*pwm_set)(struct drm_device *, int line, u32, u32); - int (*temp_get)(struct drm_device *); -}; - -struct nouveau_vram_engine { - struct nouveau_mm mm; - - int (*init)(struct drm_device *); - void (*takedown)(struct drm_device *dev); - int (*get)(struct drm_device *, u64, u32 align, u32 size_nc, - u32 type, struct nouveau_mem **); - void (*put)(struct drm_device *, struct nouveau_mem **); - - bool (*flags_valid)(struct drm_device *, u32 tile_flags); -}; - -struct nouveau_engine { - struct nouveau_instmem_engine instmem; - struct nouveau_mc_engine mc; - struct nouveau_timer_engine timer; - struct nouveau_fb_engine fb; - struct nouveau_fifo_engine fifo; - struct nouveau_display_engine display; - struct nouveau_gpio_engine gpio; - struct nouveau_pm_engine pm; - struct nouveau_vram_engine vram; -}; - -struct nouveau_pll_vals { - union { - struct { -#ifdef __BIG_ENDIAN - uint8_t N1, M1, N2, M2; -#else - uint8_t M1, N1, M2, N2; -#endif - }; - struct { - uint16_t NM1, NM2; - } __attribute__((packed)); - }; - int log2P; - - int refclk; -}; - -enum nv04_fp_display_regs { - FP_DISPLAY_END, - FP_TOTAL, - FP_CRTC, - FP_SYNC_START, - FP_SYNC_END, - FP_VALID_START, - FP_VALID_END -}; - -struct nv04_crtc_reg { - unsigned char MiscOutReg; - uint8_t CRTC[0xa0]; - uint8_t CR58[0x10]; - uint8_t Sequencer[5]; - uint8_t Graphics[9]; - uint8_t Attribute[21]; - unsigned char DAC[768]; - - /* PCRTC regs */ - uint32_t fb_start; - uint32_t crtc_cfg; - uint32_t cursor_cfg; - uint32_t gpio_ext; - uint32_t crtc_830; - uint32_t crtc_834; - uint32_t crtc_850; - uint32_t crtc_eng_ctrl; - - /* PRAMDAC regs */ - uint32_t nv10_cursync; - struct nouveau_pll_vals pllvals; - uint32_t ramdac_gen_ctrl; - uint32_t ramdac_630; - uint32_t ramdac_634; - uint32_t tv_setup; - uint32_t tv_vtotal; - uint32_t tv_vskew; - uint32_t tv_vsync_delay; - uint32_t tv_htotal; - uint32_t tv_hskew; - uint32_t tv_hsync_delay; - uint32_t tv_hsync_delay2; - uint32_t fp_horiz_regs[7]; - uint32_t fp_vert_regs[7]; - uint32_t dither; - uint32_t fp_control; - uint32_t dither_regs[6]; - uint32_t fp_debug_0; - uint32_t fp_debug_1; - uint32_t fp_debug_2; - uint32_t fp_margin_color; - uint32_t ramdac_8c0; - uint32_t ramdac_a20; - uint32_t ramdac_a24; - uint32_t ramdac_a34; - uint32_t ctv_regs[38]; -}; - -struct nv04_output_reg { - uint32_t output; - int head; -}; - -struct nv04_mode_state { - struct nv04_crtc_reg crtc_reg[2]; - uint32_t pllsel; - uint32_t sel_clk; -}; - -enum nouveau_card_type { - NV_04 = 0x04, - NV_10 = 0x10, - NV_20 = 0x20, - NV_30 = 0x30, - NV_40 = 0x40, - NV_50 = 0x50, - NV_C0 = 0xc0, - NV_D0 = 0xd0, - NV_E0 = 0xe0, -}; - -struct drm_nouveau_private { - struct drm_device *dev; - bool noaccel; - - /* the card type, takes NV_* as values */ - enum nouveau_card_type card_type; - /* exact chipset, derived from NV_PMC_BOOT_0 */ - int chipset; - int flags; - u32 crystal; - - void __iomem *mmio; - - spinlock_t ramin_lock; - void __iomem *ramin; - u32 ramin_size; - u32 ramin_base; - bool ramin_available; - struct drm_mm ramin_heap; - struct nouveau_exec_engine *eng[NVOBJ_ENGINE_NR]; - struct list_head gpuobj_list; - struct list_head classes; - - struct nouveau_bo *vga_ram; - - /* interrupt handling */ - void (*irq_handler[32])(struct drm_device *); - bool msi_enabled; - - struct list_head vbl_waiting; - - struct { - struct drm_global_reference mem_global_ref; - struct ttm_bo_global_ref bo_global_ref; - struct ttm_bo_device bdev; - atomic_t validate_sequence; - } ttm; - - struct { - spinlock_t lock; - struct drm_mm heap; - struct nouveau_bo *bo; - } fence; - - struct { - spinlock_t lock; - struct nouveau_channel *ptr[NOUVEAU_MAX_CHANNEL_NR]; - } channels; - - struct nouveau_engine engine; - struct nouveau_channel *channel; - - /* For PFIFO and PGRAPH. */ - spinlock_t context_switch_lock; - - /* VM/PRAMIN flush, legacy PRAMIN aperture */ - spinlock_t vm_lock; - - /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ - struct nouveau_ramht *ramht; - struct nouveau_gpuobj *ramfc; - struct nouveau_gpuobj *ramro; - - uint32_t ramin_rsvd_vram; - - struct { - enum { - NOUVEAU_GART_NONE = 0, - NOUVEAU_GART_AGP, /* AGP */ - NOUVEAU_GART_PDMA, /* paged dma object */ - NOUVEAU_GART_HW /* on-chip gart/vm */ - } type; - uint64_t aper_base; - uint64_t aper_size; - uint64_t aper_free; - - struct ttm_backend_func *func; - - struct { - struct page *page; - dma_addr_t addr; - } dummy; - - struct nouveau_gpuobj *sg_ctxdma; - } gart_info; - - /* nv10-nv40 tiling regions */ - struct { - struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR]; - spinlock_t lock; - } tile; - - /* VRAM/fb configuration */ - enum { - NV_MEM_TYPE_UNKNOWN = 0, - NV_MEM_TYPE_STOLEN, - NV_MEM_TYPE_SGRAM, - NV_MEM_TYPE_SDRAM, - NV_MEM_TYPE_DDR1, - NV_MEM_TYPE_DDR2, - NV_MEM_TYPE_DDR3, - NV_MEM_TYPE_GDDR2, - NV_MEM_TYPE_GDDR3, - NV_MEM_TYPE_GDDR4, - NV_MEM_TYPE_GDDR5 - } vram_type; - uint64_t vram_size; - uint64_t vram_sys_base; - bool vram_rank_B; - - uint64_t fb_available_size; - uint64_t fb_mappable_pages; - uint64_t fb_aper_free; - int fb_mtrr; - - /* BAR control (NV50-) */ - struct nouveau_vm *bar1_vm; - struct nouveau_vm *bar3_vm; - - /* G8x/G9x virtual address space */ - struct nouveau_vm *chan_vm; - - struct nvbios vbios; - u8 *mxms; - struct list_head i2c_ports; - - struct nv04_mode_state mode_reg; - struct nv04_mode_state saved_reg; - uint32_t saved_vga_font[4][16384]; - uint32_t crtc_owner; - uint32_t dac_users[4]; - - struct backlight_device *backlight; - - struct { - struct dentry *channel_root; - } debugfs; - - struct nouveau_fbdev *nfbdev; - struct apertures_struct *apertures; -}; - -static inline struct drm_nouveau_private * -nouveau_private(struct drm_device *dev) -{ - return dev->dev_private; -} - -static inline struct drm_nouveau_private * -nouveau_bdev(struct ttm_bo_device *bd) -{ - return container_of(bd, struct drm_nouveau_private, ttm.bdev); -} - -static inline int -nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) -{ - struct nouveau_bo *prev; - - if (!pnvbo) - return -EINVAL; - prev = *pnvbo; - - *pnvbo = ref ? nouveau_bo(ttm_bo_reference(&ref->bo)) : NULL; - if (prev) { - struct ttm_buffer_object *bo = &prev->bo; - - ttm_bo_unref(&bo); - } - - return 0; -} - -/* nouveau_drv.c */ -extern int nouveau_modeset; -extern int nouveau_agpmode; -extern int nouveau_duallink; -extern int nouveau_uscript_lvds; -extern int nouveau_uscript_tmds; -extern int nouveau_vram_pushbuf; -extern int nouveau_vram_notify; -extern char *nouveau_vram_type; -extern int nouveau_fbpercrtc; -extern int nouveau_tv_disable; -extern char *nouveau_tv_norm; -extern int nouveau_reg_debug; -extern char *nouveau_vbios; -extern int nouveau_ignorelid; -extern int nouveau_nofbaccel; -extern int nouveau_noaccel; -extern int nouveau_force_post; -extern int nouveau_override_conntype; -extern char *nouveau_perflvl; -extern int nouveau_perflvl_wr; -extern int nouveau_msi; -extern int nouveau_ctxfw; -extern int nouveau_mxmdcb; - -extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); -extern int nouveau_pci_resume(struct pci_dev *pdev); - -/* nouveau_state.c */ -extern int nouveau_open(struct drm_device *, struct drm_file *); -extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); -extern void nouveau_postclose(struct drm_device *, struct drm_file *); -extern int nouveau_load(struct drm_device *, unsigned long flags); -extern int nouveau_firstopen(struct drm_device *); -extern void nouveau_lastclose(struct drm_device *); -extern int nouveau_unload(struct drm_device *); -extern int nouveau_ioctl_getparam(struct drm_device *, void *data, - struct drm_file *); -extern int nouveau_ioctl_setparam(struct drm_device *, void *data, - struct drm_file *); -extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val); -extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val); -extern bool nouveau_wait_cb(struct drm_device *, u64 timeout, - bool (*cond)(void *), void *); -extern bool nouveau_wait_for_idle(struct drm_device *); -extern int nouveau_card_init(struct drm_device *); - -/* nouveau_mem.c */ -extern int nouveau_mem_vram_init(struct drm_device *); -extern void nouveau_mem_vram_fini(struct drm_device *); -extern int nouveau_mem_gart_init(struct drm_device *); -extern void nouveau_mem_gart_fini(struct drm_device *); -extern int nouveau_mem_init_agp(struct drm_device *); -extern int nouveau_mem_reset_agp(struct drm_device *); -extern void nouveau_mem_close(struct drm_device *); -extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags); -extern int nouveau_mem_timing_calc(struct drm_device *, u32 freq, - struct nouveau_pm_memtiming *); -extern void nouveau_mem_timing_read(struct drm_device *, - struct nouveau_pm_memtiming *); -extern int nouveau_mem_vbios_type(struct drm_device *); -extern struct nouveau_tile_reg *nv10_mem_set_tiling( - struct drm_device *dev, uint32_t addr, uint32_t size, - uint32_t pitch, uint32_t flags); -extern void nv10_mem_put_tile_region(struct drm_device *dev, - struct nouveau_tile_reg *tile, - struct nouveau_fence *fence); -extern const struct ttm_mem_type_manager_func nouveau_vram_manager; -extern const struct ttm_mem_type_manager_func nouveau_gart_manager; - -/* nouveau_notifier.c */ -extern int nouveau_notifier_init_channel(struct nouveau_channel *); -extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); -extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, - int cout, uint32_t start, uint32_t end, - uint32_t *offset); -extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *); -extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, - struct drm_file *); -extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, - struct drm_file *); - -/* nouveau_channel.c */ -extern struct drm_ioctl_desc nouveau_ioctls[]; -extern int nouveau_max_ioctl; -extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *); -extern int nouveau_channel_alloc(struct drm_device *dev, - struct nouveau_channel **chan, - struct drm_file *file_priv, - uint32_t fb_ctxdma, uint32_t tt_ctxdma); -extern struct nouveau_channel * -nouveau_channel_get_unlocked(struct nouveau_channel *); -extern struct nouveau_channel * -nouveau_channel_get(struct drm_file *, int id); -extern void nouveau_channel_put_unlocked(struct nouveau_channel **); -extern void nouveau_channel_put(struct nouveau_channel **); -extern void nouveau_channel_ref(struct nouveau_channel *chan, - struct nouveau_channel **pchan); -extern void nouveau_channel_idle(struct nouveau_channel *chan); - -/* nouveau_object.c */ -#define NVOBJ_ENGINE_ADD(d, e, p) do { \ - struct drm_nouveau_private *dev_priv = (d)->dev_private; \ - dev_priv->eng[NVOBJ_ENGINE_##e] = (p); \ -} while (0) - -#define NVOBJ_ENGINE_DEL(d, e) do { \ - struct drm_nouveau_private *dev_priv = (d)->dev_private; \ - dev_priv->eng[NVOBJ_ENGINE_##e] = NULL; \ -} while (0) - -#define NVOBJ_CLASS(d, c, e) do { \ - int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \ - if (ret) \ - return ret; \ -} while (0) - -#define NVOBJ_MTHD(d, c, m, e) do { \ - int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e)); \ - if (ret) \ - return ret; \ -} while (0) - -extern int nouveau_gpuobj_early_init(struct drm_device *); -extern int nouveau_gpuobj_init(struct drm_device *); -extern void nouveau_gpuobj_takedown(struct drm_device *); -extern int nouveau_gpuobj_suspend(struct drm_device *dev); -extern void nouveau_gpuobj_resume(struct drm_device *dev); -extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); -extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, - int (*exec)(struct nouveau_channel *, - u32 class, u32 mthd, u32 data)); -extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32); -extern int nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32); -extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, - uint32_t vram_h, uint32_t tt_h); -extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); -extern int nouveau_gpuobj_new(struct drm_device *, struct nouveau_channel *, - uint32_t size, int align, uint32_t flags, - struct nouveau_gpuobj **); -extern void nouveau_gpuobj_ref(struct nouveau_gpuobj *, - struct nouveau_gpuobj **); -extern int nouveau_gpuobj_new_fake(struct drm_device *, u32 pinst, u64 vinst, - u32 size, u32 flags, - struct nouveau_gpuobj **); -extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, - uint64_t offset, uint64_t size, int access, - int target, struct nouveau_gpuobj **); -extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, u32 handle, int class); -extern int nv50_gpuobj_dma_new(struct nouveau_channel *, int class, u64 base, - u64 size, int target, int access, u32 type, - u32 comp, struct nouveau_gpuobj **pobj); -extern void nv50_gpuobj_dma_init(struct nouveau_gpuobj *, u32 offset, - int class, u64 base, u64 size, int target, - int access, u32 type, u32 comp); -extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, - struct drm_file *); -extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, - struct drm_file *); - -/* nouveau_irq.c */ -extern int nouveau_irq_init(struct drm_device *); -extern void nouveau_irq_fini(struct drm_device *); -extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); -extern void nouveau_irq_register(struct drm_device *, int status_bit, - void (*)(struct drm_device *)); -extern void nouveau_irq_unregister(struct drm_device *, int status_bit); -extern void nouveau_irq_preinstall(struct drm_device *); -extern int nouveau_irq_postinstall(struct drm_device *); -extern void nouveau_irq_uninstall(struct drm_device *); - -/* nouveau_sgdma.c */ -extern int nouveau_sgdma_init(struct drm_device *); -extern void nouveau_sgdma_takedown(struct drm_device *); -extern uint32_t nouveau_sgdma_get_physical(struct drm_device *, - uint32_t offset); -extern struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev, - unsigned long size, - uint32_t page_flags, - struct page *dummy_read_page); - -/* nouveau_debugfs.c */ -#if defined(CONFIG_DRM_NOUVEAU_DEBUG) -extern int nouveau_debugfs_init(struct drm_minor *); -extern void nouveau_debugfs_takedown(struct drm_minor *); -extern int nouveau_debugfs_channel_init(struct nouveau_channel *); -extern void nouveau_debugfs_channel_fini(struct nouveau_channel *); -#else -static inline int -nouveau_debugfs_init(struct drm_minor *minor) -{ - return 0; -} - -static inline void nouveau_debugfs_takedown(struct drm_minor *minor) -{ -} - -static inline int -nouveau_debugfs_channel_init(struct nouveau_channel *chan) -{ - return 0; -} - -static inline void -nouveau_debugfs_channel_fini(struct nouveau_channel *chan) -{ -} -#endif - -/* nouveau_dma.c */ -extern void nouveau_dma_init(struct nouveau_channel *); -extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); - -/* nouveau_acpi.c */ -#define ROM_BIOS_PAGE 4096 -#if defined(CONFIG_ACPI) -void nouveau_register_dsm_handler(void); -void nouveau_unregister_dsm_handler(void); -void nouveau_switcheroo_optimus_dsm(void); -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); -bool nouveau_acpi_rom_supported(struct pci_dev *pdev); -int nouveau_acpi_edid(struct drm_device *, struct drm_connector *); -#else -static inline void nouveau_register_dsm_handler(void) {} -static inline void nouveau_unregister_dsm_handler(void) {} -static inline void nouveau_switcheroo_optimus_dsm(void) {} -static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } -static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } -static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; } -#endif - -/* nouveau_backlight.c */ -#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT -extern int nouveau_backlight_init(struct drm_device *); -extern void nouveau_backlight_exit(struct drm_device *); -#else -static inline int nouveau_backlight_init(struct drm_device *dev) -{ - return 0; -} - -static inline void nouveau_backlight_exit(struct drm_device *dev) { } -#endif - -/* nouveau_bios.c */ -extern int nouveau_bios_init(struct drm_device *); -extern void nouveau_bios_takedown(struct drm_device *dev); -extern int nouveau_run_vbios_init(struct drm_device *); -extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table, - struct dcb_entry *, int crtc); -extern void nouveau_bios_init_exec(struct drm_device *, uint16_t table); -extern struct dcb_connector_table_entry * -nouveau_bios_connector_entry(struct drm_device *, int index); -extern u32 get_pll_register(struct drm_device *, enum pll_types); -extern int get_pll_limits(struct drm_device *, uint32_t limit_match, - struct pll_lims *); -extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk, - struct dcb_entry *, int crtc); -extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *); -extern uint8_t *nouveau_bios_embedded_edid(struct drm_device *); -extern int nouveau_bios_parse_lvds_table(struct drm_device *, int pxclk, - bool *dl, bool *if_is_24bit); -extern int run_tmds_table(struct drm_device *, struct dcb_entry *, - int head, int pxclk); -extern int call_lvds_script(struct drm_device *, struct dcb_entry *, int head, - enum LVDS_script, int pxclk); -bool bios_encoder_match(struct dcb_entry *, u32 hash); - -/* nouveau_mxm.c */ -int nouveau_mxm_init(struct drm_device *dev); -void nouveau_mxm_fini(struct drm_device *dev); - -/* nouveau_ttm.c */ -int nouveau_ttm_global_init(struct drm_nouveau_private *); -void nouveau_ttm_global_release(struct drm_nouveau_private *); -int nouveau_ttm_mmap(struct file *, struct vm_area_struct *); - -/* nouveau_hdmi.c */ -void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *); - -/* nv04_fb.c */ -extern int nv04_fb_vram_init(struct drm_device *); -extern int nv04_fb_init(struct drm_device *); -extern void nv04_fb_takedown(struct drm_device *); - -/* nv10_fb.c */ -extern int nv10_fb_vram_init(struct drm_device *dev); -extern int nv1a_fb_vram_init(struct drm_device *dev); -extern int nv10_fb_init(struct drm_device *); -extern void nv10_fb_takedown(struct drm_device *); -extern void nv10_fb_init_tile_region(struct drm_device *dev, int i, - uint32_t addr, uint32_t size, - uint32_t pitch, uint32_t flags); -extern void nv10_fb_set_tile_region(struct drm_device *dev, int i); -extern void nv10_fb_free_tile_region(struct drm_device *dev, int i); - -/* nv20_fb.c */ -extern int nv20_fb_vram_init(struct drm_device *dev); -extern int nv20_fb_init(struct drm_device *); -extern void nv20_fb_takedown(struct drm_device *); -extern void nv20_fb_init_tile_region(struct drm_device *dev, int i, - uint32_t addr, uint32_t size, - uint32_t pitch, uint32_t flags); -extern void nv20_fb_set_tile_region(struct drm_device *dev, int i); -extern void nv20_fb_free_tile_region(struct drm_device *dev, int i); - -/* nv30_fb.c */ -extern int nv30_fb_init(struct drm_device *); -extern void nv30_fb_takedown(struct drm_device *); -extern void nv30_fb_init_tile_region(struct drm_device *dev, int i, - uint32_t addr, uint32_t size, - uint32_t pitch, uint32_t flags); -extern void nv30_fb_free_tile_region(struct drm_device *dev, int i); - -/* nv40_fb.c */ -extern int nv40_fb_vram_init(struct drm_device *dev); -extern int nv40_fb_init(struct drm_device *); -extern void nv40_fb_takedown(struct drm_device *); -extern void nv40_fb_set_tile_region(struct drm_device *dev, int i); - -/* nv50_fb.c */ -extern int nv50_fb_init(struct drm_device *); -extern void nv50_fb_takedown(struct drm_device *); -extern void nv50_fb_vm_trap(struct drm_device *, int display); - -/* nvc0_fb.c */ -extern int nvc0_fb_init(struct drm_device *); -extern void nvc0_fb_takedown(struct drm_device *); - -/* nv04_fifo.c */ -extern int nv04_fifo_init(struct drm_device *); -extern void nv04_fifo_fini(struct drm_device *); -extern void nv04_fifo_disable(struct drm_device *); -extern void nv04_fifo_enable(struct drm_device *); -extern bool nv04_fifo_reassign(struct drm_device *, bool); -extern bool nv04_fifo_cache_pull(struct drm_device *, bool); -extern int nv04_fifo_channel_id(struct drm_device *); -extern int nv04_fifo_create_context(struct nouveau_channel *); -extern void nv04_fifo_destroy_context(struct nouveau_channel *); -extern int nv04_fifo_load_context(struct nouveau_channel *); -extern int nv04_fifo_unload_context(struct drm_device *); -extern void nv04_fifo_isr(struct drm_device *); - -/* nv10_fifo.c */ -extern int nv10_fifo_init(struct drm_device *); -extern int nv10_fifo_channel_id(struct drm_device *); -extern int nv10_fifo_create_context(struct nouveau_channel *); -extern int nv10_fifo_load_context(struct nouveau_channel *); -extern int nv10_fifo_unload_context(struct drm_device *); - -/* nv40_fifo.c */ -extern int nv40_fifo_init(struct drm_device *); -extern int nv40_fifo_create_context(struct nouveau_channel *); -extern int nv40_fifo_load_context(struct nouveau_channel *); -extern int nv40_fifo_unload_context(struct drm_device *); - -/* nv50_fifo.c */ -extern int nv50_fifo_init(struct drm_device *); -extern void nv50_fifo_takedown(struct drm_device *); -extern int nv50_fifo_channel_id(struct drm_device *); -extern int nv50_fifo_create_context(struct nouveau_channel *); -extern void nv50_fifo_destroy_context(struct nouveau_channel *); -extern int nv50_fifo_load_context(struct nouveau_channel *); -extern int nv50_fifo_unload_context(struct drm_device *); -extern void nv50_fifo_tlb_flush(struct drm_device *dev); - -/* nvc0_fifo.c */ -extern int nvc0_fifo_init(struct drm_device *); -extern void nvc0_fifo_takedown(struct drm_device *); -extern void nvc0_fifo_disable(struct drm_device *); -extern void nvc0_fifo_enable(struct drm_device *); -extern bool nvc0_fifo_reassign(struct drm_device *, bool); -extern bool nvc0_fifo_cache_pull(struct drm_device *, bool); -extern int nvc0_fifo_channel_id(struct drm_device *); -extern int nvc0_fifo_create_context(struct nouveau_channel *); -extern void nvc0_fifo_destroy_context(struct nouveau_channel *); -extern int nvc0_fifo_load_context(struct nouveau_channel *); -extern int nvc0_fifo_unload_context(struct drm_device *); - -/* nv04_graph.c */ -extern int nv04_graph_create(struct drm_device *); -extern int nv04_graph_object_new(struct nouveau_channel *, int, u32, u16); -extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data); -extern struct nouveau_bitfield nv04_graph_nsource[]; - -/* nv10_graph.c */ -extern int nv10_graph_create(struct drm_device *); -extern struct nouveau_channel *nv10_graph_channel(struct drm_device *); -extern struct nouveau_bitfield nv10_graph_intr[]; -extern struct nouveau_bitfield nv10_graph_nstatus[]; - -/* nv20_graph.c */ -extern int nv20_graph_create(struct drm_device *); - -/* nv40_graph.c */ -extern int nv40_graph_create(struct drm_device *); -extern void nv40_grctx_init(struct nouveau_grctx *); - -/* nv50_graph.c */ -extern int nv50_graph_create(struct drm_device *); -extern int nv50_grctx_init(struct nouveau_grctx *); -extern struct nouveau_enum nv50_data_error_names[]; -extern int nv50_graph_isr_chid(struct drm_device *dev, u64 inst); - -/* nvc0_graph.c */ -extern int nvc0_graph_create(struct drm_device *); -extern int nvc0_graph_isr_chid(struct drm_device *dev, u64 inst); - -/* nv84_crypt.c */ -extern int nv84_crypt_create(struct drm_device *); - -/* nv98_crypt.c */ -extern int nv98_crypt_create(struct drm_device *dev); - -/* nva3_copy.c */ -extern int nva3_copy_create(struct drm_device *dev); - -/* nvc0_copy.c */ -extern int nvc0_copy_create(struct drm_device *dev, int engine); - -/* nv31_mpeg.c */ -extern int nv31_mpeg_create(struct drm_device *dev); - -/* nv50_mpeg.c */ -extern int nv50_mpeg_create(struct drm_device *dev); - -/* nv84_bsp.c */ -/* nv98_bsp.c */ -extern int nv84_bsp_create(struct drm_device *dev); - -/* nv84_vp.c */ -/* nv98_vp.c */ -extern int nv84_vp_create(struct drm_device *dev); - -/* nv98_ppp.c */ -extern int nv98_ppp_create(struct drm_device *dev); - -/* nv04_instmem.c */ -extern int nv04_instmem_init(struct drm_device *); -extern void nv04_instmem_takedown(struct drm_device *); -extern int nv04_instmem_suspend(struct drm_device *); -extern void nv04_instmem_resume(struct drm_device *); -extern int nv04_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *, - u32 size, u32 align); -extern void nv04_instmem_put(struct nouveau_gpuobj *); -extern int nv04_instmem_map(struct nouveau_gpuobj *); -extern void nv04_instmem_unmap(struct nouveau_gpuobj *); -extern void nv04_instmem_flush(struct drm_device *); - -/* nv50_instmem.c */ -extern int nv50_instmem_init(struct drm_device *); -extern void nv50_instmem_takedown(struct drm_device *); -extern int nv50_instmem_suspend(struct drm_device *); -extern void nv50_instmem_resume(struct drm_device *); -extern int nv50_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *, - u32 size, u32 align); -extern void nv50_instmem_put(struct nouveau_gpuobj *); -extern int nv50_instmem_map(struct nouveau_gpuobj *); -extern void nv50_instmem_unmap(struct nouveau_gpuobj *); -extern void nv50_instmem_flush(struct drm_device *); -extern void nv84_instmem_flush(struct drm_device *); - -/* nvc0_instmem.c */ -extern int nvc0_instmem_init(struct drm_device *); -extern void nvc0_instmem_takedown(struct drm_device *); -extern int nvc0_instmem_suspend(struct drm_device *); -extern void nvc0_instmem_resume(struct drm_device *); - -/* nv04_mc.c */ -extern int nv04_mc_init(struct drm_device *); -extern void nv04_mc_takedown(struct drm_device *); - -/* nv40_mc.c */ -extern int nv40_mc_init(struct drm_device *); -extern void nv40_mc_takedown(struct drm_device *); - -/* nv50_mc.c */ -extern int nv50_mc_init(struct drm_device *); -extern void nv50_mc_takedown(struct drm_device *); - -/* nv04_timer.c */ -extern int nv04_timer_init(struct drm_device *); -extern uint64_t nv04_timer_read(struct drm_device *); -extern void nv04_timer_takedown(struct drm_device *); - -extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long arg); - -/* nv04_dac.c */ -extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *); -extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); -extern int nv04_dac_output_offset(struct drm_encoder *encoder); -extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); -extern bool nv04_dac_in_use(struct drm_encoder *encoder); - -/* nv04_dfp.c */ -extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *); -extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); -extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, - int head, bool dl); -extern void nv04_dfp_disable(struct drm_device *dev, int head); -extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode); - -/* nv04_tv.c */ -extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); -extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *); - -/* nv17_tv.c */ -extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); - -/* nv04_display.c */ -extern int nv04_display_early_init(struct drm_device *); -extern void nv04_display_late_takedown(struct drm_device *); -extern int nv04_display_create(struct drm_device *); -extern void nv04_display_destroy(struct drm_device *); -extern int nv04_display_init(struct drm_device *); -extern void nv04_display_fini(struct drm_device *); - -/* nvd0_display.c */ -extern int nvd0_display_create(struct drm_device *); -extern void nvd0_display_destroy(struct drm_device *); -extern int nvd0_display_init(struct drm_device *); -extern void nvd0_display_fini(struct drm_device *); -struct nouveau_bo *nvd0_display_crtc_sema(struct drm_device *, int crtc); -void nvd0_display_flip_stop(struct drm_crtc *); -int nvd0_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, - struct nouveau_channel *, u32 swap_interval); - -/* nv04_crtc.c */ -extern int nv04_crtc_create(struct drm_device *, int index); - -/* nouveau_bo.c */ -extern struct ttm_bo_driver nouveau_bo_driver; -extern int nouveau_bo_new(struct drm_device *, int size, int align, - uint32_t flags, uint32_t tile_mode, - uint32_t tile_flags, struct nouveau_bo **); -extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); -extern int nouveau_bo_unpin(struct nouveau_bo *); -extern int nouveau_bo_map(struct nouveau_bo *); -extern void nouveau_bo_unmap(struct nouveau_bo *); -extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type, - uint32_t busy); -extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); -extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); -extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); -extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); -extern void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *); -extern int nouveau_bo_validate(struct nouveau_bo *, bool interruptible, - bool no_wait_reserve, bool no_wait_gpu); - -extern struct nouveau_vma * -nouveau_bo_vma_find(struct nouveau_bo *, struct nouveau_vm *); -extern int nouveau_bo_vma_add(struct nouveau_bo *, struct nouveau_vm *, - struct nouveau_vma *); -extern void nouveau_bo_vma_del(struct nouveau_bo *, struct nouveau_vma *); - -/* nouveau_fence.c */ -struct nouveau_fence; -extern int nouveau_fence_init(struct drm_device *); -extern void nouveau_fence_fini(struct drm_device *); -extern int nouveau_fence_channel_init(struct nouveau_channel *); -extern void nouveau_fence_channel_fini(struct nouveau_channel *); -extern void nouveau_fence_update(struct nouveau_channel *); -extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **, - bool emit); -extern int nouveau_fence_emit(struct nouveau_fence *); -extern void nouveau_fence_work(struct nouveau_fence *fence, - void (*work)(void *priv, bool signalled), - void *priv); -struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *); - -extern bool __nouveau_fence_signalled(void *obj, void *arg); -extern int __nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); -extern int __nouveau_fence_flush(void *obj, void *arg); -extern void __nouveau_fence_unref(void **obj); -extern void *__nouveau_fence_ref(void *obj); - -static inline bool nouveau_fence_signalled(struct nouveau_fence *obj) -{ - return __nouveau_fence_signalled(obj, NULL); -} -static inline int -nouveau_fence_wait(struct nouveau_fence *obj, bool lazy, bool intr) -{ - return __nouveau_fence_wait(obj, NULL, lazy, intr); -} -extern int nouveau_fence_sync(struct nouveau_fence *, struct nouveau_channel *); -static inline int nouveau_fence_flush(struct nouveau_fence *obj) -{ - return __nouveau_fence_flush(obj, NULL); -} -static inline void nouveau_fence_unref(struct nouveau_fence **obj) -{ - __nouveau_fence_unref((void **)obj); -} -static inline struct nouveau_fence *nouveau_fence_ref(struct nouveau_fence *obj) -{ - return __nouveau_fence_ref(obj); -} - -/* nouveau_gem.c */ -extern int nouveau_gem_new(struct drm_device *, int size, int align, - uint32_t domain, uint32_t tile_mode, - uint32_t tile_flags, struct nouveau_bo **); -extern int nouveau_gem_object_new(struct drm_gem_object *); -extern void nouveau_gem_object_del(struct drm_gem_object *); -extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *); -extern void nouveau_gem_object_close(struct drm_gem_object *, - struct drm_file *); -extern int nouveau_gem_ioctl_new(struct drm_device *, void *, - struct drm_file *); -extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, - struct drm_file *); -extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *, - struct drm_file *); -extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, - struct drm_file *); -extern int nouveau_gem_ioctl_info(struct drm_device *, void *, - struct drm_file *); - -/* nouveau_display.c */ -int nouveau_display_create(struct drm_device *dev); -void nouveau_display_destroy(struct drm_device *dev); -int nouveau_display_init(struct drm_device *dev); -void nouveau_display_fini(struct drm_device *dev); -int nouveau_vblank_enable(struct drm_device *dev, int crtc); -void nouveau_vblank_disable(struct drm_device *dev, int crtc); -int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event); -int nouveau_finish_page_flip(struct nouveau_channel *, - struct nouveau_page_flip_state *); -int nouveau_display_dumb_create(struct drm_file *, struct drm_device *, - struct drm_mode_create_dumb *args); -int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *, - uint32_t handle, uint64_t *offset); -int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *, - uint32_t handle); - -/* nv10_gpio.c */ -int nv10_gpio_init(struct drm_device *dev); -void nv10_gpio_fini(struct drm_device *dev); -int nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out); -int nv10_gpio_sense(struct drm_device *dev, int line); -void nv10_gpio_irq_enable(struct drm_device *, int line, bool on); - -/* nv50_gpio.c */ -int nv50_gpio_init(struct drm_device *dev); -void nv50_gpio_fini(struct drm_device *dev); -int nv50_gpio_drive(struct drm_device *dev, int line, int dir, int out); -int nv50_gpio_sense(struct drm_device *dev, int line); -void nv50_gpio_irq_enable(struct drm_device *, int line, bool on); -int nvd0_gpio_drive(struct drm_device *dev, int line, int dir, int out); -int nvd0_gpio_sense(struct drm_device *dev, int line); - -/* nv50_calc.c */ -int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, - int *N1, int *M1, int *N2, int *M2, int *P); -int nva3_calc_pll(struct drm_device *, struct pll_lims *, - int clk, int *N, int *fN, int *M, int *P); - -#ifndef ioread32_native -#ifdef __BIG_ENDIAN -#define ioread16_native ioread16be -#define iowrite16_native iowrite16be -#define ioread32_native ioread32be -#define iowrite32_native iowrite32be -#else /* def __BIG_ENDIAN */ -#define ioread16_native ioread16 -#define iowrite16_native iowrite16 -#define ioread32_native ioread32 -#define iowrite32_native iowrite32 -#endif /* def __BIG_ENDIAN else */ -#endif /* !ioread32_native */ - -/* channel control reg access */ -static inline u32 nvchan_rd32(struct nouveau_channel *chan, unsigned reg) -{ - return ioread32_native(chan->user + reg); -} - -static inline void nvchan_wr32(struct nouveau_channel *chan, - unsigned reg, u32 val) -{ - iowrite32_native(val, chan->user + reg); -} - -/* register access */ -static inline u32 nv_rd32(struct drm_device *dev, unsigned reg) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return ioread32_native(dev_priv->mmio + reg); -} - -static inline void nv_wr32(struct drm_device *dev, unsigned reg, u32 val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - iowrite32_native(val, dev_priv->mmio + reg); -} - -static inline u32 nv_mask(struct drm_device *dev, u32 reg, u32 mask, u32 val) -{ - u32 tmp = nv_rd32(dev, reg); - nv_wr32(dev, reg, (tmp & ~mask) | val); - return tmp; -} - -static inline u8 nv_rd08(struct drm_device *dev, unsigned reg) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return ioread8(dev_priv->mmio + reg); -} - -static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - iowrite8(val, dev_priv->mmio + reg); -} - -#define nv_wait(dev, reg, mask, val) \ - nouveau_wait_eq(dev, 2000000000ULL, (reg), (mask), (val)) -#define nv_wait_ne(dev, reg, mask, val) \ - nouveau_wait_ne(dev, 2000000000ULL, (reg), (mask), (val)) -#define nv_wait_cb(dev, func, data) \ - nouveau_wait_cb(dev, 2000000000ULL, (func), (data)) - -/* PRAMIN access */ -static inline u32 nv_ri32(struct drm_device *dev, unsigned offset) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return ioread32_native(dev_priv->ramin + offset); -} - -static inline void nv_wi32(struct drm_device *dev, unsigned offset, u32 val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - iowrite32_native(val, dev_priv->ramin + offset); -} - -/* object access */ -extern u32 nv_ro32(struct nouveau_gpuobj *, u32 offset); -extern void nv_wo32(struct nouveau_gpuobj *, u32 offset, u32 val); - -/* - * Logging - * Argument d is (struct drm_device *). - */ -#define NV_PRINTK(level, d, fmt, arg...) \ - printk(level "[" DRM_NAME "] " DRIVER_NAME " %s: " fmt, \ - pci_name(d->pdev), ##arg) -#ifndef NV_DEBUG_NOTRACE -#define NV_DEBUG(d, fmt, arg...) do { \ - if (drm_debug & DRM_UT_DRIVER) { \ - NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ - __LINE__, ##arg); \ - } \ -} while (0) -#define NV_DEBUG_KMS(d, fmt, arg...) do { \ - if (drm_debug & DRM_UT_KMS) { \ - NV_PRINTK(KERN_DEBUG, d, "%s:%d - " fmt, __func__, \ - __LINE__, ##arg); \ - } \ -} while (0) -#else -#define NV_DEBUG(d, fmt, arg...) do { \ - if (drm_debug & DRM_UT_DRIVER) \ - NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ -} while (0) -#define NV_DEBUG_KMS(d, fmt, arg...) do { \ - if (drm_debug & DRM_UT_KMS) \ - NV_PRINTK(KERN_DEBUG, d, fmt, ##arg); \ -} while (0) -#endif -#define NV_ERROR(d, fmt, arg...) NV_PRINTK(KERN_ERR, d, fmt, ##arg) -#define NV_INFO(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg) -#define NV_TRACEWARN(d, fmt, arg...) NV_PRINTK(KERN_NOTICE, d, fmt, ##arg) -#define NV_TRACE(d, fmt, arg...) NV_PRINTK(KERN_INFO, d, fmt, ##arg) -#define NV_WARN(d, fmt, arg...) NV_PRINTK(KERN_WARNING, d, fmt, ##arg) -#define NV_WARNONCE(d, fmt, arg...) do { \ - static int _warned = 0; \ - if (!_warned) { \ - NV_WARN(d, fmt, ##arg); \ - _warned = 1; \ - } \ -} while(0) - -/* nouveau_reg_debug bitmask */ -enum { - NOUVEAU_REG_DEBUG_MC = 0x1, - NOUVEAU_REG_DEBUG_VIDEO = 0x2, - NOUVEAU_REG_DEBUG_FB = 0x4, - NOUVEAU_REG_DEBUG_EXTDEV = 0x8, - NOUVEAU_REG_DEBUG_CRTC = 0x10, - NOUVEAU_REG_DEBUG_RAMDAC = 0x20, - NOUVEAU_REG_DEBUG_VGACRTC = 0x40, - NOUVEAU_REG_DEBUG_RMVIO = 0x80, - NOUVEAU_REG_DEBUG_VGAATTR = 0x100, - NOUVEAU_REG_DEBUG_EVO = 0x200, - NOUVEAU_REG_DEBUG_AUXCH = 0x400 -}; - -#define NV_REG_DEBUG(type, dev, fmt, arg...) do { \ - if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_##type) \ - NV_PRINTK(KERN_DEBUG, dev, "%s: " fmt, __func__, ##arg); \ -} while (0) - -static inline bool -nv_two_heads(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - const int impl = dev->pci_device & 0x0ff0; - - if (dev_priv->card_type >= NV_10 && impl != 0x0100 && - impl != 0x0150 && impl != 0x01a0 && impl != 0x0200) - return true; - - return false; -} - -static inline bool -nv_gf4_disp_arch(struct drm_device *dev) -{ - return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110; -} - -static inline bool -nv_two_reg_pll(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - const int impl = dev->pci_device & 0x0ff0; - - if (impl == 0x0310 || impl == 0x0340 || dev_priv->card_type >= NV_40) - return true; - return false; -} - -static inline bool -nv_match_device(struct drm_device *dev, unsigned device, - unsigned sub_vendor, unsigned sub_device) -{ - return dev->pdev->device == device && - dev->pdev->subsystem_vendor == sub_vendor && - dev->pdev->subsystem_device == sub_device; -} - -static inline void * -nv_engine(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return (void *)dev_priv->eng[engine]; -} - -/* returns 1 if device is one of the nv4x using the 0x4497 object class, - * helpful to determine a number of other hardware features - */ -static inline int -nv44_graph_class(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if ((dev_priv->chipset & 0xf0) == 0x60) - return 1; - - return !(0x0baf & (1 << (dev_priv->chipset & 0x0f))); -} - -/* memory type/access flags, do not match hardware values */ -#define NV_MEM_ACCESS_RO 1 -#define NV_MEM_ACCESS_WO 2 -#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO) -#define NV_MEM_ACCESS_SYS 4 -#define NV_MEM_ACCESS_VM 8 -#define NV_MEM_ACCESS_NOSNOOP 16 - -#define NV_MEM_TARGET_VRAM 0 -#define NV_MEM_TARGET_PCI 1 -#define NV_MEM_TARGET_PCI_NOSNOOP 2 -#define NV_MEM_TARGET_VM 3 -#define NV_MEM_TARGET_GART 4 - -#define NV_MEM_TYPE_VM 0x7f -#define NV_MEM_COMP_VM 0x03 - -/* FIFO methods */ -#define NV01_SUBCHAN_OBJECT 0x00000000 -#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH 0x00000010 -#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_LOW 0x00000014 -#define NV84_SUBCHAN_SEMAPHORE_SEQUENCE 0x00000018 -#define NV84_SUBCHAN_SEMAPHORE_TRIGGER 0x0000001c -#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL 0x00000001 -#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG 0x00000002 -#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL 0x00000004 -#define NV84_SUBCHAN_NOTIFY_INTR 0x00000020 -#define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024 -#define NV10_SUBCHAN_REF_CNT 0x00000050 -#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054 -#define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060 -#define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064 -#define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068 -#define NV11_SUBCHAN_SEMAPHORE_RELEASE 0x0000006c -#define NV40_SUBCHAN_YIELD 0x00000080 - -/* NV_SW object class */ -#define NV_SW 0x0000506e -#define NV_SW_DMA_VBLSEM 0x0000018c -#define NV_SW_VBLSEM_OFFSET 0x00000400 -#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404 -#define NV_SW_VBLSEM_RELEASE 0x00000408 -#define NV_SW_PAGE_FLIP 0x00000500 - -#endif /* __NOUVEAU_DRV_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_encoder.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_encoder.h deleted file mode 100644 index 3dc14a3d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_ENCODER_H__ -#define __NOUVEAU_ENCODER_H__ - -#include "drm_encoder_slave.h" -#include "nouveau_drv.h" - -#define NV_DPMS_CLEARED 0x80 - -struct dp_train_func { - void (*link_set)(struct drm_device *, struct dcb_entry *, int crtc, - int nr, u32 bw, bool enhframe); - void (*train_set)(struct drm_device *, struct dcb_entry *, u8 pattern); - void (*train_adj)(struct drm_device *, struct dcb_entry *, - u8 lane, u8 swing, u8 preem); -}; - -struct nouveau_encoder { - struct drm_encoder_slave base; - - struct dcb_entry *dcb; - int or; - - /* different to drm_encoder.crtc, this reflects what's - * actually programmed on the hw, not the proposed crtc */ - struct drm_crtc *crtc; - - struct drm_display_mode mode; - int last_dpms; - - struct nv04_output_reg restore; - - union { - struct { - u8 dpcd[8]; - int link_nr; - int link_bw; - u32 datarate; - } dp; - }; -}; - -struct nouveau_encoder * -find_encoder(struct drm_connector *connector, int type); - -static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc) -{ - struct drm_encoder_slave *slave = to_encoder_slave(enc); - - return container_of(slave, struct nouveau_encoder, base); -} - -static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc) -{ - return &enc->base.base; -} - -static inline struct drm_encoder_slave_funcs * -get_slave_funcs(struct drm_encoder *enc) -{ - return to_encoder_slave(enc)->slave_funcs; -} - -/* nouveau_dp.c */ -int nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, - uint8_t *data, int data_nr); -bool nouveau_dp_detect(struct drm_encoder *); -void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate, - struct dp_train_func *); -u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_entry *, u8 **); - -struct nouveau_connector * -nouveau_encoder_connector_get(struct nouveau_encoder *encoder); -int nv50_sor_create(struct drm_connector *, struct dcb_entry *); -void nv50_sor_dp_calc_tu(struct drm_device *, int, int, u32, u32); -int nv50_dac_create(struct drm_connector *, struct dcb_entry *); - - -#endif /* __NOUVEAU_ENCODER_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fb.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fb.h deleted file mode 100644 index f3fb649f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fb.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_FB_H__ -#define __NOUVEAU_FB_H__ - -struct nouveau_framebuffer { - struct drm_framebuffer base; - struct nouveau_bo *nvbo; - struct nouveau_vma vma; - u32 r_dma; - u32 r_format; - u32 r_pitch; -}; - -static inline struct nouveau_framebuffer * -nouveau_framebuffer(struct drm_framebuffer *fb) -{ - return container_of(fb, struct nouveau_framebuffer, base); -} - -int nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb, - struct drm_mode_fb_cmd2 *mode_cmd, struct nouveau_bo *nvbo); -#endif /* __NOUVEAU_FB_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.c deleted file mode 100644 index 6fd22111..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - * Copyright © 2007 David Airlie - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * David Airlie - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_crtc.h" -#include "nouveau_fb.h" -#include "nouveau_fbcon.h" -#include "nouveau_dma.h" - -static void -nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int ret; - - if (info->state != FBINFO_STATE_RUNNING) - return; - - ret = -ENODEV; - if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) && - mutex_trylock(&dev_priv->channel->mutex)) { - if (dev_priv->card_type < NV_50) - ret = nv04_fbcon_fillrect(info, rect); - else - if (dev_priv->card_type < NV_C0) - ret = nv50_fbcon_fillrect(info, rect); - else - ret = nvc0_fbcon_fillrect(info, rect); - mutex_unlock(&dev_priv->channel->mutex); - } - - if (ret == 0) - return; - - if (ret != -ENODEV) - nouveau_fbcon_gpu_lockup(info); - cfb_fillrect(info, rect); -} - -static void -nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int ret; - - if (info->state != FBINFO_STATE_RUNNING) - return; - - ret = -ENODEV; - if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) && - mutex_trylock(&dev_priv->channel->mutex)) { - if (dev_priv->card_type < NV_50) - ret = nv04_fbcon_copyarea(info, image); - else - if (dev_priv->card_type < NV_C0) - ret = nv50_fbcon_copyarea(info, image); - else - ret = nvc0_fbcon_copyarea(info, image); - mutex_unlock(&dev_priv->channel->mutex); - } - - if (ret == 0) - return; - - if (ret != -ENODEV) - nouveau_fbcon_gpu_lockup(info); - cfb_copyarea(info, image); -} - -static void -nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int ret; - - if (info->state != FBINFO_STATE_RUNNING) - return; - - ret = -ENODEV; - if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) && - mutex_trylock(&dev_priv->channel->mutex)) { - if (dev_priv->card_type < NV_50) - ret = nv04_fbcon_imageblit(info, image); - else - if (dev_priv->card_type < NV_C0) - ret = nv50_fbcon_imageblit(info, image); - else - ret = nvc0_fbcon_imageblit(info, image); - mutex_unlock(&dev_priv->channel->mutex); - } - - if (ret == 0) - return; - - if (ret != -ENODEV) - nouveau_fbcon_gpu_lockup(info); - cfb_imageblit(info, image); -} - -static int -nouveau_fbcon_sync(struct fb_info *info) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret, i; - - if (!chan || !chan->accel_done || in_interrupt() || - info->state != FBINFO_STATE_RUNNING || - info->flags & FBINFO_HWACCEL_DISABLED) - return 0; - - if (!mutex_trylock(&chan->mutex)) - return 0; - - ret = RING_SPACE(chan, 4); - if (ret) { - mutex_unlock(&chan->mutex); - nouveau_fbcon_gpu_lockup(info); - return 0; - } - - if (dev_priv->card_type >= NV_C0) { - BEGIN_NVC0(chan, 2, NvSub2D, 0x010c, 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0100, 1); - OUT_RING (chan, 0); - } else { - BEGIN_RING(chan, 0, 0x0104, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, 0, 0x0100, 1); - OUT_RING (chan, 0); - } - - nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3, 0xffffffff); - FIRE_RING(chan); - mutex_unlock(&chan->mutex); - - ret = -EBUSY; - for (i = 0; i < 100000; i++) { - if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3)) { - ret = 0; - break; - } - DRM_UDELAY(1); - } - - if (ret) { - nouveau_fbcon_gpu_lockup(info); - return 0; - } - - chan->accel_done = false; - return 0; -} - -static struct fb_ops nouveau_fbcon_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = nouveau_fbcon_fillrect, - .fb_copyarea = nouveau_fbcon_copyarea, - .fb_imageblit = nouveau_fbcon_imageblit, - .fb_sync = nouveau_fbcon_sync, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, -}; - -static struct fb_ops nouveau_fbcon_sw_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, -}; - -static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nv_crtc->lut.r[regno] = red; - nv_crtc->lut.g[regno] = green; - nv_crtc->lut.b[regno] = blue; -} - -static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - *red = nv_crtc->lut.r[regno]; - *green = nv_crtc->lut.g[regno]; - *blue = nv_crtc->lut.b[regno]; -} - -static void -nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev) -{ - struct fb_info *info = nfbdev->helper.fbdev; - struct fb_fillrect rect; - - /* Clear the entire fbcon. The drm will program every connector - * with it's preferred mode. If the sizes differ, one display will - * quite likely have garbage around the console. - */ - rect.dx = rect.dy = 0; - rect.width = info->var.xres_virtual; - rect.height = info->var.yres_virtual; - rect.color = 0; - rect.rop = ROP_COPY; - info->fbops->fb_fillrect(info, &rect); -} - -static int -nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct fb_info *info; - struct drm_framebuffer *fb; - struct nouveau_framebuffer *nouveau_fb; - struct nouveau_channel *chan; - struct nouveau_bo *nvbo; - struct drm_mode_fb_cmd2 mode_cmd; - struct pci_dev *pdev = dev->pdev; - struct device *device = &pdev->dev; - int size, ret; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - - mode_cmd.pitches[0] = mode_cmd.width * (sizes->surface_bpp >> 3); - mode_cmd.pitches[0] = roundup(mode_cmd.pitches[0], 256); - - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - size = mode_cmd.pitches[0] * mode_cmd.height; - size = roundup(size, PAGE_SIZE); - - ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM, - 0, 0x0000, &nvbo); - if (ret) { - NV_ERROR(dev, "failed to allocate framebuffer\n"); - goto out; - } - - ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM); - if (ret) { - NV_ERROR(dev, "failed to pin fb: %d\n", ret); - nouveau_bo_ref(NULL, &nvbo); - goto out; - } - - ret = nouveau_bo_map(nvbo); - if (ret) { - NV_ERROR(dev, "failed to map fb: %d\n", ret); - nouveau_bo_unpin(nvbo); - nouveau_bo_ref(NULL, &nvbo); - goto out; - } - - chan = nouveau_nofbaccel ? NULL : dev_priv->channel; - if (chan && dev_priv->card_type >= NV_50) { - ret = nouveau_bo_vma_add(nvbo, chan->vm, &nfbdev->nouveau_fb.vma); - if (ret) { - NV_ERROR(dev, "failed to map fb into chan: %d\n", ret); - chan = NULL; - } - } - - mutex_lock(&dev->struct_mutex); - - info = framebuffer_alloc(0, device); - if (!info) { - ret = -ENOMEM; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; - } - - info->par = nfbdev; - - nouveau_framebuffer_init(dev, &nfbdev->nouveau_fb, &mode_cmd, nvbo); - - nouveau_fb = &nfbdev->nouveau_fb; - fb = &nouveau_fb->base; - - /* setup helper */ - nfbdev->helper.fb = fb; - nfbdev->helper.fbdev = info; - - strcpy(info->fix.id, "nouveaufb"); - if (nouveau_nofbaccel) - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED; - else - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | - FBINFO_HWACCEL_FILLRECT | - FBINFO_HWACCEL_IMAGEBLIT; - info->flags |= FBINFO_CAN_FORCE_OUTPUT; - info->fbops = &nouveau_fbcon_sw_ops; - info->fix.smem_start = nvbo->bo.mem.bus.base + - nvbo->bo.mem.bus.offset; - info->fix.smem_len = size; - - info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo); - info->screen_size = size; - - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); - drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height); - - /* Set aperture base/size for vesafb takeover */ - info->apertures = dev_priv->apertures; - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } - - /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - - mutex_unlock(&dev->struct_mutex); - - if (dev_priv->channel && !nouveau_nofbaccel) { - ret = -ENODEV; - if (dev_priv->card_type < NV_50) - ret = nv04_fbcon_accel_init(info); - else - if (dev_priv->card_type < NV_C0) - ret = nv50_fbcon_accel_init(info); - else - ret = nvc0_fbcon_accel_init(info); - - if (ret == 0) - info->fbops = &nouveau_fbcon_ops; - } - - nouveau_fbcon_zfill(dev, nfbdev); - - /* To allow resizeing without swapping buffers */ - NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n", - nouveau_fb->base.width, - nouveau_fb->base.height, - nvbo->bo.offset, nvbo); - - vga_switcheroo_client_fb_set(dev->pdev, info); - return 0; - -out_unref: - mutex_unlock(&dev->struct_mutex); -out: - return ret; -} - -static int -nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct nouveau_fbdev *nfbdev = (struct nouveau_fbdev *)helper; - int new_fb = 0; - int ret; - - if (!helper->fb) { - ret = nouveau_fbcon_create(nfbdev, sizes); - if (ret) - return ret; - new_fb = 1; - } - return new_fb; -} - -void -nouveau_fbcon_output_poll_changed(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper); -} - -static int -nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) -{ - struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb; - struct fb_info *info; - - if (nfbdev->helper.fbdev) { - info = nfbdev->helper.fbdev; - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } - - if (nouveau_fb->nvbo) { - nouveau_bo_unmap(nouveau_fb->nvbo); - nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma); - drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); - nouveau_fb->nvbo = NULL; - } - drm_fb_helper_fini(&nfbdev->helper); - drm_framebuffer_cleanup(&nouveau_fb->base); - return 0; -} - -void nouveau_fbcon_gpu_lockup(struct fb_info *info) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - - NV_ERROR(dev, "GPU lockup - switching to software fbcon\n"); - info->flags |= FBINFO_HWACCEL_DISABLED; -} - -static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { - .gamma_set = nouveau_fbcon_gamma_set, - .gamma_get = nouveau_fbcon_gamma_get, - .fb_probe = nouveau_fbcon_find_or_create_single, -}; - - -int nouveau_fbcon_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fbdev *nfbdev; - int preferred_bpp; - int ret; - - nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); - if (!nfbdev) - return -ENOMEM; - - nfbdev->dev = dev; - dev_priv->nfbdev = nfbdev; - nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; - - ret = drm_fb_helper_init(dev, &nfbdev->helper, - dev->mode_config.num_crtc, 4); - if (ret) { - kfree(nfbdev); - return ret; - } - - drm_fb_helper_single_add_all_connectors(&nfbdev->helper); - - if (dev_priv->vram_size <= 32 * 1024 * 1024) - preferred_bpp = 8; - else if (dev_priv->vram_size <= 64 * 1024 * 1024) - preferred_bpp = 16; - else - preferred_bpp = 32; - - drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp); - return 0; -} - -void nouveau_fbcon_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (!dev_priv->nfbdev) - return; - - nouveau_fbcon_destroy(dev, dev_priv->nfbdev); - kfree(dev_priv->nfbdev); - dev_priv->nfbdev = NULL; -} - -void nouveau_fbcon_save_disable_accel(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - dev_priv->nfbdev->saved_flags = dev_priv->nfbdev->helper.fbdev->flags; - dev_priv->nfbdev->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; -} - -void nouveau_fbcon_restore_accel(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - dev_priv->nfbdev->helper.fbdev->flags = dev_priv->nfbdev->saved_flags; -} - -void nouveau_fbcon_set_suspend(struct drm_device *dev, int state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - console_lock(); - if (state == 0) - nouveau_fbcon_save_disable_accel(dev); - fb_set_suspend(dev_priv->nfbdev->helper.fbdev, state); - if (state == 1) - nouveau_fbcon_restore_accel(dev); - console_unlock(); -} - -void nouveau_fbcon_zfill_all(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - nouveau_fbcon_zfill(dev, dev_priv->nfbdev); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.h deleted file mode 100644 index b73c29f8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_FBCON_H__ -#define __NOUVEAU_FBCON_H__ - -#include "drm_fb_helper.h" - -#include "nouveau_fb.h" -struct nouveau_fbdev { - struct drm_fb_helper helper; - struct nouveau_framebuffer nouveau_fb; - struct list_head fbdev_list; - struct drm_device *dev; - unsigned int saved_flags; -}; - -void nouveau_fbcon_restore(void); - -int nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); -int nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -int nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); -int nv04_fbcon_accel_init(struct fb_info *info); - -int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -int nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); -int nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); -int nv50_fbcon_accel_init(struct fb_info *info); - -int nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -int nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); -int nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); -int nvc0_fbcon_accel_init(struct fb_info *info); - -void nouveau_fbcon_gpu_lockup(struct fb_info *info); - -int nouveau_fbcon_init(struct drm_device *dev); -void nouveau_fbcon_fini(struct drm_device *dev); -void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); -void nouveau_fbcon_zfill_all(struct drm_device *dev); -void nouveau_fbcon_save_disable_accel(struct drm_device *dev); -void nouveau_fbcon_restore_accel(struct drm_device *dev); - -void nouveau_fbcon_output_poll_changed(struct drm_device *dev); -#endif /* __NV50_FBCON_H__ */ - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fence.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fence.c deleted file mode 100644 index c1dc20f6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_fence.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" - -#include -#include - -#include "nouveau_drv.h" -#include "nouveau_ramht.h" -#include "nouveau_dma.h" - -#define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10) -#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17) - -struct nouveau_fence { - struct nouveau_channel *channel; - struct kref refcount; - struct list_head entry; - - uint32_t sequence; - bool signalled; - - void (*work)(void *priv, bool signalled); - void *priv; -}; - -struct nouveau_semaphore { - struct kref ref; - struct drm_device *dev; - struct drm_mm_node *mem; -}; - -static inline struct nouveau_fence * -nouveau_fence(void *sync_obj) -{ - return (struct nouveau_fence *)sync_obj; -} - -static void -nouveau_fence_del(struct kref *ref) -{ - struct nouveau_fence *fence = - container_of(ref, struct nouveau_fence, refcount); - - nouveau_channel_ref(NULL, &fence->channel); - kfree(fence); -} - -void -nouveau_fence_update(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct nouveau_fence *tmp, *fence; - uint32_t sequence; - - spin_lock(&chan->fence.lock); - - /* Fetch the last sequence if the channel is still up and running */ - if (likely(!list_empty(&chan->fence.pending))) { - if (USE_REFCNT(dev)) - sequence = nvchan_rd32(chan, 0x48); - else - sequence = atomic_read(&chan->fence.last_sequence_irq); - - if (chan->fence.sequence_ack == sequence) - goto out; - chan->fence.sequence_ack = sequence; - } - - list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { - if (fence->sequence > chan->fence.sequence_ack) - break; - - fence->signalled = true; - list_del(&fence->entry); - if (fence->work) - fence->work(fence->priv, true); - - kref_put(&fence->refcount, nouveau_fence_del); - } - -out: - spin_unlock(&chan->fence.lock); -} - -int -nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence, - bool emit) -{ - struct nouveau_fence *fence; - int ret = 0; - - fence = kzalloc(sizeof(*fence), GFP_KERNEL); - if (!fence) - return -ENOMEM; - kref_init(&fence->refcount); - nouveau_channel_ref(chan, &fence->channel); - - if (emit) - ret = nouveau_fence_emit(fence); - - if (ret) - nouveau_fence_unref(&fence); - *pfence = fence; - return ret; -} - -struct nouveau_channel * -nouveau_fence_channel(struct nouveau_fence *fence) -{ - return fence ? nouveau_channel_get_unlocked(fence->channel) : NULL; -} - -int -nouveau_fence_emit(struct nouveau_fence *fence) -{ - struct nouveau_channel *chan = fence->channel; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int ret; - - ret = RING_SPACE(chan, 2); - if (ret) - return ret; - - if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) { - nouveau_fence_update(chan); - - BUG_ON(chan->fence.sequence == - chan->fence.sequence_ack - 1); - } - - fence->sequence = ++chan->fence.sequence; - - kref_get(&fence->refcount); - spin_lock(&chan->fence.lock); - list_add_tail(&fence->entry, &chan->fence.pending); - spin_unlock(&chan->fence.lock); - - if (USE_REFCNT(dev)) { - if (dev_priv->card_type < NV_C0) - BEGIN_RING(chan, 0, NV10_SUBCHAN_REF_CNT, 1); - else - BEGIN_NVC0(chan, 2, 0, NV10_SUBCHAN_REF_CNT, 1); - } else { - BEGIN_RING(chan, NvSubSw, 0x0150, 1); - } - OUT_RING (chan, fence->sequence); - FIRE_RING(chan); - - return 0; -} - -void -nouveau_fence_work(struct nouveau_fence *fence, - void (*work)(void *priv, bool signalled), - void *priv) -{ - BUG_ON(fence->work); - - spin_lock(&fence->channel->fence.lock); - - if (fence->signalled) { - work(priv, true); - } else { - fence->work = work; - fence->priv = priv; - } - - spin_unlock(&fence->channel->fence.lock); -} - -void -__nouveau_fence_unref(void **sync_obj) -{ - struct nouveau_fence *fence = nouveau_fence(*sync_obj); - - if (fence) - kref_put(&fence->refcount, nouveau_fence_del); - *sync_obj = NULL; -} - -void * -__nouveau_fence_ref(void *sync_obj) -{ - struct nouveau_fence *fence = nouveau_fence(sync_obj); - - kref_get(&fence->refcount); - return sync_obj; -} - -bool -__nouveau_fence_signalled(void *sync_obj, void *sync_arg) -{ - struct nouveau_fence *fence = nouveau_fence(sync_obj); - struct nouveau_channel *chan = fence->channel; - - if (fence->signalled) - return true; - - nouveau_fence_update(chan); - return fence->signalled; -} - -int -__nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) -{ - unsigned long timeout = jiffies + (3 * DRM_HZ); - unsigned long sleep_time = NSEC_PER_MSEC / 1000; - ktime_t t; - int ret = 0; - - while (1) { - if (__nouveau_fence_signalled(sync_obj, sync_arg)) - break; - - if (time_after_eq(jiffies, timeout)) { - ret = -EBUSY; - break; - } - - __set_current_state(intr ? TASK_INTERRUPTIBLE - : TASK_UNINTERRUPTIBLE); - if (lazy) { - t = ktime_set(0, sleep_time); - schedule_hrtimeout(&t, HRTIMER_MODE_REL); - sleep_time *= 2; - if (sleep_time > NSEC_PER_MSEC) - sleep_time = NSEC_PER_MSEC; - } - - if (intr && signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - } - - __set_current_state(TASK_RUNNING); - - return ret; -} - -static struct nouveau_semaphore * -semaphore_alloc(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_semaphore *sema; - int size = (dev_priv->chipset < 0x84) ? 4 : 16; - int ret, i; - - if (!USE_SEMA(dev)) - return NULL; - - sema = kmalloc(sizeof(*sema), GFP_KERNEL); - if (!sema) - goto fail; - - ret = drm_mm_pre_get(&dev_priv->fence.heap); - if (ret) - goto fail; - - spin_lock(&dev_priv->fence.lock); - sema->mem = drm_mm_search_free(&dev_priv->fence.heap, size, 0, 0); - if (sema->mem) - sema->mem = drm_mm_get_block_atomic(sema->mem, size, 0); - spin_unlock(&dev_priv->fence.lock); - - if (!sema->mem) - goto fail; - - kref_init(&sema->ref); - sema->dev = dev; - for (i = sema->mem->start; i < sema->mem->start + size; i += 4) - nouveau_bo_wr32(dev_priv->fence.bo, i / 4, 0); - - return sema; -fail: - kfree(sema); - return NULL; -} - -static void -semaphore_free(struct kref *ref) -{ - struct nouveau_semaphore *sema = - container_of(ref, struct nouveau_semaphore, ref); - struct drm_nouveau_private *dev_priv = sema->dev->dev_private; - - spin_lock(&dev_priv->fence.lock); - drm_mm_put_block(sema->mem); - spin_unlock(&dev_priv->fence.lock); - - kfree(sema); -} - -static void -semaphore_work(void *priv, bool signalled) -{ - struct nouveau_semaphore *sema = priv; - struct drm_nouveau_private *dev_priv = sema->dev->dev_private; - - if (unlikely(!signalled)) - nouveau_bo_wr32(dev_priv->fence.bo, sema->mem->start / 4, 1); - - kref_put(&sema->ref, semaphore_free); -} - -static int -semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_fence *fence = NULL; - u64 offset = chan->fence.vma.offset + sema->mem->start; - int ret; - - if (dev_priv->chipset < 0x84) { - ret = RING_SPACE(chan, 4); - if (ret) - return ret; - - BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 3); - OUT_RING (chan, NvSema); - OUT_RING (chan, offset); - OUT_RING (chan, 1); - } else - if (dev_priv->chipset < 0xc0) { - ret = RING_SPACE(chan, 7); - if (ret) - return ret; - - BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram_handle); - BEGIN_RING(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 1); - OUT_RING (chan, 1); /* ACQUIRE_EQ */ - } else { - ret = RING_SPACE(chan, 5); - if (ret) - return ret; - - BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 1); - OUT_RING (chan, 0x1001); /* ACQUIRE_EQ */ - } - - /* Delay semaphore destruction until its work is done */ - ret = nouveau_fence_new(chan, &fence, true); - if (ret) - return ret; - - kref_get(&sema->ref); - nouveau_fence_work(fence, semaphore_work, sema); - nouveau_fence_unref(&fence); - return 0; -} - -static int -semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_fence *fence = NULL; - u64 offset = chan->fence.vma.offset + sema->mem->start; - int ret; - - if (dev_priv->chipset < 0x84) { - ret = RING_SPACE(chan, 5); - if (ret) - return ret; - - BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); - OUT_RING (chan, NvSema); - OUT_RING (chan, offset); - BEGIN_RING(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); - OUT_RING (chan, 1); - } else - if (dev_priv->chipset < 0xc0) { - ret = RING_SPACE(chan, 7); - if (ret) - return ret; - - BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram_handle); - BEGIN_RING(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 1); - OUT_RING (chan, 2); /* RELEASE */ - } else { - ret = RING_SPACE(chan, 5); - if (ret) - return ret; - - BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 1); - OUT_RING (chan, 0x1002); /* RELEASE */ - } - - /* Delay semaphore destruction until its work is done */ - ret = nouveau_fence_new(chan, &fence, true); - if (ret) - return ret; - - kref_get(&sema->ref); - nouveau_fence_work(fence, semaphore_work, sema); - nouveau_fence_unref(&fence); - return 0; -} - -int -nouveau_fence_sync(struct nouveau_fence *fence, - struct nouveau_channel *wchan) -{ - struct nouveau_channel *chan = nouveau_fence_channel(fence); - struct drm_device *dev = wchan->dev; - struct nouveau_semaphore *sema; - int ret = 0; - - if (likely(!chan || chan == wchan || - nouveau_fence_signalled(fence))) - goto out; - - sema = semaphore_alloc(dev); - if (!sema) { - /* Early card or broken userspace, fall back to - * software sync. */ - ret = nouveau_fence_wait(fence, true, false); - goto out; - } - - /* try to take chan's mutex, if we can't take it right away - * we have to fallback to software sync to prevent locking - * order issues - */ - if (!mutex_trylock(&chan->mutex)) { - ret = nouveau_fence_wait(fence, true, false); - goto out_unref; - } - - /* Make wchan wait until it gets signalled */ - ret = semaphore_acquire(wchan, sema); - if (ret) - goto out_unlock; - - /* Signal the semaphore from chan */ - ret = semaphore_release(chan, sema); - -out_unlock: - mutex_unlock(&chan->mutex); -out_unref: - kref_put(&sema->ref, semaphore_free); -out: - if (chan) - nouveau_channel_put_unlocked(&chan); - return ret; -} - -int -__nouveau_fence_flush(void *sync_obj, void *sync_arg) -{ - return 0; -} - -int -nouveau_fence_channel_init(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = NULL; - int ret; - - if (dev_priv->card_type < NV_C0) { - /* Create an NV_SW object for various sync purposes */ - ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); - if (ret) - return ret; - - ret = RING_SPACE(chan, 2); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubSw, NV01_SUBCHAN_OBJECT, 1); - OUT_RING (chan, NvSw); - FIRE_RING (chan); - } - - /* Setup area of memory shared between all channels for x-chan sync */ - if (USE_SEMA(dev) && dev_priv->chipset < 0x84) { - struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem; - - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_FROM_MEMORY, - mem->start << PAGE_SHIFT, - mem->size, NV_MEM_ACCESS_RW, - NV_MEM_TARGET_VRAM, &obj); - if (ret) - return ret; - - ret = nouveau_ramht_insert(chan, NvSema, obj); - nouveau_gpuobj_ref(NULL, &obj); - if (ret) - return ret; - } else - if (USE_SEMA(dev)) { - /* map fence bo into channel's vm */ - ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm, - &chan->fence.vma); - if (ret) - return ret; - } - - atomic_set(&chan->fence.last_sequence_irq, 0); - return 0; -} - -void -nouveau_fence_channel_fini(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_fence *tmp, *fence; - - spin_lock(&chan->fence.lock); - list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { - fence->signalled = true; - list_del(&fence->entry); - - if (unlikely(fence->work)) - fence->work(fence->priv, false); - - kref_put(&fence->refcount, nouveau_fence_del); - } - spin_unlock(&chan->fence.lock); - - nouveau_bo_vma_del(dev_priv->fence.bo, &chan->fence.vma); -} - -int -nouveau_fence_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int size = (dev_priv->chipset < 0x84) ? 4096 : 16384; - int ret; - - /* Create a shared VRAM heap for cross-channel sync. */ - if (USE_SEMA(dev)) { - ret = nouveau_bo_new(dev, size, 0, TTM_PL_FLAG_VRAM, - 0, 0, &dev_priv->fence.bo); - if (ret) - return ret; - - ret = nouveau_bo_pin(dev_priv->fence.bo, TTM_PL_FLAG_VRAM); - if (ret) - goto fail; - - ret = nouveau_bo_map(dev_priv->fence.bo); - if (ret) - goto fail; - - ret = drm_mm_init(&dev_priv->fence.heap, 0, - dev_priv->fence.bo->bo.mem.size); - if (ret) - goto fail; - - spin_lock_init(&dev_priv->fence.lock); - } - - return 0; -fail: - nouveau_bo_unmap(dev_priv->fence.bo); - nouveau_bo_ref(NULL, &dev_priv->fence.bo); - return ret; -} - -void -nouveau_fence_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (USE_SEMA(dev)) { - drm_mm_takedown(&dev_priv->fence.heap); - nouveau_bo_unmap(dev_priv->fence.bo); - nouveau_bo_unpin(dev_priv->fence.bo); - nouveau_bo_ref(NULL, &dev_priv->fence.bo); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gem.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gem.c deleted file mode 100644 index ed52a6f4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gem.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * Copyright (C) 2008 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#include "drmP.h" -#include "drm.h" - -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_dma.h" - -#define nouveau_gem_pushbuf_sync(chan) 0 - -int -nouveau_gem_object_new(struct drm_gem_object *gem) -{ - return 0; -} - -void -nouveau_gem_object_del(struct drm_gem_object *gem) -{ - struct nouveau_bo *nvbo = gem->driver_private; - struct ttm_buffer_object *bo = &nvbo->bo; - - if (!nvbo) - return; - nvbo->gem = NULL; - - if (unlikely(nvbo->pin_refcnt)) { - nvbo->pin_refcnt = 1; - nouveau_bo_unpin(nvbo); - } - - ttm_bo_unref(&bo); - - drm_gem_object_release(gem); - kfree(gem); -} - -int -nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) -{ - struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); - struct nouveau_bo *nvbo = nouveau_gem_object(gem); - struct nouveau_vma *vma; - int ret; - - if (!fpriv->vm) - return 0; - - ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0); - if (ret) - return ret; - - vma = nouveau_bo_vma_find(nvbo, fpriv->vm); - if (!vma) { - vma = kzalloc(sizeof(*vma), GFP_KERNEL); - if (!vma) { - ret = -ENOMEM; - goto out; - } - - ret = nouveau_bo_vma_add(nvbo, fpriv->vm, vma); - if (ret) { - kfree(vma); - goto out; - } - } else { - vma->refcount++; - } - -out: - ttm_bo_unreserve(&nvbo->bo); - return ret; -} - -void -nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) -{ - struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); - struct nouveau_bo *nvbo = nouveau_gem_object(gem); - struct nouveau_vma *vma; - int ret; - - if (!fpriv->vm) - return; - - ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0); - if (ret) - return; - - vma = nouveau_bo_vma_find(nvbo, fpriv->vm); - if (vma) { - if (--vma->refcount == 0) { - nouveau_bo_vma_del(nvbo, vma); - kfree(vma); - } - } - ttm_bo_unreserve(&nvbo->bo); -} - -int -nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain, - uint32_t tile_mode, uint32_t tile_flags, - struct nouveau_bo **pnvbo) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *nvbo; - u32 flags = 0; - int ret; - - if (domain & NOUVEAU_GEM_DOMAIN_VRAM) - flags |= TTM_PL_FLAG_VRAM; - if (domain & NOUVEAU_GEM_DOMAIN_GART) - flags |= TTM_PL_FLAG_TT; - if (!flags || domain & NOUVEAU_GEM_DOMAIN_CPU) - flags |= TTM_PL_FLAG_SYSTEM; - - ret = nouveau_bo_new(dev, size, align, flags, tile_mode, - tile_flags, pnvbo); - if (ret) - return ret; - nvbo = *pnvbo; - - /* we restrict allowed domains on nv50+ to only the types - * that were requested at creation time. not possibly on - * earlier chips without busting the ABI. - */ - nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM | - NOUVEAU_GEM_DOMAIN_GART; - if (dev_priv->card_type >= NV_50) - nvbo->valid_domains &= domain; - - nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size); - if (!nvbo->gem) { - nouveau_bo_ref(NULL, pnvbo); - return -ENOMEM; - } - - nvbo->bo.persistent_swap_storage = nvbo->gem->filp; - nvbo->gem->driver_private = nvbo; - return 0; -} - -static int -nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, - struct drm_nouveau_gem_info *rep) -{ - struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); - struct nouveau_bo *nvbo = nouveau_gem_object(gem); - struct nouveau_vma *vma; - - if (nvbo->bo.mem.mem_type == TTM_PL_TT) - rep->domain = NOUVEAU_GEM_DOMAIN_GART; - else - rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; - - rep->offset = nvbo->bo.offset; - if (fpriv->vm) { - vma = nouveau_bo_vma_find(nvbo, fpriv->vm); - if (!vma) - return -EINVAL; - - rep->offset = vma->offset; - } - - rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT; - rep->map_handle = nvbo->bo.addr_space_offset; - rep->tile_mode = nvbo->tile_mode; - rep->tile_flags = nvbo->tile_flags; - return 0; -} - -int -nouveau_gem_ioctl_new(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_gem_new *req = data; - struct nouveau_bo *nvbo = NULL; - int ret = 0; - - if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) - dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; - - if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) { - NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags); - return -EINVAL; - } - - ret = nouveau_gem_new(dev, req->info.size, req->align, - req->info.domain, req->info.tile_mode, - req->info.tile_flags, &nvbo); - if (ret) - return ret; - - ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); - if (ret == 0) { - ret = nouveau_gem_info(file_priv, nvbo->gem, &req->info); - if (ret) - drm_gem_handle_delete(file_priv, req->info.handle); - } - - /* drop reference from allocate - handle holds it now */ - drm_gem_object_unreference_unlocked(nvbo->gem); - return ret; -} - -static int -nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, - uint32_t write_domains, uint32_t valid_domains) -{ - struct nouveau_bo *nvbo = gem->driver_private; - struct ttm_buffer_object *bo = &nvbo->bo; - uint32_t domains = valid_domains & nvbo->valid_domains & - (write_domains ? write_domains : read_domains); - uint32_t pref_flags = 0, valid_flags = 0; - - if (!domains) - return -EINVAL; - - if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) - valid_flags |= TTM_PL_FLAG_VRAM; - - if (valid_domains & NOUVEAU_GEM_DOMAIN_GART) - valid_flags |= TTM_PL_FLAG_TT; - - if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) && - bo->mem.mem_type == TTM_PL_VRAM) - pref_flags |= TTM_PL_FLAG_VRAM; - - else if ((domains & NOUVEAU_GEM_DOMAIN_GART) && - bo->mem.mem_type == TTM_PL_TT) - pref_flags |= TTM_PL_FLAG_TT; - - else if (domains & NOUVEAU_GEM_DOMAIN_VRAM) - pref_flags |= TTM_PL_FLAG_VRAM; - - else - pref_flags |= TTM_PL_FLAG_TT; - - nouveau_bo_placement_set(nvbo, pref_flags, valid_flags); - - return 0; -} - -struct validate_op { - struct list_head vram_list; - struct list_head gart_list; - struct list_head both_list; -}; - -static void -validate_fini_list(struct list_head *list, struct nouveau_fence *fence) -{ - struct list_head *entry, *tmp; - struct nouveau_bo *nvbo; - - list_for_each_safe(entry, tmp, list) { - nvbo = list_entry(entry, struct nouveau_bo, entry); - - nouveau_bo_fence(nvbo, fence); - - if (unlikely(nvbo->validate_mapped)) { - ttm_bo_kunmap(&nvbo->kmap); - nvbo->validate_mapped = false; - } - - list_del(&nvbo->entry); - nvbo->reserved_by = NULL; - ttm_bo_unreserve(&nvbo->bo); - drm_gem_object_unreference_unlocked(nvbo->gem); - } -} - -static void -validate_fini(struct validate_op *op, struct nouveau_fence* fence) -{ - validate_fini_list(&op->vram_list, fence); - validate_fini_list(&op->gart_list, fence); - validate_fini_list(&op->both_list, fence); -} - -static int -validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, - struct drm_nouveau_gem_pushbuf_bo *pbbo, - int nr_buffers, struct validate_op *op) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t sequence; - int trycnt = 0; - int ret, i; - - sequence = atomic_add_return(1, &dev_priv->ttm.validate_sequence); -retry: - if (++trycnt > 100000) { - NV_ERROR(dev, "%s failed and gave up.\n", __func__); - return -EINVAL; - } - - for (i = 0; i < nr_buffers; i++) { - struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[i]; - struct drm_gem_object *gem; - struct nouveau_bo *nvbo; - - gem = drm_gem_object_lookup(dev, file_priv, b->handle); - if (!gem) { - NV_ERROR(dev, "Unknown handle 0x%08x\n", b->handle); - validate_fini(op, NULL); - return -ENOENT; - } - nvbo = gem->driver_private; - - if (nvbo->reserved_by && nvbo->reserved_by == file_priv) { - NV_ERROR(dev, "multiple instances of buffer %d on " - "validation list\n", b->handle); - validate_fini(op, NULL); - return -EINVAL; - } - - ret = ttm_bo_reserve(&nvbo->bo, true, false, true, sequence); - if (ret) { - validate_fini(op, NULL); - if (unlikely(ret == -EAGAIN)) - ret = ttm_bo_wait_unreserved(&nvbo->bo, true); - drm_gem_object_unreference_unlocked(gem); - if (unlikely(ret)) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "fail reserve\n"); - return ret; - } - goto retry; - } - - b->user_priv = (uint64_t)(unsigned long)nvbo; - nvbo->reserved_by = file_priv; - nvbo->pbbo_index = i; - if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && - (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART)) - list_add_tail(&nvbo->entry, &op->both_list); - else - if (b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) - list_add_tail(&nvbo->entry, &op->vram_list); - else - if (b->valid_domains & NOUVEAU_GEM_DOMAIN_GART) - list_add_tail(&nvbo->entry, &op->gart_list); - else { - NV_ERROR(dev, "invalid valid domains: 0x%08x\n", - b->valid_domains); - list_add_tail(&nvbo->entry, &op->both_list); - validate_fini(op, NULL); - return -EINVAL; - } - } - - return 0; -} - -static int -validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) -{ - struct nouveau_fence *fence = NULL; - int ret = 0; - - spin_lock(&nvbo->bo.bdev->fence_lock); - if (nvbo->bo.sync_obj) - fence = nouveau_fence_ref(nvbo->bo.sync_obj); - spin_unlock(&nvbo->bo.bdev->fence_lock); - - if (fence) { - ret = nouveau_fence_sync(fence, chan); - nouveau_fence_unref(&fence); - } - - return ret; -} - -static int -validate_list(struct nouveau_channel *chan, struct list_head *list, - struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_nouveau_gem_pushbuf_bo __user *upbbo = - (void __force __user *)(uintptr_t)user_pbbo_ptr; - struct drm_device *dev = chan->dev; - struct nouveau_bo *nvbo; - int ret, relocs = 0; - - list_for_each_entry(nvbo, list, entry) { - struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; - - ret = validate_sync(chan, nvbo); - if (unlikely(ret)) { - NV_ERROR(dev, "fail pre-validate sync\n"); - return ret; - } - - ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, - b->write_domains, - b->valid_domains); - if (unlikely(ret)) { - NV_ERROR(dev, "fail set_domain\n"); - return ret; - } - - ret = nouveau_bo_validate(nvbo, true, false, false); - if (unlikely(ret)) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "fail ttm_validate\n"); - return ret; - } - - ret = validate_sync(chan, nvbo); - if (unlikely(ret)) { - NV_ERROR(dev, "fail post-validate sync\n"); - return ret; - } - - if (dev_priv->card_type < NV_50) { - if (nvbo->bo.offset == b->presumed.offset && - ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && - b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || - (nvbo->bo.mem.mem_type == TTM_PL_TT && - b->presumed.domain & NOUVEAU_GEM_DOMAIN_GART))) - continue; - - if (nvbo->bo.mem.mem_type == TTM_PL_TT) - b->presumed.domain = NOUVEAU_GEM_DOMAIN_GART; - else - b->presumed.domain = NOUVEAU_GEM_DOMAIN_VRAM; - b->presumed.offset = nvbo->bo.offset; - b->presumed.valid = 0; - relocs++; - - if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index].presumed, - &b->presumed, sizeof(b->presumed))) - return -EFAULT; - } - } - - return relocs; -} - -static int -nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, - struct drm_file *file_priv, - struct drm_nouveau_gem_pushbuf_bo *pbbo, - uint64_t user_buffers, int nr_buffers, - struct validate_op *op, int *apply_relocs) -{ - struct drm_device *dev = chan->dev; - int ret, relocs = 0; - - INIT_LIST_HEAD(&op->vram_list); - INIT_LIST_HEAD(&op->gart_list); - INIT_LIST_HEAD(&op->both_list); - - if (nr_buffers == 0) - return 0; - - ret = validate_init(chan, file_priv, pbbo, nr_buffers, op); - if (unlikely(ret)) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "validate_init\n"); - return ret; - } - - ret = validate_list(chan, &op->vram_list, pbbo, user_buffers); - if (unlikely(ret < 0)) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "validate vram_list\n"); - validate_fini(op, NULL); - return ret; - } - relocs += ret; - - ret = validate_list(chan, &op->gart_list, pbbo, user_buffers); - if (unlikely(ret < 0)) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "validate gart_list\n"); - validate_fini(op, NULL); - return ret; - } - relocs += ret; - - ret = validate_list(chan, &op->both_list, pbbo, user_buffers); - if (unlikely(ret < 0)) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "validate both_list\n"); - validate_fini(op, NULL); - return ret; - } - relocs += ret; - - *apply_relocs = relocs; - return 0; -} - -static inline void * -u_memcpya(uint64_t user, unsigned nmemb, unsigned size) -{ - void *mem; - void __user *userptr = (void __force __user *)(uintptr_t)user; - - mem = kmalloc(nmemb * size, GFP_KERNEL); - if (!mem) - return ERR_PTR(-ENOMEM); - - if (DRM_COPY_FROM_USER(mem, userptr, nmemb * size)) { - kfree(mem); - return ERR_PTR(-EFAULT); - } - - return mem; -} - -static int -nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev, - struct drm_nouveau_gem_pushbuf *req, - struct drm_nouveau_gem_pushbuf_bo *bo) -{ - struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; - int ret = 0; - unsigned i; - - reloc = u_memcpya(req->relocs, req->nr_relocs, sizeof(*reloc)); - if (IS_ERR(reloc)) - return PTR_ERR(reloc); - - for (i = 0; i < req->nr_relocs; i++) { - struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i]; - struct drm_nouveau_gem_pushbuf_bo *b; - struct nouveau_bo *nvbo; - uint32_t data; - - if (unlikely(r->bo_index > req->nr_buffers)) { - NV_ERROR(dev, "reloc bo index invalid\n"); - ret = -EINVAL; - break; - } - - b = &bo[r->bo_index]; - if (b->presumed.valid) - continue; - - if (unlikely(r->reloc_bo_index > req->nr_buffers)) { - NV_ERROR(dev, "reloc container bo index invalid\n"); - ret = -EINVAL; - break; - } - nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv; - - if (unlikely(r->reloc_bo_offset + 4 > - nvbo->bo.mem.num_pages << PAGE_SHIFT)) { - NV_ERROR(dev, "reloc outside of bo\n"); - ret = -EINVAL; - break; - } - - if (!nvbo->kmap.virtual) { - ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, - &nvbo->kmap); - if (ret) { - NV_ERROR(dev, "failed kmap for reloc\n"); - break; - } - nvbo->validate_mapped = true; - } - - if (r->flags & NOUVEAU_GEM_RELOC_LOW) - data = b->presumed.offset + r->data; - else - if (r->flags & NOUVEAU_GEM_RELOC_HIGH) - data = (b->presumed.offset + r->data) >> 32; - else - data = r->data; - - if (r->flags & NOUVEAU_GEM_RELOC_OR) { - if (b->presumed.domain == NOUVEAU_GEM_DOMAIN_GART) - data |= r->tor; - else - data |= r->vor; - } - - spin_lock(&nvbo->bo.bdev->fence_lock); - ret = ttm_bo_wait(&nvbo->bo, false, false, false); - spin_unlock(&nvbo->bo.bdev->fence_lock); - if (ret) { - NV_ERROR(dev, "reloc wait_idle failed: %d\n", ret); - break; - } - - nouveau_bo_wr32(nvbo, r->reloc_bo_offset >> 2, data); - } - - kfree(reloc); - return ret; -} - -int -nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_gem_pushbuf *req = data; - struct drm_nouveau_gem_pushbuf_push *push; - struct drm_nouveau_gem_pushbuf_bo *bo; - struct nouveau_channel *chan; - struct validate_op op; - struct nouveau_fence *fence = NULL; - int i, j, ret = 0, do_reloc = 0; - - chan = nouveau_channel_get(file_priv, req->channel); - if (IS_ERR(chan)) - return PTR_ERR(chan); - - req->vram_available = dev_priv->fb_aper_free; - req->gart_available = dev_priv->gart_info.aper_free; - if (unlikely(req->nr_push == 0)) - goto out_next; - - if (unlikely(req->nr_push > NOUVEAU_GEM_MAX_PUSH)) { - NV_ERROR(dev, "pushbuf push count exceeds limit: %d max %d\n", - req->nr_push, NOUVEAU_GEM_MAX_PUSH); - nouveau_channel_put(&chan); - return -EINVAL; - } - - if (unlikely(req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS)) { - NV_ERROR(dev, "pushbuf bo count exceeds limit: %d max %d\n", - req->nr_buffers, NOUVEAU_GEM_MAX_BUFFERS); - nouveau_channel_put(&chan); - return -EINVAL; - } - - if (unlikely(req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS)) { - NV_ERROR(dev, "pushbuf reloc count exceeds limit: %d max %d\n", - req->nr_relocs, NOUVEAU_GEM_MAX_RELOCS); - nouveau_channel_put(&chan); - return -EINVAL; - } - - push = u_memcpya(req->push, req->nr_push, sizeof(*push)); - if (IS_ERR(push)) { - nouveau_channel_put(&chan); - return PTR_ERR(push); - } - - bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); - if (IS_ERR(bo)) { - kfree(push); - nouveau_channel_put(&chan); - return PTR_ERR(bo); - } - - /* Ensure all push buffers are on validate list */ - for (i = 0; i < req->nr_push; i++) { - if (push[i].bo_index >= req->nr_buffers) { - NV_ERROR(dev, "push %d buffer not in list\n", i); - ret = -EINVAL; - goto out_prevalid; - } - } - - /* Validate buffer list */ - ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, - req->nr_buffers, &op, &do_reloc); - if (ret) { - if (ret != -ERESTARTSYS) - NV_ERROR(dev, "validate: %d\n", ret); - goto out_prevalid; - } - - /* Apply any relocations that are required */ - if (do_reloc) { - ret = nouveau_gem_pushbuf_reloc_apply(dev, req, bo); - if (ret) { - NV_ERROR(dev, "reloc apply: %d\n", ret); - goto out; - } - } - - if (chan->dma.ib_max) { - ret = nouveau_dma_wait(chan, req->nr_push + 1, 6); - if (ret) { - NV_INFO(dev, "nv50cal_space: %d\n", ret); - goto out; - } - - for (i = 0; i < req->nr_push; i++) { - struct nouveau_bo *nvbo = (void *)(unsigned long) - bo[push[i].bo_index].user_priv; - - nv50_dma_push(chan, nvbo, push[i].offset, - push[i].length); - } - } else - if (dev_priv->chipset >= 0x25) { - ret = RING_SPACE(chan, req->nr_push * 2); - if (ret) { - NV_ERROR(dev, "cal_space: %d\n", ret); - goto out; - } - - for (i = 0; i < req->nr_push; i++) { - struct nouveau_bo *nvbo = (void *)(unsigned long) - bo[push[i].bo_index].user_priv; - struct drm_mm_node *mem = nvbo->bo.mem.mm_node; - - OUT_RING(chan, ((mem->start << PAGE_SHIFT) + - push[i].offset) | 2); - OUT_RING(chan, 0); - } - } else { - ret = RING_SPACE(chan, req->nr_push * (2 + NOUVEAU_DMA_SKIPS)); - if (ret) { - NV_ERROR(dev, "jmp_space: %d\n", ret); - goto out; - } - - for (i = 0; i < req->nr_push; i++) { - struct nouveau_bo *nvbo = (void *)(unsigned long) - bo[push[i].bo_index].user_priv; - struct drm_mm_node *mem = nvbo->bo.mem.mm_node; - uint32_t cmd; - - cmd = chan->pushbuf_base + ((chan->dma.cur + 2) << 2); - cmd |= 0x20000000; - if (unlikely(cmd != req->suffix0)) { - if (!nvbo->kmap.virtual) { - ret = ttm_bo_kmap(&nvbo->bo, 0, - nvbo->bo.mem. - num_pages, - &nvbo->kmap); - if (ret) { - WIND_RING(chan); - goto out; - } - nvbo->validate_mapped = true; - } - - nouveau_bo_wr32(nvbo, (push[i].offset + - push[i].length - 8) / 4, cmd); - } - - OUT_RING(chan, ((mem->start << PAGE_SHIFT) + - push[i].offset) | 0x20000000); - OUT_RING(chan, 0); - for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) - OUT_RING(chan, 0); - } - } - - ret = nouveau_fence_new(chan, &fence, true); - if (ret) { - NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); - WIND_RING(chan); - goto out; - } - -out: - validate_fini(&op, fence); - nouveau_fence_unref(&fence); - -out_prevalid: - kfree(bo); - kfree(push); - -out_next: - if (chan->dma.ib_max) { - req->suffix0 = 0x00000000; - req->suffix1 = 0x00000000; - } else - if (dev_priv->chipset >= 0x25) { - req->suffix0 = 0x00020000; - req->suffix1 = 0x00000000; - } else { - req->suffix0 = 0x20000000 | - (chan->pushbuf_base + ((chan->dma.cur + 2) << 2)); - req->suffix1 = 0x00000000; - } - - nouveau_channel_put(&chan); - return ret; -} - -static inline uint32_t -domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain) -{ - uint32_t flags = 0; - - if (domain & NOUVEAU_GEM_DOMAIN_VRAM) - flags |= TTM_PL_FLAG_VRAM; - if (domain & NOUVEAU_GEM_DOMAIN_GART) - flags |= TTM_PL_FLAG_TT; - - return flags; -} - -int -nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_gem_cpu_prep *req = data; - struct drm_gem_object *gem; - struct nouveau_bo *nvbo; - bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT); - int ret = -EINVAL; - - gem = drm_gem_object_lookup(dev, file_priv, req->handle); - if (!gem) - return -ENOENT; - nvbo = nouveau_gem_object(gem); - - spin_lock(&nvbo->bo.bdev->fence_lock); - ret = ttm_bo_wait(&nvbo->bo, true, true, no_wait); - spin_unlock(&nvbo->bo.bdev->fence_lock); - drm_gem_object_unreference_unlocked(gem); - return ret; -} - -int -nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - return 0; -} - -int -nouveau_gem_ioctl_info(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_gem_info *req = data; - struct drm_gem_object *gem; - int ret; - - gem = drm_gem_object_lookup(dev, file_priv, req->handle); - if (!gem) - return -ENOENT; - - ret = nouveau_gem_info(file_priv, gem, req); - drm_gem_object_unreference_unlocked(gem); - return ret; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.c deleted file mode 100644 index a580cc62..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_i2c.h" -#include "nouveau_gpio.h" - -static u8 * -dcb_gpio_table(struct drm_device *dev) -{ - u8 *dcb = dcb_table(dev); - if (dcb) { - if (dcb[0] >= 0x30 && dcb[1] >= 0x0c) - return ROMPTR(dev, dcb[0x0a]); - if (dcb[0] >= 0x22 && dcb[-1] >= 0x13) - return ROMPTR(dev, dcb[-15]); - } - return NULL; -} - -static u8 * -dcb_gpio_entry(struct drm_device *dev, int idx, int ent, u8 *version) -{ - u8 *table = dcb_gpio_table(dev); - if (table) { - *version = table[0]; - if (*version < 0x30 && ent < table[2]) - return table + 3 + (ent * table[1]); - else if (ent < table[2]) - return table + table[1] + (ent * table[3]); - } - return NULL; -} - -int -nouveau_gpio_drive(struct drm_device *dev, int idx, int line, int dir, int out) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - - return pgpio->drive ? pgpio->drive(dev, line, dir, out) : -ENODEV; -} - -int -nouveau_gpio_sense(struct drm_device *dev, int idx, int line) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - - return pgpio->sense ? pgpio->sense(dev, line) : -ENODEV; -} - -int -nouveau_gpio_find(struct drm_device *dev, int idx, u8 func, u8 line, - struct gpio_func *gpio) -{ - u8 *table, *entry, version; - int i = -1; - - if (line == 0xff && func == 0xff) - return -EINVAL; - - while ((entry = dcb_gpio_entry(dev, idx, ++i, &version))) { - if (version < 0x40) { - u16 data = ROM16(entry[0]); - *gpio = (struct gpio_func) { - .line = (data & 0x001f) >> 0, - .func = (data & 0x07e0) >> 5, - .log[0] = (data & 0x1800) >> 11, - .log[1] = (data & 0x6000) >> 13, - }; - } else - if (version < 0x41) { - *gpio = (struct gpio_func) { - .line = entry[0] & 0x1f, - .func = entry[1], - .log[0] = (entry[3] & 0x18) >> 3, - .log[1] = (entry[3] & 0x60) >> 5, - }; - } else { - *gpio = (struct gpio_func) { - .line = entry[0] & 0x3f, - .func = entry[1], - .log[0] = (entry[4] & 0x30) >> 4, - .log[1] = (entry[4] & 0xc0) >> 6, - }; - } - - if ((line == 0xff || line == gpio->line) && - (func == 0xff || func == gpio->func)) - return 0; - } - - /* DCB 2.2, fixed TVDAC GPIO data */ - if ((table = dcb_table(dev)) && table[0] >= 0x22) { - if (func == DCB_GPIO_TVDAC0) { - *gpio = (struct gpio_func) { - .func = DCB_GPIO_TVDAC0, - .line = table[-4] >> 4, - .log[0] = !!(table[-5] & 2), - .log[1] = !(table[-5] & 2), - }; - return 0; - } - } - - /* Apple iMac G4 NV18 */ - if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { - if (func == DCB_GPIO_TVDAC0) { - *gpio = (struct gpio_func) { - .func = DCB_GPIO_TVDAC0, - .line = 4, - .log[0] = 0, - .log[1] = 1, - }; - return 0; - } - } - - return -EINVAL; -} - -int -nouveau_gpio_set(struct drm_device *dev, int idx, u8 tag, u8 line, int state) -{ - struct gpio_func gpio; - int ret; - - ret = nouveau_gpio_find(dev, idx, tag, line, &gpio); - if (ret == 0) { - int dir = !!(gpio.log[state] & 0x02); - int out = !!(gpio.log[state] & 0x01); - ret = nouveau_gpio_drive(dev, idx, gpio.line, dir, out); - } - - return ret; -} - -int -nouveau_gpio_get(struct drm_device *dev, int idx, u8 tag, u8 line) -{ - struct gpio_func gpio; - int ret; - - ret = nouveau_gpio_find(dev, idx, tag, line, &gpio); - if (ret == 0) { - ret = nouveau_gpio_sense(dev, idx, gpio.line); - if (ret >= 0) - ret = (ret == (gpio.log[1] & 1)); - } - - return ret; -} - -int -nouveau_gpio_irq(struct drm_device *dev, int idx, u8 tag, u8 line, bool on) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - struct gpio_func gpio; - int ret; - - ret = nouveau_gpio_find(dev, idx, tag, line, &gpio); - if (ret == 0) { - if (idx == 0 && pgpio->irq_enable) - pgpio->irq_enable(dev, gpio.line, on); - else - ret = -ENODEV; - } - - return ret; -} - -struct gpio_isr { - struct drm_device *dev; - struct list_head head; - struct work_struct work; - int idx; - struct gpio_func func; - void (*handler)(void *, int); - void *data; - bool inhibit; -}; - -static void -nouveau_gpio_isr_bh(struct work_struct *work) -{ - struct gpio_isr *isr = container_of(work, struct gpio_isr, work); - struct drm_device *dev = isr->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - unsigned long flags; - int state; - - state = nouveau_gpio_get(dev, isr->idx, isr->func.func, isr->func.line); - if (state >= 0) - isr->handler(isr->data, state); - - spin_lock_irqsave(&pgpio->lock, flags); - isr->inhibit = false; - spin_unlock_irqrestore(&pgpio->lock, flags); -} - -void -nouveau_gpio_isr(struct drm_device *dev, int idx, u32 line_mask) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - struct gpio_isr *isr; - - if (idx != 0) - return; - - spin_lock(&pgpio->lock); - list_for_each_entry(isr, &pgpio->isr, head) { - if (line_mask & (1 << isr->func.line)) { - if (isr->inhibit) - continue; - isr->inhibit = true; - schedule_work(&isr->work); - } - } - spin_unlock(&pgpio->lock); -} - -int -nouveau_gpio_isr_add(struct drm_device *dev, int idx, u8 tag, u8 line, - void (*handler)(void *, int), void *data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - struct gpio_isr *isr; - unsigned long flags; - int ret; - - isr = kzalloc(sizeof(*isr), GFP_KERNEL); - if (!isr) - return -ENOMEM; - - ret = nouveau_gpio_find(dev, idx, tag, line, &isr->func); - if (ret) { - kfree(isr); - return ret; - } - - INIT_WORK(&isr->work, nouveau_gpio_isr_bh); - isr->dev = dev; - isr->handler = handler; - isr->data = data; - isr->idx = idx; - - spin_lock_irqsave(&pgpio->lock, flags); - list_add(&isr->head, &pgpio->isr); - spin_unlock_irqrestore(&pgpio->lock, flags); - return 0; -} - -void -nouveau_gpio_isr_del(struct drm_device *dev, int idx, u8 tag, u8 line, - void (*handler)(void *, int), void *data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - struct gpio_isr *isr, *tmp; - struct gpio_func func; - unsigned long flags; - LIST_HEAD(tofree); - int ret; - - ret = nouveau_gpio_find(dev, idx, tag, line, &func); - if (ret == 0) { - spin_lock_irqsave(&pgpio->lock, flags); - list_for_each_entry_safe(isr, tmp, &pgpio->isr, head) { - if (memcmp(&isr->func, &func, sizeof(func)) || - isr->idx != idx || - isr->handler != handler || isr->data != data) - continue; - list_move(&isr->head, &tofree); - } - spin_unlock_irqrestore(&pgpio->lock, flags); - - list_for_each_entry_safe(isr, tmp, &tofree, head) { - flush_work_sync(&isr->work); - kfree(isr); - } - } -} - -int -nouveau_gpio_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - - INIT_LIST_HEAD(&pgpio->isr); - spin_lock_init(&pgpio->lock); - - return nouveau_gpio_init(dev); -} - -void -nouveau_gpio_destroy(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - - nouveau_gpio_fini(dev); - BUG_ON(!list_empty(&pgpio->isr)); -} - -int -nouveau_gpio_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - int ret = 0; - - if (pgpio->init) - ret = pgpio->init(dev); - - return ret; -} - -void -nouveau_gpio_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - - if (pgpio->fini) - pgpio->fini(dev); -} - -void -nouveau_gpio_reset(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u8 *entry, version; - int ent = -1; - - while ((entry = dcb_gpio_entry(dev, 0, ++ent, &version))) { - u8 func = 0xff, line, defs, unk0, unk1; - if (version >= 0x41) { - defs = !!(entry[0] & 0x80); - line = entry[0] & 0x3f; - func = entry[1]; - unk0 = entry[2]; - unk1 = entry[3] & 0x1f; - } else - if (version >= 0x40) { - line = entry[0] & 0x1f; - func = entry[1]; - defs = !!(entry[3] & 0x01); - unk0 = !!(entry[3] & 0x02); - unk1 = !!(entry[3] & 0x04); - } else { - break; - } - - if (func == 0xff) - continue; - - nouveau_gpio_func_set(dev, func, defs); - - if (dev_priv->card_type >= NV_D0) { - nv_mask(dev, 0x00d610 + (line * 4), 0xff, unk0); - if (unk1--) - nv_mask(dev, 0x00d640 + (unk1 * 4), 0xff, line); - } else - if (dev_priv->card_type >= NV_50) { - static const u32 regs[] = { 0xe100, 0xe28c }; - u32 val = (unk1 << 16) | unk0; - u32 reg = regs[line >> 4]; line &= 0x0f; - - nv_mask(dev, reg, 0x00010001 << line, val << line); - } - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.h deleted file mode 100644 index 64c5cb07..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_gpio.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __NOUVEAU_GPIO_H__ -#define __NOUVEAU_GPIO_H__ - -struct gpio_func { - u8 func; - u8 line; - u8 log[2]; -}; - -/* nouveau_gpio.c */ -int nouveau_gpio_create(struct drm_device *); -void nouveau_gpio_destroy(struct drm_device *); -int nouveau_gpio_init(struct drm_device *); -void nouveau_gpio_fini(struct drm_device *); -void nouveau_gpio_reset(struct drm_device *); -int nouveau_gpio_drive(struct drm_device *, int idx, int line, - int dir, int out); -int nouveau_gpio_sense(struct drm_device *, int idx, int line); -int nouveau_gpio_find(struct drm_device *, int idx, u8 tag, u8 line, - struct gpio_func *); -int nouveau_gpio_set(struct drm_device *, int idx, u8 tag, u8 line, int state); -int nouveau_gpio_get(struct drm_device *, int idx, u8 tag, u8 line); -int nouveau_gpio_irq(struct drm_device *, int idx, u8 tag, u8 line, bool on); -void nouveau_gpio_isr(struct drm_device *, int idx, u32 mask); -int nouveau_gpio_isr_add(struct drm_device *, int idx, u8 tag, u8 line, - void (*)(void *, int state), void *data); -void nouveau_gpio_isr_del(struct drm_device *, int idx, u8 tag, u8 line, - void (*)(void *, int state), void *data); - -static inline bool -nouveau_gpio_func_valid(struct drm_device *dev, u8 tag) -{ - struct gpio_func func; - return (nouveau_gpio_find(dev, 0, tag, 0xff, &func)) == 0; -} - -static inline int -nouveau_gpio_func_set(struct drm_device *dev, u8 tag, int state) -{ - return nouveau_gpio_set(dev, 0, tag, 0xff, state); -} - -static inline int -nouveau_gpio_func_get(struct drm_device *dev, u8 tag) -{ - return nouveau_gpio_get(dev, 0, tag, 0xff); -} - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_grctx.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_grctx.h deleted file mode 100644 index 86c2e374..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_grctx.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef __NOUVEAU_GRCTX_H__ -#define __NOUVEAU_GRCTX_H__ - -struct nouveau_grctx { - struct drm_device *dev; - - enum { - NOUVEAU_GRCTX_PROG, - NOUVEAU_GRCTX_VALS - } mode; - void *data; - - uint32_t ctxprog_max; - uint32_t ctxprog_len; - uint32_t ctxprog_reg; - int ctxprog_label[32]; - uint32_t ctxvals_pos; - uint32_t ctxvals_base; -}; - -#ifdef CP_CTX -static inline void -cp_out(struct nouveau_grctx *ctx, uint32_t inst) -{ - uint32_t *ctxprog = ctx->data; - - if (ctx->mode != NOUVEAU_GRCTX_PROG) - return; - - BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max); - ctxprog[ctx->ctxprog_len++] = inst; -} - -static inline void -cp_lsr(struct nouveau_grctx *ctx, uint32_t val) -{ - cp_out(ctx, CP_LOAD_SR | val); -} - -static inline void -cp_ctx(struct nouveau_grctx *ctx, uint32_t reg, uint32_t length) -{ - ctx->ctxprog_reg = (reg - 0x00400000) >> 2; - - ctx->ctxvals_base = ctx->ctxvals_pos; - ctx->ctxvals_pos = ctx->ctxvals_base + length; - - if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) { - cp_lsr(ctx, length); - length = 0; - } - - cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg); -} - -static inline void -cp_name(struct nouveau_grctx *ctx, int name) -{ - uint32_t *ctxprog = ctx->data; - int i; - - if (ctx->mode != NOUVEAU_GRCTX_PROG) - return; - - ctx->ctxprog_label[name] = ctx->ctxprog_len; - for (i = 0; i < ctx->ctxprog_len; i++) { - if ((ctxprog[i] & 0xfff00000) != 0xff400000) - continue; - if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT)) - continue; - ctxprog[i] = (ctxprog[i] & 0x00ff00ff) | - (ctx->ctxprog_len << CP_BRA_IP_SHIFT); - } -} - -static inline void -_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name) -{ - int ip = 0; - - if (mod != 2) { - ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT; - if (ip == 0) - ip = 0xff000000 | (name << CP_BRA_IP_SHIFT); - } - - cp_out(ctx, CP_BRA | (mod << 18) | ip | flag | - (state ? 0 : CP_BRA_IF_CLEAR)); -} -#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n) -#ifdef CP_BRA_MOD -#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n) -#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0) -#endif - -static inline void -_cp_wait(struct nouveau_grctx *ctx, int flag, int state) -{ - cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0)); -} -#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s) - -static inline void -_cp_set(struct nouveau_grctx *ctx, int flag, int state) -{ - cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0)); -} -#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s) - -static inline void -cp_pos(struct nouveau_grctx *ctx, int offset) -{ - ctx->ctxvals_pos = offset; - ctx->ctxvals_base = ctx->ctxvals_pos; - - cp_lsr(ctx, ctx->ctxvals_pos); - cp_out(ctx, CP_SET_CONTEXT_POINTER); -} - -static inline void -gr_def(struct nouveau_grctx *ctx, uint32_t reg, uint32_t val) -{ - if (ctx->mode != NOUVEAU_GRCTX_VALS) - return; - - reg = (reg - 0x00400000) / 4; - reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base; - - nv_wo32(ctx->data, reg * 4, val); -} -#endif - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hdmi.c deleted file mode 100644 index c3de3638..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hdmi.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_connector.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" - -static bool -hdmi_sor(struct drm_encoder *encoder) -{ - struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; - if (dev_priv->chipset < 0xa3 || - dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) - return false; - return true; -} - -static inline u32 -hdmi_base(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); - if (!hdmi_sor(encoder)) - return 0x616500 + (nv_crtc->index * 0x800); - return 0x61c500 + (nv_encoder->or * 0x800); -} - -static void -hdmi_wr32(struct drm_encoder *encoder, u32 reg, u32 val) -{ - nv_wr32(encoder->dev, hdmi_base(encoder) + reg, val); -} - -static u32 -hdmi_rd32(struct drm_encoder *encoder, u32 reg) -{ - return nv_rd32(encoder->dev, hdmi_base(encoder) + reg); -} - -static u32 -hdmi_mask(struct drm_encoder *encoder, u32 reg, u32 mask, u32 val) -{ - u32 tmp = hdmi_rd32(encoder, reg); - hdmi_wr32(encoder, reg, (tmp & ~mask) | val); - return tmp; -} - -static void -nouveau_audio_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - u32 or = nv_encoder->or * 0x800; - - if (hdmi_sor(encoder)) { - nv_mask(dev, 0x61c448 + or, 0x00000003, 0x00000000); - } -} - -static void -nouveau_audio_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector; - struct drm_device *dev = encoder->dev; - u32 or = nv_encoder->or * 0x800; - int i; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (!drm_detect_monitor_audio(nv_connector->edid)) { - nouveau_audio_disconnect(encoder); - return; - } - - if (hdmi_sor(encoder)) { - nv_mask(dev, 0x61c448 + or, 0x00000001, 0x00000001); - - drm_edid_to_eld(&nv_connector->base, nv_connector->edid); - if (nv_connector->base.eld[0]) { - u8 *eld = nv_connector->base.eld; - for (i = 0; i < eld[2] * 4; i++) - nv_wr32(dev, 0x61c440 + or, (i << 8) | eld[i]); - for (i = eld[2] * 4; i < 0x60; i++) - nv_wr32(dev, 0x61c440 + or, (i << 8) | 0x00); - nv_mask(dev, 0x61c448 + or, 0x00000002, 0x00000002); - } - } -} - -static void -nouveau_hdmi_infoframe(struct drm_encoder *encoder, u32 ctrl, u8 *frame) -{ - /* calculate checksum for the infoframe */ - u8 sum = 0, i; - for (i = 0; i < frame[2]; i++) - sum += frame[i]; - frame[3] = 256 - sum; - - /* disable infoframe, and write header */ - hdmi_mask(encoder, ctrl + 0x00, 0x00000001, 0x00000000); - hdmi_wr32(encoder, ctrl + 0x08, *(u32 *)frame & 0xffffff); - - /* register scans tell me the audio infoframe has only one set of - * subpack regs, according to tegra (gee nvidia, it'd be nice if we - * could get those docs too!), the hdmi block pads out the rest of - * the packet on its own. - */ - if (ctrl == 0x020) - frame[2] = 6; - - /* write out checksum and data, weird weird 7 byte register pairs */ - for (i = 0; i < frame[2] + 1; i += 7) { - u32 rsubpack = ctrl + 0x0c + ((i / 7) * 8); - u32 *subpack = (u32 *)&frame[3 + i]; - hdmi_wr32(encoder, rsubpack + 0, subpack[0]); - hdmi_wr32(encoder, rsubpack + 4, subpack[1] & 0xffffff); - } - - /* enable the infoframe */ - hdmi_mask(encoder, ctrl, 0x00000001, 0x00000001); -} - -static void -nouveau_hdmi_video_infoframe(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - const u8 Y = 0, A = 0, B = 0, S = 0, C = 0, M = 0, R = 0; - const u8 ITC = 0, EC = 0, Q = 0, SC = 0, VIC = 0, PR = 0; - const u8 bar_top = 0, bar_bottom = 0, bar_left = 0, bar_right = 0; - u8 frame[20]; - - frame[0x00] = 0x82; /* AVI infoframe */ - frame[0x01] = 0x02; /* version */ - frame[0x02] = 0x0d; /* length */ - frame[0x03] = 0x00; - frame[0x04] = (Y << 5) | (A << 4) | (B << 2) | S; - frame[0x05] = (C << 6) | (M << 4) | R; - frame[0x06] = (ITC << 7) | (EC << 4) | (Q << 2) | SC; - frame[0x07] = VIC; - frame[0x08] = PR; - frame[0x09] = bar_top & 0xff; - frame[0x0a] = bar_top >> 8; - frame[0x0b] = bar_bottom & 0xff; - frame[0x0c] = bar_bottom >> 8; - frame[0x0d] = bar_left & 0xff; - frame[0x0e] = bar_left >> 8; - frame[0x0f] = bar_right & 0xff; - frame[0x10] = bar_right >> 8; - frame[0x11] = 0x00; - frame[0x12] = 0x00; - frame[0x13] = 0x00; - - nouveau_hdmi_infoframe(encoder, 0x020, frame); -} - -static void -nouveau_hdmi_audio_infoframe(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - const u8 CT = 0x00, CC = 0x01, ceaSS = 0x00, SF = 0x00, FMT = 0x00; - const u8 CA = 0x00, DM_INH = 0, LSV = 0x00; - u8 frame[12]; - - frame[0x00] = 0x84; /* Audio infoframe */ - frame[0x01] = 0x01; /* version */ - frame[0x02] = 0x0a; /* length */ - frame[0x03] = 0x00; - frame[0x04] = (CT << 4) | CC; - frame[0x05] = (SF << 2) | ceaSS; - frame[0x06] = FMT; - frame[0x07] = CA; - frame[0x08] = (DM_INH << 7) | (LSV << 3); - frame[0x09] = 0x00; - frame[0x0a] = 0x00; - frame[0x0b] = 0x00; - - nouveau_hdmi_infoframe(encoder, 0x000, frame); -} - -static void -nouveau_hdmi_disconnect(struct drm_encoder *encoder) -{ - nouveau_audio_disconnect(encoder); - - /* disable audio and avi infoframes */ - hdmi_mask(encoder, 0x000, 0x00000001, 0x00000000); - hdmi_mask(encoder, 0x020, 0x00000001, 0x00000000); - - /* disable hdmi */ - hdmi_mask(encoder, 0x0a4, 0x40000000, 0x00000000); -} - -void -nouveau_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector; - struct drm_device *dev = encoder->dev; - u32 max_ac_packet, rekey; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (!mode || !nv_connector || !nv_connector->edid || - !drm_detect_hdmi_monitor(nv_connector->edid)) { - nouveau_hdmi_disconnect(encoder); - return; - } - - nouveau_hdmi_video_infoframe(encoder, mode); - nouveau_hdmi_audio_infoframe(encoder, mode); - - hdmi_mask(encoder, 0x0d0, 0x00070001, 0x00010001); /* SPARE, HW_CTS */ - hdmi_mask(encoder, 0x068, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */ - hdmi_mask(encoder, 0x078, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */ - - nv_mask(dev, 0x61733c, 0x00100000, 0x00100000); /* RESETF */ - nv_mask(dev, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */ - nv_mask(dev, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ - - /* value matches nvidia binary driver, and tegra constant */ - rekey = 56; - - max_ac_packet = mode->htotal - mode->hdisplay; - max_ac_packet -= rekey; - max_ac_packet -= 18; /* constant from tegra */ - max_ac_packet /= 32; - - /* enable hdmi */ - hdmi_mask(encoder, 0x0a4, 0x5f1f003f, 0x40000000 | /* enable */ - 0x1f000000 | /* unknown */ - max_ac_packet << 16 | - rekey); - - nouveau_audio_mode_set(encoder, mode); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.c deleted file mode 100644 index ba896e54..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Copyright 2006 Dave Airlie - * Copyright 2007 Maarten Maathuis - * Copyright 2007-2009 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" - -#define CHIPSET_NFORCE 0x01a0 -#define CHIPSET_NFORCE2 0x01f0 - -/* - * misc hw access wrappers/control functions - */ - -void -NVWriteVgaSeq(struct drm_device *dev, int head, uint8_t index, uint8_t value) -{ - NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index); - NVWritePRMVIO(dev, head, NV_PRMVIO_SR, value); -} - -uint8_t -NVReadVgaSeq(struct drm_device *dev, int head, uint8_t index) -{ - NVWritePRMVIO(dev, head, NV_PRMVIO_SRX, index); - return NVReadPRMVIO(dev, head, NV_PRMVIO_SR); -} - -void -NVWriteVgaGr(struct drm_device *dev, int head, uint8_t index, uint8_t value) -{ - NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index); - NVWritePRMVIO(dev, head, NV_PRMVIO_GX, value); -} - -uint8_t -NVReadVgaGr(struct drm_device *dev, int head, uint8_t index) -{ - NVWritePRMVIO(dev, head, NV_PRMVIO_GRX, index); - return NVReadPRMVIO(dev, head, NV_PRMVIO_GX); -} - -/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied) - * it affects only the 8 bit vga io regs, which we access using mmio at - * 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d* - * in general, the set value of cr44 does not matter: reg access works as - * expected and values can be set for the appropriate head by using a 0x2000 - * offset as required - * however: - * a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and - * cr44 must be set to 0 or 3 for accessing values on the correct head - * through the common 0xc03c* addresses - * b) in tied mode (4) head B is programmed to the values set on head A, and - * access using the head B addresses can have strange results, ergo we leave - * tied mode in init once we know to what cr44 should be restored on exit - * - * the owner parameter is slightly abused: - * 0 and 1 are treated as head values and so the set value is (owner * 3) - * other values are treated as literal values to set - */ -void -NVSetOwner(struct drm_device *dev, int owner) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (owner == 1) - owner *= 3; - - if (dev_priv->chipset == 0x11) { - /* This might seem stupid, but the blob does it and - * omitting it often locks the system up. - */ - NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); - NVReadVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX); - } - - /* CR44 is always changed on CRTC0 */ - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_44, owner); - - if (dev_priv->chipset == 0x11) { /* set me harder */ - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner); - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_2E, owner); - } -} - -void -NVBlankScreen(struct drm_device *dev, int head, bool blank) -{ - unsigned char seq1; - - if (nv_two_heads(dev)) - NVSetOwner(dev, head); - - seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); - - NVVgaSeqReset(dev, head, true); - if (blank) - NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); - else - NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); - NVVgaSeqReset(dev, head, false); -} - -/* - * PLL setting - */ - -static int -powerctrl_1_shift(int chip_version, int reg) -{ - int shift = -4; - - if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20) - return shift; - - switch (reg) { - case NV_RAMDAC_VPLL2: - shift += 4; - case NV_PRAMDAC_VPLL_COEFF: - shift += 4; - case NV_PRAMDAC_MPLL_COEFF: - shift += 4; - case NV_PRAMDAC_NVPLL_COEFF: - shift += 4; - } - - /* - * the shift for vpll regs is only used for nv3x chips with a single - * stage pll - */ - if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 || - chip_version == 0x36 || chip_version >= 0x40)) - shift = -4; - - return shift; -} - -static void -setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chip_version = dev_priv->vbios.chip_version; - uint32_t oldpll = NVReadRAMDAC(dev, 0, reg); - int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff; - uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1; - uint32_t saved_powerctrl_1 = 0; - int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg); - - if (oldpll == pll) - return; /* already set */ - - if (shift_powerctrl_1 >= 0) { - saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1); - nvWriteMC(dev, NV_PBUS_POWERCTRL_1, - (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) | - 1 << shift_powerctrl_1); - } - - if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1)) - /* upclock -- write new post divider first */ - NVWriteRAMDAC(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff)); - else - /* downclock -- write new NM first */ - NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1); - - if (chip_version < 0x17 && chip_version != 0x11) - /* wait a bit on older chips */ - msleep(64); - NVReadRAMDAC(dev, 0, reg); - - /* then write the other half as well */ - NVWriteRAMDAC(dev, 0, reg, pll); - - if (shift_powerctrl_1 >= 0) - nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1); -} - -static uint32_t -new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580) -{ - bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF); - - if (ss) /* single stage pll mode */ - ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE : - NV_RAMDAC_580_VPLL2_ACTIVE; - else - ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE : - ~NV_RAMDAC_580_VPLL2_ACTIVE; - - return ramdac580; -} - -static void -setPLL_double_highregs(struct drm_device *dev, uint32_t reg1, - struct nouveau_pll_vals *pv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chip_version = dev_priv->vbios.chip_version; - bool nv3035 = chip_version == 0x30 || chip_version == 0x35; - uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70); - uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1); - uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 0, reg2) : 0; - uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1; - uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2; - uint32_t oldramdac580 = 0, ramdac580 = 0; - bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */ - uint32_t saved_powerctrl_1 = 0, savedc040 = 0; - int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1); - - /* model specific additions to generic pll1 and pll2 set up above */ - if (nv3035) { - pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 | - (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4; - pll2 = 0; - } - if (chip_version > 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */ - oldramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580); - ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580); - if (oldramdac580 != ramdac580) - oldpll1 = ~0; /* force mismatch */ - if (single_stage) - /* magic value used by nvidia in single stage mode */ - pll2 |= 0x011f; - } - if (chip_version > 0x70) - /* magic bits set by the blob (but not the bios) on g71-73 */ - pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28; - - if (oldpll1 == pll1 && oldpll2 == pll2) - return; /* already set */ - - if (shift_powerctrl_1 >= 0) { - saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1); - nvWriteMC(dev, NV_PBUS_POWERCTRL_1, - (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) | - 1 << shift_powerctrl_1); - } - - if (chip_version >= 0x40) { - int shift_c040 = 14; - - switch (reg1) { - case NV_PRAMDAC_MPLL_COEFF: - shift_c040 += 2; - case NV_PRAMDAC_NVPLL_COEFF: - shift_c040 += 2; - case NV_RAMDAC_VPLL2: - shift_c040 += 2; - case NV_PRAMDAC_VPLL_COEFF: - shift_c040 += 2; - } - - savedc040 = nvReadMC(dev, 0xc040); - if (shift_c040 != 14) - nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040)); - } - - if (oldramdac580 != ramdac580) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580); - - if (!nv3035) - NVWriteRAMDAC(dev, 0, reg2, pll2); - NVWriteRAMDAC(dev, 0, reg1, pll1); - - if (shift_powerctrl_1 >= 0) - nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1); - if (chip_version >= 0x40) - nvWriteMC(dev, 0xc040, savedc040); -} - -static void -setPLL_double_lowregs(struct drm_device *dev, uint32_t NMNMreg, - struct nouveau_pll_vals *pv) -{ - /* When setting PLLs, there is a merry game of disabling and enabling - * various bits of hardware during the process. This function is a - * synthesis of six nv4x traces, nearly each card doing a subtly - * different thing. With luck all the necessary bits for each card are - * combined herein. Without luck it deviates from each card's formula - * so as to not work on any :) - */ - - uint32_t Preg = NMNMreg - 4; - bool mpll = Preg == 0x4020; - uint32_t oldPval = nvReadMC(dev, Preg); - uint32_t NMNM = pv->NM2 << 16 | pv->NM1; - uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) | - 0xc << 28 | pv->log2P << 16; - uint32_t saved4600 = 0; - /* some cards have different maskc040s */ - uint32_t maskc040 = ~(3 << 14), savedc040; - bool single_stage = !pv->NM2 || pv->N2 == pv->M2; - - if (nvReadMC(dev, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval) - return; - - if (Preg == 0x4000) - maskc040 = ~0x333; - if (Preg == 0x4058) - maskc040 = ~(0xc << 24); - - if (mpll) { - struct pll_lims pll_lim; - uint8_t Pval2; - - if (get_pll_limits(dev, Preg, &pll_lim)) - return; - - Pval2 = pv->log2P + pll_lim.log2p_bias; - if (Pval2 > pll_lim.max_log2p) - Pval2 = pll_lim.max_log2p; - Pval |= 1 << 28 | Pval2 << 20; - - saved4600 = nvReadMC(dev, 0x4600); - nvWriteMC(dev, 0x4600, saved4600 | 8 << 28); - } - if (single_stage) - Pval |= mpll ? 1 << 12 : 1 << 8; - - nvWriteMC(dev, Preg, oldPval | 1 << 28); - nvWriteMC(dev, Preg, Pval & ~(4 << 28)); - if (mpll) { - Pval |= 8 << 20; - nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28)); - nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28)); - } - - savedc040 = nvReadMC(dev, 0xc040); - nvWriteMC(dev, 0xc040, savedc040 & maskc040); - - nvWriteMC(dev, NMNMreg, NMNM); - if (NMNMreg == 0x4024) - nvWriteMC(dev, 0x403c, NMNM); - - nvWriteMC(dev, Preg, Pval); - if (mpll) { - Pval &= ~(8 << 20); - nvWriteMC(dev, 0x4020, Pval); - nvWriteMC(dev, 0x4038, Pval); - nvWriteMC(dev, 0x4600, saved4600); - } - - nvWriteMC(dev, 0xc040, savedc040); - - if (mpll) { - nvWriteMC(dev, 0x4020, Pval & ~(1 << 28)); - nvWriteMC(dev, 0x4038, Pval & ~(1 << 28)); - } -} - -void -nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1, - struct nouveau_pll_vals *pv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int cv = dev_priv->vbios.chip_version; - - if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || - cv >= 0x40) { - if (reg1 > 0x405c) - setPLL_double_highregs(dev, reg1, pv); - else - setPLL_double_lowregs(dev, reg1, pv); - } else - setPLL_single(dev, reg1, pv); -} - -/* - * PLL getting - */ - -static void -nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1, - uint32_t pll2, struct nouveau_pll_vals *pllvals) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* to force parsing as single stage (i.e. nv40 vplls) pass pll2 as 0 */ - - /* log2P is & 0x7 as never more than 7, and nv30/35 only uses 3 bits */ - pllvals->log2P = (pll1 >> 16) & 0x7; - pllvals->N2 = pllvals->M2 = 1; - - if (reg1 <= 0x405c) { - pllvals->NM1 = pll2 & 0xffff; - /* single stage NVPLL and VPLLs use 1 << 8, MPLL uses 1 << 12 */ - if (!(pll1 & 0x1100)) - pllvals->NM2 = pll2 >> 16; - } else { - pllvals->NM1 = pll1 & 0xffff; - if (nv_two_reg_pll(dev) && pll2 & NV31_RAMDAC_ENABLE_VCO2) - pllvals->NM2 = pll2 & 0xffff; - else if (dev_priv->chipset == 0x30 || dev_priv->chipset == 0x35) { - pllvals->M1 &= 0xf; /* only 4 bits */ - if (pll1 & NV30_RAMDAC_ENABLE_VCO2) { - pllvals->M2 = (pll1 >> 4) & 0x7; - pllvals->N2 = ((pll1 >> 21) & 0x18) | - ((pll1 >> 19) & 0x7); - } - } - } -} - -int -nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype, - struct nouveau_pll_vals *pllvals) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t reg1 = get_pll_register(dev, plltype), pll1, pll2 = 0; - struct pll_lims pll_lim; - int ret; - - if (reg1 == 0) - return -ENOENT; - - pll1 = nvReadMC(dev, reg1); - - if (reg1 <= 0x405c) - pll2 = nvReadMC(dev, reg1 + 4); - else if (nv_two_reg_pll(dev)) { - uint32_t reg2 = reg1 + (reg1 == NV_RAMDAC_VPLL2 ? 0x5c : 0x70); - - pll2 = nvReadMC(dev, reg2); - } - - if (dev_priv->card_type == 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { - uint32_t ramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580); - - /* check whether vpll has been forced into single stage mode */ - if (reg1 == NV_PRAMDAC_VPLL_COEFF) { - if (ramdac580 & NV_RAMDAC_580_VPLL1_ACTIVE) - pll2 = 0; - } else - if (ramdac580 & NV_RAMDAC_580_VPLL2_ACTIVE) - pll2 = 0; - } - - nouveau_hw_decode_pll(dev, reg1, pll1, pll2, pllvals); - - ret = get_pll_limits(dev, plltype, &pll_lim); - if (ret) - return ret; - - pllvals->refclk = pll_lim.refclk; - - return 0; -} - -int -nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv) -{ - /* Avoid divide by zero if called at an inappropriate time */ - if (!pv->M1 || !pv->M2) - return 0; - - return pv->N1 * pv->N2 * pv->refclk / (pv->M1 * pv->M2) >> pv->log2P; -} - -int -nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype) -{ - struct nouveau_pll_vals pllvals; - int ret; - - if (plltype == PLL_MEMORY && - (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) { - uint32_t mpllP; - - pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); - if (!mpllP) - mpllP = 4; - - return 400000 / mpllP; - } else - if (plltype == PLL_MEMORY && - (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) { - uint32_t clock; - - pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); - return clock; - } - - ret = nouveau_hw_get_pllvals(dev, plltype, &pllvals); - if (ret) - return ret; - - return nouveau_hw_pllvals_to_clk(&pllvals); -} - -static void -nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head) -{ - /* the vpll on an unused head can come up with a random value, way - * beyond the pll limits. for some reason this causes the chip to - * lock up when reading the dac palette regs, so set a valid pll here - * when such a condition detected. only seen on nv11 to date - */ - - struct pll_lims pll_lim; - struct nouveau_pll_vals pv; - enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0; - - if (get_pll_limits(dev, pll, &pll_lim)) - return; - nouveau_hw_get_pllvals(dev, pll, &pv); - - if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && - pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && - pv.log2P <= pll_lim.max_log2p) - return; - - NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1); - - /* set lowest clock within static limits */ - pv.M1 = pll_lim.vco1.max_m; - pv.N1 = pll_lim.vco1.min_n; - pv.log2P = pll_lim.max_usable_log2p; - nouveau_hw_setpll(dev, pll_lim.reg, &pv); -} - -/* - * vga font save/restore - */ - -static void nouveau_vga_font_io(struct drm_device *dev, - void __iomem *iovram, - bool save, unsigned plane) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned i; - - NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, 1 << plane); - NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, plane); - for (i = 0; i < 16384; i++) { - if (save) { - dev_priv->saved_vga_font[plane][i] = - ioread32_native(iovram + i * 4); - } else { - iowrite32_native(dev_priv->saved_vga_font[plane][i], - iovram + i * 4); - } - } -} - -void -nouveau_hw_save_vga_fonts(struct drm_device *dev, bool save) -{ - uint8_t misc, gr4, gr5, gr6, seq2, seq4; - bool graphicsmode; - unsigned plane; - void __iomem *iovram; - - if (nv_two_heads(dev)) - NVSetOwner(dev, 0); - - NVSetEnablePalette(dev, 0, true); - graphicsmode = NVReadVgaAttr(dev, 0, NV_CIO_AR_MODE_INDEX) & 1; - NVSetEnablePalette(dev, 0, false); - - if (graphicsmode) /* graphics mode => framebuffer => no need to save */ - return; - - NV_INFO(dev, "%sing VGA fonts\n", save ? "Sav" : "Restor"); - - /* map first 64KiB of VRAM, holds VGA fonts etc */ - iovram = ioremap(pci_resource_start(dev->pdev, 1), 65536); - if (!iovram) { - NV_ERROR(dev, "Failed to map VRAM, " - "cannot save/restore VGA fonts.\n"); - return; - } - - if (nv_two_heads(dev)) - NVBlankScreen(dev, 1, true); - NVBlankScreen(dev, 0, true); - - /* save control regs */ - misc = NVReadPRMVIO(dev, 0, NV_PRMVIO_MISC__READ); - seq2 = NVReadVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX); - seq4 = NVReadVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX); - gr4 = NVReadVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX); - gr5 = NVReadVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX); - gr6 = NVReadVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX); - - NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, 0x67); - NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, 0x6); - NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, 0x0); - NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, 0x5); - - /* store font in planes 0..3 */ - for (plane = 0; plane < 4; plane++) - nouveau_vga_font_io(dev, iovram, save, plane); - - /* restore control regs */ - NVWritePRMVIO(dev, 0, NV_PRMVIO_MISC__WRITE, misc); - NVWriteVgaGr(dev, 0, NV_VIO_GX_READ_MAP_INDEX, gr4); - NVWriteVgaGr(dev, 0, NV_VIO_GX_MODE_INDEX, gr5); - NVWriteVgaGr(dev, 0, NV_VIO_GX_MISC_INDEX, gr6); - NVWriteVgaSeq(dev, 0, NV_VIO_SR_PLANE_MASK_INDEX, seq2); - NVWriteVgaSeq(dev, 0, NV_VIO_SR_MEM_MODE_INDEX, seq4); - - if (nv_two_heads(dev)) - NVBlankScreen(dev, 1, false); - NVBlankScreen(dev, 0, false); - - iounmap(iovram); -} - -/* - * mode state save/load - */ - -static void -rd_cio_state(struct drm_device *dev, int head, - struct nv04_crtc_reg *crtcstate, int index) -{ - crtcstate->CRTC[index] = NVReadVgaCrtc(dev, head, index); -} - -static void -wr_cio_state(struct drm_device *dev, int head, - struct nv04_crtc_reg *crtcstate, int index) -{ - NVWriteVgaCrtc(dev, head, index, crtcstate->CRTC[index]); -} - -static void -nv_save_state_ramdac(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *regp = &state->crtc_reg[head]; - int i; - - if (dev_priv->card_type >= NV_10) - regp->nv10_cursync = NVReadRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC); - - nouveau_hw_get_pllvals(dev, head ? PLL_VPLL1 : PLL_VPLL0, ®p->pllvals); - state->pllsel = NVReadRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT); - if (nv_two_heads(dev)) - state->sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK); - if (dev_priv->chipset == 0x11) - regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11); - - regp->ramdac_gen_ctrl = NVReadRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL); - - if (nv_gf4_disp_arch(dev)) - regp->ramdac_630 = NVReadRAMDAC(dev, head, NV_PRAMDAC_630); - if (dev_priv->chipset >= 0x30) - regp->ramdac_634 = NVReadRAMDAC(dev, head, NV_PRAMDAC_634); - - regp->tv_setup = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP); - regp->tv_vtotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL); - regp->tv_vskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW); - regp->tv_vsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY); - regp->tv_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL); - regp->tv_hskew = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW); - regp->tv_hsync_delay = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY); - regp->tv_hsync_delay2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2); - - for (i = 0; i < 7; i++) { - uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4); - regp->fp_vert_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg); - regp->fp_horiz_regs[i] = NVReadRAMDAC(dev, head, ramdac_reg + 0x20); - } - - if (nv_gf4_disp_arch(dev)) { - regp->dither = NVReadRAMDAC(dev, head, NV_RAMDAC_FP_DITHER); - for (i = 0; i < 3; i++) { - regp->dither_regs[i] = NVReadRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4); - regp->dither_regs[i + 3] = NVReadRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4); - } - } - - regp->fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); - regp->fp_debug_0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0); - if (!nv_gf4_disp_arch(dev) && head == 0) { - /* early chips don't allow access to PRAMDAC_TMDS_* without - * the head A FPCLK on (nv11 even locks up) */ - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0 & - ~NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK); - } - regp->fp_debug_1 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1); - regp->fp_debug_2 = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2); - - regp->fp_margin_color = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR); - - if (nv_gf4_disp_arch(dev)) - regp->ramdac_8c0 = NVReadRAMDAC(dev, head, NV_PRAMDAC_8C0); - - if (dev_priv->card_type == NV_40) { - regp->ramdac_a20 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A20); - regp->ramdac_a24 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A24); - regp->ramdac_a34 = NVReadRAMDAC(dev, head, NV_PRAMDAC_A34); - - for (i = 0; i < 38; i++) - regp->ctv_regs[i] = NVReadRAMDAC(dev, head, - NV_PRAMDAC_CTV + 4*i); - } -} - -static void -nv_load_state_ramdac(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *regp = &state->crtc_reg[head]; - uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; - int i; - - if (dev_priv->card_type >= NV_10) - NVWriteRAMDAC(dev, head, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync); - - nouveau_hw_setpll(dev, pllreg, ®p->pllvals); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); - if (nv_two_heads(dev)) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, state->sel_clk); - if (dev_priv->chipset == 0x11) - NVWriteRAMDAC(dev, head, NV_RAMDAC_DITHER_NV11, regp->dither); - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_GENERAL_CONTROL, regp->ramdac_gen_ctrl); - - if (nv_gf4_disp_arch(dev)) - NVWriteRAMDAC(dev, head, NV_PRAMDAC_630, regp->ramdac_630); - if (dev_priv->chipset >= 0x30) - NVWriteRAMDAC(dev, head, NV_PRAMDAC_634, regp->ramdac_634); - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, regp->tv_setup); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VTOTAL, regp->tv_vtotal); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSKEW, regp->tv_vskew); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_VSYNC_DELAY, regp->tv_vsync_delay); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HTOTAL, regp->tv_htotal); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSKEW, regp->tv_hskew); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY, regp->tv_hsync_delay); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_HSYNC_DELAY2, regp->tv_hsync_delay2); - - for (i = 0; i < 7; i++) { - uint32_t ramdac_reg = NV_PRAMDAC_FP_VDISPLAY_END + (i * 4); - - NVWriteRAMDAC(dev, head, ramdac_reg, regp->fp_vert_regs[i]); - NVWriteRAMDAC(dev, head, ramdac_reg + 0x20, regp->fp_horiz_regs[i]); - } - - if (nv_gf4_disp_arch(dev)) { - NVWriteRAMDAC(dev, head, NV_RAMDAC_FP_DITHER, regp->dither); - for (i = 0; i < 3; i++) { - NVWriteRAMDAC(dev, head, NV_PRAMDAC_850 + i * 4, regp->dither_regs[i]); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_85C + i * 4, regp->dither_regs[i + 3]); - } - } - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, regp->fp_control); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_0, regp->fp_debug_0); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regp->fp_debug_1); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_2, regp->fp_debug_2); - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_MARGIN_COLOR, regp->fp_margin_color); - - if (nv_gf4_disp_arch(dev)) - NVWriteRAMDAC(dev, head, NV_PRAMDAC_8C0, regp->ramdac_8c0); - - if (dev_priv->card_type == NV_40) { - NVWriteRAMDAC(dev, head, NV_PRAMDAC_A20, regp->ramdac_a20); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_A24, regp->ramdac_a24); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_A34, regp->ramdac_a34); - - for (i = 0; i < 38; i++) - NVWriteRAMDAC(dev, head, - NV_PRAMDAC_CTV + 4*i, regp->ctv_regs[i]); - } -} - -static void -nv_save_state_vga(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct nv04_crtc_reg *regp = &state->crtc_reg[head]; - int i; - - regp->MiscOutReg = NVReadPRMVIO(dev, head, NV_PRMVIO_MISC__READ); - - for (i = 0; i < 25; i++) - rd_cio_state(dev, head, regp, i); - - NVSetEnablePalette(dev, head, true); - for (i = 0; i < 21; i++) - regp->Attribute[i] = NVReadVgaAttr(dev, head, i); - NVSetEnablePalette(dev, head, false); - - for (i = 0; i < 9; i++) - regp->Graphics[i] = NVReadVgaGr(dev, head, i); - - for (i = 0; i < 5; i++) - regp->Sequencer[i] = NVReadVgaSeq(dev, head, i); -} - -static void -nv_load_state_vga(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct nv04_crtc_reg *regp = &state->crtc_reg[head]; - int i; - - NVWritePRMVIO(dev, head, NV_PRMVIO_MISC__WRITE, regp->MiscOutReg); - - for (i = 0; i < 5; i++) - NVWriteVgaSeq(dev, head, i, regp->Sequencer[i]); - - nv_lock_vga_crtc_base(dev, head, false); - for (i = 0; i < 25; i++) - wr_cio_state(dev, head, regp, i); - nv_lock_vga_crtc_base(dev, head, true); - - for (i = 0; i < 9; i++) - NVWriteVgaGr(dev, head, i, regp->Graphics[i]); - - NVSetEnablePalette(dev, head, true); - for (i = 0; i < 21; i++) - NVWriteVgaAttr(dev, head, i, regp->Attribute[i]); - NVSetEnablePalette(dev, head, false); -} - -static void -nv_save_state_ext(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *regp = &state->crtc_reg[head]; - int i; - - rd_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); - - rd_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_21); - - if (dev_priv->card_type >= NV_20) - rd_cio_state(dev, head, regp, NV_CIO_CRE_47); - - if (dev_priv->card_type >= NV_30) - rd_cio_state(dev, head, regp, 0x9f); - - rd_cio_state(dev, head, regp, NV_CIO_CRE_49); - rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX); - - if (dev_priv->card_type >= NV_10) { - regp->crtc_830 = NVReadCRTC(dev, head, NV_PCRTC_830); - regp->crtc_834 = NVReadCRTC(dev, head, NV_PCRTC_834); - - if (dev_priv->card_type >= NV_30) - regp->gpio_ext = NVReadCRTC(dev, head, NV_PCRTC_GPIO_EXT); - - if (dev_priv->card_type == NV_40) - regp->crtc_850 = NVReadCRTC(dev, head, NV_PCRTC_850); - - if (nv_two_heads(dev)) - regp->crtc_eng_ctrl = NVReadCRTC(dev, head, NV_PCRTC_ENGINE_CTRL); - regp->cursor_cfg = NVReadCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG); - } - - regp->crtc_cfg = NVReadCRTC(dev, head, NV_PCRTC_CONFIG); - - rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX); - if (dev_priv->card_type >= NV_10) { - rd_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX); - rd_cio_state(dev, head, regp, NV_CIO_CRE_CSB); - rd_cio_state(dev, head, regp, NV_CIO_CRE_4B); - rd_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY); - } - /* NV11 and NV20 don't have this, they stop at 0x52. */ - if (nv_gf4_disp_arch(dev)) { - rd_cio_state(dev, head, regp, NV_CIO_CRE_42); - rd_cio_state(dev, head, regp, NV_CIO_CRE_53); - rd_cio_state(dev, head, regp, NV_CIO_CRE_54); - - for (i = 0; i < 0x10; i++) - regp->CR58[i] = NVReadVgaCrtc5758(dev, head, i); - rd_cio_state(dev, head, regp, NV_CIO_CRE_59); - rd_cio_state(dev, head, regp, NV_CIO_CRE_5B); - - rd_cio_state(dev, head, regp, NV_CIO_CRE_85); - rd_cio_state(dev, head, regp, NV_CIO_CRE_86); - } - - regp->fb_start = NVReadCRTC(dev, head, NV_PCRTC_START); -} - -static void -nv_load_state_ext(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *regp = &state->crtc_reg[head]; - uint32_t reg900; - int i; - - if (dev_priv->card_type >= NV_10) { - if (nv_two_heads(dev)) - /* setting ENGINE_CTRL (EC) *must* come before - * CIO_CRE_LCD, as writing CRE_LCD sets bits 16 & 17 in - * EC that should not be overwritten by writing stale EC - */ - NVWriteCRTC(dev, head, NV_PCRTC_ENGINE_CTRL, regp->crtc_eng_ctrl); - - nvWriteVIDEO(dev, NV_PVIDEO_STOP, 1); - nvWriteVIDEO(dev, NV_PVIDEO_INTR_EN, 0); - nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(0), 0); - nvWriteVIDEO(dev, NV_PVIDEO_OFFSET_BUFF(1), 0); - nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(0), dev_priv->fb_available_size - 1); - nvWriteVIDEO(dev, NV_PVIDEO_LIMIT(1), dev_priv->fb_available_size - 1); - nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(0), dev_priv->fb_available_size - 1); - nvWriteVIDEO(dev, NV_PVIDEO_UVPLANE_LIMIT(1), dev_priv->fb_available_size - 1); - nvWriteMC(dev, NV_PBUS_POWERCTRL_2, 0); - - NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg); - NVWriteCRTC(dev, head, NV_PCRTC_830, regp->crtc_830); - NVWriteCRTC(dev, head, NV_PCRTC_834, regp->crtc_834); - - if (dev_priv->card_type >= NV_30) - NVWriteCRTC(dev, head, NV_PCRTC_GPIO_EXT, regp->gpio_ext); - - if (dev_priv->card_type == NV_40) { - NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850); - - reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900); - if (regp->crtc_cfg == NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC) - NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 | 0x10000); - else - NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 & ~0x10000); - } - } - - NVWriteCRTC(dev, head, NV_PCRTC_CONFIG, regp->crtc_cfg); - - wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC0_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_RPC1_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_LSR_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_PIXEL_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_LCD__INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_HEB__INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_ENH_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_FF_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_FFLWM__INDEX); - - if (dev_priv->card_type >= NV_20) - wr_cio_state(dev, head, regp, NV_CIO_CRE_47); - - if (dev_priv->card_type >= NV_30) - wr_cio_state(dev, head, regp, 0x9f); - - wr_cio_state(dev, head, regp, NV_CIO_CRE_49); - wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); - if (dev_priv->card_type == NV_40) - nv_fix_nv40_hw_cursor(dev, head); - wr_cio_state(dev, head, regp, NV_CIO_CRE_ILACE__INDEX); - - wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH3__INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_SCRATCH4__INDEX); - if (dev_priv->card_type >= NV_10) { - wr_cio_state(dev, head, regp, NV_CIO_CRE_EBR_INDEX); - wr_cio_state(dev, head, regp, NV_CIO_CRE_CSB); - wr_cio_state(dev, head, regp, NV_CIO_CRE_4B); - wr_cio_state(dev, head, regp, NV_CIO_CRE_TVOUT_LATENCY); - } - /* NV11 and NV20 stop at 0x52. */ - if (nv_gf4_disp_arch(dev)) { - if (dev_priv->card_type == NV_10) { - /* Not waiting for vertical retrace before modifying - CRE_53/CRE_54 causes lockups. */ - nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8); - nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0); - } - - wr_cio_state(dev, head, regp, NV_CIO_CRE_42); - wr_cio_state(dev, head, regp, NV_CIO_CRE_53); - wr_cio_state(dev, head, regp, NV_CIO_CRE_54); - - for (i = 0; i < 0x10; i++) - NVWriteVgaCrtc5758(dev, head, i, regp->CR58[i]); - wr_cio_state(dev, head, regp, NV_CIO_CRE_59); - wr_cio_state(dev, head, regp, NV_CIO_CRE_5B); - - wr_cio_state(dev, head, regp, NV_CIO_CRE_85); - wr_cio_state(dev, head, regp, NV_CIO_CRE_86); - } - - NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start); - - /* Enable vblank interrupts. */ - NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, - (dev->vblank_enabled[head] ? 1 : 0)); - NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK); -} - -static void -nv_save_state_palette(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - int head_offset = head * NV_PRMDIO_SIZE, i; - - nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset, - NV_PRMDIO_PIXEL_MASK_MASK); - nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS + head_offset, 0x0); - - for (i = 0; i < 768; i++) { - state->crtc_reg[head].DAC[i] = nv_rd08(dev, - NV_PRMDIO_PALETTE_DATA + head_offset); - } - - NVSetEnablePalette(dev, head, false); -} - -void -nouveau_hw_load_state_palette(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - int head_offset = head * NV_PRMDIO_SIZE, i; - - nv_wr08(dev, NV_PRMDIO_PIXEL_MASK + head_offset, - NV_PRMDIO_PIXEL_MASK_MASK); - nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS + head_offset, 0x0); - - for (i = 0; i < 768; i++) { - nv_wr08(dev, NV_PRMDIO_PALETTE_DATA + head_offset, - state->crtc_reg[head].DAC[i]); - } - - NVSetEnablePalette(dev, head, false); -} - -void nouveau_hw_save_state(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset == 0x11) - /* NB: no attempt is made to restore the bad pll later on */ - nouveau_hw_fix_bad_vpll(dev, head); - nv_save_state_ramdac(dev, head, state); - nv_save_state_vga(dev, head, state); - nv_save_state_palette(dev, head, state); - nv_save_state_ext(dev, head, state); -} - -void nouveau_hw_load_state(struct drm_device *dev, int head, - struct nv04_mode_state *state) -{ - NVVgaProtect(dev, head, true); - nv_load_state_ramdac(dev, head, state); - nv_load_state_ext(dev, head, state); - nouveau_hw_load_state_palette(dev, head, state); - nv_load_state_vga(dev, head, state); - NVVgaProtect(dev, head, false); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.h deleted file mode 100644 index 2989090b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hw.h +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright 2008 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __NOUVEAU_HW_H__ -#define __NOUVEAU_HW_H__ - -#include "drmP.h" -#include "nouveau_drv.h" - -#define MASK(field) ( \ - (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field)) - -#define XLATE(src, srclowbit, outfield) ( \ - (((src) >> (srclowbit)) << (0 ? outfield)) & MASK(outfield)) - -void NVWriteVgaSeq(struct drm_device *, int head, uint8_t index, uint8_t value); -uint8_t NVReadVgaSeq(struct drm_device *, int head, uint8_t index); -void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value); -uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index); -void NVSetOwner(struct drm_device *, int owner); -void NVBlankScreen(struct drm_device *, int head, bool blank); -void nouveau_hw_setpll(struct drm_device *, uint32_t reg1, - struct nouveau_pll_vals *pv); -int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype, - struct nouveau_pll_vals *pllvals); -int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals); -int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype); -void nouveau_hw_save_vga_fonts(struct drm_device *, bool save); -void nouveau_hw_save_state(struct drm_device *, int head, - struct nv04_mode_state *state); -void nouveau_hw_load_state(struct drm_device *, int head, - struct nv04_mode_state *state); -void nouveau_hw_load_state_palette(struct drm_device *, int head, - struct nv04_mode_state *state); - -/* nouveau_calc.c */ -extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, - int *burst, int *lwm); -extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim, - int clk, struct nouveau_pll_vals *pv); - -static inline uint32_t -nvReadMC(struct drm_device *dev, uint32_t reg) -{ - uint32_t val = nv_rd32(dev, reg); - NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); - return val; -} - -static inline void -nvWriteMC(struct drm_device *dev, uint32_t reg, uint32_t val) -{ - NV_REG_DEBUG(MC, dev, "reg %08x val %08x\n", reg, val); - nv_wr32(dev, reg, val); -} - -static inline uint32_t -nvReadVIDEO(struct drm_device *dev, uint32_t reg) -{ - uint32_t val = nv_rd32(dev, reg); - NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); - return val; -} - -static inline void -nvWriteVIDEO(struct drm_device *dev, uint32_t reg, uint32_t val) -{ - NV_REG_DEBUG(VIDEO, dev, "reg %08x val %08x\n", reg, val); - nv_wr32(dev, reg, val); -} - -static inline uint32_t -nvReadFB(struct drm_device *dev, uint32_t reg) -{ - uint32_t val = nv_rd32(dev, reg); - NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); - return val; -} - -static inline void -nvWriteFB(struct drm_device *dev, uint32_t reg, uint32_t val) -{ - NV_REG_DEBUG(FB, dev, "reg %08x val %08x\n", reg, val); - nv_wr32(dev, reg, val); -} - -static inline uint32_t -nvReadEXTDEV(struct drm_device *dev, uint32_t reg) -{ - uint32_t val = nv_rd32(dev, reg); - NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); - return val; -} - -static inline void -nvWriteEXTDEV(struct drm_device *dev, uint32_t reg, uint32_t val) -{ - NV_REG_DEBUG(EXTDEV, dev, "reg %08x val %08x\n", reg, val); - nv_wr32(dev, reg, val); -} - -static inline uint32_t NVReadCRTC(struct drm_device *dev, - int head, uint32_t reg) -{ - uint32_t val; - if (head) - reg += NV_PCRTC0_SIZE; - val = nv_rd32(dev, reg); - NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); - return val; -} - -static inline void NVWriteCRTC(struct drm_device *dev, - int head, uint32_t reg, uint32_t val) -{ - if (head) - reg += NV_PCRTC0_SIZE; - NV_REG_DEBUG(CRTC, dev, "head %d reg %08x val %08x\n", head, reg, val); - nv_wr32(dev, reg, val); -} - -static inline uint32_t NVReadRAMDAC(struct drm_device *dev, - int head, uint32_t reg) -{ - uint32_t val; - if (head) - reg += NV_PRAMDAC0_SIZE; - val = nv_rd32(dev, reg); - NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", - head, reg, val); - return val; -} - -static inline void NVWriteRAMDAC(struct drm_device *dev, - int head, uint32_t reg, uint32_t val) -{ - if (head) - reg += NV_PRAMDAC0_SIZE; - NV_REG_DEBUG(RAMDAC, dev, "head %d reg %08x val %08x\n", - head, reg, val); - nv_wr32(dev, reg, val); -} - -static inline uint8_t nv_read_tmds(struct drm_device *dev, - int or, int dl, uint8_t address) -{ - int ramdac = (or & OUTPUT_C) >> 2; - - NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, - NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address); - return NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8); -} - -static inline void nv_write_tmds(struct drm_device *dev, - int or, int dl, uint8_t address, - uint8_t data) -{ - int ramdac = (or & OUTPUT_C) >> 2; - - NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA + dl * 8, data); - NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL + dl * 8, address); -} - -static inline void NVWriteVgaCrtc(struct drm_device *dev, - int head, uint8_t index, uint8_t value) -{ - NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", - head, index, value); - nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); - nv_wr08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); -} - -static inline uint8_t NVReadVgaCrtc(struct drm_device *dev, - int head, uint8_t index) -{ - uint8_t val; - nv_wr08(dev, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); - val = nv_rd08(dev, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE); - NV_REG_DEBUG(VGACRTC, dev, "head %d index 0x%02x data 0x%02x\n", - head, index, val); - return val; -} - -/* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58 - * I suspect they in fact do nothing, but are merely a way to carry useful - * per-head variables around - * - * Known uses: - * CR57 CR58 - * 0x00 index to the appropriate dcb entry (or 7f for inactive) - * 0x02 dcb entry's "or" value (or 00 for inactive) - * 0x03 bit0 set for dual link (LVDS, possibly elsewhere too) - * 0x08 or 0x09 pxclk in MHz - * 0x0f laptop panel info - low nibble for PEXTDEV_BOOT_0 strap - * high nibble for xlat strap value - */ - -static inline void -NVWriteVgaCrtc5758(struct drm_device *dev, int head, uint8_t index, uint8_t value) -{ - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_58, value); -} - -static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_t index) -{ - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_57, index); - return NVReadVgaCrtc(dev, head, NV_CIO_CRE_58); -} - -static inline uint8_t NVReadPRMVIO(struct drm_device *dev, - int head, uint32_t reg) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint8_t val; - - /* Only NV4x have two pvio ranges; other twoHeads cards MUST call - * NVSetOwner for the relevant head to be programmed */ - if (head && dev_priv->card_type == NV_40) - reg += NV_PRMVIO_SIZE; - - val = nv_rd08(dev, reg); - NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", head, reg, val); - return val; -} - -static inline void NVWritePRMVIO(struct drm_device *dev, - int head, uint32_t reg, uint8_t value) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* Only NV4x have two pvio ranges; other twoHeads cards MUST call - * NVSetOwner for the relevant head to be programmed */ - if (head && dev_priv->card_type == NV_40) - reg += NV_PRMVIO_SIZE; - - NV_REG_DEBUG(RMVIO, dev, "head %d reg %08x val %02x\n", - head, reg, value); - nv_wr08(dev, reg, value); -} - -static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable) -{ - nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); - nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); -} - -static inline bool NVGetEnablePalette(struct drm_device *dev, int head) -{ - nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); - return !(nv_rd08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); -} - -static inline void NVWriteVgaAttr(struct drm_device *dev, - int head, uint8_t index, uint8_t value) -{ - if (NVGetEnablePalette(dev, head)) - index &= ~0x20; - else - index |= 0x20; - - nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); - NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", - head, index, value); - nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); - nv_wr08(dev, NV_PRMCIO_AR__WRITE + head * NV_PRMCIO_SIZE, value); -} - -static inline uint8_t NVReadVgaAttr(struct drm_device *dev, - int head, uint8_t index) -{ - uint8_t val; - if (NVGetEnablePalette(dev, head)) - index &= ~0x20; - else - index |= 0x20; - - nv_rd08(dev, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); - nv_wr08(dev, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, index); - val = nv_rd08(dev, NV_PRMCIO_AR__READ + head * NV_PRMCIO_SIZE); - NV_REG_DEBUG(VGAATTR, dev, "head %d index 0x%02x data 0x%02x\n", - head, index, val); - return val; -} - -static inline void NVVgaSeqReset(struct drm_device *dev, int head, bool start) -{ - NVWriteVgaSeq(dev, head, NV_VIO_SR_RESET_INDEX, start ? 0x1 : 0x3); -} - -static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect) -{ - uint8_t seq1 = NVReadVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX); - - if (protect) { - NVVgaSeqReset(dev, head, true); - NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 | 0x20); - } else { - /* Reenable sequencer, then turn on screen */ - NVWriteVgaSeq(dev, head, NV_VIO_SR_CLOCK_INDEX, seq1 & ~0x20); /* reenable display */ - NVVgaSeqReset(dev, head, false); - } - NVSetEnablePalette(dev, head, protect); -} - -static inline bool -nv_heads_tied(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset == 0x11) - return !!(nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)); - - return NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44) & 0x4; -} - -/* makes cr0-7 on the specified head read-only */ -static inline bool -nv_lock_vga_crtc_base(struct drm_device *dev, int head, bool lock) -{ - uint8_t cr11 = NVReadVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX); - bool waslocked = cr11 & 0x80; - - if (lock) - cr11 |= 0x80; - else - cr11 &= ~0x80; - NVWriteVgaCrtc(dev, head, NV_CIO_CR_VRE_INDEX, cr11); - - return waslocked; -} - -static inline void -nv_lock_vga_crtc_shadow(struct drm_device *dev, int head, int lock) -{ - /* shadow lock: connects 0x60?3d? regs to "real" 0x3d? regs - * bit7: unlocks HDT, HBS, HBE, HRS, HRE, HEB - * bit6: seems to have some effect on CR09 (double scan, VBS_9) - * bit5: unlocks HDE - * bit4: unlocks VDE - * bit3: unlocks VDT, OVL, VRS, ?VRE?, VBS, VBE, LSR, EBR - * bit2: same as bit 1 of 0x60?804 - * bit0: same as bit 0 of 0x60?804 - */ - - uint8_t cr21 = lock; - - if (lock < 0) - /* 0xfa is generic "unlock all" mask */ - cr21 = NVReadVgaCrtc(dev, head, NV_CIO_CRE_21) | 0xfa; - - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_21, cr21); -} - -/* renders the extended crtc regs (cr19+) on all crtcs impervious: - * immutable and unreadable - */ -static inline bool -NVLockVgaCrtcs(struct drm_device *dev, bool lock) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - bool waslocked = !NVReadVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX); - - NVWriteVgaCrtc(dev, 0, NV_CIO_SR_LOCK_INDEX, - lock ? NV_CIO_SR_LOCK_VALUE : NV_CIO_SR_UNLOCK_RW_VALUE); - /* NV11 has independently lockable extended crtcs, except when tied */ - if (dev_priv->chipset == 0x11 && !nv_heads_tied(dev)) - NVWriteVgaCrtc(dev, 1, NV_CIO_SR_LOCK_INDEX, - lock ? NV_CIO_SR_LOCK_VALUE : - NV_CIO_SR_UNLOCK_RW_VALUE); - - return waslocked; -} - -/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */ -#define NV04_CURSOR_SIZE 32 -/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */ -#define NV10_CURSOR_SIZE 64 - -static inline int nv_cursor_width(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - return dev_priv->card_type >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE; -} - -static inline void -nv_fix_nv40_hw_cursor(struct drm_device *dev, int head) -{ - /* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense) nv40, - * the gf6800gt) a hardware bug requires a write to PRAMDAC_CURSOR_POS - * for changes to the CRTC CURCTL regs to take effect, whether changing - * the pixmap location, or just showing/hiding the cursor - */ - uint32_t curpos = NVReadRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_CU_START_POS, curpos); -} - -static inline void -nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - NVWriteCRTC(dev, head, NV_PCRTC_START, offset); - - if (dev_priv->card_type == NV_04) { - /* - * Hilarious, the 24th bit doesn't want to stick to - * PCRTC_START... - */ - int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX); - - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX, - (cre_heb & ~0x40) | ((offset >> 18) & 0x40)); - } -} - -static inline void -nv_show_cursor(struct drm_device *dev, int head, bool show) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint8_t *curctl1 = - &dev_priv->mode_reg.crtc_reg[head].CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX]; - - if (show) - *curctl1 |= MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); - else - *curctl1 &= ~MASK(NV_CIO_CRE_HCUR_ADDR1_ENABLE); - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HCUR_ADDR1_INDEX, *curctl1); - - if (dev_priv->card_type == NV_40) - nv_fix_nv40_hw_cursor(dev, head); -} - -static inline uint32_t -nv_pitch_align(struct drm_device *dev, uint32_t width, int bpp) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int mask; - - if (bpp == 15) - bpp = 16; - if (bpp == 24) - bpp = 8; - - /* Alignment requirements taken from the Haiku driver */ - if (dev_priv->card_type == NV_04) - mask = 128 / bpp - 1; - else - mask = 512 / bpp - 1; - - return (width + mask) & ~mask; -} - -#endif /* __NOUVEAU_HW_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hwsq.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hwsq.h deleted file mode 100644 index 69768759..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_hwsq.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#ifndef __NOUVEAU_HWSQ_H__ -#define __NOUVEAU_HWSQ_H__ - -struct hwsq_ucode { - u8 data[0x200]; - union { - u8 *u08; - u16 *u16; - u32 *u32; - } ptr; - u16 len; - - u32 reg; - u32 val; -}; - -static inline void -hwsq_init(struct hwsq_ucode *hwsq) -{ - hwsq->ptr.u08 = hwsq->data; - hwsq->reg = 0xffffffff; - hwsq->val = 0xffffffff; -} - -static inline void -hwsq_fini(struct hwsq_ucode *hwsq) -{ - do { - *hwsq->ptr.u08++ = 0x7f; - hwsq->len = hwsq->ptr.u08 - hwsq->data; - } while (hwsq->len & 3); - hwsq->ptr.u08 = hwsq->data; -} - -static inline void -hwsq_usec(struct hwsq_ucode *hwsq, u8 usec) -{ - u32 shift = 0; - while (usec & ~3) { - usec >>= 2; - shift++; - } - - *hwsq->ptr.u08++ = (shift << 2) | usec; -} - -static inline void -hwsq_setf(struct hwsq_ucode *hwsq, u8 flag, int val) -{ - flag += 0x80; - if (val >= 0) - flag += 0x20; - if (val >= 1) - flag += 0x20; - *hwsq->ptr.u08++ = flag; -} - -static inline void -hwsq_op5f(struct hwsq_ucode *hwsq, u8 v0, u8 v1) -{ - *hwsq->ptr.u08++ = 0x5f; - *hwsq->ptr.u08++ = v0; - *hwsq->ptr.u08++ = v1; -} - -static inline void -hwsq_wr32(struct hwsq_ucode *hwsq, u32 reg, u32 val) -{ - if (val != hwsq->val) { - if ((val & 0xffff0000) == (hwsq->val & 0xffff0000)) { - *hwsq->ptr.u08++ = 0x42; - *hwsq->ptr.u16++ = (val & 0x0000ffff); - } else { - *hwsq->ptr.u08++ = 0xe2; - *hwsq->ptr.u32++ = val; - } - - hwsq->val = val; - } - - if ((reg & 0xffff0000) == (hwsq->reg & 0xffff0000)) { - *hwsq->ptr.u08++ = 0x40; - *hwsq->ptr.u16++ = (reg & 0x0000ffff); - } else { - *hwsq->ptr.u08++ = 0xe0; - *hwsq->ptr.u32++ = reg; - } - hwsq->reg = reg; -} - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.c deleted file mode 100644 index 77e56466..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_i2c.h" -#include "nouveau_hw.h" - -static void -i2c_drive_scl(void *data, int state) -{ - struct nouveau_i2c_chan *port = data; - if (port->type == 0) { - u8 val = NVReadVgaCrtc(port->dev, 0, port->drive); - if (state) val |= 0x20; - else val &= 0xdf; - NVWriteVgaCrtc(port->dev, 0, port->drive, val | 0x01); - } else - if (port->type == 4) { - nv_mask(port->dev, port->drive, 0x2f, state ? 0x21 : 0x01); - } else - if (port->type == 5) { - if (state) port->state |= 0x01; - else port->state &= 0xfe; - nv_wr32(port->dev, port->drive, 4 | port->state); - } -} - -static void -i2c_drive_sda(void *data, int state) -{ - struct nouveau_i2c_chan *port = data; - if (port->type == 0) { - u8 val = NVReadVgaCrtc(port->dev, 0, port->drive); - if (state) val |= 0x10; - else val &= 0xef; - NVWriteVgaCrtc(port->dev, 0, port->drive, val | 0x01); - } else - if (port->type == 4) { - nv_mask(port->dev, port->drive, 0x1f, state ? 0x11 : 0x01); - } else - if (port->type == 5) { - if (state) port->state |= 0x02; - else port->state &= 0xfd; - nv_wr32(port->dev, port->drive, 4 | port->state); - } -} - -static int -i2c_sense_scl(void *data) -{ - struct nouveau_i2c_chan *port = data; - struct drm_nouveau_private *dev_priv = port->dev->dev_private; - if (port->type == 0) { - return !!(NVReadVgaCrtc(port->dev, 0, port->sense) & 0x04); - } else - if (port->type == 4) { - return !!(nv_rd32(port->dev, port->sense) & 0x00040000); - } else - if (port->type == 5) { - if (dev_priv->card_type < NV_D0) - return !!(nv_rd32(port->dev, port->sense) & 0x01); - else - return !!(nv_rd32(port->dev, port->sense) & 0x10); - } - return 0; -} - -static int -i2c_sense_sda(void *data) -{ - struct nouveau_i2c_chan *port = data; - struct drm_nouveau_private *dev_priv = port->dev->dev_private; - if (port->type == 0) { - return !!(NVReadVgaCrtc(port->dev, 0, port->sense) & 0x08); - } else - if (port->type == 4) { - return !!(nv_rd32(port->dev, port->sense) & 0x00080000); - } else - if (port->type == 5) { - if (dev_priv->card_type < NV_D0) - return !!(nv_rd32(port->dev, port->sense) & 0x02); - else - return !!(nv_rd32(port->dev, port->sense) & 0x20); - } - return 0; -} - -static const uint32_t nv50_i2c_port[] = { - 0x00e138, 0x00e150, 0x00e168, 0x00e180, - 0x00e254, 0x00e274, 0x00e764, 0x00e780, - 0x00e79c, 0x00e7b8 -}; - -static u8 * -i2c_table(struct drm_device *dev, u8 *version) -{ - u8 *dcb = dcb_table(dev), *i2c = NULL; - if (dcb) { - if (dcb[0] >= 0x15) - i2c = ROMPTR(dev, dcb[2]); - if (dcb[0] >= 0x30) - i2c = ROMPTR(dev, dcb[4]); - } - - /* early revisions had no version number, use dcb version */ - if (i2c) { - *version = dcb[0]; - if (*version >= 0x30) - *version = i2c[0]; - } - - return i2c; -} - -int -nouveau_i2c_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct nouveau_i2c_chan *port; - u8 version = 0x00, entries, recordlen; - u8 *i2c, *entry, legacy[2][4] = {}; - int ret, i; - - INIT_LIST_HEAD(&dev_priv->i2c_ports); - - i2c = i2c_table(dev, &version); - if (!i2c) { - u8 *bmp = &bios->data[bios->offset]; - if (bios->type != NVBIOS_BMP) - return -ENODEV; - - legacy[0][0] = NV_CIO_CRE_DDC_WR__INDEX; - legacy[0][1] = NV_CIO_CRE_DDC_STATUS__INDEX; - legacy[1][0] = NV_CIO_CRE_DDC0_WR__INDEX; - legacy[1][1] = NV_CIO_CRE_DDC0_STATUS__INDEX; - - /* BMP (from v4.0) has i2c info in the structure, it's in a - * fixed location on earlier VBIOS - */ - if (bmp[5] < 4) - i2c = &bios->data[0x48]; - else - i2c = &bmp[0x36]; - - if (i2c[4]) legacy[0][0] = i2c[4]; - if (i2c[5]) legacy[0][1] = i2c[5]; - if (i2c[6]) legacy[1][0] = i2c[6]; - if (i2c[7]) legacy[1][1] = i2c[7]; - } - - if (version >= 0x30) { - entry = i2c[1] + i2c; - entries = i2c[2]; - recordlen = i2c[3]; - } else - if (version) { - entry = i2c; - entries = 16; - recordlen = 4; - } else { - entry = legacy[0]; - entries = 2; - recordlen = 4; - } - - for (i = 0; i < entries; i++, entry += recordlen) { - port = kzalloc(sizeof(*port), GFP_KERNEL); - if (port == NULL) { - nouveau_i2c_fini(dev); - return -ENOMEM; - } - - port->type = entry[3]; - if (version < 0x30) { - port->type &= 0x07; - if (port->type == 0x07) - port->type = 0xff; - } - - if (port->type == 0xff) { - kfree(port); - continue; - } - - switch (port->type) { - case 0: /* NV04:NV50 */ - port->drive = entry[0]; - port->sense = entry[1]; - break; - case 4: /* NV4E */ - port->drive = 0x600800 + entry[1]; - port->sense = port->drive; - break; - case 5: /* NV50- */ - port->drive = entry[0] & 0x0f; - if (dev_priv->card_type < NV_D0) { - if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) - break; - port->drive = nv50_i2c_port[port->drive]; - port->sense = port->drive; - } else { - port->drive = 0x00d014 + (port->drive * 0x20); - port->sense = port->drive; - } - break; - case 6: /* NV50- DP AUX */ - port->drive = entry[0]; - port->sense = port->drive; - port->adapter.algo = &nouveau_dp_i2c_algo; - break; - default: - break; - } - - if (!port->adapter.algo && !port->drive) { - NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", - i, port->type, port->drive, port->sense); - kfree(port); - continue; - } - - snprintf(port->adapter.name, sizeof(port->adapter.name), - "nouveau-%s-%d", pci_name(dev->pdev), i); - port->adapter.owner = THIS_MODULE; - port->adapter.dev.parent = &dev->pdev->dev; - port->dev = dev; - port->index = i; - port->dcb = ROM32(entry[0]); - i2c_set_adapdata(&port->adapter, i2c); - - if (port->adapter.algo != &nouveau_dp_i2c_algo) { - port->adapter.algo_data = &port->bit; - port->bit.udelay = 10; - port->bit.timeout = usecs_to_jiffies(2200); - port->bit.data = port; - port->bit.setsda = i2c_drive_sda; - port->bit.setscl = i2c_drive_scl; - port->bit.getsda = i2c_sense_sda; - port->bit.getscl = i2c_sense_scl; - - i2c_drive_scl(port, 0); - i2c_drive_sda(port, 1); - i2c_drive_scl(port, 1); - - ret = i2c_bit_add_bus(&port->adapter); - } else { - port->adapter.algo = &nouveau_dp_i2c_algo; - ret = i2c_add_adapter(&port->adapter); - } - - if (ret) { - NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); - kfree(port); - continue; - } - - list_add_tail(&port->head, &dev_priv->i2c_ports); - } - - return 0; -} - -void -nouveau_i2c_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_i2c_chan *port, *tmp; - - list_for_each_entry_safe(port, tmp, &dev_priv->i2c_ports, head) { - i2c_del_adapter(&port->adapter); - kfree(port); - } -} - -struct nouveau_i2c_chan * -nouveau_i2c_find(struct drm_device *dev, u8 index) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_i2c_chan *port; - - if (index == NV_I2C_DEFAULT(0) || - index == NV_I2C_DEFAULT(1)) { - u8 version, *i2c = i2c_table(dev, &version); - if (i2c && version >= 0x30) { - if (index == NV_I2C_DEFAULT(0)) - index = (i2c[4] & 0x0f); - else - index = (i2c[4] & 0xf0) >> 4; - } else { - index = 2; - } - } - - list_for_each_entry(port, &dev_priv->i2c_ports, head) { - if (port->index == index) - break; - } - - if (&port->head == &dev_priv->i2c_ports) - return NULL; - - if (dev_priv->card_type >= NV_50 && (port->dcb & 0x00000100)) { - u32 reg = 0x00e500, val; - if (port->type == 6) { - reg += port->drive * 0x50; - val = 0x2002; - } else { - reg += ((port->dcb & 0x1e00) >> 9) * 0x50; - val = 0xe001; - } - - /* nfi, but neither auxch or i2c work if it's 1 */ - nv_mask(dev, reg + 0x0c, 0x00000001, 0x00000000); - /* nfi, but switches auxch vs normal i2c */ - nv_mask(dev, reg + 0x00, 0x0000f003, val); - } - - return port; -} - -bool -nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr) -{ - uint8_t buf[] = { 0 }; - struct i2c_msg msgs[] = { - { - .addr = addr, - .flags = 0, - .len = 1, - .buf = buf, - }, - { - .addr = addr, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - return i2c_transfer(&i2c->adapter, msgs, 2) == 2; -} - -int -nouveau_i2c_identify(struct drm_device *dev, const char *what, - struct i2c_board_info *info, - bool (*match)(struct nouveau_i2c_chan *, - struct i2c_board_info *), - int index) -{ - struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); - int i; - - if (!i2c) { - NV_DEBUG(dev, "No bus when probing %s on %d\n", what, index); - return -ENODEV; - } - - NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, i2c->index); - for (i = 0; info[i].addr; i++) { - if (nouveau_probe_i2c_addr(i2c, info[i].addr) && - (!match || match(i2c, &info[i]))) { - NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); - return i; - } - } - - NV_DEBUG(dev, "No devices found.\n"); - return -ENODEV; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.h deleted file mode 100644 index 1d083893..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __NOUVEAU_I2C_H__ -#define __NOUVEAU_I2C_H__ - -#include -#include -#include "drm_dp_helper.h" - -#define NV_I2C_PORT(n) (0x00 + (n)) -#define NV_I2C_PORT_NUM 0x10 -#define NV_I2C_DEFAULT(n) (0x80 + (n)) - -struct nouveau_i2c_chan { - struct i2c_adapter adapter; - struct drm_device *dev; - struct i2c_algo_bit_data bit; - struct list_head head; - u8 index; - u8 type; - u32 dcb; - u32 drive; - u32 sense; - u32 state; -}; - -int nouveau_i2c_init(struct drm_device *); -void nouveau_i2c_fini(struct drm_device *); -struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, u8 index); -bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); -int nouveau_i2c_identify(struct drm_device *dev, const char *what, - struct i2c_board_info *info, - bool (*match)(struct nouveau_i2c_chan *, - struct i2c_board_info *), - int index); - -extern const struct i2c_algorithm nouveau_dp_i2c_algo; - -#endif /* __NOUVEAU_I2C_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ioc32.c deleted file mode 100644 index 475ba810..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ioc32.c +++ /dev/null @@ -1,70 +0,0 @@ -/** - * \file mga_ioc32.c - * - * 32-bit ioctl compatibility routines for the MGA DRM. - * - * \author Dave Airlie with code from patches by Egbert Eich - * - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Egbert Eich 2003,2004 - * Copyright (C) Dave Airlie 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "drmP.h" -#include "drm.h" - -#include "nouveau_drv.h" - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - -#if 0 - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) - fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; -#endif - if (fn != NULL) - ret = (*fn)(filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_irq.c deleted file mode 100644 index 868c7fd7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_irq.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2006 Ben Skeggs. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* - * Authors: - * Ben Skeggs - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drm.h" -#include "nouveau_drv.h" -#include "nouveau_reg.h" -#include "nouveau_ramht.h" -#include "nouveau_util.h" - -void -nouveau_irq_preinstall(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* Master disable */ - nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); - - INIT_LIST_HEAD(&dev_priv->vbl_waiting); -} - -int -nouveau_irq_postinstall(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* Master enable */ - nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); - if (dev_priv->msi_enabled) - nv_wr08(dev, 0x00088068, 0xff); - - return 0; -} - -void -nouveau_irq_uninstall(struct drm_device *dev) -{ - /* Master disable */ - nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); -} - -irqreturn_t -nouveau_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *)arg; - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - u32 stat; - int i; - - stat = nv_rd32(dev, NV03_PMC_INTR_0); - if (stat == 0 || stat == ~0) - return IRQ_NONE; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - for (i = 0; i < 32 && stat; i++) { - if (!(stat & (1 << i)) || !dev_priv->irq_handler[i]) - continue; - - dev_priv->irq_handler[i](dev); - stat &= ~(1 << i); - } - - if (dev_priv->msi_enabled) - nv_wr08(dev, 0x00088068, 0xff); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - if (stat && nouveau_ratelimit()) - NV_ERROR(dev, "PMC - unhandled INTR 0x%08x\n", stat); - return IRQ_HANDLED; -} - -int -nouveau_irq_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int ret; - - if (nouveau_msi != 0 && dev_priv->card_type >= NV_50) { - ret = pci_enable_msi(dev->pdev); - if (ret == 0) { - NV_INFO(dev, "enabled MSI\n"); - dev_priv->msi_enabled = true; - } - } - - return drm_irq_install(dev); -} - -void -nouveau_irq_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - drm_irq_uninstall(dev); - if (dev_priv->msi_enabled) - pci_disable_msi(dev->pdev); -} - -void -nouveau_irq_register(struct drm_device *dev, int status_bit, - void (*handler)(struct drm_device *)) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - dev_priv->irq_handler[status_bit] = handler; - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -} - -void -nouveau_irq_unregister(struct drm_device *dev, int status_bit) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - dev_priv->irq_handler[status_bit] = NULL; - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mem.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mem.c deleted file mode 100644 index b08065f9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mem.c +++ /dev/null @@ -1,1248 +0,0 @@ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * Copyright 2005 Stephane Marchesin - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Ben Skeggs - * Roy Spliet - */ - - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" - -#include "nouveau_drv.h" -#include "nouveau_pm.h" -#include "nouveau_mm.h" -#include "nouveau_vm.h" - -/* - * NV10-NV40 tiling helpers - */ - -static void -nv10_mem_update_tile_region(struct drm_device *dev, - struct nouveau_tile_reg *tile, uint32_t addr, - uint32_t size, uint32_t pitch, uint32_t flags) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int i = tile - dev_priv->tile.reg, j; - unsigned long save; - - nouveau_fence_unref(&tile->fence); - - if (tile->pitch) - pfb->free_tile_region(dev, i); - - if (pitch) - pfb->init_tile_region(dev, i, addr, size, pitch, flags); - - spin_lock_irqsave(&dev_priv->context_switch_lock, save); - pfifo->reassign(dev, false); - pfifo->cache_pull(dev, false); - - nouveau_wait_for_idle(dev); - - pfb->set_tile_region(dev, i); - for (j = 0; j < NVOBJ_ENGINE_NR; j++) { - if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region) - dev_priv->eng[j]->set_tile_region(dev, i); - } - - pfifo->cache_pull(dev, true); - pfifo->reassign(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, save); -} - -static struct nouveau_tile_reg * -nv10_mem_get_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - spin_lock(&dev_priv->tile.lock); - - if (!tile->used && - (!tile->fence || nouveau_fence_signalled(tile->fence))) - tile->used = true; - else - tile = NULL; - - spin_unlock(&dev_priv->tile.lock); - return tile; -} - -void -nv10_mem_put_tile_region(struct drm_device *dev, struct nouveau_tile_reg *tile, - struct nouveau_fence *fence) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (tile) { - spin_lock(&dev_priv->tile.lock); - if (fence) { - /* Mark it as pending. */ - tile->fence = fence; - nouveau_fence_ref(fence); - } - - tile->used = false; - spin_unlock(&dev_priv->tile.lock); - } -} - -struct nouveau_tile_reg * -nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, - uint32_t pitch, uint32_t flags) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nouveau_tile_reg *tile, *found = NULL; - int i; - - for (i = 0; i < pfb->num_tiles; i++) { - tile = nv10_mem_get_tile_region(dev, i); - - if (pitch && !found) { - found = tile; - continue; - - } else if (tile && tile->pitch) { - /* Kill an unused tile region. */ - nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0); - } - - nv10_mem_put_tile_region(dev, tile, NULL); - } - - if (found) - nv10_mem_update_tile_region(dev, found, addr, size, - pitch, flags); - return found; -} - -/* - * Cleanup everything - */ -void -nouveau_mem_vram_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - ttm_bo_device_release(&dev_priv->ttm.bdev); - - nouveau_ttm_global_release(dev_priv); - - if (dev_priv->fb_mtrr >= 0) { - drm_mtrr_del(dev_priv->fb_mtrr, - pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1), DRM_MTRR_WC); - dev_priv->fb_mtrr = -1; - } -} - -void -nouveau_mem_gart_fini(struct drm_device *dev) -{ - nouveau_sgdma_takedown(dev); - - if (drm_core_has_AGP(dev) && dev->agp) { - struct drm_agp_mem *entry, *tempe; - - /* Remove AGP resources, but leave dev->agp - intact until drv_cleanup is called. */ - list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { - if (entry->bound) - drm_unbind_agp(entry->memory); - drm_free_agp(entry->memory, entry->pages); - kfree(entry); - } - INIT_LIST_HEAD(&dev->agp->memory); - - if (dev->agp->acquired) - drm_agp_release(dev); - - dev->agp->acquired = 0; - dev->agp->enabled = 0; - } -} - -bool -nouveau_mem_flags_valid(struct drm_device *dev, u32 tile_flags) -{ - if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)) - return true; - - return false; -} - -#if __OS_HAS_AGP -static unsigned long -get_agp_mode(struct drm_device *dev, unsigned long mode) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* - * FW seems to be broken on nv18, it makes the card lock up - * randomly. - */ - if (dev_priv->chipset == 0x18) - mode &= ~PCI_AGP_COMMAND_FW; - - /* - * AGP mode set in the command line. - */ - if (nouveau_agpmode > 0) { - bool agpv3 = mode & 0x8; - int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode; - - mode = (mode & ~0x7) | (rate & 0x7); - } - - return mode; -} -#endif - -int -nouveau_mem_reset_agp(struct drm_device *dev) -{ -#if __OS_HAS_AGP - uint32_t saved_pci_nv_1, pmc_enable; - int ret; - - /* First of all, disable fast writes, otherwise if it's - * already enabled in the AGP bridge and we disable the card's - * AGP controller we might be locking ourselves out of it. */ - if ((nv_rd32(dev, NV04_PBUS_PCI_NV_19) | - dev->agp->mode) & PCI_AGP_COMMAND_FW) { - struct drm_agp_info info; - struct drm_agp_mode mode; - - ret = drm_agp_info(dev, &info); - if (ret) - return ret; - - mode.mode = get_agp_mode(dev, info.mode) & ~PCI_AGP_COMMAND_FW; - ret = drm_agp_enable(dev, mode); - if (ret) - return ret; - } - - saved_pci_nv_1 = nv_rd32(dev, NV04_PBUS_PCI_NV_1); - - /* clear busmaster bit */ - nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~0x4); - /* disable AGP */ - nv_wr32(dev, NV04_PBUS_PCI_NV_19, 0); - - /* power cycle pgraph, if enabled */ - pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); - if (pmc_enable & NV_PMC_ENABLE_PGRAPH) { - nv_wr32(dev, NV03_PMC_ENABLE, - pmc_enable & ~NV_PMC_ENABLE_PGRAPH); - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | - NV_PMC_ENABLE_PGRAPH); - } - - /* and restore (gives effect of resetting AGP) */ - nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); -#endif - - return 0; -} - -int -nouveau_mem_init_agp(struct drm_device *dev) -{ -#if __OS_HAS_AGP - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_agp_info info; - struct drm_agp_mode mode; - int ret; - - if (!dev->agp->acquired) { - ret = drm_agp_acquire(dev); - if (ret) { - NV_ERROR(dev, "Unable to acquire AGP: %d\n", ret); - return ret; - } - } - - nouveau_mem_reset_agp(dev); - - ret = drm_agp_info(dev, &info); - if (ret) { - NV_ERROR(dev, "Unable to get AGP info: %d\n", ret); - return ret; - } - - /* see agp.h for the AGPSTAT_* modes available */ - mode.mode = get_agp_mode(dev, info.mode); - ret = drm_agp_enable(dev, mode); - if (ret) { - NV_ERROR(dev, "Unable to enable AGP: %d\n", ret); - return ret; - } - - dev_priv->gart_info.type = NOUVEAU_GART_AGP; - dev_priv->gart_info.aper_base = info.aperture_base; - dev_priv->gart_info.aper_size = info.aperture_size; -#endif - return 0; -} - -static const struct vram_types { - int value; - const char *name; -} vram_type_map[] = { - { NV_MEM_TYPE_STOLEN , "stolen system memory" }, - { NV_MEM_TYPE_SGRAM , "SGRAM" }, - { NV_MEM_TYPE_SDRAM , "SDRAM" }, - { NV_MEM_TYPE_DDR1 , "DDR1" }, - { NV_MEM_TYPE_DDR2 , "DDR2" }, - { NV_MEM_TYPE_DDR3 , "DDR3" }, - { NV_MEM_TYPE_GDDR2 , "GDDR2" }, - { NV_MEM_TYPE_GDDR3 , "GDDR3" }, - { NV_MEM_TYPE_GDDR4 , "GDDR4" }, - { NV_MEM_TYPE_GDDR5 , "GDDR5" }, - { NV_MEM_TYPE_UNKNOWN, "unknown type" } -}; - -int -nouveau_mem_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; - const struct vram_types *vram_type; - int ret, dma_bits; - - dma_bits = 32; - if (dev_priv->card_type >= NV_50) { - if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(40))) - dma_bits = 40; - } else - if (0 && pci_is_pcie(dev->pdev) && - dev_priv->chipset > 0x40 && - dev_priv->chipset != 0x45) { - if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) - dma_bits = 39; - } - - ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); - if (ret) - return ret; - ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); - if (ret) { - /* Reset to default value. */ - pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32)); - } - - - ret = nouveau_ttm_global_init(dev_priv); - if (ret) - return ret; - - ret = ttm_bo_device_init(&dev_priv->ttm.bdev, - dev_priv->ttm.bo_global_ref.ref.object, - &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET, - dma_bits <= 32 ? true : false); - if (ret) { - NV_ERROR(dev, "Error initialising bo driver: %d\n", ret); - return ret; - } - - vram_type = vram_type_map; - while (vram_type->value != NV_MEM_TYPE_UNKNOWN) { - if (nouveau_vram_type) { - if (!strcasecmp(nouveau_vram_type, vram_type->name)) - break; - dev_priv->vram_type = vram_type->value; - } else { - if (vram_type->value == dev_priv->vram_type) - break; - } - vram_type++; - } - - NV_INFO(dev, "Detected %dMiB VRAM (%s)\n", - (int)(dev_priv->vram_size >> 20), vram_type->name); - if (dev_priv->vram_sys_base) { - NV_INFO(dev, "Stolen system memory at: 0x%010llx\n", - dev_priv->vram_sys_base); - } - - dev_priv->fb_available_size = dev_priv->vram_size; - dev_priv->fb_mappable_pages = dev_priv->fb_available_size; - if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) - dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1); - dev_priv->fb_mappable_pages >>= PAGE_SHIFT; - - dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; - dev_priv->fb_aper_free = dev_priv->fb_available_size; - - /* mappable vram */ - ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, - dev_priv->fb_available_size >> PAGE_SHIFT); - if (ret) { - NV_ERROR(dev, "Failed VRAM mm init: %d\n", ret); - return ret; - } - - if (dev_priv->card_type < NV_50) { - ret = nouveau_bo_new(dev, 256*1024, 0, TTM_PL_FLAG_VRAM, - 0, 0, &dev_priv->vga_ram); - if (ret == 0) - ret = nouveau_bo_pin(dev_priv->vga_ram, - TTM_PL_FLAG_VRAM); - - if (ret) { - NV_WARN(dev, "failed to reserve VGA memory\n"); - nouveau_bo_ref(NULL, &dev_priv->vga_ram); - } - } - - dev_priv->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1), - DRM_MTRR_WC); - return 0; -} - -int -nouveau_mem_gart_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; - int ret; - - dev_priv->gart_info.type = NOUVEAU_GART_NONE; - -#if !defined(__powerpc__) && !defined(__ia64__) - if (drm_pci_device_is_agp(dev) && dev->agp && nouveau_agpmode) { - ret = nouveau_mem_init_agp(dev); - if (ret) - NV_ERROR(dev, "Error initialising AGP: %d\n", ret); - } -#endif - - if (dev_priv->gart_info.type == NOUVEAU_GART_NONE) { - ret = nouveau_sgdma_init(dev); - if (ret) { - NV_ERROR(dev, "Error initialising PCI(E): %d\n", ret); - return ret; - } - } - - NV_INFO(dev, "%d MiB GART (aperture)\n", - (int)(dev_priv->gart_info.aper_size >> 20)); - dev_priv->gart_info.aper_free = dev_priv->gart_info.aper_size; - - ret = ttm_bo_init_mm(bdev, TTM_PL_TT, - dev_priv->gart_info.aper_size >> PAGE_SHIFT); - if (ret) { - NV_ERROR(dev, "Failed TT mm init: %d\n", ret); - return ret; - } - - return 0; -} - -static int -nv40_mem_timing_calc(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC); - - /* XXX: I don't trust the -1's and +1's... they must come - * from somewhere! */ - t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 | - 1 << 16 | - (e->tWTR + 2 + (t->tCWL - 1)) << 8 | - (e->tCL + 2 - (t->tCWL - 1)); - - t->reg[2] = 0x20200000 | - ((t->tCWL - 1) << 24 | - e->tRRD << 16 | - e->tRCDWR << 8 | - e->tRCDRD); - - NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x\n", t->id, - t->reg[0], t->reg[1], t->reg[2]); - return 0; -} - -static int -nv50_mem_timing_calc(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct bit_entry P; - uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3; - - if (bit_table(dev, 'P', &P)) - return -EINVAL; - - switch (min(len, (u8) 22)) { - case 22: - unk21 = e->tUNK_21; - case 21: - unk20 = e->tUNK_20; - case 20: - if (e->tCWL > 0) - t->tCWL = e->tCWL; - case 19: - unk18 = e->tUNK_18; - break; - } - - t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC); - - t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 | - max(unk18, (u8) 1) << 16 | - (e->tWTR + 2 + (t->tCWL - 1)) << 8; - - t->reg[2] = ((t->tCWL - 1) << 24 | - e->tRRD << 16 | - e->tRCDWR << 8 | - e->tRCDRD); - - t->reg[4] = e->tUNK_13 << 8 | e->tUNK_13; - - t->reg[5] = (e->tRFC << 24 | max(e->tRCDRD, e->tRCDWR) << 16 | e->tRP); - - t->reg[8] = boot->reg[8] & 0xffffff00; - - if (P.version == 1) { - t->reg[1] |= (e->tCL + 2 - (t->tCWL - 1)); - - t->reg[3] = (0x14 + e->tCL) << 24 | - 0x16 << 16 | - (e->tCL - 1) << 8 | - (e->tCL - 1); - - t->reg[4] |= boot->reg[4] & 0xffff0000; - - t->reg[6] = (0x33 - t->tCWL) << 16 | - t->tCWL << 8 | - (0x2e + e->tCL - t->tCWL); - - t->reg[7] = 0x4000202 | (e->tCL - 1) << 16; - - /* XXX: P.version == 1 only has DDR2 and GDDR3? */ - if (dev_priv->vram_type == NV_MEM_TYPE_DDR2) { - t->reg[5] |= (e->tCL + 3) << 8; - t->reg[6] |= (t->tCWL - 2) << 8; - t->reg[8] |= (e->tCL - 4); - } else { - t->reg[5] |= (e->tCL + 2) << 8; - t->reg[6] |= t->tCWL << 8; - t->reg[8] |= (e->tCL - 2); - } - } else { - t->reg[1] |= (5 + e->tCL - (t->tCWL)); - - /* XXX: 0xb? 0x30? */ - t->reg[3] = (0x30 + e->tCL) << 24 | - (boot->reg[3] & 0x00ff0000)| - (0xb + e->tCL) << 8 | - (e->tCL - 1); - - t->reg[4] |= (unk20 << 24 | unk21 << 16); - - /* XXX: +6? */ - t->reg[5] |= (t->tCWL + 6) << 8; - - t->reg[6] = (0x5a + e->tCL) << 16 | - (6 - e->tCL + t->tCWL) << 8 | - (0x50 + e->tCL - t->tCWL); - - tmp7_3 = (boot->reg[7] & 0xff000000) >> 24; - t->reg[7] = (tmp7_3 << 24) | - ((tmp7_3 - 6 + e->tCL) << 16) | - 0x202; - } - - NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", t->id, - t->reg[0], t->reg[1], t->reg[2], t->reg[3]); - NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n", - t->reg[4], t->reg[5], t->reg[6], t->reg[7]); - NV_DEBUG(dev, " 240: %08x\n", t->reg[8]); - return 0; -} - -static int -nvc0_mem_timing_calc(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - if (e->tCWL > 0) - t->tCWL = e->tCWL; - - t->reg[0] = (e->tRP << 24 | (e->tRAS & 0x7f) << 17 | - e->tRFC << 8 | e->tRC); - - t->reg[1] = (boot->reg[1] & 0xff000000) | - (e->tRCDWR & 0x0f) << 20 | - (e->tRCDRD & 0x0f) << 14 | - (t->tCWL << 7) | - (e->tCL & 0x0f); - - t->reg[2] = (boot->reg[2] & 0xff0000ff) | - e->tWR << 16 | e->tWTR << 8; - - t->reg[3] = (e->tUNK_20 & 0x1f) << 9 | - (e->tUNK_21 & 0xf) << 5 | - (e->tUNK_13 & 0x1f); - - t->reg[4] = (boot->reg[4] & 0xfff00fff) | - (e->tRRD&0x1f) << 15; - - NV_DEBUG(dev, "Entry %d: 290: %08x %08x %08x %08x\n", t->id, - t->reg[0], t->reg[1], t->reg[2], t->reg[3]); - NV_DEBUG(dev, " 2a0: %08x\n", t->reg[4]); - return 0; -} - -/** - * MR generation methods - */ - -static int -nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - t->drive_strength = 0; - if (len < 15) { - t->odt = boot->odt; - } else { - t->odt = e->RAM_FT1 & 0x07; - } - - if (e->tCL >= NV_MEM_CL_DDR2_MAX) { - NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL); - return -ERANGE; - } - - if (e->tWR >= NV_MEM_WR_DDR2_MAX) { - NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR); - return -ERANGE; - } - - if (t->odt > 3) { - NV_WARN(dev, "(%u) Invalid odt value, assuming disabled: %x", - t->id, t->odt); - t->odt = 0; - } - - t->mr[0] = (boot->mr[0] & 0x100f) | - (e->tCL) << 4 | - (e->tWR - 1) << 9; - t->mr[1] = (boot->mr[1] & 0x101fbb) | - (t->odt & 0x1) << 2 | - (t->odt & 0x2) << 5; - - NV_DEBUG(dev, "(%u) MR: %08x", t->id, t->mr[0]); - return 0; -} - -uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = { - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; - -static int -nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - u8 cl = e->tCL - 4; - - t->drive_strength = 0; - if (len < 15) { - t->odt = boot->odt; - } else { - t->odt = e->RAM_FT1 & 0x07; - } - - if (e->tCL >= NV_MEM_CL_DDR3_MAX || e->tCL < 4) { - NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL); - return -ERANGE; - } - - if (e->tWR >= NV_MEM_WR_DDR3_MAX || e->tWR < 4) { - NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR); - return -ERANGE; - } - - if (e->tCWL < 5) { - NV_WARN(dev, "(%u) Invalid tCWL: %u", t->id, e->tCWL); - return -ERANGE; - } - - t->mr[0] = (boot->mr[0] & 0x180b) | - /* CAS */ - (cl & 0x7) << 4 | - (cl & 0x8) >> 1 | - (nv_mem_wr_lut_ddr3[e->tWR]) << 9; - t->mr[1] = (boot->mr[1] & 0x101dbb) | - (t->odt & 0x1) << 2 | - (t->odt & 0x2) << 5 | - (t->odt & 0x4) << 7; - t->mr[2] = (boot->mr[2] & 0x20ffb7) | (e->tCWL - 5) << 3; - - NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]); - return 0; -} - -uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = { - 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11}; -uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = { - 0, 0, 0, 0, 0, 2, 3, 8, 9, 10, 11, 0, 0, 1, 1, 0, 3}; - -static int -nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - if (len < 15) { - t->drive_strength = boot->drive_strength; - t->odt = boot->odt; - } else { - t->drive_strength = (e->RAM_FT1 & 0x30) >> 4; - t->odt = e->RAM_FT1 & 0x07; - } - - if (e->tCL >= NV_MEM_CL_GDDR3_MAX) { - NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL); - return -ERANGE; - } - - if (e->tWR >= NV_MEM_WR_GDDR3_MAX) { - NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR); - return -ERANGE; - } - - if (t->odt > 3) { - NV_WARN(dev, "(%u) Invalid odt value, assuming autocal: %x", - t->id, t->odt); - t->odt = 0; - } - - t->mr[0] = (boot->mr[0] & 0xe0b) | - /* CAS */ - ((nv_mem_cl_lut_gddr3[e->tCL] & 0x7) << 4) | - ((nv_mem_cl_lut_gddr3[e->tCL] & 0x8) >> 2); - t->mr[1] = (boot->mr[1] & 0x100f40) | t->drive_strength | - (t->odt << 2) | - (nv_mem_wr_lut_gddr3[e->tWR] & 0xf) << 4; - t->mr[2] = boot->mr[2]; - - NV_DEBUG(dev, "(%u) MR: %08x %08x %08x", t->id, - t->mr[0], t->mr[1], t->mr[2]); - return 0; -} - -static int -nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq, - struct nouveau_pm_tbl_entry *e, u8 len, - struct nouveau_pm_memtiming *boot, - struct nouveau_pm_memtiming *t) -{ - if (len < 15) { - t->drive_strength = boot->drive_strength; - t->odt = boot->odt; - } else { - t->drive_strength = (e->RAM_FT1 & 0x30) >> 4; - t->odt = e->RAM_FT1 & 0x03; - } - - if (e->tCL >= NV_MEM_CL_GDDR5_MAX) { - NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL); - return -ERANGE; - } - - if (e->tWR >= NV_MEM_WR_GDDR5_MAX) { - NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR); - return -ERANGE; - } - - if (t->odt > 3) { - NV_WARN(dev, "(%u) Invalid odt value, assuming autocal: %x", - t->id, t->odt); - t->odt = 0; - } - - t->mr[0] = (boot->mr[0] & 0x007) | - ((e->tCL - 5) << 3) | - ((e->tWR - 4) << 8); - t->mr[1] = (boot->mr[1] & 0x1007f0) | - t->drive_strength | - (t->odt << 2); - - NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]); - return 0; -} - -int -nouveau_mem_timing_calc(struct drm_device *dev, u32 freq, - struct nouveau_pm_memtiming *t) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_memtiming *boot = &pm->boot.timing; - struct nouveau_pm_tbl_entry *e; - u8 ver, len, *ptr, *ramcfg; - int ret; - - ptr = nouveau_perf_timing(dev, freq, &ver, &len); - if (!ptr || ptr[0] == 0x00) { - *t = *boot; - return 0; - } - e = (struct nouveau_pm_tbl_entry *)ptr; - - t->tCWL = boot->tCWL; - - switch (dev_priv->card_type) { - case NV_40: - ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t); - break; - case NV_50: - ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t); - break; - case NV_C0: - ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t); - break; - default: - ret = -ENODEV; - break; - } - - switch (dev_priv->vram_type * !ret) { - case NV_MEM_TYPE_GDDR3: - ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t); - break; - case NV_MEM_TYPE_GDDR5: - ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t); - break; - case NV_MEM_TYPE_DDR2: - ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t); - break; - case NV_MEM_TYPE_DDR3: - ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t); - break; - default: - ret = -EINVAL; - break; - } - - ramcfg = nouveau_perf_ramcfg(dev, freq, &ver, &len); - if (ramcfg) { - int dll_off; - - if (ver == 0x00) - dll_off = !!(ramcfg[3] & 0x04); - else - dll_off = !!(ramcfg[2] & 0x40); - - switch (dev_priv->vram_type) { - case NV_MEM_TYPE_GDDR3: - t->mr[1] &= ~0x00000040; - t->mr[1] |= 0x00000040 * dll_off; - break; - default: - t->mr[1] &= ~0x00000001; - t->mr[1] |= 0x00000001 * dll_off; - break; - } - } - - return ret; -} - -void -nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 timing_base, timing_regs, mr_base; - int i; - - if (dev_priv->card_type >= 0xC0) { - timing_base = 0x10f290; - mr_base = 0x10f300; - } else { - timing_base = 0x100220; - mr_base = 0x1002c0; - } - - t->id = -1; - - switch (dev_priv->card_type) { - case NV_50: - timing_regs = 9; - break; - case NV_C0: - case NV_D0: - timing_regs = 5; - break; - case NV_30: - case NV_40: - timing_regs = 3; - break; - default: - timing_regs = 0; - return; - } - for(i = 0; i < timing_regs; i++) - t->reg[i] = nv_rd32(dev, timing_base + (0x04 * i)); - - t->tCWL = 0; - if (dev_priv->card_type < NV_C0) { - t->tCWL = ((nv_rd32(dev, 0x100228) & 0x0f000000) >> 24) + 1; - } else if (dev_priv->card_type <= NV_D0) { - t->tCWL = ((nv_rd32(dev, 0x10f294) & 0x00000f80) >> 7); - } - - t->mr[0] = nv_rd32(dev, mr_base); - t->mr[1] = nv_rd32(dev, mr_base + 0x04); - t->mr[2] = nv_rd32(dev, mr_base + 0x20); - t->mr[3] = nv_rd32(dev, mr_base + 0x24); - - t->odt = 0; - t->drive_strength = 0; - - switch (dev_priv->vram_type) { - case NV_MEM_TYPE_DDR3: - t->odt |= (t->mr[1] & 0x200) >> 7; - case NV_MEM_TYPE_DDR2: - t->odt |= (t->mr[1] & 0x04) >> 2 | - (t->mr[1] & 0x40) >> 5; - break; - case NV_MEM_TYPE_GDDR3: - case NV_MEM_TYPE_GDDR5: - t->drive_strength = t->mr[1] & 0x03; - t->odt = (t->mr[1] & 0x0c) >> 2; - break; - default: - break; - } -} - -int -nouveau_mem_exec(struct nouveau_mem_exec_func *exec, - struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = exec->dev->dev_private; - struct nouveau_pm_memtiming *info = &perflvl->timing; - u32 tMRD = 1000, tCKSRE = 0, tCKSRX = 0, tXS = 0, tDLLK = 0; - u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] }; - u32 mr1_dlloff; - - switch (dev_priv->vram_type) { - case NV_MEM_TYPE_DDR2: - tDLLK = 2000; - mr1_dlloff = 0x00000001; - break; - case NV_MEM_TYPE_DDR3: - tDLLK = 12000; - mr1_dlloff = 0x00000001; - break; - case NV_MEM_TYPE_GDDR3: - tDLLK = 40000; - mr1_dlloff = 0x00000040; - break; - default: - NV_ERROR(exec->dev, "cannot reclock unsupported memtype\n"); - return -ENODEV; - } - - /* fetch current MRs */ - switch (dev_priv->vram_type) { - case NV_MEM_TYPE_GDDR3: - case NV_MEM_TYPE_DDR3: - mr[2] = exec->mrg(exec, 2); - default: - mr[1] = exec->mrg(exec, 1); - mr[0] = exec->mrg(exec, 0); - break; - } - - /* DLL 'on' -> DLL 'off' mode, disable before entering self-refresh */ - if (!(mr[1] & mr1_dlloff) && (info->mr[1] & mr1_dlloff)) { - exec->precharge(exec); - exec->mrs (exec, 1, mr[1] | mr1_dlloff); - exec->wait(exec, tMRD); - } - - /* enter self-refresh mode */ - exec->precharge(exec); - exec->refresh(exec); - exec->refresh(exec); - exec->refresh_auto(exec, false); - exec->refresh_self(exec, true); - exec->wait(exec, tCKSRE); - - /* modify input clock frequency */ - exec->clock_set(exec); - - /* exit self-refresh mode */ - exec->wait(exec, tCKSRX); - exec->precharge(exec); - exec->refresh_self(exec, false); - exec->refresh_auto(exec, true); - exec->wait(exec, tXS); - - /* update MRs */ - if (mr[2] != info->mr[2]) { - exec->mrs (exec, 2, info->mr[2]); - exec->wait(exec, tMRD); - } - - if (mr[1] != info->mr[1]) { - /* need to keep DLL off until later, at least on GDDR3 */ - exec->mrs (exec, 1, info->mr[1] | (mr[1] & mr1_dlloff)); - exec->wait(exec, tMRD); - } - - if (mr[0] != info->mr[0]) { - exec->mrs (exec, 0, info->mr[0]); - exec->wait(exec, tMRD); - } - - /* update PFB timing registers */ - exec->timing_set(exec); - - /* DLL (enable + ) reset */ - if (!(info->mr[1] & mr1_dlloff)) { - if (mr[1] & mr1_dlloff) { - exec->mrs (exec, 1, info->mr[1]); - exec->wait(exec, tMRD); - } - exec->mrs (exec, 0, info->mr[0] | 0x00000100); - exec->wait(exec, tMRD); - exec->mrs (exec, 0, info->mr[0] | 0x00000000); - exec->wait(exec, tMRD); - exec->wait(exec, tDLLK); - if (dev_priv->vram_type == NV_MEM_TYPE_GDDR3) - exec->precharge(exec); - } - - return 0; -} - -int -nouveau_mem_vbios_type(struct drm_device *dev) -{ - struct bit_entry M; - u8 ramcfg = (nv_rd32(dev, 0x101000) & 0x0000003c) >> 2; - if (!bit_table(dev, 'M', &M) || M.version != 2 || M.length < 5) { - u8 *table = ROMPTR(dev, M.data[3]); - if (table && table[0] == 0x10 && ramcfg < table[3]) { - u8 *entry = table + table[1] + (ramcfg * table[2]); - switch (entry[0] & 0x0f) { - case 0: return NV_MEM_TYPE_DDR2; - case 1: return NV_MEM_TYPE_DDR3; - case 2: return NV_MEM_TYPE_GDDR3; - case 3: return NV_MEM_TYPE_GDDR5; - default: - break; - } - - } - } - return NV_MEM_TYPE_UNKNOWN; -} - -static int -nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) -{ - /* nothing to do */ - return 0; -} - -static int -nouveau_vram_manager_fini(struct ttm_mem_type_manager *man) -{ - /* nothing to do */ - return 0; -} - -static inline void -nouveau_mem_node_cleanup(struct nouveau_mem *node) -{ - if (node->vma[0].node) { - nouveau_vm_unmap(&node->vma[0]); - nouveau_vm_put(&node->vma[0]); - } - - if (node->vma[1].node) { - nouveau_vm_unmap(&node->vma[1]); - nouveau_vm_put(&node->vma[1]); - } -} - -static void -nouveau_vram_manager_del(struct ttm_mem_type_manager *man, - struct ttm_mem_reg *mem) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - struct drm_device *dev = dev_priv->dev; - - nouveau_mem_node_cleanup(mem->mm_node); - vram->put(dev, (struct nouveau_mem **)&mem->mm_node); -} - -static int -nouveau_vram_manager_new(struct ttm_mem_type_manager *man, - struct ttm_buffer_object *bo, - struct ttm_placement *placement, - struct ttm_mem_reg *mem) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - struct drm_device *dev = dev_priv->dev; - struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nouveau_mem *node; - u32 size_nc = 0; - int ret; - - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) - size_nc = 1 << nvbo->page_shift; - - ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, - mem->page_alignment << PAGE_SHIFT, size_nc, - (nvbo->tile_flags >> 8) & 0x3ff, &node); - if (ret) { - mem->mm_node = NULL; - return (ret == -ENOSPC) ? 0 : ret; - } - - node->page_shift = nvbo->page_shift; - - mem->mm_node = node; - mem->start = node->offset >> PAGE_SHIFT; - return 0; -} - -void -nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) -{ - struct nouveau_mm *mm = man->priv; - struct nouveau_mm_node *r; - u32 total = 0, free = 0; - - mutex_lock(&mm->mutex); - list_for_each_entry(r, &mm->nodes, nl_entry) { - printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n", - prefix, r->type, ((u64)r->offset << 12), - (((u64)r->offset + r->length) << 12)); - - total += r->length; - if (!r->type) - free += r->length; - } - mutex_unlock(&mm->mutex); - - printk(KERN_DEBUG "%s total: 0x%010llx free: 0x%010llx\n", - prefix, (u64)total << 12, (u64)free << 12); - printk(KERN_DEBUG "%s block: 0x%08x\n", - prefix, mm->block_size << 12); -} - -const struct ttm_mem_type_manager_func nouveau_vram_manager = { - nouveau_vram_manager_init, - nouveau_vram_manager_fini, - nouveau_vram_manager_new, - nouveau_vram_manager_del, - nouveau_vram_manager_debug -}; - -static int -nouveau_gart_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) -{ - return 0; -} - -static int -nouveau_gart_manager_fini(struct ttm_mem_type_manager *man) -{ - return 0; -} - -static void -nouveau_gart_manager_del(struct ttm_mem_type_manager *man, - struct ttm_mem_reg *mem) -{ - nouveau_mem_node_cleanup(mem->mm_node); - kfree(mem->mm_node); - mem->mm_node = NULL; -} - -static int -nouveau_gart_manager_new(struct ttm_mem_type_manager *man, - struct ttm_buffer_object *bo, - struct ttm_placement *placement, - struct ttm_mem_reg *mem) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); - struct nouveau_mem *node; - - if (unlikely((mem->num_pages << PAGE_SHIFT) >= - dev_priv->gart_info.aper_size)) - return -ENOMEM; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - node->page_shift = 12; - - mem->mm_node = node; - mem->start = 0; - return 0; -} - -void -nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) -{ -} - -const struct ttm_mem_type_manager_func nouveau_gart_manager = { - nouveau_gart_manager_init, - nouveau_gart_manager_fini, - nouveau_gart_manager_new, - nouveau_gart_manager_del, - nouveau_gart_manager_debug -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.c deleted file mode 100644 index b29ffb3d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_mm.h" - -static inline void -region_put(struct nouveau_mm *mm, struct nouveau_mm_node *a) -{ - list_del(&a->nl_entry); - list_del(&a->fl_entry); - kfree(a); -} - -static struct nouveau_mm_node * -region_split(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size) -{ - struct nouveau_mm_node *b; - - if (a->length == size) - return a; - - b = kmalloc(sizeof(*b), GFP_KERNEL); - if (unlikely(b == NULL)) - return NULL; - - b->offset = a->offset; - b->length = size; - b->type = a->type; - a->offset += size; - a->length -= size; - list_add_tail(&b->nl_entry, &a->nl_entry); - if (b->type == 0) - list_add_tail(&b->fl_entry, &a->fl_entry); - return b; -} - -#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \ - list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry) - -void -nouveau_mm_put(struct nouveau_mm *mm, struct nouveau_mm_node *this) -{ - struct nouveau_mm_node *prev = node(this, prev); - struct nouveau_mm_node *next = node(this, next); - - list_add(&this->fl_entry, &mm->free); - this->type = 0; - - if (prev && prev->type == 0) { - prev->length += this->length; - region_put(mm, this); - this = prev; - } - - if (next && next->type == 0) { - next->offset = this->offset; - next->length += this->length; - region_put(mm, this); - } -} - -int -nouveau_mm_get(struct nouveau_mm *mm, int type, u32 size, u32 size_nc, - u32 align, struct nouveau_mm_node **pnode) -{ - struct nouveau_mm_node *prev, *this, *next; - u32 min = size_nc ? size_nc : size; - u32 align_mask = align - 1; - u32 splitoff; - u32 s, e; - - list_for_each_entry(this, &mm->free, fl_entry) { - e = this->offset + this->length; - s = this->offset; - - prev = node(this, prev); - if (prev && prev->type != type) - s = roundup(s, mm->block_size); - - next = node(this, next); - if (next && next->type != type) - e = rounddown(e, mm->block_size); - - s = (s + align_mask) & ~align_mask; - e &= ~align_mask; - if (s > e || e - s < min) - continue; - - splitoff = s - this->offset; - if (splitoff && !region_split(mm, this, splitoff)) - return -ENOMEM; - - this = region_split(mm, this, min(size, e - s)); - if (!this) - return -ENOMEM; - - this->type = type; - list_del(&this->fl_entry); - *pnode = this; - return 0; - } - - return -ENOSPC; -} - -int -nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) -{ - struct nouveau_mm_node *node; - - if (block) { - mutex_init(&mm->mutex); - INIT_LIST_HEAD(&mm->nodes); - INIT_LIST_HEAD(&mm->free); - mm->block_size = block; - mm->heap_nodes = 0; - } - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - node->offset = roundup(offset, mm->block_size); - node->length = rounddown(offset + length, mm->block_size) - node->offset; - - list_add_tail(&node->nl_entry, &mm->nodes); - list_add_tail(&node->fl_entry, &mm->free); - mm->heap_nodes++; - return 0; -} - -int -nouveau_mm_fini(struct nouveau_mm *mm) -{ - struct nouveau_mm_node *node, *heap = - list_first_entry(&mm->nodes, struct nouveau_mm_node, nl_entry); - int nodes = 0; - - list_for_each_entry(node, &mm->nodes, nl_entry) { - if (nodes++ == mm->heap_nodes) { - printk(KERN_ERR "nouveau_mm in use at destroy time!\n"); - list_for_each_entry(node, &mm->nodes, nl_entry) { - printk(KERN_ERR "0x%02x: 0x%08x 0x%08x\n", - node->type, node->offset, node->length); - } - WARN_ON(1); - return -EBUSY; - } - } - - kfree(heap); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.h deleted file mode 100644 index 57a600c3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mm.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#ifndef __NOUVEAU_REGION_H__ -#define __NOUVEAU_REGION_H__ - -struct nouveau_mm_node { - struct list_head nl_entry; - struct list_head fl_entry; - struct list_head rl_entry; - - u8 type; - u32 offset; - u32 length; -}; - -struct nouveau_mm { - struct list_head nodes; - struct list_head free; - - struct mutex mutex; - - u32 block_size; - int heap_nodes; -}; - -int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); -int nouveau_mm_fini(struct nouveau_mm *); -int nouveau_mm_pre(struct nouveau_mm *); -int nouveau_mm_get(struct nouveau_mm *, int type, u32 size, u32 size_nc, - u32 align, struct nouveau_mm_node **); -void nouveau_mm_put(struct nouveau_mm *, struct nouveau_mm_node *); - -int nv50_vram_init(struct drm_device *); -void nv50_vram_fini(struct drm_device *); -int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc, - u32 memtype, struct nouveau_mem **); -void nv50_vram_del(struct drm_device *, struct nouveau_mem **); -bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags); - -int nvc0_vram_init(struct drm_device *); -int nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin, - u32 memtype, struct nouveau_mem **); -bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mxm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mxm.c deleted file mode 100644 index 07d0d1e0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_mxm.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include - -#include "drmP.h" -#include "nouveau_drv.h" - -#define MXM_DBG(dev, fmt, args...) NV_DEBUG((dev), "MXM: " fmt, ##args) -#define MXM_MSG(dev, fmt, args...) NV_INFO((dev), "MXM: " fmt, ##args) - -static u8 * -mxms_data(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return dev_priv->mxms; - -} - -static u16 -mxms_version(struct drm_device *dev) -{ - u8 *mxms = mxms_data(dev); - u16 version = (mxms[4] << 8) | mxms[5]; - switch (version ) { - case 0x0200: - case 0x0201: - case 0x0300: - return version; - default: - break; - } - - MXM_DBG(dev, "unknown version %d.%d\n", mxms[4], mxms[5]); - return 0x0000; -} - -static u16 -mxms_headerlen(struct drm_device *dev) -{ - return 8; -} - -static u16 -mxms_structlen(struct drm_device *dev) -{ - return *(u16 *)&mxms_data(dev)[6]; -} - -static bool -mxms_checksum(struct drm_device *dev) -{ - u16 size = mxms_headerlen(dev) + mxms_structlen(dev); - u8 *mxms = mxms_data(dev), sum = 0; - while (size--) - sum += *mxms++; - if (sum) { - MXM_DBG(dev, "checksum invalid\n"); - return false; - } - return true; -} - -static bool -mxms_valid(struct drm_device *dev) -{ - u8 *mxms = mxms_data(dev); - if (*(u32 *)mxms != 0x5f4d584d) { - MXM_DBG(dev, "signature invalid\n"); - return false; - } - - if (!mxms_version(dev) || !mxms_checksum(dev)) - return false; - - return true; -} - -static bool -mxms_foreach(struct drm_device *dev, u8 types, - bool (*exec)(struct drm_device *, u8 *, void *), void *info) -{ - u8 *mxms = mxms_data(dev); - u8 *desc = mxms + mxms_headerlen(dev); - u8 *fini = desc + mxms_structlen(dev) - 1; - while (desc < fini) { - u8 type = desc[0] & 0x0f; - u8 headerlen = 0; - u8 recordlen = 0; - u8 entries = 0; - - switch (type) { - case 0: /* Output Device Structure */ - if (mxms_version(dev) >= 0x0300) - headerlen = 8; - else - headerlen = 6; - break; - case 1: /* System Cooling Capability Structure */ - case 2: /* Thermal Structure */ - case 3: /* Input Power Structure */ - headerlen = 4; - break; - case 4: /* GPIO Device Structure */ - headerlen = 4; - recordlen = 2; - entries = (ROM32(desc[0]) & 0x01f00000) >> 20; - break; - case 5: /* Vendor Specific Structure */ - headerlen = 8; - break; - case 6: /* Backlight Control Structure */ - if (mxms_version(dev) >= 0x0300) { - headerlen = 4; - recordlen = 8; - entries = (desc[1] & 0xf0) >> 4; - } else { - headerlen = 8; - } - break; - case 7: /* Fan Control Structure */ - headerlen = 8; - recordlen = 4; - entries = desc[1] & 0x07; - break; - default: - MXM_DBG(dev, "unknown descriptor type %d\n", type); - return false; - } - - if ((drm_debug & DRM_UT_DRIVER) && (exec == NULL)) { - static const char * mxms_desc_name[] = { - "ODS", "SCCS", "TS", "IPS", - "GSD", "VSS", "BCS", "FCS", - }; - u8 *dump = desc; - int i, j; - - MXM_DBG(dev, "%4s: ", mxms_desc_name[type]); - for (j = headerlen - 1; j >= 0; j--) - printk("%02x", dump[j]); - printk("\n"); - dump += headerlen; - - for (i = 0; i < entries; i++, dump += recordlen) { - MXM_DBG(dev, " "); - for (j = recordlen - 1; j >= 0; j--) - printk("%02x", dump[j]); - printk("\n"); - } - } - - if (types & (1 << type)) { - if (!exec(dev, desc, info)) - return false; - } - - desc += headerlen + (entries * recordlen); - } - - return true; -} - -static u8 * -mxm_table(struct drm_device *dev, u8 *size) -{ - struct bit_entry x; - - if (bit_table(dev, 'x', &x)) { - MXM_DBG(dev, "BIT 'x' table not present\n"); - return NULL; - } - - if (x.version != 1 || x.length < 3) { - MXM_MSG(dev, "BIT x table %d/%d unknown\n", - x.version, x.length); - return NULL; - } - - *size = x.length; - return x.data; -} - -/* These map MXM v2.x digital connection values to the appropriate SOR/link, - * hopefully they're correct for all boards within the same chipset... - * - * MXM v3.x VBIOS are nicer and provide pointers to these tables. - */ -static u8 nv84_sor_map[16] = { - 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static u8 nv92_sor_map[16] = { - 0x00, 0x12, 0x22, 0x11, 0x32, 0x31, 0x11, 0x31, - 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static u8 nv94_sor_map[16] = { - 0x00, 0x14, 0x24, 0x11, 0x34, 0x31, 0x11, 0x31, - 0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static u8 nv96_sor_map[16] = { - 0x00, 0x14, 0x24, 0x00, 0x34, 0x00, 0x11, 0x31, - 0x11, 0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static u8 nv98_sor_map[16] = { - 0x00, 0x14, 0x12, 0x11, 0x00, 0x31, 0x11, 0x31, - 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static u8 -mxm_sor_map(struct drm_device *dev, u8 conn) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u8 len, *mxm = mxm_table(dev, &len); - if (mxm && len >= 6) { - u8 *map = ROMPTR(dev, mxm[4]); - if (map) { - if (map[0] == 0x10) { - if (conn < map[3]) - return map[map[1] + conn]; - return 0x00; - } - - MXM_MSG(dev, "unknown sor map 0x%02x\n", map[0]); - } - } - - if (dev_priv->chipset == 0x84 || dev_priv->chipset == 0x86) - return nv84_sor_map[conn]; - if (dev_priv->chipset == 0x92) - return nv92_sor_map[conn]; - if (dev_priv->chipset == 0x94) - return nv94_sor_map[conn]; - if (dev_priv->chipset == 0x96) - return nv96_sor_map[conn]; - if (dev_priv->chipset == 0x98) - return nv98_sor_map[conn]; - - MXM_MSG(dev, "missing sor map\n"); - return 0x00; -} - -static u8 -mxm_ddc_map(struct drm_device *dev, u8 port) -{ - u8 len, *mxm = mxm_table(dev, &len); - if (mxm && len >= 8) { - u8 *map = ROMPTR(dev, mxm[6]); - if (map) { - if (map[0] == 0x10) { - if (port < map[3]) - return map[map[1] + port]; - return 0x00; - } - - MXM_MSG(dev, "unknown ddc map 0x%02x\n", map[0]); - } - } - - /* v2.x: directly write port as dcb i2cidx */ - return (port << 4) | port; -} - -struct mxms_odev { - u8 outp_type; - u8 conn_type; - u8 ddc_port; - u8 dig_conn; -}; - -static void -mxms_output_device(struct drm_device *dev, u8 *pdata, struct mxms_odev *desc) -{ - u64 data = ROM32(pdata[0]); - if (mxms_version(dev) >= 0x0300) - data |= (u64)ROM16(pdata[4]) << 32; - - desc->outp_type = (data & 0x00000000000000f0ULL) >> 4; - desc->ddc_port = (data & 0x0000000000000f00ULL) >> 8; - desc->conn_type = (data & 0x000000000001f000ULL) >> 12; - desc->dig_conn = (data & 0x0000000000780000ULL) >> 19; -} - -struct context { - u32 *outp; - struct mxms_odev desc; -}; - -static bool -mxm_match_tmds_partner(struct drm_device *dev, u8 *data, void *info) -{ - struct context *ctx = info; - struct mxms_odev desc; - - mxms_output_device(dev, data, &desc); - if (desc.outp_type == 2 && - desc.dig_conn == ctx->desc.dig_conn) - return false; - return true; -} - -static bool -mxm_match_dcb(struct drm_device *dev, u8 *data, void *info) -{ - struct context *ctx = info; - u64 desc = *(u64 *)data; - - mxms_output_device(dev, data, &ctx->desc); - - /* match dcb encoder type to mxm-ods device type */ - if ((ctx->outp[0] & 0x0000000f) != ctx->desc.outp_type) - return true; - - /* digital output, have some extra stuff to match here, there's a - * table in the vbios that provides a mapping from the mxm digital - * connection enum values to SOR/link - */ - if ((desc & 0x00000000000000f0) >= 0x20) { - /* check against sor index */ - u8 link = mxm_sor_map(dev, ctx->desc.dig_conn); - if ((ctx->outp[0] & 0x0f000000) != (link & 0x0f) << 24) - return true; - - /* check dcb entry has a compatible link field */ - link = (link & 0x30) >> 4; - if ((link & ((ctx->outp[1] & 0x00000030) >> 4)) != link) - return true; - } - - /* mark this descriptor accounted for by setting invalid device type, - * except of course some manufactures don't follow specs properly and - * we need to avoid killing off the TMDS function on DP connectors - * if MXM-SIS is missing an entry for it. - */ - data[0] &= ~0xf0; - if (ctx->desc.outp_type == 6 && ctx->desc.conn_type == 6 && - mxms_foreach(dev, 0x01, mxm_match_tmds_partner, ctx)) { - data[0] |= 0x20; /* modify descriptor to match TMDS now */ - } else { - data[0] |= 0xf0; - } - - return false; -} - -static int -mxm_dcb_sanitise_entry(struct drm_device *dev, void *data, int idx, u8 *dcbe) -{ - struct context ctx = { .outp = (u32 *)dcbe }; - u8 type, i2cidx, link; - u8 *conn; - - /* look for an output device structure that matches this dcb entry. - * if one isn't found, disable it. - */ - if (mxms_foreach(dev, 0x01, mxm_match_dcb, &ctx)) { - MXM_DBG(dev, "disable %d: 0x%08x 0x%08x\n", - idx, ctx.outp[0], ctx.outp[1]); - ctx.outp[0] |= 0x0000000f; - return 0; - } - - /* modify the output's ddc/aux port, there's a pointer to a table - * with the mapping from mxm ddc/aux port to dcb i2c_index in the - * vbios mxm table - */ - i2cidx = mxm_ddc_map(dev, ctx.desc.ddc_port); - if ((ctx.outp[0] & 0x0000000f) != OUTPUT_DP) - i2cidx = (i2cidx & 0x0f) << 4; - else - i2cidx = (i2cidx & 0xf0); - - if (i2cidx != 0xf0) { - ctx.outp[0] &= ~0x000000f0; - ctx.outp[0] |= i2cidx; - } - - /* override dcb sorconf.link, based on what mxm data says */ - switch (ctx.desc.outp_type) { - case 0x00: /* Analog CRT */ - case 0x01: /* Analog TV/HDTV */ - break; - default: - link = mxm_sor_map(dev, ctx.desc.dig_conn) & 0x30; - ctx.outp[1] &= ~0x00000030; - ctx.outp[1] |= link; - break; - } - - /* we may need to fixup various other vbios tables based on what - * the descriptor says the connector type should be. - * - * in a lot of cases, the vbios tables will claim DVI-I is possible, - * and the mxm data says the connector is really HDMI. another - * common example is DP->eDP. - */ - conn = dcb_conn(dev, (ctx.outp[0] & 0x0000f000) >> 12); - type = conn[0]; - switch (ctx.desc.conn_type) { - case 0x01: /* LVDS */ - ctx.outp[1] |= 0x00000004; /* use_power_scripts */ - /* XXX: modify default link width in LVDS table */ - break; - case 0x02: /* HDMI */ - type = DCB_CONNECTOR_HDMI_1; - break; - case 0x03: /* DVI-D */ - type = DCB_CONNECTOR_DVI_D; - break; - case 0x0e: /* eDP, falls through to DPint */ - ctx.outp[1] |= 0x00010000; - case 0x07: /* DP internal, wtf is this?? HP8670w */ - ctx.outp[1] |= 0x00000004; /* use_power_scripts? */ - type = DCB_CONNECTOR_eDP; - break; - default: - break; - } - - if (mxms_version(dev) >= 0x0300) - conn[0] = type; - - return 0; -} - -static bool -mxm_show_unmatched(struct drm_device *dev, u8 *data, void *info) -{ - u64 desc = *(u64 *)data; - if ((desc & 0xf0) != 0xf0) - MXM_MSG(dev, "unmatched output device 0x%016llx\n", desc); - return true; -} - -static void -mxm_dcb_sanitise(struct drm_device *dev) -{ - u8 *dcb = dcb_table(dev); - if (!dcb || dcb[0] != 0x40) { - MXM_DBG(dev, "unsupported DCB version\n"); - return; - } - - dcb_outp_foreach(dev, NULL, mxm_dcb_sanitise_entry); - mxms_foreach(dev, 0x01, mxm_show_unmatched, NULL); -} - -static bool -mxm_shadow_rom_fetch(struct nouveau_i2c_chan *i2c, u8 addr, - u8 offset, u8 size, u8 *data) -{ - struct i2c_msg msgs[] = { - { .addr = addr, .flags = 0, .len = 1, .buf = &offset }, - { .addr = addr, .flags = I2C_M_RD, .len = size, .buf = data, }, - }; - - return i2c_transfer(&i2c->adapter, msgs, 2) == 2; -} - -static bool -mxm_shadow_rom(struct drm_device *dev, u8 version) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_i2c_chan *i2c = NULL; - u8 i2cidx, mxms[6], addr, size; - - i2cidx = mxm_ddc_map(dev, 1 /* LVDS_DDC */) & 0x0f; - if (i2cidx < 0x0f) - i2c = nouveau_i2c_find(dev, i2cidx); - if (!i2c) - return false; - - addr = 0x54; - if (!mxm_shadow_rom_fetch(i2c, addr, 0, 6, mxms)) { - addr = 0x56; - if (!mxm_shadow_rom_fetch(i2c, addr, 0, 6, mxms)) - return false; - } - - dev_priv->mxms = mxms; - size = mxms_headerlen(dev) + mxms_structlen(dev); - dev_priv->mxms = kmalloc(size, GFP_KERNEL); - - if (dev_priv->mxms && - mxm_shadow_rom_fetch(i2c, addr, 0, size, dev_priv->mxms)) - return true; - - kfree(dev_priv->mxms); - dev_priv->mxms = NULL; - return false; -} - -#if defined(CONFIG_ACPI) -static bool -mxm_shadow_dsm(struct drm_device *dev, u8 version) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - static char muid[] = { - 0x00, 0xA4, 0x04, 0x40, 0x7D, 0x91, 0xF2, 0x4C, - 0xB8, 0x9C, 0x79, 0xB6, 0x2F, 0xD5, 0x56, 0x65 - }; - u32 mxms_args[] = { 0x00000000 }; - union acpi_object args[4] = { - /* _DSM MUID */ - { .buffer.type = 3, - .buffer.length = sizeof(muid), - .buffer.pointer = muid, - }, - /* spec says this can be zero to mean "highest revision", but - * of course there's at least one bios out there which fails - * unless you pass in exactly the version it supports.. - */ - { .integer.type = ACPI_TYPE_INTEGER, - .integer.value = (version & 0xf0) << 4 | (version & 0x0f), - }, - /* MXMS function */ - { .integer.type = ACPI_TYPE_INTEGER, - .integer.value = 0x00000010, - }, - /* Pointer to MXMS arguments */ - { .buffer.type = ACPI_TYPE_BUFFER, - .buffer.length = sizeof(mxms_args), - .buffer.pointer = (char *)mxms_args, - }, - }; - struct acpi_object_list list = { ARRAY_SIZE(args), args }; - struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - acpi_handle handle; - int ret; - - handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); - if (!handle) - return false; - - ret = acpi_evaluate_object(handle, "_DSM", &list, &retn); - if (ret) { - MXM_DBG(dev, "DSM MXMS failed: %d\n", ret); - return false; - } - - obj = retn.pointer; - if (obj->type == ACPI_TYPE_BUFFER) { - dev_priv->mxms = kmemdup(obj->buffer.pointer, - obj->buffer.length, GFP_KERNEL); - } else - if (obj->type == ACPI_TYPE_INTEGER) { - MXM_DBG(dev, "DSM MXMS returned 0x%llx\n", obj->integer.value); - } - - kfree(obj); - return dev_priv->mxms != NULL; -} -#endif - -#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) - -#define WMI_WMMX_GUID "F6CB5C3C-9CAE-4EBD-B577-931EA32A2CC0" - -static u8 -wmi_wmmx_mxmi(struct drm_device *dev, u8 version) -{ - u32 mxmi_args[] = { 0x494D584D /* MXMI */, version, 0 }; - struct acpi_buffer args = { sizeof(mxmi_args), mxmi_args }; - struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - acpi_status status; - - status = wmi_evaluate_method(WMI_WMMX_GUID, 0, 0, &args, &retn); - if (ACPI_FAILURE(status)) { - MXM_DBG(dev, "WMMX MXMI returned %d\n", status); - return 0x00; - } - - obj = retn.pointer; - if (obj->type == ACPI_TYPE_INTEGER) { - version = obj->integer.value; - MXM_DBG(dev, "WMMX MXMI version %d.%d\n", - (version >> 4), version & 0x0f); - } else { - version = 0; - MXM_DBG(dev, "WMMX MXMI returned non-integer\n"); - } - - kfree(obj); - return version; -} - -static bool -mxm_shadow_wmi(struct drm_device *dev, u8 version) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 mxms_args[] = { 0x534D584D /* MXMS */, version, 0 }; - struct acpi_buffer args = { sizeof(mxms_args), mxms_args }; - struct acpi_buffer retn = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - acpi_status status; - - if (!wmi_has_guid(WMI_WMMX_GUID)) { - MXM_DBG(dev, "WMMX GUID not found\n"); - return false; - } - - mxms_args[1] = wmi_wmmx_mxmi(dev, 0x00); - if (!mxms_args[1]) - mxms_args[1] = wmi_wmmx_mxmi(dev, version); - if (!mxms_args[1]) - return false; - - status = wmi_evaluate_method(WMI_WMMX_GUID, 0, 0, &args, &retn); - if (ACPI_FAILURE(status)) { - MXM_DBG(dev, "WMMX MXMS returned %d\n", status); - return false; - } - - obj = retn.pointer; - if (obj->type == ACPI_TYPE_BUFFER) { - dev_priv->mxms = kmemdup(obj->buffer.pointer, - obj->buffer.length, GFP_KERNEL); - } - - kfree(obj); - return dev_priv->mxms != NULL; -} -#endif - -struct mxm_shadow_h { - const char *name; - bool (*exec)(struct drm_device *, u8 version); -} _mxm_shadow[] = { - { "ROM", mxm_shadow_rom }, -#if defined(CONFIG_ACPI) - { "DSM", mxm_shadow_dsm }, -#endif -#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) - { "WMI", mxm_shadow_wmi }, -#endif - {} -}; - -static int -mxm_shadow(struct drm_device *dev, u8 version) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct mxm_shadow_h *shadow = _mxm_shadow; - do { - MXM_DBG(dev, "checking %s\n", shadow->name); - if (shadow->exec(dev, version)) { - if (mxms_valid(dev)) - return 0; - kfree(dev_priv->mxms); - dev_priv->mxms = NULL; - } - } while ((++shadow)->name); - return -ENOENT; -} - -int -nouveau_mxm_init(struct drm_device *dev) -{ - u8 mxm_size, *mxm = mxm_table(dev, &mxm_size); - if (!mxm || !mxm[0]) { - MXM_MSG(dev, "no VBIOS data, nothing to do\n"); - return 0; - } - - MXM_MSG(dev, "BIOS version %d.%d\n", mxm[0] >> 4, mxm[0] & 0x0f); - - if (mxm_shadow(dev, mxm[0])) { - MXM_MSG(dev, "failed to locate valid SIS\n"); -#if 0 - /* we should, perhaps, fall back to some kind of limited - * mode here if the x86 vbios hasn't already done the - * work for us (so we prevent loading with completely - * whacked vbios tables). - */ - return -EINVAL; -#else - return 0; -#endif - } - - MXM_MSG(dev, "MXMS Version %d.%d\n", - mxms_version(dev) >> 8, mxms_version(dev) & 0xff); - mxms_foreach(dev, 0, NULL, NULL); - - if (nouveau_mxmdcb) - mxm_dcb_sanitise(dev); - return 0; -} - -void -nouveau_mxm_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - kfree(dev_priv->mxms); - dev_priv->mxms = NULL; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_notifier.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_notifier.c deleted file mode 100644 index 2ef883c4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" - -int -nouveau_notifier_init_channel(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_bo *ntfy = NULL; - uint32_t flags, ttmpl; - int ret; - - if (nouveau_vram_notify) { - flags = NOUVEAU_GEM_DOMAIN_VRAM; - ttmpl = TTM_PL_FLAG_VRAM; - } else { - flags = NOUVEAU_GEM_DOMAIN_GART; - ttmpl = TTM_PL_FLAG_TT; - } - - ret = nouveau_gem_new(dev, PAGE_SIZE, 0, flags, 0, 0, &ntfy); - if (ret) - return ret; - - ret = nouveau_bo_pin(ntfy, ttmpl); - if (ret) - goto out_err; - - ret = nouveau_bo_map(ntfy); - if (ret) - goto out_err; - - if (dev_priv->card_type >= NV_50) { - ret = nouveau_bo_vma_add(ntfy, chan->vm, &chan->notifier_vma); - if (ret) - goto out_err; - } - - ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size); - if (ret) - goto out_err; - - chan->notifier_bo = ntfy; -out_err: - if (ret) { - nouveau_bo_vma_del(ntfy, &chan->notifier_vma); - drm_gem_object_unreference_unlocked(ntfy->gem); - } - - return ret; -} - -void -nouveau_notifier_takedown_channel(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - - if (!chan->notifier_bo) - return; - - nouveau_bo_vma_del(chan->notifier_bo, &chan->notifier_vma); - nouveau_bo_unmap(chan->notifier_bo); - mutex_lock(&dev->struct_mutex); - nouveau_bo_unpin(chan->notifier_bo); - mutex_unlock(&dev->struct_mutex); - drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); - drm_mm_takedown(&chan->notifier_heap); -} - -static void -nouveau_notifier_gpuobj_dtor(struct drm_device *dev, - struct nouveau_gpuobj *gpuobj) -{ - NV_DEBUG(dev, "\n"); - - if (gpuobj->priv) - drm_mm_put_block(gpuobj->priv); -} - -int -nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int size, uint32_t start, uint32_t end, - uint32_t *b_offset) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *nobj = NULL; - struct drm_mm_node *mem; - uint64_t offset; - int target, ret; - - mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0, - start, end, 0); - if (mem) - mem = drm_mm_get_block_range(mem, size, 0, start, end); - if (!mem) { - NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); - return -ENOMEM; - } - - if (dev_priv->card_type < NV_50) { - if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) - target = NV_MEM_TARGET_VRAM; - else - target = NV_MEM_TARGET_GART; - offset = chan->notifier_bo->bo.offset; - } else { - target = NV_MEM_TARGET_VM; - offset = chan->notifier_vma.offset; - } - offset += mem->start; - - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, - mem->size, NV_MEM_ACCESS_RW, target, - &nobj); - if (ret) { - drm_mm_put_block(mem); - NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret); - return ret; - } - nobj->dtor = nouveau_notifier_gpuobj_dtor; - nobj->priv = mem; - - ret = nouveau_ramht_insert(chan, handle, nobj); - nouveau_gpuobj_ref(NULL, &nobj); - if (ret) { - drm_mm_put_block(mem); - NV_ERROR(dev, "Error adding notifier to ramht: %d\n", ret); - return ret; - } - - *b_offset = mem->start; - return 0; -} - -int -nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset) -{ - if (!nobj || nobj->dtor != nouveau_notifier_gpuobj_dtor) - return -EINVAL; - - if (poffset) { - struct drm_mm_node *mem = nobj->priv; - - if (*poffset >= mem->size) - return false; - - *poffset += mem->start; - } - - return 0; -} - -int -nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_notifierobj_alloc *na = data; - struct nouveau_channel *chan; - int ret; - - /* completely unnecessary for these chipsets... */ - if (unlikely(dev_priv->card_type >= NV_C0)) - return -EINVAL; - - chan = nouveau_channel_get(file_priv, na->channel); - if (IS_ERR(chan)) - return PTR_ERR(chan); - - ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, - &na->offset); - nouveau_channel_put(&chan); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_object.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_object.c deleted file mode 100644 index cc419fae..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_object.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* - * Copyright (C) 2006 Ben Skeggs. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* - * Authors: - * Ben Skeggs - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_ramht.h" -#include "nouveau_vm.h" -#include "nv50_display.h" - -struct nouveau_gpuobj_method { - struct list_head head; - u32 mthd; - int (*exec)(struct nouveau_channel *, u32 class, u32 mthd, u32 data); -}; - -struct nouveau_gpuobj_class { - struct list_head head; - struct list_head methods; - u32 id; - u32 engine; -}; - -int -nouveau_gpuobj_class_new(struct drm_device *dev, u32 class, u32 engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj_class *oc; - - oc = kzalloc(sizeof(*oc), GFP_KERNEL); - if (!oc) - return -ENOMEM; - - INIT_LIST_HEAD(&oc->methods); - oc->id = class; - oc->engine = engine; - list_add(&oc->head, &dev_priv->classes); - return 0; -} - -int -nouveau_gpuobj_mthd_new(struct drm_device *dev, u32 class, u32 mthd, - int (*exec)(struct nouveau_channel *, u32, u32, u32)) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj_method *om; - struct nouveau_gpuobj_class *oc; - - list_for_each_entry(oc, &dev_priv->classes, head) { - if (oc->id == class) - goto found; - } - - return -EINVAL; - -found: - om = kzalloc(sizeof(*om), GFP_KERNEL); - if (!om) - return -ENOMEM; - - om->mthd = mthd; - om->exec = exec; - list_add(&om->head, &oc->methods); - return 0; -} - -int -nouveau_gpuobj_mthd_call(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_gpuobj_method *om; - struct nouveau_gpuobj_class *oc; - - list_for_each_entry(oc, &dev_priv->classes, head) { - if (oc->id != class) - continue; - - list_for_each_entry(om, &oc->methods, head) { - if (om->mthd == mthd) - return om->exec(chan, class, mthd, data); - } - } - - return -ENOENT; -} - -int -nouveau_gpuobj_mthd_call2(struct drm_device *dev, int chid, - u32 class, u32 mthd, u32 data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - if (chid >= 0 && chid < dev_priv->engine.fifo.channels) - chan = dev_priv->channels.ptr[chid]; - if (chan) - ret = nouveau_gpuobj_mthd_call(chan, class, mthd, data); - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return ret; -} - -/* NVidia uses context objects to drive drawing operations. - - Context objects can be selected into 8 subchannels in the FIFO, - and then used via DMA command buffers. - - A context object is referenced by a user defined handle (CARD32). The HW - looks up graphics objects in a hash table in the instance RAM. - - An entry in the hash table consists of 2 CARD32. The first CARD32 contains - the handle, the second one a bitfield, that contains the address of the - object in instance RAM. - - The format of the second CARD32 seems to be: - - NV4 to NV30: - - 15: 0 instance_addr >> 4 - 17:16 engine (here uses 1 = graphics) - 28:24 channel id (here uses 0) - 31 valid (use 1) - - NV40: - - 15: 0 instance_addr >> 4 (maybe 19-0) - 21:20 engine (here uses 1 = graphics) - I'm unsure about the other bits, but using 0 seems to work. - - The key into the hash table depends on the object handle and channel id and - is given as: -*/ - -int -nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, - uint32_t size, int align, uint32_t flags, - struct nouveau_gpuobj **gpuobj_ret) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; - struct nouveau_gpuobj *gpuobj; - struct drm_mm_node *ramin = NULL; - int ret, i; - - NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", - chan ? chan->id : -1, size, align, flags); - - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); - if (!gpuobj) - return -ENOMEM; - NV_DEBUG(dev, "gpuobj %p\n", gpuobj); - gpuobj->dev = dev; - gpuobj->flags = flags; - kref_init(&gpuobj->refcount); - gpuobj->size = size; - - spin_lock(&dev_priv->ramin_lock); - list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); - spin_unlock(&dev_priv->ramin_lock); - - if (!(flags & NVOBJ_FLAG_VM) && chan) { - ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0); - if (ramin) - ramin = drm_mm_get_block(ramin, size, align); - if (!ramin) { - nouveau_gpuobj_ref(NULL, &gpuobj); - return -ENOMEM; - } - - gpuobj->pinst = chan->ramin->pinst; - if (gpuobj->pinst != ~0) - gpuobj->pinst += ramin->start; - - gpuobj->cinst = ramin->start; - gpuobj->vinst = ramin->start + chan->ramin->vinst; - gpuobj->node = ramin; - } else { - ret = instmem->get(gpuobj, chan, size, align); - if (ret) { - nouveau_gpuobj_ref(NULL, &gpuobj); - return ret; - } - - ret = -ENOSYS; - if (!(flags & NVOBJ_FLAG_DONT_MAP)) - ret = instmem->map(gpuobj); - if (ret) - gpuobj->pinst = ~0; - - gpuobj->cinst = NVOBJ_CINST_GLOBAL; - } - - if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { - for (i = 0; i < gpuobj->size; i += 4) - nv_wo32(gpuobj, i, 0); - instmem->flush(dev); - } - - - *gpuobj_ret = gpuobj; - return 0; -} - -int -nouveau_gpuobj_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - NV_DEBUG(dev, "\n"); - - INIT_LIST_HEAD(&dev_priv->gpuobj_list); - INIT_LIST_HEAD(&dev_priv->classes); - spin_lock_init(&dev_priv->ramin_lock); - dev_priv->ramin_base = ~0; - - return 0; -} - -void -nouveau_gpuobj_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj_method *om, *tm; - struct nouveau_gpuobj_class *oc, *tc; - - NV_DEBUG(dev, "\n"); - - list_for_each_entry_safe(oc, tc, &dev_priv->classes, head) { - list_for_each_entry_safe(om, tm, &oc->methods, head) { - list_del(&om->head); - kfree(om); - } - list_del(&oc->head); - kfree(oc); - } - - BUG_ON(!list_empty(&dev_priv->gpuobj_list)); -} - - -static void -nouveau_gpuobj_del(struct kref *ref) -{ - struct nouveau_gpuobj *gpuobj = - container_of(ref, struct nouveau_gpuobj, refcount); - struct drm_device *dev = gpuobj->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; - int i; - - NV_DEBUG(dev, "gpuobj %p\n", gpuobj); - - if (gpuobj->node && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { - for (i = 0; i < gpuobj->size; i += 4) - nv_wo32(gpuobj, i, 0); - instmem->flush(dev); - } - - if (gpuobj->dtor) - gpuobj->dtor(dev, gpuobj); - - if (gpuobj->cinst == NVOBJ_CINST_GLOBAL) { - if (gpuobj->node) { - instmem->unmap(gpuobj); - instmem->put(gpuobj); - } - } else { - if (gpuobj->node) { - spin_lock(&dev_priv->ramin_lock); - drm_mm_put_block(gpuobj->node); - spin_unlock(&dev_priv->ramin_lock); - } - } - - spin_lock(&dev_priv->ramin_lock); - list_del(&gpuobj->list); - spin_unlock(&dev_priv->ramin_lock); - - kfree(gpuobj); -} - -void -nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr) -{ - if (ref) - kref_get(&ref->refcount); - - if (*ptr) - kref_put(&(*ptr)->refcount, nouveau_gpuobj_del); - - *ptr = ref; -} - -int -nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst, - u32 size, u32 flags, struct nouveau_gpuobj **pgpuobj) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj = NULL; - int i; - - NV_DEBUG(dev, - "pinst=0x%08x vinst=0x%010llx size=0x%08x flags=0x%08x\n", - pinst, vinst, size, flags); - - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); - if (!gpuobj) - return -ENOMEM; - NV_DEBUG(dev, "gpuobj %p\n", gpuobj); - gpuobj->dev = dev; - gpuobj->flags = flags; - kref_init(&gpuobj->refcount); - gpuobj->size = size; - gpuobj->pinst = pinst; - gpuobj->cinst = NVOBJ_CINST_GLOBAL; - gpuobj->vinst = vinst; - - if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { - for (i = 0; i < gpuobj->size; i += 4) - nv_wo32(gpuobj, i, 0); - dev_priv->engine.instmem.flush(dev); - } - - spin_lock(&dev_priv->ramin_lock); - list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); - spin_unlock(&dev_priv->ramin_lock); - *pgpuobj = gpuobj; - return 0; -} - -/* - DMA objects are used to reference a piece of memory in the - framebuffer, PCI or AGP address space. Each object is 16 bytes big - and looks as follows: - - entry[0] - 11:0 class (seems like I can always use 0 here) - 12 page table present? - 13 page entry linear? - 15:14 access: 0 rw, 1 ro, 2 wo - 17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP - 31:20 dma adjust (bits 0-11 of the address) - entry[1] - dma limit (size of transfer) - entry[X] - 1 0 readonly, 1 readwrite - 31:12 dma frame address of the page (bits 12-31 of the address) - entry[N] - page table terminator, same value as the first pte, as does nvidia - rivatv uses 0xffffffff - - Non linear page tables need a list of frame addresses afterwards, - the rivatv project has some info on this. - - The method below creates a DMA object in instance RAM and returns a handle - to it that can be used to set up context objects. -*/ - -void -nv50_gpuobj_dma_init(struct nouveau_gpuobj *obj, u32 offset, int class, - u64 base, u64 size, int target, int access, - u32 type, u32 comp) -{ - struct drm_nouveau_private *dev_priv = obj->dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - u32 flags0; - - flags0 = (comp << 29) | (type << 22) | class; - flags0 |= 0x00100000; - - switch (access) { - case NV_MEM_ACCESS_RO: flags0 |= 0x00040000; break; - case NV_MEM_ACCESS_RW: - case NV_MEM_ACCESS_WO: flags0 |= 0x00080000; break; - default: - break; - } - - switch (target) { - case NV_MEM_TARGET_VRAM: - flags0 |= 0x00010000; - break; - case NV_MEM_TARGET_PCI: - flags0 |= 0x00020000; - break; - case NV_MEM_TARGET_PCI_NOSNOOP: - flags0 |= 0x00030000; - break; - case NV_MEM_TARGET_GART: - base += dev_priv->gart_info.aper_base; - default: - flags0 &= ~0x00100000; - break; - } - - /* convert to base + limit */ - size = (base + size) - 1; - - nv_wo32(obj, offset + 0x00, flags0); - nv_wo32(obj, offset + 0x04, lower_32_bits(size)); - nv_wo32(obj, offset + 0x08, lower_32_bits(base)); - nv_wo32(obj, offset + 0x0c, upper_32_bits(size) << 24 | - upper_32_bits(base)); - nv_wo32(obj, offset + 0x10, 0x00000000); - nv_wo32(obj, offset + 0x14, 0x00000000); - - pinstmem->flush(obj->dev); -} - -int -nv50_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, u64 size, - int target, int access, u32 type, u32 comp, - struct nouveau_gpuobj **pobj) -{ - struct drm_device *dev = chan->dev; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_FREE, pobj); - if (ret) - return ret; - - nv50_gpuobj_dma_init(*pobj, 0, class, base, size, target, - access, type, comp); - return 0; -} - -int -nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, - u64 size, int access, int target, - struct nouveau_gpuobj **pobj) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj *obj; - u32 flags0, flags2; - int ret; - - if (dev_priv->card_type >= NV_50) { - u32 comp = (target == NV_MEM_TARGET_VM) ? NV_MEM_COMP_VM : 0; - u32 type = (target == NV_MEM_TARGET_VM) ? NV_MEM_TYPE_VM : 0; - - return nv50_gpuobj_dma_new(chan, class, base, size, - target, access, type, comp, pobj); - } - - if (target == NV_MEM_TARGET_GART) { - struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; - - if (dev_priv->gart_info.type == NOUVEAU_GART_PDMA) { - if (base == 0) { - nouveau_gpuobj_ref(gart, pobj); - return 0; - } - - base = nouveau_sgdma_get_physical(dev, base); - target = NV_MEM_TARGET_PCI; - } else { - base += dev_priv->gart_info.aper_base; - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) - target = NV_MEM_TARGET_PCI_NOSNOOP; - else - target = NV_MEM_TARGET_PCI; - } - } - - flags0 = class; - flags0 |= 0x00003000; /* PT present, PT linear */ - flags2 = 0; - - switch (target) { - case NV_MEM_TARGET_PCI: - flags0 |= 0x00020000; - break; - case NV_MEM_TARGET_PCI_NOSNOOP: - flags0 |= 0x00030000; - break; - default: - break; - } - - switch (access) { - case NV_MEM_ACCESS_RO: - flags0 |= 0x00004000; - break; - case NV_MEM_ACCESS_WO: - flags0 |= 0x00008000; - default: - flags2 |= 0x00000002; - break; - } - - flags0 |= (base & 0x00000fff) << 20; - flags2 |= (base & 0xfffff000); - - ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - - nv_wo32(obj, 0x00, flags0); - nv_wo32(obj, 0x04, size - 1); - nv_wo32(obj, 0x08, flags2); - nv_wo32(obj, 0x0c, flags2); - - obj->engine = NVOBJ_ENGINE_SW; - obj->class = class; - *pobj = obj; - return 0; -} - -/* Context objects in the instance RAM have the following structure. - * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes. - - NV4 - NV30: - - entry[0] - 11:0 class - 12 chroma key enable - 13 user clip enable - 14 swizzle enable - 17:15 patch config: - scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre - 18 synchronize enable - 19 endian: 1 big, 0 little - 21:20 dither mode - 23 single step enable - 24 patch status: 0 invalid, 1 valid - 25 context_surface 0: 1 valid - 26 context surface 1: 1 valid - 27 context pattern: 1 valid - 28 context rop: 1 valid - 29,30 context beta, beta4 - entry[1] - 7:0 mono format - 15:8 color format - 31:16 notify instance address - entry[2] - 15:0 dma 0 instance address - 31:16 dma 1 instance address - entry[3] - dma method traps - - NV40: - No idea what the exact format is. Here's what can be deducted: - - entry[0]: - 11:0 class (maybe uses more bits here?) - 17 user clip enable - 21:19 patch config - 25 patch status valid ? - entry[1]: - 15:0 DMA notifier (maybe 20:0) - entry[2]: - 15:0 DMA 0 instance (maybe 20:0) - 24 big endian - entry[3]: - 15:0 DMA 1 instance (maybe 20:0) - entry[4]: - entry[5]: - set to 0? -*/ -static int -nouveau_gpuobj_sw_new(struct nouveau_channel *chan, u32 handle, u16 class) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_gpuobj *gpuobj; - int ret; - - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); - if (!gpuobj) - return -ENOMEM; - gpuobj->dev = chan->dev; - gpuobj->engine = NVOBJ_ENGINE_SW; - gpuobj->class = class; - kref_init(&gpuobj->refcount); - gpuobj->cinst = 0x40; - - spin_lock(&dev_priv->ramin_lock); - list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); - spin_unlock(&dev_priv->ramin_lock); - - ret = nouveau_ramht_insert(chan, handle, gpuobj); - nouveau_gpuobj_ref(NULL, &gpuobj); - return ret; -} - -int -nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj_class *oc; - int ret; - - NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); - - list_for_each_entry(oc, &dev_priv->classes, head) { - struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine]; - - if (oc->id != class) - continue; - - if (oc->engine == NVOBJ_ENGINE_SW) - return nouveau_gpuobj_sw_new(chan, handle, class); - - if (!chan->engctx[oc->engine]) { - ret = eng->context_new(chan, oc->engine); - if (ret) - return ret; - } - - return eng->object_new(chan, oc->engine, handle, class); - } - - NV_ERROR(dev, "illegal object class: 0x%x\n", class); - return -EINVAL; -} - -static int -nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t size; - uint32_t base; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - /* Base amount for object storage (4KiB enough?) */ - size = 0x2000; - base = 0; - - if (dev_priv->card_type == NV_50) { - /* Various fixed table thingos */ - size += 0x1400; /* mostly unknown stuff */ - size += 0x4000; /* vm pd */ - base = 0x6000; - /* RAMHT, not sure about setting size yet, 32KiB to be safe */ - size += 0x8000; - /* RAMFC */ - size += 0x1000; - } - - ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin); - if (ret) { - NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret); - return ret; - } - - ret = drm_mm_init(&chan->ramin_heap, base, size - base); - if (ret) { - NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); - nouveau_gpuobj_ref(NULL, &chan->ramin); - return ret; - } - - return 0; -} - -static int -nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj *pgd = NULL; - struct nouveau_vm_pgd *vpgd; - int ret, i; - - ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, &chan->ramin); - if (ret) - return ret; - - /* create page directory for this vm if none currently exists, - * will be destroyed automagically when last reference to the - * vm is removed - */ - if (list_empty(&vm->pgd_list)) { - ret = nouveau_gpuobj_new(dev, NULL, 65536, 0x1000, 0, &pgd); - if (ret) - return ret; - } - nouveau_vm_ref(vm, &chan->vm, pgd); - nouveau_gpuobj_ref(NULL, &pgd); - - /* point channel at vm's page directory */ - vpgd = list_first_entry(&vm->pgd_list, struct nouveau_vm_pgd, head); - nv_wo32(chan->ramin, 0x0200, lower_32_bits(vpgd->obj->vinst)); - nv_wo32(chan->ramin, 0x0204, upper_32_bits(vpgd->obj->vinst)); - nv_wo32(chan->ramin, 0x0208, 0xffffffff); - nv_wo32(chan->ramin, 0x020c, 0x000000ff); - - /* map display semaphore buffers into channel's vm */ - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo; - if (dev_priv->card_type >= NV_D0) - bo = nvd0_display_crtc_sema(dev, i); - else - bo = nv50_display(dev)->crtc[i].sem.bo; - - ret = nouveau_bo_vma_add(bo, chan->vm, &chan->dispc_vma[i]); - if (ret) - return ret; - } - - return 0; -} - -int -nouveau_gpuobj_channel_init(struct nouveau_channel *chan, - uint32_t vram_h, uint32_t tt_h) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fpriv *fpriv = nouveau_fpriv(chan->file_priv); - struct nouveau_vm *vm = fpriv ? fpriv->vm : dev_priv->chan_vm; - struct nouveau_gpuobj *vram = NULL, *tt = NULL; - int ret, i; - - NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); - if (dev_priv->card_type >= NV_C0) - return nvc0_gpuobj_channel_init(chan, vm); - - /* Allocate a chunk of memory for per-channel object storage */ - ret = nouveau_gpuobj_channel_init_pramin(chan); - if (ret) { - NV_ERROR(dev, "init pramin\n"); - return ret; - } - - /* NV50 VM - * - Allocate per-channel page-directory - * - Link with shared channel VM - */ - if (vm) { - u32 pgd_offs = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; - u64 vm_vinst = chan->ramin->vinst + pgd_offs; - u32 vm_pinst = chan->ramin->pinst; - - if (vm_pinst != ~0) - vm_pinst += pgd_offs; - - ret = nouveau_gpuobj_new_fake(dev, vm_pinst, vm_vinst, 0x4000, - 0, &chan->vm_pd); - if (ret) - return ret; - - nouveau_vm_ref(vm, &chan->vm, chan->vm_pd); - } - - /* RAMHT */ - if (dev_priv->card_type < NV_50) { - nouveau_ramht_ref(dev_priv->ramht, &chan->ramht, NULL); - } else { - struct nouveau_gpuobj *ramht = NULL; - - ret = nouveau_gpuobj_new(dev, chan, 0x8000, 16, - NVOBJ_FLAG_ZERO_ALLOC, &ramht); - if (ret) - return ret; - - ret = nouveau_ramht_new(dev, ramht, &chan->ramht); - nouveau_gpuobj_ref(NULL, &ramht); - if (ret) - return ret; - - /* dma objects for display sync channel semaphore blocks */ - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct nouveau_gpuobj *sem = NULL; - struct nv50_display_crtc *dispc = - &nv50_display(dev)->crtc[i]; - u64 offset = dispc->sem.bo->bo.offset; - - ret = nouveau_gpuobj_dma_new(chan, 0x3d, offset, 0xfff, - NV_MEM_ACCESS_RW, - NV_MEM_TARGET_VRAM, &sem); - if (ret) - return ret; - - ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, sem); - nouveau_gpuobj_ref(NULL, &sem); - if (ret) - return ret; - } - } - - /* VRAM ctxdma */ - if (dev_priv->card_type >= NV_50) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 0, (1ULL << 40), NV_MEM_ACCESS_RW, - NV_MEM_TARGET_VM, &vram); - if (ret) { - NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); - return ret; - } - } else { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 0, dev_priv->fb_available_size, - NV_MEM_ACCESS_RW, - NV_MEM_TARGET_VRAM, &vram); - if (ret) { - NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); - return ret; - } - } - - ret = nouveau_ramht_insert(chan, vram_h, vram); - nouveau_gpuobj_ref(NULL, &vram); - if (ret) { - NV_ERROR(dev, "Error adding VRAM ctxdma to RAMHT: %d\n", ret); - return ret; - } - - /* TT memory ctxdma */ - if (dev_priv->card_type >= NV_50) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 0, (1ULL << 40), NV_MEM_ACCESS_RW, - NV_MEM_TARGET_VM, &tt); - } else { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 0, dev_priv->gart_info.aper_size, - NV_MEM_ACCESS_RW, - NV_MEM_TARGET_GART, &tt); - } - - if (ret) { - NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret); - return ret; - } - - ret = nouveau_ramht_insert(chan, tt_h, tt); - nouveau_gpuobj_ref(NULL, &tt); - if (ret) { - NV_ERROR(dev, "Error adding TT ctxdma to RAMHT: %d\n", ret); - return ret; - } - - return 0; -} - -void -nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - if (dev_priv->card_type >= NV_D0) { - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct nouveau_bo *bo = nvd0_display_crtc_sema(dev, i); - nouveau_bo_vma_del(bo, &chan->dispc_vma[i]); - } - } else - if (dev_priv->card_type >= NV_50) { - struct nv50_display *disp = nv50_display(dev); - for (i = 0; i < dev->mode_config.num_crtc; i++) { - struct nv50_display_crtc *dispc = &disp->crtc[i]; - nouveau_bo_vma_del(dispc->sem.bo, &chan->dispc_vma[i]); - } - } - - nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); - nouveau_gpuobj_ref(NULL, &chan->vm_pd); - - if (drm_mm_initialized(&chan->ramin_heap)) - drm_mm_takedown(&chan->ramin_heap); - nouveau_gpuobj_ref(NULL, &chan->ramin); -} - -int -nouveau_gpuobj_suspend(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj; - int i; - - list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { - if (gpuobj->cinst != NVOBJ_CINST_GLOBAL) - continue; - - gpuobj->suspend = vmalloc(gpuobj->size); - if (!gpuobj->suspend) { - nouveau_gpuobj_resume(dev); - return -ENOMEM; - } - - for (i = 0; i < gpuobj->size; i += 4) - gpuobj->suspend[i/4] = nv_ro32(gpuobj, i); - } - - return 0; -} - -void -nouveau_gpuobj_resume(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj; - int i; - - list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { - if (!gpuobj->suspend) - continue; - - for (i = 0; i < gpuobj->size; i += 4) - nv_wo32(gpuobj, i, gpuobj->suspend[i/4]); - - vfree(gpuobj->suspend); - gpuobj->suspend = NULL; - } - - dev_priv->engine.instmem.flush(dev); -} - -int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_grobj_alloc *init = data; - struct nouveau_channel *chan; - int ret; - - if (init->handle == ~0) - return -EINVAL; - - chan = nouveau_channel_get(file_priv, init->channel); - if (IS_ERR(chan)) - return PTR_ERR(chan); - - if (nouveau_ramht_find(chan, init->handle)) { - ret = -EEXIST; - goto out; - } - - ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class); - if (ret) { - NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", - ret, init->channel, init->handle); - } - -out: - nouveau_channel_put(&chan); - return ret; -} - -int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_gpuobj_free *objfree = data; - struct nouveau_channel *chan; - int ret; - - chan = nouveau_channel_get(file_priv, objfree->channel); - if (IS_ERR(chan)) - return PTR_ERR(chan); - - /* Synchronize with the user channel */ - nouveau_channel_idle(chan); - - ret = nouveau_ramht_remove(chan, objfree->handle); - nouveau_channel_put(&chan); - return ret; -} - -u32 -nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) -{ - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct drm_device *dev = gpuobj->dev; - unsigned long flags; - - if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { - u64 ptr = gpuobj->vinst + offset; - u32 base = ptr >> 16; - u32 val; - - spin_lock_irqsave(&dev_priv->vm_lock, flags); - if (dev_priv->ramin_base != base) { - dev_priv->ramin_base = base; - nv_wr32(dev, 0x001700, dev_priv->ramin_base); - } - val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); - spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - return val; - } - - return nv_ri32(dev, gpuobj->pinst + offset); -} - -void -nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) -{ - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct drm_device *dev = gpuobj->dev; - unsigned long flags; - - if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { - u64 ptr = gpuobj->vinst + offset; - u32 base = ptr >> 16; - - spin_lock_irqsave(&dev_priv->vm_lock, flags); - if (dev_priv->ramin_base != base) { - dev_priv->ramin_base = base; - nv_wr32(dev, 0x001700, dev_priv->ramin_base); - } - nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); - spin_unlock_irqrestore(&dev_priv->vm_lock, flags); - return; - } - - nv_wi32(dev, gpuobj->pinst + offset, val); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_perf.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_perf.c deleted file mode 100644 index 69a528d1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_perf.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_pm.h" - -static u8 * -nouveau_perf_table(struct drm_device *dev, u8 *ver) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct bit_entry P; - - if (!bit_table(dev, 'P', &P) && P.version && P.version <= 2) { - u8 *perf = ROMPTR(dev, P.data[0]); - if (perf) { - *ver = perf[0]; - return perf; - } - } - - if (bios->type == NVBIOS_BMP) { - if (bios->data[bios->offset + 6] >= 0x25) { - u8 *perf = ROMPTR(dev, bios->data[bios->offset + 0x94]); - if (perf) { - *ver = perf[1]; - return perf; - } - } - } - - return NULL; -} - -static u8 * -nouveau_perf_entry(struct drm_device *dev, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - u8 *perf = nouveau_perf_table(dev, ver); - if (perf) { - if (*ver >= 0x12 && *ver < 0x20 && idx < perf[2]) { - *hdr = perf[3]; - *cnt = 0; - *len = 0; - return perf + perf[0] + idx * perf[3]; - } else - if (*ver >= 0x20 && *ver < 0x40 && idx < perf[2]) { - *hdr = perf[3]; - *cnt = perf[4]; - *len = perf[5]; - return perf + perf[1] + idx * (*hdr + (*cnt * *len)); - } else - if (*ver >= 0x40 && *ver < 0x41 && idx < perf[5]) { - *hdr = perf[2]; - *cnt = perf[4]; - *len = perf[3]; - return perf + perf[1] + idx * (*hdr + (*cnt * *len)); - } - } - return NULL; -} - -static u8 * -nouveau_perf_rammap(struct drm_device *dev, u32 freq, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct bit_entry P; - u8 *perf, i = 0; - - if (!bit_table(dev, 'P', &P) && P.version == 2) { - u8 *rammap = ROMPTR(dev, P.data[4]); - if (rammap) { - u8 *ramcfg = rammap + rammap[1]; - - *ver = rammap[0]; - *hdr = rammap[2]; - *cnt = rammap[4]; - *len = rammap[3]; - - freq /= 1000; - for (i = 0; i < rammap[5]; i++) { - if (freq >= ROM16(ramcfg[0]) && - freq <= ROM16(ramcfg[2])) - return ramcfg; - - ramcfg += *hdr + (*cnt * *len); - } - } - - return NULL; - } - - if (dev_priv->chipset == 0x49 || - dev_priv->chipset == 0x4b) - freq /= 2; - - while ((perf = nouveau_perf_entry(dev, i++, ver, hdr, cnt, len))) { - if (*ver >= 0x20 && *ver < 0x25) { - if (perf[0] != 0xff && freq <= ROM16(perf[11]) * 1000) - break; - } else - if (*ver >= 0x25 && *ver < 0x40) { - if (perf[0] != 0xff && freq <= ROM16(perf[12]) * 1000) - break; - } - } - - if (perf) { - u8 *ramcfg = perf + *hdr; - *ver = 0x00; - *hdr = 0; - return ramcfg; - } - - return NULL; -} - -u8 * -nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - u8 strap, hdr, cnt; - u8 *rammap; - - strap = (nv_rd32(dev, 0x101000) & 0x0000003c) >> 2; - if (bios->ram_restrict_tbl_ptr) - strap = bios->data[bios->ram_restrict_tbl_ptr + strap]; - - rammap = nouveau_perf_rammap(dev, freq, ver, &hdr, &cnt, len); - if (rammap && strap < cnt) - return rammap + hdr + (strap * *len); - - return NULL; -} - -u8 * -nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct bit_entry P; - u8 *perf, *timing = NULL; - u8 i = 0, hdr, cnt; - - if (bios->type == NVBIOS_BMP) { - while ((perf = nouveau_perf_entry(dev, i++, ver, &hdr, &cnt, - len)) && *ver == 0x15) { - if (freq <= ROM32(perf[5]) * 20) { - *ver = 0x00; - *len = 14; - return perf + 41; - } - } - return NULL; - } - - if (!bit_table(dev, 'P', &P)) { - if (P.version == 1) - timing = ROMPTR(dev, P.data[4]); - else - if (P.version == 2) - timing = ROMPTR(dev, P.data[8]); - } - - if (timing && timing[0] == 0x10) { - u8 *ramcfg = nouveau_perf_ramcfg(dev, freq, ver, len); - if (ramcfg && ramcfg[1] < timing[2]) { - *ver = timing[0]; - *len = timing[3]; - return timing + timing[1] + (ramcfg[1] * timing[3]); - } - } - - return NULL; -} - -static void -legacy_perf_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - char *perf, *entry, *bmp = &bios->data[bios->offset]; - int headerlen, use_straps; - - if (bmp[5] < 0x5 || bmp[6] < 0x14) { - NV_DEBUG(dev, "BMP version too old for perf\n"); - return; - } - - perf = ROMPTR(dev, bmp[0x73]); - if (!perf) { - NV_DEBUG(dev, "No memclock table pointer found.\n"); - return; - } - - switch (perf[0]) { - case 0x12: - case 0x14: - case 0x18: - use_straps = 0; - headerlen = 1; - break; - case 0x01: - use_straps = perf[1] & 1; - headerlen = (use_straps ? 8 : 2); - break; - default: - NV_WARN(dev, "Unknown memclock table version %x.\n", perf[0]); - return; - } - - entry = perf + headerlen; - if (use_straps) - entry += (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x3c) >> 1; - - sprintf(pm->perflvl[0].name, "performance_level_0"); - pm->perflvl[0].memory = ROM16(entry[0]) * 20; - pm->nr_perflvl = 1; -} - -static void -nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct bit_entry P; - u8 *vmap; - int id; - - id = perflvl->volt_min; - perflvl->volt_min = 0; - - /* boards using voltage table version <0x40 store the voltage - * level directly in the perflvl entry as a multiple of 10mV - */ - if (dev_priv->engine.pm.voltage.version < 0x40) { - perflvl->volt_min = id * 10000; - perflvl->volt_max = perflvl->volt_min; - return; - } - - /* on newer ones, the perflvl stores an index into yet another - * vbios table containing a min/max voltage value for the perflvl - */ - if (bit_table(dev, 'P', &P) || P.version != 2 || P.length < 34) { - NV_DEBUG(dev, "where's our volt map table ptr? %d %d\n", - P.version, P.length); - return; - } - - vmap = ROMPTR(dev, P.data[32]); - if (!vmap) { - NV_DEBUG(dev, "volt map table pointer invalid\n"); - return; - } - - if (id < vmap[3]) { - vmap += vmap[1] + (vmap[2] * id); - perflvl->volt_min = ROM32(vmap[0]); - perflvl->volt_max = ROM32(vmap[4]); - } -} - -void -nouveau_perf_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nvbios *bios = &dev_priv->vbios; - u8 *perf, ver, hdr, cnt, len; - int ret, vid, i = -1; - - if (bios->type == NVBIOS_BMP && bios->data[bios->offset + 6] < 0x25) { - legacy_perf_init(dev); - return; - } - - perf = nouveau_perf_table(dev, &ver); - if (ver >= 0x20 && ver < 0x40) - pm->fan.pwm_divisor = ROM16(perf[6]); - - while ((perf = nouveau_perf_entry(dev, ++i, &ver, &hdr, &cnt, &len))) { - struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl]; - - if (perf[0] == 0xff) - continue; - - switch (ver) { - case 0x12: - case 0x13: - case 0x15: - perflvl->fanspeed = perf[55]; - if (hdr > 56) - perflvl->volt_min = perf[56]; - perflvl->core = ROM32(perf[1]) * 10; - perflvl->memory = ROM32(perf[5]) * 20; - break; - case 0x21: - case 0x23: - case 0x24: - perflvl->fanspeed = perf[4]; - perflvl->volt_min = perf[5]; - perflvl->shader = ROM16(perf[6]) * 1000; - perflvl->core = perflvl->shader; - perflvl->core += (signed char)perf[8] * 1000; - if (dev_priv->chipset == 0x49 || - dev_priv->chipset == 0x4b) - perflvl->memory = ROM16(perf[11]) * 1000; - else - perflvl->memory = ROM16(perf[11]) * 2000; - break; - case 0x25: - perflvl->fanspeed = perf[4]; - perflvl->volt_min = perf[5]; - perflvl->core = ROM16(perf[6]) * 1000; - perflvl->shader = ROM16(perf[10]) * 1000; - perflvl->memory = ROM16(perf[12]) * 1000; - break; - case 0x30: - perflvl->memscript = ROM16(perf[2]); - case 0x35: - perflvl->fanspeed = perf[6]; - perflvl->volt_min = perf[7]; - perflvl->core = ROM16(perf[8]) * 1000; - perflvl->shader = ROM16(perf[10]) * 1000; - perflvl->memory = ROM16(perf[12]) * 1000; - perflvl->vdec = ROM16(perf[16]) * 1000; - perflvl->dom6 = ROM16(perf[20]) * 1000; - break; - case 0x40: -#define subent(n) ((ROM16(perf[hdr + (n) * len]) & 0xfff) * 1000) - perflvl->fanspeed = 0; /*XXX*/ - perflvl->volt_min = perf[2]; - if (dev_priv->card_type == NV_50) { - perflvl->core = subent(0); - perflvl->shader = subent(1); - perflvl->memory = subent(2); - perflvl->vdec = subent(3); - perflvl->unka0 = subent(4); - } else { - perflvl->hub06 = subent(0); - perflvl->hub01 = subent(1); - perflvl->copy = subent(2); - perflvl->shader = subent(3); - perflvl->rop = subent(4); - perflvl->memory = subent(5); - perflvl->vdec = subent(6); - perflvl->daemon = subent(10); - perflvl->hub07 = subent(11); - perflvl->core = perflvl->shader / 2; - } - break; - } - - /* make sure vid is valid */ - nouveau_perf_voltage(dev, perflvl); - if (pm->voltage.supported && perflvl->volt_min) { - vid = nouveau_volt_vid_lookup(dev, perflvl->volt_min); - if (vid < 0) { - NV_DEBUG(dev, "perflvl %d, bad vid\n", i); - continue; - } - } - - /* get the corresponding memory timings */ - ret = nouveau_mem_timing_calc(dev, perflvl->memory, - &perflvl->timing); - if (ret) { - NV_DEBUG(dev, "perflvl %d, bad timing: %d\n", i, ret); - continue; - } - - snprintf(perflvl->name, sizeof(perflvl->name), - "performance_level_%d", i); - perflvl->id = i; - - snprintf(perflvl->profile.name, sizeof(perflvl->profile.name), - "%d", perflvl->id); - perflvl->profile.func = &nouveau_pm_static_profile_func; - list_add_tail(&perflvl->profile.head, &pm->profiles); - - - pm->nr_perflvl++; - } -} - -void -nouveau_perf_fini(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.c deleted file mode 100644 index da3e7c3a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_pm.h" -#include "nouveau_gpio.h" - -#ifdef CONFIG_ACPI -#include -#endif -#include -#include -#include - -static int -nouveau_pwmfan_get(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct gpio_func gpio; - u32 divs, duty; - int ret; - - if (!pm->pwm_get) - return -ENODEV; - - ret = nouveau_gpio_find(dev, 0, DCB_GPIO_PWM_FAN, 0xff, &gpio); - if (ret == 0) { - ret = pm->pwm_get(dev, gpio.line, &divs, &duty); - if (ret == 0 && divs) { - divs = max(divs, duty); - if (dev_priv->card_type <= NV_40 || (gpio.log[0] & 1)) - duty = divs - duty; - return (duty * 100) / divs; - } - - return nouveau_gpio_func_get(dev, gpio.func) * 100; - } - - return -ENODEV; -} - -static int -nouveau_pwmfan_set(struct drm_device *dev, int percent) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct gpio_func gpio; - u32 divs, duty; - int ret; - - if (!pm->pwm_set) - return -ENODEV; - - ret = nouveau_gpio_find(dev, 0, DCB_GPIO_PWM_FAN, 0xff, &gpio); - if (ret == 0) { - divs = pm->fan.pwm_divisor; - if (pm->fan.pwm_freq) { - /*XXX: PNVIO clock more than likely... */ - divs = 135000 / pm->fan.pwm_freq; - if (dev_priv->chipset < 0xa3) - divs /= 4; - } - - duty = ((divs * percent) + 99) / 100; - if (dev_priv->card_type <= NV_40 || (gpio.log[0] & 1)) - duty = divs - duty; - - ret = pm->pwm_set(dev, gpio.line, divs, duty); - if (!ret) - pm->fan.percent = percent; - return ret; - } - - return -ENODEV; -} - -static int -nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl, - struct nouveau_pm_level *a, struct nouveau_pm_level *b) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - int ret; - - /*XXX: not on all boards, we should control based on temperature - * on recent boards.. or maybe on some other factor we don't - * know about? - */ - if (a->fanspeed && b->fanspeed && b->fanspeed > a->fanspeed) { - ret = nouveau_pwmfan_set(dev, perflvl->fanspeed); - if (ret && ret != -ENODEV) { - NV_ERROR(dev, "fanspeed set failed: %d\n", ret); - return ret; - } - } - - if (pm->voltage.supported && pm->voltage_set) { - if (perflvl->volt_min && b->volt_min > a->volt_min) { - ret = pm->voltage_set(dev, perflvl->volt_min); - if (ret) { - NV_ERROR(dev, "voltage set failed: %d\n", ret); - return ret; - } - } - } - - return 0; -} - -static int -nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - void *state; - int ret; - - if (perflvl == pm->cur) - return 0; - - ret = nouveau_pm_perflvl_aux(dev, perflvl, pm->cur, perflvl); - if (ret) - return ret; - - state = pm->clocks_pre(dev, perflvl); - if (IS_ERR(state)) { - ret = PTR_ERR(state); - goto error; - } - ret = pm->clocks_set(dev, state); - if (ret) - goto error; - - ret = nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur); - if (ret) - return ret; - - pm->cur = perflvl; - return 0; - -error: - /* restore the fan speed and voltage before leaving */ - nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur); - return ret; -} - -void -nouveau_pm_trigger(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_profile *profile = NULL; - struct nouveau_pm_level *perflvl = NULL; - int ret; - - /* select power profile based on current power source */ - if (power_supply_is_system_supplied()) - profile = pm->profile_ac; - else - profile = pm->profile_dc; - - if (profile != pm->profile) { - pm->profile->func->fini(pm->profile); - pm->profile = profile; - pm->profile->func->init(pm->profile); - } - - /* select performance level based on profile */ - perflvl = profile->func->select(profile); - - /* change perflvl, if necessary */ - if (perflvl != pm->cur) { - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - u64 time0 = ptimer->read(dev); - - NV_INFO(dev, "setting performance level: %d", perflvl->id); - ret = nouveau_pm_perflvl_set(dev, perflvl); - if (ret) - NV_INFO(dev, "> reclocking failed: %d\n\n", ret); - - NV_INFO(dev, "> reclocking took %lluns\n\n", - ptimer->read(dev) - time0); - } -} - -static struct nouveau_pm_profile * -profile_find(struct drm_device *dev, const char *string) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_profile *profile; - - list_for_each_entry(profile, &pm->profiles, head) { - if (!strncmp(profile->name, string, sizeof(profile->name))) - return profile; - } - - return NULL; -} - -static int -nouveau_pm_profile_set(struct drm_device *dev, const char *profile) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_profile *ac = NULL, *dc = NULL; - char string[16], *cur = string, *ptr; - - /* safety precaution, for now */ - if (nouveau_perflvl_wr != 7777) - return -EPERM; - - strncpy(string, profile, sizeof(string)); - string[sizeof(string) - 1] = 0; - if ((ptr = strchr(string, '\n'))) - *ptr = '\0'; - - ptr = strsep(&cur, ","); - if (ptr) - ac = profile_find(dev, ptr); - - ptr = strsep(&cur, ","); - if (ptr) - dc = profile_find(dev, ptr); - else - dc = ac; - - if (ac == NULL || dc == NULL) - return -EINVAL; - - pm->profile_ac = ac; - pm->profile_dc = dc; - nouveau_pm_trigger(dev); - return 0; -} - -static void -nouveau_pm_static_dummy(struct nouveau_pm_profile *profile) -{ -} - -static struct nouveau_pm_level * -nouveau_pm_static_select(struct nouveau_pm_profile *profile) -{ - return container_of(profile, struct nouveau_pm_level, profile); -} - -const struct nouveau_pm_profile_func nouveau_pm_static_profile_func = { - .destroy = nouveau_pm_static_dummy, - .init = nouveau_pm_static_dummy, - .fini = nouveau_pm_static_dummy, - .select = nouveau_pm_static_select, -}; - -static int -nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - int ret; - - memset(perflvl, 0, sizeof(*perflvl)); - - if (pm->clocks_get) { - ret = pm->clocks_get(dev, perflvl); - if (ret) - return ret; - } - - if (pm->voltage.supported && pm->voltage_get) { - ret = pm->voltage_get(dev); - if (ret > 0) { - perflvl->volt_min = ret; - perflvl->volt_max = ret; - } - } - - ret = nouveau_pwmfan_get(dev); - if (ret > 0) - perflvl->fanspeed = ret; - - nouveau_mem_timing_read(dev, &perflvl->timing); - return 0; -} - -static void -nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) -{ - char c[16], s[16], v[32], f[16], m[16]; - - c[0] = '\0'; - if (perflvl->core) - snprintf(c, sizeof(c), " core %dMHz", perflvl->core / 1000); - - s[0] = '\0'; - if (perflvl->shader) - snprintf(s, sizeof(s), " shader %dMHz", perflvl->shader / 1000); - - m[0] = '\0'; - if (perflvl->memory) - snprintf(m, sizeof(m), " memory %dMHz", perflvl->memory / 1000); - - v[0] = '\0'; - if (perflvl->volt_min && perflvl->volt_min != perflvl->volt_max) { - snprintf(v, sizeof(v), " voltage %dmV-%dmV", - perflvl->volt_min / 1000, perflvl->volt_max / 1000); - } else - if (perflvl->volt_min) { - snprintf(v, sizeof(v), " voltage %dmV", - perflvl->volt_min / 1000); - } - - f[0] = '\0'; - if (perflvl->fanspeed) - snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed); - - snprintf(ptr, len, "%s%s%s%s%s\n", c, s, m, v, f); -} - -static ssize_t -nouveau_pm_get_perflvl_info(struct device *d, - struct device_attribute *a, char *buf) -{ - struct nouveau_pm_level *perflvl = - container_of(a, struct nouveau_pm_level, dev_attr); - char *ptr = buf; - int len = PAGE_SIZE; - - snprintf(ptr, len, "%d:", perflvl->id); - ptr += strlen(buf); - len -= strlen(buf); - - nouveau_pm_perflvl_info(perflvl, ptr, len); - return strlen(buf); -} - -static ssize_t -nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf) -{ - struct drm_device *dev = pci_get_drvdata(to_pci_dev(d)); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_level cur; - int len = PAGE_SIZE, ret; - char *ptr = buf; - - snprintf(ptr, len, "profile: %s, %s\nc:", - pm->profile_ac->name, pm->profile_dc->name); - ptr += strlen(buf); - len -= strlen(buf); - - ret = nouveau_pm_perflvl_get(dev, &cur); - if (ret == 0) - nouveau_pm_perflvl_info(&cur, ptr, len); - return strlen(buf); -} - -static ssize_t -nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = pci_get_drvdata(to_pci_dev(d)); - int ret; - - ret = nouveau_pm_profile_set(dev, buf); - if (ret) - return ret; - return strlen(buf); -} - -static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR, - nouveau_pm_get_perflvl, nouveau_pm_set_perflvl); - -static int -nouveau_sysfs_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct device *d = &dev->pdev->dev; - int ret, i; - - ret = device_create_file(d, &dev_attr_performance_level); - if (ret) - return ret; - - for (i = 0; i < pm->nr_perflvl; i++) { - struct nouveau_pm_level *perflvl = &pm->perflvl[i]; - - perflvl->dev_attr.attr.name = perflvl->name; - perflvl->dev_attr.attr.mode = S_IRUGO; - perflvl->dev_attr.show = nouveau_pm_get_perflvl_info; - perflvl->dev_attr.store = NULL; - sysfs_attr_init(&perflvl->dev_attr.attr); - - ret = device_create_file(d, &perflvl->dev_attr); - if (ret) { - NV_ERROR(dev, "failed pervlvl %d sysfs: %d\n", - perflvl->id, i); - perflvl->dev_attr.attr.name = NULL; - nouveau_pm_fini(dev); - return ret; - } - } - - return 0; -} - -static void -nouveau_sysfs_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct device *d = &dev->pdev->dev; - int i; - - device_remove_file(d, &dev_attr_performance_level); - for (i = 0; i < pm->nr_perflvl; i++) { - struct nouveau_pm_level *pl = &pm->perflvl[i]; - - if (!pl->dev_attr.attr.name) - break; - - device_remove_file(d, &pl->dev_attr); - } -} - -#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) -static ssize_t -nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - - return snprintf(buf, PAGE_SIZE, "%d\n", pm->temp_get(dev)*1000); -} -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp, - NULL, 0); - -static ssize_t -nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; - - return snprintf(buf, PAGE_SIZE, "%d\n", temp->down_clock*1000); -} -static ssize_t -nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - temp->down_clock = value/1000; - - nouveau_temp_safety_checks(dev); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp, - nouveau_hwmon_set_max_temp, - 0); - -static ssize_t -nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a, - char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; - - return snprintf(buf, PAGE_SIZE, "%d\n", temp->critical*1000); -} -static ssize_t -nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a, - const char *buf, - size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_threshold_temp *temp = &pm->threshold_temp; - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return count; - - temp->critical = value/1000; - - nouveau_temp_safety_checks(dev); - - return count; -} -static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, - nouveau_hwmon_critical_temp, - nouveau_hwmon_set_critical_temp, - 0); - -static ssize_t nouveau_hwmon_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "nouveau\n"); -} -static SENSOR_DEVICE_ATTR(name, S_IRUGO, nouveau_hwmon_show_name, NULL, 0); - -static ssize_t nouveau_hwmon_show_update_rate(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "1000\n"); -} -static SENSOR_DEVICE_ATTR(update_rate, S_IRUGO, - nouveau_hwmon_show_update_rate, - NULL, 0); - -static ssize_t -nouveau_hwmon_show_fan0_input(struct device *d, struct device_attribute *attr, - char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - struct gpio_func gpio; - u32 cycles, cur, prev; - u64 start; - int ret; - - ret = nouveau_gpio_find(dev, 0, DCB_GPIO_FAN_SENSE, 0xff, &gpio); - if (ret) - return ret; - - /* Monitor the GPIO input 0x3b for 250ms. - * When the fan spins, it changes the value of GPIO FAN_SENSE. - * We get 4 changes (0 -> 1 -> 0 -> 1 -> [...]) per complete rotation. - */ - start = ptimer->read(dev); - prev = nouveau_gpio_sense(dev, 0, gpio.line); - cycles = 0; - do { - cur = nouveau_gpio_sense(dev, 0, gpio.line); - if (prev != cur) { - cycles++; - prev = cur; - } - - usleep_range(500, 1000); /* supports 0 < rpm < 7500 */ - } while (ptimer->read(dev) - start < 250000000); - - /* interpolate to get rpm */ - return sprintf(buf, "%i\n", cycles / 4 * 4 * 60); -} -static SENSOR_DEVICE_ATTR(fan0_input, S_IRUGO, nouveau_hwmon_show_fan0_input, - NULL, 0); - -static ssize_t -nouveau_hwmon_get_pwm0(struct device *d, struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - int ret; - - ret = nouveau_pwmfan_get(dev); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", ret); -} - -static ssize_t -nouveau_hwmon_set_pwm0(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - int ret = -ENODEV; - long value; - - if (nouveau_perflvl_wr != 7777) - return -EPERM; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return -EINVAL; - - if (value < pm->fan.min_duty) - value = pm->fan.min_duty; - if (value > pm->fan.max_duty) - value = pm->fan.max_duty; - - ret = nouveau_pwmfan_set(dev, value); - if (ret) - return ret; - - return count; -} - -static SENSOR_DEVICE_ATTR(pwm0, S_IRUGO | S_IWUSR, - nouveau_hwmon_get_pwm0, - nouveau_hwmon_set_pwm0, 0); - -static ssize_t -nouveau_hwmon_get_pwm0_min(struct device *d, - struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - - return sprintf(buf, "%i\n", pm->fan.min_duty); -} - -static ssize_t -nouveau_hwmon_set_pwm0_min(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return -EINVAL; - - if (value < 0) - value = 0; - - if (pm->fan.max_duty - value < 10) - value = pm->fan.max_duty - 10; - - if (value < 10) - pm->fan.min_duty = 10; - else - pm->fan.min_duty = value; - - return count; -} - -static SENSOR_DEVICE_ATTR(pwm0_min, S_IRUGO | S_IWUSR, - nouveau_hwmon_get_pwm0_min, - nouveau_hwmon_set_pwm0_min, 0); - -static ssize_t -nouveau_hwmon_get_pwm0_max(struct device *d, - struct device_attribute *a, char *buf) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - - return sprintf(buf, "%i\n", pm->fan.max_duty); -} - -static ssize_t -nouveau_hwmon_set_pwm0_max(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct drm_device *dev = dev_get_drvdata(d); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - long value; - - if (kstrtol(buf, 10, &value) == -EINVAL) - return -EINVAL; - - if (value < 0) - value = 0; - - if (value - pm->fan.min_duty < 10) - value = pm->fan.min_duty + 10; - - if (value > 100) - pm->fan.max_duty = 100; - else - pm->fan.max_duty = value; - - return count; -} - -static SENSOR_DEVICE_ATTR(pwm0_max, S_IRUGO | S_IWUSR, - nouveau_hwmon_get_pwm0_max, - nouveau_hwmon_set_pwm0_max, 0); - -static struct attribute *hwmon_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_crit.dev_attr.attr, - &sensor_dev_attr_name.dev_attr.attr, - &sensor_dev_attr_update_rate.dev_attr.attr, - NULL -}; -static struct attribute *hwmon_fan_rpm_attributes[] = { - &sensor_dev_attr_fan0_input.dev_attr.attr, - NULL -}; -static struct attribute *hwmon_pwm_fan_attributes[] = { - &sensor_dev_attr_pwm0.dev_attr.attr, - &sensor_dev_attr_pwm0_min.dev_attr.attr, - &sensor_dev_attr_pwm0_max.dev_attr.attr, - NULL -}; - -static const struct attribute_group hwmon_attrgroup = { - .attrs = hwmon_attributes, -}; -static const struct attribute_group hwmon_fan_rpm_attrgroup = { - .attrs = hwmon_fan_rpm_attributes, -}; -static const struct attribute_group hwmon_pwm_fan_attrgroup = { - .attrs = hwmon_pwm_fan_attributes, -}; -#endif - -static int -nouveau_hwmon_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; -#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) - struct device *hwmon_dev; - int ret = 0; - - if (!pm->temp_get) - return -ENODEV; - - hwmon_dev = hwmon_device_register(&dev->pdev->dev); - if (IS_ERR(hwmon_dev)) { - ret = PTR_ERR(hwmon_dev); - NV_ERROR(dev, - "Unable to register hwmon device: %d\n", ret); - return ret; - } - dev_set_drvdata(hwmon_dev, dev); - - /* default sysfs entries */ - ret = sysfs_create_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); - if (ret) { - if (ret) - goto error; - } - - /* if the card has a pwm fan */ - /*XXX: incorrect, need better detection for this, some boards have - * the gpio entries for pwm fan control even when there's no - * actual fan connected to it... therm table? */ - if (nouveau_pwmfan_get(dev) >= 0) { - ret = sysfs_create_group(&dev->pdev->dev.kobj, - &hwmon_pwm_fan_attrgroup); - if (ret) - goto error; - } - - /* if the card can read the fan rpm */ - if (nouveau_gpio_func_valid(dev, DCB_GPIO_FAN_SENSE)) { - ret = sysfs_create_group(&dev->pdev->dev.kobj, - &hwmon_fan_rpm_attrgroup); - if (ret) - goto error; - } - - pm->hwmon = hwmon_dev; - - return 0; - -error: - NV_ERROR(dev, "Unable to create some hwmon sysfs files: %d\n", ret); - hwmon_device_unregister(hwmon_dev); - pm->hwmon = NULL; - return ret; -#else - pm->hwmon = NULL; - return 0; -#endif -} - -static void -nouveau_hwmon_fini(struct drm_device *dev) -{ -#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - - if (pm->hwmon) { - sysfs_remove_group(&dev->pdev->dev.kobj, &hwmon_attrgroup); - sysfs_remove_group(&dev->pdev->dev.kobj, - &hwmon_pwm_fan_attrgroup); - sysfs_remove_group(&dev->pdev->dev.kobj, - &hwmon_fan_rpm_attrgroup); - - hwmon_device_unregister(pm->hwmon); - } -#endif -} - -#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) -static int -nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data) -{ - struct drm_nouveau_private *dev_priv = - container_of(nb, struct drm_nouveau_private, engine.pm.acpi_nb); - struct drm_device *dev = dev_priv->dev; - struct acpi_bus_event *entry = (struct acpi_bus_event *)data; - - if (strcmp(entry->device_class, "ac_adapter") == 0) { - bool ac = power_supply_is_system_supplied(); - - NV_DEBUG(dev, "power supply changed: %s\n", ac ? "AC" : "DC"); - nouveau_pm_trigger(dev); - } - - return NOTIFY_OK; -} -#endif - -int -nouveau_pm_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - char info[256]; - int ret, i; - - /* parse aux tables from vbios */ - nouveau_volt_init(dev); - nouveau_temp_init(dev); - - /* determine current ("boot") performance level */ - ret = nouveau_pm_perflvl_get(dev, &pm->boot); - if (ret) { - NV_ERROR(dev, "failed to determine boot perflvl\n"); - return ret; - } - - strncpy(pm->boot.name, "boot", 4); - strncpy(pm->boot.profile.name, "boot", 4); - pm->boot.profile.func = &nouveau_pm_static_profile_func; - - INIT_LIST_HEAD(&pm->profiles); - list_add(&pm->boot.profile.head, &pm->profiles); - - pm->profile_ac = &pm->boot.profile; - pm->profile_dc = &pm->boot.profile; - pm->profile = &pm->boot.profile; - pm->cur = &pm->boot; - - /* add performance levels from vbios */ - nouveau_perf_init(dev); - - /* display available performance levels */ - NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl); - for (i = 0; i < pm->nr_perflvl; i++) { - nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info)); - NV_INFO(dev, "%d:%s", pm->perflvl[i].id, info); - } - - nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info)); - NV_INFO(dev, "c:%s", info); - - /* switch performance levels now if requested */ - if (nouveau_perflvl != NULL) - nouveau_pm_profile_set(dev, nouveau_perflvl); - - /* determine the current fan speed */ - pm->fan.percent = nouveau_pwmfan_get(dev); - - nouveau_sysfs_init(dev); - nouveau_hwmon_init(dev); -#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) - pm->acpi_nb.notifier_call = nouveau_pm_acpi_event; - register_acpi_notifier(&pm->acpi_nb); -#endif - - return 0; -} - -void -nouveau_pm_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_profile *profile, *tmp; - - list_for_each_entry_safe(profile, tmp, &pm->profiles, head) { - list_del(&profile->head); - profile->func->destroy(profile); - } - - if (pm->cur != &pm->boot) - nouveau_pm_perflvl_set(dev, &pm->boot); - - nouveau_temp_fini(dev); - nouveau_perf_fini(dev); - nouveau_volt_fini(dev); - -#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) - unregister_acpi_notifier(&pm->acpi_nb); -#endif - nouveau_hwmon_fini(dev); - nouveau_sysfs_fini(dev); -} - -void -nouveau_pm_resume(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_level *perflvl; - - if (!pm->cur || pm->cur == &pm->boot) - return; - - perflvl = pm->cur; - pm->cur = &pm->boot; - nouveau_pm_perflvl_set(dev, perflvl); - nouveau_pwmfan_set(dev, pm->fan.percent); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.h deleted file mode 100644 index 3f82dfea..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_pm.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#ifndef __NOUVEAU_PM_H__ -#define __NOUVEAU_PM_H__ - -struct nouveau_mem_exec_func { - struct drm_device *dev; - void (*precharge)(struct nouveau_mem_exec_func *); - void (*refresh)(struct nouveau_mem_exec_func *); - void (*refresh_auto)(struct nouveau_mem_exec_func *, bool); - void (*refresh_self)(struct nouveau_mem_exec_func *, bool); - void (*wait)(struct nouveau_mem_exec_func *, u32 nsec); - u32 (*mrg)(struct nouveau_mem_exec_func *, int mr); - void (*mrs)(struct nouveau_mem_exec_func *, int mr, u32 data); - void (*clock_set)(struct nouveau_mem_exec_func *); - void (*timing_set)(struct nouveau_mem_exec_func *); - void *priv; -}; - -/* nouveau_mem.c */ -int nouveau_mem_exec(struct nouveau_mem_exec_func *, - struct nouveau_pm_level *); - -/* nouveau_pm.c */ -int nouveau_pm_init(struct drm_device *dev); -void nouveau_pm_fini(struct drm_device *dev); -void nouveau_pm_resume(struct drm_device *dev); -extern const struct nouveau_pm_profile_func nouveau_pm_static_profile_func; -void nouveau_pm_trigger(struct drm_device *dev); - -/* nouveau_volt.c */ -void nouveau_volt_init(struct drm_device *); -void nouveau_volt_fini(struct drm_device *); -int nouveau_volt_vid_lookup(struct drm_device *, int voltage); -int nouveau_volt_lvl_lookup(struct drm_device *, int vid); -int nouveau_voltage_gpio_get(struct drm_device *); -int nouveau_voltage_gpio_set(struct drm_device *, int voltage); - -/* nouveau_perf.c */ -void nouveau_perf_init(struct drm_device *); -void nouveau_perf_fini(struct drm_device *); -u8 *nouveau_perf_timing(struct drm_device *, u32 freq, u8 *ver, u8 *len); -u8 *nouveau_perf_ramcfg(struct drm_device *, u32 freq, u8 *ver, u8 *len); - -/* nouveau_mem.c */ -void nouveau_mem_timing_init(struct drm_device *); -void nouveau_mem_timing_fini(struct drm_device *); - -/* nv04_pm.c */ -int nv04_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); -void *nv04_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); -int nv04_pm_clocks_set(struct drm_device *, void *); - -/* nv40_pm.c */ -int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); -void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); -int nv40_pm_clocks_set(struct drm_device *, void *); -int nv40_pm_pwm_get(struct drm_device *, int, u32 *, u32 *); -int nv40_pm_pwm_set(struct drm_device *, int, u32, u32); - -/* nv50_pm.c */ -int nv50_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); -void *nv50_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); -int nv50_pm_clocks_set(struct drm_device *, void *); -int nv50_pm_pwm_get(struct drm_device *, int, u32 *, u32 *); -int nv50_pm_pwm_set(struct drm_device *, int, u32, u32); - -/* nva3_pm.c */ -int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); -void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); -int nva3_pm_clocks_set(struct drm_device *, void *); - -/* nvc0_pm.c */ -int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); -void *nvc0_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); -int nvc0_pm_clocks_set(struct drm_device *, void *); - -/* nouveau_temp.c */ -void nouveau_temp_init(struct drm_device *dev); -void nouveau_temp_fini(struct drm_device *dev); -void nouveau_temp_safety_checks(struct drm_device *dev); -int nv40_temp_get(struct drm_device *dev); -int nv84_temp_get(struct drm_device *dev); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.c deleted file mode 100644 index a24a81f5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_ramht.h" - -static u32 -nouveau_ramht_hash_handle(struct nouveau_channel *chan, u32 handle) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_ramht *ramht = chan->ramht; - u32 hash = 0; - int i; - - NV_DEBUG(dev, "ch%d handle=0x%08x\n", chan->id, handle); - - for (i = 32; i > 0; i -= ramht->bits) { - hash ^= (handle & ((1 << ramht->bits) - 1)); - handle >>= ramht->bits; - } - - if (dev_priv->card_type < NV_50) - hash ^= chan->id << (ramht->bits - 4); - hash <<= 3; - - NV_DEBUG(dev, "hash=0x%08x\n", hash); - return hash; -} - -static int -nouveau_ramht_entry_valid(struct drm_device *dev, struct nouveau_gpuobj *ramht, - u32 offset) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 ctx = nv_ro32(ramht, offset + 4); - - if (dev_priv->card_type < NV_40) - return ((ctx & NV_RAMHT_CONTEXT_VALID) != 0); - return (ctx != 0); -} - -static int -nouveau_ramht_entry_same_channel(struct nouveau_channel *chan, - struct nouveau_gpuobj *ramht, u32 offset) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - u32 ctx = nv_ro32(ramht, offset + 4); - - if (dev_priv->card_type >= NV_50) - return true; - else if (dev_priv->card_type >= NV_40) - return chan->id == - ((ctx >> NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f); - else - return chan->id == - ((ctx >> NV_RAMHT_CONTEXT_CHANNEL_SHIFT) & 0x1f); -} - -int -nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, - struct nouveau_gpuobj *gpuobj) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; - struct nouveau_ramht_entry *entry; - struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; - unsigned long flags; - u32 ctx, co, ho; - - if (nouveau_ramht_find(chan, handle)) - return -EEXIST; - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; - entry->channel = chan; - entry->gpuobj = NULL; - entry->handle = handle; - nouveau_gpuobj_ref(gpuobj, &entry->gpuobj); - - if (dev_priv->card_type < NV_40) { - ctx = NV_RAMHT_CONTEXT_VALID | (gpuobj->pinst >> 4) | - (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | - (gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); - } else - if (dev_priv->card_type < NV_50) { - ctx = (gpuobj->pinst >> 4) | - (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | - (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); - } else { - if (gpuobj->engine == NVOBJ_ENGINE_DISPLAY) { - ctx = (gpuobj->cinst << 10) | - (chan->id << 28) | - chan->id; /* HASH_TAG */ - } else { - ctx = (gpuobj->cinst >> 4) | - ((gpuobj->engine << - NV40_RAMHT_CONTEXT_ENGINE_SHIFT)); - } - } - - spin_lock_irqsave(&chan->ramht->lock, flags); - list_add(&entry->head, &chan->ramht->entries); - - co = ho = nouveau_ramht_hash_handle(chan, handle); - do { - if (!nouveau_ramht_entry_valid(dev, ramht, co)) { - NV_DEBUG(dev, - "insert ch%d 0x%08x: h=0x%08x, c=0x%08x\n", - chan->id, co, handle, ctx); - nv_wo32(ramht, co + 0, handle); - nv_wo32(ramht, co + 4, ctx); - - spin_unlock_irqrestore(&chan->ramht->lock, flags); - instmem->flush(dev); - return 0; - } - NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n", - chan->id, co, nv_ro32(ramht, co)); - - co += 8; - if (co >= ramht->size) - co = 0; - } while (co != ho); - - NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id); - list_del(&entry->head); - spin_unlock_irqrestore(&chan->ramht->lock, flags); - kfree(entry); - return -ENOMEM; -} - -static struct nouveau_ramht_entry * -nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle) -{ - struct nouveau_ramht *ramht = chan ? chan->ramht : NULL; - struct nouveau_ramht_entry *entry; - unsigned long flags; - - if (!ramht) - return NULL; - - spin_lock_irqsave(&ramht->lock, flags); - list_for_each_entry(entry, &ramht->entries, head) { - if (entry->channel == chan && - (!handle || entry->handle == handle)) { - list_del(&entry->head); - spin_unlock_irqrestore(&ramht->lock, flags); - - return entry; - } - } - spin_unlock_irqrestore(&ramht->lock, flags); - - return NULL; -} - -static void -nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; - struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; - unsigned long flags; - u32 co, ho; - - spin_lock_irqsave(&chan->ramht->lock, flags); - co = ho = nouveau_ramht_hash_handle(chan, handle); - do { - if (nouveau_ramht_entry_valid(dev, ramht, co) && - nouveau_ramht_entry_same_channel(chan, ramht, co) && - (handle == nv_ro32(ramht, co))) { - NV_DEBUG(dev, - "remove ch%d 0x%08x: h=0x%08x, c=0x%08x\n", - chan->id, co, handle, nv_ro32(ramht, co + 4)); - nv_wo32(ramht, co + 0, 0x00000000); - nv_wo32(ramht, co + 4, 0x00000000); - instmem->flush(dev); - goto out; - } - - co += 8; - if (co >= ramht->size) - co = 0; - } while (co != ho); - - NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", - chan->id, handle); -out: - spin_unlock_irqrestore(&chan->ramht->lock, flags); -} - -int -nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle) -{ - struct nouveau_ramht_entry *entry; - - entry = nouveau_ramht_remove_entry(chan, handle); - if (!entry) - return -ENOENT; - - nouveau_ramht_remove_hash(chan, entry->handle); - nouveau_gpuobj_ref(NULL, &entry->gpuobj); - kfree(entry); - return 0; -} - -struct nouveau_gpuobj * -nouveau_ramht_find(struct nouveau_channel *chan, u32 handle) -{ - struct nouveau_ramht *ramht = chan->ramht; - struct nouveau_ramht_entry *entry; - struct nouveau_gpuobj *gpuobj = NULL; - unsigned long flags; - - if (unlikely(!chan->ramht)) - return NULL; - - spin_lock_irqsave(&ramht->lock, flags); - list_for_each_entry(entry, &chan->ramht->entries, head) { - if (entry->channel == chan && entry->handle == handle) { - gpuobj = entry->gpuobj; - break; - } - } - spin_unlock_irqrestore(&ramht->lock, flags); - - return gpuobj; -} - -int -nouveau_ramht_new(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - struct nouveau_ramht **pramht) -{ - struct nouveau_ramht *ramht; - - ramht = kzalloc(sizeof(*ramht), GFP_KERNEL); - if (!ramht) - return -ENOMEM; - - ramht->dev = dev; - kref_init(&ramht->refcount); - ramht->bits = drm_order(gpuobj->size / 8); - INIT_LIST_HEAD(&ramht->entries); - spin_lock_init(&ramht->lock); - nouveau_gpuobj_ref(gpuobj, &ramht->gpuobj); - - *pramht = ramht; - return 0; -} - -static void -nouveau_ramht_del(struct kref *ref) -{ - struct nouveau_ramht *ramht = - container_of(ref, struct nouveau_ramht, refcount); - - nouveau_gpuobj_ref(NULL, &ramht->gpuobj); - kfree(ramht); -} - -void -nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr, - struct nouveau_channel *chan) -{ - struct nouveau_ramht_entry *entry; - struct nouveau_ramht *ramht; - - if (ref) - kref_get(&ref->refcount); - - ramht = *ptr; - if (ramht) { - while ((entry = nouveau_ramht_remove_entry(chan, 0))) { - nouveau_ramht_remove_hash(chan, entry->handle); - nouveau_gpuobj_ref(NULL, &entry->gpuobj); - kfree(entry); - } - - kref_put(&ramht->refcount, nouveau_ramht_del); - } - *ptr = ref; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.h deleted file mode 100644 index c82de98f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ramht.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#ifndef __NOUVEAU_RAMHT_H__ -#define __NOUVEAU_RAMHT_H__ - -struct nouveau_ramht_entry { - struct list_head head; - struct nouveau_channel *channel; - struct nouveau_gpuobj *gpuobj; - u32 handle; -}; - -struct nouveau_ramht { - struct drm_device *dev; - struct kref refcount; - spinlock_t lock; - struct nouveau_gpuobj *gpuobj; - struct list_head entries; - int bits; -}; - -extern int nouveau_ramht_new(struct drm_device *, struct nouveau_gpuobj *, - struct nouveau_ramht **); -extern void nouveau_ramht_ref(struct nouveau_ramht *, struct nouveau_ramht **, - struct nouveau_channel *unref_channel); - -extern int nouveau_ramht_insert(struct nouveau_channel *, u32 handle, - struct nouveau_gpuobj *); -extern int nouveau_ramht_remove(struct nouveau_channel *, u32 handle); -extern struct nouveau_gpuobj * -nouveau_ramht_find(struct nouveau_channel *chan, u32 handle); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_reg.h deleted file mode 100644 index 43a96b99..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_reg.h +++ /dev/null @@ -1,858 +0,0 @@ - -#define NV04_PFB_BOOT_0 0x00100000 -# define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003 -# define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 -# define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 -# define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 -# define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 -# define NV04_PFB_BOOT_0_RAM_WIDTH_128 0x00000004 -# define NV04_PFB_BOOT_0_RAM_TYPE 0x00000028 -# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x00000000 -# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x00000008 -# define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x00000010 -# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x00000018 -# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x00000020 -# define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x00000028 -# define NV04_PFB_BOOT_0_UMA_ENABLE 0x00000100 -# define NV04_PFB_BOOT_0_UMA_SIZE 0x0000f000 -#define NV04_PFB_DEBUG_0 0x00100080 -# define NV04_PFB_DEBUG_0_PAGE_MODE 0x00000001 -# define NV04_PFB_DEBUG_0_REFRESH_OFF 0x00000010 -# define NV04_PFB_DEBUG_0_REFRESH_COUNTX64 0x00003f00 -# define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK 0x00004000 -# define NV04_PFB_DEBUG_0_SAFE_MODE 0x00008000 -# define NV04_PFB_DEBUG_0_ALOM_ENABLE 0x00010000 -# define NV04_PFB_DEBUG_0_CASOE 0x00100000 -# define NV04_PFB_DEBUG_0_CKE_INVERT 0x10000000 -# define NV04_PFB_DEBUG_0_REFINC 0x20000000 -# define NV04_PFB_DEBUG_0_SAVE_POWER_OFF 0x40000000 -#define NV04_PFB_CFG0 0x00100200 -# define NV04_PFB_CFG0_SCRAMBLE 0x20000000 -#define NV04_PFB_CFG1 0x00100204 -#define NV04_PFB_FIFO_DATA 0x0010020c -# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000 -# define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20 -#define NV10_PFB_REFCTRL 0x00100210 -# define NV10_PFB_REFCTRL_VALID_1 (1 << 31) -#define NV04_PFB_PAD 0x0010021c -# define NV04_PFB_PAD_CKE_NORMAL (1 << 0) -#define NV10_PFB_TILE(i) (0x00100240 + (i*16)) -#define NV10_PFB_TILE__SIZE 8 -#define NV10_PFB_TLIMIT(i) (0x00100244 + (i*16)) -#define NV10_PFB_TSIZE(i) (0x00100248 + (i*16)) -#define NV10_PFB_TSTATUS(i) (0x0010024c + (i*16)) -#define NV04_PFB_REF 0x001002d0 -# define NV04_PFB_REF_CMD_REFRESH (1 << 0) -#define NV04_PFB_PRE 0x001002d4 -# define NV04_PFB_PRE_CMD_PRECHARGE (1 << 0) -#define NV20_PFB_ZCOMP(i) (0x00100300 + 4*(i)) -# define NV20_PFB_ZCOMP_MODE_32 (4 << 24) -# define NV20_PFB_ZCOMP_EN (1 << 31) -# define NV25_PFB_ZCOMP_MODE_16 (1 << 20) -# define NV25_PFB_ZCOMP_MODE_32 (2 << 20) -#define NV10_PFB_CLOSE_PAGE2 0x0010033c -#define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i)) -#define NV40_PFB_TILE(i) (0x00100600 + (i*16)) -#define NV40_PFB_TILE__SIZE_0 12 -#define NV40_PFB_TILE__SIZE_1 15 -#define NV40_PFB_TLIMIT(i) (0x00100604 + (i*16)) -#define NV40_PFB_TSIZE(i) (0x00100608 + (i*16)) -#define NV40_PFB_TSTATUS(i) (0x0010060c + (i*16)) -#define NV40_PFB_UNK_800 0x00100800 - -#define NV_PEXTDEV_BOOT_0 0x00101000 -#define NV_PEXTDEV_BOOT_0_RAMCFG 0x0000003c -# define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT (8 << 12) -#define NV_PEXTDEV_BOOT_3 0x0010100c - -#define NV_RAMIN 0x00700000 - -#define NV_RAMHT_HANDLE_OFFSET 0 -#define NV_RAMHT_CONTEXT_OFFSET 4 -# define NV_RAMHT_CONTEXT_VALID (1<<31) -# define NV_RAMHT_CONTEXT_CHANNEL_SHIFT 24 -# define NV_RAMHT_CONTEXT_ENGINE_SHIFT 16 -# define NV_RAMHT_CONTEXT_ENGINE_SOFTWARE 0 -# define NV_RAMHT_CONTEXT_ENGINE_GRAPHICS 1 -# define NV_RAMHT_CONTEXT_INSTANCE_SHIFT 0 -# define NV40_RAMHT_CONTEXT_CHANNEL_SHIFT 23 -# define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 -# define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 - -/* Some object classes we care about in the drm */ -#define NV_CLASS_DMA_FROM_MEMORY 0x00000002 -#define NV_CLASS_DMA_TO_MEMORY 0x00000003 -#define NV_CLASS_NULL 0x00000030 -#define NV_CLASS_DMA_IN_MEMORY 0x0000003D - -#define NV03_USER(i) (0x00800000+(i*NV03_USER_SIZE)) -#define NV03_USER__SIZE 16 -#define NV10_USER__SIZE 32 -#define NV03_USER_SIZE 0x00010000 -#define NV03_USER_DMA_PUT(i) (0x00800040+(i*NV03_USER_SIZE)) -#define NV03_USER_DMA_PUT__SIZE 16 -#define NV10_USER_DMA_PUT__SIZE 32 -#define NV03_USER_DMA_GET(i) (0x00800044+(i*NV03_USER_SIZE)) -#define NV03_USER_DMA_GET__SIZE 16 -#define NV10_USER_DMA_GET__SIZE 32 -#define NV03_USER_REF_CNT(i) (0x00800048+(i*NV03_USER_SIZE)) -#define NV03_USER_REF_CNT__SIZE 16 -#define NV10_USER_REF_CNT__SIZE 32 - -#define NV40_USER(i) (0x00c00000+(i*NV40_USER_SIZE)) -#define NV40_USER_SIZE 0x00001000 -#define NV40_USER_DMA_PUT(i) (0x00c00040+(i*NV40_USER_SIZE)) -#define NV40_USER_DMA_PUT__SIZE 32 -#define NV40_USER_DMA_GET(i) (0x00c00044+(i*NV40_USER_SIZE)) -#define NV40_USER_DMA_GET__SIZE 32 -#define NV40_USER_REF_CNT(i) (0x00c00048+(i*NV40_USER_SIZE)) -#define NV40_USER_REF_CNT__SIZE 32 - -#define NV50_USER(i) (0x00c00000+(i*NV50_USER_SIZE)) -#define NV50_USER_SIZE 0x00002000 -#define NV50_USER_DMA_PUT(i) (0x00c00040+(i*NV50_USER_SIZE)) -#define NV50_USER_DMA_PUT__SIZE 128 -#define NV50_USER_DMA_GET(i) (0x00c00044+(i*NV50_USER_SIZE)) -#define NV50_USER_DMA_GET__SIZE 128 -#define NV50_USER_REF_CNT(i) (0x00c00048+(i*NV50_USER_SIZE)) -#define NV50_USER_REF_CNT__SIZE 128 - -#define NV03_FIFO_SIZE 0x8000UL - -#define NV03_PMC_BOOT_0 0x00000000 -#define NV03_PMC_BOOT_1 0x00000004 -#define NV03_PMC_INTR_0 0x00000100 -# define NV_PMC_INTR_0_PFIFO_PENDING (1<<8) -# define NV_PMC_INTR_0_PGRAPH_PENDING (1<<12) -# define NV_PMC_INTR_0_NV50_I2C_PENDING (1<<21) -# define NV_PMC_INTR_0_CRTC0_PENDING (1<<24) -# define NV_PMC_INTR_0_CRTC1_PENDING (1<<25) -# define NV_PMC_INTR_0_NV50_DISPLAY_PENDING (1<<26) -# define NV_PMC_INTR_0_CRTCn_PENDING (3<<24) -#define NV03_PMC_INTR_EN_0 0x00000140 -# define NV_PMC_INTR_EN_0_MASTER_ENABLE (1<<0) -#define NV03_PMC_ENABLE 0x00000200 -# define NV_PMC_ENABLE_PFIFO (1<<8) -# define NV_PMC_ENABLE_PGRAPH (1<<12) -/* Disabling the below bit breaks newer (G7X only?) mobile chipsets, - * the card will hang early on in the X init process. - */ -# define NV_PMC_ENABLE_UNK13 (1<<13) -#define NV40_PMC_GRAPH_UNITS 0x00001540 -#define NV40_PMC_BACKLIGHT 0x000015f0 -# define NV40_PMC_BACKLIGHT_MASK 0x001f0000 -#define NV40_PMC_1700 0x00001700 -#define NV40_PMC_1704 0x00001704 -#define NV40_PMC_1708 0x00001708 -#define NV40_PMC_170C 0x0000170C - -/* probably PMC ? */ -#define NV50_PUNK_BAR0_PRAMIN 0x00001700 -#define NV50_PUNK_BAR_CFG_BASE 0x00001704 -#define NV50_PUNK_BAR_CFG_BASE_VALID (1<<30) -#define NV50_PUNK_BAR1_CTXDMA 0x00001708 -#define NV50_PUNK_BAR1_CTXDMA_VALID (1<<31) -#define NV50_PUNK_BAR3_CTXDMA 0x0000170C -#define NV50_PUNK_BAR3_CTXDMA_VALID (1<<31) -#define NV50_PUNK_UNK1710 0x00001710 - -#define NV04_PBUS_PCI_NV_1 0x00001804 -#define NV04_PBUS_PCI_NV_19 0x0000184C -#define NV04_PBUS_PCI_NV_20 0x00001850 -# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) -# define NV04_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) - -#define NV04_PTIMER_INTR_0 0x00009100 -#define NV04_PTIMER_INTR_EN_0 0x00009140 -#define NV04_PTIMER_NUMERATOR 0x00009200 -#define NV04_PTIMER_DENOMINATOR 0x00009210 -#define NV04_PTIMER_TIME_0 0x00009400 -#define NV04_PTIMER_TIME_1 0x00009410 -#define NV04_PTIMER_ALARM_0 0x00009420 - -#define NV04_PGRAPH_DEBUG_0 0x00400080 -#define NV04_PGRAPH_DEBUG_1 0x00400084 -#define NV04_PGRAPH_DEBUG_2 0x00400088 -#define NV04_PGRAPH_DEBUG_3 0x0040008c -#define NV10_PGRAPH_DEBUG_4 0x00400090 -#define NV03_PGRAPH_INTR 0x00400100 -#define NV03_PGRAPH_NSTATUS 0x00400104 -# define NV04_PGRAPH_NSTATUS_STATE_IN_USE (1<<11) -# define NV04_PGRAPH_NSTATUS_INVALID_STATE (1<<12) -# define NV04_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<13) -# define NV04_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<14) -# define NV10_PGRAPH_NSTATUS_STATE_IN_USE (1<<23) -# define NV10_PGRAPH_NSTATUS_INVALID_STATE (1<<24) -# define NV10_PGRAPH_NSTATUS_BAD_ARGUMENT (1<<25) -# define NV10_PGRAPH_NSTATUS_PROTECTION_FAULT (1<<26) -#define NV03_PGRAPH_NSOURCE 0x00400108 -# define NV03_PGRAPH_NSOURCE_NOTIFICATION (1<<0) -# define NV03_PGRAPH_NSOURCE_DATA_ERROR (1<<1) -# define NV03_PGRAPH_NSOURCE_PROTECTION_ERROR (1<<2) -# define NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION (1<<3) -# define NV03_PGRAPH_NSOURCE_LIMIT_COLOR (1<<4) -# define NV03_PGRAPH_NSOURCE_LIMIT_ZETA (1<<5) -# define NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD (1<<6) -# define NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION (1<<7) -# define NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION (1<<8) -# define NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION (1<<9) -# define NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION (1<<10) -# define NV03_PGRAPH_NSOURCE_STATE_INVALID (1<<11) -# define NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY (1<<12) -# define NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE (1<<13) -# define NV03_PGRAPH_NSOURCE_METHOD_CNT (1<<14) -# define NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION (1<<15) -# define NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION (1<<16) -# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_A (1<<17) -# define NV03_PGRAPH_NSOURCE_DMA_WIDTH_B (1<<18) -#define NV03_PGRAPH_INTR_EN 0x00400140 -#define NV40_PGRAPH_INTR_EN 0x0040013C -# define NV_PGRAPH_INTR_NOTIFY (1<<0) -# define NV_PGRAPH_INTR_MISSING_HW (1<<4) -# define NV_PGRAPH_INTR_CONTEXT_SWITCH (1<<12) -# define NV_PGRAPH_INTR_BUFFER_NOTIFY (1<<16) -# define NV_PGRAPH_INTR_ERROR (1<<20) -#define NV10_PGRAPH_CTX_CONTROL 0x00400144 -#define NV10_PGRAPH_CTX_USER 0x00400148 -#define NV10_PGRAPH_CTX_SWITCH(i) (0x0040014C + 0x4*(i)) -#define NV04_PGRAPH_CTX_SWITCH1 0x00400160 -#define NV10_PGRAPH_CTX_CACHE(i, j) (0x00400160 \ - + 0x4*(i) + 0x20*(j)) -#define NV04_PGRAPH_CTX_SWITCH2 0x00400164 -#define NV04_PGRAPH_CTX_SWITCH3 0x00400168 -#define NV04_PGRAPH_CTX_SWITCH4 0x0040016C -#define NV04_PGRAPH_CTX_CONTROL 0x00400170 -#define NV04_PGRAPH_CTX_USER 0x00400174 -#define NV04_PGRAPH_CTX_CACHE1 0x00400180 -#define NV03_PGRAPH_CTX_CONTROL 0x00400190 -#define NV03_PGRAPH_CTX_USER 0x00400194 -#define NV04_PGRAPH_CTX_CACHE2 0x004001A0 -#define NV04_PGRAPH_CTX_CACHE3 0x004001C0 -#define NV04_PGRAPH_CTX_CACHE4 0x004001E0 -#define NV40_PGRAPH_CTXCTL_0304 0x00400304 -#define NV40_PGRAPH_CTXCTL_0304_XFER_CTX 0x00000001 -#define NV40_PGRAPH_CTXCTL_UCODE_STAT 0x00400308 -#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_MASK 0xff000000 -#define NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT 24 -#define NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK 0x00ffffff -#define NV40_PGRAPH_CTXCTL_0310 0x00400310 -#define NV40_PGRAPH_CTXCTL_0310_XFER_SAVE 0x00000020 -#define NV40_PGRAPH_CTXCTL_0310_XFER_LOAD 0x00000040 -#define NV40_PGRAPH_CTXCTL_030C 0x0040030c -#define NV40_PGRAPH_CTXCTL_UCODE_INDEX 0x00400324 -#define NV40_PGRAPH_CTXCTL_UCODE_DATA 0x00400328 -#define NV40_PGRAPH_CTXCTL_CUR 0x0040032c -#define NV40_PGRAPH_CTXCTL_CUR_LOADED 0x01000000 -#define NV40_PGRAPH_CTXCTL_CUR_INSTANCE 0x000FFFFF -#define NV40_PGRAPH_CTXCTL_NEXT 0x00400330 -#define NV40_PGRAPH_CTXCTL_NEXT_INSTANCE 0x000fffff -#define NV50_PGRAPH_CTXCTL_CUR 0x0040032c -#define NV50_PGRAPH_CTXCTL_CUR_LOADED 0x80000000 -#define NV50_PGRAPH_CTXCTL_CUR_INSTANCE 0x00ffffff -#define NV50_PGRAPH_CTXCTL_NEXT 0x00400330 -#define NV50_PGRAPH_CTXCTL_NEXT_INSTANCE 0x00ffffff -#define NV03_PGRAPH_ABS_X_RAM 0x00400400 -#define NV03_PGRAPH_ABS_Y_RAM 0x00400480 -#define NV03_PGRAPH_X_MISC 0x00400500 -#define NV03_PGRAPH_Y_MISC 0x00400504 -#define NV04_PGRAPH_VALID1 0x00400508 -#define NV04_PGRAPH_SOURCE_COLOR 0x0040050C -#define NV04_PGRAPH_MISC24_0 0x00400510 -#define NV03_PGRAPH_XY_LOGIC_MISC0 0x00400514 -#define NV03_PGRAPH_XY_LOGIC_MISC1 0x00400518 -#define NV03_PGRAPH_XY_LOGIC_MISC2 0x0040051C -#define NV03_PGRAPH_XY_LOGIC_MISC3 0x00400520 -#define NV03_PGRAPH_CLIPX_0 0x00400524 -#define NV03_PGRAPH_CLIPX_1 0x00400528 -#define NV03_PGRAPH_CLIPY_0 0x0040052C -#define NV03_PGRAPH_CLIPY_1 0x00400530 -#define NV03_PGRAPH_ABS_ICLIP_XMAX 0x00400534 -#define NV03_PGRAPH_ABS_ICLIP_YMAX 0x00400538 -#define NV03_PGRAPH_ABS_UCLIP_XMIN 0x0040053C -#define NV03_PGRAPH_ABS_UCLIP_YMIN 0x00400540 -#define NV03_PGRAPH_ABS_UCLIP_XMAX 0x00400544 -#define NV03_PGRAPH_ABS_UCLIP_YMAX 0x00400548 -#define NV03_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 -#define NV03_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 -#define NV03_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 -#define NV03_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C -#define NV04_PGRAPH_MISC24_1 0x00400570 -#define NV04_PGRAPH_MISC24_2 0x00400574 -#define NV04_PGRAPH_VALID2 0x00400578 -#define NV04_PGRAPH_PASSTHRU_0 0x0040057C -#define NV04_PGRAPH_PASSTHRU_1 0x00400580 -#define NV04_PGRAPH_PASSTHRU_2 0x00400584 -#define NV10_PGRAPH_DIMX_TEXTURE 0x00400588 -#define NV10_PGRAPH_WDIMX_TEXTURE 0x0040058C -#define NV04_PGRAPH_COMBINE_0_ALPHA 0x00400590 -#define NV04_PGRAPH_COMBINE_0_COLOR 0x00400594 -#define NV04_PGRAPH_COMBINE_1_ALPHA 0x00400598 -#define NV04_PGRAPH_COMBINE_1_COLOR 0x0040059C -#define NV04_PGRAPH_FORMAT_0 0x004005A8 -#define NV04_PGRAPH_FORMAT_1 0x004005AC -#define NV04_PGRAPH_FILTER_0 0x004005B0 -#define NV04_PGRAPH_FILTER_1 0x004005B4 -#define NV03_PGRAPH_MONO_COLOR0 0x00400600 -#define NV04_PGRAPH_ROP3 0x00400604 -#define NV04_PGRAPH_BETA_AND 0x00400608 -#define NV04_PGRAPH_BETA_PREMULT 0x0040060C -#define NV04_PGRAPH_LIMIT_VIOL_PIX 0x00400610 -#define NV04_PGRAPH_FORMATS 0x00400618 -#define NV10_PGRAPH_DEBUG_2 0x00400620 -#define NV04_PGRAPH_BOFFSET0 0x00400640 -#define NV04_PGRAPH_BOFFSET1 0x00400644 -#define NV04_PGRAPH_BOFFSET2 0x00400648 -#define NV04_PGRAPH_BOFFSET3 0x0040064C -#define NV04_PGRAPH_BOFFSET4 0x00400650 -#define NV04_PGRAPH_BOFFSET5 0x00400654 -#define NV04_PGRAPH_BBASE0 0x00400658 -#define NV04_PGRAPH_BBASE1 0x0040065C -#define NV04_PGRAPH_BBASE2 0x00400660 -#define NV04_PGRAPH_BBASE3 0x00400664 -#define NV04_PGRAPH_BBASE4 0x00400668 -#define NV04_PGRAPH_BBASE5 0x0040066C -#define NV04_PGRAPH_BPITCH0 0x00400670 -#define NV04_PGRAPH_BPITCH1 0x00400674 -#define NV04_PGRAPH_BPITCH2 0x00400678 -#define NV04_PGRAPH_BPITCH3 0x0040067C -#define NV04_PGRAPH_BPITCH4 0x00400680 -#define NV04_PGRAPH_BLIMIT0 0x00400684 -#define NV04_PGRAPH_BLIMIT1 0x00400688 -#define NV04_PGRAPH_BLIMIT2 0x0040068C -#define NV04_PGRAPH_BLIMIT3 0x00400690 -#define NV04_PGRAPH_BLIMIT4 0x00400694 -#define NV04_PGRAPH_BLIMIT5 0x00400698 -#define NV04_PGRAPH_BSWIZZLE2 0x0040069C -#define NV04_PGRAPH_BSWIZZLE5 0x004006A0 -#define NV03_PGRAPH_STATUS 0x004006B0 -#define NV04_PGRAPH_STATUS 0x00400700 -# define NV40_PGRAPH_STATUS_SYNC_STALL 0x00004000 -#define NV04_PGRAPH_TRAPPED_ADDR 0x00400704 -#define NV04_PGRAPH_TRAPPED_DATA 0x00400708 -#define NV04_PGRAPH_SURFACE 0x0040070C -#define NV10_PGRAPH_TRAPPED_DATA_HIGH 0x0040070C -#define NV04_PGRAPH_STATE 0x00400710 -#define NV10_PGRAPH_SURFACE 0x00400710 -#define NV04_PGRAPH_NOTIFY 0x00400714 -#define NV10_PGRAPH_STATE 0x00400714 -#define NV10_PGRAPH_NOTIFY 0x00400718 - -#define NV04_PGRAPH_FIFO 0x00400720 - -#define NV04_PGRAPH_BPIXEL 0x00400724 -#define NV10_PGRAPH_RDI_INDEX 0x00400750 -#define NV04_PGRAPH_FFINTFC_ST2 0x00400754 -#define NV10_PGRAPH_RDI_DATA 0x00400754 -#define NV04_PGRAPH_DMA_PITCH 0x00400760 -#define NV10_PGRAPH_FFINTFC_FIFO_PTR 0x00400760 -#define NV04_PGRAPH_DVD_COLORFMT 0x00400764 -#define NV10_PGRAPH_FFINTFC_ST2 0x00400764 -#define NV04_PGRAPH_SCALED_FORMAT 0x00400768 -#define NV10_PGRAPH_FFINTFC_ST2_DL 0x00400768 -#define NV10_PGRAPH_FFINTFC_ST2_DH 0x0040076c -#define NV10_PGRAPH_DMA_PITCH 0x00400770 -#define NV10_PGRAPH_DVD_COLORFMT 0x00400774 -#define NV10_PGRAPH_SCALED_FORMAT 0x00400778 -#define NV20_PGRAPH_CHANNEL_CTX_TABLE 0x00400780 -#define NV20_PGRAPH_CHANNEL_CTX_POINTER 0x00400784 -#define NV20_PGRAPH_CHANNEL_CTX_XFER 0x00400788 -#define NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD 0x00000001 -#define NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE 0x00000002 -#define NV04_PGRAPH_PATT_COLOR0 0x00400800 -#define NV04_PGRAPH_PATT_COLOR1 0x00400804 -#define NV04_PGRAPH_PATTERN 0x00400808 -#define NV04_PGRAPH_PATTERN_SHAPE 0x00400810 -#define NV04_PGRAPH_CHROMA 0x00400814 -#define NV04_PGRAPH_CONTROL0 0x00400818 -#define NV04_PGRAPH_CONTROL1 0x0040081C -#define NV04_PGRAPH_CONTROL2 0x00400820 -#define NV04_PGRAPH_BLEND 0x00400824 -#define NV04_PGRAPH_STORED_FMT 0x00400830 -#define NV04_PGRAPH_PATT_COLORRAM 0x00400900 -#define NV20_PGRAPH_TILE(i) (0x00400900 + (i*16)) -#define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16)) -#define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16)) -#define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16)) -#define NV20_PGRAPH_ZCOMP(i) (0x00400980 + 4*(i)) -#define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) -#define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) -#define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) -#define NV10_PGRAPH_TSTATUS(i) (0x00400B0C + (i*16)) -#define NV04_PGRAPH_U_RAM 0x00400D00 -#define NV47_PGRAPH_TILE(i) (0x00400D00 + (i*16)) -#define NV47_PGRAPH_TLIMIT(i) (0x00400D04 + (i*16)) -#define NV47_PGRAPH_TSIZE(i) (0x00400D08 + (i*16)) -#define NV47_PGRAPH_TSTATUS(i) (0x00400D0C + (i*16)) -#define NV04_PGRAPH_V_RAM 0x00400D40 -#define NV04_PGRAPH_W_RAM 0x00400D80 -#define NV10_PGRAPH_COMBINER0_IN_ALPHA 0x00400E40 -#define NV10_PGRAPH_COMBINER1_IN_ALPHA 0x00400E44 -#define NV10_PGRAPH_COMBINER0_IN_RGB 0x00400E48 -#define NV10_PGRAPH_COMBINER1_IN_RGB 0x00400E4C -#define NV10_PGRAPH_COMBINER_COLOR0 0x00400E50 -#define NV10_PGRAPH_COMBINER_COLOR1 0x00400E54 -#define NV10_PGRAPH_COMBINER0_OUT_ALPHA 0x00400E58 -#define NV10_PGRAPH_COMBINER1_OUT_ALPHA 0x00400E5C -#define NV10_PGRAPH_COMBINER0_OUT_RGB 0x00400E60 -#define NV10_PGRAPH_COMBINER1_OUT_RGB 0x00400E64 -#define NV10_PGRAPH_COMBINER_FINAL0 0x00400E68 -#define NV10_PGRAPH_COMBINER_FINAL1 0x00400E6C -#define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL 0x00400F00 -#define NV10_PGRAPH_WINDOWCLIP_VERTICAL 0x00400F20 -#define NV10_PGRAPH_XFMODE0 0x00400F40 -#define NV10_PGRAPH_XFMODE1 0x00400F44 -#define NV10_PGRAPH_GLOBALSTATE0 0x00400F48 -#define NV10_PGRAPH_GLOBALSTATE1 0x00400F4C -#define NV10_PGRAPH_PIPE_ADDRESS 0x00400F50 -#define NV10_PGRAPH_PIPE_DATA 0x00400F54 -#define NV04_PGRAPH_DMA_START_0 0x00401000 -#define NV04_PGRAPH_DMA_START_1 0x00401004 -#define NV04_PGRAPH_DMA_LENGTH 0x00401008 -#define NV04_PGRAPH_DMA_MISC 0x0040100C -#define NV04_PGRAPH_DMA_DATA_0 0x00401020 -#define NV04_PGRAPH_DMA_DATA_1 0x00401024 -#define NV04_PGRAPH_DMA_RM 0x00401030 -#define NV04_PGRAPH_DMA_A_XLATE_INST 0x00401040 -#define NV04_PGRAPH_DMA_A_CONTROL 0x00401044 -#define NV04_PGRAPH_DMA_A_LIMIT 0x00401048 -#define NV04_PGRAPH_DMA_A_TLB_PTE 0x0040104C -#define NV04_PGRAPH_DMA_A_TLB_TAG 0x00401050 -#define NV04_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 -#define NV04_PGRAPH_DMA_A_OFFSET 0x00401058 -#define NV04_PGRAPH_DMA_A_SIZE 0x0040105C -#define NV04_PGRAPH_DMA_A_Y_SIZE 0x00401060 -#define NV04_PGRAPH_DMA_B_XLATE_INST 0x00401080 -#define NV04_PGRAPH_DMA_B_CONTROL 0x00401084 -#define NV04_PGRAPH_DMA_B_LIMIT 0x00401088 -#define NV04_PGRAPH_DMA_B_TLB_PTE 0x0040108C -#define NV04_PGRAPH_DMA_B_TLB_TAG 0x00401090 -#define NV04_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 -#define NV04_PGRAPH_DMA_B_OFFSET 0x00401098 -#define NV04_PGRAPH_DMA_B_SIZE 0x0040109C -#define NV04_PGRAPH_DMA_B_Y_SIZE 0x004010A0 -#define NV40_PGRAPH_TILE1(i) (0x00406900 + (i*16)) -#define NV40_PGRAPH_TLIMIT1(i) (0x00406904 + (i*16)) -#define NV40_PGRAPH_TSIZE1(i) (0x00406908 + (i*16)) -#define NV40_PGRAPH_TSTATUS1(i) (0x0040690C + (i*16)) - - -/* It's a guess that this works on NV03. Confirmed on NV04, though */ -#define NV04_PFIFO_DELAY_0 0x00002040 -#define NV04_PFIFO_DMA_TIMESLICE 0x00002044 -#define NV04_PFIFO_NEXT_CHANNEL 0x00002050 -#define NV03_PFIFO_INTR_0 0x00002100 -#define NV03_PFIFO_INTR_EN_0 0x00002140 -# define NV_PFIFO_INTR_CACHE_ERROR (1<<0) -# define NV_PFIFO_INTR_RUNOUT (1<<4) -# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<<8) -# define NV_PFIFO_INTR_DMA_PUSHER (1<<12) -# define NV_PFIFO_INTR_DMA_PT (1<<16) -# define NV_PFIFO_INTR_SEMAPHORE (1<<20) -# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24) -#define NV03_PFIFO_RAMHT 0x00002210 -#define NV03_PFIFO_RAMFC 0x00002214 -#define NV03_PFIFO_RAMRO 0x00002218 -#define NV40_PFIFO_RAMFC 0x00002220 -#define NV03_PFIFO_CACHES 0x00002500 -#define NV04_PFIFO_MODE 0x00002504 -#define NV04_PFIFO_DMA 0x00002508 -#define NV04_PFIFO_SIZE 0x0000250c -#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4) -#define NV50_PFIFO_CTX_TABLE__SIZE 128 -#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31) -#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30) -#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF -#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF -#define NV03_PFIFO_CACHE0_PUSH0 0x00003000 -#define NV03_PFIFO_CACHE0_PULL0 0x00003040 -#define NV04_PFIFO_CACHE0_PULL0 0x00003050 -#define NV04_PFIFO_CACHE0_PULL1 0x00003054 -#define NV03_PFIFO_CACHE1_PUSH0 0x00003200 -#define NV03_PFIFO_CACHE1_PUSH1 0x00003204 -#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8) -#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16) -#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f -#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f -#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f -#define NV03_PFIFO_CACHE1_PUT 0x00003210 -#define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220 -#define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000008 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000010 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000018 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000020 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000028 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000030 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000038 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000040 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000048 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x00000050 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x00000058 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x00000060 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x00000068 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x00000070 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x00000078 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000080 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000088 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000090 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000098 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x000000A0 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x000000A8 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x000000B0 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x000000B8 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x000000C0 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x000000C8 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x000000D0 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x000000D8 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x000000E0 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x000000E8 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x000000F0 -# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x000000F8 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 0x0000E000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00002000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00004000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00006000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00008000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x0000A000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x0000C000 -# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x0000E000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 0x001F0000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00010000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00020000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00030000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00040000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00050000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00060000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00070000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00080000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00090000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x000A0000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x000B0000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x000C0000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x000D0000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x000E0000 -# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x000F0000 -# define NV_PFIFO_CACHE1_ENDIAN 0x80000000 -# define NV_PFIFO_CACHE1_LITTLE_ENDIAN 0x7FFFFFFF -# define NV_PFIFO_CACHE1_BIG_ENDIAN 0x80000000 -#define NV04_PFIFO_CACHE1_DMA_STATE 0x00003228 -#define NV04_PFIFO_CACHE1_DMA_INSTANCE 0x0000322c -#define NV04_PFIFO_CACHE1_DMA_CTL 0x00003230 -#define NV04_PFIFO_CACHE1_DMA_PUT 0x00003240 -#define NV04_PFIFO_CACHE1_DMA_GET 0x00003244 -#define NV10_PFIFO_CACHE1_REF_CNT 0x00003248 -#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C -#define NV03_PFIFO_CACHE1_PULL0 0x00003240 -#define NV04_PFIFO_CACHE1_PULL0 0x00003250 -# define NV04_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000010 -# define NV04_PFIFO_CACHE1_PULL0_HASH_BUSY 0x00001000 -#define NV03_PFIFO_CACHE1_PULL1 0x00003250 -#define NV04_PFIFO_CACHE1_PULL1 0x00003254 -#define NV04_PFIFO_CACHE1_HASH 0x00003258 -#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT 0x00003260 -#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP 0x00003264 -#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE 0x00003268 -#define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C -#define NV03_PFIFO_CACHE1_GET 0x00003270 -#define NV04_PFIFO_CACHE1_ENGINE 0x00003280 -#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0 -#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0 -#define NV40_PFIFO_UNK32E4 0x000032E4 -#define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8)) -#define NV04_PFIFO_CACHE1_DATA(i) (0x00003804+(i*8)) -#define NV40_PFIFO_CACHE1_METHOD(i) (0x00090000+(i*8)) -#define NV40_PFIFO_CACHE1_DATA(i) (0x00090004+(i*8)) - -#define NV_CRTC0_INTSTAT 0x00600100 -#define NV_CRTC0_INTEN 0x00600140 -#define NV_CRTC1_INTSTAT 0x00602100 -#define NV_CRTC1_INTEN 0x00602140 -# define NV_CRTC_INTR_VBLANK (1<<0) - -#define NV04_PRAMIN 0x00700000 - -/* Fifo commands. These are not regs, neither masks */ -#define NV03_FIFO_CMD_JUMP 0x20000000 -#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc -#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) - -/* This is a partial import from rules-ng, a few things may be duplicated. - * Eventually we should completely import everything from rules-ng. - * For the moment check rules-ng for docs. - */ - -#define NV50_PMC 0x00000000 -#define NV50_PMC__LEN 0x1 -#define NV50_PMC__ESIZE 0x2000 -# define NV50_PMC_BOOT_0 0x00000000 -# define NV50_PMC_BOOT_0_REVISION 0x000000ff -# define NV50_PMC_BOOT_0_REVISION__SHIFT 0 -# define NV50_PMC_BOOT_0_ARCH 0x0ff00000 -# define NV50_PMC_BOOT_0_ARCH__SHIFT 20 -# define NV50_PMC_INTR_0 0x00000100 -# define NV50_PMC_INTR_0_PFIFO (1<<8) -# define NV50_PMC_INTR_0_PGRAPH (1<<12) -# define NV50_PMC_INTR_0_PTIMER (1<<20) -# define NV50_PMC_INTR_0_HOTPLUG (1<<21) -# define NV50_PMC_INTR_0_DISPLAY (1<<26) -# define NV50_PMC_INTR_EN_0 0x00000140 -# define NV50_PMC_INTR_EN_0_MASTER (1<<0) -# define NV50_PMC_INTR_EN_0_MASTER_DISABLED (0<<0) -# define NV50_PMC_INTR_EN_0_MASTER_ENABLED (1<<0) -# define NV50_PMC_ENABLE 0x00000200 -# define NV50_PMC_ENABLE_PFIFO (1<<8) -# define NV50_PMC_ENABLE_PGRAPH (1<<12) - -#define NV50_PCONNECTOR 0x0000e000 -#define NV50_PCONNECTOR__LEN 0x1 -#define NV50_PCONNECTOR__ESIZE 0x1000 -# define NV50_PCONNECTOR_HOTPLUG_INTR 0x0000e050 -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C0 (1<<0) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C1 (1<<1) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C2 (1<<2) -# define NV50_PCONNECTOR_HOTPLUG_INTR_PLUG_I2C3 (1<<3) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C0 (1<<16) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C1 (1<<17) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C2 (1<<18) -# define NV50_PCONNECTOR_HOTPLUG_INTR_UNPLUG_I2C3 (1<<19) -# define NV50_PCONNECTOR_HOTPLUG_CTRL 0x0000e054 -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C0 (1<<0) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C1 (1<<1) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C2 (1<<2) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_PLUG_I2C3 (1<<3) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C0 (1<<16) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C1 (1<<17) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C2 (1<<18) -# define NV50_PCONNECTOR_HOTPLUG_CTRL_UNPLUG_I2C3 (1<<19) -# define NV50_PCONNECTOR_HOTPLUG_STATE 0x0000e104 -# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C0 (1<<2) -# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C1 (1<<6) -# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C2 (1<<10) -# define NV50_PCONNECTOR_HOTPLUG_STATE_PIN_CONNECTED_I2C3 (1<<14) -# define NV50_PCONNECTOR_I2C_PORT_0 0x0000e138 -# define NV50_PCONNECTOR_I2C_PORT_1 0x0000e150 -# define NV50_PCONNECTOR_I2C_PORT_2 0x0000e168 -# define NV50_PCONNECTOR_I2C_PORT_3 0x0000e180 -# define NV50_PCONNECTOR_I2C_PORT_4 0x0000e240 -# define NV50_PCONNECTOR_I2C_PORT_5 0x0000e258 - -#define NV50_AUXCH_DATA_OUT(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4c0) -#define NV50_AUXCH_DATA_OUT__SIZE 4 -#define NV50_AUXCH_DATA_IN(i, n) ((n) * 4 + (i) * 0x50 + 0x0000e4d0) -#define NV50_AUXCH_DATA_IN__SIZE 4 -#define NV50_AUXCH_ADDR(i) ((i) * 0x50 + 0x0000e4e0) -#define NV50_AUXCH_CTRL(i) ((i) * 0x50 + 0x0000e4e4) -#define NV50_AUXCH_CTRL_LINKSTAT 0x01000000 -#define NV50_AUXCH_CTRL_LINKSTAT_NOT_READY 0x00000000 -#define NV50_AUXCH_CTRL_LINKSTAT_READY 0x01000000 -#define NV50_AUXCH_CTRL_LINKEN 0x00100000 -#define NV50_AUXCH_CTRL_LINKEN_DISABLED 0x00000000 -#define NV50_AUXCH_CTRL_LINKEN_ENABLED 0x00100000 -#define NV50_AUXCH_CTRL_EXEC 0x00010000 -#define NV50_AUXCH_CTRL_EXEC_COMPLETE 0x00000000 -#define NV50_AUXCH_CTRL_EXEC_IN_PROCESS 0x00010000 -#define NV50_AUXCH_CTRL_CMD 0x0000f000 -#define NV50_AUXCH_CTRL_CMD_SHIFT 12 -#define NV50_AUXCH_CTRL_LEN 0x0000000f -#define NV50_AUXCH_CTRL_LEN_SHIFT 0 -#define NV50_AUXCH_STAT(i) ((i) * 0x50 + 0x0000e4e8) -#define NV50_AUXCH_STAT_STATE 0x10000000 -#define NV50_AUXCH_STAT_STATE_NOT_READY 0x00000000 -#define NV50_AUXCH_STAT_STATE_READY 0x10000000 -#define NV50_AUXCH_STAT_REPLY 0x000f0000 -#define NV50_AUXCH_STAT_REPLY_AUX 0x00030000 -#define NV50_AUXCH_STAT_REPLY_AUX_ACK 0x00000000 -#define NV50_AUXCH_STAT_REPLY_AUX_NACK 0x00010000 -#define NV50_AUXCH_STAT_REPLY_AUX_DEFER 0x00020000 -#define NV50_AUXCH_STAT_REPLY_I2C 0x000c0000 -#define NV50_AUXCH_STAT_REPLY_I2C_ACK 0x00000000 -#define NV50_AUXCH_STAT_REPLY_I2C_NACK 0x00040000 -#define NV50_AUXCH_STAT_REPLY_I2C_DEFER 0x00080000 -#define NV50_AUXCH_STAT_COUNT 0x0000001f - -#define NV50_PBUS 0x00088000 -#define NV50_PBUS__LEN 0x1 -#define NV50_PBUS__ESIZE 0x1000 -# define NV50_PBUS_PCI_ID 0x00088000 -# define NV50_PBUS_PCI_ID_VENDOR_ID 0x0000ffff -# define NV50_PBUS_PCI_ID_VENDOR_ID__SHIFT 0 -# define NV50_PBUS_PCI_ID_DEVICE_ID 0xffff0000 -# define NV50_PBUS_PCI_ID_DEVICE_ID__SHIFT 16 - -#define NV50_PFB 0x00100000 -#define NV50_PFB__LEN 0x1 -#define NV50_PFB__ESIZE 0x1000 - -#define NV50_PEXTDEV 0x00101000 -#define NV50_PEXTDEV__LEN 0x1 -#define NV50_PEXTDEV__ESIZE 0x1000 - -#define NV50_PROM 0x00300000 -#define NV50_PROM__LEN 0x1 -#define NV50_PROM__ESIZE 0x10000 - -#define NV50_PGRAPH 0x00400000 -#define NV50_PGRAPH__LEN 0x1 -#define NV50_PGRAPH__ESIZE 0x10000 - -#define NV50_PDISPLAY 0x00610000 -#define NV50_PDISPLAY_OBJECTS 0x00610010 -#define NV50_PDISPLAY_INTR_0 0x00610020 -#define NV50_PDISPLAY_INTR_1 0x00610024 -#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC 0x0000000c -#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_SHIFT 2 -#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(n) (1 << ((n) + 2)) -#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0 0x00000004 -#define NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1 0x00000008 -#define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010 -#define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020 -#define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040 -#define NV50_PDISPLAY_INTR_EN_0 0x00610028 -#define NV50_PDISPLAY_INTR_EN_1 0x0061002c -#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC 0x0000000c -#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(n) (1 << ((n) + 2)) -#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_0 0x00000004 -#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_1 0x00000008 -#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 0x00000010 -#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 0x00000020 -#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK40 0x00000040 -#define NV50_PDISPLAY_UNK30_CTRL 0x00610030 -#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200 -#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400 -#define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 -#define NV50_PDISPLAY_TRAPPED_ADDR(i) ((i) * 0x08 + 0x00610080) -#define NV50_PDISPLAY_TRAPPED_DATA(i) ((i) * 0x08 + 0x00610084) -#define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200) -#define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010 -#define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000 -#define NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED 0x00000010 -#define NV50_PDISPLAY_EVO_DMA_CB(i) ((i) * 0x10 + 0x00610204) -#define NV50_PDISPLAY_EVO_DMA_CB_LOCATION 0x00000002 -#define NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM 0x00000000 -#define NV50_PDISPLAY_EVO_DMA_CB_LOCATION_SYSTEM 0x00000002 -#define NV50_PDISPLAY_EVO_DMA_CB_VALID 0x00000001 -#define NV50_PDISPLAY_EVO_UNK2(i) ((i) * 0x10 + 0x00610208) -#define NV50_PDISPLAY_EVO_HASH_TAG(i) ((i) * 0x10 + 0x0061020c) - -#define NV50_PDISPLAY_CURSOR 0x00610270 -#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) ((i) * 0x10 + 0x00610270) -#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON 0x00000001 -#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS 0x00030000 -#define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE 0x00010000 - -#define NV50_PDISPLAY_PIO_CTRL 0x00610300 -#define NV50_PDISPLAY_PIO_CTRL_PENDING 0x80000000 -#define NV50_PDISPLAY_PIO_CTRL_MTHD 0x00001ffc -#define NV50_PDISPLAY_PIO_CTRL_ENABLED 0x00000001 -#define NV50_PDISPLAY_PIO_DATA 0x00610304 - -#define NV50_PDISPLAY_CRTC_P(i, r) ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r) -#define NV50_PDISPLAY_CRTC_C(i, r) (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r) -#define NV50_PDISPLAY_CRTC_UNK_0A18 /* mthd 0x0900 */ 0x00610a18 -#define NV50_PDISPLAY_CRTC_CLUT_MODE 0x00610a24 -#define NV50_PDISPLAY_CRTC_INTERLACE 0x00610a48 -#define NV50_PDISPLAY_CRTC_SCALE_CTRL 0x00610a50 -#define NV50_PDISPLAY_CRTC_CURSOR_CTRL 0x00610a58 -#define NV50_PDISPLAY_CRTC_UNK0A78 /* mthd 0x0904 */ 0x00610a78 -#define NV50_PDISPLAY_CRTC_UNK0AB8 0x00610ab8 -#define NV50_PDISPLAY_CRTC_DEPTH 0x00610ac8 -#define NV50_PDISPLAY_CRTC_CLOCK 0x00610ad0 -#define NV50_PDISPLAY_CRTC_COLOR_CTRL 0x00610ae0 -#define NV50_PDISPLAY_CRTC_SYNC_START_TO_BLANK_END 0x00610ae8 -#define NV50_PDISPLAY_CRTC_MODE_UNK1 0x00610af0 -#define NV50_PDISPLAY_CRTC_DISPLAY_TOTAL 0x00610af8 -#define NV50_PDISPLAY_CRTC_SYNC_DURATION 0x00610b00 -#define NV50_PDISPLAY_CRTC_MODE_UNK2 0x00610b08 -#define NV50_PDISPLAY_CRTC_UNK_0B10 /* mthd 0x0828 */ 0x00610b10 -#define NV50_PDISPLAY_CRTC_FB_SIZE 0x00610b18 -#define NV50_PDISPLAY_CRTC_FB_PITCH 0x00610b20 -#define NV50_PDISPLAY_CRTC_FB_PITCH_LINEAR 0x00100000 -#define NV50_PDISPLAY_CRTC_FB_POS 0x00610b28 -#define NV50_PDISPLAY_CRTC_SCALE_CENTER_OFFSET 0x00610b38 -#define NV50_PDISPLAY_CRTC_REAL_RES 0x00610b40 -#define NV50_PDISPLAY_CRTC_SCALE_RES1 0x00610b48 -#define NV50_PDISPLAY_CRTC_SCALE_RES2 0x00610b50 - -#define NV50_PDISPLAY_DAC_MODE_CTRL_P(i) (0x00610b58 + (i) * 0x8) -#define NV50_PDISPLAY_DAC_MODE_CTRL_C(i) (0x00610b5c + (i) * 0x8) -#define NV50_PDISPLAY_SOR_MODE_CTRL_P(i) (0x00610b70 + (i) * 0x8) -#define NV50_PDISPLAY_SOR_MODE_CTRL_C(i) (0x00610b74 + (i) * 0x8) -#define NV50_PDISPLAY_EXT_MODE_CTRL_P(i) (0x00610b80 + (i) * 0x8) -#define NV50_PDISPLAY_EXT_MODE_CTRL_C(i) (0x00610b84 + (i) * 0x8) -#define NV50_PDISPLAY_DAC_MODE_CTRL2_P(i) (0x00610bdc + (i) * 0x8) -#define NV50_PDISPLAY_DAC_MODE_CTRL2_C(i) (0x00610be0 + (i) * 0x8) -#define NV90_PDISPLAY_SOR_MODE_CTRL_P(i) (0x00610794 + (i) * 0x8) -#define NV90_PDISPLAY_SOR_MODE_CTRL_C(i) (0x00610798 + (i) * 0x8) - -#define NV50_PDISPLAY_CRTC_CLK 0x00614000 -#define NV50_PDISPLAY_CRTC_CLK_CTRL1(i) ((i) * 0x800 + 0x614100) -#define NV50_PDISPLAY_CRTC_CLK_CTRL1_CONNECTED 0x00000600 -#define NV50_PDISPLAY_CRTC_CLK_VPLL_A(i) ((i) * 0x800 + 0x614104) -#define NV50_PDISPLAY_CRTC_CLK_VPLL_B(i) ((i) * 0x800 + 0x614108) -#define NV50_PDISPLAY_CRTC_CLK_CTRL2(i) ((i) * 0x800 + 0x614200) - -#define NV50_PDISPLAY_DAC_CLK 0x00614000 -#define NV50_PDISPLAY_DAC_CLK_CTRL2(i) ((i) * 0x800 + 0x614280) - -#define NV50_PDISPLAY_SOR_CLK 0x00614000 -#define NV50_PDISPLAY_SOR_CLK_CTRL2(i) ((i) * 0x800 + 0x614300) - -#define NV50_PDISPLAY_VGACRTC(r) ((r) + 0x619400) - -#define NV50_PDISPLAY_DAC 0x0061a000 -#define NV50_PDISPLAY_DAC_DPMS_CTRL(i) (0x0061a004 + (i) * 0x800) -#define NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF 0x00000001 -#define NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF 0x00000004 -#define NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED 0x00000010 -#define NV50_PDISPLAY_DAC_DPMS_CTRL_OFF 0x00000040 -#define NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING 0x80000000 -#define NV50_PDISPLAY_DAC_LOAD_CTRL(i) (0x0061a00c + (i) * 0x800) -#define NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE 0x00100000 -#define NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT 0x38000000 -#define NV50_PDISPLAY_DAC_LOAD_CTRL_DONE 0x80000000 -#define NV50_PDISPLAY_DAC_CLK_CTRL1(i) (0x0061a010 + (i) * 0x800) -#define NV50_PDISPLAY_DAC_CLK_CTRL1_CONNECTED 0x00000600 - -#define NV50_PDISPLAY_SOR 0x0061c000 -#define NV50_PDISPLAY_SOR_DPMS_CTRL(i) (0x0061c004 + (i) * 0x800) -#define NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING 0x80000000 -#define NV50_PDISPLAY_SOR_DPMS_CTRL_ON 0x00000001 -#define NV50_PDISPLAY_SOR_CLK_CTRL1(i) (0x0061c008 + (i) * 0x800) -#define NV50_PDISPLAY_SOR_CLK_CTRL1_CONNECTED 0x00000600 -#define NV50_PDISPLAY_SOR_DPMS_STATE(i) (0x0061c030 + (i) * 0x800) -#define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE 0x00030000 -#define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED 0x00080000 -#define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT 0x10000000 -#define NV50_PDISP_SOR_PWM_DIV(i) (0x0061c080 + (i) * 0x800) -#define NV50_PDISP_SOR_PWM_CTL(i) (0x0061c084 + (i) * 0x800) -#define NV50_PDISP_SOR_PWM_CTL_NEW 0x80000000 -#define NVA3_PDISP_SOR_PWM_CTL_UNK 0x40000000 -#define NV50_PDISP_SOR_PWM_CTL_VAL 0x000007ff -#define NVA3_PDISP_SOR_PWM_CTL_VAL 0x00ffffff -#define NV50_SOR_DP_CTRL(i, l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) -#define NV50_SOR_DP_CTRL_ENABLED 0x00000001 -#define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 -#define NV50_SOR_DP_CTRL_LANE_MASK 0x001f0000 -#define NV50_SOR_DP_CTRL_LANE_0_ENABLED 0x00010000 -#define NV50_SOR_DP_CTRL_LANE_1_ENABLED 0x00020000 -#define NV50_SOR_DP_CTRL_LANE_2_ENABLED 0x00040000 -#define NV50_SOR_DP_CTRL_LANE_3_ENABLED 0x00080000 -#define NV50_SOR_DP_CTRL_TRAINING_PATTERN 0x0f000000 -#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED 0x00000000 -#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1 0x01000000 -#define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2 0x02000000 -#define NV50_SOR_DP_UNK118(i, l) (0x0061c118 + (i) * 0x800 + (l) * 0x80) -#define NV50_SOR_DP_UNK120(i, l) (0x0061c120 + (i) * 0x800 + (l) * 0x80) -#define NV50_SOR_DP_SCFG(i, l) (0x0061c128 + (i) * 0x800 + (l) * 0x80) -#define NV50_SOR_DP_UNK130(i, l) (0x0061c130 + (i) * 0x800 + (l) * 0x80) - -#define NV50_PDISPLAY_USER(i) ((i) * 0x1000 + 0x00640000) -#define NV50_PDISPLAY_USER_PUT(i) ((i) * 0x1000 + 0x00640000) -#define NV50_PDISPLAY_USER_GET(i) ((i) * 0x1000 + 0x00640004) - -#define NV50_PDISPLAY_CURSOR_USER 0x00647000 -#define NV50_PDISPLAY_CURSOR_USER_POS_CTRL(i) ((i) * 0x1000 + 0x00647080) -#define NV50_PDISPLAY_CURSOR_USER_POS(i) ((i) * 0x1000 + 0x00647084) diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_sgdma.c deleted file mode 100644 index 47f245ed..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ /dev/null @@ -1,444 +0,0 @@ -#include "drmP.h" -#include "nouveau_drv.h" -#include -#include - -#define NV_CTXDMA_PAGE_SHIFT 12 -#define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT) -#define NV_CTXDMA_PAGE_MASK (NV_CTXDMA_PAGE_SIZE - 1) - -struct nouveau_sgdma_be { - /* this has to be the first field so populate/unpopulated in - * nouve_bo.c works properly, otherwise have to move them here - */ - struct ttm_dma_tt ttm; - struct drm_device *dev; - u64 offset; -}; - -static void -nouveau_sgdma_destroy(struct ttm_tt *ttm) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - - if (ttm) { - NV_DEBUG(nvbe->dev, "\n"); - ttm_dma_tt_fini(&nvbe->ttm); - kfree(nvbe); - } -} - -static int -nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_device *dev = nvbe->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; - unsigned i, j, pte; - - NV_DEBUG(dev, "pg=0x%lx\n", mem->start); - - nvbe->offset = mem->start << PAGE_SHIFT; - pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2; - for (i = 0; i < ttm->num_pages; i++) { - dma_addr_t dma_offset = nvbe->ttm.dma_address[i]; - uint32_t offset_l = lower_32_bits(dma_offset); - - for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) { - nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); - offset_l += NV_CTXDMA_PAGE_SIZE; - } - } - - return 0; -} - -static int -nv04_sgdma_unbind(struct ttm_tt *ttm) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_device *dev = nvbe->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; - unsigned i, j, pte; - - NV_DEBUG(dev, "\n"); - - if (ttm->state != tt_bound) - return 0; - - pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2; - for (i = 0; i < ttm->num_pages; i++) { - for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) - nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); - } - - return 0; -} - -static struct ttm_backend_func nv04_sgdma_backend = { - .bind = nv04_sgdma_bind, - .unbind = nv04_sgdma_unbind, - .destroy = nouveau_sgdma_destroy -}; - -static void -nv41_sgdma_flush(struct nouveau_sgdma_be *nvbe) -{ - struct drm_device *dev = nvbe->dev; - - nv_wr32(dev, 0x100810, 0x00000022); - if (!nv_wait(dev, 0x100810, 0x00000100, 0x00000100)) - NV_ERROR(dev, "vm flush timeout: 0x%08x\n", - nv_rd32(dev, 0x100810)); - nv_wr32(dev, 0x100810, 0x00000000); -} - -static int -nv41_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; - struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; - dma_addr_t *list = nvbe->ttm.dma_address; - u32 pte = mem->start << 2; - u32 cnt = ttm->num_pages; - - nvbe->offset = mem->start << PAGE_SHIFT; - - while (cnt--) { - nv_wo32(pgt, pte, (*list++ >> 7) | 1); - pte += 4; - } - - nv41_sgdma_flush(nvbe); - return 0; -} - -static int -nv41_sgdma_unbind(struct ttm_tt *ttm) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; - struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; - u32 pte = (nvbe->offset >> 12) << 2; - u32 cnt = ttm->num_pages; - - while (cnt--) { - nv_wo32(pgt, pte, 0x00000000); - pte += 4; - } - - nv41_sgdma_flush(nvbe); - return 0; -} - -static struct ttm_backend_func nv41_sgdma_backend = { - .bind = nv41_sgdma_bind, - .unbind = nv41_sgdma_unbind, - .destroy = nouveau_sgdma_destroy -}; - -static void -nv44_sgdma_flush(struct ttm_tt *ttm) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_device *dev = nvbe->dev; - - nv_wr32(dev, 0x100814, (ttm->num_pages - 1) << 12); - nv_wr32(dev, 0x100808, nvbe->offset | 0x20); - if (!nv_wait(dev, 0x100808, 0x00000001, 0x00000001)) - NV_ERROR(dev, "gart flush timeout: 0x%08x\n", - nv_rd32(dev, 0x100808)); - nv_wr32(dev, 0x100808, 0x00000000); -} - -static void -nv44_sgdma_fill(struct nouveau_gpuobj *pgt, dma_addr_t *list, u32 base, u32 cnt) -{ - struct drm_nouveau_private *dev_priv = pgt->dev->dev_private; - dma_addr_t dummy = dev_priv->gart_info.dummy.addr; - u32 pte, tmp[4]; - - pte = base >> 2; - base &= ~0x0000000f; - - tmp[0] = nv_ro32(pgt, base + 0x0); - tmp[1] = nv_ro32(pgt, base + 0x4); - tmp[2] = nv_ro32(pgt, base + 0x8); - tmp[3] = nv_ro32(pgt, base + 0xc); - while (cnt--) { - u32 addr = list ? (*list++ >> 12) : (dummy >> 12); - switch (pte++ & 0x3) { - case 0: - tmp[0] &= ~0x07ffffff; - tmp[0] |= addr; - break; - case 1: - tmp[0] &= ~0xf8000000; - tmp[0] |= addr << 27; - tmp[1] &= ~0x003fffff; - tmp[1] |= addr >> 5; - break; - case 2: - tmp[1] &= ~0xffc00000; - tmp[1] |= addr << 22; - tmp[2] &= ~0x0001ffff; - tmp[2] |= addr >> 10; - break; - case 3: - tmp[2] &= ~0xfffe0000; - tmp[2] |= addr << 17; - tmp[3] &= ~0x00000fff; - tmp[3] |= addr >> 15; - break; - } - } - - tmp[3] |= 0x40000000; - - nv_wo32(pgt, base + 0x0, tmp[0]); - nv_wo32(pgt, base + 0x4, tmp[1]); - nv_wo32(pgt, base + 0x8, tmp[2]); - nv_wo32(pgt, base + 0xc, tmp[3]); -} - -static int -nv44_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; - struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; - dma_addr_t *list = nvbe->ttm.dma_address; - u32 pte = mem->start << 2, tmp[4]; - u32 cnt = ttm->num_pages; - int i; - - nvbe->offset = mem->start << PAGE_SHIFT; - - if (pte & 0x0000000c) { - u32 max = 4 - ((pte >> 2) & 0x3); - u32 part = (cnt > max) ? max : cnt; - nv44_sgdma_fill(pgt, list, pte, part); - pte += (part << 2); - list += part; - cnt -= part; - } - - while (cnt >= 4) { - for (i = 0; i < 4; i++) - tmp[i] = *list++ >> 12; - nv_wo32(pgt, pte + 0x0, tmp[0] >> 0 | tmp[1] << 27); - nv_wo32(pgt, pte + 0x4, tmp[1] >> 5 | tmp[2] << 22); - nv_wo32(pgt, pte + 0x8, tmp[2] >> 10 | tmp[3] << 17); - nv_wo32(pgt, pte + 0xc, tmp[3] >> 15 | 0x40000000); - pte += 0x10; - cnt -= 4; - } - - if (cnt) - nv44_sgdma_fill(pgt, list, pte, cnt); - - nv44_sgdma_flush(ttm); - return 0; -} - -static int -nv44_sgdma_unbind(struct ttm_tt *ttm) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; - struct nouveau_gpuobj *pgt = dev_priv->gart_info.sg_ctxdma; - u32 pte = (nvbe->offset >> 12) << 2; - u32 cnt = ttm->num_pages; - - if (pte & 0x0000000c) { - u32 max = 4 - ((pte >> 2) & 0x3); - u32 part = (cnt > max) ? max : cnt; - nv44_sgdma_fill(pgt, NULL, pte, part); - pte += (part << 2); - cnt -= part; - } - - while (cnt >= 4) { - nv_wo32(pgt, pte + 0x0, 0x00000000); - nv_wo32(pgt, pte + 0x4, 0x00000000); - nv_wo32(pgt, pte + 0x8, 0x00000000); - nv_wo32(pgt, pte + 0xc, 0x00000000); - pte += 0x10; - cnt -= 4; - } - - if (cnt) - nv44_sgdma_fill(pgt, NULL, pte, cnt); - - nv44_sgdma_flush(ttm); - return 0; -} - -static struct ttm_backend_func nv44_sgdma_backend = { - .bind = nv44_sgdma_bind, - .unbind = nv44_sgdma_unbind, - .destroy = nouveau_sgdma_destroy -}; - -static int -nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem) -{ - struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm; - struct nouveau_mem *node = mem->mm_node; - - /* noop: bound in move_notify() */ - node->pages = nvbe->ttm.dma_address; - return 0; -} - -static int -nv50_sgdma_unbind(struct ttm_tt *ttm) -{ - /* noop: unbound in move_notify() */ - return 0; -} - -static struct ttm_backend_func nv50_sgdma_backend = { - .bind = nv50_sgdma_bind, - .unbind = nv50_sgdma_unbind, - .destroy = nouveau_sgdma_destroy -}; - -struct ttm_tt * -nouveau_sgdma_create_ttm(struct ttm_bo_device *bdev, - unsigned long size, uint32_t page_flags, - struct page *dummy_read_page) -{ - struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); - struct drm_device *dev = dev_priv->dev; - struct nouveau_sgdma_be *nvbe; - - nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL); - if (!nvbe) - return NULL; - - nvbe->dev = dev; - nvbe->ttm.ttm.func = dev_priv->gart_info.func; - - if (ttm_dma_tt_init(&nvbe->ttm, bdev, size, page_flags, dummy_read_page)) { - kfree(nvbe); - return NULL; - } - return &nvbe->ttm.ttm; -} - -int -nouveau_sgdma_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj = NULL; - u32 aper_size, align; - int ret; - - if (dev_priv->card_type >= NV_40 && pci_is_pcie(dev->pdev)) - aper_size = 512 * 1024 * 1024; - else - aper_size = 64 * 1024 * 1024; - - /* Dear NVIDIA, NV44+ would like proper present bits in PTEs for - * christmas. The cards before it have them, the cards after - * it have them, why is NV44 so unloved? - */ - dev_priv->gart_info.dummy.page = alloc_page(GFP_DMA32 | GFP_KERNEL); - if (!dev_priv->gart_info.dummy.page) - return -ENOMEM; - - dev_priv->gart_info.dummy.addr = - pci_map_page(dev->pdev, dev_priv->gart_info.dummy.page, - 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, dev_priv->gart_info.dummy.addr)) { - NV_ERROR(dev, "error mapping dummy page\n"); - __free_page(dev_priv->gart_info.dummy.page); - dev_priv->gart_info.dummy.page = NULL; - return -ENOMEM; - } - - if (dev_priv->card_type >= NV_50) { - dev_priv->gart_info.aper_base = 0; - dev_priv->gart_info.aper_size = aper_size; - dev_priv->gart_info.type = NOUVEAU_GART_HW; - dev_priv->gart_info.func = &nv50_sgdma_backend; - } else - if (0 && pci_is_pcie(dev->pdev) && - dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) { - if (nv44_graph_class(dev)) { - dev_priv->gart_info.func = &nv44_sgdma_backend; - align = 512 * 1024; - } else { - dev_priv->gart_info.func = &nv41_sgdma_backend; - align = 16; - } - - ret = nouveau_gpuobj_new(dev, NULL, aper_size / 1024, align, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &gpuobj); - if (ret) { - NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); - return ret; - } - - dev_priv->gart_info.sg_ctxdma = gpuobj; - dev_priv->gart_info.aper_base = 0; - dev_priv->gart_info.aper_size = aper_size; - dev_priv->gart_info.type = NOUVEAU_GART_HW; - } else { - ret = nouveau_gpuobj_new(dev, NULL, (aper_size / 1024) + 8, 16, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &gpuobj); - if (ret) { - NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); - return ret; - } - - nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | - (1 << 12) /* PT present */ | - (0 << 13) /* PT *not* linear */ | - (0 << 14) /* RW */ | - (2 << 16) /* PCI */); - nv_wo32(gpuobj, 4, aper_size - 1); - - dev_priv->gart_info.sg_ctxdma = gpuobj; - dev_priv->gart_info.aper_base = 0; - dev_priv->gart_info.aper_size = aper_size; - dev_priv->gart_info.type = NOUVEAU_GART_PDMA; - dev_priv->gart_info.func = &nv04_sgdma_backend; - } - - return 0; -} - -void -nouveau_sgdma_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma); - - if (dev_priv->gart_info.dummy.page) { - pci_unmap_page(dev->pdev, dev_priv->gart_info.dummy.addr, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - __free_page(dev_priv->gart_info.dummy.page); - dev_priv->gart_info.dummy.page = NULL; - } -} - -uint32_t -nouveau_sgdma_get_physical(struct drm_device *dev, uint32_t offset) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; - int pte = (offset >> NV_CTXDMA_PAGE_SHIFT) + 2; - - BUG_ON(dev_priv->card_type >= NV_50); - - return (nv_ro32(gpuobj, 4 * pte) & ~NV_CTXDMA_PAGE_MASK) | - (offset & NV_CTXDMA_PAGE_MASK); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_state.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_state.c deleted file mode 100644 index c2a8511e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_state.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* - * Copyright 2005 Stephane Marchesin - * Copyright 2008 Stuart Bennett - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "drm_crtc_helper.h" -#include -#include - -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_fbcon.h" -#include "nouveau_ramht.h" -#include "nouveau_gpio.h" -#include "nouveau_pm.h" -#include "nv50_display.h" - -static void nouveau_stub_takedown(struct drm_device *dev) {} -static int nouveau_stub_init(struct drm_device *dev) { return 0; } - -static int nouveau_init_engine_ptrs(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - - switch (dev_priv->chipset & 0xf0) { - case 0x00: - engine->instmem.init = nv04_instmem_init; - engine->instmem.takedown = nv04_instmem_takedown; - engine->instmem.suspend = nv04_instmem_suspend; - engine->instmem.resume = nv04_instmem_resume; - engine->instmem.get = nv04_instmem_get; - engine->instmem.put = nv04_instmem_put; - engine->instmem.map = nv04_instmem_map; - engine->instmem.unmap = nv04_instmem_unmap; - engine->instmem.flush = nv04_instmem_flush; - engine->mc.init = nv04_mc_init; - engine->mc.takedown = nv04_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv04_fb_init; - engine->fb.takedown = nv04_fb_takedown; - engine->fifo.channels = 16; - engine->fifo.init = nv04_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv04_fifo_channel_id; - engine->fifo.create_context = nv04_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv04_fifo_load_context; - engine->fifo.unload_context = nv04_fifo_unload_context; - engine->display.early_init = nv04_display_early_init; - engine->display.late_takedown = nv04_display_late_takedown; - engine->display.create = nv04_display_create; - engine->display.destroy = nv04_display_destroy; - engine->display.init = nv04_display_init; - engine->display.fini = nv04_display_fini; - engine->pm.clocks_get = nv04_pm_clocks_get; - engine->pm.clocks_pre = nv04_pm_clocks_pre; - engine->pm.clocks_set = nv04_pm_clocks_set; - engine->vram.init = nv04_fb_vram_init; - engine->vram.takedown = nouveau_stub_takedown; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; - case 0x10: - engine->instmem.init = nv04_instmem_init; - engine->instmem.takedown = nv04_instmem_takedown; - engine->instmem.suspend = nv04_instmem_suspend; - engine->instmem.resume = nv04_instmem_resume; - engine->instmem.get = nv04_instmem_get; - engine->instmem.put = nv04_instmem_put; - engine->instmem.map = nv04_instmem_map; - engine->instmem.unmap = nv04_instmem_unmap; - engine->instmem.flush = nv04_instmem_flush; - engine->mc.init = nv04_mc_init; - engine->mc.takedown = nv04_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv10_fb_init; - engine->fb.takedown = nv10_fb_takedown; - engine->fb.init_tile_region = nv10_fb_init_tile_region; - engine->fb.set_tile_region = nv10_fb_set_tile_region; - engine->fb.free_tile_region = nv10_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv10_fifo_load_context; - engine->fifo.unload_context = nv10_fifo_unload_context; - engine->display.early_init = nv04_display_early_init; - engine->display.late_takedown = nv04_display_late_takedown; - engine->display.create = nv04_display_create; - engine->display.destroy = nv04_display_destroy; - engine->display.init = nv04_display_init; - engine->display.fini = nv04_display_fini; - engine->gpio.drive = nv10_gpio_drive; - engine->gpio.sense = nv10_gpio_sense; - engine->pm.clocks_get = nv04_pm_clocks_get; - engine->pm.clocks_pre = nv04_pm_clocks_pre; - engine->pm.clocks_set = nv04_pm_clocks_set; - if (dev_priv->chipset == 0x1a || - dev_priv->chipset == 0x1f) - engine->vram.init = nv1a_fb_vram_init; - else - engine->vram.init = nv10_fb_vram_init; - engine->vram.takedown = nouveau_stub_takedown; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; - case 0x20: - engine->instmem.init = nv04_instmem_init; - engine->instmem.takedown = nv04_instmem_takedown; - engine->instmem.suspend = nv04_instmem_suspend; - engine->instmem.resume = nv04_instmem_resume; - engine->instmem.get = nv04_instmem_get; - engine->instmem.put = nv04_instmem_put; - engine->instmem.map = nv04_instmem_map; - engine->instmem.unmap = nv04_instmem_unmap; - engine->instmem.flush = nv04_instmem_flush; - engine->mc.init = nv04_mc_init; - engine->mc.takedown = nv04_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv20_fb_init; - engine->fb.takedown = nv20_fb_takedown; - engine->fb.init_tile_region = nv20_fb_init_tile_region; - engine->fb.set_tile_region = nv20_fb_set_tile_region; - engine->fb.free_tile_region = nv20_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv10_fifo_load_context; - engine->fifo.unload_context = nv10_fifo_unload_context; - engine->display.early_init = nv04_display_early_init; - engine->display.late_takedown = nv04_display_late_takedown; - engine->display.create = nv04_display_create; - engine->display.destroy = nv04_display_destroy; - engine->display.init = nv04_display_init; - engine->display.fini = nv04_display_fini; - engine->gpio.drive = nv10_gpio_drive; - engine->gpio.sense = nv10_gpio_sense; - engine->pm.clocks_get = nv04_pm_clocks_get; - engine->pm.clocks_pre = nv04_pm_clocks_pre; - engine->pm.clocks_set = nv04_pm_clocks_set; - engine->vram.init = nv20_fb_vram_init; - engine->vram.takedown = nouveau_stub_takedown; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; - case 0x30: - engine->instmem.init = nv04_instmem_init; - engine->instmem.takedown = nv04_instmem_takedown; - engine->instmem.suspend = nv04_instmem_suspend; - engine->instmem.resume = nv04_instmem_resume; - engine->instmem.get = nv04_instmem_get; - engine->instmem.put = nv04_instmem_put; - engine->instmem.map = nv04_instmem_map; - engine->instmem.unmap = nv04_instmem_unmap; - engine->instmem.flush = nv04_instmem_flush; - engine->mc.init = nv04_mc_init; - engine->mc.takedown = nv04_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv30_fb_init; - engine->fb.takedown = nv30_fb_takedown; - engine->fb.init_tile_region = nv30_fb_init_tile_region; - engine->fb.set_tile_region = nv10_fb_set_tile_region; - engine->fb.free_tile_region = nv30_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv10_fifo_load_context; - engine->fifo.unload_context = nv10_fifo_unload_context; - engine->display.early_init = nv04_display_early_init; - engine->display.late_takedown = nv04_display_late_takedown; - engine->display.create = nv04_display_create; - engine->display.destroy = nv04_display_destroy; - engine->display.init = nv04_display_init; - engine->display.fini = nv04_display_fini; - engine->gpio.drive = nv10_gpio_drive; - engine->gpio.sense = nv10_gpio_sense; - engine->pm.clocks_get = nv04_pm_clocks_get; - engine->pm.clocks_pre = nv04_pm_clocks_pre; - engine->pm.clocks_set = nv04_pm_clocks_set; - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; - engine->vram.init = nv20_fb_vram_init; - engine->vram.takedown = nouveau_stub_takedown; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; - case 0x40: - case 0x60: - engine->instmem.init = nv04_instmem_init; - engine->instmem.takedown = nv04_instmem_takedown; - engine->instmem.suspend = nv04_instmem_suspend; - engine->instmem.resume = nv04_instmem_resume; - engine->instmem.get = nv04_instmem_get; - engine->instmem.put = nv04_instmem_put; - engine->instmem.map = nv04_instmem_map; - engine->instmem.unmap = nv04_instmem_unmap; - engine->instmem.flush = nv04_instmem_flush; - engine->mc.init = nv40_mc_init; - engine->mc.takedown = nv40_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv40_fb_init; - engine->fb.takedown = nv40_fb_takedown; - engine->fb.init_tile_region = nv30_fb_init_tile_region; - engine->fb.set_tile_region = nv40_fb_set_tile_region; - engine->fb.free_tile_region = nv30_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv40_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv40_fifo_create_context; - engine->fifo.destroy_context = nv04_fifo_destroy_context; - engine->fifo.load_context = nv40_fifo_load_context; - engine->fifo.unload_context = nv40_fifo_unload_context; - engine->display.early_init = nv04_display_early_init; - engine->display.late_takedown = nv04_display_late_takedown; - engine->display.create = nv04_display_create; - engine->display.destroy = nv04_display_destroy; - engine->display.init = nv04_display_init; - engine->display.fini = nv04_display_fini; - engine->gpio.init = nv10_gpio_init; - engine->gpio.fini = nv10_gpio_fini; - engine->gpio.drive = nv10_gpio_drive; - engine->gpio.sense = nv10_gpio_sense; - engine->gpio.irq_enable = nv10_gpio_irq_enable; - engine->pm.clocks_get = nv40_pm_clocks_get; - engine->pm.clocks_pre = nv40_pm_clocks_pre; - engine->pm.clocks_set = nv40_pm_clocks_set; - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; - engine->pm.temp_get = nv40_temp_get; - engine->pm.pwm_get = nv40_pm_pwm_get; - engine->pm.pwm_set = nv40_pm_pwm_set; - engine->vram.init = nv40_fb_vram_init; - engine->vram.takedown = nouveau_stub_takedown; - engine->vram.flags_valid = nouveau_mem_flags_valid; - break; - case 0x50: - case 0x80: /* gotta love NVIDIA's consistency.. */ - case 0x90: - case 0xa0: - engine->instmem.init = nv50_instmem_init; - engine->instmem.takedown = nv50_instmem_takedown; - engine->instmem.suspend = nv50_instmem_suspend; - engine->instmem.resume = nv50_instmem_resume; - engine->instmem.get = nv50_instmem_get; - engine->instmem.put = nv50_instmem_put; - engine->instmem.map = nv50_instmem_map; - engine->instmem.unmap = nv50_instmem_unmap; - if (dev_priv->chipset == 0x50) - engine->instmem.flush = nv50_instmem_flush; - else - engine->instmem.flush = nv84_instmem_flush; - engine->mc.init = nv50_mc_init; - engine->mc.takedown = nv50_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nv50_fb_init; - engine->fb.takedown = nv50_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nv50_fifo_init; - engine->fifo.takedown = nv50_fifo_takedown; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.channel_id = nv50_fifo_channel_id; - engine->fifo.create_context = nv50_fifo_create_context; - engine->fifo.destroy_context = nv50_fifo_destroy_context; - engine->fifo.load_context = nv50_fifo_load_context; - engine->fifo.unload_context = nv50_fifo_unload_context; - engine->fifo.tlb_flush = nv50_fifo_tlb_flush; - engine->display.early_init = nv50_display_early_init; - engine->display.late_takedown = nv50_display_late_takedown; - engine->display.create = nv50_display_create; - engine->display.destroy = nv50_display_destroy; - engine->display.init = nv50_display_init; - engine->display.fini = nv50_display_fini; - engine->gpio.init = nv50_gpio_init; - engine->gpio.fini = nv50_gpio_fini; - engine->gpio.drive = nv50_gpio_drive; - engine->gpio.sense = nv50_gpio_sense; - engine->gpio.irq_enable = nv50_gpio_irq_enable; - switch (dev_priv->chipset) { - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0x98: - case 0xa0: - case 0xaa: - case 0xac: - case 0x50: - engine->pm.clocks_get = nv50_pm_clocks_get; - engine->pm.clocks_pre = nv50_pm_clocks_pre; - engine->pm.clocks_set = nv50_pm_clocks_set; - break; - default: - engine->pm.clocks_get = nva3_pm_clocks_get; - engine->pm.clocks_pre = nva3_pm_clocks_pre; - engine->pm.clocks_set = nva3_pm_clocks_set; - break; - } - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; - if (dev_priv->chipset >= 0x84) - engine->pm.temp_get = nv84_temp_get; - else - engine->pm.temp_get = nv40_temp_get; - engine->pm.pwm_get = nv50_pm_pwm_get; - engine->pm.pwm_set = nv50_pm_pwm_set; - engine->vram.init = nv50_vram_init; - engine->vram.takedown = nv50_vram_fini; - engine->vram.get = nv50_vram_new; - engine->vram.put = nv50_vram_del; - engine->vram.flags_valid = nv50_vram_flags_valid; - break; - case 0xc0: - engine->instmem.init = nvc0_instmem_init; - engine->instmem.takedown = nvc0_instmem_takedown; - engine->instmem.suspend = nvc0_instmem_suspend; - engine->instmem.resume = nvc0_instmem_resume; - engine->instmem.get = nv50_instmem_get; - engine->instmem.put = nv50_instmem_put; - engine->instmem.map = nv50_instmem_map; - engine->instmem.unmap = nv50_instmem_unmap; - engine->instmem.flush = nv84_instmem_flush; - engine->mc.init = nv50_mc_init; - engine->mc.takedown = nv50_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nvc0_fb_init; - engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; - engine->fifo.disable = nvc0_fifo_disable; - engine->fifo.enable = nvc0_fifo_enable; - engine->fifo.reassign = nvc0_fifo_reassign; - engine->fifo.channel_id = nvc0_fifo_channel_id; - engine->fifo.create_context = nvc0_fifo_create_context; - engine->fifo.destroy_context = nvc0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nvc0_fifo_unload_context; - engine->display.early_init = nv50_display_early_init; - engine->display.late_takedown = nv50_display_late_takedown; - engine->display.create = nv50_display_create; - engine->display.destroy = nv50_display_destroy; - engine->display.init = nv50_display_init; - engine->display.fini = nv50_display_fini; - engine->gpio.init = nv50_gpio_init; - engine->gpio.fini = nv50_gpio_fini; - engine->gpio.drive = nv50_gpio_drive; - engine->gpio.sense = nv50_gpio_sense; - engine->gpio.irq_enable = nv50_gpio_irq_enable; - engine->vram.init = nvc0_vram_init; - engine->vram.takedown = nv50_vram_fini; - engine->vram.get = nvc0_vram_new; - engine->vram.put = nv50_vram_del; - engine->vram.flags_valid = nvc0_vram_flags_valid; - engine->pm.temp_get = nv84_temp_get; - engine->pm.clocks_get = nvc0_pm_clocks_get; - engine->pm.clocks_pre = nvc0_pm_clocks_pre; - engine->pm.clocks_set = nvc0_pm_clocks_set; - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; - engine->pm.pwm_get = nv50_pm_pwm_get; - engine->pm.pwm_set = nv50_pm_pwm_set; - break; - case 0xd0: - engine->instmem.init = nvc0_instmem_init; - engine->instmem.takedown = nvc0_instmem_takedown; - engine->instmem.suspend = nvc0_instmem_suspend; - engine->instmem.resume = nvc0_instmem_resume; - engine->instmem.get = nv50_instmem_get; - engine->instmem.put = nv50_instmem_put; - engine->instmem.map = nv50_instmem_map; - engine->instmem.unmap = nv50_instmem_unmap; - engine->instmem.flush = nv84_instmem_flush; - engine->mc.init = nv50_mc_init; - engine->mc.takedown = nv50_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nvc0_fb_init; - engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; - engine->fifo.disable = nvc0_fifo_disable; - engine->fifo.enable = nvc0_fifo_enable; - engine->fifo.reassign = nvc0_fifo_reassign; - engine->fifo.channel_id = nvc0_fifo_channel_id; - engine->fifo.create_context = nvc0_fifo_create_context; - engine->fifo.destroy_context = nvc0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nvc0_fifo_unload_context; - engine->display.early_init = nouveau_stub_init; - engine->display.late_takedown = nouveau_stub_takedown; - engine->display.create = nvd0_display_create; - engine->display.destroy = nvd0_display_destroy; - engine->display.init = nvd0_display_init; - engine->display.fini = nvd0_display_fini; - engine->gpio.init = nv50_gpio_init; - engine->gpio.fini = nv50_gpio_fini; - engine->gpio.drive = nvd0_gpio_drive; - engine->gpio.sense = nvd0_gpio_sense; - engine->gpio.irq_enable = nv50_gpio_irq_enable; - engine->vram.init = nvc0_vram_init; - engine->vram.takedown = nv50_vram_fini; - engine->vram.get = nvc0_vram_new; - engine->vram.put = nv50_vram_del; - engine->vram.flags_valid = nvc0_vram_flags_valid; - engine->pm.temp_get = nv84_temp_get; - engine->pm.clocks_get = nvc0_pm_clocks_get; - engine->pm.clocks_pre = nvc0_pm_clocks_pre; - engine->pm.clocks_set = nvc0_pm_clocks_set; - engine->pm.voltage_get = nouveau_voltage_gpio_get; - engine->pm.voltage_set = nouveau_voltage_gpio_set; - break; - case 0xe0: - engine->instmem.init = nvc0_instmem_init; - engine->instmem.takedown = nvc0_instmem_takedown; - engine->instmem.suspend = nvc0_instmem_suspend; - engine->instmem.resume = nvc0_instmem_resume; - engine->instmem.get = nv50_instmem_get; - engine->instmem.put = nv50_instmem_put; - engine->instmem.map = nv50_instmem_map; - engine->instmem.unmap = nv50_instmem_unmap; - engine->instmem.flush = nv84_instmem_flush; - engine->mc.init = nv50_mc_init; - engine->mc.takedown = nv50_mc_takedown; - engine->timer.init = nv04_timer_init; - engine->timer.read = nv04_timer_read; - engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nvc0_fb_init; - engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 0; - engine->fifo.init = nouveau_stub_init; - engine->fifo.takedown = nouveau_stub_takedown; - engine->fifo.disable = nvc0_fifo_disable; - engine->fifo.enable = nvc0_fifo_enable; - engine->fifo.reassign = nvc0_fifo_reassign; - engine->fifo.unload_context = nouveau_stub_init; - engine->display.early_init = nouveau_stub_init; - engine->display.late_takedown = nouveau_stub_takedown; - engine->display.create = nvd0_display_create; - engine->display.destroy = nvd0_display_destroy; - engine->display.init = nvd0_display_init; - engine->display.fini = nvd0_display_fini; - engine->gpio.init = nv50_gpio_init; - engine->gpio.fini = nv50_gpio_fini; - engine->gpio.drive = nvd0_gpio_drive; - engine->gpio.sense = nvd0_gpio_sense; - engine->gpio.irq_enable = nv50_gpio_irq_enable; - engine->vram.init = nvc0_vram_init; - engine->vram.takedown = nv50_vram_fini; - engine->vram.get = nvc0_vram_new; - engine->vram.put = nv50_vram_del; - engine->vram.flags_valid = nvc0_vram_flags_valid; - break; - default: - NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); - return 1; - } - - /* headless mode */ - if (nouveau_modeset == 2) { - engine->display.early_init = nouveau_stub_init; - engine->display.late_takedown = nouveau_stub_takedown; - engine->display.create = nouveau_stub_init; - engine->display.init = nouveau_stub_init; - engine->display.destroy = nouveau_stub_takedown; - } - - return 0; -} - -static unsigned int -nouveau_vga_set_decode(void *priv, bool state) -{ - struct drm_device *dev = priv; - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset >= 0x40) - nv_wr32(dev, 0x88054, state); - else - nv_wr32(dev, 0x1854, state); - - if (state) - return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | - VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; - else - return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; -} - -static void nouveau_switcheroo_set_state(struct pci_dev *pdev, - enum vga_switcheroo_state state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; - if (state == VGA_SWITCHEROO_ON) { - printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - nouveau_pci_resume(pdev); - drm_kms_helper_poll_enable(dev); - dev->switch_power_state = DRM_SWITCH_POWER_ON; - } else { - printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - drm_kms_helper_poll_disable(dev); - nouveau_switcheroo_optimus_dsm(); - nouveau_pci_suspend(pdev, pmm); - dev->switch_power_state = DRM_SWITCH_POWER_OFF; - } -} - -static void nouveau_switcheroo_reprobe(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - nouveau_fbcon_output_poll_changed(dev); -} - -static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - bool can_switch; - - spin_lock(&dev->count_lock); - can_switch = (dev->open_count == 0); - spin_unlock(&dev->count_lock); - return can_switch; -} - -static void -nouveau_card_channel_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->channel) - nouveau_channel_put_unlocked(&dev_priv->channel); -} - -static int -nouveau_card_channel_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan; - int ret, oclass; - - ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT); - dev_priv->channel = chan; - if (ret) - return ret; - - mutex_unlock(&dev_priv->channel->mutex); - - if (dev_priv->card_type <= NV_50) { - if (dev_priv->card_type < NV_50) - oclass = 0x0039; - else - oclass = 0x5039; - - ret = nouveau_gpuobj_gr_new(chan, NvM2MF, oclass); - if (ret) - goto error; - - ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, - &chan->m2mf_ntfy); - if (ret) - goto error; - - ret = RING_SPACE(chan, 6); - if (ret) - goto error; - - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); - OUT_RING (chan, NvM2MF); - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); - OUT_RING (chan, NvNotify0); - OUT_RING (chan, chan->vram_handle); - OUT_RING (chan, chan->gart_handle); - } else - if (dev_priv->card_type <= NV_D0) { - ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039); - if (ret) - goto error; - - ret = RING_SPACE(chan, 2); - if (ret) - goto error; - - BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1); - OUT_RING (chan, 0x00009039); - } - - FIRE_RING (chan); -error: - if (ret) - nouveau_card_channel_fini(dev); - return ret; -} - -int -nouveau_card_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine; - int ret, e = 0; - - vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); - vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, - nouveau_switcheroo_reprobe, - nouveau_switcheroo_can_switch); - - /* Initialise internal driver API hooks */ - ret = nouveau_init_engine_ptrs(dev); - if (ret) - goto out; - engine = &dev_priv->engine; - spin_lock_init(&dev_priv->channels.lock); - spin_lock_init(&dev_priv->tile.lock); - spin_lock_init(&dev_priv->context_switch_lock); - spin_lock_init(&dev_priv->vm_lock); - - /* Make the CRTCs and I2C buses accessible */ - ret = engine->display.early_init(dev); - if (ret) - goto out; - - /* Parse BIOS tables / Run init tables if card not POSTed */ - ret = nouveau_bios_init(dev); - if (ret) - goto out_display_early; - - /* workaround an odd issue on nvc1 by disabling the device's - * nosnoop capability. hopefully won't cause issues until a - * better fix is found - assuming there is one... - */ - if (dev_priv->chipset == 0xc1) { - nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); - } - - /* PMC */ - ret = engine->mc.init(dev); - if (ret) - goto out_bios; - - /* PTIMER */ - ret = engine->timer.init(dev); - if (ret) - goto out_mc; - - /* PFB */ - ret = engine->fb.init(dev); - if (ret) - goto out_timer; - - ret = engine->vram.init(dev); - if (ret) - goto out_fb; - - /* PGPIO */ - ret = nouveau_gpio_create(dev); - if (ret) - goto out_vram; - - ret = nouveau_gpuobj_init(dev); - if (ret) - goto out_gpio; - - ret = engine->instmem.init(dev); - if (ret) - goto out_gpuobj; - - ret = nouveau_mem_vram_init(dev); - if (ret) - goto out_instmem; - - ret = nouveau_mem_gart_init(dev); - if (ret) - goto out_ttmvram; - - if (!dev_priv->noaccel) { - switch (dev_priv->card_type) { - case NV_04: - nv04_graph_create(dev); - break; - case NV_10: - nv10_graph_create(dev); - break; - case NV_20: - case NV_30: - nv20_graph_create(dev); - break; - case NV_40: - nv40_graph_create(dev); - break; - case NV_50: - nv50_graph_create(dev); - break; - case NV_C0: - case NV_D0: - nvc0_graph_create(dev); - break; - default: - break; - } - - switch (dev_priv->chipset) { - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0xa0: - nv84_crypt_create(dev); - break; - case 0x98: - case 0xaa: - case 0xac: - nv98_crypt_create(dev); - break; - } - - switch (dev_priv->card_type) { - case NV_50: - switch (dev_priv->chipset) { - case 0xa3: - case 0xa5: - case 0xa8: - case 0xaf: - nva3_copy_create(dev); - break; - } - break; - case NV_C0: - nvc0_copy_create(dev, 0); - nvc0_copy_create(dev, 1); - break; - default: - break; - } - - if (dev_priv->chipset >= 0xa3 || dev_priv->chipset == 0x98) { - nv84_bsp_create(dev); - nv84_vp_create(dev); - nv98_ppp_create(dev); - } else - if (dev_priv->chipset >= 0x84) { - nv50_mpeg_create(dev); - nv84_bsp_create(dev); - nv84_vp_create(dev); - } else - if (dev_priv->chipset >= 0x50) { - nv50_mpeg_create(dev); - } else - if (dev_priv->card_type == NV_40 || - dev_priv->chipset == 0x31 || - dev_priv->chipset == 0x34 || - dev_priv->chipset == 0x36) { - nv31_mpeg_create(dev); - } - - for (e = 0; e < NVOBJ_ENGINE_NR; e++) { - if (dev_priv->eng[e]) { - ret = dev_priv->eng[e]->init(dev, e); - if (ret) - goto out_engine; - } - } - - /* PFIFO */ - ret = engine->fifo.init(dev); - if (ret) - goto out_engine; - } - - ret = nouveau_irq_init(dev); - if (ret) - goto out_fifo; - - ret = nouveau_display_create(dev); - if (ret) - goto out_irq; - - nouveau_backlight_init(dev); - nouveau_pm_init(dev); - - ret = nouveau_fence_init(dev); - if (ret) - goto out_pm; - - if (dev_priv->eng[NVOBJ_ENGINE_GR]) { - ret = nouveau_card_channel_init(dev); - if (ret) - goto out_fence; - } - - if (dev->mode_config.num_crtc) { - ret = nouveau_display_init(dev); - if (ret) - goto out_chan; - - nouveau_fbcon_init(dev); - } - - return 0; - -out_chan: - nouveau_card_channel_fini(dev); -out_fence: - nouveau_fence_fini(dev); -out_pm: - nouveau_pm_fini(dev); - nouveau_backlight_exit(dev); - nouveau_display_destroy(dev); -out_irq: - nouveau_irq_fini(dev); -out_fifo: - if (!dev_priv->noaccel) - engine->fifo.takedown(dev); -out_engine: - if (!dev_priv->noaccel) { - for (e = e - 1; e >= 0; e--) { - if (!dev_priv->eng[e]) - continue; - dev_priv->eng[e]->fini(dev, e, false); - dev_priv->eng[e]->destroy(dev,e ); - } - } - nouveau_mem_gart_fini(dev); -out_ttmvram: - nouveau_mem_vram_fini(dev); -out_instmem: - engine->instmem.takedown(dev); -out_gpuobj: - nouveau_gpuobj_takedown(dev); -out_gpio: - nouveau_gpio_destroy(dev); -out_vram: - engine->vram.takedown(dev); -out_fb: - engine->fb.takedown(dev); -out_timer: - engine->timer.takedown(dev); -out_mc: - engine->mc.takedown(dev); -out_bios: - nouveau_bios_takedown(dev); -out_display_early: - engine->display.late_takedown(dev); -out: - vga_client_register(dev->pdev, NULL, NULL, NULL); - return ret; -} - -static void nouveau_card_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - int e; - - if (dev->mode_config.num_crtc) { - nouveau_fbcon_fini(dev); - nouveau_display_fini(dev); - } - - nouveau_card_channel_fini(dev); - nouveau_fence_fini(dev); - nouveau_pm_fini(dev); - nouveau_backlight_exit(dev); - nouveau_display_destroy(dev); - - if (!dev_priv->noaccel) { - engine->fifo.takedown(dev); - for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { - if (dev_priv->eng[e]) { - dev_priv->eng[e]->fini(dev, e, false); - dev_priv->eng[e]->destroy(dev,e ); - } - } - } - - if (dev_priv->vga_ram) { - nouveau_bo_unpin(dev_priv->vga_ram); - nouveau_bo_ref(NULL, &dev_priv->vga_ram); - } - - mutex_lock(&dev->struct_mutex); - ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); - ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); - mutex_unlock(&dev->struct_mutex); - nouveau_mem_gart_fini(dev); - nouveau_mem_vram_fini(dev); - - engine->instmem.takedown(dev); - nouveau_gpuobj_takedown(dev); - - nouveau_gpio_destroy(dev); - engine->vram.takedown(dev); - engine->fb.takedown(dev); - engine->timer.takedown(dev); - engine->mc.takedown(dev); - - nouveau_bios_takedown(dev); - engine->display.late_takedown(dev); - - nouveau_irq_fini(dev); - - vga_client_register(dev->pdev, NULL, NULL, NULL); -} - -int -nouveau_open(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fpriv *fpriv; - int ret; - - fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); - if (unlikely(!fpriv)) - return -ENOMEM; - - spin_lock_init(&fpriv->lock); - INIT_LIST_HEAD(&fpriv->channels); - - if (dev_priv->card_type == NV_50) { - ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL, - &fpriv->vm); - if (ret) { - kfree(fpriv); - return ret; - } - } else - if (dev_priv->card_type >= NV_C0) { - ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL, - &fpriv->vm); - if (ret) { - kfree(fpriv); - return ret; - } - } - - file_priv->driver_priv = fpriv; - return 0; -} - -/* here a client dies, release the stuff that was allocated for its - * file_priv */ -void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv) -{ - nouveau_channel_cleanup(dev, file_priv); -} - -void -nouveau_postclose(struct drm_device *dev, struct drm_file *file_priv) -{ - struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); - nouveau_vm_ref(NULL, &fpriv->vm, NULL); - kfree(fpriv); -} - -/* first module load, setup the mmio/fb mapping */ -/* KMS: we need mmio at load time, not when the first drm client opens. */ -int nouveau_firstopen(struct drm_device *dev) -{ - return 0; -} - -/* if we have an OF card, copy vbios to RAMIN */ -static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev) -{ -#if defined(__powerpc__) - int size, i; - const uint32_t *bios; - struct device_node *dn = pci_device_to_OF_node(dev->pdev); - if (!dn) { - NV_INFO(dev, "Unable to get the OF node\n"); - return; - } - - bios = of_get_property(dn, "NVDA,BMP", &size); - if (bios) { - for (i = 0; i < size; i += 4) - nv_wi32(dev, i, bios[i/4]); - NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size); - } else { - NV_INFO(dev, "Unable to get the OF bios\n"); - } -#endif -} - -static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev) -{ - struct pci_dev *pdev = dev->pdev; - struct apertures_struct *aper = alloc_apertures(3); - if (!aper) - return NULL; - - aper->ranges[0].base = pci_resource_start(pdev, 1); - aper->ranges[0].size = pci_resource_len(pdev, 1); - aper->count = 1; - - if (pci_resource_len(pdev, 2)) { - aper->ranges[aper->count].base = pci_resource_start(pdev, 2); - aper->ranges[aper->count].size = pci_resource_len(pdev, 2); - aper->count++; - } - - if (pci_resource_len(pdev, 3)) { - aper->ranges[aper->count].base = pci_resource_start(pdev, 3); - aper->ranges[aper->count].size = pci_resource_len(pdev, 3); - aper->count++; - } - - return aper; -} - -static int nouveau_remove_conflicting_drivers(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - bool primary = false; - dev_priv->apertures = nouveau_get_apertures(dev); - if (!dev_priv->apertures) - return -ENOMEM; - -#ifdef CONFIG_X86 - primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif - - remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary); - return 0; -} - -int nouveau_load(struct drm_device *dev, unsigned long flags) -{ - struct drm_nouveau_private *dev_priv; - unsigned long long offset, length; - uint32_t reg0 = ~0, strap; - int ret; - - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (!dev_priv) { - ret = -ENOMEM; - goto err_out; - } - dev->dev_private = dev_priv; - dev_priv->dev = dev; - - pci_set_master(dev->pdev); - - dev_priv->flags = flags & NOUVEAU_FLAGS; - - NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", - dev->pci_vendor, dev->pci_device, dev->pdev->class); - - /* first up, map the start of mmio and determine the chipset */ - dev_priv->mmio = ioremap(pci_resource_start(dev->pdev, 0), PAGE_SIZE); - if (dev_priv->mmio) { -#ifdef __BIG_ENDIAN - /* put the card into big-endian mode if it's not */ - if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001) - nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001); - DRM_MEMORYBARRIER(); -#endif - - /* determine chipset and derive architecture from it */ - reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); - if ((reg0 & 0x0f000000) > 0) { - dev_priv->chipset = (reg0 & 0xff00000) >> 20; - switch (dev_priv->chipset & 0xf0) { - case 0x10: - case 0x20: - case 0x30: - dev_priv->card_type = dev_priv->chipset & 0xf0; - break; - case 0x40: - case 0x60: - dev_priv->card_type = NV_40; - break; - case 0x50: - case 0x80: - case 0x90: - case 0xa0: - dev_priv->card_type = NV_50; - break; - case 0xc0: - dev_priv->card_type = NV_C0; - break; - case 0xd0: - dev_priv->card_type = NV_D0; - break; - case 0xe0: - dev_priv->card_type = NV_E0; - break; - default: - break; - } - } else - if ((reg0 & 0xff00fff0) == 0x20004000) { - if (reg0 & 0x00f00000) - dev_priv->chipset = 0x05; - else - dev_priv->chipset = 0x04; - dev_priv->card_type = NV_04; - } - - iounmap(dev_priv->mmio); - } - - if (!dev_priv->card_type) { - NV_ERROR(dev, "unsupported chipset 0x%08x\n", reg0); - ret = -EINVAL; - goto err_priv; - } - - NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", - dev_priv->card_type, reg0); - - /* map the mmio regs, limiting the amount to preserve vmap space */ - offset = pci_resource_start(dev->pdev, 0); - length = pci_resource_len(dev->pdev, 0); - if (dev_priv->card_type < NV_E0) - length = min(length, (unsigned long long)0x00800000); - - dev_priv->mmio = ioremap(offset, length); - if (!dev_priv->mmio) { - NV_ERROR(dev, "Unable to initialize the mmio mapping. " - "Please report your setup to " DRIVER_EMAIL "\n"); - ret = -EINVAL; - goto err_priv; - } - NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", offset); - - /* determine frequency of timing crystal */ - strap = nv_rd32(dev, 0x101000); - if ( dev_priv->chipset < 0x17 || - (dev_priv->chipset >= 0x20 && dev_priv->chipset <= 0x25)) - strap &= 0x00000040; - else - strap &= 0x00400040; - - switch (strap) { - case 0x00000000: dev_priv->crystal = 13500; break; - case 0x00000040: dev_priv->crystal = 14318; break; - case 0x00400000: dev_priv->crystal = 27000; break; - case 0x00400040: dev_priv->crystal = 25000; break; - } - - NV_DEBUG(dev, "crystal freq: %dKHz\n", dev_priv->crystal); - - /* Determine whether we'll attempt acceleration or not, some - * cards are disabled by default here due to them being known - * non-functional, or never been tested due to lack of hw. - */ - dev_priv->noaccel = !!nouveau_noaccel; - if (nouveau_noaccel == -1) { - switch (dev_priv->chipset) { - case 0xd9: /* known broken */ - NV_INFO(dev, "acceleration disabled by default, pass " - "noaccel=0 to force enable\n"); - dev_priv->noaccel = true; - break; - default: - dev_priv->noaccel = false; - break; - } - } - - ret = nouveau_remove_conflicting_drivers(dev); - if (ret) - goto err_mmio; - - /* Map PRAMIN BAR, or on older cards, the aperture within BAR0 */ - if (dev_priv->card_type >= NV_40) { - int ramin_bar = 2; - if (pci_resource_len(dev->pdev, ramin_bar) == 0) - ramin_bar = 3; - - dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar); - dev_priv->ramin = - ioremap(pci_resource_start(dev->pdev, ramin_bar), - dev_priv->ramin_size); - if (!dev_priv->ramin) { - NV_ERROR(dev, "Failed to map PRAMIN BAR\n"); - ret = -ENOMEM; - goto err_mmio; - } - } else { - dev_priv->ramin_size = 1 * 1024 * 1024; - dev_priv->ramin = ioremap(offset + NV_RAMIN, - dev_priv->ramin_size); - if (!dev_priv->ramin) { - NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); - ret = -ENOMEM; - goto err_mmio; - } - } - - nouveau_OF_copy_vbios_to_ramin(dev); - - /* Special flags */ - if (dev->pci_device == 0x01a0) - dev_priv->flags |= NV_NFORCE; - else if (dev->pci_device == 0x01f0) - dev_priv->flags |= NV_NFORCE2; - - /* For kernel modesetting, init card now and bring up fbcon */ - ret = nouveau_card_init(dev); - if (ret) - goto err_ramin; - - return 0; - -err_ramin: - iounmap(dev_priv->ramin); -err_mmio: - iounmap(dev_priv->mmio); -err_priv: - kfree(dev_priv); - dev->dev_private = NULL; -err_out: - return ret; -} - -void nouveau_lastclose(struct drm_device *dev) -{ - vga_switcheroo_process_delayed_switch(); -} - -int nouveau_unload(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nouveau_card_takedown(dev); - - iounmap(dev_priv->mmio); - iounmap(dev_priv->ramin); - - kfree(dev_priv); - dev->dev_private = NULL; - return 0; -} - -int nouveau_ioctl_getparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_nouveau_getparam *getparam = data; - - switch (getparam->param) { - case NOUVEAU_GETPARAM_CHIPSET_ID: - getparam->value = dev_priv->chipset; - break; - case NOUVEAU_GETPARAM_PCI_VENDOR: - getparam->value = dev->pci_vendor; - break; - case NOUVEAU_GETPARAM_PCI_DEVICE: - getparam->value = dev->pci_device; - break; - case NOUVEAU_GETPARAM_BUS_TYPE: - if (drm_pci_device_is_agp(dev)) - getparam->value = NV_AGP; - else if (pci_is_pcie(dev->pdev)) - getparam->value = NV_PCIE; - else - getparam->value = NV_PCI; - break; - case NOUVEAU_GETPARAM_FB_SIZE: - getparam->value = dev_priv->fb_available_size; - break; - case NOUVEAU_GETPARAM_AGP_SIZE: - getparam->value = dev_priv->gart_info.aper_size; - break; - case NOUVEAU_GETPARAM_VM_VRAM_BASE: - getparam->value = 0; /* deprecated */ - break; - case NOUVEAU_GETPARAM_PTIMER_TIME: - getparam->value = dev_priv->engine.timer.read(dev); - break; - case NOUVEAU_GETPARAM_HAS_BO_USAGE: - getparam->value = 1; - break; - case NOUVEAU_GETPARAM_HAS_PAGEFLIP: - getparam->value = 1; - break; - case NOUVEAU_GETPARAM_GRAPH_UNITS: - /* NV40 and NV50 versions are quite different, but register - * address is the same. User is supposed to know the card - * family anyway... */ - if (dev_priv->chipset >= 0x40) { - getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS); - break; - } - /* FALLTHRU */ - default: - NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param); - return -EINVAL; - } - - return 0; -} - -int -nouveau_ioctl_setparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_nouveau_setparam *setparam = data; - - switch (setparam->param) { - default: - NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param); - return -EINVAL; - } - - return 0; -} - -/* Wait until (value(reg) & mask) == val, up until timeout has hit */ -bool -nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - uint64_t start = ptimer->read(dev); - - do { - if ((nv_rd32(dev, reg) & mask) == val) - return true; - } while (ptimer->read(dev) - start < timeout); - - return false; -} - -/* Wait until (value(reg) & mask) != val, up until timeout has hit */ -bool -nouveau_wait_ne(struct drm_device *dev, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - uint64_t start = ptimer->read(dev); - - do { - if ((nv_rd32(dev, reg) & mask) != val) - return true; - } while (ptimer->read(dev) - start < timeout); - - return false; -} - -/* Wait until cond(data) == true, up until timeout has hit */ -bool -nouveau_wait_cb(struct drm_device *dev, u64 timeout, - bool (*cond)(void *), void *data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - u64 start = ptimer->read(dev); - - do { - if (cond(data) == true) - return true; - } while (ptimer->read(dev) - start < timeout); - - return false; -} - -/* Waits for PGRAPH to go completely idle */ -bool nouveau_wait_for_idle(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t mask = ~0; - - if (dev_priv->card_type == NV_40) - mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL; - - if (!nv_wait(dev, NV04_PGRAPH_STATUS, mask, 0)) { - NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", - nv_rd32(dev, NV04_PGRAPH_STATUS)); - return false; - } - - return true; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_temp.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_temp.c deleted file mode 100644 index 0f5a3016..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_temp.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright 2010 PathScale inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Martin Peres - */ - -#include - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_pm.h" - -static void -nouveau_temp_vbios_parse(struct drm_device *dev, u8 *temp) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants; - struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp; - int i, headerlen, recordlen, entries; - - if (!temp) { - NV_DEBUG(dev, "temperature table pointer invalid\n"); - return; - } - - /* Set the default sensor's contants */ - sensor->offset_constant = 0; - sensor->offset_mult = 0; - sensor->offset_div = 1; - sensor->slope_mult = 1; - sensor->slope_div = 1; - - /* Set the default temperature thresholds */ - temps->critical = 110; - temps->down_clock = 100; - temps->fan_boost = 90; - - /* Set the default range for the pwm fan */ - pm->fan.min_duty = 30; - pm->fan.max_duty = 100; - - /* Set the known default values to setup the temperature sensor */ - if (dev_priv->card_type >= NV_40) { - switch (dev_priv->chipset) { - case 0x43: - sensor->offset_mult = 32060; - sensor->offset_div = 1000; - sensor->slope_mult = 792; - sensor->slope_div = 1000; - break; - - case 0x44: - case 0x47: - case 0x4a: - sensor->offset_mult = 27839; - sensor->offset_div = 1000; - sensor->slope_mult = 780; - sensor->slope_div = 1000; - break; - - case 0x46: - sensor->offset_mult = -24775; - sensor->offset_div = 100; - sensor->slope_mult = 467; - sensor->slope_div = 10000; - break; - - case 0x49: - sensor->offset_mult = -25051; - sensor->offset_div = 100; - sensor->slope_mult = 458; - sensor->slope_div = 10000; - break; - - case 0x4b: - sensor->offset_mult = -24088; - sensor->offset_div = 100; - sensor->slope_mult = 442; - sensor->slope_div = 10000; - break; - - case 0x50: - sensor->offset_mult = -22749; - sensor->offset_div = 100; - sensor->slope_mult = 431; - sensor->slope_div = 10000; - break; - - case 0x67: - sensor->offset_mult = -26149; - sensor->offset_div = 100; - sensor->slope_mult = 484; - sensor->slope_div = 10000; - break; - } - } - - headerlen = temp[1]; - recordlen = temp[2]; - entries = temp[3]; - temp = temp + headerlen; - - /* Read the entries from the table */ - for (i = 0; i < entries; i++) { - s16 value = ROM16(temp[1]); - - switch (temp[0]) { - case 0x01: - if ((value & 0x8f) == 0) - sensor->offset_constant = (value >> 9) & 0x7f; - break; - - case 0x04: - if ((value & 0xf00f) == 0xa000) /* core */ - temps->critical = (value&0x0ff0) >> 4; - break; - - case 0x07: - if ((value & 0xf00f) == 0xa000) /* core */ - temps->down_clock = (value&0x0ff0) >> 4; - break; - - case 0x08: - if ((value & 0xf00f) == 0xa000) /* core */ - temps->fan_boost = (value&0x0ff0) >> 4; - break; - - case 0x10: - sensor->offset_mult = value; - break; - - case 0x11: - sensor->offset_div = value; - break; - - case 0x12: - sensor->slope_mult = value; - break; - - case 0x13: - sensor->slope_div = value; - break; - case 0x22: - pm->fan.min_duty = value & 0xff; - pm->fan.max_duty = (value & 0xff00) >> 8; - break; - case 0x26: - pm->fan.pwm_freq = value; - break; - } - temp += recordlen; - } - - nouveau_temp_safety_checks(dev); - - /* check the fan min/max settings */ - if (pm->fan.min_duty < 10) - pm->fan.min_duty = 10; - if (pm->fan.max_duty > 100) - pm->fan.max_duty = 100; - if (pm->fan.max_duty < pm->fan.min_duty) - pm->fan.max_duty = pm->fan.min_duty; -} - -static int -nv40_sensor_setup(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants; - s32 offset = sensor->offset_mult / sensor->offset_div; - s32 sensor_calibration; - - /* set up the sensors */ - sensor_calibration = 120 - offset - sensor->offset_constant; - sensor_calibration = sensor_calibration * sensor->slope_div / - sensor->slope_mult; - - if (dev_priv->chipset >= 0x46) - sensor_calibration |= 0x80000000; - else - sensor_calibration |= 0x10000000; - - nv_wr32(dev, 0x0015b0, sensor_calibration); - - /* Wait for the sensor to update */ - msleep(5); - - /* read */ - return nv_rd32(dev, 0x0015b4) & 0x1fff; -} - -int -nv40_temp_get(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants; - int offset = sensor->offset_mult / sensor->offset_div; - int core_temp; - - if (dev_priv->card_type >= NV_50) { - core_temp = nv_rd32(dev, 0x20008); - } else { - core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff; - /* Setup the sensor if the temperature is 0 */ - if (core_temp == 0) - core_temp = nv40_sensor_setup(dev); - } - - core_temp = core_temp * sensor->slope_mult / sensor->slope_div; - core_temp = core_temp + offset + sensor->offset_constant; - - return core_temp; -} - -int -nv84_temp_get(struct drm_device *dev) -{ - return nv_rd32(dev, 0x20400); -} - -void -nouveau_temp_safety_checks(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_threshold_temp *temps = &pm->threshold_temp; - - if (temps->critical > 120) - temps->critical = 120; - else if (temps->critical < 80) - temps->critical = 80; - - if (temps->down_clock > 110) - temps->down_clock = 110; - else if (temps->down_clock < 60) - temps->down_clock = 60; - - if (temps->fan_boost > 100) - temps->fan_boost = 100; - else if (temps->fan_boost < 40) - temps->fan_boost = 40; -} - -static bool -probe_monitoring_device(struct nouveau_i2c_chan *i2c, - struct i2c_board_info *info) -{ - struct i2c_client *client; - - request_module("%s%s", I2C_MODULE_PREFIX, info->type); - - client = i2c_new_device(&i2c->adapter, info); - if (!client) - return false; - - if (!client->driver || client->driver->detect(client, info)) { - i2c_unregister_device(client); - return false; - } - - return true; -} - -static void -nouveau_temp_probe_i2c(struct drm_device *dev) -{ - struct i2c_board_info info[] = { - { I2C_BOARD_INFO("w83l785ts", 0x2d) }, - { I2C_BOARD_INFO("w83781d", 0x2d) }, - { I2C_BOARD_INFO("adt7473", 0x2e) }, - { I2C_BOARD_INFO("f75375", 0x2e) }, - { I2C_BOARD_INFO("lm99", 0x4c) }, - { } - }; - - nouveau_i2c_identify(dev, "monitoring device", info, - probe_monitoring_device, NV_I2C_DEFAULT(0)); -} - -void -nouveau_temp_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; - struct bit_entry P; - u8 *temp = NULL; - - if (bios->type == NVBIOS_BIT) { - if (bit_table(dev, 'P', &P)) - return; - - if (P.version == 1) - temp = ROMPTR(dev, P.data[12]); - else if (P.version == 2) - temp = ROMPTR(dev, P.data[16]); - else - NV_WARN(dev, "unknown temp for BIT P %d\n", P.version); - - nouveau_temp_vbios_parse(dev, temp); - } - - nouveau_temp_probe_i2c(dev); -} - -void -nouveau_temp_fini(struct drm_device *dev) -{ - -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ttm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ttm.c deleted file mode 100644 index bd35f930..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA, - * All Rights Reserved. - * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA, - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" - -#include "nouveau_drv.h" - -int -nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv = filp->private_data; - struct drm_nouveau_private *dev_priv = - file_priv->minor->dev->dev_private; - - if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) - return drm_mmap(filp, vma); - - return ttm_bo_mmap(filp, vma, &dev_priv->ttm.bdev); -} - -static int -nouveau_ttm_mem_global_init(struct drm_global_reference *ref) -{ - return ttm_mem_global_init(ref->object); -} - -static void -nouveau_ttm_mem_global_release(struct drm_global_reference *ref) -{ - ttm_mem_global_release(ref->object); -} - -int -nouveau_ttm_global_init(struct drm_nouveau_private *dev_priv) -{ - struct drm_global_reference *global_ref; - int ret; - - global_ref = &dev_priv->ttm.mem_global_ref; - global_ref->global_type = DRM_GLOBAL_TTM_MEM; - global_ref->size = sizeof(struct ttm_mem_global); - global_ref->init = &nouveau_ttm_mem_global_init; - global_ref->release = &nouveau_ttm_mem_global_release; - - ret = drm_global_item_ref(global_ref); - if (unlikely(ret != 0)) { - DRM_ERROR("Failed setting up TTM memory accounting\n"); - dev_priv->ttm.mem_global_ref.release = NULL; - return ret; - } - - dev_priv->ttm.bo_global_ref.mem_glob = global_ref->object; - global_ref = &dev_priv->ttm.bo_global_ref.ref; - global_ref->global_type = DRM_GLOBAL_TTM_BO; - global_ref->size = sizeof(struct ttm_bo_global); - global_ref->init = &ttm_bo_global_init; - global_ref->release = &ttm_bo_global_release; - - ret = drm_global_item_ref(global_ref); - if (unlikely(ret != 0)) { - DRM_ERROR("Failed setting up TTM BO subsystem\n"); - drm_global_item_unref(&dev_priv->ttm.mem_global_ref); - dev_priv->ttm.mem_global_ref.release = NULL; - return ret; - } - - return 0; -} - -void -nouveau_ttm_global_release(struct drm_nouveau_private *dev_priv) -{ - if (dev_priv->ttm.mem_global_ref.release == NULL) - return; - - drm_global_item_unref(&dev_priv->ttm.bo_global_ref.ref); - drm_global_item_unref(&dev_priv->ttm.mem_global_ref); - dev_priv->ttm.mem_global_ref.release = NULL; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.c deleted file mode 100644 index e51b5150..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2010 Nouveau Project - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include - -#include "nouveau_util.h" - -static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); - -void -nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value) -{ - while (bf->name) { - if (value & bf->mask) { - printk(" %s", bf->name); - value &= ~bf->mask; - } - - bf++; - } - - if (value) - printk(" (unknown bits 0x%08x)", value); -} - -const struct nouveau_enum * -nouveau_enum_find(const struct nouveau_enum *en, u32 value) -{ - while (en->name) { - if (en->value == value) - return en; - en++; - } - - return NULL; -} - -void -nouveau_enum_print(const struct nouveau_enum *en, u32 value) -{ - en = nouveau_enum_find(en, value); - if (en) { - printk("%s", en->name); - return; - } - - printk("(unknown enum 0x%08x)", value); -} - -int -nouveau_ratelimit(void) -{ - return __ratelimit(&nouveau_ratelimit_state); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.h deleted file mode 100644 index b97719fb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_util.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2010 Nouveau Project - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NOUVEAU_UTIL_H__ -#define __NOUVEAU_UTIL_H__ - -struct nouveau_bitfield { - u32 mask; - const char *name; -}; - -struct nouveau_enum { - u32 value; - const char *name; - void *data; -}; - -void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value); -void nouveau_enum_print(const struct nouveau_enum *, u32 value); -const struct nouveau_enum * -nouveau_enum_find(const struct nouveau_enum *, u32 value); - -int nouveau_ratelimit(void); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.c deleted file mode 100644 index 2bf6c035..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_mm.h" -#include "nouveau_vm.h" - -void -nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node) -{ - struct nouveau_vm *vm = vma->vm; - struct nouveau_mm_node *r; - int big = vma->node->type != vm->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 pde = (offset >> vm->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits; - u32 max = 1 << (vm->pgt_bits - bits); - u32 end, len; - - delta = 0; - list_for_each_entry(r, &node->regions, rl_entry) { - u64 phys = (u64)r->offset << 12; - u32 num = r->length >> bits; - - while (num) { - struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big]; - - end = (pte + num); - if (unlikely(end >= max)) - end = max; - len = end - pte; - - vm->map(vma, pgt, node, pte, len, phys, delta); - - num -= len; - pte += len; - if (unlikely(end >= max)) { - phys += len << (bits + 12); - pde++; - pte = 0; - } - - delta += (u64)len << vma->node->type; - } - } - - vm->flush(vm); -} - -void -nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node) -{ - nouveau_vm_map_at(vma, 0, node); -} - -void -nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length, - struct nouveau_mem *mem) -{ - struct nouveau_vm *vm = vma->vm; - dma_addr_t *list = mem->pages; - int big = vma->node->type != vm->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 num = length >> vma->node->type; - u32 pde = (offset >> vm->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits; - u32 max = 1 << (vm->pgt_bits - bits); - u32 end, len; - - while (num) { - struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big]; - - end = (pte + num); - if (unlikely(end >= max)) - end = max; - len = end - pte; - - vm->map_sg(vma, pgt, mem, pte, len, list); - - num -= len; - pte += len; - list += len; - if (unlikely(end >= max)) { - pde++; - pte = 0; - } - } - - vm->flush(vm); -} - -void -nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length) -{ - struct nouveau_vm *vm = vma->vm; - int big = vma->node->type != vm->spg_shift; - u32 offset = vma->node->offset + (delta >> 12); - u32 bits = vma->node->type - 12; - u32 num = length >> vma->node->type; - u32 pde = (offset >> vm->pgt_bits) - vm->fpde; - u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits; - u32 max = 1 << (vm->pgt_bits - bits); - u32 end, len; - - while (num) { - struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big]; - - end = (pte + num); - if (unlikely(end >= max)) - end = max; - len = end - pte; - - vm->unmap(pgt, pte, len); - - num -= len; - pte += len; - if (unlikely(end >= max)) { - pde++; - pte = 0; - } - } - - vm->flush(vm); -} - -void -nouveau_vm_unmap(struct nouveau_vma *vma) -{ - nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12); -} - -static void -nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde) -{ - struct nouveau_vm_pgd *vpgd; - struct nouveau_vm_pgt *vpgt; - struct nouveau_gpuobj *pgt; - u32 pde; - - for (pde = fpde; pde <= lpde; pde++) { - vpgt = &vm->pgt[pde - vm->fpde]; - if (--vpgt->refcount[big]) - continue; - - pgt = vpgt->obj[big]; - vpgt->obj[big] = NULL; - - list_for_each_entry(vpgd, &vm->pgd_list, head) { - vm->map_pgt(vpgd->obj, pde, vpgt->obj); - } - - mutex_unlock(&vm->mm.mutex); - nouveau_gpuobj_ref(NULL, &pgt); - mutex_lock(&vm->mm.mutex); - } -} - -static int -nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type) -{ - struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; - struct nouveau_vm_pgd *vpgd; - struct nouveau_gpuobj *pgt; - int big = (type != vm->spg_shift); - u32 pgt_size; - int ret; - - pgt_size = (1 << (vm->pgt_bits + 12)) >> type; - pgt_size *= 8; - - mutex_unlock(&vm->mm.mutex); - ret = nouveau_gpuobj_new(vm->dev, NULL, pgt_size, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &pgt); - mutex_lock(&vm->mm.mutex); - if (unlikely(ret)) - return ret; - - /* someone beat us to filling the PDE while we didn't have the lock */ - if (unlikely(vpgt->refcount[big]++)) { - mutex_unlock(&vm->mm.mutex); - nouveau_gpuobj_ref(NULL, &pgt); - mutex_lock(&vm->mm.mutex); - return 0; - } - - vpgt->obj[big] = pgt; - list_for_each_entry(vpgd, &vm->pgd_list, head) { - vm->map_pgt(vpgd->obj, pde, vpgt->obj); - } - - return 0; -} - -int -nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift, - u32 access, struct nouveau_vma *vma) -{ - u32 align = (1 << page_shift) >> 12; - u32 msize = size >> 12; - u32 fpde, lpde, pde; - int ret; - - mutex_lock(&vm->mm.mutex); - ret = nouveau_mm_get(&vm->mm, page_shift, msize, 0, align, &vma->node); - if (unlikely(ret != 0)) { - mutex_unlock(&vm->mm.mutex); - return ret; - } - - fpde = (vma->node->offset >> vm->pgt_bits); - lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits; - for (pde = fpde; pde <= lpde; pde++) { - struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; - int big = (vma->node->type != vm->spg_shift); - - if (likely(vpgt->refcount[big])) { - vpgt->refcount[big]++; - continue; - } - - ret = nouveau_vm_map_pgt(vm, pde, vma->node->type); - if (ret) { - if (pde != fpde) - nouveau_vm_unmap_pgt(vm, big, fpde, pde - 1); - nouveau_mm_put(&vm->mm, vma->node); - mutex_unlock(&vm->mm.mutex); - vma->node = NULL; - return ret; - } - } - mutex_unlock(&vm->mm.mutex); - - vma->vm = vm; - vma->offset = (u64)vma->node->offset << 12; - vma->access = access; - return 0; -} - -void -nouveau_vm_put(struct nouveau_vma *vma) -{ - struct nouveau_vm *vm = vma->vm; - u32 fpde, lpde; - - if (unlikely(vma->node == NULL)) - return; - fpde = (vma->node->offset >> vm->pgt_bits); - lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits; - - mutex_lock(&vm->mm.mutex); - nouveau_vm_unmap_pgt(vm, vma->node->type != vm->spg_shift, fpde, lpde); - nouveau_mm_put(&vm->mm, vma->node); - vma->node = NULL; - mutex_unlock(&vm->mm.mutex); -} - -int -nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, - struct nouveau_vm **pvm) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_vm *vm; - u64 mm_length = (offset + length) - mm_offset; - u32 block, pgt_bits; - int ret; - - vm = kzalloc(sizeof(*vm), GFP_KERNEL); - if (!vm) - return -ENOMEM; - - if (dev_priv->card_type == NV_50) { - vm->map_pgt = nv50_vm_map_pgt; - vm->map = nv50_vm_map; - vm->map_sg = nv50_vm_map_sg; - vm->unmap = nv50_vm_unmap; - vm->flush = nv50_vm_flush; - vm->spg_shift = 12; - vm->lpg_shift = 16; - - pgt_bits = 29; - block = (1 << pgt_bits); - if (length < block) - block = length; - - } else - if (dev_priv->card_type >= NV_C0) { - vm->map_pgt = nvc0_vm_map_pgt; - vm->map = nvc0_vm_map; - vm->map_sg = nvc0_vm_map_sg; - vm->unmap = nvc0_vm_unmap; - vm->flush = nvc0_vm_flush; - vm->spg_shift = 12; - vm->lpg_shift = 17; - pgt_bits = 27; - block = 4096; - } else { - kfree(vm); - return -ENOSYS; - } - - vm->fpde = offset >> pgt_bits; - vm->lpde = (offset + length - 1) >> pgt_bits; - vm->pgt = kcalloc(vm->lpde - vm->fpde + 1, sizeof(*vm->pgt), GFP_KERNEL); - if (!vm->pgt) { - kfree(vm); - return -ENOMEM; - } - - INIT_LIST_HEAD(&vm->pgd_list); - vm->dev = dev; - vm->refcount = 1; - vm->pgt_bits = pgt_bits - 12; - - ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12, - block >> 12); - if (ret) { - kfree(vm); - return ret; - } - - *pvm = vm; - return 0; -} - -static int -nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd) -{ - struct nouveau_vm_pgd *vpgd; - int i; - - if (!pgd) - return 0; - - vpgd = kzalloc(sizeof(*vpgd), GFP_KERNEL); - if (!vpgd) - return -ENOMEM; - - nouveau_gpuobj_ref(pgd, &vpgd->obj); - - mutex_lock(&vm->mm.mutex); - for (i = vm->fpde; i <= vm->lpde; i++) - vm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj); - list_add(&vpgd->head, &vm->pgd_list); - mutex_unlock(&vm->mm.mutex); - return 0; -} - -static void -nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd) -{ - struct nouveau_vm_pgd *vpgd, *tmp; - struct nouveau_gpuobj *pgd = NULL; - - if (!mpgd) - return; - - mutex_lock(&vm->mm.mutex); - list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { - if (vpgd->obj == mpgd) { - pgd = vpgd->obj; - list_del(&vpgd->head); - kfree(vpgd); - break; - } - } - mutex_unlock(&vm->mm.mutex); - - nouveau_gpuobj_ref(NULL, &pgd); -} - -static void -nouveau_vm_del(struct nouveau_vm *vm) -{ - struct nouveau_vm_pgd *vpgd, *tmp; - - list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { - nouveau_vm_unlink(vm, vpgd->obj); - } - - nouveau_mm_fini(&vm->mm); - kfree(vm->pgt); - kfree(vm); -} - -int -nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, - struct nouveau_gpuobj *pgd) -{ - struct nouveau_vm *vm; - int ret; - - vm = ref; - if (vm) { - ret = nouveau_vm_link(vm, pgd); - if (ret) - return ret; - - vm->refcount++; - } - - vm = *ptr; - *ptr = ref; - - if (vm) { - nouveau_vm_unlink(vm, pgd); - - if (--vm->refcount == 0) - nouveau_vm_del(vm); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.h deleted file mode 100644 index 4fb6e728..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_vm.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#ifndef __NOUVEAU_VM_H__ -#define __NOUVEAU_VM_H__ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_mm.h" - -struct nouveau_vm_pgt { - struct nouveau_gpuobj *obj[2]; - u32 refcount[2]; -}; - -struct nouveau_vm_pgd { - struct list_head head; - struct nouveau_gpuobj *obj; -}; - -struct nouveau_vma { - struct list_head head; - int refcount; - struct nouveau_vm *vm; - struct nouveau_mm_node *node; - u64 offset; - u32 access; -}; - -struct nouveau_vm { - struct drm_device *dev; - struct nouveau_mm mm; - int refcount; - - struct list_head pgd_list; - atomic_t engref[16]; - - struct nouveau_vm_pgt *pgt; - u32 fpde; - u32 lpde; - - u32 pgt_bits; - u8 spg_shift; - u8 lpg_shift; - - void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]); - void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *, - struct nouveau_mem *, u32 pte, u32 cnt, - u64 phys, u64 delta); - void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *, - struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); - void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt); - void (*flush)(struct nouveau_vm *); -}; - -/* nouveau_vm.c */ -int nouveau_vm_new(struct drm_device *, u64 offset, u64 length, u64 mm_offset, - struct nouveau_vm **); -int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **, - struct nouveau_gpuobj *pgd); -int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift, - u32 access, struct nouveau_vma *); -void nouveau_vm_put(struct nouveau_vma *); -void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *); -void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *); -void nouveau_vm_unmap(struct nouveau_vma *); -void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length); -void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length, - struct nouveau_mem *); - -/* nv50_vm.c */ -void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]); -void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, - struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta); -void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, - struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); -void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); -void nv50_vm_flush(struct nouveau_vm *); -void nv50_vm_flush_engine(struct drm_device *, int engine); - -/* nvc0_vm.c */ -void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]); -void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, - struct nouveau_mem *, u32 pte, u32 cnt, u64 phys, u64 delta); -void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, - struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *); -void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); -void nvc0_vm_flush(struct nouveau_vm *); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_volt.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_volt.c deleted file mode 100644 index b010cb99..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nouveau_volt.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_pm.h" -#include "nouveau_gpio.h" - -static const enum dcb_gpio_tag vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 }; -static int nr_vidtag = sizeof(vidtag) / sizeof(vidtag[0]); - -int -nouveau_voltage_gpio_get(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; - u8 vid = 0; - int i; - - for (i = 0; i < nr_vidtag; i++) { - if (!(volt->vid_mask & (1 << i))) - continue; - - vid |= nouveau_gpio_func_get(dev, vidtag[i]) << i; - } - - return nouveau_volt_lvl_lookup(dev, vid); -} - -int -nouveau_voltage_gpio_set(struct drm_device *dev, int voltage) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; - int vid, i; - - vid = nouveau_volt_vid_lookup(dev, voltage); - if (vid < 0) - return vid; - - for (i = 0; i < nr_vidtag; i++) { - if (!(volt->vid_mask & (1 << i))) - continue; - - nouveau_gpio_func_set(dev, vidtag[i], !!(vid & (1 << i))); - } - - return 0; -} - -int -nouveau_volt_vid_lookup(struct drm_device *dev, int voltage) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; - int i; - - for (i = 0; i < volt->nr_level; i++) { - if (volt->level[i].voltage == voltage) - return volt->level[i].vid; - } - - return -ENOENT; -} - -int -nouveau_volt_lvl_lookup(struct drm_device *dev, int vid) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; - int i; - - for (i = 0; i < volt->nr_level; i++) { - if (volt->level[i].vid == vid) - return volt->level[i].voltage; - } - - return -ENOENT; -} - -void -nouveau_volt_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_engine *pm = &dev_priv->engine.pm; - struct nouveau_pm_voltage *voltage = &pm->voltage; - struct nvbios *bios = &dev_priv->vbios; - struct bit_entry P; - u8 *volt = NULL, *entry; - int i, headerlen, recordlen, entries, vidmask, vidshift; - - if (bios->type == NVBIOS_BIT) { - if (bit_table(dev, 'P', &P)) - return; - - if (P.version == 1) - volt = ROMPTR(dev, P.data[16]); - else - if (P.version == 2) - volt = ROMPTR(dev, P.data[12]); - else { - NV_WARN(dev, "unknown volt for BIT P %d\n", P.version); - } - } else { - if (bios->data[bios->offset + 6] < 0x27) { - NV_DEBUG(dev, "BMP version too old for voltage\n"); - return; - } - - volt = ROMPTR(dev, bios->data[bios->offset + 0x98]); - } - - if (!volt) { - NV_DEBUG(dev, "voltage table pointer invalid\n"); - return; - } - - switch (volt[0]) { - case 0x10: - case 0x11: - case 0x12: - headerlen = 5; - recordlen = volt[1]; - entries = volt[2]; - vidshift = 0; - vidmask = volt[4]; - break; - case 0x20: - headerlen = volt[1]; - recordlen = volt[3]; - entries = volt[2]; - vidshift = 0; /* could be vidshift like 0x30? */ - vidmask = volt[5]; - break; - case 0x30: - headerlen = volt[1]; - recordlen = volt[2]; - entries = volt[3]; - vidmask = volt[4]; - /* no longer certain what volt[5] is, if it's related to - * the vid shift then it's definitely not a function of - * how many bits are set. - * - * after looking at a number of nva3+ vbios images, they - * all seem likely to have a static shift of 2.. lets - * go with that for now until proven otherwise. - */ - vidshift = 2; - break; - case 0x40: - headerlen = volt[1]; - recordlen = volt[2]; - entries = volt[3]; /* not a clue what the entries are for.. */ - vidmask = volt[11]; /* guess.. */ - vidshift = 0; - break; - default: - NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]); - return; - } - - /* validate vid mask */ - voltage->vid_mask = vidmask; - if (!voltage->vid_mask) - return; - - i = 0; - while (vidmask) { - if (i > nr_vidtag) { - NV_DEBUG(dev, "vid bit %d unknown\n", i); - return; - } - - if (!nouveau_gpio_func_valid(dev, vidtag[i])) { - NV_DEBUG(dev, "vid bit %d has no gpio tag\n", i); - return; - } - - vidmask >>= 1; - i++; - } - - /* parse vbios entries into common format */ - voltage->version = volt[0]; - if (voltage->version < 0x40) { - voltage->nr_level = entries; - voltage->level = - kcalloc(entries, sizeof(*voltage->level), GFP_KERNEL); - if (!voltage->level) - return; - - entry = volt + headerlen; - for (i = 0; i < entries; i++, entry += recordlen) { - voltage->level[i].voltage = entry[0] * 10000; - voltage->level[i].vid = entry[1] >> vidshift; - } - } else { - u32 volt_uv = ROM32(volt[4]); - s16 step_uv = ROM16(volt[8]); - u8 vid; - - voltage->nr_level = voltage->vid_mask + 1; - voltage->level = kcalloc(voltage->nr_level, - sizeof(*voltage->level), GFP_KERNEL); - if (!voltage->level) - return; - - for (vid = 0; vid <= voltage->vid_mask; vid++) { - voltage->level[vid].voltage = volt_uv; - voltage->level[vid].vid = vid; - volt_uv += step_uv; - } - } - - voltage->supported = true; -} - -void -nouveau_volt_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pm_voltage *volt = &dev_priv->engine.pm.voltage; - - kfree(volt->level); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_crtc.c deleted file mode 100644 index 728d0758..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_crtc.c +++ /dev/null @@ -1,1063 +0,0 @@ -/* - * Copyright 1993-2003 NVIDIA, Corporation - * Copyright 2006 Dave Airlie - * Copyright 2007 Maarten Maathuis - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nouveau_fb.h" -#include "nouveau_hw.h" -#include "nvreg.h" -#include "nouveau_fbcon.h" - -static int -nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb); - -static void -crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index) -{ - NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index, - crtcstate->CRTC[index]); -} - -static void nv_crtc_set_digital_vibrance(struct drm_crtc *crtc, int level) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - - regp->CRTC[NV_CIO_CRE_CSB] = nv_crtc->saturation = level; - if (nv_crtc->saturation && nv_gf4_disp_arch(crtc->dev)) { - regp->CRTC[NV_CIO_CRE_CSB] = 0x80; - regp->CRTC[NV_CIO_CRE_5B] = nv_crtc->saturation << 2; - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_5B); - } - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_CSB); -} - -static void nv_crtc_set_image_sharpening(struct drm_crtc *crtc, int level) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - - nv_crtc->sharpness = level; - if (level < 0) /* blur is in hw range 0x3f -> 0x20 */ - level += 0x40; - regp->ramdac_634 = level; - NVWriteRAMDAC(crtc->dev, nv_crtc->index, NV_PRAMDAC_634, regp->ramdac_634); -} - -#define PLLSEL_VPLL1_MASK \ - (NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL \ - | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2) -#define PLLSEL_VPLL2_MASK \ - (NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2 \ - | NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2) -#define PLLSEL_TV_MASK \ - (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ - | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1 \ - | NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2 \ - | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2) - -/* NV4x 0x40.. pll notes: - * gpu pll: 0x4000 + 0x4004 - * ?gpu? pll: 0x4008 + 0x400c - * vpll1: 0x4010 + 0x4014 - * vpll2: 0x4018 + 0x401c - * mpll: 0x4020 + 0x4024 - * mpll: 0x4038 + 0x403c - * - * the first register of each pair has some unknown details: - * bits 0-7: redirected values from elsewhere? (similar to PLL_SETUP_CONTROL?) - * bits 20-23: (mpll) something to do with post divider? - * bits 28-31: related to single stage mode? (bit 8/12) - */ - -static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mode * mode, int dot_clock) -{ - struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nv04_mode_state *state = &dev_priv->mode_reg; - struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index]; - struct nouveau_pll_vals *pv = ®p->pllvals; - struct pll_lims pll_lim; - - if (get_pll_limits(dev, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0, &pll_lim)) - return; - - /* NM2 == 0 is used to determine single stage mode on two stage plls */ - pv->NM2 = 0; - - /* for newer nv4x the blob uses only the first stage of the vpll below a - * certain clock. for a certain nv4b this is 150MHz. since the max - * output frequency of the first stage for this card is 300MHz, it is - * assumed the threshold is given by vco1 maxfreq/2 - */ - /* for early nv4x, specifically nv40 and *some* nv43 (devids 0 and 6, - * not 8, others unknown), the blob always uses both plls. no problem - * has yet been observed in allowing the use a single stage pll on all - * nv43 however. the behaviour of single stage use is untested on nv40 - */ - if (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2)) - memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2)); - - if (!nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv)) - return; - - state->pllsel &= PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK; - - /* The blob uses this always, so let's do the same */ - if (dev_priv->card_type == NV_40) - state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE; - /* again nv40 and some nv43 act more like nv3x as described above */ - if (dev_priv->chipset < 0x41) - state->pllsel |= NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL | - NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL; - state->pllsel |= nv_crtc->index ? PLLSEL_VPLL2_MASK : PLLSEL_VPLL1_MASK; - - if (pv->NM2) - NV_DEBUG_KMS(dev, "vpll: n1 %d n2 %d m1 %d m2 %d log2p %d\n", - pv->N1, pv->N2, pv->M1, pv->M2, pv->log2P); - else - NV_DEBUG_KMS(dev, "vpll: n %d m %d log2p %d\n", - pv->N1, pv->M1, pv->log2P); - - nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); -} - -static void -nv_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = crtc->dev; - unsigned char seq1 = 0, crtc17 = 0; - unsigned char crtc1A; - - NV_DEBUG_KMS(dev, "Setting dpms mode %d on CRTC %d\n", mode, - nv_crtc->index); - - if (nv_crtc->last_dpms == mode) /* Don't do unnecessary mode changes. */ - return; - - nv_crtc->last_dpms = mode; - - if (nv_two_heads(dev)) - NVSetOwner(dev, nv_crtc->index); - - /* nv4ref indicates these two RPC1 bits inhibit h/v sync */ - crtc1A = NVReadVgaCrtc(dev, nv_crtc->index, - NV_CIO_CRE_RPC1_INDEX) & ~0xC0; - switch (mode) { - case DRM_MODE_DPMS_STANDBY: - /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ - seq1 = 0x20; - crtc17 = 0x80; - crtc1A |= 0x80; - break; - case DRM_MODE_DPMS_SUSPEND: - /* Screen: Off; HSync: On, VSync: Off -- Not Supported */ - seq1 = 0x20; - crtc17 = 0x80; - crtc1A |= 0x40; - break; - case DRM_MODE_DPMS_OFF: - /* Screen: Off; HSync: Off, VSync: Off */ - seq1 = 0x20; - crtc17 = 0x00; - crtc1A |= 0xC0; - break; - case DRM_MODE_DPMS_ON: - default: - /* Screen: On; HSync: On, VSync: On */ - seq1 = 0x00; - crtc17 = 0x80; - break; - } - - NVVgaSeqReset(dev, nv_crtc->index, true); - /* Each head has it's own sequencer, so we can turn it off when we want */ - seq1 |= (NVReadVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX) & ~0x20); - NVWriteVgaSeq(dev, nv_crtc->index, NV_VIO_SR_CLOCK_INDEX, seq1); - crtc17 |= (NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX) & ~0x80); - mdelay(10); - NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CR_MODE_INDEX, crtc17); - NVVgaSeqReset(dev, nv_crtc->index, false); - - NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); -} - -static bool -nv_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void -nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - struct drm_framebuffer *fb = crtc->fb; - - /* Calculate our timings */ - int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; - int horizStart = (mode->crtc_hsync_start >> 3) + 1; - int horizEnd = (mode->crtc_hsync_end >> 3) + 1; - int horizTotal = (mode->crtc_htotal >> 3) - 5; - int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1; - int horizBlankEnd = (mode->crtc_htotal >> 3) - 1; - int vertDisplay = mode->crtc_vdisplay - 1; - int vertStart = mode->crtc_vsync_start - 1; - int vertEnd = mode->crtc_vsync_end - 1; - int vertTotal = mode->crtc_vtotal - 2; - int vertBlankStart = mode->crtc_vdisplay - 1; - int vertBlankEnd = mode->crtc_vtotal - 1; - - struct drm_encoder *encoder; - bool fp_output = false; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (encoder->crtc == crtc && - (nv_encoder->dcb->type == OUTPUT_LVDS || - nv_encoder->dcb->type == OUTPUT_TMDS)) - fp_output = true; - } - - if (fp_output) { - vertStart = vertTotal - 3; - vertEnd = vertTotal - 2; - vertBlankStart = vertStart; - horizStart = horizTotal - 5; - horizEnd = horizTotal - 2; - horizBlankEnd = horizTotal + 4; -#if 0 - if (dev->overlayAdaptor && dev_priv->card_type >= NV_10) - /* This reportedly works around some video overlay bandwidth problems */ - horizTotal += 2; -#endif - } - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - vertTotal |= 1; - -#if 0 - ErrorF("horizDisplay: 0x%X \n", horizDisplay); - ErrorF("horizStart: 0x%X \n", horizStart); - ErrorF("horizEnd: 0x%X \n", horizEnd); - ErrorF("horizTotal: 0x%X \n", horizTotal); - ErrorF("horizBlankStart: 0x%X \n", horizBlankStart); - ErrorF("horizBlankEnd: 0x%X \n", horizBlankEnd); - ErrorF("vertDisplay: 0x%X \n", vertDisplay); - ErrorF("vertStart: 0x%X \n", vertStart); - ErrorF("vertEnd: 0x%X \n", vertEnd); - ErrorF("vertTotal: 0x%X \n", vertTotal); - ErrorF("vertBlankStart: 0x%X \n", vertBlankStart); - ErrorF("vertBlankEnd: 0x%X \n", vertBlankEnd); -#endif - - /* - * compute correct Hsync & Vsync polarity - */ - if ((mode->flags & (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)) - && (mode->flags & (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))) { - - regp->MiscOutReg = 0x23; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - regp->MiscOutReg |= 0x40; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - regp->MiscOutReg |= 0x80; - } else { - int vdisplay = mode->vdisplay; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - vdisplay *= 2; - if (mode->vscan > 1) - vdisplay *= mode->vscan; - if (vdisplay < 400) - regp->MiscOutReg = 0xA3; /* +hsync -vsync */ - else if (vdisplay < 480) - regp->MiscOutReg = 0x63; /* -hsync +vsync */ - else if (vdisplay < 768) - regp->MiscOutReg = 0xE3; /* -hsync -vsync */ - else - regp->MiscOutReg = 0x23; /* +hsync +vsync */ - } - - regp->MiscOutReg |= (mode->clock_index & 0x03) << 2; - - /* - * Time Sequencer - */ - regp->Sequencer[NV_VIO_SR_RESET_INDEX] = 0x00; - /* 0x20 disables the sequencer */ - if (mode->flags & DRM_MODE_FLAG_CLKDIV2) - regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x29; - else - regp->Sequencer[NV_VIO_SR_CLOCK_INDEX] = 0x21; - regp->Sequencer[NV_VIO_SR_PLANE_MASK_INDEX] = 0x0F; - regp->Sequencer[NV_VIO_SR_CHAR_MAP_INDEX] = 0x00; - regp->Sequencer[NV_VIO_SR_MEM_MODE_INDEX] = 0x0E; - - /* - * CRTC - */ - regp->CRTC[NV_CIO_CR_HDT_INDEX] = horizTotal; - regp->CRTC[NV_CIO_CR_HDE_INDEX] = horizDisplay; - regp->CRTC[NV_CIO_CR_HBS_INDEX] = horizBlankStart; - regp->CRTC[NV_CIO_CR_HBE_INDEX] = (1 << 7) | - XLATE(horizBlankEnd, 0, NV_CIO_CR_HBE_4_0); - regp->CRTC[NV_CIO_CR_HRS_INDEX] = horizStart; - regp->CRTC[NV_CIO_CR_HRE_INDEX] = XLATE(horizBlankEnd, 5, NV_CIO_CR_HRE_HBE_5) | - XLATE(horizEnd, 0, NV_CIO_CR_HRE_4_0); - regp->CRTC[NV_CIO_CR_VDT_INDEX] = vertTotal; - regp->CRTC[NV_CIO_CR_OVL_INDEX] = XLATE(vertStart, 9, NV_CIO_CR_OVL_VRS_9) | - XLATE(vertDisplay, 9, NV_CIO_CR_OVL_VDE_9) | - XLATE(vertTotal, 9, NV_CIO_CR_OVL_VDT_9) | - (1 << 4) | - XLATE(vertBlankStart, 8, NV_CIO_CR_OVL_VBS_8) | - XLATE(vertStart, 8, NV_CIO_CR_OVL_VRS_8) | - XLATE(vertDisplay, 8, NV_CIO_CR_OVL_VDE_8) | - XLATE(vertTotal, 8, NV_CIO_CR_OVL_VDT_8); - regp->CRTC[NV_CIO_CR_RSAL_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_CELL_HT_INDEX] = ((mode->flags & DRM_MODE_FLAG_DBLSCAN) ? MASK(NV_CIO_CR_CELL_HT_SCANDBL) : 0) | - 1 << 6 | - XLATE(vertBlankStart, 9, NV_CIO_CR_CELL_HT_VBS_9); - regp->CRTC[NV_CIO_CR_CURS_ST_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_CURS_END_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_SA_HI_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_SA_LO_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_TCOFF_HI_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_TCOFF_LO_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_VRS_INDEX] = vertStart; - regp->CRTC[NV_CIO_CR_VRE_INDEX] = 1 << 5 | XLATE(vertEnd, 0, NV_CIO_CR_VRE_3_0); - regp->CRTC[NV_CIO_CR_VDE_INDEX] = vertDisplay; - /* framebuffer can be larger than crtc scanout area. */ - regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = fb->pitches[0] / 8; - regp->CRTC[NV_CIO_CR_ULINE_INDEX] = 0x00; - regp->CRTC[NV_CIO_CR_VBS_INDEX] = vertBlankStart; - regp->CRTC[NV_CIO_CR_VBE_INDEX] = vertBlankEnd; - regp->CRTC[NV_CIO_CR_MODE_INDEX] = 0x43; - regp->CRTC[NV_CIO_CR_LCOMP_INDEX] = 0xff; - - /* - * Some extended CRTC registers (they are not saved with the rest of the vga regs). - */ - - /* framebuffer can be larger than crtc scanout area. */ - regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = - XLATE(fb->pitches[0] / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); - regp->CRTC[NV_CIO_CRE_42] = - XLATE(fb->pitches[0] / 8, 11, NV_CIO_CRE_42_OFFSET_11); - regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ? - MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00; - regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) | - XLATE(vertBlankStart, 10, NV_CIO_CRE_LSR_VBS_10) | - XLATE(vertStart, 10, NV_CIO_CRE_LSR_VRS_10) | - XLATE(vertDisplay, 10, NV_CIO_CRE_LSR_VDE_10) | - XLATE(vertTotal, 10, NV_CIO_CRE_LSR_VDT_10); - regp->CRTC[NV_CIO_CRE_HEB__INDEX] = XLATE(horizStart, 8, NV_CIO_CRE_HEB_HRS_8) | - XLATE(horizBlankStart, 8, NV_CIO_CRE_HEB_HBS_8) | - XLATE(horizDisplay, 8, NV_CIO_CRE_HEB_HDE_8) | - XLATE(horizTotal, 8, NV_CIO_CRE_HEB_HDT_8); - regp->CRTC[NV_CIO_CRE_EBR_INDEX] = XLATE(vertBlankStart, 11, NV_CIO_CRE_EBR_VBS_11) | - XLATE(vertStart, 11, NV_CIO_CRE_EBR_VRS_11) | - XLATE(vertDisplay, 11, NV_CIO_CRE_EBR_VDE_11) | - XLATE(vertTotal, 11, NV_CIO_CRE_EBR_VDT_11); - - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { - horizTotal = (horizTotal >> 1) & ~1; - regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = horizTotal; - regp->CRTC[NV_CIO_CRE_HEB__INDEX] |= XLATE(horizTotal, 8, NV_CIO_CRE_HEB_ILC_8); - } else - regp->CRTC[NV_CIO_CRE_ILACE__INDEX] = 0xff; /* interlace off */ - - /* - * Graphics Display Controller - */ - regp->Graphics[NV_VIO_GX_SR_INDEX] = 0x00; - regp->Graphics[NV_VIO_GX_SREN_INDEX] = 0x00; - regp->Graphics[NV_VIO_GX_CCOMP_INDEX] = 0x00; - regp->Graphics[NV_VIO_GX_ROP_INDEX] = 0x00; - regp->Graphics[NV_VIO_GX_READ_MAP_INDEX] = 0x00; - regp->Graphics[NV_VIO_GX_MODE_INDEX] = 0x40; /* 256 color mode */ - regp->Graphics[NV_VIO_GX_MISC_INDEX] = 0x05; /* map 64k mem + graphic mode */ - regp->Graphics[NV_VIO_GX_DONT_CARE_INDEX] = 0x0F; - regp->Graphics[NV_VIO_GX_BIT_MASK_INDEX] = 0xFF; - - regp->Attribute[0] = 0x00; /* standard colormap translation */ - regp->Attribute[1] = 0x01; - regp->Attribute[2] = 0x02; - regp->Attribute[3] = 0x03; - regp->Attribute[4] = 0x04; - regp->Attribute[5] = 0x05; - regp->Attribute[6] = 0x06; - regp->Attribute[7] = 0x07; - regp->Attribute[8] = 0x08; - regp->Attribute[9] = 0x09; - regp->Attribute[10] = 0x0A; - regp->Attribute[11] = 0x0B; - regp->Attribute[12] = 0x0C; - regp->Attribute[13] = 0x0D; - regp->Attribute[14] = 0x0E; - regp->Attribute[15] = 0x0F; - regp->Attribute[NV_CIO_AR_MODE_INDEX] = 0x01; /* Enable graphic mode */ - /* Non-vga */ - regp->Attribute[NV_CIO_AR_OSCAN_INDEX] = 0x00; - regp->Attribute[NV_CIO_AR_PLANE_INDEX] = 0x0F; /* enable all color planes */ - regp->Attribute[NV_CIO_AR_HPP_INDEX] = 0x00; - regp->Attribute[NV_CIO_AR_CSEL_INDEX] = 0x00; -} - -/** - * Sets up registers for the given mode/adjusted_mode pair. - * - * The clocks, CRTCs and outputs attached to this CRTC must be off. - * - * This shouldn't enable any clocks, CRTCs, or outputs, but they should - * be easily turned on/off after this. - */ -static void -nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) -{ - struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index]; - struct drm_encoder *encoder; - bool lvds_output = false, tmds_output = false, tv_output = false, - off_chip_digital = false; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - bool digital = false; - - if (encoder->crtc != crtc) - continue; - - if (nv_encoder->dcb->type == OUTPUT_LVDS) - digital = lvds_output = true; - if (nv_encoder->dcb->type == OUTPUT_TV) - tv_output = true; - if (nv_encoder->dcb->type == OUTPUT_TMDS) - digital = tmds_output = true; - if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP && digital) - off_chip_digital = true; - } - - /* Registers not directly related to the (s)vga mode */ - - /* What is the meaning of this register? */ - /* A few popular values are 0x18, 0x1c, 0x38, 0x3c */ - regp->CRTC[NV_CIO_CRE_ENH_INDEX] = savep->CRTC[NV_CIO_CRE_ENH_INDEX] & ~(1<<5); - - regp->crtc_eng_ctrl = 0; - /* Except for rare conditions I2C is enabled on the primary crtc */ - if (nv_crtc->index == 0) - regp->crtc_eng_ctrl |= NV_CRTC_FSEL_I2C; -#if 0 - /* Set overlay to desired crtc. */ - if (dev->overlayAdaptor) { - NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(dev); - if (pPriv->overlayCRTC == nv_crtc->index) - regp->crtc_eng_ctrl |= NV_CRTC_FSEL_OVERLAY; - } -#endif - - /* ADDRESS_SPACE_PNVM is the same as setting HCUR_ASI */ - regp->cursor_cfg = NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 | - NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 | - NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM; - if (dev_priv->chipset >= 0x11) - regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - regp->cursor_cfg |= NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE; - - /* Unblock some timings */ - regp->CRTC[NV_CIO_CRE_53] = 0; - regp->CRTC[NV_CIO_CRE_54] = 0; - - /* 0x00 is disabled, 0x11 is lvds, 0x22 crt and 0x88 tmds */ - if (lvds_output) - regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x11; - else if (tmds_output) - regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x88; - else - regp->CRTC[NV_CIO_CRE_SCRATCH3__INDEX] = 0x22; - - /* These values seem to vary */ - /* This register seems to be used by the bios to make certain decisions on some G70 cards? */ - regp->CRTC[NV_CIO_CRE_SCRATCH4__INDEX] = savep->CRTC[NV_CIO_CRE_SCRATCH4__INDEX]; - - nv_crtc_set_digital_vibrance(crtc, nv_crtc->saturation); - - /* probably a scratch reg, but kept for cargo-cult purposes: - * bit0: crtc0?, head A - * bit6: lvds, head A - * bit7: (only in X), head A - */ - if (nv_crtc->index == 0) - regp->CRTC[NV_CIO_CRE_4B] = savep->CRTC[NV_CIO_CRE_4B] | 0x80; - - /* The blob seems to take the current value from crtc 0, add 4 to that - * and reuse the old value for crtc 1 */ - regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] = dev_priv->saved_reg.crtc_reg[0].CRTC[NV_CIO_CRE_TVOUT_LATENCY]; - if (!nv_crtc->index) - regp->CRTC[NV_CIO_CRE_TVOUT_LATENCY] += 4; - - /* the blob sometimes sets |= 0x10 (which is the same as setting |= - * 1 << 30 on 0x60.830), for no apparent reason */ - regp->CRTC[NV_CIO_CRE_59] = off_chip_digital; - - if (dev_priv->card_type >= NV_30) - regp->CRTC[0x9f] = off_chip_digital ? 0x11 : 0x1; - - regp->crtc_830 = mode->crtc_vdisplay - 3; - regp->crtc_834 = mode->crtc_vdisplay - 1; - - if (dev_priv->card_type == NV_40) - /* This is what the blob does */ - regp->crtc_850 = NVReadCRTC(dev, 0, NV_PCRTC_850); - - if (dev_priv->card_type >= NV_30) - regp->gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT); - - if (dev_priv->card_type >= NV_10) - regp->crtc_cfg = NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC; - else - regp->crtc_cfg = NV04_PCRTC_CONFIG_START_ADDRESS_HSYNC; - - /* Some misc regs */ - if (dev_priv->card_type == NV_40) { - regp->CRTC[NV_CIO_CRE_85] = 0xFF; - regp->CRTC[NV_CIO_CRE_86] = 0x1; - } - - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8; - /* Enable slaved mode (called MODE_TV in nv4ref.h) */ - if (lvds_output || tmds_output || tv_output) - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7); - - /* Generic PRAMDAC regs */ - - if (dev_priv->card_type >= NV_10) - /* Only bit that bios and blob set. */ - regp->nv10_cursync = (1 << 25); - - regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | - NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL | - NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; - if (crtc->fb->depth == 16) - regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; - if (dev_priv->chipset >= 0x11) - regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG; - - regp->ramdac_630 = 0; /* turn off green mode (tv test pattern?) */ - regp->tv_setup = 0; - - nv_crtc_set_image_sharpening(crtc, nv_crtc->sharpness); - - /* Some values the blob sets */ - regp->ramdac_8c0 = 0x100; - regp->ramdac_a20 = 0x0; - regp->ramdac_a24 = 0xfffff; - regp->ramdac_a34 = 0x1; -} - -/** - * Sets up registers for the given mode/adjusted_mode pair. - * - * The clocks, CRTCs and outputs attached to this CRTC must be off. - * - * This shouldn't enable any clocks, CRTCs, or outputs, but they should - * be easily turned on/off after this. - */ -static int -nv_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_nouveau_private *dev_priv = dev->dev_private; - - NV_DEBUG_KMS(dev, "CTRC mode on CRTC %d:\n", nv_crtc->index); - drm_mode_debug_printmodeline(adjusted_mode); - - /* unlock must come after turning off FP_TG_CONTROL in output_prepare */ - nv_lock_vga_crtc_shadow(dev, nv_crtc->index, -1); - - nv_crtc_mode_set_vga(crtc, adjusted_mode); - /* calculated in nv04_dfp_prepare, nv40 needs it written before calculating PLLs */ - if (dev_priv->card_type == NV_40) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk); - nv_crtc_mode_set_regs(crtc, adjusted_mode); - nv_crtc_calc_state_ext(crtc, mode, adjusted_mode->clock); - return 0; -} - -static void nv_crtc_save(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct nv04_mode_state *state = &dev_priv->mode_reg; - struct nv04_crtc_reg *crtc_state = &state->crtc_reg[nv_crtc->index]; - struct nv04_mode_state *saved = &dev_priv->saved_reg; - struct nv04_crtc_reg *crtc_saved = &saved->crtc_reg[nv_crtc->index]; - - if (nv_two_heads(crtc->dev)) - NVSetOwner(crtc->dev, nv_crtc->index); - - nouveau_hw_save_state(crtc->dev, nv_crtc->index, saved); - - /* init some state to saved value */ - state->sel_clk = saved->sel_clk & ~(0x5 << 16); - crtc_state->CRTC[NV_CIO_CRE_LCD__INDEX] = crtc_saved->CRTC[NV_CIO_CRE_LCD__INDEX]; - state->pllsel = saved->pllsel & ~(PLLSEL_VPLL1_MASK | PLLSEL_VPLL2_MASK | PLLSEL_TV_MASK); - crtc_state->gpio_ext = crtc_saved->gpio_ext; -} - -static void nv_crtc_restore(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - int head = nv_crtc->index; - uint8_t saved_cr21 = dev_priv->saved_reg.crtc_reg[head].CRTC[NV_CIO_CRE_21]; - - if (nv_two_heads(crtc->dev)) - NVSetOwner(crtc->dev, head); - - nouveau_hw_load_state(crtc->dev, head, &dev_priv->saved_reg); - nv_lock_vga_crtc_shadow(crtc->dev, head, saved_cr21); - - nv_crtc->last_dpms = NV_DPMS_CLEARED; -} - -static void nv_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_crtc_helper_funcs *funcs = crtc->helper_private; - - if (nv_two_heads(dev)) - NVSetOwner(dev, nv_crtc->index); - - drm_vblank_pre_modeset(dev, nv_crtc->index); - funcs->dpms(crtc, DRM_MODE_DPMS_OFF); - - NVBlankScreen(dev, nv_crtc->index, true); - - /* Some more preparation. */ - NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_CONFIG, NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA); - if (dev_priv->card_type == NV_40) { - uint32_t reg900 = NVReadRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900); - NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_900, reg900 & ~0x10000); - } -} - -static void nv_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_crtc_helper_funcs *funcs = crtc->helper_private; - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nouveau_hw_load_state(dev, nv_crtc->index, &dev_priv->mode_reg); - nv04_crtc_mode_set_base(crtc, crtc->x, crtc->y, NULL); - -#ifdef __BIG_ENDIAN - /* turn on LFB swapping */ - { - uint8_t tmp = NVReadVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR); - tmp |= MASK(NV_CIO_CRE_RCR_ENDIAN_BIG); - NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RCR, tmp); - } -#endif - - funcs->dpms(crtc, DRM_MODE_DPMS_ON); - drm_vblank_post_modeset(dev, nv_crtc->index); -} - -static void nv_crtc_destroy(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - NV_DEBUG_KMS(crtc->dev, "\n"); - - if (!nv_crtc) - return; - - drm_crtc_cleanup(crtc); - - nouveau_bo_unmap(nv_crtc->cursor.nvbo); - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); - kfree(nv_crtc); -} - -static void -nv_crtc_gamma_load(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs; - int i; - - rgbs = (struct rgb *)dev_priv->mode_reg.crtc_reg[nv_crtc->index].DAC; - for (i = 0; i < 256; i++) { - rgbs[i].r = nv_crtc->lut.r[i] >> 8; - rgbs[i].g = nv_crtc->lut.g[i] >> 8; - rgbs[i].b = nv_crtc->lut.b[i] >> 8; - } - - nouveau_hw_load_state_palette(dev, nv_crtc->index, &dev_priv->mode_reg); -} - -static void -nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start, - uint32_t size) -{ - int end = (start + size > 256) ? 256 : start + size, i; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - for (i = start; i < end; i++) { - nv_crtc->lut.r[i] = r[i]; - nv_crtc->lut.g[i] = g[i]; - nv_crtc->lut.b[i] = b[i]; - } - - /* We need to know the depth before we upload, but it's possible to - * get called before a framebuffer is bound. If this is the case, - * mark the lut values as dirty by setting depth==0, and it'll be - * uploaded on the first mode_set_base() - */ - if (!nv_crtc->base.fb) { - nv_crtc->lut.depth = 0; - return; - } - - nv_crtc_gamma_load(crtc); -} - -static int -nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *passed_fb, - int x, int y, bool atomic) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - struct drm_framebuffer *drm_fb; - struct nouveau_framebuffer *fb; - int arb_burst, arb_lwm; - int ret; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - - /* no fb bound */ - if (!atomic && !crtc->fb) { - NV_DEBUG_KMS(dev, "No FB bound\n"); - return 0; - } - - - /* If atomic, we want to switch to the fb we were passed, so - * now we update pointers to do that. (We don't pin; just - * assume we're already pinned and update the base address.) - */ - if (atomic) { - drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); - } else { - drm_fb = crtc->fb; - fb = nouveau_framebuffer(crtc->fb); - /* If not atomic, we can go ahead and pin, and unpin the - * old fb we were passed. - */ - ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); - if (ret) - return ret; - - if (passed_fb) { - struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb); - nouveau_bo_unpin(ofb->nvbo); - } - } - - nv_crtc->fb.offset = fb->nvbo->bo.offset; - - if (nv_crtc->lut.depth != drm_fb->depth) { - nv_crtc->lut.depth = drm_fb->depth; - nv_crtc_gamma_load(crtc); - } - - /* Update the framebuffer format. */ - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3; - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8; - regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; - if (crtc->fb->depth == 16) - regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX); - NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL, - regp->ramdac_gen_ctrl); - - regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitches[0] >> 3; - regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = - XLATE(drm_fb->pitches[0] >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8); - regp->CRTC[NV_CIO_CRE_42] = - XLATE(drm_fb->pitches[0] / 8, 11, NV_CIO_CRE_42_OFFSET_11); - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX); - crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX); - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_42); - - /* Update the framebuffer location. */ - regp->fb_start = nv_crtc->fb.offset & ~3; - regp->fb_start += (y * drm_fb->pitches[0]) + (x * drm_fb->bits_per_pixel / 8); - nv_set_crtc_base(dev, nv_crtc->index, regp->fb_start); - - /* Update the arbitration parameters. */ - nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel, - &arb_burst, &arb_lwm); - - regp->CRTC[NV_CIO_CRE_FF_INDEX] = arb_burst; - regp->CRTC[NV_CIO_CRE_FFLWM__INDEX] = arb_lwm & 0xff; - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FF_INDEX); - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_FFLWM__INDEX); - - if (dev_priv->card_type >= NV_20) { - regp->CRTC[NV_CIO_CRE_47] = arb_lwm >> 8; - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_47); - } - - return 0; -} - -static int -nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false); -} - -static int -nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) -{ - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct drm_device *dev = dev_priv->dev; - - if (state == ENTER_ATOMIC_MODE_SET) - nouveau_fbcon_save_disable_accel(dev); - else - nouveau_fbcon_restore_accel(dev); - - return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true); -} - -static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src, - struct nouveau_bo *dst) -{ - int width = nv_cursor_width(dev); - uint32_t pixel; - int i, j; - - for (i = 0; i < width; i++) { - for (j = 0; j < width; j++) { - pixel = nouveau_bo_rd32(src, i*64 + j); - - nouveau_bo_wr16(dst, i*width + j, (pixel & 0x80000000) >> 16 - | (pixel & 0xf80000) >> 9 - | (pixel & 0xf800) >> 6 - | (pixel & 0xf8) >> 3); - } - } -} - -static void nv11_cursor_upload(struct drm_device *dev, struct nouveau_bo *src, - struct nouveau_bo *dst) -{ - uint32_t pixel; - int alpha, i; - - /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha - * cursors (though NPM in combination with fp dithering may not work on - * nv11, from "nv" driver history) - * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the - * blob uses, however we get given PM cursors so we use PM mode - */ - for (i = 0; i < 64 * 64; i++) { - pixel = nouveau_bo_rd32(src, i); - - /* hw gets unhappy if alpha <= rgb values. for a PM image "less - * than" shouldn't happen; fix "equal to" case by adding one to - * alpha channel (slightly inaccurate, but so is attempting to - * get back to NPM images, due to limits of integer precision) - */ - alpha = pixel >> 24; - if (alpha > 0 && alpha < 255) - pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24); - -#ifdef __BIG_ENDIAN - { - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset == 0x11) { - pixel = ((pixel & 0x000000ff) << 24) | - ((pixel & 0x0000ff00) << 8) | - ((pixel & 0x00ff0000) >> 8) | - ((pixel & 0xff000000) >> 24); - } - } -#endif - - nouveau_bo_wr32(dst, i, pixel); - } -} - -static int -nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - uint32_t buffer_handle, uint32_t width, uint32_t height) -{ - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct drm_device *dev = dev_priv->dev; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nouveau_bo *cursor = NULL; - struct drm_gem_object *gem; - int ret = 0; - - if (!buffer_handle) { - nv_crtc->cursor.hide(nv_crtc, true); - return 0; - } - - if (width != 64 || height != 64) - return -EINVAL; - - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); - if (!gem) - return -ENOENT; - cursor = nouveau_gem_object(gem); - - ret = nouveau_bo_map(cursor); - if (ret) - goto out; - - if (dev_priv->chipset >= 0x11) - nv11_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo); - else - nv04_cursor_upload(dev, cursor, nv_crtc->cursor.nvbo); - - nouveau_bo_unmap(cursor); - nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset; - nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.offset); - nv_crtc->cursor.show(nv_crtc, true); -out: - drm_gem_object_unreference_unlocked(gem); - return ret; -} - -static int -nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nv_crtc->cursor.set_pos(nv_crtc, x, y); - return 0; -} - -static const struct drm_crtc_funcs nv04_crtc_funcs = { - .save = nv_crtc_save, - .restore = nv_crtc_restore, - .cursor_set = nv04_crtc_cursor_set, - .cursor_move = nv04_crtc_cursor_move, - .gamma_set = nv_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, - .page_flip = nouveau_crtc_page_flip, - .destroy = nv_crtc_destroy, -}; - -static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { - .dpms = nv_crtc_dpms, - .prepare = nv_crtc_prepare, - .commit = nv_crtc_commit, - .mode_fixup = nv_crtc_mode_fixup, - .mode_set = nv_crtc_mode_set, - .mode_set_base = nv04_crtc_mode_set_base, - .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic, - .load_lut = nv_crtc_gamma_load, -}; - -int -nv04_crtc_create(struct drm_device *dev, int crtc_num) -{ - struct nouveau_crtc *nv_crtc; - int ret, i; - - nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); - if (!nv_crtc) - return -ENOMEM; - - for (i = 0; i < 256; i++) { - nv_crtc->lut.r[i] = i << 8; - nv_crtc->lut.g[i] = i << 8; - nv_crtc->lut.b[i] = i << 8; - } - nv_crtc->lut.depth = 0; - - nv_crtc->index = crtc_num; - nv_crtc->last_dpms = NV_DPMS_CLEARED; - - drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs); - drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs); - drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); - - ret = nouveau_bo_new(dev, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, - 0, 0x0000, &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(nv_crtc->cursor.nvbo); - if (ret) - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); - } - - nv04_cursor_init(nv_crtc); - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_cursor.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_cursor.c deleted file mode 100644 index aaf3de3b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_cursor.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "drmP.h" -#include "drm_mode.h" -#include "nouveau_reg.h" -#include "nouveau_drv.h" -#include "nouveau_crtc.h" -#include "nouveau_hw.h" - -static void -nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update) -{ - nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, true); -} - -static void -nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) -{ - nv_show_cursor(nv_crtc->base.dev, nv_crtc->index, false); -} - -static void -nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) -{ - nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y; - NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index, - NV_PRAMDAC_CU_START_POS, - XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) | - XLATE(x, 0, NV_PRAMDAC_CU_START_POS_X)); -} - -static void -crtc_wr_cio_state(struct drm_crtc *crtc, struct nv04_crtc_reg *crtcstate, int index) -{ - NVWriteVgaCrtc(crtc->dev, nouveau_crtc(crtc)->index, index, - crtcstate->CRTC[index]); -} - -static void -nv04_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) -{ - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - struct drm_crtc *crtc = &nv_crtc->base; - - regp->CRTC[NV_CIO_CRE_HCUR_ADDR0_INDEX] = - MASK(NV_CIO_CRE_HCUR_ASI) | - XLATE(offset, 17, NV_CIO_CRE_HCUR_ADDR0_ADR); - regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] = - XLATE(offset, 11, NV_CIO_CRE_HCUR_ADDR1_ADR); - if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) - regp->CRTC[NV_CIO_CRE_HCUR_ADDR1_INDEX] |= - MASK(NV_CIO_CRE_HCUR_ADDR1_CUR_DBL); - regp->CRTC[NV_CIO_CRE_HCUR_ADDR2_INDEX] = offset >> 24; - - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR0_INDEX); - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR1_INDEX); - crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_HCUR_ADDR2_INDEX); - if (dev_priv->card_type == NV_40) - nv_fix_nv40_hw_cursor(dev, nv_crtc->index); -} - -int -nv04_cursor_init(struct nouveau_crtc *crtc) -{ - crtc->cursor.set_offset = nv04_cursor_set_offset; - crtc->cursor.set_pos = nv04_cursor_set_pos; - crtc->cursor.hide = nv04_cursor_hide; - crtc->cursor.show = nv04_cursor_show; - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dac.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dac.c deleted file mode 100644 index 8300266f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dac.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright 2003 NVIDIA, Corporation - * Copyright 2006 Dave Airlie - * Copyright 2007 Maarten Maathuis - * Copyright 2007-2009 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nouveau_hw.h" -#include "nouveau_gpio.h" -#include "nvreg.h" - -int nv04_dac_output_offset(struct drm_encoder *encoder) -{ - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - int offset = 0; - - if (dcb->or & (8 | OUTPUT_C)) - offset += 0x68; - if (dcb->or & (8 | OUTPUT_B)) - offset += 0x2000; - - return offset; -} - -/* - * arbitrary limit to number of sense oscillations tolerated in one sample - * period (observed to be at least 13 in "nvidia") - */ -#define MAX_HBLANK_OSC 20 - -/* - * arbitrary limit to number of conflicting sample pairs to tolerate at a - * voltage step (observed to be at least 5 in "nvidia") - */ -#define MAX_SAMPLE_PAIRS 10 - -static int sample_load_twice(struct drm_device *dev, bool sense[2]) -{ - int i; - - for (i = 0; i < 2; i++) { - bool sense_a, sense_b, sense_b_prime; - int j = 0; - - /* - * wait for bit 0 clear -- out of hblank -- (say reg value 0x4), - * then wait for transition 0x4->0x5->0x4: enter hblank, leave - * hblank again - * use a 10ms timeout (guards against crtc being inactive, in - * which case blank state would never change) - */ - if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR, - 0x00000001, 0x00000000)) - return -EBUSY; - if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR, - 0x00000001, 0x00000001)) - return -EBUSY; - if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR, - 0x00000001, 0x00000000)) - return -EBUSY; - - udelay(100); - /* when level triggers, sense is _LO_ */ - sense_a = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10; - - /* take another reading until it agrees with sense_a... */ - do { - udelay(100); - sense_b = nv_rd08(dev, NV_PRMCIO_INP0) & 0x10; - if (sense_a != sense_b) { - sense_b_prime = - nv_rd08(dev, NV_PRMCIO_INP0) & 0x10; - if (sense_b == sense_b_prime) { - /* ... unless two consecutive subsequent - * samples agree; sense_a is replaced */ - sense_a = sense_b; - /* force mis-match so we loop */ - sense_b = !sense_a; - } - } - } while ((sense_a != sense_b) && ++j < MAX_HBLANK_OSC); - - if (j == MAX_HBLANK_OSC) - /* with so much oscillation, default to sense:LO */ - sense[i] = false; - else - sense[i] = sense_a; - } - - return 0; -} - -static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode; - uint8_t saved_palette0[3], saved_palette_mask; - uint32_t saved_rtest_ctrl, saved_rgen_ctrl; - int i; - uint8_t blue; - bool sense = true; - - /* - * for this detection to work, there needs to be a mode set up on the - * CRTC. this is presumed to be the case - */ - - if (nv_two_heads(dev)) - /* only implemented for head A for now */ - NVSetOwner(dev, 0); - - saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX); - NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80); - - saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); - NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); - - saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, - saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF); - - msleep(10); - - saved_pi = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX); - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, - saved_pi & ~(0x80 | MASK(NV_CIO_CRE_PIXEL_FORMAT))); - saved_rpc1 = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX); - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1 & ~0xc0); - - nv_wr08(dev, NV_PRMDIO_READ_MODE_ADDRESS, 0x0); - for (i = 0; i < 3; i++) - saved_palette0[i] = nv_rd08(dev, NV_PRMDIO_PALETTE_DATA); - saved_palette_mask = nv_rd08(dev, NV_PRMDIO_PIXEL_MASK); - nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, 0); - - saved_rgen_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, - (saved_rgen_ctrl & ~(NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | - NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM)) | - NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON); - - blue = 8; /* start of test range */ - - do { - bool sense_pair[2]; - - nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0); - nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0); - nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, 0); - /* testing blue won't find monochrome monitors. I don't care */ - nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, blue); - - i = 0; - /* take sample pairs until both samples in the pair agree */ - do { - if (sample_load_twice(dev, sense_pair)) - goto out; - } while ((sense_pair[0] != sense_pair[1]) && - ++i < MAX_SAMPLE_PAIRS); - - if (i == MAX_SAMPLE_PAIRS) - /* too much oscillation defaults to LO */ - sense = false; - else - sense = sense_pair[0]; - - /* - * if sense goes LO before blue ramps to 0x18, monitor is not connected. - * ergo, if blue gets to 0x18, monitor must be connected - */ - } while (++blue < 0x18 && sense); - -out: - nv_wr08(dev, NV_PRMDIO_PIXEL_MASK, saved_palette_mask); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_GENERAL_CONTROL, saved_rgen_ctrl); - nv_wr08(dev, NV_PRMDIO_WRITE_MODE_ADDRESS, 0); - for (i = 0; i < 3; i++) - nv_wr08(dev, NV_PRMDIO_PALETTE_DATA, saved_palette0[i]); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL, saved_rtest_ctrl); - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); - NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); - NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); - NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); - - if (blue == 0x18) { - NV_INFO(dev, "Load detected on head A\n"); - return connector_status_connected; - } - - return connector_status_disconnected; -} - -uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); - uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, - saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput; - int head; - -#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) - if (dcb->type == OUTPUT_TV) { - testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0); - - if (dev_priv->vbios.tvdactestval) - testval = dev_priv->vbios.tvdactestval; - } else { - testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */ - - if (dev_priv->vbios.dactestval) - testval = dev_priv->vbios.dactestval; - } - - saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, - saved_rtest_ctrl & ~NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF); - - saved_powerctrl_2 = nvReadMC(dev, NV_PBUS_POWERCTRL_2); - - nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2 & 0xd7ffffff); - if (regoffset == 0x68) { - saved_powerctrl_4 = nvReadMC(dev, NV_PBUS_POWERCTRL_4); - nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); - } - - saved_gpio1 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC1); - saved_gpio0 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC0); - - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); - - msleep(4); - - saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); - head = (saved_routput & 0x100) >> 8; - - /* if there's a spare crtc, using it will minimise flicker */ - if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0)) - head ^= 1; - - /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ - routput = (saved_routput & 0xfffffece) | head << 8; - - if (dev_priv->card_type >= NV_40) { - if (dcb->type == OUTPUT_TV) - routput |= 0x1a << 16; - else - routput &= ~(0x1a << 16); - } - - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, routput); - msleep(1); - - temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, temp | 1); - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, - NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK | testval); - temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, - temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); - msleep(5); - - sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); - /* do it again just in case it's a residual current */ - sample &= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); - - temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, - temp & ~NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TESTPOINT_DATA, 0); - - /* bios does something more complex for restoring, but I think this is good enough */ - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, saved_routput); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, saved_rtest_ctrl); - if (regoffset == 0x68) - nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); - nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); - - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); - - return sample; -} - -static enum drm_connector_status -nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - - if (nv04_dac_in_use(encoder)) - return connector_status_disconnected; - - if (nv17_dac_sample_load(encoder) & - NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { - NV_INFO(dev, "Load detected on output %c\n", - '@' + ffs(dcb->or)); - return connector_status_connected; - } else { - return connector_status_disconnected; - } -} - -static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - if (nv04_dac_in_use(encoder)) - return false; - - return true; -} - -static void nv04_dac_prepare(struct drm_encoder *encoder) -{ - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - struct drm_device *dev = encoder->dev; - int head = nouveau_crtc(encoder->crtc)->index; - - helper->dpms(encoder, DRM_MODE_DPMS_OFF); - - nv04_dfp_disable(dev, head); -} - -static void nv04_dac_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int head = nouveau_crtc(encoder->crtc)->index; - - if (nv_gf4_disp_arch(dev)) { - struct drm_encoder *rebind; - uint32_t dac_offset = nv04_dac_output_offset(encoder); - uint32_t otherdac; - - /* bit 16-19 are bits that are set on some G70 cards, - * but don't seem to have much effect */ - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset, - head << 8 | NV_PRAMDAC_DACCLK_SEL_DACCLK); - /* force any other vga encoders to bind to the other crtc */ - list_for_each_entry(rebind, &dev->mode_config.encoder_list, head) { - if (rebind == encoder - || nouveau_encoder(rebind)->dcb->type != OUTPUT_ANALOG) - continue; - - dac_offset = nv04_dac_output_offset(rebind); - otherdac = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + dac_offset, - (otherdac & ~0x0100) | (head ^ 1) << 8); - } - } - - /* This could use refinement for flatpanels, but it should work this way */ - if (dev_priv->chipset < 0x44) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000); - else - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); -} - -static void nv04_dac_commit(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - - helper->dpms(encoder, DRM_MODE_DPMS_ON); - - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); -} - -void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - - if (nv_gf4_disp_arch(dev)) { - uint32_t *dac_users = &dev_priv->dac_users[ffs(dcb->or) - 1]; - int dacclk_off = NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder); - uint32_t dacclk = NVReadRAMDAC(dev, 0, dacclk_off); - - if (enable) { - *dac_users |= 1 << dcb->index; - NVWriteRAMDAC(dev, 0, dacclk_off, dacclk | NV_PRAMDAC_DACCLK_SEL_DACCLK); - - } else { - *dac_users &= ~(1 << dcb->index); - if (!*dac_users) - NVWriteRAMDAC(dev, 0, dacclk_off, - dacclk & ~NV_PRAMDAC_DACCLK_SEL_DACCLK); - } - } -} - -/* Check if the DAC corresponding to 'encoder' is being used by - * someone else. */ -bool nv04_dac_in_use(struct drm_encoder *encoder) -{ - struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - - return nv_gf4_disp_arch(encoder->dev) && - (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index)); -} - -static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->last_dpms == mode) - return; - nv_encoder->last_dpms = mode; - - NV_INFO(dev, "Setting dpms mode %d on vga encoder (output %d)\n", - mode, nv_encoder->dcb->index); - - nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); -} - -static void nv04_dac_save(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - - if (nv_gf4_disp_arch(dev)) - nv_encoder->restore.output = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + - nv04_dac_output_offset(encoder)); -} - -static void nv04_dac_restore(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - - if (nv_gf4_disp_arch(dev)) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + nv04_dac_output_offset(encoder), - nv_encoder->restore.output); - - nv_encoder->last_dpms = NV_DPMS_CLEARED; -} - -static void nv04_dac_destroy(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - NV_DEBUG_KMS(encoder->dev, "\n"); - - drm_encoder_cleanup(encoder); - kfree(nv_encoder); -} - -static const struct drm_encoder_helper_funcs nv04_dac_helper_funcs = { - .dpms = nv04_dac_dpms, - .save = nv04_dac_save, - .restore = nv04_dac_restore, - .mode_fixup = nv04_dac_mode_fixup, - .prepare = nv04_dac_prepare, - .commit = nv04_dac_commit, - .mode_set = nv04_dac_mode_set, - .detect = nv04_dac_detect -}; - -static const struct drm_encoder_helper_funcs nv17_dac_helper_funcs = { - .dpms = nv04_dac_dpms, - .save = nv04_dac_save, - .restore = nv04_dac_restore, - .mode_fixup = nv04_dac_mode_fixup, - .prepare = nv04_dac_prepare, - .commit = nv04_dac_commit, - .mode_set = nv04_dac_mode_set, - .detect = nv17_dac_detect -}; - -static const struct drm_encoder_funcs nv04_dac_funcs = { - .destroy = nv04_dac_destroy, -}; - -int -nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry) -{ - const struct drm_encoder_helper_funcs *helper; - struct nouveau_encoder *nv_encoder = NULL; - struct drm_device *dev = connector->dev; - struct drm_encoder *encoder; - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - - encoder = to_drm_encoder(nv_encoder); - - nv_encoder->dcb = entry; - nv_encoder->or = ffs(entry->or) - 1; - - if (nv_gf4_disp_arch(dev)) - helper = &nv17_dac_helper_funcs; - else - helper = &nv04_dac_helper_funcs; - - drm_encoder_init(dev, encoder, &nv04_dac_funcs, DRM_MODE_ENCODER_DAC); - drm_encoder_helper_add(encoder, helper); - - encoder->possible_crtcs = entry->heads; - encoder->possible_clones = 0; - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dfp.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dfp.c deleted file mode 100644 index 22587460..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_dfp.c +++ /dev/null @@ -1,720 +0,0 @@ -/* - * Copyright 2003 NVIDIA, Corporation - * Copyright 2006 Dave Airlie - * Copyright 2007 Maarten Maathuis - * Copyright 2007-2009 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nouveau_hw.h" -#include "nvreg.h" - -#include "i2c/sil164.h" - -#define FP_TG_CONTROL_ON (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | \ - NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | \ - NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS) -#define FP_TG_CONTROL_OFF (NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE | \ - NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE | \ - NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE) - -static inline bool is_fpc_off(uint32_t fpc) -{ - return ((fpc & (FP_TG_CONTROL_ON | FP_TG_CONTROL_OFF)) == - FP_TG_CONTROL_OFF); -} - -int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent) -{ - /* special case of nv_read_tmds to find crtc associated with an output. - * this does not give a correct answer for off-chip dvi, but there's no - * use for such an answer anyway - */ - int ramdac = (dcbent->or & OUTPUT_C) >> 2; - - NVWriteRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_CONTROL, - NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4); - return ((NVReadRAMDAC(dev, ramdac, NV_PRAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac; -} - -void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, - int head, bool dl) -{ - /* The BIOS scripts don't do this for us, sadly - * Luckily we do know the values ;-) - * - * head < 0 indicates we wish to force a setting with the overrideval - * (for VT restore etc.) - */ - - int ramdac = (dcbent->or & OUTPUT_C) >> 2; - uint8_t tmds04 = 0x80; - - if (head != ramdac) - tmds04 = 0x88; - - if (dcbent->type == OUTPUT_LVDS) - tmds04 |= 0x01; - - nv_write_tmds(dev, dcbent->or, 0, 0x04, tmds04); - - if (dl) /* dual link */ - nv_write_tmds(dev, dcbent->or, 1, 0x04, tmds04 ^ 0x08); -} - -void nv04_dfp_disable(struct drm_device *dev, int head) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg; - - if (NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL) & - FP_TG_CONTROL_ON) { - /* digital remnants must be cleaned before new crtc - * values programmed. delay is time for the vga stuff - * to realise it's in control again - */ - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, - FP_TG_CONTROL_OFF); - msleep(50); - } - /* don't inadvertently turn it on when state written later */ - crtcstate[head].fp_control = FP_TG_CONTROL_OFF; - crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX] &= - ~NV_CIO_CRE_LCD_ROUTE_MASK; -} - -void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct nouveau_crtc *nv_crtc; - uint32_t *fpc; - - if (mode == DRM_MODE_DPMS_ON) { - nv_crtc = nouveau_crtc(encoder->crtc); - fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control; - - if (is_fpc_off(*fpc)) { - /* using saved value is ok, as (is_digital && dpms_on && - * fp_control==OFF) is (at present) *only* true when - * fpc's most recent change was by below "off" code - */ - *fpc = nv_crtc->dpms_saved_fp_control; - } - - nv_crtc->fp_users |= 1 << nouveau_encoder(encoder)->dcb->index; - NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_FP_TG_CONTROL, *fpc); - } else { - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - nv_crtc = nouveau_crtc(crtc); - fpc = &dev_priv->mode_reg.crtc_reg[nv_crtc->index].fp_control; - - nv_crtc->fp_users &= ~(1 << nouveau_encoder(encoder)->dcb->index); - if (!is_fpc_off(*fpc) && !nv_crtc->fp_users) { - nv_crtc->dpms_saved_fp_control = *fpc; - /* cut the FP output */ - *fpc &= ~FP_TG_CONTROL_ON; - *fpc |= FP_TG_CONTROL_OFF; - NVWriteRAMDAC(dev, nv_crtc->index, - NV_PRAMDAC_FP_TG_CONTROL, *fpc); - } - } - } -} - -static struct drm_encoder *get_tmds_slave(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - struct drm_encoder *slave; - - if (dcb->type != OUTPUT_TMDS || dcb->location == DCB_LOC_ON_CHIP) - return NULL; - - /* Some BIOSes (e.g. the one in a Quadro FX1000) report several - * TMDS transmitters at the same I2C address, in the same I2C - * bus. This can still work because in that case one of them is - * always hard-wired to a reasonable configuration using straps, - * and the other one needs to be programmed. - * - * I don't think there's a way to know which is which, even the - * blob programs the one exposed via I2C for *both* heads, so - * let's do the same. - */ - list_for_each_entry(slave, &dev->mode_config.encoder_list, head) { - struct dcb_entry *slave_dcb = nouveau_encoder(slave)->dcb; - - if (slave_dcb->type == OUTPUT_TMDS && get_slave_funcs(slave) && - slave_dcb->tmdsconf.slave_addr == dcb->tmdsconf.slave_addr) - return slave; - } - - return NULL; -} - -static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); - - if (!nv_connector->native_mode || - nv_connector->scaling_mode == DRM_MODE_SCALE_NONE || - mode->hdisplay > nv_connector->native_mode->hdisplay || - mode->vdisplay > nv_connector->native_mode->vdisplay) { - nv_encoder->mode = *adjusted_mode; - - } else { - nv_encoder->mode = *nv_connector->native_mode; - adjusted_mode->clock = nv_connector->native_mode->clock; - } - - return true; -} - -static void nv04_dfp_prepare_sel_clk(struct drm_device *dev, - struct nouveau_encoder *nv_encoder, int head) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_mode_state *state = &dev_priv->mode_reg; - uint32_t bits1618 = nv_encoder->dcb->or & OUTPUT_A ? 0x10000 : 0x40000; - - if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP) - return; - - /* SEL_CLK is only used on the primary ramdac - * It toggles spread spectrum PLL output and sets the bindings of PLLs - * to heads on digital outputs - */ - if (head) - state->sel_clk |= bits1618; - else - state->sel_clk &= ~bits1618; - - /* nv30: - * bit 0 NVClk spread spectrum on/off - * bit 2 MemClk spread spectrum on/off - * bit 4 PixClk1 spread spectrum on/off toggle - * bit 6 PixClk2 spread spectrum on/off toggle - * - * nv40 (observations from bios behaviour and mmio traces): - * bits 4&6 as for nv30 - * bits 5&7 head dependent as for bits 4&6, but do not appear with 4&6; - * maybe a different spread mode - * bits 8&10 seen on dual-link dvi outputs, purpose unknown (set by POST scripts) - * The logic behind turning spread spectrum on/off in the first place, - * and which bit-pair to use, is unclear on nv40 (for earlier cards, the fp table - * entry has the necessary info) - */ - if (nv_encoder->dcb->type == OUTPUT_LVDS && dev_priv->saved_reg.sel_clk & 0xf0) { - int shift = (dev_priv->saved_reg.sel_clk & 0x50) ? 0 : 1; - - state->sel_clk &= ~0xf0; - state->sel_clk |= (head ? 0x40 : 0x10) << shift; - } -} - -static void nv04_dfp_prepare(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int head = nouveau_crtc(encoder->crtc)->index; - struct nv04_crtc_reg *crtcstate = dev_priv->mode_reg.crtc_reg; - uint8_t *cr_lcd = &crtcstate[head].CRTC[NV_CIO_CRE_LCD__INDEX]; - uint8_t *cr_lcd_oth = &crtcstate[head ^ 1].CRTC[NV_CIO_CRE_LCD__INDEX]; - - helper->dpms(encoder, DRM_MODE_DPMS_OFF); - - nv04_dfp_prepare_sel_clk(dev, nv_encoder, head); - - *cr_lcd = (*cr_lcd & ~NV_CIO_CRE_LCD_ROUTE_MASK) | 0x3; - - if (nv_two_heads(dev)) { - if (nv_encoder->dcb->location == DCB_LOC_ON_CHIP) - *cr_lcd |= head ? 0x0 : 0x8; - else { - *cr_lcd |= (nv_encoder->dcb->or << 4) & 0x30; - if (nv_encoder->dcb->type == OUTPUT_LVDS) - *cr_lcd |= 0x30; - if ((*cr_lcd & 0x30) == (*cr_lcd_oth & 0x30)) { - /* avoid being connected to both crtcs */ - *cr_lcd_oth &= ~0x30; - NVWriteVgaCrtc(dev, head ^ 1, - NV_CIO_CRE_LCD__INDEX, - *cr_lcd_oth); - } - } - } -} - - -static void nv04_dfp_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - struct nv04_crtc_reg *savep = &dev_priv->saved_reg.crtc_reg[nv_crtc->index]; - struct nouveau_connector *nv_connector = nouveau_crtc_connector_get(nv_crtc); - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_display_mode *output_mode = &nv_encoder->mode; - struct drm_connector *connector = &nv_connector->base; - uint32_t mode_ratio, panel_ratio; - - NV_DEBUG_KMS(dev, "Output mode on CRTC %d:\n", nv_crtc->index); - drm_mode_debug_printmodeline(output_mode); - - /* Initialize the FP registers in this CRTC. */ - regp->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1; - regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1; - if (!nv_gf4_disp_arch(dev) || - (output_mode->hsync_start - output_mode->hdisplay) >= - dev_priv->vbios.digital_min_front_porch) - regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay; - else - regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1; - regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1; - regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1; - regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew; - regp->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - 1; - - regp->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1; - regp->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1; - regp->fp_vert_regs[FP_CRTC] = output_mode->vtotal - 5 - 1; - regp->fp_vert_regs[FP_SYNC_START] = output_mode->vsync_start - 1; - regp->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1; - regp->fp_vert_regs[FP_VALID_START] = 0; - regp->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - 1; - - /* bit26: a bit seen on some g7x, no as yet discernable purpose */ - regp->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | - (savep->fp_control & (1 << 26 | NV_PRAMDAC_FP_TG_CONTROL_READ_PROG)); - /* Deal with vsync/hsync polarity */ - /* LVDS screens do set this, but modes with +ve syncs are very rare */ - if (output_mode->flags & DRM_MODE_FLAG_PVSYNC) - regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS; - if (output_mode->flags & DRM_MODE_FLAG_PHSYNC) - regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS; - /* panel scaling first, as native would get set otherwise */ - if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE || - nv_connector->scaling_mode == DRM_MODE_SCALE_CENTER) /* panel handles it */ - regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER; - else if (adjusted_mode->hdisplay == output_mode->hdisplay && - adjusted_mode->vdisplay == output_mode->vdisplay) /* native mode */ - regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE; - else /* gpu needs to scale */ - regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE; - if (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT) - regp->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12; - if (nv_encoder->dcb->location != DCB_LOC_ON_CHIP && - output_mode->clock > 165000) - regp->fp_control |= (2 << 24); - if (nv_encoder->dcb->type == OUTPUT_LVDS) { - bool duallink = false, dummy; - if (nv_connector->edid && - nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) { - duallink = (((u8 *)nv_connector->edid)[121] == 2); - } else { - nouveau_bios_parse_lvds_table(dev, output_mode->clock, - &duallink, &dummy); - } - - if (duallink) - regp->fp_control |= (8 << 28); - } else - if (output_mode->clock > 165000) - regp->fp_control |= (8 << 28); - - regp->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND | - NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND | - NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR | - NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR | - NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED | - NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE | - NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE; - - /* We want automatic scaling */ - regp->fp_debug_1 = 0; - /* This can override HTOTAL and VTOTAL */ - regp->fp_debug_2 = 0; - - /* Use 20.12 fixed point format to avoid floats */ - mode_ratio = (1 << 12) * adjusted_mode->hdisplay / adjusted_mode->vdisplay; - panel_ratio = (1 << 12) * output_mode->hdisplay / output_mode->vdisplay; - /* if ratios are equal, SCALE_ASPECT will automatically (and correctly) - * get treated the same as SCALE_FULLSCREEN */ - if (nv_connector->scaling_mode == DRM_MODE_SCALE_ASPECT && - mode_ratio != panel_ratio) { - uint32_t diff, scale; - bool divide_by_2 = nv_gf4_disp_arch(dev); - - if (mode_ratio < panel_ratio) { - /* vertical needs to expand to glass size (automatic) - * horizontal needs to be scaled at vertical scale factor - * to maintain aspect */ - - scale = (1 << 12) * adjusted_mode->vdisplay / output_mode->vdisplay; - regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE | - XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE); - - /* restrict area of screen used, horizontally */ - diff = output_mode->hdisplay - - output_mode->vdisplay * mode_ratio / (1 << 12); - regp->fp_horiz_regs[FP_VALID_START] += diff / 2; - regp->fp_horiz_regs[FP_VALID_END] -= diff / 2; - } - - if (mode_ratio > panel_ratio) { - /* horizontal needs to expand to glass size (automatic) - * vertical needs to be scaled at horizontal scale factor - * to maintain aspect */ - - scale = (1 << 12) * adjusted_mode->hdisplay / output_mode->hdisplay; - regp->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE | - XLATE(scale, divide_by_2, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE); - - /* restrict area of screen used, vertically */ - diff = output_mode->vdisplay - - (1 << 12) * output_mode->hdisplay / mode_ratio; - regp->fp_vert_regs[FP_VALID_START] += diff / 2; - regp->fp_vert_regs[FP_VALID_END] -= diff / 2; - } - } - - /* Output property. */ - if ((nv_connector->dithering_mode == DITHERING_MODE_ON) || - (nv_connector->dithering_mode == DITHERING_MODE_AUTO && - encoder->crtc->fb->depth > connector->display_info.bpc * 3)) { - if (dev_priv->chipset == 0x11) - regp->dither = savep->dither | 0x00010000; - else { - int i; - regp->dither = savep->dither | 0x00000001; - for (i = 0; i < 3; i++) { - regp->dither_regs[i] = 0xe4e4e4e4; - regp->dither_regs[i + 3] = 0x44444444; - } - } - } else { - if (dev_priv->chipset != 0x11) { - /* reset them */ - int i; - for (i = 0; i < 3; i++) { - regp->dither_regs[i] = savep->dither_regs[i]; - regp->dither_regs[i + 3] = savep->dither_regs[i + 3]; - } - } - regp->dither = savep->dither; - } - - regp->fp_margin_color = 0; -} - -static void nv04_dfp_commit(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct dcb_entry *dcbe = nv_encoder->dcb; - int head = nouveau_crtc(encoder->crtc)->index; - struct drm_encoder *slave_encoder; - - if (dcbe->type == OUTPUT_TMDS) - run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); - else if (dcbe->type == OUTPUT_LVDS) - call_lvds_script(dev, dcbe, head, LVDS_RESET, nv_encoder->mode.clock); - - /* update fp_control state for any changes made by scripts, - * so correct value is written at DPMS on */ - dev_priv->mode_reg.crtc_reg[head].fp_control = - NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); - - /* This could use refinement for flatpanels, but it should work this way */ - if (dev_priv->chipset < 0x44) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0xf0000000); - else - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); - - /* Init external transmitters */ - slave_encoder = get_tmds_slave(encoder); - if (slave_encoder) - get_slave_funcs(slave_encoder)->mode_set( - slave_encoder, &nv_encoder->mode, &nv_encoder->mode); - - helper->dpms(encoder, DRM_MODE_DPMS_ON); - - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); -} - -static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) -{ -#ifdef __powerpc__ - struct drm_device *dev = encoder->dev; - - /* BIOS scripts usually take care of the backlight, thanks - * Apple for your consistency. - */ - if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || - dev->pci_device == 0x0329) { - if (mode == DRM_MODE_DPMS_ON) { - nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); - nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); - } else { - nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); - nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); - } - } -#endif -} - -static inline bool is_powersaving_dpms(int mode) -{ - return (mode != DRM_MODE_DPMS_ON); -} - -static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_crtc *crtc = encoder->crtc; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - bool was_powersaving = is_powersaving_dpms(nv_encoder->last_dpms); - - if (nv_encoder->last_dpms == mode) - return; - nv_encoder->last_dpms = mode; - - NV_INFO(dev, "Setting dpms mode %d on lvds encoder (output %d)\n", - mode, nv_encoder->dcb->index); - - if (was_powersaving && is_powersaving_dpms(mode)) - return; - - if (nv_encoder->dcb->lvdsconf.use_power_scripts) { - /* when removing an output, crtc may not be set, but PANEL_OFF - * must still be run - */ - int head = crtc ? nouveau_crtc(crtc)->index : - nv04_dfp_get_bound_head(dev, nv_encoder->dcb); - - if (mode == DRM_MODE_DPMS_ON) { - call_lvds_script(dev, nv_encoder->dcb, head, - LVDS_PANEL_ON, nv_encoder->mode.clock); - } else - /* pxclk of 0 is fine for PANEL_OFF, and for a - * disconnected LVDS encoder there is no native_mode - */ - call_lvds_script(dev, nv_encoder->dcb, head, - LVDS_PANEL_OFF, 0); - } - - nv04_dfp_update_backlight(encoder, mode); - nv04_dfp_update_fp_control(encoder, mode); - - if (mode == DRM_MODE_DPMS_ON) - nv04_dfp_prepare_sel_clk(dev, nv_encoder, nouveau_crtc(crtc)->index); - else { - dev_priv->mode_reg.sel_clk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK); - dev_priv->mode_reg.sel_clk &= ~0xf0; - } - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_SEL_CLK, dev_priv->mode_reg.sel_clk); -} - -static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->last_dpms == mode) - return; - nv_encoder->last_dpms = mode; - - NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", - mode, nv_encoder->dcb->index); - - nv04_dfp_update_backlight(encoder, mode); - nv04_dfp_update_fp_control(encoder, mode); -} - -static void nv04_dfp_save(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - - if (nv_two_heads(dev)) - nv_encoder->restore.head = - nv04_dfp_get_bound_head(dev, nv_encoder->dcb); -} - -static void nv04_dfp_restore(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int head = nv_encoder->restore.head; - - if (nv_encoder->dcb->type == OUTPUT_LVDS) { - struct nouveau_connector *connector = - nouveau_encoder_connector_get(nv_encoder); - - if (connector && connector->native_mode) - call_lvds_script(dev, nv_encoder->dcb, head, - LVDS_PANEL_ON, - connector->native_mode->clock); - - } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { - int clock = nouveau_hw_pllvals_to_clk - (&dev_priv->saved_reg.crtc_reg[head].pllvals); - - run_tmds_table(dev, nv_encoder->dcb, head, clock); - } - - nv_encoder->last_dpms = NV_DPMS_CLEARED; -} - -static void nv04_dfp_destroy(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - NV_DEBUG_KMS(encoder->dev, "\n"); - - if (get_slave_funcs(encoder)) - get_slave_funcs(encoder)->destroy(encoder); - - drm_encoder_cleanup(encoder); - kfree(nv_encoder); -} - -static void nv04_tmds_slave_init(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, 2); - struct i2c_board_info info[] = { - { - .type = "sil164", - .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38), - .platform_data = &(struct sil164_encoder_params) { - SIL164_INPUT_EDGE_RISING - } - }, - { } - }; - int type; - - if (!nv_gf4_disp_arch(dev) || !i2c || - get_tmds_slave(encoder)) - return; - - type = nouveau_i2c_identify(dev, "TMDS transmitter", info, NULL, 2); - if (type < 0) - return; - - drm_i2c_encoder_init(dev, to_encoder_slave(encoder), - &i2c->adapter, &info[type]); -} - -static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { - .dpms = nv04_lvds_dpms, - .save = nv04_dfp_save, - .restore = nv04_dfp_restore, - .mode_fixup = nv04_dfp_mode_fixup, - .prepare = nv04_dfp_prepare, - .commit = nv04_dfp_commit, - .mode_set = nv04_dfp_mode_set, - .detect = NULL, -}; - -static const struct drm_encoder_helper_funcs nv04_tmds_helper_funcs = { - .dpms = nv04_tmds_dpms, - .save = nv04_dfp_save, - .restore = nv04_dfp_restore, - .mode_fixup = nv04_dfp_mode_fixup, - .prepare = nv04_dfp_prepare, - .commit = nv04_dfp_commit, - .mode_set = nv04_dfp_mode_set, - .detect = NULL, -}; - -static const struct drm_encoder_funcs nv04_dfp_funcs = { - .destroy = nv04_dfp_destroy, -}; - -int -nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry) -{ - const struct drm_encoder_helper_funcs *helper; - struct nouveau_encoder *nv_encoder = NULL; - struct drm_encoder *encoder; - int type; - - switch (entry->type) { - case OUTPUT_TMDS: - type = DRM_MODE_ENCODER_TMDS; - helper = &nv04_tmds_helper_funcs; - break; - case OUTPUT_LVDS: - type = DRM_MODE_ENCODER_LVDS; - helper = &nv04_lvds_helper_funcs; - break; - default: - return -EINVAL; - } - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - - encoder = to_drm_encoder(nv_encoder); - - nv_encoder->dcb = entry; - nv_encoder->or = ffs(entry->or) - 1; - - drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type); - drm_encoder_helper_add(encoder, helper); - - encoder->possible_crtcs = entry->heads; - encoder->possible_clones = 0; - - if (entry->type == OUTPUT_TMDS && - entry->location != DCB_LOC_ON_CHIP) - nv04_tmds_slave_init(encoder); - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_display.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_display.c deleted file mode 100644 index 7047d37e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_display.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Author: Ben Skeggs - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc_helper.h" - -#include "nouveau_drv.h" -#include "nouveau_fb.h" -#include "nouveau_hw.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" - -static void nv04_vblank_crtc0_isr(struct drm_device *); -static void nv04_vblank_crtc1_isr(struct drm_device *); - -static void -nv04_display_store_initial_head_owner(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset != 0x11) { - dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44); - return; - } - - /* reading CR44 is broken on nv11, so we attempt to infer it */ - if (nvReadMC(dev, NV_PBUS_DEBUG_1) & (1 << 28)) /* heads tied, restore both */ - dev_priv->crtc_owner = 0x4; - else { - uint8_t slaved_on_A, slaved_on_B; - bool tvA = false; - bool tvB = false; - - slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) & - 0x80; - if (slaved_on_B) - tvB = !(NVReadVgaCrtc(dev, 1, NV_CIO_CRE_LCD__INDEX) & - MASK(NV_CIO_CRE_LCD_LCD_SELECT)); - - slaved_on_A = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX) & - 0x80; - if (slaved_on_A) - tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) & - MASK(NV_CIO_CRE_LCD_LCD_SELECT)); - - if (slaved_on_A && !tvA) - dev_priv->crtc_owner = 0x0; - else if (slaved_on_B && !tvB) - dev_priv->crtc_owner = 0x3; - else if (slaved_on_A) - dev_priv->crtc_owner = 0x0; - else if (slaved_on_B) - dev_priv->crtc_owner = 0x3; - else - dev_priv->crtc_owner = 0x0; - } -} - -int -nv04_display_early_init(struct drm_device *dev) -{ - /* Make the I2C buses accessible. */ - if (!nv_gf4_disp_arch(dev)) { - uint32_t pmc_enable = nv_rd32(dev, NV03_PMC_ENABLE); - - if (!(pmc_enable & 1)) - nv_wr32(dev, NV03_PMC_ENABLE, pmc_enable | 1); - } - - /* Unlock the VGA CRTCs. */ - NVLockVgaCrtcs(dev, false); - - /* Make sure the CRTCs aren't in slaved mode. */ - if (nv_two_heads(dev)) { - nv04_display_store_initial_head_owner(dev); - NVSetOwner(dev, 0); - } - - return 0; -} - -void -nv04_display_late_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (nv_two_heads(dev)) - NVSetOwner(dev, dev_priv->crtc_owner); - - NVLockVgaCrtcs(dev, true); -} - -int -nv04_display_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_table *dcb = &dev_priv->vbios.dcb; - struct drm_connector *connector, *ct; - struct drm_encoder *encoder; - struct drm_crtc *crtc; - int i, ret; - - NV_DEBUG_KMS(dev, "\n"); - - nouveau_hw_save_vga_fonts(dev, 1); - - nv04_crtc_create(dev, 0); - if (nv_two_heads(dev)) - nv04_crtc_create(dev, 1); - - for (i = 0; i < dcb->entries; i++) { - struct dcb_entry *dcbent = &dcb->entry[i]; - - connector = nouveau_connector_create(dev, dcbent->connector); - if (IS_ERR(connector)) - continue; - - switch (dcbent->type) { - case OUTPUT_ANALOG: - ret = nv04_dac_create(connector, dcbent); - break; - case OUTPUT_LVDS: - case OUTPUT_TMDS: - ret = nv04_dfp_create(connector, dcbent); - break; - case OUTPUT_TV: - if (dcbent->location == DCB_LOC_ON_CHIP) - ret = nv17_tv_create(connector, dcbent); - else - ret = nv04_tv_create(connector, dcbent); - break; - default: - NV_WARN(dev, "DCB type %d not known\n", dcbent->type); - continue; - } - - if (ret) - continue; - } - - list_for_each_entry_safe(connector, ct, - &dev->mode_config.connector_list, head) { - if (!connector->encoder_ids[0]) { - NV_WARN(dev, "%s has no encoders, removing\n", - drm_get_connector_name(connector)); - connector->funcs->destroy(connector); - } - } - - /* Save previous state */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - crtc->funcs->save(crtc); - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct drm_encoder_helper_funcs *func = encoder->helper_private; - - func->save(encoder); - } - - nouveau_irq_register(dev, 24, nv04_vblank_crtc0_isr); - nouveau_irq_register(dev, 25, nv04_vblank_crtc1_isr); - return 0; -} - -void -nv04_display_destroy(struct drm_device *dev) -{ - struct drm_encoder *encoder; - struct drm_crtc *crtc; - - NV_DEBUG_KMS(dev, "\n"); - - nouveau_irq_unregister(dev, 24); - nouveau_irq_unregister(dev, 25); - - /* Turn every CRTC off. */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct drm_mode_set modeset = { - .crtc = crtc, - }; - - crtc->funcs->set_config(&modeset); - } - - /* Restore state */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct drm_encoder_helper_funcs *func = encoder->helper_private; - - func->restore(encoder); - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - crtc->funcs->restore(crtc); - - nouveau_hw_save_vga_fonts(dev, 0); -} - -int -nv04_display_init(struct drm_device *dev) -{ - struct drm_encoder *encoder; - struct drm_crtc *crtc; - - /* meh.. modeset apparently doesn't setup all the regs and depends - * on pre-existing state, for now load the state of the card *before* - * nouveau was loaded, and then do a modeset. - * - * best thing to do probably is to make save/restore routines not - * save/restore "pre-load" state, but more general so we can save - * on suspend too. - */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct drm_encoder_helper_funcs *func = encoder->helper_private; - - func->restore(encoder); - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - crtc->funcs->restore(crtc); - - return 0; -} - -void -nv04_display_fini(struct drm_device *dev) -{ -} - -static void -nv04_vblank_crtc0_isr(struct drm_device *dev) -{ - nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); - drm_handle_vblank(dev, 0); -} - -static void -nv04_vblank_crtc1_isr(struct drm_device *dev) -{ - nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); - drm_handle_vblank(dev, 1); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fb.c deleted file mode 100644 index d5eedd67..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fb.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -int -nv04_fb_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 boot0 = nv_rd32(dev, NV04_PFB_BOOT_0); - - if (boot0 & 0x00000100) { - dev_priv->vram_size = ((boot0 >> 12) & 0xf) * 2 + 2; - dev_priv->vram_size *= 1024 * 1024; - } else { - switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) { - case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB: - dev_priv->vram_size = 32 * 1024 * 1024; - break; - case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB: - dev_priv->vram_size = 16 * 1024 * 1024; - break; - case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB: - dev_priv->vram_size = 8 * 1024 * 1024; - break; - case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB: - dev_priv->vram_size = 4 * 1024 * 1024; - break; - } - } - - if ((boot0 & 0x00000038) <= 0x10) - dev_priv->vram_type = NV_MEM_TYPE_SGRAM; - else - dev_priv->vram_type = NV_MEM_TYPE_SDRAM; - - return 0; -} - -int -nv04_fb_init(struct drm_device *dev) -{ - /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows - * nvidia reading PFB_CFG_0, then writing back its original value. - * (which was 0x701114 in this case) - */ - - nv_wr32(dev, NV04_PFB_CFG0, 0x1114); - return 0; -} - -void -nv04_fb_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fbcon.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fbcon.c deleted file mode 100644 index 7a118937..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2009 Ben Skeggs - * Copyright 2008 Stuart Bennett - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_ramht.h" -#include "nouveau_fbcon.h" - -int -nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret; - - ret = RING_SPACE(chan, 4); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3); - OUT_RING(chan, (region->sy << 16) | region->sx); - OUT_RING(chan, (region->dy << 16) | region->dx); - OUT_RING(chan, (region->height << 16) | region->width); - FIRE_RING(chan); - return 0; -} - -int -nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret; - - ret = RING_SPACE(chan, 7); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); - OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); - BEGIN_RING(chan, NvSubGdiRect, 0x03fc, 1); - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) - OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]); - else - OUT_RING(chan, rect->color); - BEGIN_RING(chan, NvSubGdiRect, 0x0400, 2); - OUT_RING(chan, (rect->dx << 16) | rect->dy); - OUT_RING(chan, (rect->width << 16) | rect->height); - FIRE_RING(chan); - return 0; -} - -int -nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - uint32_t fg; - uint32_t bg; - uint32_t dsize; - uint32_t width; - uint32_t *data = (uint32_t *)image->data; - int ret; - - if (image->depth != 1) - return -ENODEV; - - ret = RING_SPACE(chan, 8); - if (ret) - return ret; - - width = ALIGN(image->width, 8); - dsize = ALIGN(width * image->height, 32) >> 5; - - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fg = ((uint32_t *) info->pseudo_palette)[image->fg_color]; - bg = ((uint32_t *) info->pseudo_palette)[image->bg_color]; - } else { - fg = image->fg_color; - bg = image->bg_color; - } - - BEGIN_RING(chan, NvSubGdiRect, 0x0be4, 7); - OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); - OUT_RING(chan, ((image->dy + image->height) << 16) | - ((image->dx + image->width) & 0xffff)); - OUT_RING(chan, bg); - OUT_RING(chan, fg); - OUT_RING(chan, (image->height << 16) | width); - OUT_RING(chan, (image->height << 16) | image->width); - OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); - - while (dsize) { - int iter_len = dsize > 128 ? 128 : dsize; - - ret = RING_SPACE(chan, iter_len + 1); - if (ret) - return ret; - - BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len); - OUT_RINGp(chan, data, iter_len); - data += iter_len; - dsize -= iter_len; - } - - FIRE_RING(chan); - return 0; -} - -int -nv04_fbcon_accel_init(struct fb_info *info) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - const int sub = NvSubCtxSurf2D; - int surface_fmt, pattern_fmt, rect_fmt; - int ret; - - switch (info->var.bits_per_pixel) { - case 8: - surface_fmt = 1; - pattern_fmt = 3; - rect_fmt = 3; - break; - case 16: - surface_fmt = 4; - pattern_fmt = 1; - rect_fmt = 1; - break; - case 32: - switch (info->var.transp.length) { - case 0: /* depth 24 */ - case 8: /* depth 32 */ - break; - default: - return -EINVAL; - } - - surface_fmt = 6; - pattern_fmt = 3; - rect_fmt = 3; - break; - default: - return -EINVAL; - } - - ret = nouveau_gpuobj_gr_new(chan, NvCtxSurf2D, - dev_priv->card_type >= NV_10 ? - 0x0062 : 0x0042); - if (ret) - return ret; - - ret = nouveau_gpuobj_gr_new(chan, NvClipRect, 0x0019); - if (ret) - return ret; - - ret = nouveau_gpuobj_gr_new(chan, NvRop, 0x0043); - if (ret) - return ret; - - ret = nouveau_gpuobj_gr_new(chan, NvImagePatt, 0x0044); - if (ret) - return ret; - - ret = nouveau_gpuobj_gr_new(chan, NvGdiRect, 0x004a); - if (ret) - return ret; - - ret = nouveau_gpuobj_gr_new(chan, NvImageBlit, - dev_priv->chipset >= 0x11 ? - 0x009f : 0x005f); - if (ret) - return ret; - - if (RING_SPACE(chan, 49)) { - nouveau_fbcon_gpu_lockup(info); - return 0; - } - - BEGIN_RING(chan, sub, 0x0000, 1); - OUT_RING(chan, NvCtxSurf2D); - BEGIN_RING(chan, sub, 0x0184, 2); - OUT_RING(chan, NvDmaFB); - OUT_RING(chan, NvDmaFB); - BEGIN_RING(chan, sub, 0x0300, 4); - OUT_RING(chan, surface_fmt); - OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16)); - OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); - OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); - - BEGIN_RING(chan, sub, 0x0000, 1); - OUT_RING(chan, NvRop); - BEGIN_RING(chan, sub, 0x0300, 1); - OUT_RING(chan, 0x55); - - BEGIN_RING(chan, sub, 0x0000, 1); - OUT_RING(chan, NvImagePatt); - BEGIN_RING(chan, sub, 0x0300, 8); - OUT_RING(chan, pattern_fmt); -#ifdef __BIG_ENDIAN - OUT_RING(chan, 2); -#else - OUT_RING(chan, 1); -#endif - OUT_RING(chan, 0); - OUT_RING(chan, 1); - OUT_RING(chan, ~0); - OUT_RING(chan, ~0); - OUT_RING(chan, ~0); - OUT_RING(chan, ~0); - - BEGIN_RING(chan, sub, 0x0000, 1); - OUT_RING(chan, NvClipRect); - BEGIN_RING(chan, sub, 0x0300, 2); - OUT_RING(chan, 0); - OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual); - - BEGIN_RING(chan, NvSubImageBlit, 0x0000, 1); - OUT_RING(chan, NvImageBlit); - BEGIN_RING(chan, NvSubImageBlit, 0x019c, 1); - OUT_RING(chan, NvCtxSurf2D); - BEGIN_RING(chan, NvSubImageBlit, 0x02fc, 1); - OUT_RING(chan, 3); - - BEGIN_RING(chan, NvSubGdiRect, 0x0000, 1); - OUT_RING(chan, NvGdiRect); - BEGIN_RING(chan, NvSubGdiRect, 0x0198, 1); - OUT_RING(chan, NvCtxSurf2D); - BEGIN_RING(chan, NvSubGdiRect, 0x0188, 2); - OUT_RING(chan, NvImagePatt); - OUT_RING(chan, NvRop); - BEGIN_RING(chan, NvSubGdiRect, 0x0304, 1); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSubGdiRect, 0x0300, 1); - OUT_RING(chan, rect_fmt); - BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); - OUT_RING(chan, 3); - - FIRE_RING(chan); - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fifo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fifo.c deleted file mode 100644 index db465a3e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_fifo.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" -#include "nouveau_util.h" - -#define NV04_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV04_RAMFC__SIZE)) -#define NV04_RAMFC__SIZE 32 -#define NV04_RAMFC_DMA_PUT 0x00 -#define NV04_RAMFC_DMA_GET 0x04 -#define NV04_RAMFC_DMA_INSTANCE 0x08 -#define NV04_RAMFC_DMA_STATE 0x0C -#define NV04_RAMFC_DMA_FETCH 0x10 -#define NV04_RAMFC_ENGINE 0x14 -#define NV04_RAMFC_PULL1_ENGINE 0x18 - -#define RAMFC_WR(offset, val) nv_wo32(chan->ramfc, NV04_RAMFC_##offset, (val)) -#define RAMFC_RD(offset) nv_ro32(chan->ramfc, NV04_RAMFC_##offset) - -void -nv04_fifo_disable(struct drm_device *dev) -{ - uint32_t tmp; - - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, tmp & ~1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 0); - tmp = nv_rd32(dev, NV03_PFIFO_CACHE1_PULL1); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, tmp & ~1); -} - -void -nv04_fifo_enable(struct drm_device *dev) -{ - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, 1); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); -} - -bool -nv04_fifo_reassign(struct drm_device *dev, bool enable) -{ - uint32_t reassign = nv_rd32(dev, NV03_PFIFO_CACHES); - - nv_wr32(dev, NV03_PFIFO_CACHES, enable ? 1 : 0); - return (reassign == 1); -} - -bool -nv04_fifo_cache_pull(struct drm_device *dev, bool enable) -{ - int pull = nv_mask(dev, NV04_PFIFO_CACHE1_PULL0, 1, enable); - - if (!enable) { - /* In some cases the PFIFO puller may be left in an - * inconsistent state if you try to stop it when it's - * busy translating handles. Sometimes you get a - * PFIFO_CACHE_ERROR, sometimes it just fails silently - * sending incorrect instance offsets to PGRAPH after - * it's started up again. To avoid the latter we - * invalidate the most recently calculated instance. - */ - if (!nv_wait(dev, NV04_PFIFO_CACHE1_PULL0, - NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0)) - NV_ERROR(dev, "Timeout idling the PFIFO puller.\n"); - - if (nv_rd32(dev, NV04_PFIFO_CACHE1_PULL0) & - NV04_PFIFO_CACHE1_PULL0_HASH_FAILED) - nv_wr32(dev, NV03_PFIFO_INTR_0, - NV_PFIFO_INTR_CACHE_ERROR); - - nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); - } - - return pull & 1; -} - -int -nv04_fifo_channel_id(struct drm_device *dev) -{ - return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & - NV03_PFIFO_CACHE1_PUSH1_CHID_MASK; -} - -#ifdef __BIG_ENDIAN -#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN -#else -#define DMA_FETCH_ENDIANNESS 0 -#endif - -int -nv04_fifo_create_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - int ret; - - ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, - NV04_RAMFC__SIZE, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, - &chan->ramfc); - if (ret) - return ret; - - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV03_USER(chan->id), PAGE_SIZE); - if (!chan->user) - return -ENOMEM; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - - /* Setup initial state */ - RAMFC_WR(DMA_PUT, chan->pushbuf_base); - RAMFC_WR(DMA_GET, chan->pushbuf_base); - RAMFC_WR(DMA_INSTANCE, chan->pushbuf->pinst >> 4); - RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | - DMA_FETCH_ENDIANNESS)); - - /* enable the fifo dma operation */ - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); - - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - return 0; -} - -void -nv04_fifo_destroy_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - pfifo->reassign(dev, false); - - /* Unload the context if it's the currently active one */ - if (pfifo->channel_id(dev) == chan->id) { - pfifo->disable(dev); - pfifo->unload_context(dev); - pfifo->enable(dev); - } - - /* Keep it from being rescheduled */ - nv_mask(dev, NV04_PFIFO_MODE, 1 << chan->id, 0); - - pfifo->reassign(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the channel resources */ - if (chan->user) { - iounmap(chan->user); - chan->user = NULL; - } - nouveau_gpuobj_ref(NULL, &chan->ramfc); -} - -static void -nv04_fifo_do_load_context(struct drm_device *dev, int chid) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t fc = NV04_RAMFC(chid), tmp; - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); - tmp = nv_ri32(dev, fc + 8); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 12)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 16)); - nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20)); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24)); - - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); -} - -int -nv04_fifo_load_context(struct nouveau_channel *chan) -{ - uint32_t tmp; - - nv_wr32(chan->dev, NV03_PFIFO_CACHE1_PUSH1, - NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); - nv04_fifo_do_load_context(chan->dev, chan->id); - nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); - - /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ - tmp = nv_rd32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); - nv_wr32(chan->dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); - - return 0; -} - -int -nv04_fifo_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_channel *chan = NULL; - uint32_t tmp; - int chid; - - chid = pfifo->channel_id(dev); - if (chid < 0 || chid >= dev_priv->engine.fifo.channels) - return 0; - - chan = dev_priv->channels.ptr[chid]; - if (!chan) { - NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); - return -EINVAL; - } - - RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); - RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16; - tmp |= nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE); - RAMFC_WR(DMA_INSTANCE, tmp); - RAMFC_WR(DMA_STATE, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); - RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); - RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); - RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); - - nv04_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); - return 0; -} - -static void -nv04_fifo_init_reset(struct drm_device *dev) -{ - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); - - nv_wr32(dev, 0x003224, 0x000f0078); - nv_wr32(dev, 0x002044, 0x0101ffff); - nv_wr32(dev, 0x002040, 0x000000ff); - nv_wr32(dev, 0x002500, 0x00000000); - nv_wr32(dev, 0x003000, 0x00000000); - nv_wr32(dev, 0x003050, 0x00000000); - nv_wr32(dev, 0x003200, 0x00000000); - nv_wr32(dev, 0x003250, 0x00000000); - nv_wr32(dev, 0x003220, 0x00000000); - - nv_wr32(dev, 0x003250, 0x00000000); - nv_wr32(dev, 0x003270, 0x00000000); - nv_wr32(dev, 0x003210, 0x00000000); -} - -static void -nv04_fifo_init_ramxx(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | - ((dev_priv->ramht->bits - 9) << 16) | - (dev_priv->ramht->gpuobj->pinst >> 8)); - nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8); - nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8); -} - -static void -nv04_fifo_init_intr(struct drm_device *dev) -{ - nouveau_irq_register(dev, 8, nv04_fifo_isr); - nv_wr32(dev, 0x002100, 0xffffffff); - nv_wr32(dev, 0x002140, 0xffffffff); -} - -int -nv04_fifo_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - int i; - - nv04_fifo_init_reset(dev); - nv04_fifo_init_ramxx(dev); - - nv04_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); - - nv04_fifo_init_intr(dev); - pfifo->enable(dev); - pfifo->reassign(dev, true); - - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (dev_priv->channels.ptr[i]) { - uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); - nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); - } - } - - return 0; -} - -void -nv04_fifo_fini(struct drm_device *dev) -{ - nv_wr32(dev, 0x2140, 0x00000000); - nouveau_irq_unregister(dev, 8); -} - -static bool -nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - struct nouveau_gpuobj *obj; - unsigned long flags; - const int subc = (addr >> 13) & 0x7; - const int mthd = addr & 0x1ffc; - bool handled = false; - u32 engine; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) - chan = dev_priv->channels.ptr[chid]; - if (unlikely(!chan)) - goto out; - - switch (mthd) { - case 0x0000: /* bind object to subchannel */ - obj = nouveau_ramht_find(chan, data); - if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW)) - break; - - chan->sw_subchannel[subc] = obj->class; - engine = 0x0000000f << (subc * 4); - - nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000); - handled = true; - break; - default: - engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE); - if (unlikely(((engine >> (subc * 4)) & 0xf) != 0)) - break; - - if (!nouveau_gpuobj_mthd_call(chan, chan->sw_subchannel[subc], - mthd, data)) - handled = true; - break; - } - -out: - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return handled; -} - -static const char *nv_dma_state_err(u32 state) -{ - static const char * const desc[] = { - "NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD", "RET_SUBR_INACTIVE", - "INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT", "UNK" - }; - return desc[(state >> 29) & 0x7]; -} - -void -nv04_fifo_isr(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - uint32_t status, reassign; - int cnt = 0; - - reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; - while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { - uint32_t chid, get; - - nv_wr32(dev, NV03_PFIFO_CACHES, 0); - - chid = engine->fifo.channel_id(dev); - get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); - - if (status & NV_PFIFO_INTR_CACHE_ERROR) { - uint32_t mthd, data; - int ptr; - - /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before - * wrapping on my G80 chips, but CACHE1 isn't big - * enough for this much data.. Tests show that it - * wraps around to the start at GET=0x800.. No clue - * as to why.. - */ - ptr = (get & 0x7ff) >> 2; - - if (dev_priv->card_type < NV_40) { - mthd = nv_rd32(dev, - NV04_PFIFO_CACHE1_METHOD(ptr)); - data = nv_rd32(dev, - NV04_PFIFO_CACHE1_DATA(ptr)); - } else { - mthd = nv_rd32(dev, - NV40_PFIFO_CACHE1_METHOD(ptr)); - data = nv_rd32(dev, - NV40_PFIFO_CACHE1_DATA(ptr)); - } - - if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) { - NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " - "Mthd 0x%04x Data 0x%08x\n", - chid, (mthd >> 13) & 7, mthd & 0x1ffc, - data); - } - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0); - nv_wr32(dev, NV03_PFIFO_INTR_0, - NV_PFIFO_INTR_CACHE_ERROR); - - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, - nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, - nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1); - nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, - nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); - - status &= ~NV_PFIFO_INTR_CACHE_ERROR; - } - - if (status & NV_PFIFO_INTR_DMA_PUSHER) { - u32 dma_get = nv_rd32(dev, 0x003244); - u32 dma_put = nv_rd32(dev, 0x003240); - u32 push = nv_rd32(dev, 0x003220); - u32 state = nv_rd32(dev, 0x003228); - - if (dev_priv->card_type == NV_50) { - u32 ho_get = nv_rd32(dev, 0x003328); - u32 ho_put = nv_rd32(dev, 0x003320); - u32 ib_get = nv_rd32(dev, 0x003334); - u32 ib_put = nv_rd32(dev, 0x003330); - - if (nouveau_ratelimit()) - NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " - "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " - "State 0x%08x (err: %s) Push 0x%08x\n", - chid, ho_get, dma_get, ho_put, - dma_put, ib_get, ib_put, state, - nv_dma_state_err(state), - push); - - /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ - nv_wr32(dev, 0x003364, 0x00000000); - if (dma_get != dma_put || ho_get != ho_put) { - nv_wr32(dev, 0x003244, dma_put); - nv_wr32(dev, 0x003328, ho_put); - } else - if (ib_get != ib_put) { - nv_wr32(dev, 0x003334, ib_put); - } - } else { - NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " - "Put 0x%08x State 0x%08x (err: %s) Push 0x%08x\n", - chid, dma_get, dma_put, state, - nv_dma_state_err(state), push); - - if (dma_get != dma_put) - nv_wr32(dev, 0x003244, dma_put); - } - - nv_wr32(dev, 0x003228, 0x00000000); - nv_wr32(dev, 0x003220, 0x00000001); - nv_wr32(dev, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); - status &= ~NV_PFIFO_INTR_DMA_PUSHER; - } - - if (status & NV_PFIFO_INTR_SEMAPHORE) { - uint32_t sem; - - status &= ~NV_PFIFO_INTR_SEMAPHORE; - nv_wr32(dev, NV03_PFIFO_INTR_0, - NV_PFIFO_INTR_SEMAPHORE); - - sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE); - nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); - - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); - } - - if (dev_priv->card_type == NV_50) { - if (status & 0x00000010) { - nv50_fb_vm_trap(dev, nouveau_ratelimit()); - status &= ~0x00000010; - nv_wr32(dev, 0x002100, 0x00000010); - } - } - - if (status) { - if (nouveau_ratelimit()) - NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", - status, chid); - nv_wr32(dev, NV03_PFIFO_INTR_0, status); - status = 0; - } - - nv_wr32(dev, NV03_PFIFO_CACHES, reassign); - } - - if (status) { - NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt); - nv_wr32(dev, 0x2140, 0); - nv_wr32(dev, 0x140, 0); - } - - nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_graph.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_graph.c deleted file mode 100644 index dbdea8ed..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_graph.c +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * Copyright 2007 Stephane Marchesin - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drm.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_util.h" -#include "nouveau_ramht.h" - -struct nv04_graph_engine { - struct nouveau_exec_engine base; -}; - -static uint32_t nv04_graph_ctx_regs[] = { - 0x0040053c, - 0x00400544, - 0x00400540, - 0x00400548, - NV04_PGRAPH_CTX_SWITCH1, - NV04_PGRAPH_CTX_SWITCH2, - NV04_PGRAPH_CTX_SWITCH3, - NV04_PGRAPH_CTX_SWITCH4, - NV04_PGRAPH_CTX_CACHE1, - NV04_PGRAPH_CTX_CACHE2, - NV04_PGRAPH_CTX_CACHE3, - NV04_PGRAPH_CTX_CACHE4, - 0x00400184, - 0x004001a4, - 0x004001c4, - 0x004001e4, - 0x00400188, - 0x004001a8, - 0x004001c8, - 0x004001e8, - 0x0040018c, - 0x004001ac, - 0x004001cc, - 0x004001ec, - 0x00400190, - 0x004001b0, - 0x004001d0, - 0x004001f0, - 0x00400194, - 0x004001b4, - 0x004001d4, - 0x004001f4, - 0x00400198, - 0x004001b8, - 0x004001d8, - 0x004001f8, - 0x0040019c, - 0x004001bc, - 0x004001dc, - 0x004001fc, - 0x00400174, - NV04_PGRAPH_DMA_START_0, - NV04_PGRAPH_DMA_START_1, - NV04_PGRAPH_DMA_LENGTH, - NV04_PGRAPH_DMA_MISC, - NV04_PGRAPH_DMA_PITCH, - NV04_PGRAPH_BOFFSET0, - NV04_PGRAPH_BBASE0, - NV04_PGRAPH_BLIMIT0, - NV04_PGRAPH_BOFFSET1, - NV04_PGRAPH_BBASE1, - NV04_PGRAPH_BLIMIT1, - NV04_PGRAPH_BOFFSET2, - NV04_PGRAPH_BBASE2, - NV04_PGRAPH_BLIMIT2, - NV04_PGRAPH_BOFFSET3, - NV04_PGRAPH_BBASE3, - NV04_PGRAPH_BLIMIT3, - NV04_PGRAPH_BOFFSET4, - NV04_PGRAPH_BBASE4, - NV04_PGRAPH_BLIMIT4, - NV04_PGRAPH_BOFFSET5, - NV04_PGRAPH_BBASE5, - NV04_PGRAPH_BLIMIT5, - NV04_PGRAPH_BPITCH0, - NV04_PGRAPH_BPITCH1, - NV04_PGRAPH_BPITCH2, - NV04_PGRAPH_BPITCH3, - NV04_PGRAPH_BPITCH4, - NV04_PGRAPH_SURFACE, - NV04_PGRAPH_STATE, - NV04_PGRAPH_BSWIZZLE2, - NV04_PGRAPH_BSWIZZLE5, - NV04_PGRAPH_BPIXEL, - NV04_PGRAPH_NOTIFY, - NV04_PGRAPH_PATT_COLOR0, - NV04_PGRAPH_PATT_COLOR1, - NV04_PGRAPH_PATT_COLORRAM+0x00, - NV04_PGRAPH_PATT_COLORRAM+0x04, - NV04_PGRAPH_PATT_COLORRAM+0x08, - NV04_PGRAPH_PATT_COLORRAM+0x0c, - NV04_PGRAPH_PATT_COLORRAM+0x10, - NV04_PGRAPH_PATT_COLORRAM+0x14, - NV04_PGRAPH_PATT_COLORRAM+0x18, - NV04_PGRAPH_PATT_COLORRAM+0x1c, - NV04_PGRAPH_PATT_COLORRAM+0x20, - NV04_PGRAPH_PATT_COLORRAM+0x24, - NV04_PGRAPH_PATT_COLORRAM+0x28, - NV04_PGRAPH_PATT_COLORRAM+0x2c, - NV04_PGRAPH_PATT_COLORRAM+0x30, - NV04_PGRAPH_PATT_COLORRAM+0x34, - NV04_PGRAPH_PATT_COLORRAM+0x38, - NV04_PGRAPH_PATT_COLORRAM+0x3c, - NV04_PGRAPH_PATT_COLORRAM+0x40, - NV04_PGRAPH_PATT_COLORRAM+0x44, - NV04_PGRAPH_PATT_COLORRAM+0x48, - NV04_PGRAPH_PATT_COLORRAM+0x4c, - NV04_PGRAPH_PATT_COLORRAM+0x50, - NV04_PGRAPH_PATT_COLORRAM+0x54, - NV04_PGRAPH_PATT_COLORRAM+0x58, - NV04_PGRAPH_PATT_COLORRAM+0x5c, - NV04_PGRAPH_PATT_COLORRAM+0x60, - NV04_PGRAPH_PATT_COLORRAM+0x64, - NV04_PGRAPH_PATT_COLORRAM+0x68, - NV04_PGRAPH_PATT_COLORRAM+0x6c, - NV04_PGRAPH_PATT_COLORRAM+0x70, - NV04_PGRAPH_PATT_COLORRAM+0x74, - NV04_PGRAPH_PATT_COLORRAM+0x78, - NV04_PGRAPH_PATT_COLORRAM+0x7c, - NV04_PGRAPH_PATT_COLORRAM+0x80, - NV04_PGRAPH_PATT_COLORRAM+0x84, - NV04_PGRAPH_PATT_COLORRAM+0x88, - NV04_PGRAPH_PATT_COLORRAM+0x8c, - NV04_PGRAPH_PATT_COLORRAM+0x90, - NV04_PGRAPH_PATT_COLORRAM+0x94, - NV04_PGRAPH_PATT_COLORRAM+0x98, - NV04_PGRAPH_PATT_COLORRAM+0x9c, - NV04_PGRAPH_PATT_COLORRAM+0xa0, - NV04_PGRAPH_PATT_COLORRAM+0xa4, - NV04_PGRAPH_PATT_COLORRAM+0xa8, - NV04_PGRAPH_PATT_COLORRAM+0xac, - NV04_PGRAPH_PATT_COLORRAM+0xb0, - NV04_PGRAPH_PATT_COLORRAM+0xb4, - NV04_PGRAPH_PATT_COLORRAM+0xb8, - NV04_PGRAPH_PATT_COLORRAM+0xbc, - NV04_PGRAPH_PATT_COLORRAM+0xc0, - NV04_PGRAPH_PATT_COLORRAM+0xc4, - NV04_PGRAPH_PATT_COLORRAM+0xc8, - NV04_PGRAPH_PATT_COLORRAM+0xcc, - NV04_PGRAPH_PATT_COLORRAM+0xd0, - NV04_PGRAPH_PATT_COLORRAM+0xd4, - NV04_PGRAPH_PATT_COLORRAM+0xd8, - NV04_PGRAPH_PATT_COLORRAM+0xdc, - NV04_PGRAPH_PATT_COLORRAM+0xe0, - NV04_PGRAPH_PATT_COLORRAM+0xe4, - NV04_PGRAPH_PATT_COLORRAM+0xe8, - NV04_PGRAPH_PATT_COLORRAM+0xec, - NV04_PGRAPH_PATT_COLORRAM+0xf0, - NV04_PGRAPH_PATT_COLORRAM+0xf4, - NV04_PGRAPH_PATT_COLORRAM+0xf8, - NV04_PGRAPH_PATT_COLORRAM+0xfc, - NV04_PGRAPH_PATTERN, - 0x0040080c, - NV04_PGRAPH_PATTERN_SHAPE, - 0x00400600, - NV04_PGRAPH_ROP3, - NV04_PGRAPH_CHROMA, - NV04_PGRAPH_BETA_AND, - NV04_PGRAPH_BETA_PREMULT, - NV04_PGRAPH_CONTROL0, - NV04_PGRAPH_CONTROL1, - NV04_PGRAPH_CONTROL2, - NV04_PGRAPH_BLEND, - NV04_PGRAPH_STORED_FMT, - NV04_PGRAPH_SOURCE_COLOR, - 0x00400560, - 0x00400568, - 0x00400564, - 0x0040056c, - 0x00400400, - 0x00400480, - 0x00400404, - 0x00400484, - 0x00400408, - 0x00400488, - 0x0040040c, - 0x0040048c, - 0x00400410, - 0x00400490, - 0x00400414, - 0x00400494, - 0x00400418, - 0x00400498, - 0x0040041c, - 0x0040049c, - 0x00400420, - 0x004004a0, - 0x00400424, - 0x004004a4, - 0x00400428, - 0x004004a8, - 0x0040042c, - 0x004004ac, - 0x00400430, - 0x004004b0, - 0x00400434, - 0x004004b4, - 0x00400438, - 0x004004b8, - 0x0040043c, - 0x004004bc, - 0x00400440, - 0x004004c0, - 0x00400444, - 0x004004c4, - 0x00400448, - 0x004004c8, - 0x0040044c, - 0x004004cc, - 0x00400450, - 0x004004d0, - 0x00400454, - 0x004004d4, - 0x00400458, - 0x004004d8, - 0x0040045c, - 0x004004dc, - 0x00400460, - 0x004004e0, - 0x00400464, - 0x004004e4, - 0x00400468, - 0x004004e8, - 0x0040046c, - 0x004004ec, - 0x00400470, - 0x004004f0, - 0x00400474, - 0x004004f4, - 0x00400478, - 0x004004f8, - 0x0040047c, - 0x004004fc, - 0x00400534, - 0x00400538, - 0x00400514, - 0x00400518, - 0x0040051c, - 0x00400520, - 0x00400524, - 0x00400528, - 0x0040052c, - 0x00400530, - 0x00400d00, - 0x00400d40, - 0x00400d80, - 0x00400d04, - 0x00400d44, - 0x00400d84, - 0x00400d08, - 0x00400d48, - 0x00400d88, - 0x00400d0c, - 0x00400d4c, - 0x00400d8c, - 0x00400d10, - 0x00400d50, - 0x00400d90, - 0x00400d14, - 0x00400d54, - 0x00400d94, - 0x00400d18, - 0x00400d58, - 0x00400d98, - 0x00400d1c, - 0x00400d5c, - 0x00400d9c, - 0x00400d20, - 0x00400d60, - 0x00400da0, - 0x00400d24, - 0x00400d64, - 0x00400da4, - 0x00400d28, - 0x00400d68, - 0x00400da8, - 0x00400d2c, - 0x00400d6c, - 0x00400dac, - 0x00400d30, - 0x00400d70, - 0x00400db0, - 0x00400d34, - 0x00400d74, - 0x00400db4, - 0x00400d38, - 0x00400d78, - 0x00400db8, - 0x00400d3c, - 0x00400d7c, - 0x00400dbc, - 0x00400590, - 0x00400594, - 0x00400598, - 0x0040059c, - 0x004005a8, - 0x004005ac, - 0x004005b0, - 0x004005b4, - 0x004005c0, - 0x004005c4, - 0x004005c8, - 0x004005cc, - 0x004005d0, - 0x004005d4, - 0x004005d8, - 0x004005dc, - 0x004005e0, - NV04_PGRAPH_PASSTHRU_0, - NV04_PGRAPH_PASSTHRU_1, - NV04_PGRAPH_PASSTHRU_2, - NV04_PGRAPH_DVD_COLORFMT, - NV04_PGRAPH_SCALED_FORMAT, - NV04_PGRAPH_MISC24_0, - NV04_PGRAPH_MISC24_1, - NV04_PGRAPH_MISC24_2, - 0x00400500, - 0x00400504, - NV04_PGRAPH_VALID1, - NV04_PGRAPH_VALID2, - NV04_PGRAPH_DEBUG_3 -}; - -struct graph_state { - uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)]; -}; - -static struct nouveau_channel * -nv04_graph_channel(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chid = dev_priv->engine.fifo.channels; - - if (nv_rd32(dev, NV04_PGRAPH_CTX_CONTROL) & 0x00010000) - chid = nv_rd32(dev, NV04_PGRAPH_CTX_USER) >> 24; - - if (chid >= dev_priv->engine.fifo.channels) - return NULL; - - return dev_priv->channels.ptr[chid]; -} - -static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) { - if (nv04_graph_ctx_regs[i] == reg) - return &ctx->nv04[i]; - } - - return NULL; -} - -static int -nv04_graph_load_context(struct nouveau_channel *chan) -{ - struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - uint32_t tmp; - int i; - - for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) - nv_wr32(dev, nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]); - - nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10010100); - - tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; - nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp | chan->id << 24); - - tmp = nv_rd32(dev, NV04_PGRAPH_FFINTFC_ST2); - nv_wr32(dev, NV04_PGRAPH_FFINTFC_ST2, tmp & 0x000fffff); - - return 0; -} - -static int -nv04_graph_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - struct graph_state *ctx; - uint32_t tmp; - int i; - - chan = nv04_graph_channel(dev); - if (!chan) - return 0; - ctx = chan->engctx[NVOBJ_ENGINE_GR]; - - for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++) - ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]); - - nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL, 0x10000000); - tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; - tmp |= (dev_priv->engine.fifo.channels - 1) << 24; - nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); - return 0; -} - -static int -nv04_graph_context_new(struct nouveau_channel *chan, int engine) -{ - struct graph_state *pgraph_ctx; - NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id); - - pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL); - if (pgraph_ctx == NULL) - return -ENOMEM; - - *ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31; - - chan->engctx[engine] = pgraph_ctx; - return 0; -} - -static void -nv04_graph_context_del(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct graph_state *pgraph_ctx = chan->engctx[engine]; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - - /* Unload the context if it's the currently active one */ - if (nv04_graph_channel(dev) == chan) - nv04_graph_unload_context(dev); - - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the context resources */ - kfree(pgraph_ctx); - chan->engctx[engine] = NULL; -} - -int -nv04_graph_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - obj->engine = 1; - obj->class = class; - -#ifdef __BIG_ENDIAN - nv_wo32(obj, 0x00, 0x00080000 | class); -#else - nv_wo32(obj, 0x00, class); -#endif - nv_wo32(obj, 0x04, 0x00000000); - nv_wo32(obj, 0x08, 0x00000000); - nv_wo32(obj, 0x0c, 0x00000000); - - ret = nouveau_ramht_insert(chan, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static int -nv04_graph_init(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t tmp; - - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & - ~NV_PMC_ENABLE_PGRAPH); - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | - NV_PMC_ENABLE_PGRAPH); - - /* Enable PGRAPH interrupts */ - nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - - nv_wr32(dev, NV04_PGRAPH_VALID1, 0); - nv_wr32(dev, NV04_PGRAPH_VALID2, 0); - /*nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x000001FF); - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/ - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000); - /*1231C000 blob, 001 haiku*/ - /*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/ - nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100); - /*0x72111100 blob , 01 haiku*/ - /*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/ - nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f071); - /*haiku same*/ - - /*nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/ - nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf0d4ff31); - /*haiku and blob 10d4*/ - - nv_wr32(dev, NV04_PGRAPH_STATE , 0xFFFFFFFF); - nv_wr32(dev, NV04_PGRAPH_CTX_CONTROL , 0x10000100); - tmp = nv_rd32(dev, NV04_PGRAPH_CTX_USER) & 0x00ffffff; - tmp |= (dev_priv->engine.fifo.channels - 1) << 24; - nv_wr32(dev, NV04_PGRAPH_CTX_USER, tmp); - - /* These don't belong here, they're part of a per-channel context */ - nv_wr32(dev, NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); - nv_wr32(dev, NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); - - return 0; -} - -static int -nv04_graph_fini(struct drm_device *dev, int engine, bool suspend) -{ - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) { - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - return -EBUSY; - } - nv04_graph_unload_context(dev); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); - return 0; -} - -static int -nv04_graph_mthd_set_ref(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - atomic_set(&chan->fence.last_sequence_irq, data); - return 0; -} - -int -nv04_graph_mthd_page_flip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - struct drm_device *dev = chan->dev; - struct nouveau_page_flip_state s; - - if (!nouveau_finish_page_flip(chan, &s)) - nv_set_crtc_base(dev, s.crtc, - s.offset + s.y * s.pitch + s.x * s.bpp / 8); - - return 0; -} - -/* - * Software methods, why they are needed, and how they all work: - * - * NV04 and NV05 keep most of the state in PGRAPH context itself, but some - * 2d engine settings are kept inside the grobjs themselves. The grobjs are - * 3 words long on both. grobj format on NV04 is: - * - * word 0: - * - bits 0-7: class - * - bit 12: color key active - * - bit 13: clip rect active - * - bit 14: if set, destination surface is swizzled and taken from buffer 5 - * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken - * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or - * NV03_CONTEXT_SURFACE_DST]. - * - bits 15-17: 2d operation [aka patch config] - * - bit 24: patch valid [enables rendering using this object] - * - bit 25: surf3d valid [for tex_tri and multitex_tri only] - * word 1: - * - bits 0-1: mono format - * - bits 8-13: color format - * - bits 16-31: DMA_NOTIFY instance - * word 2: - * - bits 0-15: DMA_A instance - * - bits 16-31: DMA_B instance - * - * On NV05 it's: - * - * word 0: - * - bits 0-7: class - * - bit 12: color key active - * - bit 13: clip rect active - * - bit 14: if set, destination surface is swizzled and taken from buffer 5 - * [set by NV04_SWIZZLED_SURFACE], otherwise it's linear and taken - * from buffer 0 [set by NV04_CONTEXT_SURFACES_2D or - * NV03_CONTEXT_SURFACE_DST]. - * - bits 15-17: 2d operation [aka patch config] - * - bits 20-22: dither mode - * - bit 24: patch valid [enables rendering using this object] - * - bit 25: surface_dst/surface_color/surf2d/surf3d valid - * - bit 26: surface_src/surface_zeta valid - * - bit 27: pattern valid - * - bit 28: rop valid - * - bit 29: beta1 valid - * - bit 30: beta4 valid - * word 1: - * - bits 0-1: mono format - * - bits 8-13: color format - * - bits 16-31: DMA_NOTIFY instance - * word 2: - * - bits 0-15: DMA_A instance - * - bits 16-31: DMA_B instance - * - * NV05 will set/unset the relevant valid bits when you poke the relevant - * object-binding methods with object of the proper type, or with the NULL - * type. It'll only allow rendering using the grobj if all needed objects - * are bound. The needed set of objects depends on selected operation: for - * example rop object is needed by ROP_AND, but not by SRCCOPY_AND. - * - * NV04 doesn't have these methods implemented at all, and doesn't have the - * relevant bits in grobj. Instead, it'll allow rendering whenever bit 24 - * is set. So we have to emulate them in software, internally keeping the - * same bits as NV05 does. Since grobjs are aligned to 16 bytes on nv04, - * but the last word isn't actually used for anything, we abuse it for this - * purpose. - * - * Actually, NV05 can optionally check bit 24 too, but we disable this since - * there's no use for it. - * - * For unknown reasons, NV04 implements surf3d binding in hardware as an - * exception. Also for unknown reasons, NV04 doesn't implement the clipping - * methods on the surf3d object, so we have to emulate them too. - */ - -static void -nv04_graph_set_ctx1(struct nouveau_channel *chan, u32 mask, u32 value) -{ - struct drm_device *dev = chan->dev; - u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; - int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; - u32 tmp; - - tmp = nv_ri32(dev, instance); - tmp &= ~mask; - tmp |= value; - - nv_wi32(dev, instance, tmp); - nv_wr32(dev, NV04_PGRAPH_CTX_SWITCH1, tmp); - nv_wr32(dev, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp); -} - -static void -nv04_graph_set_ctx_val(struct nouveau_channel *chan, u32 mask, u32 value) -{ - struct drm_device *dev = chan->dev; - u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; - u32 tmp, ctx1; - int class, op, valid = 1; - - ctx1 = nv_ri32(dev, instance); - class = ctx1 & 0xff; - op = (ctx1 >> 15) & 7; - tmp = nv_ri32(dev, instance + 0xc); - tmp &= ~mask; - tmp |= value; - nv_wi32(dev, instance + 0xc, tmp); - - /* check for valid surf2d/surf_dst/surf_color */ - if (!(tmp & 0x02000000)) - valid = 0; - /* check for valid surf_src/surf_zeta */ - if ((class == 0x1f || class == 0x48) && !(tmp & 0x04000000)) - valid = 0; - - switch (op) { - /* SRCCOPY_AND, SRCCOPY: no extra objects required */ - case 0: - case 3: - break; - /* ROP_AND: requires pattern and rop */ - case 1: - if (!(tmp & 0x18000000)) - valid = 0; - break; - /* BLEND_AND: requires beta1 */ - case 2: - if (!(tmp & 0x20000000)) - valid = 0; - break; - /* SRCCOPY_PREMULT, BLEND_PREMULT: beta4 required */ - case 4: - case 5: - if (!(tmp & 0x40000000)) - valid = 0; - break; - } - - nv04_graph_set_ctx1(chan, 0x01000000, valid << 24); -} - -static int -nv04_graph_mthd_set_operation(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - if (data > 5) - return 1; - /* Old versions of the objects only accept first three operations. */ - if (data > 2 && class < 0x40) - return 1; - nv04_graph_set_ctx1(chan, 0x00038000, data << 15); - /* changing operation changes set of objects needed for validation */ - nv04_graph_set_ctx_val(chan, 0, 0); - return 0; -} - -static int -nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - uint32_t min = data & 0xffff, max; - uint32_t w = data >> 16; - if (min & 0x8000) - /* too large */ - return 1; - if (w & 0x8000) - /* yes, it accepts negative for some reason. */ - w |= 0xffff0000; - max = min + w; - max &= 0x3ffff; - nv_wr32(chan->dev, 0x40053c, min); - nv_wr32(chan->dev, 0x400544, max); - return 0; -} - -static int -nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - uint32_t min = data & 0xffff, max; - uint32_t w = data >> 16; - if (min & 0x8000) - /* too large */ - return 1; - if (w & 0x8000) - /* yes, it accepts negative for some reason. */ - w |= 0xffff0000; - max = min + w; - max &= 0x3ffff; - nv_wr32(chan->dev, 0x400540, min); - nv_wr32(chan->dev, 0x400548, max); - return 0; -} - -static int -nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx1(chan, 0x00004000, 0); - nv04_graph_set_ctx_val(chan, 0x02000000, 0); - return 0; - case 0x42: - nv04_graph_set_ctx1(chan, 0x00004000, 0); - nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx1(chan, 0x00004000, 0); - nv04_graph_set_ctx_val(chan, 0x02000000, 0); - return 0; - case 0x42: - nv04_graph_set_ctx1(chan, 0x00004000, 0); - nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000); - return 0; - case 0x52: - nv04_graph_set_ctx1(chan, 0x00004000, 0x00004000); - nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x08000000, 0); - return 0; - case 0x18: - nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x08000000, 0); - return 0; - case 0x44: - nv04_graph_set_ctx_val(chan, 0x08000000, 0x08000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_rop(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x10000000, 0); - return 0; - case 0x43: - nv04_graph_set_ctx_val(chan, 0x10000000, 0x10000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x20000000, 0); - return 0; - case 0x12: - nv04_graph_set_ctx_val(chan, 0x20000000, 0x20000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x40000000, 0); - return 0; - case 0x72: - nv04_graph_set_ctx_val(chan, 0x40000000, 0x40000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x02000000, 0); - return 0; - case 0x58: - nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x04000000, 0); - return 0; - case 0x59: - nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x02000000, 0); - return 0; - case 0x5a: - nv04_graph_set_ctx_val(chan, 0x02000000, 0x02000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx_val(chan, 0x04000000, 0); - return 0; - case 0x5b: - nv04_graph_set_ctx_val(chan, 0x04000000, 0x04000000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_clip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx1(chan, 0x2000, 0); - return 0; - case 0x19: - nv04_graph_set_ctx1(chan, 0x2000, 0x2000); - return 0; - } - return 1; -} - -static int -nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - switch (nv_ri32(chan->dev, data << 4) & 0xff) { - case 0x30: - nv04_graph_set_ctx1(chan, 0x1000, 0); - return 0; - /* Yes, for some reason even the old versions of objects - * accept 0x57 and not 0x17. Consistency be damned. - */ - case 0x57: - nv04_graph_set_ctx1(chan, 0x1000, 0x1000); - return 0; - } - return 1; -} - -static struct nouveau_bitfield nv04_graph_intr[] = { - { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, - {} -}; - -static struct nouveau_bitfield nv04_graph_nstatus[] = { - { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, - { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, - {} -}; - -struct nouveau_bitfield nv04_graph_nsource[] = { - { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, - { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, - { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, - { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, - { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, - { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, - { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, - { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, - { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, - { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, - { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, - { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, - { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, - { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, - { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, - { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, - { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, - { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, - { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, - {} -}; - -static void -nv04_graph_context_switch(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - int chid; - - nouveau_wait_for_idle(dev); - - /* If previous context is valid, we need to save it */ - nv04_graph_unload_context(dev); - - /* Load context for next channel */ - chid = dev_priv->engine.fifo.channel_id(dev); - chan = dev_priv->channels.ptr[chid]; - if (chan) - nv04_graph_load_context(chan); -} - -static void -nv04_graph_isr(struct drm_device *dev) -{ - u32 stat; - - while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { - u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); - u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); - u32 chid = (addr & 0x0f000000) >> 24; - u32 subc = (addr & 0x0000e000) >> 13; - u32 mthd = (addr & 0x00001ffc); - u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); - u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff; - u32 show = stat; - - if (stat & NV_PGRAPH_INTR_NOTIFY) { - if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { - if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) - show &= ~NV_PGRAPH_INTR_NOTIFY; - } - } - - if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { - nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); - stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - nv04_graph_context_switch(dev); - } - - nv_wr32(dev, NV03_PGRAPH_INTR, stat); - nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); - - if (show && nouveau_ratelimit()) { - NV_INFO(dev, "PGRAPH -"); - nouveau_bitfield_print(nv04_graph_intr, show); - printk(" nsource:"); - nouveau_bitfield_print(nv04_graph_nsource, nsource); - printk(" nstatus:"); - nouveau_bitfield_print(nv04_graph_nstatus, nstatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " - "mthd 0x%04x data 0x%08x\n", - chid, subc, class, mthd, data); - } - } -} - -static void -nv04_graph_destroy(struct drm_device *dev, int engine) -{ - struct nv04_graph_engine *pgraph = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 12); - - NVOBJ_ENGINE_DEL(dev, GR); - kfree(pgraph); -} - -int -nv04_graph_create(struct drm_device *dev) -{ - struct nv04_graph_engine *pgraph; - - pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); - if (!pgraph) - return -ENOMEM; - - pgraph->base.destroy = nv04_graph_destroy; - pgraph->base.init = nv04_graph_init; - pgraph->base.fini = nv04_graph_fini; - pgraph->base.context_new = nv04_graph_context_new; - pgraph->base.context_del = nv04_graph_context_del; - pgraph->base.object_new = nv04_graph_object_new; - - NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); - nouveau_irq_register(dev, 12, nv04_graph_isr); - - /* dvd subpicture */ - NVOBJ_CLASS(dev, 0x0038, GR); - - /* m2mf */ - NVOBJ_CLASS(dev, 0x0039, GR); - - /* nv03 gdirect */ - NVOBJ_CLASS(dev, 0x004b, GR); - NVOBJ_MTHD (dev, 0x004b, 0x0184, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x004b, 0x0188, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x004b, 0x018c, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x004b, 0x0190, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x004b, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 gdirect */ - NVOBJ_CLASS(dev, 0x004a, GR); - NVOBJ_MTHD (dev, 0x004a, 0x0188, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x004a, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x004a, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x004a, 0x0194, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x004a, 0x0198, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x004a, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv01 imageblit */ - NVOBJ_CLASS(dev, 0x001f, GR); - NVOBJ_MTHD (dev, 0x001f, 0x0184, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x001f, 0x0188, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x001f, 0x018c, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x001f, 0x0190, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x001f, 0x0194, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x001f, 0x0198, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x001f, 0x019c, nv04_graph_mthd_bind_surf_src); - NVOBJ_MTHD (dev, 0x001f, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 imageblit */ - NVOBJ_CLASS(dev, 0x005f, GR); - NVOBJ_MTHD (dev, 0x005f, 0x0184, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x005f, 0x0188, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x005f, 0x018c, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x005f, 0x0190, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x005f, 0x0194, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x005f, 0x0198, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x005f, 0x019c, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x005f, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 iifc */ - NVOBJ_CLASS(dev, 0x0060, GR); - NVOBJ_MTHD (dev, 0x0060, 0x0188, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x0060, 0x018c, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x0060, 0x0190, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x0060, 0x0194, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0060, 0x0198, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0060, 0x019c, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x0060, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf); - NVOBJ_MTHD (dev, 0x0060, 0x03e4, nv04_graph_mthd_set_operation); - - /* nv05 iifc */ - NVOBJ_CLASS(dev, 0x0064, GR); - - /* nv01 ifc */ - NVOBJ_CLASS(dev, 0x0021, GR); - NVOBJ_MTHD (dev, 0x0021, 0x0184, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x0021, 0x0188, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x0021, 0x018c, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x0021, 0x0190, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0021, 0x0194, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0021, 0x0198, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x0021, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 ifc */ - NVOBJ_CLASS(dev, 0x0061, GR); - NVOBJ_MTHD (dev, 0x0061, 0x0184, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x0061, 0x0188, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x0061, 0x018c, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x0061, 0x0190, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0061, 0x0194, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0061, 0x0198, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x0061, 0x019c, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x0061, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv05 ifc */ - NVOBJ_CLASS(dev, 0x0065, GR); - - /* nv03 sifc */ - NVOBJ_CLASS(dev, 0x0036, GR); - NVOBJ_MTHD (dev, 0x0036, 0x0184, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x0036, 0x0188, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x0036, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0036, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0036, 0x0194, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x0036, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 sifc */ - NVOBJ_CLASS(dev, 0x0076, GR); - NVOBJ_MTHD (dev, 0x0076, 0x0184, nv04_graph_mthd_bind_chroma); - NVOBJ_MTHD (dev, 0x0076, 0x0188, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x0076, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0076, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0076, 0x0194, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x0076, 0x0198, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x0076, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv05 sifc */ - NVOBJ_CLASS(dev, 0x0066, GR); - - /* nv03 sifm */ - NVOBJ_CLASS(dev, 0x0037, GR); - NVOBJ_MTHD (dev, 0x0037, 0x0188, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x0037, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0037, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0037, 0x0194, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x0037, 0x0304, nv04_graph_mthd_set_operation); - - /* nv04 sifm */ - NVOBJ_CLASS(dev, 0x0077, GR); - NVOBJ_MTHD (dev, 0x0077, 0x0188, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x0077, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x0077, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x0077, 0x0194, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x0077, 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf); - NVOBJ_MTHD (dev, 0x0077, 0x0304, nv04_graph_mthd_set_operation); - - /* null */ - NVOBJ_CLASS(dev, 0x0030, GR); - - /* surf2d */ - NVOBJ_CLASS(dev, 0x0042, GR); - - /* rop */ - NVOBJ_CLASS(dev, 0x0043, GR); - - /* beta1 */ - NVOBJ_CLASS(dev, 0x0012, GR); - - /* beta4 */ - NVOBJ_CLASS(dev, 0x0072, GR); - - /* cliprect */ - NVOBJ_CLASS(dev, 0x0019, GR); - - /* nv01 pattern */ - NVOBJ_CLASS(dev, 0x0018, GR); - - /* nv04 pattern */ - NVOBJ_CLASS(dev, 0x0044, GR); - - /* swzsurf */ - NVOBJ_CLASS(dev, 0x0052, GR); - - /* surf3d */ - NVOBJ_CLASS(dev, 0x0053, GR); - NVOBJ_MTHD (dev, 0x0053, 0x02f8, nv04_graph_mthd_surf3d_clip_h); - NVOBJ_MTHD (dev, 0x0053, 0x02fc, nv04_graph_mthd_surf3d_clip_v); - - /* nv03 tex_tri */ - NVOBJ_CLASS(dev, 0x0048, GR); - NVOBJ_MTHD (dev, 0x0048, 0x0188, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x0048, 0x018c, nv04_graph_mthd_bind_surf_color); - NVOBJ_MTHD (dev, 0x0048, 0x0190, nv04_graph_mthd_bind_surf_zeta); - - /* tex_tri */ - NVOBJ_CLASS(dev, 0x0054, GR); - - /* multitex_tri */ - NVOBJ_CLASS(dev, 0x0055, GR); - - /* nv01 chroma */ - NVOBJ_CLASS(dev, 0x0017, GR); - - /* nv04 chroma */ - NVOBJ_CLASS(dev, 0x0057, GR); - - /* surf_dst */ - NVOBJ_CLASS(dev, 0x0058, GR); - - /* surf_src */ - NVOBJ_CLASS(dev, 0x0059, GR); - - /* surf_color */ - NVOBJ_CLASS(dev, 0x005a, GR); - - /* surf_zeta */ - NVOBJ_CLASS(dev, 0x005b, GR); - - /* nv01 line */ - NVOBJ_CLASS(dev, 0x001c, GR); - NVOBJ_MTHD (dev, 0x001c, 0x0184, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x001c, 0x0188, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x001c, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x001c, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x001c, 0x0194, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x001c, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 line */ - NVOBJ_CLASS(dev, 0x005c, GR); - NVOBJ_MTHD (dev, 0x005c, 0x0184, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x005c, 0x0188, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x005c, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x005c, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x005c, 0x0194, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x005c, 0x0198, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x005c, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv01 tri */ - NVOBJ_CLASS(dev, 0x001d, GR); - NVOBJ_MTHD (dev, 0x001d, 0x0184, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x001d, 0x0188, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x001d, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x001d, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x001d, 0x0194, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x001d, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 tri */ - NVOBJ_CLASS(dev, 0x005d, GR); - NVOBJ_MTHD (dev, 0x005d, 0x0184, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x005d, 0x0188, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x005d, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x005d, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x005d, 0x0194, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x005d, 0x0198, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x005d, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv01 rect */ - NVOBJ_CLASS(dev, 0x001e, GR); - NVOBJ_MTHD (dev, 0x001e, 0x0184, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x001e, 0x0188, nv04_graph_mthd_bind_nv01_patt); - NVOBJ_MTHD (dev, 0x001e, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x001e, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x001e, 0x0194, nv04_graph_mthd_bind_surf_dst); - NVOBJ_MTHD (dev, 0x001e, 0x02fc, nv04_graph_mthd_set_operation); - - /* nv04 rect */ - NVOBJ_CLASS(dev, 0x005e, GR); - NVOBJ_MTHD (dev, 0x005e, 0x0184, nv04_graph_mthd_bind_clip); - NVOBJ_MTHD (dev, 0x005e, 0x0188, nv04_graph_mthd_bind_nv04_patt); - NVOBJ_MTHD (dev, 0x005e, 0x018c, nv04_graph_mthd_bind_rop); - NVOBJ_MTHD (dev, 0x005e, 0x0190, nv04_graph_mthd_bind_beta1); - NVOBJ_MTHD (dev, 0x005e, 0x0194, nv04_graph_mthd_bind_beta4); - NVOBJ_MTHD (dev, 0x005e, 0x0198, nv04_graph_mthd_bind_surf2d); - NVOBJ_MTHD (dev, 0x005e, 0x02fc, nv04_graph_mthd_set_operation); - - /* nvsw */ - NVOBJ_CLASS(dev, 0x506e, SW); - NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref); - NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_instmem.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_instmem.c deleted file mode 100644 index c1248e07..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_instmem.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" - -/* returns the size of fifo context */ -static int -nouveau_fifo_ctx_size(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset >= 0x40) - return 128; - else - if (dev_priv->chipset >= 0x17) - return 64; - - return 32; -} - -int nv04_instmem_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramht = NULL; - u32 offset, length; - int ret; - - /* RAMIN always available */ - dev_priv->ramin_available = true; - - /* Reserve space at end of VRAM for PRAMIN */ - if (dev_priv->card_type >= NV_40) { - u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8); - u32 rsvd; - - /* estimate grctx size, the magics come from nv40_grctx.c */ - if (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs; - else if (dev_priv->chipset < 0x43) rsvd = 0x4f00 * vs; - else if (nv44_graph_class(dev)) rsvd = 0x4980 * vs; - else rsvd = 0x4a40 * vs; - rsvd += 16 * 1024; - rsvd *= dev_priv->engine.fifo.channels; - - /* pciegart table */ - if (pci_is_pcie(dev->pdev)) - rsvd += 512 * 1024; - - /* object storage */ - rsvd += 512 * 1024; - - dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096); - } else { - dev_priv->ramin_rsvd_vram = 512 * 1024; - } - - /* Setup shared RAMHT */ - ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096, - NVOBJ_FLAG_ZERO_ALLOC, &ramht); - if (ret) - return ret; - - ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht); - nouveau_gpuobj_ref(NULL, &ramht); - if (ret) - return ret; - - /* And RAMRO */ - ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512, - NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro); - if (ret) - return ret; - - /* And RAMFC */ - length = dev_priv->engine.fifo.channels * nouveau_fifo_ctx_size(dev); - switch (dev_priv->card_type) { - case NV_40: - offset = 0x20000; - break; - default: - offset = 0x11400; - break; - } - - ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length, - NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc); - if (ret) - return ret; - - /* Only allow space after RAMFC to be used for object allocation */ - offset += length; - - /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230 - * on certain NV4x chipsets as well as RAMFC. When 0x2230 == 0 - * ("new style" control) the upper 16-bits of 0x2220 points at this - * other mysterious table that's clobbering important things. - * - * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting - * smashed to pieces on us, so reserve 0x30000-0x40000 too.. - */ - if (dev_priv->card_type >= NV_40) { - if (offset < 0x40000) - offset = 0x40000; - } - - ret = drm_mm_init(&dev_priv->ramin_heap, offset, - dev_priv->ramin_rsvd_vram - offset); - if (ret) { - NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret); - return ret; - } - - return 0; -} - -void -nv04_instmem_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL); - nouveau_gpuobj_ref(NULL, &dev_priv->ramro); - nouveau_gpuobj_ref(NULL, &dev_priv->ramfc); - - if (drm_mm_initialized(&dev_priv->ramin_heap)) - drm_mm_takedown(&dev_priv->ramin_heap); -} - -int -nv04_instmem_suspend(struct drm_device *dev) -{ - return 0; -} - -void -nv04_instmem_resume(struct drm_device *dev) -{ -} - -int -nv04_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan, - u32 size, u32 align) -{ - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct drm_mm_node *ramin = NULL; - - do { - if (drm_mm_pre_get(&dev_priv->ramin_heap)) - return -ENOMEM; - - spin_lock(&dev_priv->ramin_lock); - ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0); - if (ramin == NULL) { - spin_unlock(&dev_priv->ramin_lock); - return -ENOMEM; - } - - ramin = drm_mm_get_block_atomic(ramin, size, align); - spin_unlock(&dev_priv->ramin_lock); - } while (ramin == NULL); - - gpuobj->node = ramin; - gpuobj->vinst = ramin->start; - return 0; -} - -void -nv04_instmem_put(struct nouveau_gpuobj *gpuobj) -{ - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - - spin_lock(&dev_priv->ramin_lock); - drm_mm_put_block(gpuobj->node); - gpuobj->node = NULL; - spin_unlock(&dev_priv->ramin_lock); -} - -int -nv04_instmem_map(struct nouveau_gpuobj *gpuobj) -{ - gpuobj->pinst = gpuobj->vinst; - return 0; -} - -void -nv04_instmem_unmap(struct nouveau_gpuobj *gpuobj) -{ -} - -void -nv04_instmem_flush(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_mc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_mc.c deleted file mode 100644 index 2af43a1c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_mc.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -int -nv04_mc_init(struct drm_device *dev) -{ - /* Power up everything, resetting each individual unit will - * be done later if needed. - */ - - nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); - - /* Disable PROM access. */ - nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED); - - return 0; -} - -void -nv04_mc_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_pm.c deleted file mode 100644 index 6e758991..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_pm.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_pm.h" - -int -nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - int ret; - - ret = nouveau_hw_get_clock(dev, PLL_CORE); - if (ret < 0) - return ret; - perflvl->core = ret; - - ret = nouveau_hw_get_clock(dev, PLL_MEMORY); - if (ret < 0) - return ret; - perflvl->memory = ret; - - return 0; -} - -struct nv04_pm_clock { - struct pll_lims pll; - struct nouveau_pll_vals calc; -}; - -struct nv04_pm_state { - struct nv04_pm_clock core; - struct nv04_pm_clock memory; -}; - -static int -calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk) -{ - int ret; - - ret = get_pll_limits(dev, id, &clk->pll); - if (ret) - return ret; - - ret = nouveau_calc_pll_mnp(dev, &clk->pll, khz, &clk->calc); - if (!ret) - return -EINVAL; - - return 0; -} - -void * -nv04_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct nv04_pm_state *info; - int ret; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return ERR_PTR(-ENOMEM); - - ret = calc_pll(dev, PLL_CORE, perflvl->core, &info->core); - if (ret) - goto error; - - if (perflvl->memory) { - ret = calc_pll(dev, PLL_MEMORY, perflvl->memory, &info->memory); - if (ret) - goto error; - } - - return info; -error: - kfree(info); - return ERR_PTR(ret); -} - -static void -prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 reg = clk->pll.reg; - - /* thank the insane nouveau_hw_setpll() interface for this */ - if (dev_priv->card_type >= NV_40) - reg += 4; - - nouveau_hw_setpll(dev, reg, &clk->calc); -} - -int -nv04_pm_clocks_set(struct drm_device *dev, void *pre_state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - struct nv04_pm_state *state = pre_state; - - prog_pll(dev, &state->core); - - if (state->memory.pll.reg) { - prog_pll(dev, &state->memory); - if (dev_priv->card_type < NV_30) { - if (dev_priv->card_type == NV_20) - nv_mask(dev, 0x1002c4, 0, 1 << 20); - - /* Reset the DLLs */ - nv_mask(dev, 0x1002c0, 0, 1 << 8); - } - } - - ptimer->init(dev); - - kfree(state); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_timer.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_timer.c deleted file mode 100644 index 55c94529..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_timer.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_hw.h" - -int -nv04_timer_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 m, n, d; - - nv_wr32(dev, NV04_PTIMER_INTR_EN_0, 0x00000000); - nv_wr32(dev, NV04_PTIMER_INTR_0, 0xFFFFFFFF); - - /* aim for 31.25MHz, which gives us nanosecond timestamps */ - d = 1000000 / 32; - - /* determine base clock for timer source */ - if (dev_priv->chipset < 0x40) { - n = nouveau_hw_get_clock(dev, PLL_CORE); - } else - if (dev_priv->chipset == 0x40) { - /*XXX: figure this out */ - n = 0; - } else { - n = dev_priv->crystal; - m = 1; - while (n < (d * 2)) { - n += (n / m); - m++; - } - - nv_wr32(dev, 0x009220, m - 1); - } - - if (!n) { - NV_WARN(dev, "PTIMER: unknown input clock freq\n"); - if (!nv_rd32(dev, NV04_PTIMER_NUMERATOR) || - !nv_rd32(dev, NV04_PTIMER_DENOMINATOR)) { - nv_wr32(dev, NV04_PTIMER_NUMERATOR, 1); - nv_wr32(dev, NV04_PTIMER_DENOMINATOR, 1); - } - return 0; - } - - /* reduce ratio to acceptable values */ - while (((n % 5) == 0) && ((d % 5) == 0)) { - n /= 5; - d /= 5; - } - - while (((n % 2) == 0) && ((d % 2) == 0)) { - n /= 2; - d /= 2; - } - - while (n > 0xffff || d > 0xffff) { - n >>= 1; - d >>= 1; - } - - nv_wr32(dev, NV04_PTIMER_NUMERATOR, n); - nv_wr32(dev, NV04_PTIMER_DENOMINATOR, d); - return 0; -} - -u64 -nv04_timer_read(struct drm_device *dev) -{ - u32 hi, lo; - - do { - hi = nv_rd32(dev, NV04_PTIMER_TIME_1); - lo = nv_rd32(dev, NV04_PTIMER_TIME_0); - } while (hi != nv_rd32(dev, NV04_PTIMER_TIME_1)); - - return ((u64)hi << 32 | lo); -} - -void -nv04_timer_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_tv.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_tv.c deleted file mode 100644 index 3eb605dd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv04_tv.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nouveau_hw.h" -#include "drm_crtc_helper.h" - -#include "i2c/ch7006.h" - -static struct i2c_board_info nv04_tv_encoder_info[] = { - { - I2C_BOARD_INFO("ch7006", 0x75), - .platform_data = &(struct ch7006_encoder_params) { - CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, - 0, 0, 0, - CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, - CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC - } - }, - { } -}; - -int nv04_tv_identify(struct drm_device *dev, int i2c_index) -{ - return nouveau_i2c_identify(dev, "TV encoder", nv04_tv_encoder_info, - NULL, i2c_index); -} - - -#define PLLSEL_TV_CRTC1_MASK \ - (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 \ - | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1) -#define PLLSEL_TV_CRTC2_MASK \ - (NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2 \ - | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2) - -static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_mode_state *state = &dev_priv->mode_reg; - uint8_t crtc1A; - - NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", - mode, nv_encoder->dcb->index); - - state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); - - if (mode == DRM_MODE_DPMS_ON) { - int head = nouveau_crtc(encoder->crtc)->index; - crtc1A = NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX); - - state->pllsel |= head ? PLLSEL_TV_CRTC2_MASK : - PLLSEL_TV_CRTC1_MASK; - - /* Inhibit hsync */ - crtc1A |= 0x80; - - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX, crtc1A); - } - - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_PLL_COEFF_SELECT, state->pllsel); - - get_slave_funcs(encoder)->dpms(encoder, mode); -} - -static void nv04_tv_bind(struct drm_device *dev, int head, bool bind) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv04_crtc_reg *state = &dev_priv->mode_reg.crtc_reg[head]; - - state->tv_setup = 0; - - if (bind) - state->CRTC[NV_CIO_CRE_49] |= 0x10; - else - state->CRTC[NV_CIO_CRE_49] &= ~0x10; - - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_LCD__INDEX, - state->CRTC[NV_CIO_CRE_LCD__INDEX]); - NVWriteVgaCrtc(dev, head, NV_CIO_CRE_49, - state->CRTC[NV_CIO_CRE_49]); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_TV_SETUP, - state->tv_setup); -} - -static void nv04_tv_prepare(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - int head = nouveau_crtc(encoder->crtc)->index; - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - - helper->dpms(encoder, DRM_MODE_DPMS_OFF); - - nv04_dfp_disable(dev, head); - - if (nv_two_heads(dev)) - nv04_tv_bind(dev, head ^ 1, false); - - nv04_tv_bind(dev, head, true); -} - -static void nv04_tv_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; - - regp->tv_htotal = adjusted_mode->htotal; - regp->tv_vtotal = adjusted_mode->vtotal; - - /* These delay the TV signals with respect to the VGA port, - * they might be useful if we ever allow a CRTC to drive - * multiple outputs. - */ - regp->tv_hskew = 1; - regp->tv_hsync_delay = 1; - regp->tv_hsync_delay2 = 64; - regp->tv_vskew = 1; - regp->tv_vsync_delay = 1; - - get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode); -} - -static void nv04_tv_commit(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - - helper->dpms(encoder, DRM_MODE_DPMS_ON); - - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, - '@' + ffs(nv_encoder->dcb->or)); -} - -static void nv04_tv_destroy(struct drm_encoder *encoder) -{ - get_slave_funcs(encoder)->destroy(encoder); - drm_encoder_cleanup(encoder); - - kfree(encoder->helper_private); - kfree(nouveau_encoder(encoder)); -} - -static const struct drm_encoder_funcs nv04_tv_funcs = { - .destroy = nv04_tv_destroy, -}; - -int -nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry) -{ - struct nouveau_encoder *nv_encoder; - struct drm_encoder *encoder; - struct drm_device *dev = connector->dev; - struct drm_encoder_helper_funcs *hfuncs; - struct drm_encoder_slave_funcs *sfuncs; - struct nouveau_i2c_chan *i2c = - nouveau_i2c_find(dev, entry->i2c_index); - int type, ret; - - /* Ensure that we can talk to this encoder */ - type = nv04_tv_identify(dev, entry->i2c_index); - if (type < 0) - return type; - - /* Allocate the necessary memory */ - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - - hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL); - if (!hfuncs) { - ret = -ENOMEM; - goto fail_free; - } - - /* Initialize the common members */ - encoder = to_drm_encoder(nv_encoder); - - drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC); - drm_encoder_helper_add(encoder, hfuncs); - - encoder->possible_crtcs = entry->heads; - encoder->possible_clones = 0; - nv_encoder->dcb = entry; - nv_encoder->or = ffs(entry->or) - 1; - - /* Run the slave-specific initialization */ - ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), - &i2c->adapter, &nv04_tv_encoder_info[type]); - if (ret < 0) - goto fail_cleanup; - - /* Fill the function pointers */ - sfuncs = get_slave_funcs(encoder); - - *hfuncs = (struct drm_encoder_helper_funcs) { - .dpms = nv04_tv_dpms, - .save = sfuncs->save, - .restore = sfuncs->restore, - .mode_fixup = sfuncs->mode_fixup, - .prepare = nv04_tv_prepare, - .commit = nv04_tv_commit, - .mode_set = nv04_tv_mode_set, - .detect = sfuncs->detect, - }; - - /* Attach it to the specified connector. */ - sfuncs->create_resources(encoder, connector); - drm_mode_connector_attach_encoder(connector, encoder); - - return 0; - -fail_cleanup: - drm_encoder_cleanup(encoder); - kfree(hfuncs); -fail_free: - kfree(nv_encoder); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fb.c deleted file mode 100644 index 420b1608..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fb.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -void -nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch, uint32_t flags) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - tile->addr = 0x80000000 | addr; - tile->limit = max(1u, addr + size) - 1; - tile->pitch = pitch; -} - -void -nv10_fb_free_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - tile->addr = tile->limit = tile->pitch = tile->zcomp = 0; -} - -void -nv10_fb_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); - nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); - nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); -} - -int -nv1a_fb_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct pci_dev *bridge; - uint32_t mem, mib; - - bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1)); - if (!bridge) { - NV_ERROR(dev, "no bridge device\n"); - return 0; - } - - if (dev_priv->chipset == 0x1a) { - pci_read_config_dword(bridge, 0x7c, &mem); - mib = ((mem >> 6) & 31) + 1; - } else { - pci_read_config_dword(bridge, 0x84, &mem); - mib = ((mem >> 4) & 127) + 1; - } - - dev_priv->vram_size = mib * 1024 * 1024; - return 0; -} - -int -nv10_fb_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 fifo_data = nv_rd32(dev, NV04_PFB_FIFO_DATA); - u32 cfg0 = nv_rd32(dev, 0x100200); - - dev_priv->vram_size = fifo_data & NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; - - if (cfg0 & 0x00000001) - dev_priv->vram_type = NV_MEM_TYPE_DDR1; - else - dev_priv->vram_type = NV_MEM_TYPE_SDRAM; - - return 0; -} - -int -nv10_fb_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int i; - - /* Turn all the tiling regions off. */ - pfb->num_tiles = NV10_PFB_TILE__SIZE; - for (i = 0; i < pfb->num_tiles; i++) - pfb->set_tile_region(dev, i); - - return 0; -} - -void -nv10_fb_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int i; - - for (i = 0; i < pfb->num_tiles; i++) - pfb->free_tile_region(dev, i); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fifo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fifo.c deleted file mode 100644 index d2ecbff4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_fifo.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" - -#define NV10_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV10_RAMFC__SIZE)) -#define NV10_RAMFC__SIZE ((dev_priv->chipset) >= 0x17 ? 64 : 32) - -int -nv10_fifo_channel_id(struct drm_device *dev) -{ - return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & - NV10_PFIFO_CACHE1_PUSH1_CHID_MASK; -} - -int -nv10_fifo_create_context(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct drm_device *dev = chan->dev; - uint32_t fc = NV10_RAMFC(chan->id); - int ret; - - ret = nouveau_gpuobj_new_fake(dev, NV10_RAMFC(chan->id), ~0, - NV10_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); - if (ret) - return ret; - - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV03_USER(chan->id), PAGE_SIZE); - if (!chan->user) - return -ENOMEM; - - /* Fill entries that are seen filled in dumps of nvidia driver just - * after channel's is put into DMA mode - */ - nv_wi32(dev, fc + 0, chan->pushbuf_base); - nv_wi32(dev, fc + 4, chan->pushbuf_base); - nv_wi32(dev, fc + 12, chan->pushbuf->pinst >> 4); - nv_wi32(dev, fc + 20, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0); - - /* enable the fifo dma operation */ - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); - return 0; -} - -static void -nv10_fifo_do_load_context(struct drm_device *dev, int chid) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t fc = NV10_RAMFC(chid), tmp; - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); - nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); - - tmp = nv_ri32(dev, fc + 12); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, tmp & 0xFFFF); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, tmp >> 16); - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 16)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, nv_ri32(dev, fc + 20)); - nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 24)); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 28)); - - if (dev_priv->chipset < 0x17) - goto out; - - nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 32)); - tmp = nv_ri32(dev, fc + 36); - nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp); - nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 40)); - nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 44)); - nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48)); - -out: - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); -} - -int -nv10_fifo_load_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - uint32_t tmp; - - nv10_fifo_do_load_context(dev, chan->id); - - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, - NV03_PFIFO_CACHE1_PUSH1_DMA | chan->id); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); - - /* Reset NV04_PFIFO_CACHE1_DMA_CTL_AT_INFO to INVALID */ - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); - - return 0; -} - -int -nv10_fifo_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - uint32_t fc, tmp; - int chid; - - chid = pfifo->channel_id(dev); - if (chid < 0 || chid >= dev_priv->engine.fifo.channels) - return 0; - fc = NV10_RAMFC(chid); - - nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); - nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); - nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE) & 0xFFFF; - tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16); - nv_wi32(dev, fc + 12, tmp); - nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); - nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH)); - nv_wi32(dev, fc + 24, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); - nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); - - if (dev_priv->chipset < 0x17) - goto out; - - nv_wi32(dev, fc + 32, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); - nv_wi32(dev, fc + 36, tmp); - nv_wi32(dev, fc + 40, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE)); - nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); - -out: - nv10_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); - return 0; -} - -static void -nv10_fifo_init_reset(struct drm_device *dev) -{ - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); - - nv_wr32(dev, 0x003224, 0x000f0078); - nv_wr32(dev, 0x002044, 0x0101ffff); - nv_wr32(dev, 0x002040, 0x000000ff); - nv_wr32(dev, 0x002500, 0x00000000); - nv_wr32(dev, 0x003000, 0x00000000); - nv_wr32(dev, 0x003050, 0x00000000); - - nv_wr32(dev, 0x003258, 0x00000000); - nv_wr32(dev, 0x003210, 0x00000000); - nv_wr32(dev, 0x003270, 0x00000000); -} - -static void -nv10_fifo_init_ramxx(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | - ((dev_priv->ramht->bits - 9) << 16) | - (dev_priv->ramht->gpuobj->pinst >> 8)); - nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8); - - if (dev_priv->chipset < 0x17) { - nv_wr32(dev, NV03_PFIFO_RAMFC, dev_priv->ramfc->pinst >> 8); - } else { - nv_wr32(dev, NV03_PFIFO_RAMFC, (dev_priv->ramfc->pinst >> 8) | - (1 << 16) /* 64 Bytes entry*/); - /* XXX nvidia blob set bit 18, 21,23 for nv20 & nv30 */ - } -} - -static void -nv10_fifo_init_intr(struct drm_device *dev) -{ - nouveau_irq_register(dev, 8, nv04_fifo_isr); - nv_wr32(dev, 0x002100, 0xffffffff); - nv_wr32(dev, 0x002140, 0xffffffff); -} - -int -nv10_fifo_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - int i; - - nv10_fifo_init_reset(dev); - nv10_fifo_init_ramxx(dev); - - nv10_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); - - nv10_fifo_init_intr(dev); - pfifo->enable(dev); - pfifo->reassign(dev, true); - - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (dev_priv->channels.ptr[i]) { - uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); - nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); - } - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_gpio.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_gpio.c deleted file mode 100644 index 9d791800..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_gpio.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_gpio.h" - -int -nv10_gpio_sense(struct drm_device *dev, int line) -{ - if (line < 2) { - line = line * 16; - line = NVReadCRTC(dev, 0, NV_PCRTC_GPIO) >> line; - return !!(line & 0x0100); - } else - if (line < 10) { - line = (line - 2) * 4; - line = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT) >> line; - return !!(line & 0x04); - } else - if (line < 14) { - line = (line - 10) * 4; - line = NVReadCRTC(dev, 0, NV_PCRTC_850) >> line; - return !!(line & 0x04); - } - - return -EINVAL; -} - -int -nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out) -{ - u32 reg, mask, data; - - if (line < 2) { - line = line * 16; - reg = NV_PCRTC_GPIO; - mask = 0x00000011; - data = (dir << 4) | out; - } else - if (line < 10) { - line = (line - 2) * 4; - reg = NV_PCRTC_GPIO_EXT; - mask = 0x00000003; - data = (dir << 1) | out; - } else - if (line < 14) { - line = (line - 10) * 4; - reg = NV_PCRTC_850; - mask = 0x00000003; - data = (dir << 1) | out; - } else { - return -EINVAL; - } - - mask = NVReadCRTC(dev, 0, reg) & ~(mask << line); - NVWriteCRTC(dev, 0, reg, mask | (data << line)); - return 0; -} - -void -nv10_gpio_irq_enable(struct drm_device *dev, int line, bool on) -{ - u32 mask = 0x00010001 << line; - - nv_wr32(dev, 0x001104, mask); - nv_mask(dev, 0x001144, mask, on ? mask : 0); -} - -static void -nv10_gpio_isr(struct drm_device *dev) -{ - u32 intr = nv_rd32(dev, 0x1104); - u32 hi = (intr & 0x0000ffff) >> 0; - u32 lo = (intr & 0xffff0000) >> 16; - - nouveau_gpio_isr(dev, 0, hi | lo); - - nv_wr32(dev, 0x001104, intr); -} - -int -nv10_gpio_init(struct drm_device *dev) -{ - nv_wr32(dev, 0x001140, 0x00000000); - nv_wr32(dev, 0x001100, 0xffffffff); - nv_wr32(dev, 0x001144, 0x00000000); - nv_wr32(dev, 0x001104, 0xffffffff); - nouveau_irq_register(dev, 28, nv10_gpio_isr); /* PBUS */ - return 0; -} - -void -nv10_gpio_fini(struct drm_device *dev) -{ - nv_wr32(dev, 0x001140, 0x00000000); - nv_wr32(dev, 0x001144, 0x00000000); - nouveau_irq_unregister(dev, 28); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_graph.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_graph.c deleted file mode 100644 index 7255e4a4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv10_graph.c +++ /dev/null @@ -1,1194 +0,0 @@ -/* - * Copyright 2007 Matthieu CASTET - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drm.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" - -struct nv10_graph_engine { - struct nouveau_exec_engine base; -}; - -struct pipe_state { - uint32_t pipe_0x0000[0x040/4]; - uint32_t pipe_0x0040[0x010/4]; - uint32_t pipe_0x0200[0x0c0/4]; - uint32_t pipe_0x4400[0x080/4]; - uint32_t pipe_0x6400[0x3b0/4]; - uint32_t pipe_0x6800[0x2f0/4]; - uint32_t pipe_0x6c00[0x030/4]; - uint32_t pipe_0x7000[0x130/4]; - uint32_t pipe_0x7400[0x0c0/4]; - uint32_t pipe_0x7800[0x0c0/4]; -}; - -static int nv10_graph_ctx_regs[] = { - NV10_PGRAPH_CTX_SWITCH(0), - NV10_PGRAPH_CTX_SWITCH(1), - NV10_PGRAPH_CTX_SWITCH(2), - NV10_PGRAPH_CTX_SWITCH(3), - NV10_PGRAPH_CTX_SWITCH(4), - NV10_PGRAPH_CTX_CACHE(0, 0), - NV10_PGRAPH_CTX_CACHE(0, 1), - NV10_PGRAPH_CTX_CACHE(0, 2), - NV10_PGRAPH_CTX_CACHE(0, 3), - NV10_PGRAPH_CTX_CACHE(0, 4), - NV10_PGRAPH_CTX_CACHE(1, 0), - NV10_PGRAPH_CTX_CACHE(1, 1), - NV10_PGRAPH_CTX_CACHE(1, 2), - NV10_PGRAPH_CTX_CACHE(1, 3), - NV10_PGRAPH_CTX_CACHE(1, 4), - NV10_PGRAPH_CTX_CACHE(2, 0), - NV10_PGRAPH_CTX_CACHE(2, 1), - NV10_PGRAPH_CTX_CACHE(2, 2), - NV10_PGRAPH_CTX_CACHE(2, 3), - NV10_PGRAPH_CTX_CACHE(2, 4), - NV10_PGRAPH_CTX_CACHE(3, 0), - NV10_PGRAPH_CTX_CACHE(3, 1), - NV10_PGRAPH_CTX_CACHE(3, 2), - NV10_PGRAPH_CTX_CACHE(3, 3), - NV10_PGRAPH_CTX_CACHE(3, 4), - NV10_PGRAPH_CTX_CACHE(4, 0), - NV10_PGRAPH_CTX_CACHE(4, 1), - NV10_PGRAPH_CTX_CACHE(4, 2), - NV10_PGRAPH_CTX_CACHE(4, 3), - NV10_PGRAPH_CTX_CACHE(4, 4), - NV10_PGRAPH_CTX_CACHE(5, 0), - NV10_PGRAPH_CTX_CACHE(5, 1), - NV10_PGRAPH_CTX_CACHE(5, 2), - NV10_PGRAPH_CTX_CACHE(5, 3), - NV10_PGRAPH_CTX_CACHE(5, 4), - NV10_PGRAPH_CTX_CACHE(6, 0), - NV10_PGRAPH_CTX_CACHE(6, 1), - NV10_PGRAPH_CTX_CACHE(6, 2), - NV10_PGRAPH_CTX_CACHE(6, 3), - NV10_PGRAPH_CTX_CACHE(6, 4), - NV10_PGRAPH_CTX_CACHE(7, 0), - NV10_PGRAPH_CTX_CACHE(7, 1), - NV10_PGRAPH_CTX_CACHE(7, 2), - NV10_PGRAPH_CTX_CACHE(7, 3), - NV10_PGRAPH_CTX_CACHE(7, 4), - NV10_PGRAPH_CTX_USER, - NV04_PGRAPH_DMA_START_0, - NV04_PGRAPH_DMA_START_1, - NV04_PGRAPH_DMA_LENGTH, - NV04_PGRAPH_DMA_MISC, - NV10_PGRAPH_DMA_PITCH, - NV04_PGRAPH_BOFFSET0, - NV04_PGRAPH_BBASE0, - NV04_PGRAPH_BLIMIT0, - NV04_PGRAPH_BOFFSET1, - NV04_PGRAPH_BBASE1, - NV04_PGRAPH_BLIMIT1, - NV04_PGRAPH_BOFFSET2, - NV04_PGRAPH_BBASE2, - NV04_PGRAPH_BLIMIT2, - NV04_PGRAPH_BOFFSET3, - NV04_PGRAPH_BBASE3, - NV04_PGRAPH_BLIMIT3, - NV04_PGRAPH_BOFFSET4, - NV04_PGRAPH_BBASE4, - NV04_PGRAPH_BLIMIT4, - NV04_PGRAPH_BOFFSET5, - NV04_PGRAPH_BBASE5, - NV04_PGRAPH_BLIMIT5, - NV04_PGRAPH_BPITCH0, - NV04_PGRAPH_BPITCH1, - NV04_PGRAPH_BPITCH2, - NV04_PGRAPH_BPITCH3, - NV04_PGRAPH_BPITCH4, - NV10_PGRAPH_SURFACE, - NV10_PGRAPH_STATE, - NV04_PGRAPH_BSWIZZLE2, - NV04_PGRAPH_BSWIZZLE5, - NV04_PGRAPH_BPIXEL, - NV10_PGRAPH_NOTIFY, - NV04_PGRAPH_PATT_COLOR0, - NV04_PGRAPH_PATT_COLOR1, - NV04_PGRAPH_PATT_COLORRAM, /* 64 values from 0x400900 to 0x4009fc */ - 0x00400904, - 0x00400908, - 0x0040090c, - 0x00400910, - 0x00400914, - 0x00400918, - 0x0040091c, - 0x00400920, - 0x00400924, - 0x00400928, - 0x0040092c, - 0x00400930, - 0x00400934, - 0x00400938, - 0x0040093c, - 0x00400940, - 0x00400944, - 0x00400948, - 0x0040094c, - 0x00400950, - 0x00400954, - 0x00400958, - 0x0040095c, - 0x00400960, - 0x00400964, - 0x00400968, - 0x0040096c, - 0x00400970, - 0x00400974, - 0x00400978, - 0x0040097c, - 0x00400980, - 0x00400984, - 0x00400988, - 0x0040098c, - 0x00400990, - 0x00400994, - 0x00400998, - 0x0040099c, - 0x004009a0, - 0x004009a4, - 0x004009a8, - 0x004009ac, - 0x004009b0, - 0x004009b4, - 0x004009b8, - 0x004009bc, - 0x004009c0, - 0x004009c4, - 0x004009c8, - 0x004009cc, - 0x004009d0, - 0x004009d4, - 0x004009d8, - 0x004009dc, - 0x004009e0, - 0x004009e4, - 0x004009e8, - 0x004009ec, - 0x004009f0, - 0x004009f4, - 0x004009f8, - 0x004009fc, - NV04_PGRAPH_PATTERN, /* 2 values from 0x400808 to 0x40080c */ - 0x0040080c, - NV04_PGRAPH_PATTERN_SHAPE, - NV03_PGRAPH_MONO_COLOR0, - NV04_PGRAPH_ROP3, - NV04_PGRAPH_CHROMA, - NV04_PGRAPH_BETA_AND, - NV04_PGRAPH_BETA_PREMULT, - 0x00400e70, - 0x00400e74, - 0x00400e78, - 0x00400e7c, - 0x00400e80, - 0x00400e84, - 0x00400e88, - 0x00400e8c, - 0x00400ea0, - 0x00400ea4, - 0x00400ea8, - 0x00400e90, - 0x00400e94, - 0x00400e98, - 0x00400e9c, - NV10_PGRAPH_WINDOWCLIP_HORIZONTAL, /* 8 values from 0x400f00-0x400f1c */ - NV10_PGRAPH_WINDOWCLIP_VERTICAL, /* 8 values from 0x400f20-0x400f3c */ - 0x00400f04, - 0x00400f24, - 0x00400f08, - 0x00400f28, - 0x00400f0c, - 0x00400f2c, - 0x00400f10, - 0x00400f30, - 0x00400f14, - 0x00400f34, - 0x00400f18, - 0x00400f38, - 0x00400f1c, - 0x00400f3c, - NV10_PGRAPH_XFMODE0, - NV10_PGRAPH_XFMODE1, - NV10_PGRAPH_GLOBALSTATE0, - NV10_PGRAPH_GLOBALSTATE1, - NV04_PGRAPH_STORED_FMT, - NV04_PGRAPH_SOURCE_COLOR, - NV03_PGRAPH_ABS_X_RAM, /* 32 values from 0x400400 to 0x40047c */ - NV03_PGRAPH_ABS_Y_RAM, /* 32 values from 0x400480 to 0x4004fc */ - 0x00400404, - 0x00400484, - 0x00400408, - 0x00400488, - 0x0040040c, - 0x0040048c, - 0x00400410, - 0x00400490, - 0x00400414, - 0x00400494, - 0x00400418, - 0x00400498, - 0x0040041c, - 0x0040049c, - 0x00400420, - 0x004004a0, - 0x00400424, - 0x004004a4, - 0x00400428, - 0x004004a8, - 0x0040042c, - 0x004004ac, - 0x00400430, - 0x004004b0, - 0x00400434, - 0x004004b4, - 0x00400438, - 0x004004b8, - 0x0040043c, - 0x004004bc, - 0x00400440, - 0x004004c0, - 0x00400444, - 0x004004c4, - 0x00400448, - 0x004004c8, - 0x0040044c, - 0x004004cc, - 0x00400450, - 0x004004d0, - 0x00400454, - 0x004004d4, - 0x00400458, - 0x004004d8, - 0x0040045c, - 0x004004dc, - 0x00400460, - 0x004004e0, - 0x00400464, - 0x004004e4, - 0x00400468, - 0x004004e8, - 0x0040046c, - 0x004004ec, - 0x00400470, - 0x004004f0, - 0x00400474, - 0x004004f4, - 0x00400478, - 0x004004f8, - 0x0040047c, - 0x004004fc, - NV03_PGRAPH_ABS_UCLIP_XMIN, - NV03_PGRAPH_ABS_UCLIP_XMAX, - NV03_PGRAPH_ABS_UCLIP_YMIN, - NV03_PGRAPH_ABS_UCLIP_YMAX, - 0x00400550, - 0x00400558, - 0x00400554, - 0x0040055c, - NV03_PGRAPH_ABS_UCLIPA_XMIN, - NV03_PGRAPH_ABS_UCLIPA_XMAX, - NV03_PGRAPH_ABS_UCLIPA_YMIN, - NV03_PGRAPH_ABS_UCLIPA_YMAX, - NV03_PGRAPH_ABS_ICLIP_XMAX, - NV03_PGRAPH_ABS_ICLIP_YMAX, - NV03_PGRAPH_XY_LOGIC_MISC0, - NV03_PGRAPH_XY_LOGIC_MISC1, - NV03_PGRAPH_XY_LOGIC_MISC2, - NV03_PGRAPH_XY_LOGIC_MISC3, - NV03_PGRAPH_CLIPX_0, - NV03_PGRAPH_CLIPX_1, - NV03_PGRAPH_CLIPY_0, - NV03_PGRAPH_CLIPY_1, - NV10_PGRAPH_COMBINER0_IN_ALPHA, - NV10_PGRAPH_COMBINER1_IN_ALPHA, - NV10_PGRAPH_COMBINER0_IN_RGB, - NV10_PGRAPH_COMBINER1_IN_RGB, - NV10_PGRAPH_COMBINER_COLOR0, - NV10_PGRAPH_COMBINER_COLOR1, - NV10_PGRAPH_COMBINER0_OUT_ALPHA, - NV10_PGRAPH_COMBINER1_OUT_ALPHA, - NV10_PGRAPH_COMBINER0_OUT_RGB, - NV10_PGRAPH_COMBINER1_OUT_RGB, - NV10_PGRAPH_COMBINER_FINAL0, - NV10_PGRAPH_COMBINER_FINAL1, - 0x00400e00, - 0x00400e04, - 0x00400e08, - 0x00400e0c, - 0x00400e10, - 0x00400e14, - 0x00400e18, - 0x00400e1c, - 0x00400e20, - 0x00400e24, - 0x00400e28, - 0x00400e2c, - 0x00400e30, - 0x00400e34, - 0x00400e38, - 0x00400e3c, - NV04_PGRAPH_PASSTHRU_0, - NV04_PGRAPH_PASSTHRU_1, - NV04_PGRAPH_PASSTHRU_2, - NV10_PGRAPH_DIMX_TEXTURE, - NV10_PGRAPH_WDIMX_TEXTURE, - NV10_PGRAPH_DVD_COLORFMT, - NV10_PGRAPH_SCALED_FORMAT, - NV04_PGRAPH_MISC24_0, - NV04_PGRAPH_MISC24_1, - NV04_PGRAPH_MISC24_2, - NV03_PGRAPH_X_MISC, - NV03_PGRAPH_Y_MISC, - NV04_PGRAPH_VALID1, - NV04_PGRAPH_VALID2, -}; - -static int nv17_graph_ctx_regs[] = { - NV10_PGRAPH_DEBUG_4, - 0x004006b0, - 0x00400eac, - 0x00400eb0, - 0x00400eb4, - 0x00400eb8, - 0x00400ebc, - 0x00400ec0, - 0x00400ec4, - 0x00400ec8, - 0x00400ecc, - 0x00400ed0, - 0x00400ed4, - 0x00400ed8, - 0x00400edc, - 0x00400ee0, - 0x00400a00, - 0x00400a04, -}; - -struct graph_state { - int nv10[ARRAY_SIZE(nv10_graph_ctx_regs)]; - int nv17[ARRAY_SIZE(nv17_graph_ctx_regs)]; - struct pipe_state pipe_state; - uint32_t lma_window[4]; -}; - -#define PIPE_SAVE(dev, state, addr) \ - do { \ - int __i; \ - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ - for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ - state[__i] = nv_rd32(dev, NV10_PGRAPH_PIPE_DATA); \ - } while (0) - -#define PIPE_RESTORE(dev, state, addr) \ - do { \ - int __i; \ - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, addr); \ - for (__i = 0; __i < ARRAY_SIZE(state); __i++) \ - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, state[__i]); \ - } while (0) - -static void nv10_graph_save_pipe(struct nouveau_channel *chan) -{ - struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct pipe_state *pipe = &pgraph_ctx->pipe_state; - struct drm_device *dev = chan->dev; - - PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); - PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); - PIPE_SAVE(dev, pipe->pipe_0x6400, 0x6400); - PIPE_SAVE(dev, pipe->pipe_0x6800, 0x6800); - PIPE_SAVE(dev, pipe->pipe_0x6c00, 0x6c00); - PIPE_SAVE(dev, pipe->pipe_0x7000, 0x7000); - PIPE_SAVE(dev, pipe->pipe_0x7400, 0x7400); - PIPE_SAVE(dev, pipe->pipe_0x7800, 0x7800); - PIPE_SAVE(dev, pipe->pipe_0x0040, 0x0040); - PIPE_SAVE(dev, pipe->pipe_0x0000, 0x0000); -} - -static void nv10_graph_load_pipe(struct nouveau_channel *chan) -{ - struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct pipe_state *pipe = &pgraph_ctx->pipe_state; - struct drm_device *dev = chan->dev; - uint32_t xfmode0, xfmode1; - int i; - - nouveau_wait_for_idle(dev); - /* XXX check haiku comments */ - xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0); - xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1); - nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000); - nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000); - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); - for (i = 0; i < 4; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); - for (i = 0; i < 4; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); - for (i = 0; i < 3; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); - for (i = 0; i < 3; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); - - - PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200); - nouveau_wait_for_idle(dev); - - /* restore XFMODE */ - nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); - nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); - PIPE_RESTORE(dev, pipe->pipe_0x6400, 0x6400); - PIPE_RESTORE(dev, pipe->pipe_0x6800, 0x6800); - PIPE_RESTORE(dev, pipe->pipe_0x6c00, 0x6c00); - PIPE_RESTORE(dev, pipe->pipe_0x7000, 0x7000); - PIPE_RESTORE(dev, pipe->pipe_0x7400, 0x7400); - PIPE_RESTORE(dev, pipe->pipe_0x7800, 0x7800); - PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400); - PIPE_RESTORE(dev, pipe->pipe_0x0000, 0x0000); - PIPE_RESTORE(dev, pipe->pipe_0x0040, 0x0040); - nouveau_wait_for_idle(dev); -} - -static void nv10_graph_create_pipe(struct nouveau_channel *chan) -{ - struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; - struct drm_device *dev = chan->dev; - uint32_t *fifo_pipe_state_addr; - int i; -#define PIPE_INIT(addr) \ - do { \ - fifo_pipe_state_addr = fifo_pipe_state->pipe_##addr; \ - } while (0) -#define PIPE_INIT_END(addr) \ - do { \ - uint32_t *__end_addr = fifo_pipe_state->pipe_##addr + \ - ARRAY_SIZE(fifo_pipe_state->pipe_##addr); \ - if (fifo_pipe_state_addr != __end_addr) \ - NV_ERROR(dev, "incomplete pipe init for 0x%x : %p/%p\n", \ - addr, fifo_pipe_state_addr, __end_addr); \ - } while (0) -#define NV_WRITE_PIPE_INIT(value) *(fifo_pipe_state_addr++) = value - - PIPE_INIT(0x0200); - for (i = 0; i < 48; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x0200); - - PIPE_INIT(0x6400); - for (i = 0; i < 211; i++) - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x3f800000); - NV_WRITE_PIPE_INIT(0x40000000); - NV_WRITE_PIPE_INIT(0x40000000); - NV_WRITE_PIPE_INIT(0x40000000); - NV_WRITE_PIPE_INIT(0x40000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x3f800000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x3f000000); - NV_WRITE_PIPE_INIT(0x3f000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x3f800000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x3f800000); - NV_WRITE_PIPE_INIT(0x3f800000); - NV_WRITE_PIPE_INIT(0x3f800000); - NV_WRITE_PIPE_INIT(0x3f800000); - PIPE_INIT_END(0x6400); - - PIPE_INIT(0x6800); - for (i = 0; i < 162; i++) - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x3f800000); - for (i = 0; i < 25; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x6800); - - PIPE_INIT(0x6c00); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0xbf800000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x6c00); - - PIPE_INIT(0x7000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x00000000); - NV_WRITE_PIPE_INIT(0x7149f2ca); - for (i = 0; i < 35; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x7000); - - PIPE_INIT(0x7400); - for (i = 0; i < 48; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x7400); - - PIPE_INIT(0x7800); - for (i = 0; i < 48; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x7800); - - PIPE_INIT(0x4400); - for (i = 0; i < 32; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x4400); - - PIPE_INIT(0x0000); - for (i = 0; i < 16; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x0000); - - PIPE_INIT(0x0040); - for (i = 0; i < 4; i++) - NV_WRITE_PIPE_INIT(0x00000000); - PIPE_INIT_END(0x0040); - -#undef PIPE_INIT -#undef PIPE_INIT_END -#undef NV_WRITE_PIPE_INIT -} - -static int nv10_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) -{ - int i; - for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) { - if (nv10_graph_ctx_regs[i] == reg) - return i; - } - NV_ERROR(dev, "unknow offset nv10_ctx_regs %d\n", reg); - return -1; -} - -static int nv17_graph_ctx_regs_find_offset(struct drm_device *dev, int reg) -{ - int i; - for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) { - if (nv17_graph_ctx_regs[i] == reg) - return i; - } - NV_ERROR(dev, "unknow offset nv17_ctx_regs %d\n", reg); - return -1; -} - -static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan, - uint32_t inst) -{ - struct drm_device *dev = chan->dev; - uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; - uint32_t ctx_user, ctx_switch[5]; - int i, subchan = -1; - - /* NV10TCL_DMA_VTXBUF (method 0x18c) modifies hidden state - * that cannot be restored via MMIO. Do it through the FIFO - * instead. - */ - - /* Look for a celsius object */ - for (i = 0; i < 8; i++) { - int class = nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(i, 0)) & 0xfff; - - if (class == 0x56 || class == 0x96 || class == 0x99) { - subchan = i; - break; - } - } - - if (subchan < 0 || !inst) - return; - - /* Save the current ctx object */ - ctx_user = nv_rd32(dev, NV10_PGRAPH_CTX_USER); - for (i = 0; i < 5; i++) - ctx_switch[i] = nv_rd32(dev, NV10_PGRAPH_CTX_SWITCH(i)); - - /* Save the FIFO state */ - st2 = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2); - st2_dl = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DL); - st2_dh = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2_DH); - fifo_ptr = nv_rd32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR); - - for (i = 0; i < ARRAY_SIZE(fifo); i++) - fifo[i] = nv_rd32(dev, 0x4007a0 + 4 * i); - - /* Switch to the celsius subchannel */ - for (i = 0; i < 5; i++) - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), - nv_rd32(dev, NV10_PGRAPH_CTX_CACHE(subchan, i))); - nv_mask(dev, NV10_PGRAPH_CTX_USER, 0xe000, subchan << 13); - - /* Inject NV10TCL_DMA_VTXBUF */ - nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, 0); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, - 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); - nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - - /* Restore the FIFO state */ - for (i = 0; i < ARRAY_SIZE(fifo); i++) - nv_wr32(dev, 0x4007a0 + 4 * i, fifo[i]); - - nv_wr32(dev, NV10_PGRAPH_FFINTFC_FIFO_PTR, fifo_ptr); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, st2); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, st2_dl); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DH, st2_dh); - - /* Restore the current ctx object */ - for (i = 0; i < 5; i++) - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(i), ctx_switch[i]); - nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user); -} - -static int -nv10_graph_load_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; - uint32_t tmp; - int i; - - for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) - nv_wr32(dev, nv10_graph_ctx_regs[i], pgraph_ctx->nv10[i]); - if (dev_priv->chipset >= 0x17) { - for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) - nv_wr32(dev, nv17_graph_ctx_regs[i], - pgraph_ctx->nv17[i]); - } - - nv10_graph_load_pipe(chan); - nv10_graph_load_dma_vtxbuf(chan, (nv_rd32(dev, NV10_PGRAPH_GLOBALSTATE1) - & 0xffff)); - - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); - tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER); - nv_wr32(dev, NV10_PGRAPH_CTX_USER, (tmp & 0xffffff) | chan->id << 24); - tmp = nv_rd32(dev, NV10_PGRAPH_FFINTFC_ST2); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, tmp & 0xcfffffff); - return 0; -} - -static int -nv10_graph_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_channel *chan; - struct graph_state *ctx; - uint32_t tmp; - int i; - - chan = nv10_graph_channel(dev); - if (!chan) - return 0; - ctx = chan->engctx[NVOBJ_ENGINE_GR]; - - for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) - ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]); - - if (dev_priv->chipset >= 0x17) { - for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) - ctx->nv17[i] = nv_rd32(dev, nv17_graph_ctx_regs[i]); - } - - nv10_graph_save_pipe(chan); - - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000); - tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; - tmp |= (pfifo->channels - 1) << 24; - nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp); - return 0; -} - -static void -nv10_graph_context_switch(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - int chid; - - nouveau_wait_for_idle(dev); - - /* If previous context is valid, we need to save it */ - nv10_graph_unload_context(dev); - - /* Load context for next channel */ - chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; - chan = dev_priv->channels.ptr[chid]; - if (chan && chan->engctx[NVOBJ_ENGINE_GR]) - nv10_graph_load_context(chan); -} - -#define NV_WRITE_CTX(reg, val) do { \ - int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \ - if (offset > 0) \ - pgraph_ctx->nv10[offset] = val; \ - } while (0) - -#define NV17_WRITE_CTX(reg, val) do { \ - int offset = nv17_graph_ctx_regs_find_offset(dev, reg); \ - if (offset > 0) \ - pgraph_ctx->nv17[offset] = val; \ - } while (0) - -struct nouveau_channel * -nv10_graph_channel(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chid = dev_priv->engine.fifo.channels; - - if (nv_rd32(dev, NV10_PGRAPH_CTX_CONTROL) & 0x00010000) - chid = nv_rd32(dev, NV10_PGRAPH_CTX_USER) >> 24; - - if (chid >= dev_priv->engine.fifo.channels) - return NULL; - - return dev_priv->channels.ptr[chid]; -} - -static int -nv10_graph_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct graph_state *pgraph_ctx; - - NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id); - - pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL); - if (pgraph_ctx == NULL) - return -ENOMEM; - chan->engctx[engine] = pgraph_ctx; - - NV_WRITE_CTX(0x00400e88, 0x08000000); - NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); - NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); - NV_WRITE_CTX(0x00400e10, 0x00001000); - NV_WRITE_CTX(0x00400e14, 0x00001000); - NV_WRITE_CTX(0x00400e30, 0x00080008); - NV_WRITE_CTX(0x00400e34, 0x00080008); - if (dev_priv->chipset >= 0x17) { - /* is it really needed ??? */ - NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, - nv_rd32(dev, NV10_PGRAPH_DEBUG_4)); - NV17_WRITE_CTX(0x004006b0, nv_rd32(dev, 0x004006b0)); - NV17_WRITE_CTX(0x00400eac, 0x0fff0000); - NV17_WRITE_CTX(0x00400eb0, 0x0fff0000); - NV17_WRITE_CTX(0x00400ec0, 0x00000080); - NV17_WRITE_CTX(0x00400ed0, 0x00000080); - } - NV_WRITE_CTX(NV10_PGRAPH_CTX_USER, chan->id << 24); - - nv10_graph_create_pipe(chan); - return 0; -} - -static void -nv10_graph_context_del(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct graph_state *pgraph_ctx = chan->engctx[engine]; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - - /* Unload the context if it's the currently active one */ - if (nv10_graph_channel(dev) == chan) - nv10_graph_unload_context(dev); - - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the context resources */ - chan->engctx[engine] = NULL; - kfree(pgraph_ctx); -} - -static void -nv10_graph_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr); -} - -static int -nv10_graph_init(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 tmp; - int i; - - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & - ~NV_PMC_ENABLE_PGRAPH); - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | - NV_PMC_ENABLE_PGRAPH); - - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); - nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700); - /* nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x24E00810); */ /* 0x25f92ad9 */ - nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x25f92ad9); - nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | - (1<<29) | - (1<<31)); - if (dev_priv->chipset >= 0x17) { - nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x1f000000); - nv_wr32(dev, 0x400a10, 0x3ff3fb6); - nv_wr32(dev, 0x400838, 0x2f8684); - nv_wr32(dev, 0x40083c, 0x115f3f); - nv_wr32(dev, 0x004006b0, 0x40000020); - } else - nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); - - /* Turn all the tiling regions off. */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) - nv10_graph_set_tile_region(dev, i); - - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000); - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000); - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(2), 0x00000000); - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(3), 0x00000000); - nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(4), 0x00000000); - nv_wr32(dev, NV10_PGRAPH_STATE, 0xFFFFFFFF); - - tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; - tmp |= (dev_priv->engine.fifo.channels - 1) << 24; - nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp); - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); - nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2, 0x08000000); - - return 0; -} - -static int -nv10_graph_fini(struct drm_device *dev, int engine, bool suspend) -{ - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) { - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - return -EBUSY; - } - nv10_graph_unload_context(dev); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); - return 0; -} - -static int -nv17_graph_mthd_lma_window(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - struct graph_state *ctx = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - struct pipe_state *pipe = &ctx->pipe_state; - uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; - uint32_t xfmode0, xfmode1; - int i; - - ctx->lma_window[(mthd - 0x1638) / 4] = data; - - if (mthd != 0x1644) - return 0; - - nouveau_wait_for_idle(dev); - - PIPE_SAVE(dev, pipe_0x0040, 0x0040); - PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); - - PIPE_RESTORE(dev, ctx->lma_window, 0x6790); - - nouveau_wait_for_idle(dev); - - xfmode0 = nv_rd32(dev, NV10_PGRAPH_XFMODE0); - xfmode1 = nv_rd32(dev, NV10_PGRAPH_XFMODE1); - - PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); - PIPE_SAVE(dev, pipe_0x64c0, 0x64c0); - PIPE_SAVE(dev, pipe_0x6ab0, 0x6ab0); - PIPE_SAVE(dev, pipe_0x6a80, 0x6a80); - - nouveau_wait_for_idle(dev); - - nv_wr32(dev, NV10_PGRAPH_XFMODE0, 0x10000000); - nv_wr32(dev, NV10_PGRAPH_XFMODE1, 0x00000000); - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000064c0); - for (i = 0; i < 4; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); - for (i = 0; i < 4; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006ab0); - for (i = 0; i < 3; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x3f800000); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00006a80); - for (i = 0; i < 3; i++) - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040); - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000008); - - PIPE_RESTORE(dev, pipe->pipe_0x0200, 0x0200); - - nouveau_wait_for_idle(dev); - - PIPE_RESTORE(dev, pipe_0x0040, 0x0040); - - nv_wr32(dev, NV10_PGRAPH_XFMODE0, xfmode0); - nv_wr32(dev, NV10_PGRAPH_XFMODE1, xfmode1); - - PIPE_RESTORE(dev, pipe_0x64c0, 0x64c0); - PIPE_RESTORE(dev, pipe_0x6ab0, 0x6ab0); - PIPE_RESTORE(dev, pipe_0x6a80, 0x6a80); - PIPE_RESTORE(dev, pipe->pipe_0x4400, 0x4400); - - nv_wr32(dev, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0); - nv_wr32(dev, NV10_PGRAPH_PIPE_DATA, 0x00000000); - - nouveau_wait_for_idle(dev); - - return 0; -} - -static int -nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - struct drm_device *dev = chan->dev; - - nouveau_wait_for_idle(dev); - - nv_wr32(dev, NV10_PGRAPH_DEBUG_4, - nv_rd32(dev, NV10_PGRAPH_DEBUG_4) | 0x1 << 8); - nv_wr32(dev, 0x004006b0, - nv_rd32(dev, 0x004006b0) | 0x8 << 24); - - return 0; -} - -struct nouveau_bitfield nv10_graph_intr[] = { - { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, - { NV_PGRAPH_INTR_ERROR, "ERROR" }, - {} -}; - -struct nouveau_bitfield nv10_graph_nstatus[] = { - { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, - { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, - {} -}; - -static void -nv10_graph_isr(struct drm_device *dev) -{ - u32 stat; - - while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { - u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); - u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); - u32 chid = (addr & 0x01f00000) >> 20; - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00001ffc); - u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); - u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff; - u32 show = stat; - - if (stat & NV_PGRAPH_INTR_ERROR) { - if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { - if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) - show &= ~NV_PGRAPH_INTR_ERROR; - } - } - - if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { - nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); - stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - nv10_graph_context_switch(dev); - } - - nv_wr32(dev, NV03_PGRAPH_INTR, stat); - nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); - - if (show && nouveau_ratelimit()) { - NV_INFO(dev, "PGRAPH -"); - nouveau_bitfield_print(nv10_graph_intr, show); - printk(" nsource:"); - nouveau_bitfield_print(nv04_graph_nsource, nsource); - printk(" nstatus:"); - nouveau_bitfield_print(nv10_graph_nstatus, nstatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " - "mthd 0x%04x data 0x%08x\n", - chid, subc, class, mthd, data); - } - } -} - -static void -nv10_graph_destroy(struct drm_device *dev, int engine) -{ - struct nv10_graph_engine *pgraph = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 12); - kfree(pgraph); -} - -int -nv10_graph_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv10_graph_engine *pgraph; - - pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); - if (!pgraph) - return -ENOMEM; - - pgraph->base.destroy = nv10_graph_destroy; - pgraph->base.init = nv10_graph_init; - pgraph->base.fini = nv10_graph_fini; - pgraph->base.context_new = nv10_graph_context_new; - pgraph->base.context_del = nv10_graph_context_del; - pgraph->base.object_new = nv04_graph_object_new; - pgraph->base.set_tile_region = nv10_graph_set_tile_region; - - NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); - nouveau_irq_register(dev, 12, nv10_graph_isr); - - /* nvsw */ - NVOBJ_CLASS(dev, 0x506e, SW); - NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); - - NVOBJ_CLASS(dev, 0x0030, GR); /* null */ - NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ - NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ - NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */ - NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ - NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ - NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ - NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ - NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ - NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ - NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ - NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ - NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ - NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */ - NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */ - NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */ - NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */ - - /* celcius */ - if (dev_priv->chipset <= 0x10) { - NVOBJ_CLASS(dev, 0x0056, GR); - } else - if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) { - NVOBJ_CLASS(dev, 0x0096, GR); - } else { - NVOBJ_CLASS(dev, 0x0099, GR); - NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window); - NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window); - NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window); - NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window); - NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.c deleted file mode 100644 index 696d7e7d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.c +++ /dev/null @@ -1,825 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nouveau_gpio.h" -#include "nouveau_hw.h" -#include "nv17_tv.h" - -static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t testval, regoffset = nv04_dac_output_offset(encoder); - uint32_t gpio0, gpio1, fp_htotal, fp_hsync_start, fp_hsync_end, - fp_control, test_ctrl, dacclk, ctv_14, ctv_1c, ctv_6c; - uint32_t sample = 0; - int head; - -#define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) - testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); - if (dev_priv->vbios.tvdactestval) - testval = dev_priv->vbios.tvdactestval; - - dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); - head = (dacclk & 0x100) >> 8; - - /* Save the previous state. */ - gpio1 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC1); - gpio0 = nouveau_gpio_func_get(dev, DCB_GPIO_TVDAC0); - fp_htotal = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL); - fp_hsync_start = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START); - fp_hsync_end = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END); - fp_control = NVReadRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL); - test_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); - ctv_1c = NVReadRAMDAC(dev, head, 0x680c1c); - ctv_14 = NVReadRAMDAC(dev, head, 0x680c14); - ctv_6c = NVReadRAMDAC(dev, head, 0x680c6c); - - /* Prepare the DAC for load detection. */ - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, true); - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, true); - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, 1343); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, 1047); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, 1183); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, - NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | - NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 | - NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | - NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS | - NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS); - - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, 0); - - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, - (dacclk & ~0xff) | 0x22); - msleep(1); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, - (dacclk & ~0xff) | 0x21); - - NVWriteRAMDAC(dev, head, 0x680c1c, 1 << 20); - NVWriteRAMDAC(dev, head, 0x680c14, 4 << 16); - - /* Sample pin 0x4 (usually S-video luma). */ - NVWriteRAMDAC(dev, head, 0x680c6c, testval >> 10 & 0x3ff); - msleep(20); - sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) - & 0x4 << 28; - - /* Sample the remaining pins. */ - NVWriteRAMDAC(dev, head, 0x680c6c, testval & 0x3ff); - msleep(20); - sample |= NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset) - & 0xa << 28; - - /* Restore the previous state. */ - NVWriteRAMDAC(dev, head, 0x680c1c, ctv_1c); - NVWriteRAMDAC(dev, head, 0x680c14, ctv_14); - NVWriteRAMDAC(dev, head, 0x680c6c, ctv_6c); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset, dacclk); - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset, test_ctrl); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_TG_CONTROL, fp_control); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_END, fp_hsync_end); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HSYNC_START, fp_hsync_start); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HTOTAL, fp_htotal); - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, gpio1); - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, gpio0); - - return sample; -} - -static bool -get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) -{ - /* Zotac FX5200 */ - if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || - nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { - *pin_mask = 0xc; - return false; - } - - /* MSI nForce2 IGP */ - if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { - *pin_mask = 0xc; - return false; - } - - return true; -} - -static enum drm_connector_status -nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_mode_config *conf = &dev->mode_config; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - struct dcb_entry *dcb = tv_enc->base.dcb; - bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask); - - if (nv04_dac_in_use(encoder)) - return connector_status_disconnected; - - if (reliable) { - if (dev_priv->chipset == 0x42 || - dev_priv->chipset == 0x43) - tv_enc->pin_mask = - nv42_tv_sample_load(encoder) >> 28 & 0xe; - else - tv_enc->pin_mask = - nv17_dac_sample_load(encoder) >> 28 & 0xe; - } - - switch (tv_enc->pin_mask) { - case 0x2: - case 0x4: - tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Composite; - break; - case 0xc: - tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SVIDEO; - break; - case 0xe: - if (dcb->tvconf.has_component_output) - tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Component; - else - tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_SCART; - break; - default: - tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; - break; - } - - drm_connector_property_set_value(connector, - conf->tv_subconnector_property, - tv_enc->subconnector); - - if (!reliable) { - return connector_status_unknown; - } else if (tv_enc->subconnector) { - NV_INFO(dev, "Load detected on output %c\n", - '@' + ffs(dcb->or)); - return connector_status_connected; - } else { - return connector_status_disconnected; - } -} - -static int nv17_tv_get_ld_modes(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - const struct drm_display_mode *tv_mode; - int n = 0; - - for (tv_mode = nv17_tv_modes; tv_mode->hdisplay; tv_mode++) { - struct drm_display_mode *mode; - - mode = drm_mode_duplicate(encoder->dev, tv_mode); - - mode->clock = tv_norm->tv_enc_mode.vrefresh * - mode->htotal / 1000 * - mode->vtotal / 1000; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - mode->clock *= 2; - - if (mode->hdisplay == tv_norm->tv_enc_mode.hdisplay && - mode->vdisplay == tv_norm->tv_enc_mode.vdisplay) - mode->type |= DRM_MODE_TYPE_PREFERRED; - - drm_mode_probed_add(connector, mode); - n++; - } - - return n; -} - -static int nv17_tv_get_hd_modes(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - struct drm_display_mode *output_mode = &tv_norm->ctv_enc_mode.mode; - struct drm_display_mode *mode; - const struct { - int hdisplay; - int vdisplay; - } modes[] = { - { 640, 400 }, - { 640, 480 }, - { 720, 480 }, - { 720, 576 }, - { 800, 600 }, - { 1024, 768 }, - { 1280, 720 }, - { 1280, 1024 }, - { 1920, 1080 } - }; - int i, n = 0; - - for (i = 0; i < ARRAY_SIZE(modes); i++) { - if (modes[i].hdisplay > output_mode->hdisplay || - modes[i].vdisplay > output_mode->vdisplay) - continue; - - if (modes[i].hdisplay == output_mode->hdisplay && - modes[i].vdisplay == output_mode->vdisplay) { - mode = drm_mode_duplicate(encoder->dev, output_mode); - mode->type |= DRM_MODE_TYPE_PREFERRED; - - } else { - mode = drm_cvt_mode(encoder->dev, modes[i].hdisplay, - modes[i].vdisplay, 60, false, - (output_mode->flags & - DRM_MODE_FLAG_INTERLACE), false); - } - - /* CVT modes are sometimes unsuitable... */ - if (output_mode->hdisplay <= 720 - || output_mode->hdisplay >= 1920) { - mode->htotal = output_mode->htotal; - mode->hsync_start = (mode->hdisplay + (mode->htotal - - mode->hdisplay) * 9 / 10) & ~7; - mode->hsync_end = mode->hsync_start + 8; - } - - if (output_mode->vdisplay >= 1024) { - mode->vtotal = output_mode->vtotal; - mode->vsync_start = output_mode->vsync_start; - mode->vsync_end = output_mode->vsync_end; - } - - mode->type |= DRM_MODE_TYPE_DRIVER; - drm_mode_probed_add(connector, mode); - n++; - } - - return n; -} - -static int nv17_tv_get_modes(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - - if (tv_norm->kind == CTV_ENC_MODE) - return nv17_tv_get_hd_modes(encoder, connector); - else - return nv17_tv_get_ld_modes(encoder, connector); -} - -static int nv17_tv_mode_valid(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - - if (tv_norm->kind == CTV_ENC_MODE) { - struct drm_display_mode *output_mode = - &tv_norm->ctv_enc_mode.mode; - - if (mode->clock > 400000) - return MODE_CLOCK_HIGH; - - if (mode->hdisplay > output_mode->hdisplay || - mode->vdisplay > output_mode->vdisplay) - return MODE_BAD; - - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) != - (output_mode->flags & DRM_MODE_FLAG_INTERLACE)) - return MODE_NO_INTERLACE; - - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - return MODE_NO_DBLESCAN; - - } else { - const int vsync_tolerance = 600; - - if (mode->clock > 70000) - return MODE_CLOCK_HIGH; - - if (abs(drm_mode_vrefresh(mode) * 1000 - - tv_norm->tv_enc_mode.vrefresh) > vsync_tolerance) - return MODE_VSYNC; - - /* The encoder takes care of the actual interlacing */ - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_NO_INTERLACE; - } - - return MODE_OK; -} - -static bool nv17_tv_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - - if (nv04_dac_in_use(encoder)) - return false; - - if (tv_norm->kind == CTV_ENC_MODE) - adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock; - else - adjusted_mode->clock = 90000; - - return true; -} - -static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct nv17_tv_state *regs = &to_tv_enc(encoder)->state; - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - - if (nouveau_encoder(encoder)->last_dpms == mode) - return; - nouveau_encoder(encoder)->last_dpms = mode; - - NV_INFO(dev, "Setting dpms mode %d on TV encoder (output %d)\n", - mode, nouveau_encoder(encoder)->dcb->index); - - regs->ptv_200 &= ~1; - - if (tv_norm->kind == CTV_ENC_MODE) { - nv04_dfp_update_fp_control(encoder, mode); - - } else { - nv04_dfp_update_fp_control(encoder, DRM_MODE_DPMS_OFF); - - if (mode == DRM_MODE_DPMS_ON) - regs->ptv_200 |= 1; - } - - nv_load_ptv(dev, regs, 200); - - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC1, mode == DRM_MODE_DPMS_ON); - nouveau_gpio_func_set(dev, DCB_GPIO_TVDAC0, mode == DRM_MODE_DPMS_ON); - - nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); -} - -static void nv17_tv_prepare(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - int head = nouveau_crtc(encoder->crtc)->index; - uint8_t *cr_lcd = &dev_priv->mode_reg.crtc_reg[head].CRTC[ - NV_CIO_CRE_LCD__INDEX]; - uint32_t dacclk_off = NV_PRAMDAC_DACCLK + - nv04_dac_output_offset(encoder); - uint32_t dacclk; - - helper->dpms(encoder, DRM_MODE_DPMS_OFF); - - nv04_dfp_disable(dev, head); - - /* Unbind any FP encoders from this head if we need the FP - * stuff enabled. */ - if (tv_norm->kind == CTV_ENC_MODE) { - struct drm_encoder *enc; - - list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { - struct dcb_entry *dcb = nouveau_encoder(enc)->dcb; - - if ((dcb->type == OUTPUT_TMDS || - dcb->type == OUTPUT_LVDS) && - !enc->crtc && - nv04_dfp_get_bound_head(dev, dcb) == head) { - nv04_dfp_bind_head(dev, dcb, head ^ 1, - dev_priv->vbios.fp.dual_link); - } - } - - } - - if (tv_norm->kind == CTV_ENC_MODE) - *cr_lcd |= 0x1 | (head ? 0x0 : 0x8); - - /* Set the DACCLK register */ - dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1; - - if (dev_priv->card_type == NV_40) - dacclk |= 0x1a << 16; - - if (tv_norm->kind == CTV_ENC_MODE) { - dacclk |= 0x20; - - if (head) - dacclk |= 0x100; - else - dacclk &= ~0x100; - - } else { - dacclk |= 0x10; - - } - - NVWriteRAMDAC(dev, 0, dacclk_off, dacclk); -} - -static void nv17_tv_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *drm_mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int head = nouveau_crtc(encoder->crtc)->index; - struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head]; - struct nv17_tv_state *tv_regs = &to_tv_enc(encoder)->state; - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - int i; - - regs->CRTC[NV_CIO_CRE_53] = 0x40; /* FP_HTIMING */ - regs->CRTC[NV_CIO_CRE_54] = 0; /* FP_VTIMING */ - regs->ramdac_630 = 0x2; /* turn off green mode (tv test pattern?) */ - regs->tv_setup = 1; - regs->ramdac_8c0 = 0x0; - - if (tv_norm->kind == TV_ENC_MODE) { - tv_regs->ptv_200 = 0x13111100; - if (head) - tv_regs->ptv_200 |= 0x10; - - tv_regs->ptv_20c = 0x808010; - tv_regs->ptv_304 = 0x2d00000; - tv_regs->ptv_600 = 0x0; - tv_regs->ptv_60c = 0x0; - tv_regs->ptv_610 = 0x1e00000; - - if (tv_norm->tv_enc_mode.vdisplay == 576) { - tv_regs->ptv_508 = 0x1200000; - tv_regs->ptv_614 = 0x33; - - } else if (tv_norm->tv_enc_mode.vdisplay == 480) { - tv_regs->ptv_508 = 0xf00000; - tv_regs->ptv_614 = 0x13; - } - - if (dev_priv->card_type >= NV_30) { - tv_regs->ptv_500 = 0xe8e0; - tv_regs->ptv_504 = 0x1710; - tv_regs->ptv_604 = 0x0; - tv_regs->ptv_608 = 0x0; - } else { - if (tv_norm->tv_enc_mode.vdisplay == 576) { - tv_regs->ptv_604 = 0x20; - tv_regs->ptv_608 = 0x10; - tv_regs->ptv_500 = 0x19710; - tv_regs->ptv_504 = 0x68f0; - - } else if (tv_norm->tv_enc_mode.vdisplay == 480) { - tv_regs->ptv_604 = 0x10; - tv_regs->ptv_608 = 0x20; - tv_regs->ptv_500 = 0x4b90; - tv_regs->ptv_504 = 0x1b480; - } - } - - for (i = 0; i < 0x40; i++) - tv_regs->tv_enc[i] = tv_norm->tv_enc_mode.tv_enc[i]; - - } else { - struct drm_display_mode *output_mode = - &tv_norm->ctv_enc_mode.mode; - - /* The registers in PRAMDAC+0xc00 control some timings and CSC - * parameters for the CTV encoder (It's only used for "HD" TV - * modes, I don't think I have enough working to guess what - * they exactly mean...), it's probably connected at the - * output of the FP encoder, but it also needs the analog - * encoder in its OR enabled and routed to the head it's - * using. It's enabled with the DACCLK register, bits [5:4]. - */ - for (i = 0; i < 38; i++) - regs->ctv_regs[i] = tv_norm->ctv_enc_mode.ctv_regs[i]; - - regs->fp_horiz_regs[FP_DISPLAY_END] = output_mode->hdisplay - 1; - regs->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1; - regs->fp_horiz_regs[FP_SYNC_START] = - output_mode->hsync_start - 1; - regs->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1; - regs->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay + - max((output_mode->hdisplay-600)/40 - 1, 1); - - regs->fp_vert_regs[FP_DISPLAY_END] = output_mode->vdisplay - 1; - regs->fp_vert_regs[FP_TOTAL] = output_mode->vtotal - 1; - regs->fp_vert_regs[FP_SYNC_START] = - output_mode->vsync_start - 1; - regs->fp_vert_regs[FP_SYNC_END] = output_mode->vsync_end - 1; - regs->fp_vert_regs[FP_CRTC] = output_mode->vdisplay - 1; - - regs->fp_control = NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS | - NV_PRAMDAC_FP_TG_CONTROL_READ_PROG | - NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12; - - if (output_mode->flags & DRM_MODE_FLAG_PVSYNC) - regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS; - if (output_mode->flags & DRM_MODE_FLAG_PHSYNC) - regs->fp_control |= NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS; - - regs->fp_debug_0 = NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND | - NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND | - NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR | - NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR | - NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED | - NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE | - NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE; - - regs->fp_debug_2 = 0; - - regs->fp_margin_color = 0x801080; - - } -} - -static void nv17_tv_commit(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_encoder_helper_funcs *helper = encoder->helper_private; - - if (get_tv_norm(encoder)->kind == TV_ENC_MODE) { - nv17_tv_update_rescaler(encoder); - nv17_tv_update_properties(encoder); - } else { - nv17_ctv_update_rescaler(encoder); - } - - nv17_tv_state_load(dev, &to_tv_enc(encoder)->state); - - /* This could use refinement for flatpanels, but it should work */ - if (dev_priv->chipset < 0x44) - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + - nv04_dac_output_offset(encoder), - 0xf0000000); - else - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + - nv04_dac_output_offset(encoder), - 0x00100000); - - helper->dpms(encoder, DRM_MODE_DPMS_ON); - - NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name( - &nouveau_encoder_connector_get(nv_encoder)->base), - nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); -} - -static void nv17_tv_save(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - - nouveau_encoder(encoder)->restore.output = - NVReadRAMDAC(dev, 0, - NV_PRAMDAC_DACCLK + - nv04_dac_output_offset(encoder)); - - nv17_tv_state_save(dev, &tv_enc->saved_state); - - tv_enc->state.ptv_200 = tv_enc->saved_state.ptv_200; -} - -static void nv17_tv_restore(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - - NVWriteRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + - nv04_dac_output_offset(encoder), - nouveau_encoder(encoder)->restore.output); - - nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state); - - nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED; -} - -static int nv17_tv_create_resources(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct drm_mode_config *conf = &dev->mode_config; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; - int num_tv_norms = dcb->tvconf.has_component_output ? NUM_TV_NORMS : - NUM_LD_TV_NORMS; - int i; - - if (nouveau_tv_norm) { - for (i = 0; i < num_tv_norms; i++) { - if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) { - tv_enc->tv_norm = i; - break; - } - } - - if (i == num_tv_norms) - NV_WARN(dev, "Invalid TV norm setting \"%s\"\n", - nouveau_tv_norm); - } - - drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names); - - drm_connector_attach_property(connector, - conf->tv_select_subconnector_property, - tv_enc->select_subconnector); - drm_connector_attach_property(connector, - conf->tv_subconnector_property, - tv_enc->subconnector); - drm_connector_attach_property(connector, - conf->tv_mode_property, - tv_enc->tv_norm); - drm_connector_attach_property(connector, - conf->tv_flicker_reduction_property, - tv_enc->flicker); - drm_connector_attach_property(connector, - conf->tv_saturation_property, - tv_enc->saturation); - drm_connector_attach_property(connector, - conf->tv_hue_property, - tv_enc->hue); - drm_connector_attach_property(connector, - conf->tv_overscan_property, - tv_enc->overscan); - - return 0; -} - -static int nv17_tv_set_property(struct drm_encoder *encoder, - struct drm_connector *connector, - struct drm_property *property, - uint64_t val) -{ - struct drm_mode_config *conf = &encoder->dev->mode_config; - struct drm_crtc *crtc = encoder->crtc; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - bool modes_changed = false; - - if (property == conf->tv_overscan_property) { - tv_enc->overscan = val; - if (encoder->crtc) { - if (tv_norm->kind == CTV_ENC_MODE) - nv17_ctv_update_rescaler(encoder); - else - nv17_tv_update_rescaler(encoder); - } - - } else if (property == conf->tv_saturation_property) { - if (tv_norm->kind != TV_ENC_MODE) - return -EINVAL; - - tv_enc->saturation = val; - nv17_tv_update_properties(encoder); - - } else if (property == conf->tv_hue_property) { - if (tv_norm->kind != TV_ENC_MODE) - return -EINVAL; - - tv_enc->hue = val; - nv17_tv_update_properties(encoder); - - } else if (property == conf->tv_flicker_reduction_property) { - if (tv_norm->kind != TV_ENC_MODE) - return -EINVAL; - - tv_enc->flicker = val; - if (encoder->crtc) - nv17_tv_update_rescaler(encoder); - - } else if (property == conf->tv_mode_property) { - if (connector->dpms != DRM_MODE_DPMS_OFF) - return -EINVAL; - - tv_enc->tv_norm = val; - - modes_changed = true; - - } else if (property == conf->tv_select_subconnector_property) { - if (tv_norm->kind != TV_ENC_MODE) - return -EINVAL; - - tv_enc->select_subconnector = val; - nv17_tv_update_properties(encoder); - - } else { - return -EINVAL; - } - - if (modes_changed) { - drm_helper_probe_single_connector_modes(connector, 0, 0); - - /* Disable the crtc to ensure a full modeset is - * performed whenever it's turned on again. */ - if (crtc) { - struct drm_mode_set modeset = { - .crtc = crtc, - }; - - crtc->funcs->set_config(&modeset); - } - } - - return 0; -} - -static void nv17_tv_destroy(struct drm_encoder *encoder) -{ - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - - NV_DEBUG_KMS(encoder->dev, "\n"); - - drm_encoder_cleanup(encoder); - kfree(tv_enc); -} - -static struct drm_encoder_helper_funcs nv17_tv_helper_funcs = { - .dpms = nv17_tv_dpms, - .save = nv17_tv_save, - .restore = nv17_tv_restore, - .mode_fixup = nv17_tv_mode_fixup, - .prepare = nv17_tv_prepare, - .commit = nv17_tv_commit, - .mode_set = nv17_tv_mode_set, - .detect = nv17_tv_detect, -}; - -static struct drm_encoder_slave_funcs nv17_tv_slave_funcs = { - .get_modes = nv17_tv_get_modes, - .mode_valid = nv17_tv_mode_valid, - .create_resources = nv17_tv_create_resources, - .set_property = nv17_tv_set_property, -}; - -static struct drm_encoder_funcs nv17_tv_funcs = { - .destroy = nv17_tv_destroy, -}; - -int -nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry) -{ - struct drm_device *dev = connector->dev; - struct drm_encoder *encoder; - struct nv17_tv_encoder *tv_enc = NULL; - - tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL); - if (!tv_enc) - return -ENOMEM; - - tv_enc->overscan = 50; - tv_enc->flicker = 50; - tv_enc->saturation = 50; - tv_enc->hue = 0; - tv_enc->tv_norm = TV_NORM_PAL; - tv_enc->subconnector = DRM_MODE_SUBCONNECTOR_Unknown; - tv_enc->select_subconnector = DRM_MODE_SUBCONNECTOR_Automatic; - tv_enc->pin_mask = 0; - - encoder = to_drm_encoder(&tv_enc->base); - - tv_enc->base.dcb = entry; - tv_enc->base.or = ffs(entry->or) - 1; - - drm_encoder_init(dev, encoder, &nv17_tv_funcs, DRM_MODE_ENCODER_TVDAC); - drm_encoder_helper_add(encoder, &nv17_tv_helper_funcs); - to_encoder_slave(encoder)->slave_funcs = &nv17_tv_slave_funcs; - - encoder->possible_crtcs = entry->heads; - encoder->possible_clones = 0; - - nv17_tv_create_resources(encoder, connector); - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.h deleted file mode 100644 index 622e7222..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NV17_TV_H__ -#define __NV17_TV_H__ - -struct nv17_tv_state { - uint8_t tv_enc[0x40]; - - uint32_t hfilter[4][7]; - uint32_t hfilter2[4][7]; - uint32_t vfilter[4][7]; - - uint32_t ptv_200; - uint32_t ptv_204; - uint32_t ptv_208; - uint32_t ptv_20c; - uint32_t ptv_304; - uint32_t ptv_500; - uint32_t ptv_504; - uint32_t ptv_508; - uint32_t ptv_600; - uint32_t ptv_604; - uint32_t ptv_608; - uint32_t ptv_60c; - uint32_t ptv_610; - uint32_t ptv_614; -}; - -enum nv17_tv_norm{ - TV_NORM_PAL, - TV_NORM_PAL_M, - TV_NORM_PAL_N, - TV_NORM_PAL_NC, - TV_NORM_NTSC_M, - TV_NORM_NTSC_J, - NUM_LD_TV_NORMS, - TV_NORM_HD480I = NUM_LD_TV_NORMS, - TV_NORM_HD480P, - TV_NORM_HD576I, - TV_NORM_HD576P, - TV_NORM_HD720P, - TV_NORM_HD1080I, - NUM_TV_NORMS -}; - -struct nv17_tv_encoder { - struct nouveau_encoder base; - - struct nv17_tv_state state; - struct nv17_tv_state saved_state; - - int overscan; - int flicker; - int saturation; - int hue; - enum nv17_tv_norm tv_norm; - int subconnector; - int select_subconnector; - uint32_t pin_mask; -}; -#define to_tv_enc(x) container_of(nouveau_encoder(x), \ - struct nv17_tv_encoder, base) - -extern char *nv17_tv_norm_names[NUM_TV_NORMS]; - -extern struct nv17_tv_norm_params { - enum { - TV_ENC_MODE, - CTV_ENC_MODE, - } kind; - - union { - struct { - int hdisplay; - int vdisplay; - int vrefresh; /* mHz */ - - uint8_t tv_enc[0x40]; - } tv_enc_mode; - - struct { - struct drm_display_mode mode; - - uint32_t ctv_regs[38]; - } ctv_enc_mode; - }; - -} nv17_tv_norms[NUM_TV_NORMS]; -#define get_tv_norm(enc) (&nv17_tv_norms[to_tv_enc(enc)->tv_norm]) - -extern const struct drm_display_mode nv17_tv_modes[]; - -static inline int interpolate(int y0, int y1, int y2, int x) -{ - return y1 + (x < 50 ? y1 - y0 : y2 - y1) * (x - 50) / 50; -} - -void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state); -void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state); -void nv17_tv_update_properties(struct drm_encoder *encoder); -void nv17_tv_update_rescaler(struct drm_encoder *encoder); -void nv17_ctv_update_rescaler(struct drm_encoder *encoder); - -/* TV hardware access functions */ - -static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, - uint32_t val) -{ - nv_wr32(dev, reg, val); -} - -static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg) -{ - return nv_rd32(dev, reg); -} - -static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, - uint8_t val) -{ - nv_write_ptv(dev, NV_PTV_TV_INDEX, reg); - nv_write_ptv(dev, NV_PTV_TV_DATA, val); -} - -static inline uint8_t nv_read_tv_enc(struct drm_device *dev, uint8_t reg) -{ - nv_write_ptv(dev, NV_PTV_TV_INDEX, reg); - return nv_read_ptv(dev, NV_PTV_TV_DATA); -} - -#define nv_load_ptv(dev, state, reg) \ - nv_write_ptv(dev, NV_PTV_OFFSET + 0x##reg, state->ptv_##reg) -#define nv_save_ptv(dev, state, reg) \ - state->ptv_##reg = nv_read_ptv(dev, NV_PTV_OFFSET + 0x##reg) -#define nv_load_tv_enc(dev, state, reg) \ - nv_write_tv_enc(dev, 0x##reg, state->tv_enc[0x##reg]) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv_modes.c deleted file mode 100644 index 4d1d29f6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv17_tv_modes.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Copyright (C) 2009 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "nouveau_drv.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" -#include "nouveau_hw.h" -#include "nv17_tv.h" - -char *nv17_tv_norm_names[NUM_TV_NORMS] = { - [TV_NORM_PAL] = "PAL", - [TV_NORM_PAL_M] = "PAL-M", - [TV_NORM_PAL_N] = "PAL-N", - [TV_NORM_PAL_NC] = "PAL-Nc", - [TV_NORM_NTSC_M] = "NTSC-M", - [TV_NORM_NTSC_J] = "NTSC-J", - [TV_NORM_HD480I] = "hd480i", - [TV_NORM_HD480P] = "hd480p", - [TV_NORM_HD576I] = "hd576i", - [TV_NORM_HD576P] = "hd576p", - [TV_NORM_HD720P] = "hd720p", - [TV_NORM_HD1080I] = "hd1080i" -}; - -/* TV standard specific parameters */ - -struct nv17_tv_norm_params nv17_tv_norms[NUM_TV_NORMS] = { - [TV_NORM_PAL] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 576, 50000, { - 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3, - 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3, - 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, - 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0 - } } } }, - - [TV_NORM_PAL_M] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 480, 59940, { - 0x21, 0xe6, 0xef, 0xe3, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x44, 0x76, 0x32, 0x25, 0x0, 0x3c, 0x0, - 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, - 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x18, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x40, 0x10, 0x0, 0x9c, - 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 - } } } }, - - [TV_NORM_PAL_N] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 576, 50000, { - 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x40, 0x8a, 0x32, 0x25, 0x0, 0x3c, 0x0, - 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, - 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, - 0xbd, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 - } } } }, - - [TV_NORM_PAL_NC] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 576, 50000, { - 0x21, 0xf6, 0x94, 0x46, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x44, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3, - 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3, - 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, - 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0 - } } } }, - - [TV_NORM_NTSC_M] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 480, 59940, { - 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x3c, 0x0, - 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, - 0xc5, 0x4, 0xc5, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0x9c, - 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 - } } } }, - - [TV_NORM_NTSC_J] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 480, 59940, { - 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0, - 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, - 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4, - 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 - } } } }, - - [TV_NORM_HD480I] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 480, 59940, { - 0x21, 0xf0, 0x7c, 0x1f, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x44, 0x76, 0x48, 0x0, 0x0, 0x32, 0x0, - 0x3c, 0x0, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x83, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x1, - 0xcf, 0x4, 0xcf, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x16, 0xff, 0x3, 0x20, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x4, 0x10, 0x0, 0xa4, - 0xc8, 0x15, 0x5, 0x15, 0x3c, 0x0, 0x0, 0x0 - } } } }, - - [TV_NORM_HD576I] = { TV_ENC_MODE, { - .tv_enc_mode = { 720, 576, 50000, { - 0x2a, 0x9, 0x8a, 0xcb, 0x0, 0x0, 0xb, 0x18, - 0x7e, 0x40, 0x8a, 0x35, 0x27, 0x0, 0x34, 0x3, - 0x3e, 0x3, 0x17, 0x21, 0x1b, 0x1b, 0x24, 0x9c, - 0x1, 0x0, 0xf, 0xf, 0x60, 0x5, 0xd3, 0x3, - 0xd3, 0x4, 0xd4, 0x1, 0x2, 0x0, 0xa, 0x5, - 0x0, 0x1a, 0xff, 0x3, 0x18, 0xf, 0x78, 0x0, - 0x0, 0xb4, 0x0, 0x15, 0x49, 0x10, 0x0, 0x9b, - 0xbd, 0x15, 0x5, 0x15, 0x3e, 0x3, 0x0, 0x0 - } } } }, - - - [TV_NORM_HD480P] = { CTV_ENC_MODE, { - .ctv_enc_mode = { - .mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, - 720, 735, 743, 858, 0, 480, 490, 494, 525, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314, - 0x354003a, 0x40000, 0x6f0344, 0x18100000, - 0x10160004, 0x10060005, 0x1006000c, 0x10060020, - 0x10060021, 0x140e0022, 0x10060202, 0x1802020a, - 0x1810020b, 0x10000fff, 0x10000fff, 0x10000fff, - 0x10000fff, 0x10000fff, 0x10000fff, 0x70, - 0x3ff0000, 0x57, 0x2e001e, 0x258012c, - 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300, - 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400 - } } } }, - - [TV_NORM_HD576P] = { CTV_ENC_MODE, { - .ctv_enc_mode = { - .mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, - 720, 730, 738, 864, 0, 576, 581, 585, 625, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - .ctv_regs = { 0x3540000, 0x0, 0x0, 0x314, - 0x354003a, 0x40000, 0x6f0344, 0x18100000, - 0x10060001, 0x10060009, 0x10060026, 0x10060027, - 0x140e0028, 0x10060268, 0x1810026d, 0x10000fff, - 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, - 0x10000fff, 0x10000fff, 0x10000fff, 0x69, - 0x3ff0000, 0x57, 0x2e001e, 0x258012c, - 0xa0aa04ec, 0x30, 0x80960019, 0x12c0300, - 0x2019, 0x600, 0x32060019, 0x0, 0x0, 0x400 - } } } }, - - [TV_NORM_HD720P] = { CTV_ENC_MODE, { - .ctv_enc_mode = { - .mode = { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, - 1280, 1349, 1357, 1650, 0, 720, 725, 730, 750, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - .ctv_regs = { 0x1260394, 0x0, 0x0, 0x622, - 0x66b0021, 0x6004a, 0x1210626, 0x8170000, - 0x70004, 0x70016, 0x70017, 0x40f0018, - 0x702e8, 0x81702ed, 0xfff, 0xfff, - 0xfff, 0xfff, 0xfff, 0xfff, - 0xfff, 0xfff, 0xfff, 0x0, - 0x2e40001, 0x58, 0x2e001e, 0x258012c, - 0xa0aa04ec, 0x30, 0x810c0039, 0x12c0300, - 0xc0002039, 0x600, 0x32060039, 0x0, 0x0, 0x0 - } } } }, - - [TV_NORM_HD1080I] = { CTV_ENC_MODE, { - .ctv_enc_mode = { - .mode = { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, - 1920, 1961, 2049, 2200, 0, 1080, 1084, 1088, 1125, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC - | DRM_MODE_FLAG_INTERLACE) }, - .ctv_regs = { 0xac0420, 0x44c0478, 0x4a4, 0x4fc0868, - 0x8940028, 0x60054, 0xe80870, 0xbf70000, - 0xbc70004, 0x70005, 0x70012, 0x70013, - 0x40f0014, 0x70230, 0xbf70232, 0xbf70233, - 0x1c70237, 0x70238, 0x70244, 0x70245, - 0x40f0246, 0x70462, 0x1f70464, 0x0, - 0x2e40001, 0x58, 0x2e001e, 0x258012c, - 0xa0aa04ec, 0x30, 0x815f004c, 0x12c0300, - 0xc000204c, 0x600, 0x3206004c, 0x0, 0x0, 0x0 - } } } } -}; - -/* - * The following is some guesswork on how the TV encoder flicker - * filter/rescaler works: - * - * It seems to use some sort of resampling filter, it is controlled - * through the registers at NV_PTV_HFILTER and NV_PTV_VFILTER, they - * control the horizontal and vertical stage respectively, there is - * also NV_PTV_HFILTER2 the blob fills identically to NV_PTV_HFILTER, - * but they seem to do nothing. A rough guess might be that they could - * be used to independently control the filtering of each interlaced - * field, but I don't know how they are enabled. The whole filtering - * process seems to be disabled with bits 26:27 of PTV_200, but we - * aren't doing that. - * - * The layout of both register sets is the same: - * - * A: [BASE+0x18]...[BASE+0x0] [BASE+0x58]..[BASE+0x40] - * B: [BASE+0x34]...[BASE+0x1c] [BASE+0x74]..[BASE+0x5c] - * - * Each coefficient is stored in bits [31],[15:9] in two's complement - * format. They seem to be some kind of weights used in a low-pass - * filter. Both A and B coefficients are applied to the 14 nearest - * samples on each side (Listed from nearest to furthermost. They - * roughly cover 2 framebuffer pixels on each side). They are - * probably multiplied with some more hardwired weights before being - * used: B-coefficients are applied the same on both sides, - * A-coefficients are inverted before being applied to the opposite - * side. - * - * After all the hassle, I got the following formula by empirical - * means... - */ - -#define calc_overscan(o) interpolate(0x100, 0xe1, 0xc1, o) - -#define id1 (1LL << 8) -#define id2 (1LL << 16) -#define id3 (1LL << 24) -#define id4 (1LL << 32) -#define id5 (1LL << 48) - -static struct filter_params{ - int64_t k1; - int64_t ki; - int64_t ki2; - int64_t ki3; - int64_t kr; - int64_t kir; - int64_t ki2r; - int64_t ki3r; - int64_t kf; - int64_t kif; - int64_t ki2f; - int64_t ki3f; - int64_t krf; - int64_t kirf; - int64_t ki2rf; - int64_t ki3rf; -} fparams[2][4] = { - /* Horizontal filter parameters */ - { - {64.311690 * id5, -39.516924 * id5, 6.586143 * id5, 0.000002 * id5, - 0.051285 * id4, 26.168746 * id4, -4.361449 * id4, -0.000001 * id4, - 9.308169 * id3, 78.180965 * id3, -13.030158 * id3, -0.000001 * id3, - -8.801540 * id1, -46.572890 * id1, 7.762145 * id1, -0.000000 * id1}, - {-44.565569 * id5, -68.081246 * id5, 39.812074 * id5, -4.009316 * id5, - 29.832207 * id4, 50.047322 * id4, -25.380017 * id4, 2.546422 * id4, - 104.605622 * id3, 141.908641 * id3, -74.322319 * id3, 7.484316 * id3, - -37.081621 * id1, -90.397510 * id1, 42.784229 * id1, -4.289952 * id1}, - {-56.793244 * id5, 31.153584 * id5, -5.192247 * id5, -0.000003 * id5, - 33.541131 * id4, -34.149302 * id4, 5.691537 * id4, 0.000002 * id4, - 87.196610 * id3, -88.995169 * id3, 14.832456 * id3, 0.000012 * id3, - 17.288138 * id1, 71.864786 * id1, -11.977408 * id1, -0.000009 * id1}, - {51.787796 * id5, 21.211771 * id5, -18.993730 * id5, 1.853310 * id5, - -41.470726 * id4, -17.775823 * id4, 13.057821 * id4, -1.15823 * id4, - -154.235673 * id3, -44.878641 * id3, 40.656077 * id3, -3.695595 * id3, - 112.201065 * id1, 39.992155 * id1, -25.155714 * id1, 2.113984 * id1}, - }, - - /* Vertical filter parameters */ - { - {67.601979 * id5, 0.428319 * id5, -0.071318 * id5, -0.000012 * id5, - -3.402339 * id4, 0.000209 * id4, -0.000092 * id4, 0.000010 * id4, - -9.180996 * id3, 6.111270 * id3, -1.024457 * id3, 0.001043 * id3, - 6.060315 * id1, -0.017425 * id1, 0.007830 * id1, -0.000869 * id1}, - {6.755647 * id5, 5.841348 * id5, 1.469734 * id5, -0.149656 * id5, - 8.293120 * id4, -1.192888 * id4, -0.947652 * id4, 0.094507 * id4, - 37.526655 * id3, 10.257875 * id3, -10.823275 * id3, 1.081497 * id3, - -2.361928 * id1, -2.059432 * id1, 1.840671 * id1, -0.168100 * id1}, - {-14.780391 * id5, -16.042148 * id5, 2.673692 * id5, -0.000000 * id5, - 39.541978 * id4, 5.680053 * id4, -0.946676 * id4, 0.000000 * id4, - 152.994486 * id3, 12.625439 * id3, -2.119579 * id3, 0.002708 * id3, - -38.125089 * id1, -0.855880 * id1, 0.155359 * id1, -0.002245 * id1}, - {-27.476193 * id5, -1.454976 * id5, 1.286557 * id5, 0.025346 * id5, - 20.687300 * id4, 3.014003 * id4, -0.557786 * id4, -0.01311 * id4, - 60.008737 * id3, -0.738273 * id3, 5.408217 * id3, -0.796798 * id3, - -17.296835 * id1, 4.438577 * id1, -2.809420 * id1, 0.385491 * id1}, - } -}; - -static void tv_setup_filter(struct drm_encoder *encoder) -{ - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - struct drm_display_mode *mode = &encoder->crtc->mode; - uint32_t (*filters[])[4][7] = {&tv_enc->state.hfilter, - &tv_enc->state.vfilter}; - int i, j, k; - int32_t overscan = calc_overscan(tv_enc->overscan); - int64_t flicker = (tv_enc->flicker - 50) * (id3 / 100); - uint64_t rs[] = {mode->hdisplay * id3, - mode->vdisplay * id3}; - - do_div(rs[0], overscan * tv_norm->tv_enc_mode.hdisplay); - do_div(rs[1], overscan * tv_norm->tv_enc_mode.vdisplay); - - for (k = 0; k < 2; k++) { - rs[k] = max((int64_t)rs[k], id2); - - for (j = 0; j < 4; j++) { - struct filter_params *p = &fparams[k][j]; - - for (i = 0; i < 7; i++) { - int64_t c = (p->k1 + p->ki*i + p->ki2*i*i + - p->ki3*i*i*i) - + (p->kr + p->kir*i + p->ki2r*i*i + - p->ki3r*i*i*i) * rs[k] - + (p->kf + p->kif*i + p->ki2f*i*i + - p->ki3f*i*i*i) * flicker - + (p->krf + p->kirf*i + p->ki2rf*i*i + - p->ki3rf*i*i*i) * flicker * rs[k]; - - (*filters[k])[j][i] = (c + id5/2) >> 39 - & (0x1 << 31 | 0x7f << 9); - } - } - } -} - -/* Hardware state saving/restoring */ - -static void tv_save_filter(struct drm_device *dev, uint32_t base, - uint32_t regs[4][7]) -{ - int i, j; - uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c }; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 7; j++) - regs[i][j] = nv_read_ptv(dev, offsets[i]+4*j); - } -} - -static void tv_load_filter(struct drm_device *dev, uint32_t base, - uint32_t regs[4][7]) -{ - int i, j; - uint32_t offsets[] = { base, base + 0x1c, base + 0x40, base + 0x5c }; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 7; j++) - nv_write_ptv(dev, offsets[i]+4*j, regs[i][j]); - } -} - -void nv17_tv_state_save(struct drm_device *dev, struct nv17_tv_state *state) -{ - int i; - - for (i = 0; i < 0x40; i++) - state->tv_enc[i] = nv_read_tv_enc(dev, i); - - tv_save_filter(dev, NV_PTV_HFILTER, state->hfilter); - tv_save_filter(dev, NV_PTV_HFILTER2, state->hfilter2); - tv_save_filter(dev, NV_PTV_VFILTER, state->vfilter); - - nv_save_ptv(dev, state, 200); - nv_save_ptv(dev, state, 204); - nv_save_ptv(dev, state, 208); - nv_save_ptv(dev, state, 20c); - nv_save_ptv(dev, state, 304); - nv_save_ptv(dev, state, 500); - nv_save_ptv(dev, state, 504); - nv_save_ptv(dev, state, 508); - nv_save_ptv(dev, state, 600); - nv_save_ptv(dev, state, 604); - nv_save_ptv(dev, state, 608); - nv_save_ptv(dev, state, 60c); - nv_save_ptv(dev, state, 610); - nv_save_ptv(dev, state, 614); -} - -void nv17_tv_state_load(struct drm_device *dev, struct nv17_tv_state *state) -{ - int i; - - for (i = 0; i < 0x40; i++) - nv_write_tv_enc(dev, i, state->tv_enc[i]); - - tv_load_filter(dev, NV_PTV_HFILTER, state->hfilter); - tv_load_filter(dev, NV_PTV_HFILTER2, state->hfilter2); - tv_load_filter(dev, NV_PTV_VFILTER, state->vfilter); - - nv_load_ptv(dev, state, 200); - nv_load_ptv(dev, state, 204); - nv_load_ptv(dev, state, 208); - nv_load_ptv(dev, state, 20c); - nv_load_ptv(dev, state, 304); - nv_load_ptv(dev, state, 500); - nv_load_ptv(dev, state, 504); - nv_load_ptv(dev, state, 508); - nv_load_ptv(dev, state, 600); - nv_load_ptv(dev, state, 604); - nv_load_ptv(dev, state, 608); - nv_load_ptv(dev, state, 60c); - nv_load_ptv(dev, state, 610); - nv_load_ptv(dev, state, 614); - - /* This is required for some settings to kick in. */ - nv_write_tv_enc(dev, 0x3e, 1); - nv_write_tv_enc(dev, 0x3e, 0); -} - -/* Timings similar to the ones the blob sets */ - -const struct drm_display_mode nv17_tv_modes[] = { - { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 0, - 320, 344, 392, 560, 0, 200, 200, 202, 220, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC - | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) }, - { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 0, - 320, 344, 392, 560, 0, 240, 240, 246, 263, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC - | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) }, - { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 0, - 400, 432, 496, 640, 0, 300, 300, 303, 314, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC - | DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_CLKDIV2) }, - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 0, - 640, 672, 768, 880, 0, 480, 480, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 0, - 720, 752, 872, 960, 0, 480, 480, 493, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 0, - 720, 776, 856, 960, 0, 576, 576, 588, 597, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 0, - 800, 840, 920, 1040, 0, 600, 600, 604, 618, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 0, - 1024, 1064, 1200, 1344, 0, 768, 768, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - {} -}; - -void nv17_tv_update_properties(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - struct nv17_tv_state *regs = &tv_enc->state; - struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder); - int subconnector = tv_enc->select_subconnector ? - tv_enc->select_subconnector : - tv_enc->subconnector; - - switch (subconnector) { - case DRM_MODE_SUBCONNECTOR_Composite: - { - regs->ptv_204 = 0x2; - - /* The composite connector may be found on either pin. */ - if (tv_enc->pin_mask & 0x4) - regs->ptv_204 |= 0x010000; - else if (tv_enc->pin_mask & 0x2) - regs->ptv_204 |= 0x100000; - else - regs->ptv_204 |= 0x110000; - - regs->tv_enc[0x7] = 0x10; - break; - } - case DRM_MODE_SUBCONNECTOR_SVIDEO: - regs->ptv_204 = 0x11012; - regs->tv_enc[0x7] = 0x18; - break; - - case DRM_MODE_SUBCONNECTOR_Component: - regs->ptv_204 = 0x111333; - regs->tv_enc[0x7] = 0x14; - break; - - case DRM_MODE_SUBCONNECTOR_SCART: - regs->ptv_204 = 0x111012; - regs->tv_enc[0x7] = 0x18; - break; - } - - regs->tv_enc[0x20] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x20], - 255, tv_enc->saturation); - regs->tv_enc[0x22] = interpolate(0, tv_norm->tv_enc_mode.tv_enc[0x22], - 255, tv_enc->saturation); - regs->tv_enc[0x25] = tv_enc->hue * 255 / 100; - - nv_load_ptv(dev, regs, 204); - nv_load_tv_enc(dev, regs, 7); - nv_load_tv_enc(dev, regs, 20); - nv_load_tv_enc(dev, regs, 22); - nv_load_tv_enc(dev, regs, 25); -} - -void nv17_tv_update_rescaler(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - struct nv17_tv_state *regs = &tv_enc->state; - - regs->ptv_208 = 0x40 | (calc_overscan(tv_enc->overscan) << 8); - - tv_setup_filter(encoder); - - nv_load_ptv(dev, regs, 208); - tv_load_filter(dev, NV_PTV_HFILTER, regs->hfilter); - tv_load_filter(dev, NV_PTV_HFILTER2, regs->hfilter2); - tv_load_filter(dev, NV_PTV_VFILTER, regs->vfilter); -} - -void nv17_ctv_update_rescaler(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder); - int head = nouveau_crtc(encoder->crtc)->index; - struct nv04_crtc_reg *regs = &dev_priv->mode_reg.crtc_reg[head]; - struct drm_display_mode *crtc_mode = &encoder->crtc->mode; - struct drm_display_mode *output_mode = - &get_tv_norm(encoder)->ctv_enc_mode.mode; - int overscan, hmargin, vmargin, hratio, vratio; - - /* The rescaler doesn't do the right thing for interlaced modes. */ - if (output_mode->flags & DRM_MODE_FLAG_INTERLACE) - overscan = 100; - else - overscan = tv_enc->overscan; - - hmargin = (output_mode->hdisplay - crtc_mode->hdisplay) / 2; - vmargin = (output_mode->vdisplay - crtc_mode->vdisplay) / 2; - - hmargin = interpolate(0, min(hmargin, output_mode->hdisplay/20), - hmargin, overscan); - vmargin = interpolate(0, min(vmargin, output_mode->vdisplay/20), - vmargin, overscan); - - hratio = crtc_mode->hdisplay * 0x800 / - (output_mode->hdisplay - 2*hmargin); - vratio = crtc_mode->vdisplay * 0x800 / - (output_mode->vdisplay - 2*vmargin) & ~3; - - regs->fp_horiz_regs[FP_VALID_START] = hmargin; - regs->fp_horiz_regs[FP_VALID_END] = output_mode->hdisplay - hmargin - 1; - regs->fp_vert_regs[FP_VALID_START] = vmargin; - regs->fp_vert_regs[FP_VALID_END] = output_mode->vdisplay - vmargin - 1; - - regs->fp_debug_1 = NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE | - XLATE(vratio, 0, NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE) | - NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE | - XLATE(hratio, 0, NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE); - - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_START, - regs->fp_horiz_regs[FP_VALID_START]); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_HVALID_END, - regs->fp_horiz_regs[FP_VALID_END]); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_START, - regs->fp_vert_regs[FP_VALID_START]); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_VVALID_END, - regs->fp_vert_regs[FP_VALID_END]); - NVWriteRAMDAC(dev, head, NV_PRAMDAC_FP_DEBUG_1, regs->fp_debug_1); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_fb.c deleted file mode 100644 index 19bd6405..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_fb.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -static struct drm_mm_node * -nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct drm_mm_node *mem; - int ret; - - ret = drm_mm_pre_get(&pfb->tag_heap); - if (ret) - return NULL; - - spin_lock(&dev_priv->tile.lock); - mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0); - if (mem) - mem = drm_mm_get_block_atomic(mem, size, 0); - spin_unlock(&dev_priv->tile.lock); - - return mem; -} - -static void -nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node **pmem) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct drm_mm_node *mem = *pmem; - if (mem) { - spin_lock(&dev_priv->tile.lock); - drm_mm_put_block(mem); - spin_unlock(&dev_priv->tile.lock); - *pmem = NULL; - } -} - -void -nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch, uint32_t flags) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - int bpp = (flags & NOUVEAU_GEM_TILE_32BPP ? 32 : 16); - - tile->addr = 0x00000001 | addr; - tile->limit = max(1u, addr + size) - 1; - tile->pitch = pitch; - - /* Allocate some of the on-die tag memory, used to store Z - * compression meta-data (most likely just a bitmap determining - * if a given tile is compressed or not). - */ - if (flags & NOUVEAU_GEM_TILE_ZETA) { - tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256); - if (tile->tag_mem) { - /* Enable Z compression */ - tile->zcomp = tile->tag_mem->start; - if (dev_priv->chipset >= 0x25) { - if (bpp == 16) - tile->zcomp |= NV25_PFB_ZCOMP_MODE_16; - else - tile->zcomp |= NV25_PFB_ZCOMP_MODE_32; - } else { - tile->zcomp |= NV20_PFB_ZCOMP_EN; - if (bpp != 16) - tile->zcomp |= NV20_PFB_ZCOMP_MODE_32; - } - } - - tile->addr |= 2; - } -} - -void -nv20_fb_free_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - tile->addr = tile->limit = tile->pitch = tile->zcomp = 0; - nv20_fb_free_tag(dev, &tile->tag_mem); -} - -void -nv20_fb_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); - nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); - nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); - nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp); -} - -int -nv20_fb_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 mem_size = nv_rd32(dev, 0x10020c); - u32 pbus1218 = nv_rd32(dev, 0x001218); - - dev_priv->vram_size = mem_size & 0xff000000; - switch (pbus1218 & 0x00000300) { - case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; - case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; - case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; - case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_GDDR2; break; - } - - return 0; -} - -int -nv20_fb_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int i; - - if (dev_priv->chipset >= 0x25) - drm_mm_init(&pfb->tag_heap, 0, 64 * 1024); - else - drm_mm_init(&pfb->tag_heap, 0, 32 * 1024); - - /* Turn all the tiling regions off. */ - pfb->num_tiles = NV10_PFB_TILE__SIZE; - for (i = 0; i < pfb->num_tiles; i++) - pfb->set_tile_region(dev, i); - - return 0; -} - -void -nv20_fb_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int i; - - for (i = 0; i < pfb->num_tiles; i++) - pfb->free_tile_region(dev, i); - - drm_mm_takedown(&pfb->tag_heap); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_graph.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_graph.c deleted file mode 100644 index 183e3751..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv20_graph.c +++ /dev/null @@ -1,842 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -/* - * NV20 - * ----- - * There are 3 families : - * NV20 is 0x10de:0x020* - * NV25/28 is 0x10de:0x025* / 0x10de:0x028* - * NV2A is 0x10de:0x02A0 - * - * NV30 - * ----- - * There are 3 families : - * NV30/31 is 0x10de:0x030* / 0x10de:0x031* - * NV34 is 0x10de:0x032* - * NV35/36 is 0x10de:0x033* / 0x10de:0x034* - * - * Not seen in the wild, no dumps (probably NV35) : - * NV37 is 0x10de:0x00fc, 0x10de:0x00fd - * NV38 is 0x10de:0x0333, 0x10de:0x00fe - * - */ - -struct nv20_graph_engine { - struct nouveau_exec_engine base; - struct nouveau_gpuobj *ctxtab; - void (*grctx_init)(struct nouveau_gpuobj *); - u32 grctx_size; - u32 grctx_user; -}; - -#define NV20_GRCTX_SIZE (3580*4) -#define NV25_GRCTX_SIZE (3529*4) -#define NV2A_GRCTX_SIZE (3500*4) - -#define NV30_31_GRCTX_SIZE (24392) -#define NV34_GRCTX_SIZE (18140) -#define NV35_36_GRCTX_SIZE (22396) - -int -nv20_graph_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_channel *chan; - struct nouveau_gpuobj *grctx; - u32 tmp; - - chan = nv10_graph_channel(dev); - if (!chan) - return 0; - grctx = chan->engctx[NVOBJ_ENGINE_GR]; - - nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, grctx->pinst >> 4); - nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER, - NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE); - - nouveau_wait_for_idle(dev); - - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000); - tmp = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff; - tmp |= (pfifo->channels - 1) << 24; - nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp); - return 0; -} - -static void -nv20_graph_rdi(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i, writecount = 32; - uint32_t rdi_index = 0x2c80000; - - if (dev_priv->chipset == 0x20) { - rdi_index = 0x3d0000; - writecount = 15; - } - - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index); - for (i = 0; i < writecount; i++) - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0); - - nouveau_wait_for_idle(dev); -} - -static void -nv20_graph_context_init(struct nouveau_gpuobj *ctx) -{ - int i; - - nv_wo32(ctx, 0x033c, 0xffff0000); - nv_wo32(ctx, 0x03a0, 0x0fff0000); - nv_wo32(ctx, 0x03a4, 0x0fff0000); - nv_wo32(ctx, 0x047c, 0x00000101); - nv_wo32(ctx, 0x0490, 0x00000111); - nv_wo32(ctx, 0x04a8, 0x44400000); - for (i = 0x04d4; i <= 0x04e0; i += 4) - nv_wo32(ctx, i, 0x00030303); - for (i = 0x04f4; i <= 0x0500; i += 4) - nv_wo32(ctx, i, 0x00080000); - for (i = 0x050c; i <= 0x0518; i += 4) - nv_wo32(ctx, i, 0x01012000); - for (i = 0x051c; i <= 0x0528; i += 4) - nv_wo32(ctx, i, 0x000105b8); - for (i = 0x052c; i <= 0x0538; i += 4) - nv_wo32(ctx, i, 0x00080008); - for (i = 0x055c; i <= 0x0598; i += 4) - nv_wo32(ctx, i, 0x07ff0000); - nv_wo32(ctx, 0x05a4, 0x4b7fffff); - nv_wo32(ctx, 0x05fc, 0x00000001); - nv_wo32(ctx, 0x0604, 0x00004000); - nv_wo32(ctx, 0x0610, 0x00000001); - nv_wo32(ctx, 0x0618, 0x00040000); - nv_wo32(ctx, 0x061c, 0x00010000); - for (i = 0x1c1c; i <= 0x248c; i += 16) { - nv_wo32(ctx, (i + 0), 0x10700ff9); - nv_wo32(ctx, (i + 4), 0x0436086c); - nv_wo32(ctx, (i + 8), 0x000c001b); - } - nv_wo32(ctx, 0x281c, 0x3f800000); - nv_wo32(ctx, 0x2830, 0x3f800000); - nv_wo32(ctx, 0x285c, 0x40000000); - nv_wo32(ctx, 0x2860, 0x3f800000); - nv_wo32(ctx, 0x2864, 0x3f000000); - nv_wo32(ctx, 0x286c, 0x40000000); - nv_wo32(ctx, 0x2870, 0x3f800000); - nv_wo32(ctx, 0x2878, 0xbf800000); - nv_wo32(ctx, 0x2880, 0xbf800000); - nv_wo32(ctx, 0x34a4, 0x000fe000); - nv_wo32(ctx, 0x3530, 0x000003f8); - nv_wo32(ctx, 0x3540, 0x002fe000); - for (i = 0x355c; i <= 0x3578; i += 4) - nv_wo32(ctx, i, 0x001c527c); -} - -static void -nv25_graph_context_init(struct nouveau_gpuobj *ctx) -{ - int i; - - nv_wo32(ctx, 0x035c, 0xffff0000); - nv_wo32(ctx, 0x03c0, 0x0fff0000); - nv_wo32(ctx, 0x03c4, 0x0fff0000); - nv_wo32(ctx, 0x049c, 0x00000101); - nv_wo32(ctx, 0x04b0, 0x00000111); - nv_wo32(ctx, 0x04c8, 0x00000080); - nv_wo32(ctx, 0x04cc, 0xffff0000); - nv_wo32(ctx, 0x04d0, 0x00000001); - nv_wo32(ctx, 0x04e4, 0x44400000); - nv_wo32(ctx, 0x04fc, 0x4b800000); - for (i = 0x0510; i <= 0x051c; i += 4) - nv_wo32(ctx, i, 0x00030303); - for (i = 0x0530; i <= 0x053c; i += 4) - nv_wo32(ctx, i, 0x00080000); - for (i = 0x0548; i <= 0x0554; i += 4) - nv_wo32(ctx, i, 0x01012000); - for (i = 0x0558; i <= 0x0564; i += 4) - nv_wo32(ctx, i, 0x000105b8); - for (i = 0x0568; i <= 0x0574; i += 4) - nv_wo32(ctx, i, 0x00080008); - for (i = 0x0598; i <= 0x05d4; i += 4) - nv_wo32(ctx, i, 0x07ff0000); - nv_wo32(ctx, 0x05e0, 0x4b7fffff); - nv_wo32(ctx, 0x0620, 0x00000080); - nv_wo32(ctx, 0x0624, 0x30201000); - nv_wo32(ctx, 0x0628, 0x70605040); - nv_wo32(ctx, 0x062c, 0xb0a09080); - nv_wo32(ctx, 0x0630, 0xf0e0d0c0); - nv_wo32(ctx, 0x0664, 0x00000001); - nv_wo32(ctx, 0x066c, 0x00004000); - nv_wo32(ctx, 0x0678, 0x00000001); - nv_wo32(ctx, 0x0680, 0x00040000); - nv_wo32(ctx, 0x0684, 0x00010000); - for (i = 0x1b04; i <= 0x2374; i += 16) { - nv_wo32(ctx, (i + 0), 0x10700ff9); - nv_wo32(ctx, (i + 4), 0x0436086c); - nv_wo32(ctx, (i + 8), 0x000c001b); - } - nv_wo32(ctx, 0x2704, 0x3f800000); - nv_wo32(ctx, 0x2718, 0x3f800000); - nv_wo32(ctx, 0x2744, 0x40000000); - nv_wo32(ctx, 0x2748, 0x3f800000); - nv_wo32(ctx, 0x274c, 0x3f000000); - nv_wo32(ctx, 0x2754, 0x40000000); - nv_wo32(ctx, 0x2758, 0x3f800000); - nv_wo32(ctx, 0x2760, 0xbf800000); - nv_wo32(ctx, 0x2768, 0xbf800000); - nv_wo32(ctx, 0x308c, 0x000fe000); - nv_wo32(ctx, 0x3108, 0x000003f8); - nv_wo32(ctx, 0x3468, 0x002fe000); - for (i = 0x3484; i <= 0x34a0; i += 4) - nv_wo32(ctx, i, 0x001c527c); -} - -static void -nv2a_graph_context_init(struct nouveau_gpuobj *ctx) -{ - int i; - - nv_wo32(ctx, 0x033c, 0xffff0000); - nv_wo32(ctx, 0x03a0, 0x0fff0000); - nv_wo32(ctx, 0x03a4, 0x0fff0000); - nv_wo32(ctx, 0x047c, 0x00000101); - nv_wo32(ctx, 0x0490, 0x00000111); - nv_wo32(ctx, 0x04a8, 0x44400000); - for (i = 0x04d4; i <= 0x04e0; i += 4) - nv_wo32(ctx, i, 0x00030303); - for (i = 0x04f4; i <= 0x0500; i += 4) - nv_wo32(ctx, i, 0x00080000); - for (i = 0x050c; i <= 0x0518; i += 4) - nv_wo32(ctx, i, 0x01012000); - for (i = 0x051c; i <= 0x0528; i += 4) - nv_wo32(ctx, i, 0x000105b8); - for (i = 0x052c; i <= 0x0538; i += 4) - nv_wo32(ctx, i, 0x00080008); - for (i = 0x055c; i <= 0x0598; i += 4) - nv_wo32(ctx, i, 0x07ff0000); - nv_wo32(ctx, 0x05a4, 0x4b7fffff); - nv_wo32(ctx, 0x05fc, 0x00000001); - nv_wo32(ctx, 0x0604, 0x00004000); - nv_wo32(ctx, 0x0610, 0x00000001); - nv_wo32(ctx, 0x0618, 0x00040000); - nv_wo32(ctx, 0x061c, 0x00010000); - for (i = 0x1a9c; i <= 0x22fc; i += 16) { /*XXX: check!! */ - nv_wo32(ctx, (i + 0), 0x10700ff9); - nv_wo32(ctx, (i + 4), 0x0436086c); - nv_wo32(ctx, (i + 8), 0x000c001b); - } - nv_wo32(ctx, 0x269c, 0x3f800000); - nv_wo32(ctx, 0x26b0, 0x3f800000); - nv_wo32(ctx, 0x26dc, 0x40000000); - nv_wo32(ctx, 0x26e0, 0x3f800000); - nv_wo32(ctx, 0x26e4, 0x3f000000); - nv_wo32(ctx, 0x26ec, 0x40000000); - nv_wo32(ctx, 0x26f0, 0x3f800000); - nv_wo32(ctx, 0x26f8, 0xbf800000); - nv_wo32(ctx, 0x2700, 0xbf800000); - nv_wo32(ctx, 0x3024, 0x000fe000); - nv_wo32(ctx, 0x30a0, 0x000003f8); - nv_wo32(ctx, 0x33fc, 0x002fe000); - for (i = 0x341c; i <= 0x3438; i += 4) - nv_wo32(ctx, i, 0x001c527c); -} - -static void -nv30_31_graph_context_init(struct nouveau_gpuobj *ctx) -{ - int i; - - nv_wo32(ctx, 0x0410, 0x00000101); - nv_wo32(ctx, 0x0424, 0x00000111); - nv_wo32(ctx, 0x0428, 0x00000060); - nv_wo32(ctx, 0x0444, 0x00000080); - nv_wo32(ctx, 0x0448, 0xffff0000); - nv_wo32(ctx, 0x044c, 0x00000001); - nv_wo32(ctx, 0x0460, 0x44400000); - nv_wo32(ctx, 0x048c, 0xffff0000); - for (i = 0x04e0; i < 0x04e8; i += 4) - nv_wo32(ctx, i, 0x0fff0000); - nv_wo32(ctx, 0x04ec, 0x00011100); - for (i = 0x0508; i < 0x0548; i += 4) - nv_wo32(ctx, i, 0x07ff0000); - nv_wo32(ctx, 0x0550, 0x4b7fffff); - nv_wo32(ctx, 0x058c, 0x00000080); - nv_wo32(ctx, 0x0590, 0x30201000); - nv_wo32(ctx, 0x0594, 0x70605040); - nv_wo32(ctx, 0x0598, 0xb8a89888); - nv_wo32(ctx, 0x059c, 0xf8e8d8c8); - nv_wo32(ctx, 0x05b0, 0xb0000000); - for (i = 0x0600; i < 0x0640; i += 4) - nv_wo32(ctx, i, 0x00010588); - for (i = 0x0640; i < 0x0680; i += 4) - nv_wo32(ctx, i, 0x00030303); - for (i = 0x06c0; i < 0x0700; i += 4) - nv_wo32(ctx, i, 0x0008aae4); - for (i = 0x0700; i < 0x0740; i += 4) - nv_wo32(ctx, i, 0x01012000); - for (i = 0x0740; i < 0x0780; i += 4) - nv_wo32(ctx, i, 0x00080008); - nv_wo32(ctx, 0x085c, 0x00040000); - nv_wo32(ctx, 0x0860, 0x00010000); - for (i = 0x0864; i < 0x0874; i += 4) - nv_wo32(ctx, i, 0x00040004); - for (i = 0x1f18; i <= 0x3088 ; i += 16) { - nv_wo32(ctx, i + 0, 0x10700ff9); - nv_wo32(ctx, i + 1, 0x0436086c); - nv_wo32(ctx, i + 2, 0x000c001b); - } - for (i = 0x30b8; i < 0x30c8; i += 4) - nv_wo32(ctx, i, 0x0000ffff); - nv_wo32(ctx, 0x344c, 0x3f800000); - nv_wo32(ctx, 0x3808, 0x3f800000); - nv_wo32(ctx, 0x381c, 0x3f800000); - nv_wo32(ctx, 0x3848, 0x40000000); - nv_wo32(ctx, 0x384c, 0x3f800000); - nv_wo32(ctx, 0x3850, 0x3f000000); - nv_wo32(ctx, 0x3858, 0x40000000); - nv_wo32(ctx, 0x385c, 0x3f800000); - nv_wo32(ctx, 0x3864, 0xbf800000); - nv_wo32(ctx, 0x386c, 0xbf800000); -} - -static void -nv34_graph_context_init(struct nouveau_gpuobj *ctx) -{ - int i; - - nv_wo32(ctx, 0x040c, 0x01000101); - nv_wo32(ctx, 0x0420, 0x00000111); - nv_wo32(ctx, 0x0424, 0x00000060); - nv_wo32(ctx, 0x0440, 0x00000080); - nv_wo32(ctx, 0x0444, 0xffff0000); - nv_wo32(ctx, 0x0448, 0x00000001); - nv_wo32(ctx, 0x045c, 0x44400000); - nv_wo32(ctx, 0x0480, 0xffff0000); - for (i = 0x04d4; i < 0x04dc; i += 4) - nv_wo32(ctx, i, 0x0fff0000); - nv_wo32(ctx, 0x04e0, 0x00011100); - for (i = 0x04fc; i < 0x053c; i += 4) - nv_wo32(ctx, i, 0x07ff0000); - nv_wo32(ctx, 0x0544, 0x4b7fffff); - nv_wo32(ctx, 0x057c, 0x00000080); - nv_wo32(ctx, 0x0580, 0x30201000); - nv_wo32(ctx, 0x0584, 0x70605040); - nv_wo32(ctx, 0x0588, 0xb8a89888); - nv_wo32(ctx, 0x058c, 0xf8e8d8c8); - nv_wo32(ctx, 0x05a0, 0xb0000000); - for (i = 0x05f0; i < 0x0630; i += 4) - nv_wo32(ctx, i, 0x00010588); - for (i = 0x0630; i < 0x0670; i += 4) - nv_wo32(ctx, i, 0x00030303); - for (i = 0x06b0; i < 0x06f0; i += 4) - nv_wo32(ctx, i, 0x0008aae4); - for (i = 0x06f0; i < 0x0730; i += 4) - nv_wo32(ctx, i, 0x01012000); - for (i = 0x0730; i < 0x0770; i += 4) - nv_wo32(ctx, i, 0x00080008); - nv_wo32(ctx, 0x0850, 0x00040000); - nv_wo32(ctx, 0x0854, 0x00010000); - for (i = 0x0858; i < 0x0868; i += 4) - nv_wo32(ctx, i, 0x00040004); - for (i = 0x15ac; i <= 0x271c ; i += 16) { - nv_wo32(ctx, i + 0, 0x10700ff9); - nv_wo32(ctx, i + 1, 0x0436086c); - nv_wo32(ctx, i + 2, 0x000c001b); - } - for (i = 0x274c; i < 0x275c; i += 4) - nv_wo32(ctx, i, 0x0000ffff); - nv_wo32(ctx, 0x2ae0, 0x3f800000); - nv_wo32(ctx, 0x2e9c, 0x3f800000); - nv_wo32(ctx, 0x2eb0, 0x3f800000); - nv_wo32(ctx, 0x2edc, 0x40000000); - nv_wo32(ctx, 0x2ee0, 0x3f800000); - nv_wo32(ctx, 0x2ee4, 0x3f000000); - nv_wo32(ctx, 0x2eec, 0x40000000); - nv_wo32(ctx, 0x2ef0, 0x3f800000); - nv_wo32(ctx, 0x2ef8, 0xbf800000); - nv_wo32(ctx, 0x2f00, 0xbf800000); -} - -static void -nv35_36_graph_context_init(struct nouveau_gpuobj *ctx) -{ - int i; - - nv_wo32(ctx, 0x040c, 0x00000101); - nv_wo32(ctx, 0x0420, 0x00000111); - nv_wo32(ctx, 0x0424, 0x00000060); - nv_wo32(ctx, 0x0440, 0x00000080); - nv_wo32(ctx, 0x0444, 0xffff0000); - nv_wo32(ctx, 0x0448, 0x00000001); - nv_wo32(ctx, 0x045c, 0x44400000); - nv_wo32(ctx, 0x0488, 0xffff0000); - for (i = 0x04dc; i < 0x04e4; i += 4) - nv_wo32(ctx, i, 0x0fff0000); - nv_wo32(ctx, 0x04e8, 0x00011100); - for (i = 0x0504; i < 0x0544; i += 4) - nv_wo32(ctx, i, 0x07ff0000); - nv_wo32(ctx, 0x054c, 0x4b7fffff); - nv_wo32(ctx, 0x0588, 0x00000080); - nv_wo32(ctx, 0x058c, 0x30201000); - nv_wo32(ctx, 0x0590, 0x70605040); - nv_wo32(ctx, 0x0594, 0xb8a89888); - nv_wo32(ctx, 0x0598, 0xf8e8d8c8); - nv_wo32(ctx, 0x05ac, 0xb0000000); - for (i = 0x0604; i < 0x0644; i += 4) - nv_wo32(ctx, i, 0x00010588); - for (i = 0x0644; i < 0x0684; i += 4) - nv_wo32(ctx, i, 0x00030303); - for (i = 0x06c4; i < 0x0704; i += 4) - nv_wo32(ctx, i, 0x0008aae4); - for (i = 0x0704; i < 0x0744; i += 4) - nv_wo32(ctx, i, 0x01012000); - for (i = 0x0744; i < 0x0784; i += 4) - nv_wo32(ctx, i, 0x00080008); - nv_wo32(ctx, 0x0860, 0x00040000); - nv_wo32(ctx, 0x0864, 0x00010000); - for (i = 0x0868; i < 0x0878; i += 4) - nv_wo32(ctx, i, 0x00040004); - for (i = 0x1f1c; i <= 0x308c ; i += 16) { - nv_wo32(ctx, i + 0, 0x10700ff9); - nv_wo32(ctx, i + 4, 0x0436086c); - nv_wo32(ctx, i + 8, 0x000c001b); - } - for (i = 0x30bc; i < 0x30cc; i += 4) - nv_wo32(ctx, i, 0x0000ffff); - nv_wo32(ctx, 0x3450, 0x3f800000); - nv_wo32(ctx, 0x380c, 0x3f800000); - nv_wo32(ctx, 0x3820, 0x3f800000); - nv_wo32(ctx, 0x384c, 0x40000000); - nv_wo32(ctx, 0x3850, 0x3f800000); - nv_wo32(ctx, 0x3854, 0x3f000000); - nv_wo32(ctx, 0x385c, 0x40000000); - nv_wo32(ctx, 0x3860, 0x3f800000); - nv_wo32(ctx, 0x3868, 0xbf800000); - nv_wo32(ctx, 0x3870, 0xbf800000); -} - -int -nv20_graph_context_new(struct nouveau_channel *chan, int engine) -{ - struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine); - struct nouveau_gpuobj *grctx = NULL; - struct drm_device *dev = chan->dev; - int ret; - - ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16, - NVOBJ_FLAG_ZERO_ALLOC, &grctx); - if (ret) - return ret; - - /* Initialise default context values */ - pgraph->grctx_init(grctx); - - /* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */ - /* CTX_USER */ - nv_wo32(grctx, pgraph->grctx_user, (chan->id << 24) | 0x1); - - nv_wo32(pgraph->ctxtab, chan->id * 4, grctx->pinst >> 4); - chan->engctx[engine] = grctx; - return 0; -} - -void -nv20_graph_context_del(struct nouveau_channel *chan, int engine) -{ - struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine); - struct nouveau_gpuobj *grctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - - /* Unload the context if it's the currently active one */ - if (nv10_graph_channel(dev) == chan) - nv20_graph_unload_context(dev); - - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the context resources */ - nv_wo32(pgraph->ctxtab, chan->id * 4, 0); - - nouveau_gpuobj_ref(NULL, &grctx); - chan->engctx[engine] = NULL; -} - -static void -nv20_graph_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); - - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->limit); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->pitch); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->addr); - - if (dev_priv->card_type == NV_20) { - nv_wr32(dev, NV20_PGRAPH_ZCOMP(i), tile->zcomp); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->zcomp); - } -} - -int -nv20_graph_init(struct drm_device *dev, int engine) -{ - struct nv20_graph_engine *pgraph = nv_engine(dev, engine); - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t tmp, vramsz; - int i; - - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - - nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4); - - nv20_graph_rdi(dev); - - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); - nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x00118700); - nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xF3CE0475); /* 0x4 = auto ctx switch */ - nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00000000); - nv_wr32(dev, 0x40009C , 0x00000040); - - if (dev_priv->chipset >= 0x25) { - nv_wr32(dev, 0x400890, 0x00a8cfff); - nv_wr32(dev, 0x400610, 0x304B1FB6); - nv_wr32(dev, 0x400B80, 0x1cbd3883); - nv_wr32(dev, 0x400B84, 0x44000000); - nv_wr32(dev, 0x400098, 0x40000080); - nv_wr32(dev, 0x400B88, 0x000000ff); - - } else { - nv_wr32(dev, 0x400880, 0x0008c7df); - nv_wr32(dev, 0x400094, 0x00000005); - nv_wr32(dev, 0x400B80, 0x45eae20e); - nv_wr32(dev, 0x400B84, 0x24000000); - nv_wr32(dev, 0x400098, 0x00000040); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E10038); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000030); - } - - /* Turn all the tiling regions off. */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) - nv20_graph_set_tile_region(dev, i); - - nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324)); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324)); - - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); - nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); - - tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) & 0x0007ff00; - nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); - tmp = nv_rd32(dev, NV10_PGRAPH_SURFACE) | 0x00020100; - nv_wr32(dev, NV10_PGRAPH_SURFACE, tmp); - - /* begin RAM config */ - vramsz = pci_resource_len(dev->pdev, 0) - 1; - nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , nv_rd32(dev, NV04_PFB_CFG1)); - nv_wr32(dev, 0x400820, 0); - nv_wr32(dev, 0x400824, 0); - nv_wr32(dev, 0x400864, vramsz - 1); - nv_wr32(dev, 0x400868, vramsz - 1); - - /* interesting.. the below overwrites some of the tile setup above.. */ - nv_wr32(dev, 0x400B20, 0x00000000); - nv_wr32(dev, 0x400B04, 0xFFFFFFFF); - - nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMIN, 0); - nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMIN, 0); - nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff); - nv_wr32(dev, NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff); - - return 0; -} - -int -nv30_graph_init(struct drm_device *dev, int engine) -{ - struct nv20_graph_engine *pgraph = nv_engine(dev, engine); - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i; - - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); - - nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4); - - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); - - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); - nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0); - nv_wr32(dev, 0x400890, 0x01b463ff); - nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xf2de0475); - nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000); - nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04bdff6); - nv_wr32(dev, 0x400B80, 0x1003d888); - nv_wr32(dev, 0x400B84, 0x0c000000); - nv_wr32(dev, 0x400098, 0x00000000); - nv_wr32(dev, 0x40009C, 0x0005ad00); - nv_wr32(dev, 0x400B88, 0x62ff00ff); /* suspiciously like PGRAPH_DEBUG_2 */ - nv_wr32(dev, 0x4000a0, 0x00000000); - nv_wr32(dev, 0x4000a4, 0x00000008); - nv_wr32(dev, 0x4008a8, 0xb784a400); - nv_wr32(dev, 0x400ba0, 0x002f8685); - nv_wr32(dev, 0x400ba4, 0x00231f3f); - nv_wr32(dev, 0x4008a4, 0x40000020); - - if (dev_priv->chipset == 0x34) { - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0004); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00200201); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0008); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000008); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000032); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00004); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA , 0x00000002); - } - - nv_wr32(dev, 0x4000c0, 0x00000016); - - /* Turn all the tiling regions off. */ - for (i = 0; i < NV10_PFB_TILE__SIZE; i++) - nv20_graph_set_tile_region(dev, i); - - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); - nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); - nv_wr32(dev, 0x0040075c , 0x00000001); - - /* begin RAM config */ - /* vramsz = pci_resource_len(dev->pdev, 0) - 1; */ - nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); - if (dev_priv->chipset != 0x34) { - nv_wr32(dev, 0x400750, 0x00EA0000); - nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x400750, 0x00EA0004); - nv_wr32(dev, 0x400754, nv_rd32(dev, NV04_PFB_CFG1)); - } - - return 0; -} - -int -nv20_graph_fini(struct drm_device *dev, int engine, bool suspend) -{ - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000); - if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) { - nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001); - return -EBUSY; - } - nv20_graph_unload_context(dev); - nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); - return 0; -} - -static void -nv20_graph_isr(struct drm_device *dev) -{ - u32 stat; - - while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { - u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); - u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); - u32 chid = (addr & 0x01f00000) >> 20; - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00001ffc); - u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); - u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff; - u32 show = stat; - - if (stat & NV_PGRAPH_INTR_ERROR) { - if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { - if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) - show &= ~NV_PGRAPH_INTR_ERROR; - } - } - - nv_wr32(dev, NV03_PGRAPH_INTR, stat); - nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); - - if (show && nouveau_ratelimit()) { - NV_INFO(dev, "PGRAPH -"); - nouveau_bitfield_print(nv10_graph_intr, show); - printk(" nsource:"); - nouveau_bitfield_print(nv04_graph_nsource, nsource); - printk(" nstatus:"); - nouveau_bitfield_print(nv10_graph_nstatus, nstatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " - "mthd 0x%04x data 0x%08x\n", - chid, subc, class, mthd, data); - } - } -} - -static void -nv20_graph_destroy(struct drm_device *dev, int engine) -{ - struct nv20_graph_engine *pgraph = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 12); - nouveau_gpuobj_ref(NULL, &pgraph->ctxtab); - - NVOBJ_ENGINE_DEL(dev, GR); - kfree(pgraph); -} - -int -nv20_graph_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv20_graph_engine *pgraph; - int ret; - - pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); - if (!pgraph) - return -ENOMEM; - - pgraph->base.destroy = nv20_graph_destroy; - pgraph->base.fini = nv20_graph_fini; - pgraph->base.context_new = nv20_graph_context_new; - pgraph->base.context_del = nv20_graph_context_del; - pgraph->base.object_new = nv04_graph_object_new; - pgraph->base.set_tile_region = nv20_graph_set_tile_region; - - pgraph->grctx_user = 0x0028; - if (dev_priv->card_type == NV_20) { - pgraph->base.init = nv20_graph_init; - switch (dev_priv->chipset) { - case 0x20: - pgraph->grctx_init = nv20_graph_context_init; - pgraph->grctx_size = NV20_GRCTX_SIZE; - pgraph->grctx_user = 0x0000; - break; - case 0x25: - case 0x28: - pgraph->grctx_init = nv25_graph_context_init; - pgraph->grctx_size = NV25_GRCTX_SIZE; - break; - case 0x2a: - pgraph->grctx_init = nv2a_graph_context_init; - pgraph->grctx_size = NV2A_GRCTX_SIZE; - pgraph->grctx_user = 0x0000; - break; - default: - NV_ERROR(dev, "PGRAPH: unknown chipset\n"); - kfree(pgraph); - return 0; - } - } else { - pgraph->base.init = nv30_graph_init; - switch (dev_priv->chipset) { - case 0x30: - case 0x31: - pgraph->grctx_init = nv30_31_graph_context_init; - pgraph->grctx_size = NV30_31_GRCTX_SIZE; - break; - case 0x34: - pgraph->grctx_init = nv34_graph_context_init; - pgraph->grctx_size = NV34_GRCTX_SIZE; - break; - case 0x35: - case 0x36: - pgraph->grctx_init = nv35_36_graph_context_init; - pgraph->grctx_size = NV35_36_GRCTX_SIZE; - break; - default: - NV_ERROR(dev, "PGRAPH: unknown chipset\n"); - kfree(pgraph); - return 0; - } - } - - /* Create Context Pointer Table */ - ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC, - &pgraph->ctxtab); - if (ret) { - kfree(pgraph); - return ret; - } - - NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); - nouveau_irq_register(dev, 12, nv20_graph_isr); - - /* nvsw */ - NVOBJ_CLASS(dev, 0x506e, SW); - NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); - - NVOBJ_CLASS(dev, 0x0030, GR); /* null */ - NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ - NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ - NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ - NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ - NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ - NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ - NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ - NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ - NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ - NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ - NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ - if (dev_priv->card_type == NV_20) { - NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */ - NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */ - - /* kelvin */ - if (dev_priv->chipset < 0x25) - NVOBJ_CLASS(dev, 0x0097, GR); - else - NVOBJ_CLASS(dev, 0x0597, GR); - } else { - NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */ - NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */ - NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */ - NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */ - - /* rankine */ - if (0x00000003 & (1 << (dev_priv->chipset & 0x0f))) - NVOBJ_CLASS(dev, 0x0397, GR); - else - if (0x00000010 & (1 << (dev_priv->chipset & 0x0f))) - NVOBJ_CLASS(dev, 0x0697, GR); - else - if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f))) - NVOBJ_CLASS(dev, 0x0497, GR); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv30_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv30_fb.c deleted file mode 100644 index e0135f0e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv30_fb.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2010 Francisco Jerez. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -void -nv30_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch, uint32_t flags) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - tile->addr = addr | 1; - tile->limit = max(1u, addr + size) - 1; - tile->pitch = pitch; -} - -void -nv30_fb_free_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - tile->addr = tile->limit = tile->pitch = 0; -} - -static int -calc_bias(struct drm_device *dev, int k, int i, int j) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int b = (dev_priv->chipset > 0x30 ? - nv_rd32(dev, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) : - 0) & 0xf; - - return 2 * (b & 0x8 ? b - 0x10 : b); -} - -static int -calc_ref(struct drm_device *dev, int l, int k, int i) -{ - int j, x = 0; - - for (j = 0; j < 4; j++) { - int m = (l >> (8 * i) & 0xff) + calc_bias(dev, k, i, j); - - x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j); - } - - return x; -} - -int -nv30_fb_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int i, j; - - pfb->num_tiles = NV10_PFB_TILE__SIZE; - - /* Turn all the tiling regions off. */ - for (i = 0; i < pfb->num_tiles; i++) - pfb->set_tile_region(dev, i); - - /* Init the memory timing regs at 0x10037c/0x1003ac */ - if (dev_priv->chipset == 0x30 || - dev_priv->chipset == 0x31 || - dev_priv->chipset == 0x35) { - /* Related to ROP count */ - int n = (dev_priv->chipset == 0x31 ? 2 : 4); - int l = nv_rd32(dev, 0x1003d0); - - for (i = 0; i < n; i++) { - for (j = 0; j < 3; j++) - nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j, - calc_ref(dev, l, 0, j)); - - for (j = 0; j < 2; j++) - nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j, - calc_ref(dev, l, 1, j)); - } - } - - return 0; -} - -void -nv30_fb_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv31_mpeg.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv31_mpeg.c deleted file mode 100644 index 6f06a071..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv31_mpeg.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" - -struct nv31_mpeg_engine { - struct nouveau_exec_engine base; - atomic_t refcount; -}; - - -static int -nv31_mpeg_context_new(struct nouveau_channel *chan, int engine) -{ - struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine); - - if (!atomic_add_unless(&pmpeg->refcount, 1, 1)) - return -EBUSY; - - chan->engctx[engine] = (void *)0xdeadcafe; - return 0; -} - -static void -nv31_mpeg_context_del(struct nouveau_channel *chan, int engine) -{ - struct nv31_mpeg_engine *pmpeg = nv_engine(chan->dev, engine); - atomic_dec(&pmpeg->refcount); - chan->engctx[engine] = NULL; -} - -static int -nv40_mpeg_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ctx = NULL; - unsigned long flags; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - ret = nouveau_gpuobj_new(dev, NULL, 264 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &ctx); - if (ret) - return ret; - - nv_wo32(ctx, 0x78, 0x02001ec1); - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, 0x002500, 0x00000001, 0x00000000); - if ((nv_rd32(dev, 0x003204) & 0x1f) == chan->id) - nv_wr32(dev, 0x00330c, ctx->pinst >> 4); - nv_wo32(chan->ramfc, 0x54, ctx->pinst >> 4); - nv_mask(dev, 0x002500, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - chan->engctx[engine] = ctx; - return 0; -} - -static void -nv40_mpeg_context_del(struct nouveau_channel *chan, int engine) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_gpuobj *ctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - unsigned long flags; - u32 inst = 0x80000000 | (ctx->pinst >> 4); - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); - if (nv_rd32(dev, 0x00b318) == inst) - nv_mask(dev, 0x00b318, 0x80000000, 0x00000000); - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - nouveau_gpuobj_ref(NULL, &ctx); - chan->engctx[engine] = NULL; -} - -static int -nv31_mpeg_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - obj->engine = 2; - obj->class = class; - - nv_wo32(obj, 0x00, class); - - ret = nouveau_ramht_insert(chan, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static int -nv31_mpeg_init(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine); - int i; - - /* VPE init */ - nv_mask(dev, 0x000200, 0x00000002, 0x00000000); - nv_mask(dev, 0x000200, 0x00000002, 0x00000002); - nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */ - nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */ - - for (i = 0; i < dev_priv->engine.fb.num_tiles; i++) - pmpeg->base.set_tile_region(dev, i); - - /* PMPEG init */ - nv_wr32(dev, 0x00b32c, 0x00000000); - nv_wr32(dev, 0x00b314, 0x00000100); - nv_wr32(dev, 0x00b220, nv44_graph_class(dev) ? 0x00000044 : 0x00000031); - nv_wr32(dev, 0x00b300, 0x02001ec1); - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); - - nv_wr32(dev, 0x00b100, 0xffffffff); - nv_wr32(dev, 0x00b140, 0xffffffff); - - if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200)); - return -EBUSY; - } - - return 0; -} - -static int -nv31_mpeg_fini(struct drm_device *dev, int engine, bool suspend) -{ - /*XXX: context save? */ - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); - nv_wr32(dev, 0x00b140, 0x00000000); - return 0; -} - -static int -nv31_mpeg_mthd_dma(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) -{ - struct drm_device *dev = chan->dev; - u32 inst = data << 4; - u32 dma0 = nv_ri32(dev, inst + 0); - u32 dma1 = nv_ri32(dev, inst + 4); - u32 dma2 = nv_ri32(dev, inst + 8); - u32 base = (dma2 & 0xfffff000) | (dma0 >> 20); - u32 size = dma1 + 1; - - /* only allow linear DMA objects */ - if (!(dma0 & 0x00002000)) - return -EINVAL; - - if (mthd == 0x0190) { - /* DMA_CMD */ - nv_mask(dev, 0x00b300, 0x00030000, (dma0 & 0x00030000)); - nv_wr32(dev, 0x00b334, base); - nv_wr32(dev, 0x00b324, size); - } else - if (mthd == 0x01a0) { - /* DMA_DATA */ - nv_mask(dev, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2); - nv_wr32(dev, 0x00b360, base); - nv_wr32(dev, 0x00b364, size); - } else { - /* DMA_IMAGE, VRAM only */ - if (dma0 & 0x000c0000) - return -EINVAL; - - nv_wr32(dev, 0x00b370, base); - nv_wr32(dev, 0x00b374, size); - } - - return 0; -} - -static int -nv31_mpeg_isr_chid(struct drm_device *dev, u32 inst) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ctx; - unsigned long flags; - int i; - - /* hardcode drm channel id on nv3x, so swmthd lookup works */ - if (dev_priv->card_type < NV_40) - return 0; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (!dev_priv->channels.ptr[i]) - continue; - - ctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_MPEG]; - if (ctx && ctx->pinst == inst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return i; -} - -static void -nv31_vpe_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch); - nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit); - nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr); -} - -static void -nv31_mpeg_isr(struct drm_device *dev) -{ - u32 inst = (nv_rd32(dev, 0x00b318) & 0x000fffff) << 4; - u32 chid = nv31_mpeg_isr_chid(dev, inst); - u32 stat = nv_rd32(dev, 0x00b100); - u32 type = nv_rd32(dev, 0x00b230); - u32 mthd = nv_rd32(dev, 0x00b234); - u32 data = nv_rd32(dev, 0x00b238); - u32 show = stat; - - if (stat & 0x01000000) { - /* happens on initial binding of the object */ - if (type == 0x00000020 && mthd == 0x0000) { - nv_mask(dev, 0x00b308, 0x00000000, 0x00000000); - show &= ~0x01000000; - } - - if (type == 0x00000010) { - if (!nouveau_gpuobj_mthd_call2(dev, chid, 0x3174, mthd, data)) - show &= ~0x01000000; - } - } - - nv_wr32(dev, 0x00b100, stat); - nv_wr32(dev, 0x00b230, 0x00000001); - - if (show && nouveau_ratelimit()) { - NV_INFO(dev, "PMPEG: Ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n", - chid, inst, stat, type, mthd, data); - } -} - -static void -nv31_vpe_isr(struct drm_device *dev) -{ - if (nv_rd32(dev, 0x00b100)) - nv31_mpeg_isr(dev); - - if (nv_rd32(dev, 0x00b800)) { - u32 stat = nv_rd32(dev, 0x00b800); - NV_INFO(dev, "PMSRCH: 0x%08x\n", stat); - nv_wr32(dev, 0xb800, stat); - } -} - -static void -nv31_mpeg_destroy(struct drm_device *dev, int engine) -{ - struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 0); - - NVOBJ_ENGINE_DEL(dev, MPEG); - kfree(pmpeg); -} - -int -nv31_mpeg_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv31_mpeg_engine *pmpeg; - - pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL); - if (!pmpeg) - return -ENOMEM; - atomic_set(&pmpeg->refcount, 0); - - pmpeg->base.destroy = nv31_mpeg_destroy; - pmpeg->base.init = nv31_mpeg_init; - pmpeg->base.fini = nv31_mpeg_fini; - if (dev_priv->card_type < NV_40) { - pmpeg->base.context_new = nv31_mpeg_context_new; - pmpeg->base.context_del = nv31_mpeg_context_del; - } else { - pmpeg->base.context_new = nv40_mpeg_context_new; - pmpeg->base.context_del = nv40_mpeg_context_del; - } - pmpeg->base.object_new = nv31_mpeg_object_new; - - /* ISR vector, PMC_ENABLE bit, and TILE regs are shared between - * all VPE engines, for this driver's purposes the PMPEG engine - * will be treated as the "master" and handle the global VPE - * bits too - */ - pmpeg->base.set_tile_region = nv31_vpe_set_tile_region; - nouveau_irq_register(dev, 0, nv31_vpe_isr); - - NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base); - NVOBJ_CLASS(dev, 0x3174, MPEG); - NVOBJ_MTHD (dev, 0x3174, 0x0190, nv31_mpeg_mthd_dma); - NVOBJ_MTHD (dev, 0x3174, 0x01a0, nv31_mpeg_mthd_dma); - NVOBJ_MTHD (dev, 0x3174, 0x01b0, nv31_mpeg_mthd_dma); - -#if 0 - NVOBJ_ENGINE_ADD(dev, ME, &pme->base); - NVOBJ_CLASS(dev, 0x4075, ME); -#endif - return 0; - -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fb.c deleted file mode 100644 index 7fbcb334..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fb.c +++ /dev/null @@ -1,163 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -void -nv40_fb_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - switch (dev_priv->chipset) { - case 0x40: - nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); - nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); - nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); - break; - - default: - nv_wr32(dev, NV40_PFB_TLIMIT(i), tile->limit); - nv_wr32(dev, NV40_PFB_TSIZE(i), tile->pitch); - nv_wr32(dev, NV40_PFB_TILE(i), tile->addr); - break; - } -} - -static void -nv40_fb_init_gart(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; - - if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { - nv_wr32(dev, 0x100800, 0x00000001); - return; - } - - nv_wr32(dev, 0x100800, gart->pinst | 0x00000002); - nv_mask(dev, 0x10008c, 0x00000100, 0x00000100); - nv_wr32(dev, 0x100820, 0x00000000); -} - -static void -nv44_fb_init_gart(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; - u32 vinst; - - if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { - nv_wr32(dev, 0x100850, 0x80000000); - nv_wr32(dev, 0x100800, 0x00000001); - return; - } - - /* calculate vram address of this PRAMIN block, object - * must be allocated on 512KiB alignment, and not exceed - * a total size of 512KiB for this to work correctly - */ - vinst = nv_rd32(dev, 0x10020c); - vinst -= ((gart->pinst >> 19) + 1) << 19; - - nv_wr32(dev, 0x100850, 0x80000000); - nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr); - - nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size); - nv_wr32(dev, 0x100850, 0x00008000); - nv_mask(dev, 0x10008c, 0x00000200, 0x00000200); - nv_wr32(dev, 0x100820, 0x00000000); - nv_wr32(dev, 0x10082c, 0x00000001); - nv_wr32(dev, 0x100800, vinst | 0x00000010); -} - -int -nv40_fb_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* 0x001218 is actually present on a few other NV4X I looked at, - * and even contains sane values matching 0x100474. From looking - * at various vbios images however, this isn't the case everywhere. - * So, I chose to use the same regs I've seen NVIDIA reading around - * the memory detection, hopefully that'll get us the right numbers - */ - if (dev_priv->chipset == 0x40) { - u32 pbus1218 = nv_rd32(dev, 0x001218); - switch (pbus1218 & 0x00000300) { - case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; - case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; - case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; - case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; - } - } else - if (dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { - u32 pfb914 = nv_rd32(dev, 0x100914); - switch (pfb914 & 0x00000003) { - case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; - case 0x00000001: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; - case 0x00000002: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; - case 0x00000003: break; - } - } else - if (dev_priv->chipset != 0x4e) { - u32 pfb474 = nv_rd32(dev, 0x100474); - if (pfb474 & 0x00000004) - dev_priv->vram_type = NV_MEM_TYPE_GDDR3; - if (pfb474 & 0x00000002) - dev_priv->vram_type = NV_MEM_TYPE_DDR2; - if (pfb474 & 0x00000001) - dev_priv->vram_type = NV_MEM_TYPE_DDR1; - } else { - dev_priv->vram_type = NV_MEM_TYPE_STOLEN; - } - - dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000; - return 0; -} - -int -nv40_fb_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - uint32_t tmp; - int i; - - if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) { - if (nv44_graph_class(dev)) - nv44_fb_init_gart(dev); - else - nv40_fb_init_gart(dev); - } - - switch (dev_priv->chipset) { - case 0x40: - case 0x45: - tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); - nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); - pfb->num_tiles = NV10_PFB_TILE__SIZE; - break; - case 0x46: /* G72 */ - case 0x47: /* G70 */ - case 0x49: /* G71 */ - case 0x4b: /* G73 */ - case 0x4c: /* C51 (G7X version) */ - pfb->num_tiles = NV40_PFB_TILE__SIZE_1; - break; - default: - pfb->num_tiles = NV40_PFB_TILE__SIZE_0; - break; - } - - /* Turn all the tiling regions off. */ - for (i = 0; i < pfb->num_tiles; i++) - pfb->set_tile_region(dev, i); - - return 0; -} - -void -nv40_fb_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fifo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fifo.c deleted file mode 100644 index 68cb2d99..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_fifo.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" -#include "nouveau_ramht.h" - -#define NV40_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV40_RAMFC__SIZE)) -#define NV40_RAMFC__SIZE 128 - -int -nv40_fifo_create_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t fc = NV40_RAMFC(chan->id); - unsigned long flags; - int ret; - - ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, - NV40_RAMFC__SIZE, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); - if (ret) - return ret; - - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV40_USER(chan->id), PAGE_SIZE); - if (!chan->user) - return -ENOMEM; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - - nv_wi32(dev, fc + 0, chan->pushbuf_base); - nv_wi32(dev, fc + 4, chan->pushbuf_base); - nv_wi32(dev, fc + 12, chan->pushbuf->pinst >> 4); - nv_wi32(dev, fc + 24, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | - NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 | -#ifdef __BIG_ENDIAN - NV_PFIFO_CACHE1_BIG_ENDIAN | -#endif - 0x30000000 /* no idea.. */); - nv_wi32(dev, fc + 60, 0x0001FFFF); - - /* enable the fifo dma operation */ - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); - - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - return 0; -} - -static void -nv40_fifo_do_load_context(struct drm_device *dev, int chid) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t fc = NV40_RAMFC(chid), tmp, tmp2; - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4)); - nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE, nv_ri32(dev, fc + 12)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT, nv_ri32(dev, fc + 16)); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_STATE, nv_ri32(dev, fc + 20)); - - /* No idea what 0x2058 is.. */ - tmp = nv_ri32(dev, fc + 24); - tmp2 = nv_rd32(dev, 0x2058) & 0xFFF; - tmp2 |= (tmp & 0x30000000); - nv_wr32(dev, 0x2058, tmp2); - tmp &= ~0x30000000; - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_FETCH, tmp); - - nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 28)); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 32)); - nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE, nv_ri32(dev, fc + 36)); - tmp = nv_ri32(dev, fc + 40); - nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP, tmp); - nv_wr32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT, nv_ri32(dev, fc + 44)); - nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, nv_ri32(dev, fc + 48)); - nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 52)); - nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, nv_ri32(dev, fc + 56)); - - /* Don't clobber the TIMEOUT_ENABLED flag when restoring from RAMFC */ - tmp = nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & ~0x1FFFF; - tmp |= nv_ri32(dev, fc + 60) & 0x1FFFF; - nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, tmp); - - nv_wr32(dev, 0x32e4, nv_ri32(dev, fc + 64)); - /* NVIDIA does this next line twice... */ - nv_wr32(dev, 0x32e8, nv_ri32(dev, fc + 68)); - nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76)); - nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80)); - nv_wr32(dev, 0x330c, nv_ri32(dev, fc + 84)); - - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0); -} - -int -nv40_fifo_load_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - uint32_t tmp; - - nv40_fifo_do_load_context(dev, chan->id); - - /* Set channel active, and in DMA mode */ - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, - NV40_PFIFO_CACHE1_PUSH1_DMA | chan->id); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 1); - - /* Reset DMA_CTL_AT_INFO to INVALID */ - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_CTL) & ~(1 << 31); - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_CTL, tmp); - - return 0; -} - -int -nv40_fifo_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - uint32_t fc, tmp; - int chid; - - chid = pfifo->channel_id(dev); - if (chid < 0 || chid >= dev_priv->engine.fifo.channels) - return 0; - fc = NV40_RAMFC(chid); - - nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT)); - nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); - nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT)); - nv_wi32(dev, fc + 12, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_INSTANCE)); - nv_wi32(dev, fc + 16, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT)); - nv_wi32(dev, fc + 20, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_STATE)); - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH); - tmp |= nv_rd32(dev, 0x2058) & 0x30000000; - nv_wi32(dev, fc + 24, tmp); - nv_wi32(dev, fc + 28, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE)); - nv_wi32(dev, fc + 32, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1)); - nv_wi32(dev, fc + 36, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_VALUE)); - tmp = nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP); - nv_wi32(dev, fc + 40, tmp); - nv_wi32(dev, fc + 44, nv_rd32(dev, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT)); - nv_wi32(dev, fc + 48, nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE)); - /* NVIDIA read 0x3228 first, then write DMA_GET here.. maybe something - * more involved depending on the value of 0x3228? - */ - nv_wi32(dev, fc + 52, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET)); - nv_wi32(dev, fc + 56, nv_rd32(dev, NV40_PFIFO_GRCTX_INSTANCE)); - nv_wi32(dev, fc + 60, nv_rd32(dev, NV04_PFIFO_DMA_TIMESLICE) & 0x1ffff); - /* No idea what the below is for exactly, ripped from a mmio-trace */ - nv_wi32(dev, fc + 64, nv_rd32(dev, NV40_PFIFO_UNK32E4)); - /* NVIDIA do this next line twice.. bug? */ - nv_wi32(dev, fc + 68, nv_rd32(dev, 0x32e8)); - nv_wi32(dev, fc + 76, nv_rd32(dev, 0x2088)); - nv_wi32(dev, fc + 80, nv_rd32(dev, 0x3300)); -#if 0 /* no real idea which is PUT/GET in UNK_48.. */ - tmp = nv_rd32(dev, NV04_PFIFO_CACHE1_GET); - tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16); - nv_wi32(dev, fc + 72, tmp); -#endif - nv_wi32(dev, fc + 84, nv_rd32(dev, 0x330c)); - - nv40_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, - NV40_PFIFO_CACHE1_PUSH1_DMA | (pfifo->channels - 1)); - return 0; -} - -static void -nv40_fifo_init_reset(struct drm_device *dev) -{ - int i; - - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PFIFO); - nv_wr32(dev, NV03_PMC_ENABLE, - nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PFIFO); - - nv_wr32(dev, 0x003224, 0x000f0078); - nv_wr32(dev, 0x003210, 0x00000000); - nv_wr32(dev, 0x003270, 0x00000000); - nv_wr32(dev, 0x003240, 0x00000000); - nv_wr32(dev, 0x003244, 0x00000000); - nv_wr32(dev, 0x003258, 0x00000000); - nv_wr32(dev, 0x002504, 0x00000000); - for (i = 0; i < 16; i++) - nv_wr32(dev, 0x002510 + (i * 4), 0x00000000); - nv_wr32(dev, 0x00250c, 0x0000ffff); - nv_wr32(dev, 0x002048, 0x00000000); - nv_wr32(dev, 0x003228, 0x00000000); - nv_wr32(dev, 0x0032e8, 0x00000000); - nv_wr32(dev, 0x002410, 0x00000000); - nv_wr32(dev, 0x002420, 0x00000000); - nv_wr32(dev, 0x002058, 0x00000001); - nv_wr32(dev, 0x00221c, 0x00000000); - /* something with 0x2084, read/modify/write, no change */ - nv_wr32(dev, 0x002040, 0x000000ff); - nv_wr32(dev, 0x002500, 0x00000000); - nv_wr32(dev, 0x003200, 0x00000000); - - nv_wr32(dev, NV04_PFIFO_DMA_TIMESLICE, 0x2101ffff); -} - -static void -nv40_fifo_init_ramxx(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nv_wr32(dev, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ | - ((dev_priv->ramht->bits - 9) << 16) | - (dev_priv->ramht->gpuobj->pinst >> 8)); - nv_wr32(dev, NV03_PFIFO_RAMRO, dev_priv->ramro->pinst >> 8); - - switch (dev_priv->chipset) { - case 0x47: - case 0x49: - case 0x4b: - nv_wr32(dev, 0x2230, 1); - break; - default: - break; - } - - switch (dev_priv->chipset) { - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x45: - case 0x47: - case 0x48: - case 0x49: - case 0x4b: - nv_wr32(dev, NV40_PFIFO_RAMFC, 0x30002); - break; - default: - nv_wr32(dev, 0x2230, 0); - nv_wr32(dev, NV40_PFIFO_RAMFC, - ((dev_priv->vram_size - 512 * 1024 + - dev_priv->ramfc->pinst) >> 16) | (3 << 16)); - break; - } -} - -static void -nv40_fifo_init_intr(struct drm_device *dev) -{ - nouveau_irq_register(dev, 8, nv04_fifo_isr); - nv_wr32(dev, 0x002100, 0xffffffff); - nv_wr32(dev, 0x002140, 0xffffffff); -} - -int -nv40_fifo_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - int i; - - nv40_fifo_init_reset(dev); - nv40_fifo_init_ramxx(dev); - - nv40_fifo_do_load_context(dev, pfifo->channels - 1); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1); - - nv40_fifo_init_intr(dev); - pfifo->enable(dev); - pfifo->reassign(dev, true); - - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (dev_priv->channels.ptr[i]) { - uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); - nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); - } - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_graph.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_graph.c deleted file mode 100644 index ba14a93d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_graph.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_grctx.h" -#include "nouveau_ramht.h" - -struct nv40_graph_engine { - struct nouveau_exec_engine base; - u32 grctx_size; -}; - -static int -nv40_graph_context_new(struct nouveau_channel *chan, int engine) -{ - struct nv40_graph_engine *pgraph = nv_engine(chan->dev, engine); - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *grctx = NULL; - struct nouveau_grctx ctx = {}; - unsigned long flags; - int ret; - - ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16, - NVOBJ_FLAG_ZERO_ALLOC, &grctx); - if (ret) - return ret; - - /* Initialise default context values */ - ctx.dev = chan->dev; - ctx.mode = NOUVEAU_GRCTX_VALS; - ctx.data = grctx; - nv40_grctx_init(&ctx); - - nv_wo32(grctx, 0, grctx->vinst); - - /* init grctx pointer in ramfc, and on PFIFO if channel is - * already active there - */ - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_wo32(chan->ramfc, 0x38, grctx->vinst >> 4); - nv_mask(dev, 0x002500, 0x00000001, 0x00000000); - if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id) - nv_wr32(dev, 0x0032e0, grctx->vinst >> 4); - nv_mask(dev, 0x002500, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - chan->engctx[engine] = grctx; - return 0; -} - -static void -nv40_graph_context_del(struct nouveau_channel *chan, int engine) -{ - struct nouveau_gpuobj *grctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 inst = 0x01000000 | (grctx->pinst >> 4); - unsigned long flags; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, 0x400720, 0x00000000, 0x00000001); - if (nv_rd32(dev, 0x40032c) == inst) - nv_mask(dev, 0x40032c, 0x01000000, 0x00000000); - if (nv_rd32(dev, 0x400330) == inst) - nv_mask(dev, 0x400330, 0x01000000, 0x00000000); - nv_mask(dev, 0x400720, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the context resources */ - nouveau_gpuobj_ref(NULL, &grctx); - chan->engctx[engine] = NULL; -} - -int -nv40_graph_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct drm_device *dev = chan->dev; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - obj->engine = 1; - obj->class = class; - - nv_wo32(obj, 0x00, class); - nv_wo32(obj, 0x04, 0x00000000); -#ifndef __BIG_ENDIAN - nv_wo32(obj, 0x08, 0x00000000); -#else - nv_wo32(obj, 0x08, 0x01000000); -#endif - nv_wo32(obj, 0x0c, 0x00000000); - nv_wo32(obj, 0x10, 0x00000000); - - ret = nouveau_ramht_insert(chan, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static void -nv40_graph_set_tile_region(struct drm_device *dev, int i) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - - switch (dev_priv->chipset) { - case 0x40: - case 0x41: /* guess */ - case 0x42: - case 0x43: - case 0x45: /* guess */ - case 0x4e: - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); - break; - case 0x44: - case 0x4a: - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); - break; - case 0x46: - case 0x47: - case 0x49: - case 0x4b: - case 0x4c: - case 0x67: - default: - nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); - break; - } -} - -/* - * G70 0x47 - * G71 0x49 - * NV45 0x48 - * G72[M] 0x46 - * G73 0x4b - * C51_G7X 0x4c - * C51 0x4e - */ -int -nv40_graph_init(struct drm_device *dev, int engine) -{ - struct nv40_graph_engine *pgraph = nv_engine(dev, engine); - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nouveau_grctx ctx = {}; - uint32_t vramsz, *cp; - int i, j; - - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & - ~NV_PMC_ENABLE_PGRAPH); - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | - NV_PMC_ENABLE_PGRAPH); - - cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); - if (!cp) - return -ENOMEM; - - ctx.dev = dev; - ctx.mode = NOUVEAU_GRCTX_PROG; - ctx.data = cp; - ctx.ctxprog_max = 256; - nv40_grctx_init(&ctx); - pgraph->grctx_size = ctx.ctxvals_pos * 4; - - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); - for (i = 0; i < ctx.ctxprog_len; i++) - nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); - - kfree(cp); - - /* No context present currently */ - nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); - - nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); - nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); - - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF); - nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x00000000); - nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x401287c0); - nv_wr32(dev, NV04_PGRAPH_DEBUG_3, 0xe0de8055); - nv_wr32(dev, NV10_PGRAPH_DEBUG_4, 0x00008000); - nv_wr32(dev, NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f); - - nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100); - nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); - - j = nv_rd32(dev, 0x1540) & 0xff; - if (j) { - for (i = 0; !(j & 1); j >>= 1, i++) - ; - nv_wr32(dev, 0x405000, i); - } - - if (dev_priv->chipset == 0x40) { - nv_wr32(dev, 0x4009b0, 0x83280fff); - nv_wr32(dev, 0x4009b4, 0x000000a0); - } else { - nv_wr32(dev, 0x400820, 0x83280eff); - nv_wr32(dev, 0x400824, 0x000000a0); - } - - switch (dev_priv->chipset) { - case 0x40: - case 0x45: - nv_wr32(dev, 0x4009b8, 0x0078e366); - nv_wr32(dev, 0x4009bc, 0x0000014c); - break; - case 0x41: - case 0x42: /* pciid also 0x00Cx */ - /* case 0x0120: XXX (pciid) */ - nv_wr32(dev, 0x400828, 0x007596ff); - nv_wr32(dev, 0x40082c, 0x00000108); - break; - case 0x43: - nv_wr32(dev, 0x400828, 0x0072cb77); - nv_wr32(dev, 0x40082c, 0x00000108); - break; - case 0x44: - case 0x46: /* G72 */ - case 0x4a: - case 0x4c: /* G7x-based C51 */ - case 0x4e: - nv_wr32(dev, 0x400860, 0); - nv_wr32(dev, 0x400864, 0); - break; - case 0x47: /* G70 */ - case 0x49: /* G71 */ - case 0x4b: /* G73 */ - nv_wr32(dev, 0x400828, 0x07830610); - nv_wr32(dev, 0x40082c, 0x0000016A); - break; - default: - break; - } - - nv_wr32(dev, 0x400b38, 0x2ffff800); - nv_wr32(dev, 0x400b3c, 0x00006000); - - /* Tiling related stuff. */ - switch (dev_priv->chipset) { - case 0x44: - case 0x4a: - nv_wr32(dev, 0x400bc4, 0x1003d888); - nv_wr32(dev, 0x400bbc, 0xb7a7b500); - break; - case 0x46: - nv_wr32(dev, 0x400bc4, 0x0000e024); - nv_wr32(dev, 0x400bbc, 0xb7a7b520); - break; - case 0x4c: - case 0x4e: - case 0x67: - nv_wr32(dev, 0x400bc4, 0x1003d888); - nv_wr32(dev, 0x400bbc, 0xb7a7b540); - break; - default: - break; - } - - /* Turn all the tiling regions off. */ - for (i = 0; i < pfb->num_tiles; i++) - nv40_graph_set_tile_region(dev, i); - - /* begin RAM config */ - vramsz = pci_resource_len(dev->pdev, 0) - 1; - switch (dev_priv->chipset) { - case 0x40: - nv_wr32(dev, 0x4009A4, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4009A8, nv_rd32(dev, NV04_PFB_CFG1)); - nv_wr32(dev, 0x4069A4, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4069A8, nv_rd32(dev, NV04_PFB_CFG1)); - nv_wr32(dev, 0x400820, 0); - nv_wr32(dev, 0x400824, 0); - nv_wr32(dev, 0x400864, vramsz); - nv_wr32(dev, 0x400868, vramsz); - break; - default: - switch (dev_priv->chipset) { - case 0x41: - case 0x42: - case 0x43: - case 0x45: - case 0x4e: - case 0x44: - case 0x4a: - nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); - break; - default: - nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); - break; - } - nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1)); - nv_wr32(dev, 0x400840, 0); - nv_wr32(dev, 0x400844, 0); - nv_wr32(dev, 0x4008A0, vramsz); - nv_wr32(dev, 0x4008A4, vramsz); - break; - } - - return 0; -} - -static int -nv40_graph_fini(struct drm_device *dev, int engine, bool suspend) -{ - u32 inst = nv_rd32(dev, 0x40032c); - if (inst & 0x01000000) { - nv_wr32(dev, 0x400720, 0x00000000); - nv_wr32(dev, 0x400784, inst); - nv_mask(dev, 0x400310, 0x00000020, 0x00000020); - nv_mask(dev, 0x400304, 0x00000001, 0x00000001); - if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) { - u32 insn = nv_rd32(dev, 0x400308); - NV_ERROR(dev, "PGRAPH: ctxprog timeout 0x%08x\n", insn); - } - nv_mask(dev, 0x40032c, 0x01000000, 0x00000000); - } - return 0; -} - -static int -nv40_graph_isr_chid(struct drm_device *dev, u32 inst) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *grctx; - unsigned long flags; - int i; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (!dev_priv->channels.ptr[i]) - continue; - grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR]; - - if (grctx && grctx->pinst == inst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return i; -} - -static void -nv40_graph_isr(struct drm_device *dev) -{ - u32 stat; - - while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { - u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); - u32 inst = (nv_rd32(dev, 0x40032c) & 0x000fffff) << 4; - u32 chid = nv40_graph_isr_chid(dev, inst); - u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00001ffc); - u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); - u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xffff; - u32 show = stat; - - if (stat & NV_PGRAPH_INTR_ERROR) { - if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { - if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) - show &= ~NV_PGRAPH_INTR_ERROR; - } else - if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) { - nv_mask(dev, 0x402000, 0, 0); - } - } - - nv_wr32(dev, NV03_PGRAPH_INTR, stat); - nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); - - if (show && nouveau_ratelimit()) { - NV_INFO(dev, "PGRAPH -"); - nouveau_bitfield_print(nv10_graph_intr, show); - printk(" nsource:"); - nouveau_bitfield_print(nv04_graph_nsource, nsource); - printk(" nstatus:"); - nouveau_bitfield_print(nv10_graph_nstatus, nstatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - ch %d (0x%08x) subc %d " - "class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, subc, class, mthd, data); - } - } -} - -static void -nv40_graph_destroy(struct drm_device *dev, int engine) -{ - struct nv40_graph_engine *pgraph = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 12); - - NVOBJ_ENGINE_DEL(dev, GR); - kfree(pgraph); -} - -int -nv40_graph_create(struct drm_device *dev) -{ - struct nv40_graph_engine *pgraph; - - pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); - if (!pgraph) - return -ENOMEM; - - pgraph->base.destroy = nv40_graph_destroy; - pgraph->base.init = nv40_graph_init; - pgraph->base.fini = nv40_graph_fini; - pgraph->base.context_new = nv40_graph_context_new; - pgraph->base.context_del = nv40_graph_context_del; - pgraph->base.object_new = nv40_graph_object_new; - pgraph->base.set_tile_region = nv40_graph_set_tile_region; - - NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); - nouveau_irq_register(dev, 12, nv40_graph_isr); - - NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ - NVOBJ_CLASS(dev, 0x0030, GR); /* null */ - NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ - NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ - NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ - NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ - NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ - NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */ - NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ - NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */ - NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ - NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ - NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ - NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ - NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ - NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */ - - /* curie */ - if (nv44_graph_class(dev)) - NVOBJ_CLASS(dev, 0x4497, GR); - else - NVOBJ_CLASS(dev, 0x4097, GR); - - /* nvsw */ - NVOBJ_CLASS(dev, 0x506e, SW); - NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_grctx.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_grctx.c deleted file mode 100644 index f70447d1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_grctx.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -/* NVIDIA context programs handle a number of other conditions which are - * not implemented in our versions. It's not clear why NVIDIA context - * programs have this code, nor whether it's strictly necessary for - * correct operation. We'll implement additional handling if/when we - * discover it's necessary. - * - * - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state" - * flag is set, this gets saved into the context. - * - On context save, the context program for all cards load nsource - * into a flag register and check for ILLEGAL_MTHD. If it's set, - * opcode 0x60000d is called before resuming normal operation. - * - Some context programs check more conditions than the above. NV44 - * checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001)) - * and calls 0x60000d before resuming normal operation. - * - At the very beginning of NVIDIA's context programs, flag 9 is checked - * and if true 0x800001 is called with count=0, pos=0, the flag is cleared - * and then the ctxprog is aborted. It looks like a complicated NOP, - * its purpose is unknown. - * - In the section of code that loads the per-vs state, NVIDIA check - * flag 10. If it's set, they only transfer the small 0x300 byte block - * of state + the state for a single vs as opposed to the state for - * all vs units. It doesn't seem likely that it'll occur in normal - * operation, especially seeing as it appears NVIDIA may have screwed - * up the ctxprogs for some cards and have an invalid instruction - * rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction. - * - There's a number of places where context offset 0 (where we place - * the PRAMIN offset of the context) is loaded into either 0x408000, - * 0x408004 or 0x408008. Not sure what's up there either. - * - The ctxprogs for some cards save 0x400a00 again during the cleanup - * path for auto-loadctx. - */ - -#define CP_FLAG_CLEAR 0 -#define CP_FLAG_SET 1 -#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) -#define CP_FLAG_SWAP_DIRECTION_LOAD 0 -#define CP_FLAG_SWAP_DIRECTION_SAVE 1 -#define CP_FLAG_USER_SAVE ((0 * 32) + 5) -#define CP_FLAG_USER_SAVE_NOT_PENDING 0 -#define CP_FLAG_USER_SAVE_PENDING 1 -#define CP_FLAG_USER_LOAD ((0 * 32) + 6) -#define CP_FLAG_USER_LOAD_NOT_PENDING 0 -#define CP_FLAG_USER_LOAD_PENDING 1 -#define CP_FLAG_STATUS ((3 * 32) + 0) -#define CP_FLAG_STATUS_IDLE 0 -#define CP_FLAG_STATUS_BUSY 1 -#define CP_FLAG_AUTO_SAVE ((3 * 32) + 4) -#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 -#define CP_FLAG_AUTO_SAVE_PENDING 1 -#define CP_FLAG_AUTO_LOAD ((3 * 32) + 5) -#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 -#define CP_FLAG_AUTO_LOAD_PENDING 1 -#define CP_FLAG_UNK54 ((3 * 32) + 6) -#define CP_FLAG_UNK54_CLEAR 0 -#define CP_FLAG_UNK54_SET 1 -#define CP_FLAG_ALWAYS ((3 * 32) + 8) -#define CP_FLAG_ALWAYS_FALSE 0 -#define CP_FLAG_ALWAYS_TRUE 1 -#define CP_FLAG_UNK57 ((3 * 32) + 9) -#define CP_FLAG_UNK57_CLEAR 0 -#define CP_FLAG_UNK57_SET 1 - -#define CP_CTX 0x00100000 -#define CP_CTX_COUNT 0x000fc000 -#define CP_CTX_COUNT_SHIFT 14 -#define CP_CTX_REG 0x00003fff -#define CP_LOAD_SR 0x00200000 -#define CP_LOAD_SR_VALUE 0x000fffff -#define CP_BRA 0x00400000 -#define CP_BRA_IP 0x0000ff00 -#define CP_BRA_IP_SHIFT 8 -#define CP_BRA_IF_CLEAR 0x00000080 -#define CP_BRA_FLAG 0x0000007f -#define CP_WAIT 0x00500000 -#define CP_WAIT_SET 0x00000080 -#define CP_WAIT_FLAG 0x0000007f -#define CP_SET 0x00700000 -#define CP_SET_1 0x00000080 -#define CP_SET_FLAG 0x0000007f -#define CP_NEXT_TO_SWAP 0x00600007 -#define CP_NEXT_TO_CURRENT 0x00600009 -#define CP_SET_CONTEXT_POINTER 0x0060000a -#define CP_END 0x0060000e -#define CP_LOAD_MAGIC_UNK01 0x00800001 /* unknown */ -#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */ -#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_grctx.h" - -/* TODO: - * - get vs count from 0x1540 - */ - -static int -nv40_graph_vs_count(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - switch (dev_priv->chipset) { - case 0x47: - case 0x49: - case 0x4b: - return 8; - case 0x40: - return 6; - case 0x41: - case 0x42: - return 5; - case 0x43: - case 0x44: - case 0x46: - case 0x4a: - return 3; - case 0x4c: - case 0x4e: - case 0x67: - default: - return 1; - } -} - - -enum cp_label { - cp_check_load = 1, - cp_setup_auto_load, - cp_setup_load, - cp_setup_save, - cp_swap_state, - cp_swap_state3d_3_is_save, - cp_prepare_exit, - cp_exit, -}; - -static void -nv40_graph_construct_general(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - - cp_ctx(ctx, 0x4000a4, 1); - gr_def(ctx, 0x4000a4, 0x00000008); - cp_ctx(ctx, 0x400144, 58); - gr_def(ctx, 0x400144, 0x00000001); - cp_ctx(ctx, 0x400314, 1); - gr_def(ctx, 0x400314, 0x00000000); - cp_ctx(ctx, 0x400400, 10); - cp_ctx(ctx, 0x400480, 10); - cp_ctx(ctx, 0x400500, 19); - gr_def(ctx, 0x400514, 0x00040000); - gr_def(ctx, 0x400524, 0x55555555); - gr_def(ctx, 0x400528, 0x55555555); - gr_def(ctx, 0x40052c, 0x55555555); - gr_def(ctx, 0x400530, 0x55555555); - cp_ctx(ctx, 0x400560, 6); - gr_def(ctx, 0x400568, 0x0000ffff); - gr_def(ctx, 0x40056c, 0x0000ffff); - cp_ctx(ctx, 0x40057c, 5); - cp_ctx(ctx, 0x400710, 3); - gr_def(ctx, 0x400710, 0x20010001); - gr_def(ctx, 0x400714, 0x0f73ef00); - cp_ctx(ctx, 0x400724, 1); - gr_def(ctx, 0x400724, 0x02008821); - cp_ctx(ctx, 0x400770, 3); - if (dev_priv->chipset == 0x40) { - cp_ctx(ctx, 0x400814, 4); - cp_ctx(ctx, 0x400828, 5); - cp_ctx(ctx, 0x400840, 5); - gr_def(ctx, 0x400850, 0x00000040); - cp_ctx(ctx, 0x400858, 4); - gr_def(ctx, 0x400858, 0x00000040); - gr_def(ctx, 0x40085c, 0x00000040); - gr_def(ctx, 0x400864, 0x80000000); - cp_ctx(ctx, 0x40086c, 9); - gr_def(ctx, 0x40086c, 0x80000000); - gr_def(ctx, 0x400870, 0x80000000); - gr_def(ctx, 0x400874, 0x80000000); - gr_def(ctx, 0x400878, 0x80000000); - gr_def(ctx, 0x400888, 0x00000040); - gr_def(ctx, 0x40088c, 0x80000000); - cp_ctx(ctx, 0x4009c0, 8); - gr_def(ctx, 0x4009cc, 0x80000000); - gr_def(ctx, 0x4009dc, 0x80000000); - } else { - cp_ctx(ctx, 0x400840, 20); - if (nv44_graph_class(ctx->dev)) { - for (i = 0; i < 8; i++) - gr_def(ctx, 0x400860 + (i * 4), 0x00000001); - } - gr_def(ctx, 0x400880, 0x00000040); - gr_def(ctx, 0x400884, 0x00000040); - gr_def(ctx, 0x400888, 0x00000040); - cp_ctx(ctx, 0x400894, 11); - gr_def(ctx, 0x400894, 0x00000040); - if (!nv44_graph_class(ctx->dev)) { - for (i = 0; i < 8; i++) - gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000); - } - cp_ctx(ctx, 0x4008e0, 2); - cp_ctx(ctx, 0x4008f8, 2); - if (dev_priv->chipset == 0x4c || - (dev_priv->chipset & 0xf0) == 0x60) - cp_ctx(ctx, 0x4009f8, 1); - } - cp_ctx(ctx, 0x400a00, 73); - gr_def(ctx, 0x400b0c, 0x0b0b0b0c); - cp_ctx(ctx, 0x401000, 4); - cp_ctx(ctx, 0x405004, 1); - switch (dev_priv->chipset) { - case 0x47: - case 0x49: - case 0x4b: - cp_ctx(ctx, 0x403448, 1); - gr_def(ctx, 0x403448, 0x00001010); - break; - default: - cp_ctx(ctx, 0x403440, 1); - switch (dev_priv->chipset) { - case 0x40: - gr_def(ctx, 0x403440, 0x00000010); - break; - case 0x44: - case 0x46: - case 0x4a: - gr_def(ctx, 0x403440, 0x00003010); - break; - case 0x41: - case 0x42: - case 0x43: - case 0x4c: - case 0x4e: - case 0x67: - default: - gr_def(ctx, 0x403440, 0x00001010); - break; - } - break; - } -} - -static void -nv40_graph_construct_state3d(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - - if (dev_priv->chipset == 0x40) { - cp_ctx(ctx, 0x401880, 51); - gr_def(ctx, 0x401940, 0x00000100); - } else - if (dev_priv->chipset == 0x46 || dev_priv->chipset == 0x47 || - dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { - cp_ctx(ctx, 0x401880, 32); - for (i = 0; i < 16; i++) - gr_def(ctx, 0x401880 + (i * 4), 0x00000111); - if (dev_priv->chipset == 0x46) - cp_ctx(ctx, 0x401900, 16); - cp_ctx(ctx, 0x401940, 3); - } - cp_ctx(ctx, 0x40194c, 18); - gr_def(ctx, 0x401954, 0x00000111); - gr_def(ctx, 0x401958, 0x00080060); - gr_def(ctx, 0x401974, 0x00000080); - gr_def(ctx, 0x401978, 0xffff0000); - gr_def(ctx, 0x40197c, 0x00000001); - gr_def(ctx, 0x401990, 0x46400000); - if (dev_priv->chipset == 0x40) { - cp_ctx(ctx, 0x4019a0, 2); - cp_ctx(ctx, 0x4019ac, 5); - } else { - cp_ctx(ctx, 0x4019a0, 1); - cp_ctx(ctx, 0x4019b4, 3); - } - gr_def(ctx, 0x4019bc, 0xffff0000); - switch (dev_priv->chipset) { - case 0x46: - case 0x47: - case 0x49: - case 0x4b: - cp_ctx(ctx, 0x4019c0, 18); - for (i = 0; i < 16; i++) - gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888); - break; - } - cp_ctx(ctx, 0x401a08, 8); - gr_def(ctx, 0x401a10, 0x0fff0000); - gr_def(ctx, 0x401a14, 0x0fff0000); - gr_def(ctx, 0x401a1c, 0x00011100); - cp_ctx(ctx, 0x401a2c, 4); - cp_ctx(ctx, 0x401a44, 26); - for (i = 0; i < 16; i++) - gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000); - gr_def(ctx, 0x401a8c, 0x4b7fffff); - if (dev_priv->chipset == 0x40) { - cp_ctx(ctx, 0x401ab8, 3); - } else { - cp_ctx(ctx, 0x401ab8, 1); - cp_ctx(ctx, 0x401ac0, 1); - } - cp_ctx(ctx, 0x401ad0, 8); - gr_def(ctx, 0x401ad0, 0x30201000); - gr_def(ctx, 0x401ad4, 0x70605040); - gr_def(ctx, 0x401ad8, 0xb8a89888); - gr_def(ctx, 0x401adc, 0xf8e8d8c8); - cp_ctx(ctx, 0x401b10, dev_priv->chipset == 0x40 ? 2 : 1); - gr_def(ctx, 0x401b10, 0x40100000); - cp_ctx(ctx, 0x401b18, dev_priv->chipset == 0x40 ? 6 : 5); - gr_def(ctx, 0x401b28, dev_priv->chipset == 0x40 ? - 0x00000004 : 0x00000000); - cp_ctx(ctx, 0x401b30, 25); - gr_def(ctx, 0x401b34, 0x0000ffff); - gr_def(ctx, 0x401b68, 0x435185d6); - gr_def(ctx, 0x401b6c, 0x2155b699); - gr_def(ctx, 0x401b70, 0xfedcba98); - gr_def(ctx, 0x401b74, 0x00000098); - gr_def(ctx, 0x401b84, 0xffffffff); - gr_def(ctx, 0x401b88, 0x00ff7000); - gr_def(ctx, 0x401b8c, 0x0000ffff); - if (dev_priv->chipset != 0x44 && dev_priv->chipset != 0x4a && - dev_priv->chipset != 0x4e) - cp_ctx(ctx, 0x401b94, 1); - cp_ctx(ctx, 0x401b98, 8); - gr_def(ctx, 0x401b9c, 0x00ff0000); - cp_ctx(ctx, 0x401bc0, 9); - gr_def(ctx, 0x401be0, 0x00ffff00); - cp_ctx(ctx, 0x401c00, 192); - for (i = 0; i < 16; i++) { /* fragment texture units */ - gr_def(ctx, 0x401c40 + (i * 4), 0x00018488); - gr_def(ctx, 0x401c80 + (i * 4), 0x00028202); - gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4); - gr_def(ctx, 0x401d40 + (i * 4), 0x01012000); - gr_def(ctx, 0x401d80 + (i * 4), 0x00080008); - gr_def(ctx, 0x401e00 + (i * 4), 0x00100008); - } - for (i = 0; i < 4; i++) { /* vertex texture units */ - gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80); - gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202); - gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008); - gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008); - } - cp_ctx(ctx, 0x400f5c, 3); - gr_def(ctx, 0x400f5c, 0x00000002); - cp_ctx(ctx, 0x400f84, 1); -} - -static void -nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - - cp_ctx(ctx, 0x402000, 1); - cp_ctx(ctx, 0x402404, dev_priv->chipset == 0x40 ? 1 : 2); - switch (dev_priv->chipset) { - case 0x40: - gr_def(ctx, 0x402404, 0x00000001); - break; - case 0x4c: - case 0x4e: - case 0x67: - gr_def(ctx, 0x402404, 0x00000020); - break; - case 0x46: - case 0x49: - case 0x4b: - gr_def(ctx, 0x402404, 0x00000421); - break; - default: - gr_def(ctx, 0x402404, 0x00000021); - } - if (dev_priv->chipset != 0x40) - gr_def(ctx, 0x402408, 0x030c30c3); - switch (dev_priv->chipset) { - case 0x44: - case 0x46: - case 0x4a: - case 0x4c: - case 0x4e: - case 0x67: - cp_ctx(ctx, 0x402440, 1); - gr_def(ctx, 0x402440, 0x00011001); - break; - default: - break; - } - cp_ctx(ctx, 0x402480, dev_priv->chipset == 0x40 ? 8 : 9); - gr_def(ctx, 0x402488, 0x3e020200); - gr_def(ctx, 0x40248c, 0x00ffffff); - switch (dev_priv->chipset) { - case 0x40: - gr_def(ctx, 0x402490, 0x60103f00); - break; - case 0x47: - gr_def(ctx, 0x402490, 0x40103f00); - break; - case 0x41: - case 0x42: - case 0x49: - case 0x4b: - gr_def(ctx, 0x402490, 0x20103f00); - break; - default: - gr_def(ctx, 0x402490, 0x0c103f00); - break; - } - gr_def(ctx, 0x40249c, dev_priv->chipset <= 0x43 ? - 0x00020000 : 0x00040000); - cp_ctx(ctx, 0x402500, 31); - gr_def(ctx, 0x402530, 0x00008100); - if (dev_priv->chipset == 0x40) - cp_ctx(ctx, 0x40257c, 6); - cp_ctx(ctx, 0x402594, 16); - cp_ctx(ctx, 0x402800, 17); - gr_def(ctx, 0x402800, 0x00000001); - switch (dev_priv->chipset) { - case 0x47: - case 0x49: - case 0x4b: - cp_ctx(ctx, 0x402864, 1); - gr_def(ctx, 0x402864, 0x00001001); - cp_ctx(ctx, 0x402870, 3); - gr_def(ctx, 0x402878, 0x00000003); - if (dev_priv->chipset != 0x47) { /* belong at end!! */ - cp_ctx(ctx, 0x402900, 1); - cp_ctx(ctx, 0x402940, 1); - cp_ctx(ctx, 0x402980, 1); - cp_ctx(ctx, 0x4029c0, 1); - cp_ctx(ctx, 0x402a00, 1); - cp_ctx(ctx, 0x402a40, 1); - cp_ctx(ctx, 0x402a80, 1); - cp_ctx(ctx, 0x402ac0, 1); - } - break; - case 0x40: - cp_ctx(ctx, 0x402844, 1); - gr_def(ctx, 0x402844, 0x00000001); - cp_ctx(ctx, 0x402850, 1); - break; - default: - cp_ctx(ctx, 0x402844, 1); - gr_def(ctx, 0x402844, 0x00001001); - cp_ctx(ctx, 0x402850, 2); - gr_def(ctx, 0x402854, 0x00000003); - break; - } - - cp_ctx(ctx, 0x402c00, 4); - gr_def(ctx, 0x402c00, dev_priv->chipset == 0x40 ? - 0x80800001 : 0x00888001); - switch (dev_priv->chipset) { - case 0x47: - case 0x49: - case 0x4b: - cp_ctx(ctx, 0x402c20, 40); - for (i = 0; i < 32; i++) - gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff); - cp_ctx(ctx, 0x4030b8, 13); - gr_def(ctx, 0x4030dc, 0x00000005); - gr_def(ctx, 0x4030e8, 0x0000ffff); - break; - default: - cp_ctx(ctx, 0x402c10, 4); - if (dev_priv->chipset == 0x40) - cp_ctx(ctx, 0x402c20, 36); - else - if (dev_priv->chipset <= 0x42) - cp_ctx(ctx, 0x402c20, 24); - else - if (dev_priv->chipset <= 0x4a) - cp_ctx(ctx, 0x402c20, 16); - else - cp_ctx(ctx, 0x402c20, 8); - cp_ctx(ctx, 0x402cb0, dev_priv->chipset == 0x40 ? 12 : 13); - gr_def(ctx, 0x402cd4, 0x00000005); - if (dev_priv->chipset != 0x40) - gr_def(ctx, 0x402ce0, 0x0000ffff); - break; - } - - cp_ctx(ctx, 0x403400, dev_priv->chipset == 0x40 ? 4 : 3); - cp_ctx(ctx, 0x403410, dev_priv->chipset == 0x40 ? 4 : 3); - cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->dev)); - for (i = 0; i < nv40_graph_vs_count(ctx->dev); i++) - gr_def(ctx, 0x403420 + (i * 4), 0x00005555); - - if (dev_priv->chipset != 0x40) { - cp_ctx(ctx, 0x403600, 1); - gr_def(ctx, 0x403600, 0x00000001); - } - cp_ctx(ctx, 0x403800, 1); - - cp_ctx(ctx, 0x403c18, 1); - gr_def(ctx, 0x403c18, 0x00000001); - switch (dev_priv->chipset) { - case 0x46: - case 0x47: - case 0x49: - case 0x4b: - cp_ctx(ctx, 0x405018, 1); - gr_def(ctx, 0x405018, 0x08e00001); - cp_ctx(ctx, 0x405c24, 1); - gr_def(ctx, 0x405c24, 0x000e3000); - break; - } - if (dev_priv->chipset != 0x4e) - cp_ctx(ctx, 0x405800, 11); - cp_ctx(ctx, 0x407000, 1); -} - -static void -nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx) -{ - int len = nv44_graph_class(ctx->dev) ? 0x0084 : 0x0684; - - cp_out (ctx, 0x300000); - cp_lsr (ctx, len - 4); - cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save); - cp_lsr (ctx, len); - cp_name(ctx, cp_swap_state3d_3_is_save); - cp_out (ctx, 0x800001); - - ctx->ctxvals_pos += len; -} - -static void -nv40_graph_construct_shader(struct nouveau_grctx *ctx) -{ - struct drm_device *dev = ctx->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = ctx->data; - int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset; - int offset, i; - - vs_nr = nv40_graph_vs_count(ctx->dev); - vs_nr_b0 = 363; - vs_nr_b1 = dev_priv->chipset == 0x40 ? 128 : 64; - if (dev_priv->chipset == 0x40) { - b0_offset = 0x2200/4; /* 33a0 */ - b1_offset = 0x55a0/4; /* 1500 */ - vs_len = 0x6aa0/4; - } else - if (dev_priv->chipset == 0x41 || dev_priv->chipset == 0x42) { - b0_offset = 0x2200/4; /* 2200 */ - b1_offset = 0x4400/4; /* 0b00 */ - vs_len = 0x4f00/4; - } else { - b0_offset = 0x1d40/4; /* 2200 */ - b1_offset = 0x3f40/4; /* 0b00 : 0a40 */ - vs_len = nv44_graph_class(dev) ? 0x4980/4 : 0x4a40/4; - } - - cp_lsr(ctx, vs_len * vs_nr + 0x300/4); - cp_out(ctx, nv44_graph_class(dev) ? 0x800029 : 0x800041); - - offset = ctx->ctxvals_pos; - ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len)); - - if (ctx->mode != NOUVEAU_GRCTX_VALS) - return; - - offset += 0x0280/4; - for (i = 0; i < 16; i++, offset += 2) - nv_wo32(obj, offset * 4, 0x3f800000); - - for (vs = 0; vs < vs_nr; vs++, offset += vs_len) { - for (i = 0; i < vs_nr_b0 * 6; i += 6) - nv_wo32(obj, (offset + b0_offset + i) * 4, 0x00000001); - for (i = 0; i < vs_nr_b1 * 4; i += 4) - nv_wo32(obj, (offset + b1_offset + i) * 4, 0x3f800000); - } -} - -void -nv40_grctx_init(struct nouveau_grctx *ctx) -{ - /* decide whether we're loading/unloading the context */ - cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); - cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); - - cp_name(ctx, cp_check_load); - cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); - cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); - cp_bra (ctx, ALWAYS, TRUE, cp_exit); - - /* setup for context load */ - cp_name(ctx, cp_setup_auto_load); - cp_wait(ctx, STATUS, IDLE); - cp_out (ctx, CP_NEXT_TO_SWAP); - cp_name(ctx, cp_setup_load); - cp_wait(ctx, STATUS, IDLE); - cp_set (ctx, SWAP_DIRECTION, LOAD); - cp_out (ctx, 0x00910880); /* ?? */ - cp_out (ctx, 0x00901ffe); /* ?? */ - cp_out (ctx, 0x01940000); /* ?? */ - cp_lsr (ctx, 0x20); - cp_out (ctx, 0x0060000b); /* ?? */ - cp_wait(ctx, UNK57, CLEAR); - cp_out (ctx, 0x0060000c); /* ?? */ - cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); - - /* setup for context save */ - cp_name(ctx, cp_setup_save); - cp_set (ctx, SWAP_DIRECTION, SAVE); - - /* general PGRAPH state */ - cp_name(ctx, cp_swap_state); - cp_pos (ctx, 0x00020/4); - nv40_graph_construct_general(ctx); - cp_wait(ctx, STATUS, IDLE); - - /* 3D state, block 1 */ - cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit); - nv40_graph_construct_state3d(ctx); - cp_wait(ctx, STATUS, IDLE); - - /* 3D state, block 2 */ - nv40_graph_construct_state3d_2(ctx); - - /* Some other block of "random" state */ - nv40_graph_construct_state3d_3(ctx); - - /* Per-vertex shader state */ - cp_pos (ctx, ctx->ctxvals_pos); - nv40_graph_construct_shader(ctx); - - /* pre-exit state updates */ - cp_name(ctx, cp_prepare_exit); - cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); - cp_bra (ctx, USER_SAVE, PENDING, cp_exit); - cp_out (ctx, CP_NEXT_TO_CURRENT); - - cp_name(ctx, cp_exit); - cp_set (ctx, USER_SAVE, NOT_PENDING); - cp_set (ctx, USER_LOAD, NOT_PENDING); - cp_out (ctx, CP_END); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_mc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_mc.c deleted file mode 100644 index 03c0d4c3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_mc.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -int -nv40_mc_init(struct drm_device *dev) -{ - /* Power up everything, resetting each individual unit will - * be done later if needed. - */ - nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); - - if (nv44_graph_class(dev)) { - u32 tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA); - nv_wr32(dev, NV40_PMC_1700, tmp); - nv_wr32(dev, NV40_PMC_1704, 0); - nv_wr32(dev, NV40_PMC_1708, 0); - nv_wr32(dev, NV40_PMC_170C, tmp); - } - - return 0; -} - -void -nv40_mc_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_pm.c deleted file mode 100644 index c7615381..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv40_pm.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_bios.h" -#include "nouveau_pm.h" -#include "nouveau_hw.h" - -#define min2(a,b) ((a) < (b) ? (a) : (b)) - -static u32 -read_pll_1(struct drm_device *dev, u32 reg) -{ - u32 ctrl = nv_rd32(dev, reg + 0x00); - int P = (ctrl & 0x00070000) >> 16; - int N = (ctrl & 0x0000ff00) >> 8; - int M = (ctrl & 0x000000ff) >> 0; - u32 ref = 27000, clk = 0; - - if (ctrl & 0x80000000) - clk = ref * N / M; - - return clk >> P; -} - -static u32 -read_pll_2(struct drm_device *dev, u32 reg) -{ - u32 ctrl = nv_rd32(dev, reg + 0x00); - u32 coef = nv_rd32(dev, reg + 0x04); - int N2 = (coef & 0xff000000) >> 24; - int M2 = (coef & 0x00ff0000) >> 16; - int N1 = (coef & 0x0000ff00) >> 8; - int M1 = (coef & 0x000000ff) >> 0; - int P = (ctrl & 0x00070000) >> 16; - u32 ref = 27000, clk = 0; - - if ((ctrl & 0x80000000) && M1) { - clk = ref * N1 / M1; - if ((ctrl & 0x40000100) == 0x40000000) { - if (M2) - clk = clk * N2 / M2; - else - clk = 0; - } - } - - return clk >> P; -} - -static u32 -read_clk(struct drm_device *dev, u32 src) -{ - switch (src) { - case 3: - return read_pll_2(dev, 0x004000); - case 2: - return read_pll_1(dev, 0x004008); - default: - break; - } - - return 0; -} - -int -nv40_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - u32 ctrl = nv_rd32(dev, 0x00c040); - - perflvl->core = read_clk(dev, (ctrl & 0x00000003) >> 0); - perflvl->shader = read_clk(dev, (ctrl & 0x00000030) >> 4); - perflvl->memory = read_pll_2(dev, 0x4020); - return 0; -} - -struct nv40_pm_state { - u32 ctrl; - u32 npll_ctrl; - u32 npll_coef; - u32 spll; - u32 mpll_ctrl; - u32 mpll_coef; -}; - -static int -nv40_calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll, - u32 clk, int *N1, int *M1, int *N2, int *M2, int *log2P) -{ - struct nouveau_pll_vals coef; - int ret; - - ret = get_pll_limits(dev, reg, pll); - if (ret) - return ret; - - if (clk < pll->vco1.maxfreq) - pll->vco2.maxfreq = 0; - - ret = nouveau_calc_pll_mnp(dev, pll, clk, &coef); - if (ret == 0) - return -ERANGE; - - *N1 = coef.N1; - *M1 = coef.M1; - if (N2 && M2) { - if (pll->vco2.maxfreq) { - *N2 = coef.N2; - *M2 = coef.M2; - } else { - *N2 = 1; - *M2 = 1; - } - } - *log2P = coef.log2P; - return 0; -} - -void * -nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct nv40_pm_state *info; - struct pll_lims pll; - int N1, N2, M1, M2, log2P; - int ret; - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return ERR_PTR(-ENOMEM); - - /* core/geometric clock */ - ret = nv40_calc_pll(dev, 0x004000, &pll, perflvl->core, - &N1, &M1, &N2, &M2, &log2P); - if (ret < 0) - goto out; - - if (N2 == M2) { - info->npll_ctrl = 0x80000100 | (log2P << 16); - info->npll_coef = (N1 << 8) | M1; - } else { - info->npll_ctrl = 0xc0000000 | (log2P << 16); - info->npll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1; - } - - /* use the second PLL for shader/rop clock, if it differs from core */ - if (perflvl->shader && perflvl->shader != perflvl->core) { - ret = nv40_calc_pll(dev, 0x004008, &pll, perflvl->shader, - &N1, &M1, NULL, NULL, &log2P); - if (ret < 0) - goto out; - - info->spll = 0xc0000000 | (log2P << 16) | (N1 << 8) | M1; - info->ctrl = 0x00000223; - } else { - info->spll = 0x00000000; - info->ctrl = 0x00000333; - } - - /* memory clock */ - if (!perflvl->memory) { - info->mpll_ctrl = 0x00000000; - goto out; - } - - ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, - &N1, &M1, &N2, &M2, &log2P); - if (ret < 0) - goto out; - - info->mpll_ctrl = 0x80000000 | (log2P << 16); - info->mpll_ctrl |= min2(pll.log2p_bias + log2P, pll.max_log2p) << 20; - if (N2 == M2) { - info->mpll_ctrl |= 0x00000100; - info->mpll_coef = (N1 << 8) | M1; - } else { - info->mpll_ctrl |= 0x40000000; - info->mpll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1; - } - -out: - if (ret < 0) { - kfree(info); - info = ERR_PTR(ret); - } - return info; -} - -static bool -nv40_pm_gr_idle(void *data) -{ - struct drm_device *dev = data; - - if ((nv_rd32(dev, 0x400760) & 0x000000f0) >> 4 != - (nv_rd32(dev, 0x400760) & 0x0000000f)) - return false; - - if (nv_rd32(dev, 0x400700)) - return false; - - return true; -} - -int -nv40_pm_clocks_set(struct drm_device *dev, void *pre_state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv40_pm_state *info = pre_state; - unsigned long flags; - struct bit_entry M; - u32 crtc_mask = 0; - u8 sr1[2]; - int i, ret = -EAGAIN; - - /* determine which CRTCs are active, fetch VGA_SR1 for each */ - for (i = 0; i < 2; i++) { - u32 vbl = nv_rd32(dev, 0x600808 + (i * 0x2000)); - u32 cnt = 0; - do { - if (vbl != nv_rd32(dev, 0x600808 + (i * 0x2000))) { - nv_wr08(dev, 0x0c03c4 + (i * 0x2000), 0x01); - sr1[i] = nv_rd08(dev, 0x0c03c5 + (i * 0x2000)); - if (!(sr1[i] & 0x20)) - crtc_mask |= (1 << i); - break; - } - udelay(1); - } while (cnt++ < 32); - } - - /* halt and idle engines */ - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, 0x002500, 0x00000001, 0x00000000); - if (!nv_wait(dev, 0x002500, 0x00000010, 0x00000000)) - goto resume; - nv_mask(dev, 0x003220, 0x00000001, 0x00000000); - if (!nv_wait(dev, 0x003220, 0x00000010, 0x00000000)) - goto resume; - nv_mask(dev, 0x003200, 0x00000001, 0x00000000); - nv04_fifo_cache_pull(dev, false); - - if (!nv_wait_cb(dev, nv40_pm_gr_idle, dev)) - goto resume; - - ret = 0; - - /* set engine clocks */ - nv_mask(dev, 0x00c040, 0x00000333, 0x00000000); - nv_wr32(dev, 0x004004, info->npll_coef); - nv_mask(dev, 0x004000, 0xc0070100, info->npll_ctrl); - nv_mask(dev, 0x004008, 0xc007ffff, info->spll); - mdelay(5); - nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); - - if (!info->mpll_ctrl) - goto resume; - - /* wait for vblank start on active crtcs, disable memory access */ - for (i = 0; i < 2; i++) { - if (!(crtc_mask & (1 << i))) - continue; - nv_wait(dev, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000); - nv_wait(dev, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000); - nv_wr08(dev, 0x0c03c4 + (i * 0x2000), 0x01); - nv_wr08(dev, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20); - } - - /* prepare ram for reclocking */ - nv_wr32(dev, 0x1002d4, 0x00000001); /* precharge */ - nv_wr32(dev, 0x1002d0, 0x00000001); /* refresh */ - nv_wr32(dev, 0x1002d0, 0x00000001); /* refresh */ - nv_mask(dev, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */ - nv_wr32(dev, 0x1002dc, 0x00000001); /* enable self-refresh */ - - /* change the PLL of each memory partition */ - nv_mask(dev, 0x00c040, 0x0000c000, 0x00000000); - switch (dev_priv->chipset) { - case 0x40: - case 0x45: - case 0x41: - case 0x42: - case 0x47: - nv_mask(dev, 0x004044, 0xc0771100, info->mpll_ctrl); - nv_mask(dev, 0x00402c, 0xc0771100, info->mpll_ctrl); - nv_wr32(dev, 0x004048, info->mpll_coef); - nv_wr32(dev, 0x004030, info->mpll_coef); - case 0x43: - case 0x49: - case 0x4b: - nv_mask(dev, 0x004038, 0xc0771100, info->mpll_ctrl); - nv_wr32(dev, 0x00403c, info->mpll_coef); - default: - nv_mask(dev, 0x004020, 0xc0771100, info->mpll_ctrl); - nv_wr32(dev, 0x004024, info->mpll_coef); - break; - } - udelay(100); - nv_mask(dev, 0x00c040, 0x0000c000, 0x0000c000); - - /* re-enable normal operation of memory controller */ - nv_wr32(dev, 0x1002dc, 0x00000000); - nv_mask(dev, 0x100210, 0x80000000, 0x80000000); - udelay(100); - - /* execute memory reset script from vbios */ - if (!bit_table(dev, 'M', &M)) - nouveau_bios_init_exec(dev, ROM16(M.data[0])); - - /* make sure we're in vblank (hopefully the same one as before), and - * then re-enable crtc memory access - */ - for (i = 0; i < 2; i++) { - if (!(crtc_mask & (1 << i))) - continue; - nv_wait(dev, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000); - nv_wr08(dev, 0x0c03c4 + (i * 0x2000), 0x01); - nv_wr08(dev, 0x0c03c5 + (i * 0x2000), sr1[i]); - } - - /* resume engines */ -resume: - nv_wr32(dev, 0x003250, 0x00000001); - nv_mask(dev, 0x003220, 0x00000001, 0x00000001); - nv_wr32(dev, 0x003200, 0x00000001); - nv_wr32(dev, 0x002500, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - kfree(info); - return ret; -} - -int -nv40_pm_pwm_get(struct drm_device *dev, int line, u32 *divs, u32 *duty) -{ - if (line == 2) { - u32 reg = nv_rd32(dev, 0x0010f0); - if (reg & 0x80000000) { - *duty = (reg & 0x7fff0000) >> 16; - *divs = (reg & 0x00007fff); - return 0; - } - } else - if (line == 9) { - u32 reg = nv_rd32(dev, 0x0015f4); - if (reg & 0x80000000) { - *divs = nv_rd32(dev, 0x0015f8); - *duty = (reg & 0x7fffffff); - return 0; - } - } else { - NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", line); - return -ENODEV; - } - - return -EINVAL; -} - -int -nv40_pm_pwm_set(struct drm_device *dev, int line, u32 divs, u32 duty) -{ - if (line == 2) { - nv_wr32(dev, 0x0010f0, 0x80000000 | (duty << 16) | divs); - } else - if (line == 9) { - nv_wr32(dev, 0x0015f8, divs); - nv_wr32(dev, 0x0015f4, duty | 0x80000000); - } else { - NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", line); - return -ENODEV; - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_calc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_calc.c deleted file mode 100644 index 8cf63a8b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_calc.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" - -int -nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, - int *N1, int *M1, int *N2, int *M2, int *P) -{ - struct nouveau_pll_vals pll_vals; - int ret; - - ret = nouveau_calc_pll_mnp(dev, pll, clk, &pll_vals); - if (ret <= 0) - return ret; - - *N1 = pll_vals.N1; - *M1 = pll_vals.M1; - *N2 = pll_vals.N2; - *M2 = pll_vals.M2; - *P = pll_vals.log2P; - return ret; -} - -int -nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, - int *pN, int *pfN, int *pM, int *P) -{ - u32 best_err = ~0, err; - int M, lM, hM, N, fN; - - *P = pll->vco1.maxfreq / clk; - if (*P > pll->max_p) - *P = pll->max_p; - if (*P < pll->min_p) - *P = pll->min_p; - - lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq; - lM = max(lM, (int)pll->vco1.min_m); - hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq; - hM = min(hM, (int)pll->vco1.max_m); - - for (M = lM; M <= hM; M++) { - u32 tmp = clk * *P * M; - N = tmp / pll->refclk; - fN = tmp % pll->refclk; - if (!pfN && fN >= pll->refclk / 2) - N++; - - if (N < pll->vco1.min_n) - continue; - if (N > pll->vco1.max_n) - break; - - err = abs(clk - (pll->refclk * N / M / *P)); - if (err < best_err) { - best_err = err; - *pN = N; - *pM = M; - } - - if (pfN) { - *pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff; - return clk; - } - } - - if (unlikely(best_err == ~0)) { - NV_ERROR(dev, "unable to find matching pll values\n"); - return -EINVAL; - } - - return pll->refclk * *pN / *pM / *P; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_crtc.c deleted file mode 100644 index 701b9279..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_crtc.c +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_mode.h" -#include "drm_crtc_helper.h" - -#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) -#include "nouveau_reg.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" -#include "nouveau_fb.h" -#include "nouveau_connector.h" -#include "nv50_display.h" - -static void -nv50_crtc_lut_load(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); - int i; - - NV_DEBUG_KMS(crtc->dev, "\n"); - - for (i = 0; i < 256; i++) { - writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0); - writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2); - writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4); - } - - if (nv_crtc->lut.depth == 30) { - writew(nv_crtc->lut.r[i - 1] >> 2, lut + 8*i + 0); - writew(nv_crtc->lut.g[i - 1] >> 2, lut + 8*i + 2); - writew(nv_crtc->lut.b[i - 1] >> 2, lut + 8*i + 4); - } -} - -int -nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) -{ - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *evo = nv50_display(dev)->master; - int index = nv_crtc->index, ret; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked"); - - if (blanked) { - nv_crtc->cursor.hide(nv_crtc, false); - - ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5); - if (ret) { - NV_ERROR(dev, "no space while blanking crtc\n"); - return ret; - } - BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2); - OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK); - OUT_RING(evo, 0); - if (dev_priv->chipset != 0x50) { - BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1); - OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE); - } - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); - OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE); - } else { - if (nv_crtc->cursor.visible) - nv_crtc->cursor.show(nv_crtc, false); - else - nv_crtc->cursor.hide(nv_crtc, false); - - ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8); - if (ret) { - NV_ERROR(dev, "no space while unblanking crtc\n"); - return ret; - } - BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2); - OUT_RING(evo, nv_crtc->lut.depth == 8 ? - NV50_EVO_CRTC_CLUT_MODE_OFF : - NV50_EVO_CRTC_CLUT_MODE_ON); - OUT_RING(evo, nv_crtc->lut.nvbo->bo.offset >> 8); - if (dev_priv->chipset != 0x50) { - BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1); - OUT_RING(evo, NvEvoVRAM); - } - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_OFFSET), 2); - OUT_RING(evo, nv_crtc->fb.offset >> 8); - OUT_RING(evo, 0); - BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); - if (dev_priv->chipset != 0x50) - if (nv_crtc->fb.tile_flags == 0x7a00 || - nv_crtc->fb.tile_flags == 0xfe00) - OUT_RING(evo, NvEvoFB32); - else - if (nv_crtc->fb.tile_flags == 0x7000) - OUT_RING(evo, NvEvoFB16); - else - OUT_RING(evo, NvEvoVRAM_LP); - else - OUT_RING(evo, NvEvoVRAM_LP); - } - - nv_crtc->fb.blanked = blanked; - return 0; -} - -static int -nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) -{ - struct nouveau_channel *evo = nv50_display(nv_crtc->base.dev)->master; - struct nouveau_connector *nv_connector; - struct drm_connector *connector; - int head = nv_crtc->index, ret; - u32 mode = 0x00; - - nv_connector = nouveau_crtc_connector_get(nv_crtc); - connector = &nv_connector->base; - if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) { - if (nv_crtc->base.fb->depth > connector->display_info.bpc * 3) - mode = DITHERING_MODE_DYNAMIC2X2; - } else { - mode = nv_connector->dithering_mode; - } - - if (nv_connector->dithering_depth == DITHERING_DEPTH_AUTO) { - if (connector->display_info.bpc >= 8) - mode |= DITHERING_DEPTH_8BPC; - } else { - mode |= nv_connector->dithering_depth; - } - - ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); - if (ret == 0) { - BEGIN_RING(evo, 0, NV50_EVO_CRTC(head, DITHER_CTRL), 1); - OUT_RING (evo, mode); - if (update) { - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING (evo, 0); - FIRE_RING (evo); - } - } - - return ret; -} - -static int -nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) -{ - struct drm_device *dev = nv_crtc->base.dev; - struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - int adj; - u32 hue, vib; - - NV_DEBUG_KMS(dev, "vibrance = %i, hue = %i\n", - nv_crtc->color_vibrance, nv_crtc->vibrant_hue); - - ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); - if (ret) { - NV_ERROR(dev, "no space while setting color vibrance\n"); - return ret; - } - - adj = (nv_crtc->color_vibrance > 0) ? 50 : 0; - vib = ((nv_crtc->color_vibrance * 2047 + adj) / 100) & 0xfff; - - hue = ((nv_crtc->vibrant_hue * 2047) / 100) & 0xfff; - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); - OUT_RING (evo, (hue << 20) | (vib << 8)); - - if (update) { - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING (evo, 0); - FIRE_RING (evo); - } - - return 0; -} - -struct nouveau_connector * -nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) -{ - struct drm_device *dev = nv_crtc->base.dev; - struct drm_connector *connector; - struct drm_crtc *crtc = to_drm_crtc(nv_crtc); - - /* The safest approach is to find an encoder with the right crtc, that - * is also linked to a connector. */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder) - if (connector->encoder->crtc == crtc) - return nouveau_connector(connector); - } - - return NULL; -} - -static int -nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) -{ - struct nouveau_connector *nv_connector; - struct drm_crtc *crtc = &nv_crtc->base; - struct drm_device *dev = crtc->dev; - struct nouveau_channel *evo = nv50_display(dev)->master; - struct drm_display_mode *umode = &crtc->mode; - struct drm_display_mode *omode; - int scaling_mode, ret; - u32 ctrl = 0, oX, oY; - - NV_DEBUG_KMS(dev, "\n"); - - nv_connector = nouveau_crtc_connector_get(nv_crtc); - if (!nv_connector || !nv_connector->native_mode) { - NV_ERROR(dev, "no native mode, forcing panel scaling\n"); - scaling_mode = DRM_MODE_SCALE_NONE; - } else { - scaling_mode = nv_connector->scaling_mode; - } - - /* start off at the resolution we programmed the crtc for, this - * effectively handles NONE/FULL scaling - */ - if (scaling_mode != DRM_MODE_SCALE_NONE) - omode = nv_connector->native_mode; - else - omode = umode; - - oX = omode->hdisplay; - oY = omode->vdisplay; - if (omode->flags & DRM_MODE_FLAG_DBLSCAN) - oY *= 2; - - /* add overscan compensation if necessary, will keep the aspect - * ratio the same as the backend mode unless overridden by the - * user setting both hborder and vborder properties. - */ - if (nv_connector && ( nv_connector->underscan == UNDERSCAN_ON || - (nv_connector->underscan == UNDERSCAN_AUTO && - nv_connector->edid && - drm_detect_hdmi_monitor(nv_connector->edid)))) { - u32 bX = nv_connector->underscan_hborder; - u32 bY = nv_connector->underscan_vborder; - u32 aspect = (oY << 19) / oX; - - if (bX) { - oX -= (bX * 2); - if (bY) oY -= (bY * 2); - else oY = ((oX * aspect) + (aspect / 2)) >> 19; - } else { - oX -= (oX >> 4) + 32; - if (bY) oY -= (bY * 2); - else oY = ((oX * aspect) + (aspect / 2)) >> 19; - } - } - - /* handle CENTER/ASPECT scaling, taking into account the areas - * removed already for overscan compensation - */ - switch (scaling_mode) { - case DRM_MODE_SCALE_CENTER: - oX = min((u32)umode->hdisplay, oX); - oY = min((u32)umode->vdisplay, oY); - /* fall-through */ - case DRM_MODE_SCALE_ASPECT: - if (oY < oX) { - u32 aspect = (umode->hdisplay << 19) / umode->vdisplay; - oX = ((oY * aspect) + (aspect / 2)) >> 19; - } else { - u32 aspect = (umode->vdisplay << 19) / umode->hdisplay; - oY = ((oX * aspect) + (aspect / 2)) >> 19; - } - break; - default: - break; - } - - if (umode->hdisplay != oX || umode->vdisplay != oY || - umode->flags & DRM_MODE_FLAG_INTERLACE || - umode->flags & DRM_MODE_FLAG_DBLSCAN) - ctrl |= NV50_EVO_CRTC_SCALE_CTRL_ACTIVE; - - ret = RING_SPACE(evo, 5); - if (ret) - return ret; - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CTRL), 1); - OUT_RING (evo, ctrl); - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_RES1), 2); - OUT_RING (evo, oY << 16 | oX); - OUT_RING (evo, oY << 16 | oX); - - if (update) { - nv50_display_flip_stop(crtc); - nv50_display_sync(dev); - nv50_display_flip_next(crtc, crtc->fb, NULL); - } - - return 0; -} - -int -nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct pll_lims pll; - uint32_t reg1, reg2; - int ret, N1, M1, N2, M2, P; - - ret = get_pll_limits(dev, PLL_VPLL0 + head, &pll); - if (ret) - return ret; - - if (pll.vco2.maxfreq) { - ret = nv50_calc_pll(dev, &pll, pclk, &N1, &M1, &N2, &M2, &P); - if (ret <= 0) - return 0; - - NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n", - pclk, ret, N1, M1, N2, M2, P); - - reg1 = nv_rd32(dev, pll.reg + 4) & 0xff00ff00; - reg2 = nv_rd32(dev, pll.reg + 8) & 0x8000ff00; - nv_wr32(dev, pll.reg + 0, 0x10000611); - nv_wr32(dev, pll.reg + 4, reg1 | (M1 << 16) | N1); - nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2); - } else - if (dev_priv->chipset < NV_C0) { - ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P); - if (ret <= 0) - return 0; - - NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n", - pclk, ret, N1, N2, M1, P); - - reg1 = nv_rd32(dev, pll.reg + 4) & 0xffc00000; - nv_wr32(dev, pll.reg + 0, 0x50000610); - nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1); - nv_wr32(dev, pll.reg + 8, N2); - } else { - ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P); - if (ret <= 0) - return 0; - - NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n", - pclk, ret, N1, N2, M1, P); - - nv_mask(dev, pll.reg + 0x0c, 0x00000000, 0x00000100); - nv_wr32(dev, pll.reg + 0x04, (P << 16) | (N1 << 8) | M1); - nv_wr32(dev, pll.reg + 0x10, N2 << 16); - } - - return 0; -} - -static void -nv50_crtc_destroy(struct drm_crtc *crtc) -{ - struct drm_device *dev; - struct nouveau_crtc *nv_crtc; - - if (!crtc) - return; - - dev = crtc->dev; - nv_crtc = nouveau_crtc(crtc); - - NV_DEBUG_KMS(dev, "\n"); - - drm_crtc_cleanup(&nv_crtc->base); - - nouveau_bo_unmap(nv_crtc->lut.nvbo); - nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); - nouveau_bo_unmap(nv_crtc->cursor.nvbo); - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); - kfree(nv_crtc); -} - -int -nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - uint32_t buffer_handle, uint32_t width, uint32_t height) -{ - struct drm_device *dev = crtc->dev; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nouveau_bo *cursor = NULL; - struct drm_gem_object *gem; - int ret = 0, i; - - if (!buffer_handle) { - nv_crtc->cursor.hide(nv_crtc, true); - return 0; - } - - if (width != 64 || height != 64) - return -EINVAL; - - gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); - if (!gem) - return -ENOENT; - cursor = nouveau_gem_object(gem); - - ret = nouveau_bo_map(cursor); - if (ret) - goto out; - - /* The simple will do for now. */ - for (i = 0; i < 64 * 64; i++) - nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, nouveau_bo_rd32(cursor, i)); - - nouveau_bo_unmap(cursor); - - nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset); - nv_crtc->cursor.show(nv_crtc, true); - -out: - drm_gem_object_unreference_unlocked(gem); - return ret; -} - -int -nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - nv_crtc->cursor.set_pos(nv_crtc, x, y); - return 0; -} - -static void -nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, - uint32_t start, uint32_t size) -{ - int end = (start + size > 256) ? 256 : start + size, i; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - for (i = start; i < end; i++) { - nv_crtc->lut.r[i] = r[i]; - nv_crtc->lut.g[i] = g[i]; - nv_crtc->lut.b[i] = b[i]; - } - - /* We need to know the depth before we upload, but it's possible to - * get called before a framebuffer is bound. If this is the case, - * mark the lut values as dirty by setting depth==0, and it'll be - * uploaded on the first mode_set_base() - */ - if (!nv_crtc->base.fb) { - nv_crtc->lut.depth = 0; - return; - } - - nv50_crtc_lut_load(crtc); -} - -static void -nv50_crtc_save(struct drm_crtc *crtc) -{ - NV_ERROR(crtc->dev, "!!\n"); -} - -static void -nv50_crtc_restore(struct drm_crtc *crtc) -{ - NV_ERROR(crtc->dev, "!!\n"); -} - -static const struct drm_crtc_funcs nv50_crtc_funcs = { - .save = nv50_crtc_save, - .restore = nv50_crtc_restore, - .cursor_set = nv50_crtc_cursor_set, - .cursor_move = nv50_crtc_cursor_move, - .gamma_set = nv50_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, - .page_flip = nouveau_crtc_page_flip, - .destroy = nv50_crtc_destroy, -}; - -static void -nv50_crtc_dpms(struct drm_crtc *crtc, int mode) -{ -} - -static void -nv50_crtc_prepare(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = crtc->dev; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - - nv50_display_flip_stop(crtc); - drm_vblank_pre_modeset(dev, nv_crtc->index); - nv50_crtc_blank(nv_crtc, true); -} - -static void -nv50_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - - nv50_crtc_blank(nv_crtc, false); - drm_vblank_post_modeset(dev, nv_crtc->index); - nv50_display_sync(dev); - nv50_display_flip_next(crtc, crtc->fb, NULL); -} - -static bool -nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static int -nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *passed_fb, - int x, int y, bool atomic) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *evo = nv50_display(dev)->master; - struct drm_framebuffer *drm_fb; - struct nouveau_framebuffer *fb; - int ret; - - NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); - - /* no fb bound */ - if (!atomic && !crtc->fb) { - NV_DEBUG_KMS(dev, "No FB bound\n"); - return 0; - } - - /* If atomic, we want to switch to the fb we were passed, so - * now we update pointers to do that. (We don't pin; just - * assume we're already pinned and update the base address.) - */ - if (atomic) { - drm_fb = passed_fb; - fb = nouveau_framebuffer(passed_fb); - } else { - drm_fb = crtc->fb; - fb = nouveau_framebuffer(crtc->fb); - /* If not atomic, we can go ahead and pin, and unpin the - * old fb we were passed. - */ - ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); - if (ret) - return ret; - - if (passed_fb) { - struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb); - nouveau_bo_unpin(ofb->nvbo); - } - } - - nv_crtc->fb.offset = fb->nvbo->bo.offset; - nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); - nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; - if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { - ret = RING_SPACE(evo, 2); - if (ret) - return ret; - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); - OUT_RING (evo, fb->r_dma); - } - - ret = RING_SPACE(evo, 12); - if (ret) - return ret; - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); - OUT_RING (evo, nv_crtc->fb.offset >> 8); - OUT_RING (evo, 0); - OUT_RING (evo, (drm_fb->height << 16) | drm_fb->width); - OUT_RING (evo, fb->r_pitch); - OUT_RING (evo, fb->r_format); - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); - OUT_RING (evo, fb->base.depth == 8 ? - NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); - - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); - OUT_RING (evo, (y << 16) | x); - - if (nv_crtc->lut.depth != fb->base.depth) { - nv_crtc->lut.depth = fb->base.depth; - nv50_crtc_lut_load(crtc); - } - - return 0; -} - -static int -nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, - struct drm_display_mode *mode, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct nouveau_channel *evo = nv50_display(dev)->master; - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - u32 head = nv_crtc->index * 0x400; - u32 ilace = (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1; - u32 vscan = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1; - u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks; - u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks; - u32 vblan2e = 0, vblan2s = 1; - int ret; - - /* hw timing description looks like this: - * - * <---------display---------> - * ______ - * |____________|---------------------------|____________| - * - * ^ synce ^ blanke ^ blanks ^ active - * - * interlaced modes also have 2 additional values pointing at the end - * and start of the next field's blanking period. - */ - - hactive = mode->htotal; - hsynce = mode->hsync_end - mode->hsync_start - 1; - hbackp = mode->htotal - mode->hsync_end; - hblanke = hsynce + hbackp; - hfrontp = mode->hsync_start - mode->hdisplay; - hblanks = mode->htotal - hfrontp - 1; - - vactive = mode->vtotal * vscan / ilace; - vsynce = ((mode->vsync_end - mode->vsync_start) * vscan / ilace) - 1; - vbackp = (mode->vtotal - mode->vsync_end) * vscan / ilace; - vblanke = vsynce + vbackp; - vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace; - vblanks = vactive - vfrontp - 1; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { - vblan2e = vactive + vsynce + vbackp; - vblan2s = vblan2e + (mode->vdisplay * vscan / ilace); - vactive = (vactive * 2) + 1; - } - - ret = RING_SPACE(evo, 18); - if (ret == 0) { - BEGIN_RING(evo, 0, 0x0804 + head, 2); - OUT_RING (evo, 0x00800000 | mode->clock); - OUT_RING (evo, (ilace == 2) ? 2 : 0); - BEGIN_RING(evo, 0, 0x0810 + head, 6); - OUT_RING (evo, 0x00000000); /* border colour */ - OUT_RING (evo, (vactive << 16) | hactive); - OUT_RING (evo, ( vsynce << 16) | hsynce); - OUT_RING (evo, (vblanke << 16) | hblanke); - OUT_RING (evo, (vblanks << 16) | hblanks); - OUT_RING (evo, (vblan2e << 16) | vblan2s); - BEGIN_RING(evo, 0, 0x082c + head, 1); - OUT_RING (evo, 0x00000000); - BEGIN_RING(evo, 0, 0x0900 + head, 1); - OUT_RING (evo, 0x00000311); /* makes sync channel work */ - BEGIN_RING(evo, 0, 0x08c8 + head, 1); - OUT_RING (evo, (umode->vdisplay << 16) | umode->hdisplay); - BEGIN_RING(evo, 0, 0x08d4 + head, 1); - OUT_RING (evo, 0x00000000); /* screen position */ - } - - nv_crtc->set_dither(nv_crtc, false); - nv_crtc->set_scale(nv_crtc, false); - nv_crtc->set_color_vibrance(nv_crtc, false); - - return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false); -} - -static int -nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - int ret; - - nv50_display_flip_stop(crtc); - ret = nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false); - if (ret) - return ret; - - ret = nv50_display_sync(crtc->dev); - if (ret) - return ret; - - return nv50_display_flip_next(crtc, crtc->fb, NULL); -} - -static int -nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) -{ - int ret; - - nv50_display_flip_stop(crtc); - ret = nv50_crtc_do_mode_set_base(crtc, fb, x, y, true); - if (ret) - return ret; - - return nv50_display_sync(crtc->dev); -} - -static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { - .dpms = nv50_crtc_dpms, - .prepare = nv50_crtc_prepare, - .commit = nv50_crtc_commit, - .mode_fixup = nv50_crtc_mode_fixup, - .mode_set = nv50_crtc_mode_set, - .mode_set_base = nv50_crtc_mode_set_base, - .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic, - .load_lut = nv50_crtc_lut_load, -}; - -int -nv50_crtc_create(struct drm_device *dev, int index) -{ - struct nouveau_crtc *nv_crtc = NULL; - int ret, i; - - NV_DEBUG_KMS(dev, "\n"); - - nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); - if (!nv_crtc) - return -ENOMEM; - - nv_crtc->color_vibrance = 50; - nv_crtc->vibrant_hue = 0; - - /* Default CLUT parameters, will be activated on the hw upon - * first mode set. - */ - for (i = 0; i < 256; i++) { - nv_crtc->lut.r[i] = i << 8; - nv_crtc->lut.g[i] = i << 8; - nv_crtc->lut.b[i] = i << 8; - } - nv_crtc->lut.depth = 0; - - ret = nouveau_bo_new(dev, 4096, 0x100, TTM_PL_FLAG_VRAM, - 0, 0x0000, &nv_crtc->lut.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(nv_crtc->lut.nvbo); - if (ret) - nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); - } - - if (ret) { - kfree(nv_crtc); - return ret; - } - - nv_crtc->index = index; - - /* set function pointers */ - nv_crtc->set_dither = nv50_crtc_set_dither; - nv_crtc->set_scale = nv50_crtc_set_scale; - nv_crtc->set_color_vibrance = nv50_crtc_set_color_vibrance; - - drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs); - drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs); - drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); - - ret = nouveau_bo_new(dev, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, - 0, 0x0000, &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(nv_crtc->cursor.nvbo); - if (ret) - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); - } - - nv50_cursor_init(nv_crtc); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_cursor.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_cursor.c deleted file mode 100644 index adfc9b60..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_cursor.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_mode.h" - -#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) -#include "nouveau_reg.h" -#include "nouveau_drv.h" -#include "nouveau_crtc.h" -#include "nv50_display.h" - -static void -nv50_cursor_show(struct nouveau_crtc *nv_crtc, bool update) -{ - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - NV_DEBUG_KMS(dev, "\n"); - - if (update && nv_crtc->cursor.visible) - return; - - ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2); - if (ret) { - NV_ERROR(dev, "no space while unhiding cursor\n"); - return; - } - - if (dev_priv->chipset != 0x50) { - BEGIN_RING(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1); - OUT_RING(evo, NvEvoVRAM); - } - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2); - OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_SHOW); - OUT_RING(evo, nv_crtc->cursor.offset >> 8); - - if (update) { - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING(evo, 0); - FIRE_RING(evo); - nv_crtc->cursor.visible = true; - } -} - -static void -nv50_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) -{ - struct drm_device *dev = nv_crtc->base.dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - NV_DEBUG_KMS(dev, "\n"); - - if (update && !nv_crtc->cursor.visible) - return; - - ret = RING_SPACE(evo, (dev_priv->chipset != 0x50 ? 5 : 3) + update * 2); - if (ret) { - NV_ERROR(dev, "no space while hiding cursor\n"); - return; - } - BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CURSOR_CTRL), 2); - OUT_RING(evo, NV50_EVO_CRTC_CURSOR_CTRL_HIDE); - OUT_RING(evo, 0); - if (dev_priv->chipset != 0x50) { - BEGIN_RING(evo, 0, NV84_EVO_CRTC(nv_crtc->index, CURSOR_DMA), 1); - OUT_RING(evo, NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE); - } - - if (update) { - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING(evo, 0); - FIRE_RING(evo); - nv_crtc->cursor.visible = false; - } -} - -static void -nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) -{ - struct drm_device *dev = nv_crtc->base.dev; - - nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y; - nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index), - ((y & 0xFFFF) << 16) | (x & 0xFFFF)); - /* Needed to make the cursor move. */ - nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS_CTRL(nv_crtc->index), 0); -} - -static void -nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) -{ - NV_DEBUG_KMS(nv_crtc->base.dev, "\n"); - if (offset == nv_crtc->cursor.offset) - return; - - nv_crtc->cursor.offset = offset; - if (nv_crtc->cursor.visible) { - nv_crtc->cursor.visible = false; - nv_crtc->cursor.show(nv_crtc, true); - } -} - -int -nv50_cursor_init(struct nouveau_crtc *nv_crtc) -{ - nv_crtc->cursor.set_offset = nv50_cursor_set_offset; - nv_crtc->cursor.set_pos = nv50_cursor_set_pos; - nv_crtc->cursor.hide = nv50_cursor_hide; - nv_crtc->cursor.show = nv50_cursor_show; - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_dac.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_dac.c deleted file mode 100644 index 55c56330..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_dac.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) -#include "nouveau_reg.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nv50_display.h" - -static void -nv50_dac_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - if (!nv_encoder->crtc) - return; - nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); - - NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or); - - ret = RING_SPACE(evo, 4); - if (ret) { - NV_ERROR(dev, "no space while disconnecting DAC\n"); - return; - } - BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1); - OUT_RING (evo, 0); - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING (evo, 0); - - nv_encoder->crtc = NULL; -} - -static enum drm_connector_status -nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - enum drm_connector_status status = connector_status_disconnected; - uint32_t dpms_state, load_pattern, load_state; - int or = nv_encoder->or; - - nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001); - dpms_state = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)); - - nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), - 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); - if (!nv_wait(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { - NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); - NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, - nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); - return status; - } - - /* Use bios provided value if possible. */ - if (dev_priv->vbios.dactestval) { - load_pattern = dev_priv->vbios.dactestval; - NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n", - load_pattern); - } else { - load_pattern = 340; - NV_DEBUG_KMS(dev, "Using default load_pattern of %d\n", - load_pattern); - } - - nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), - NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern); - mdelay(45); /* give it some time to process */ - load_state = nv_rd32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or)); - - nv_wr32(dev, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0); - nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state | - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); - - if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) == - NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) - status = connector_status_connected; - - if (status == connector_status_connected) - NV_DEBUG_KMS(dev, "Load was detected on output with or %d\n", or); - else - NV_DEBUG_KMS(dev, "Load was not detected on output with or %d\n", or); - - return status; -} - -static void -nv50_dac_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - uint32_t val; - int or = nv_encoder->or; - - NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode); - - /* wait for it to be done */ - if (!nv_wait(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { - NV_ERROR(dev, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); - NV_ERROR(dev, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, - nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); - return; - } - - val = nv_rd32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or)) & ~0x7F; - - if (mode != DRM_MODE_DPMS_ON) - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_BLANKED; - - switch (mode) { - case DRM_MODE_DPMS_STANDBY: - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF; - break; - case DRM_MODE_DPMS_SUSPEND: - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF; - break; - case DRM_MODE_DPMS_OFF: - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_OFF; - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_HSYNC_OFF; - val |= NV50_PDISPLAY_DAC_DPMS_CTRL_VSYNC_OFF; - break; - default: - break; - } - - nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(or), val | - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); -} - -static void -nv50_dac_save(struct drm_encoder *encoder) -{ - NV_ERROR(encoder->dev, "!!\n"); -} - -static void -nv50_dac_restore(struct drm_encoder *encoder) -{ - NV_ERROR(encoder->dev, "!!\n"); -} - -static bool -nv50_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *connector; - - NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or); - - connector = nouveau_encoder_connector_get(nv_encoder); - if (!connector) { - NV_ERROR(encoder->dev, "Encoder has no connector\n"); - return false; - } - - if (connector->scaling_mode != DRM_MODE_SCALE_NONE && - connector->native_mode) - drm_mode_copy(adjusted_mode, connector->native_mode); - - return true; -} - -static void -nv50_dac_commit(struct drm_encoder *encoder) -{ -} - -static void -nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_channel *evo = nv50_display(dev)->master; - struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); - uint32_t mode_ctl = 0, mode_ctl2 = 0; - int ret; - - NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n", - nv_encoder->or, nv_encoder->dcb->type, crtc->index); - - nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); - - if (crtc->index == 1) - mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC1; - else - mode_ctl |= NV50_EVO_DAC_MODE_CTRL_CRTC0; - - /* Lacking a working tv-out, this is not a 100% sure. */ - if (nv_encoder->dcb->type == OUTPUT_ANALOG) - mode_ctl |= 0x40; - else - if (nv_encoder->dcb->type == OUTPUT_TV) - mode_ctl |= 0x100; - - if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) - mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NHSYNC; - - if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) - mode_ctl2 |= NV50_EVO_DAC_MODE_CTRL2_NVSYNC; - - ret = RING_SPACE(evo, 3); - if (ret) { - NV_ERROR(dev, "no space while connecting DAC\n"); - return; - } - BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2); - OUT_RING(evo, mode_ctl); - OUT_RING(evo, mode_ctl2); - - nv_encoder->crtc = encoder->crtc; -} - -static struct drm_crtc * -nv50_dac_crtc_get(struct drm_encoder *encoder) -{ - return nouveau_encoder(encoder)->crtc; -} - -static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = { - .dpms = nv50_dac_dpms, - .save = nv50_dac_save, - .restore = nv50_dac_restore, - .mode_fixup = nv50_dac_mode_fixup, - .prepare = nv50_dac_disconnect, - .commit = nv50_dac_commit, - .mode_set = nv50_dac_mode_set, - .get_crtc = nv50_dac_crtc_get, - .detect = nv50_dac_detect, - .disable = nv50_dac_disconnect -}; - -static void -nv50_dac_destroy(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (!encoder) - return; - - NV_DEBUG_KMS(encoder->dev, "\n"); - - drm_encoder_cleanup(encoder); - kfree(nv_encoder); -} - -static const struct drm_encoder_funcs nv50_dac_encoder_funcs = { - .destroy = nv50_dac_destroy, -}; - -int -nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry) -{ - struct nouveau_encoder *nv_encoder; - struct drm_encoder *encoder; - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - encoder = to_drm_encoder(nv_encoder); - - nv_encoder->dcb = entry; - nv_encoder->or = ffs(entry->or) - 1; - - drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs, - DRM_MODE_ENCODER_DAC); - drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); - - encoder->possible_crtcs = entry->heads; - encoder->possible_clones = 0; - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.c deleted file mode 100644 index 8b78b9cf..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.c +++ /dev/null @@ -1,1038 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) -#include "nv50_display.h" -#include "nouveau_crtc.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_fb.h" -#include "nouveau_fbcon.h" -#include "nouveau_ramht.h" -#include "drm_crtc_helper.h" - -static void nv50_display_isr(struct drm_device *); -static void nv50_display_bh(unsigned long); - -static inline int -nv50_sor_nr(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset < 0x90 || - dev_priv->chipset == 0x92 || - dev_priv->chipset == 0xa0) - return 2; - - return 4; -} - -u32 -nv50_display_active_crtcs(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 mask = 0; - int i; - - if (dev_priv->chipset < 0x90 || - dev_priv->chipset == 0x92 || - dev_priv->chipset == 0xa0) { - for (i = 0; i < 2; i++) - mask |= nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); - } else { - for (i = 0; i < 4; i++) - mask |= nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); - } - - for (i = 0; i < 3; i++) - mask |= nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); - - return mask & 3; -} - -static int -evo_icmd(struct drm_device *dev, int ch, u32 mthd, u32 data) -{ - int ret = 0; - nv_mask(dev, 0x610300 + (ch * 0x08), 0x00000001, 0x00000001); - nv_wr32(dev, 0x610304 + (ch * 0x08), data); - nv_wr32(dev, 0x610300 + (ch * 0x08), 0x80000001 | mthd); - if (!nv_wait(dev, 0x610300 + (ch * 0x08), 0x80000000, 0x00000000)) - ret = -EBUSY; - if (ret || (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)) - NV_INFO(dev, "EvoPIO: %d 0x%04x 0x%08x\n", ch, mthd, data); - nv_mask(dev, 0x610300 + (ch * 0x08), 0x00000001, 0x00000000); - return ret; -} - -int -nv50_display_early_init(struct drm_device *dev) -{ - u32 ctrl = nv_rd32(dev, 0x610200); - int i; - - /* check if master evo channel is already active, a good a sign as any - * that the display engine is in a weird state (hibernate/kexec), if - * it is, do our best to reset the display engine... - */ - if ((ctrl & 0x00000003) == 0x00000003) { - NV_INFO(dev, "PDISP: EVO(0) 0x%08x, resetting...\n", ctrl); - - /* deactivate both heads first, PDISP will disappear forever - * (well, until you power cycle) on some boards as soon as - * PMC_ENABLE is hit unless they are.. - */ - for (i = 0; i < 2; i++) { - evo_icmd(dev, 0, 0x0880 + (i * 0x400), 0x05000000); - evo_icmd(dev, 0, 0x089c + (i * 0x400), 0); - evo_icmd(dev, 0, 0x0840 + (i * 0x400), 0); - evo_icmd(dev, 0, 0x0844 + (i * 0x400), 0); - evo_icmd(dev, 0, 0x085c + (i * 0x400), 0); - evo_icmd(dev, 0, 0x0874 + (i * 0x400), 0); - } - evo_icmd(dev, 0, 0x0080, 0); - - /* reset PDISP */ - nv_mask(dev, 0x000200, 0x40000000, 0x00000000); - nv_mask(dev, 0x000200, 0x40000000, 0x40000000); - } - - return 0; -} - -void -nv50_display_late_takedown(struct drm_device *dev) -{ -} - -int -nv50_display_sync(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - struct nv50_display *disp = nv50_display(dev); - struct nouveau_channel *evo = disp->master; - u64 start; - int ret; - - ret = RING_SPACE(evo, 6); - if (ret == 0) { - BEGIN_RING(evo, 0, 0x0084, 1); - OUT_RING (evo, 0x80000000); - BEGIN_RING(evo, 0, 0x0080, 1); - OUT_RING (evo, 0); - BEGIN_RING(evo, 0, 0x0084, 1); - OUT_RING (evo, 0x00000000); - - nv_wo32(disp->ntfy, 0x000, 0x00000000); - FIRE_RING (evo); - - start = ptimer->read(dev); - do { - if (nv_ro32(disp->ntfy, 0x000)) - return 0; - } while (ptimer->read(dev) - start < 2000000000ULL); - } - - return -EBUSY; -} - -int -nv50_display_init(struct drm_device *dev) -{ - struct nouveau_channel *evo; - int ret, i; - u32 val; - - NV_DEBUG_KMS(dev, "\n"); - - nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); - - /* - * I think the 0x006101XX range is some kind of main control area - * that enables things. - */ - /* CRTC? */ - for (i = 0; i < 2; i++) { - val = nv_rd32(dev, 0x00616100 + (i * 0x800)); - nv_wr32(dev, 0x00610190 + (i * 0x10), val); - val = nv_rd32(dev, 0x00616104 + (i * 0x800)); - nv_wr32(dev, 0x00610194 + (i * 0x10), val); - val = nv_rd32(dev, 0x00616108 + (i * 0x800)); - nv_wr32(dev, 0x00610198 + (i * 0x10), val); - val = nv_rd32(dev, 0x0061610c + (i * 0x800)); - nv_wr32(dev, 0x0061019c + (i * 0x10), val); - } - - /* DAC */ - for (i = 0; i < 3; i++) { - val = nv_rd32(dev, 0x0061a000 + (i * 0x800)); - nv_wr32(dev, 0x006101d0 + (i * 0x04), val); - } - - /* SOR */ - for (i = 0; i < nv50_sor_nr(dev); i++) { - val = nv_rd32(dev, 0x0061c000 + (i * 0x800)); - nv_wr32(dev, 0x006101e0 + (i * 0x04), val); - } - - /* EXT */ - for (i = 0; i < 3; i++) { - val = nv_rd32(dev, 0x0061e000 + (i * 0x800)); - nv_wr32(dev, 0x006101f0 + (i * 0x04), val); - } - - for (i = 0; i < 3; i++) { - nv_wr32(dev, NV50_PDISPLAY_DAC_DPMS_CTRL(i), 0x00550000 | - NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); - nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001); - } - - /* The precise purpose is unknown, i suspect it has something to do - * with text mode. - */ - if (nv_rd32(dev, NV50_PDISPLAY_INTR_1) & 0x100) { - nv_wr32(dev, NV50_PDISPLAY_INTR_1, 0x100); - nv_wr32(dev, 0x006194e8, nv_rd32(dev, 0x006194e8) & ~1); - if (!nv_wait(dev, 0x006194e8, 2, 0)) { - NV_ERROR(dev, "timeout: (0x6194e8 & 2) != 0\n"); - NV_ERROR(dev, "0x6194e8 = 0x%08x\n", - nv_rd32(dev, 0x6194e8)); - return -EBUSY; - } - } - - for (i = 0; i < 2; i++) { - nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); - if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { - NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); - NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); - return -EBUSY; - } - - nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); - if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { - NV_ERROR(dev, "timeout: " - "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i); - NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i, - nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); - return -EBUSY; - } - } - - nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); - nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); - nv_wr32(dev, NV50_PDISPLAY_INTR_EN_0, 0x00000000); - nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); - nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, - NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 | - NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 | - NV50_PDISPLAY_INTR_EN_1_CLK_UNK40); - - ret = nv50_evo_init(dev); - if (ret) - return ret; - evo = nv50_display(dev)->master; - - nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); - - ret = RING_SPACE(evo, 3); - if (ret) - return ret; - BEGIN_RING(evo, 0, NV50_EVO_UNK84, 2); - OUT_RING (evo, NV50_EVO_UNK84_NOTIFY_DISABLED); - OUT_RING (evo, NvEvoSync); - - return nv50_display_sync(dev); -} - -void -nv50_display_fini(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - struct nouveau_channel *evo = disp->master; - struct drm_crtc *drm_crtc; - int ret, i; - - NV_DEBUG_KMS(dev, "\n"); - - list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); - - nv50_crtc_blank(crtc, true); - } - - ret = RING_SPACE(evo, 2); - if (ret == 0) { - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING(evo, 0); - } - FIRE_RING(evo); - - /* Almost like ack'ing a vblank interrupt, maybe in the spirit of - * cleaning up? - */ - list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { - struct nouveau_crtc *crtc = nouveau_crtc(drm_crtc); - uint32_t mask = NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(crtc->index); - - if (!crtc->base.enabled) - continue; - - nv_wr32(dev, NV50_PDISPLAY_INTR_1, mask); - if (!nv_wait(dev, NV50_PDISPLAY_INTR_1, mask, mask)) { - NV_ERROR(dev, "timeout: (0x610024 & 0x%08x) == " - "0x%08x\n", mask, mask); - NV_ERROR(dev, "0x610024 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_INTR_1)); - } - } - - for (i = 0; i < 2; i++) { - nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0); - if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { - NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); - NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); - } - } - - nv50_evo_fini(dev); - - for (i = 0; i < 3; i++) { - if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i), - NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { - NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", i); - NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", i, - nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i))); - } - } - - /* disable interrupts. */ - nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, 0x00000000); -} - -int -nv50_display_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct dcb_table *dcb = &dev_priv->vbios.dcb; - struct drm_connector *connector, *ct; - struct nv50_display *priv; - int ret, i; - - NV_DEBUG_KMS(dev, "\n"); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - dev_priv->engine.display.priv = priv; - - /* Create CRTC objects */ - for (i = 0; i < 2; i++) - nv50_crtc_create(dev, i); - - /* We setup the encoders from the BIOS table */ - for (i = 0 ; i < dcb->entries; i++) { - struct dcb_entry *entry = &dcb->entry[i]; - - if (entry->location != DCB_LOC_ON_CHIP) { - NV_WARN(dev, "Off-chip encoder %d/%d unsupported\n", - entry->type, ffs(entry->or) - 1); - continue; - } - - connector = nouveau_connector_create(dev, entry->connector); - if (IS_ERR(connector)) - continue; - - switch (entry->type) { - case OUTPUT_TMDS: - case OUTPUT_LVDS: - case OUTPUT_DP: - nv50_sor_create(connector, entry); - break; - case OUTPUT_ANALOG: - nv50_dac_create(connector, entry); - break; - default: - NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); - continue; - } - } - - list_for_each_entry_safe(connector, ct, - &dev->mode_config.connector_list, head) { - if (!connector->encoder_ids[0]) { - NV_WARN(dev, "%s has no encoders, removing\n", - drm_get_connector_name(connector)); - connector->funcs->destroy(connector); - } - } - - tasklet_init(&priv->tasklet, nv50_display_bh, (unsigned long)dev); - nouveau_irq_register(dev, 26, nv50_display_isr); - - ret = nv50_evo_create(dev); - if (ret) { - nv50_display_destroy(dev); - return ret; - } - - return 0; -} - -void -nv50_display_destroy(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - - NV_DEBUG_KMS(dev, "\n"); - - nv50_evo_destroy(dev); - nouveau_irq_unregister(dev, 26); - kfree(disp); -} - -void -nv50_display_flip_stop(struct drm_crtc *crtc) -{ - struct nv50_display *disp = nv50_display(crtc->dev); - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index]; - struct nouveau_channel *evo = dispc->sync; - int ret; - - ret = RING_SPACE(evo, 8); - if (ret) { - WARN_ON(1); - return; - } - - BEGIN_RING(evo, 0, 0x0084, 1); - OUT_RING (evo, 0x00000000); - BEGIN_RING(evo, 0, 0x0094, 1); - OUT_RING (evo, 0x00000000); - BEGIN_RING(evo, 0, 0x00c0, 1); - OUT_RING (evo, 0x00000000); - BEGIN_RING(evo, 0, 0x0080, 1); - OUT_RING (evo, 0x00000000); - FIRE_RING (evo); -} - -int -nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = crtc->dev->dev_private; - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); - struct nv50_display *disp = nv50_display(crtc->dev); - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nv50_display_crtc *dispc = &disp->crtc[nv_crtc->index]; - struct nouveau_channel *evo = dispc->sync; - int ret; - - ret = RING_SPACE(evo, chan ? 25 : 27); - if (unlikely(ret)) - return ret; - - /* synchronise with the rendering channel, if necessary */ - if (likely(chan)) { - ret = RING_SPACE(chan, 10); - if (ret) { - WIND_RING(evo); - return ret; - } - - if (dev_priv->chipset < 0xc0) { - BEGIN_RING(chan, 0, 0x0060, 2); - OUT_RING (chan, NvEvoSema0 + nv_crtc->index); - OUT_RING (chan, dispc->sem.offset); - BEGIN_RING(chan, 0, 0x006c, 1); - OUT_RING (chan, 0xf00d0000 | dispc->sem.value); - BEGIN_RING(chan, 0, 0x0064, 2); - OUT_RING (chan, dispc->sem.offset ^ 0x10); - OUT_RING (chan, 0x74b1e000); - BEGIN_RING(chan, 0, 0x0060, 1); - if (dev_priv->chipset < 0x84) - OUT_RING (chan, NvSema); - else - OUT_RING (chan, chan->vram_handle); - } else { - u64 offset = chan->dispc_vma[nv_crtc->index].offset; - offset += dispc->sem.offset; - BEGIN_NVC0(chan, 2, 0, 0x0010, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 0xf00d0000 | dispc->sem.value); - OUT_RING (chan, 0x1002); - BEGIN_NVC0(chan, 2, 0, 0x0010, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset ^ 0x10)); - OUT_RING (chan, 0x74b1e000); - OUT_RING (chan, 0x1001); - } - FIRE_RING (chan); - } else { - nouveau_bo_wr32(dispc->sem.bo, dispc->sem.offset / 4, - 0xf00d0000 | dispc->sem.value); - } - - /* queue the flip on the crtc's "display sync" channel */ - BEGIN_RING(evo, 0, 0x0100, 1); - OUT_RING (evo, 0xfffe0000); - if (chan) { - BEGIN_RING(evo, 0, 0x0084, 1); - OUT_RING (evo, 0x00000100); - } else { - BEGIN_RING(evo, 0, 0x0084, 1); - OUT_RING (evo, 0x00000010); - /* allows gamma somehow, PDISP will bitch at you if - * you don't wait for vblank before changing this.. - */ - BEGIN_RING(evo, 0, 0x00e0, 1); - OUT_RING (evo, 0x40000000); - } - BEGIN_RING(evo, 0, 0x0088, 4); - OUT_RING (evo, dispc->sem.offset); - OUT_RING (evo, 0xf00d0000 | dispc->sem.value); - OUT_RING (evo, 0x74b1e000); - OUT_RING (evo, NvEvoSync); - BEGIN_RING(evo, 0, 0x00a0, 2); - OUT_RING (evo, 0x00000000); - OUT_RING (evo, 0x00000000); - BEGIN_RING(evo, 0, 0x00c0, 1); - OUT_RING (evo, nv_fb->r_dma); - BEGIN_RING(evo, 0, 0x0110, 2); - OUT_RING (evo, 0x00000000); - OUT_RING (evo, 0x00000000); - BEGIN_RING(evo, 0, 0x0800, 5); - OUT_RING (evo, nv_fb->nvbo->bo.offset >> 8); - OUT_RING (evo, 0); - OUT_RING (evo, (fb->height << 16) | fb->width); - OUT_RING (evo, nv_fb->r_pitch); - OUT_RING (evo, nv_fb->r_format); - BEGIN_RING(evo, 0, 0x0080, 1); - OUT_RING (evo, 0x00000000); - FIRE_RING (evo); - - dispc->sem.offset ^= 0x10; - dispc->sem.value++; - return 0; -} - -static u16 -nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, - u32 mc, int pxclk) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_connector *nv_connector = NULL; - struct drm_encoder *encoder; - struct nvbios *bios = &dev_priv->vbios; - u32 script = 0, or; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->dcb != dcb) - continue; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - break; - } - - or = ffs(dcb->or) - 1; - switch (dcb->type) { - case OUTPUT_LVDS: - script = (mc >> 8) & 0xf; - if (bios->fp_no_ddc) { - if (bios->fp.dual_link) - script |= 0x0100; - if (bios->fp.if_is_24bit) - script |= 0x0200; - } else { - /* determine number of lvds links */ - if (nv_connector && nv_connector->edid && - nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) { - /* http://www.spwg.org */ - if (((u8 *)nv_connector->edid)[121] == 2) - script |= 0x0100; - } else - if (pxclk >= bios->fp.duallink_transition_clk) { - script |= 0x0100; - } - - /* determine panel depth */ - if (script & 0x0100) { - if (bios->fp.strapless_is_24bit & 2) - script |= 0x0200; - } else { - if (bios->fp.strapless_is_24bit & 1) - script |= 0x0200; - } - - if (nv_connector && nv_connector->edid && - (nv_connector->edid->revision >= 4) && - (nv_connector->edid->input & 0x70) >= 0x20) - script |= 0x0200; - } - - if (nouveau_uscript_lvds >= 0) { - NV_INFO(dev, "override script 0x%04x with 0x%04x " - "for output LVDS-%d\n", script, - nouveau_uscript_lvds, or); - script = nouveau_uscript_lvds; - } - break; - case OUTPUT_TMDS: - script = (mc >> 8) & 0xf; - if (pxclk >= 165000) - script |= 0x0100; - - if (nouveau_uscript_tmds >= 0) { - NV_INFO(dev, "override script 0x%04x with 0x%04x " - "for output TMDS-%d\n", script, - nouveau_uscript_tmds, or); - script = nouveau_uscript_tmds; - } - break; - case OUTPUT_DP: - script = (mc >> 8) & 0xf; - break; - case OUTPUT_ANALOG: - script = 0xff; - break; - default: - NV_ERROR(dev, "modeset on unsupported output type!\n"); - break; - } - - return script; -} - -static void -nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan, *tmp; - - list_for_each_entry_safe(chan, tmp, &dev_priv->vbl_waiting, - nvsw.vbl_wait) { - if (chan->nvsw.vblsem_head != crtc) - continue; - - nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset, - chan->nvsw.vblsem_rval); - list_del(&chan->nvsw.vbl_wait); - drm_vblank_put(dev, crtc); - } - - drm_handle_vblank(dev, crtc); -} - -static void -nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) -{ - if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0) - nv50_display_vblank_crtc_handler(dev, 0); - - if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1) - nv50_display_vblank_crtc_handler(dev, 1); - - nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_VBLANK_CRTC); -} - -static void -nv50_display_unk10_handler(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_display *disp = nv50_display(dev); - u32 unk30 = nv_rd32(dev, 0x610030), mc; - int i, crtc, or = 0, type = OUTPUT_ANY; - - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); - disp->irq.dcb = NULL; - - nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); - - /* Determine which CRTC we're dealing with, only 1 ever will be - * signalled at the same time with the current nouveau code. - */ - crtc = ffs((unk30 & 0x00000060) >> 5) - 1; - if (crtc < 0) - goto ack; - - /* Nothing needs to be done for the encoder */ - crtc = ffs((unk30 & 0x00000180) >> 7) - 1; - if (crtc < 0) - goto ack; - - /* Find which encoder was connected to the CRTC */ - for (i = 0; type == OUTPUT_ANY && i < 3; i++) { - mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); - NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); - if (!(mc & (1 << crtc))) - continue; - - switch ((mc & 0x00000f00) >> 8) { - case 0: type = OUTPUT_ANALOG; break; - case 1: type = OUTPUT_TV; break; - default: - NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); - goto ack; - } - - or = i; - } - - for (i = 0; type == OUTPUT_ANY && i < nv50_sor_nr(dev); i++) { - if (dev_priv->chipset < 0x90 || - dev_priv->chipset == 0x92 || - dev_priv->chipset == 0xa0) - mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); - else - mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); - - NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); - if (!(mc & (1 << crtc))) - continue; - - switch ((mc & 0x00000f00) >> 8) { - case 0: type = OUTPUT_LVDS; break; - case 1: type = OUTPUT_TMDS; break; - case 2: type = OUTPUT_TMDS; break; - case 5: type = OUTPUT_TMDS; break; - case 8: type = OUTPUT_DP; break; - case 9: type = OUTPUT_DP; break; - default: - NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); - goto ack; - } - - or = i; - } - - /* There was no encoder to disable */ - if (type == OUTPUT_ANY) - goto ack; - - /* Disable the encoder */ - for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { - struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; - - if (dcb->type == type && (dcb->or & (1 << or))) { - nouveau_bios_run_display_table(dev, 0, -1, dcb, -1); - disp->irq.dcb = dcb; - goto ack; - } - } - - NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); -ack: - nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); - nv_wr32(dev, 0x610030, 0x80000000); -} - -static void -nv50_display_unk20_handler(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_display *disp = nv50_display(dev); - u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0; - struct dcb_entry *dcb; - int i, crtc, or = 0, type = OUTPUT_ANY; - - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); - dcb = disp->irq.dcb; - if (dcb) { - nouveau_bios_run_display_table(dev, 0, -2, dcb, -1); - disp->irq.dcb = NULL; - } - - /* CRTC clock change requested? */ - crtc = ffs((unk30 & 0x00000600) >> 9) - 1; - if (crtc >= 0) { - pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)); - pclk &= 0x003fffff; - if (pclk) - nv50_crtc_set_clock(dev, crtc, pclk); - - tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc)); - tmp &= ~0x000000f; - nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp); - } - - /* Nothing needs to be done for the encoder */ - crtc = ffs((unk30 & 0x00000180) >> 7) - 1; - if (crtc < 0) - goto ack; - pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff; - - /* Find which encoder is connected to the CRTC */ - for (i = 0; type == OUTPUT_ANY && i < 3; i++) { - mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i)); - NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); - if (!(mc & (1 << crtc))) - continue; - - switch ((mc & 0x00000f00) >> 8) { - case 0: type = OUTPUT_ANALOG; break; - case 1: type = OUTPUT_TV; break; - default: - NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); - goto ack; - } - - or = i; - } - - for (i = 0; type == OUTPUT_ANY && i < nv50_sor_nr(dev); i++) { - if (dev_priv->chipset < 0x90 || - dev_priv->chipset == 0x92 || - dev_priv->chipset == 0xa0) - mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i)); - else - mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i)); - - NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); - if (!(mc & (1 << crtc))) - continue; - - switch ((mc & 0x00000f00) >> 8) { - case 0: type = OUTPUT_LVDS; break; - case 1: type = OUTPUT_TMDS; break; - case 2: type = OUTPUT_TMDS; break; - case 5: type = OUTPUT_TMDS; break; - case 8: type = OUTPUT_DP; break; - case 9: type = OUTPUT_DP; break; - default: - NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); - goto ack; - } - - or = i; - } - - if (type == OUTPUT_ANY) - goto ack; - - /* Enable the encoder */ - for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { - dcb = &dev_priv->vbios.dcb.entry[i]; - if (dcb->type == type && (dcb->or & (1 << or))) - break; - } - - if (i == dev_priv->vbios.dcb.entries) { - NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); - goto ack; - } - - script = nv50_display_script_select(dev, dcb, mc, pclk); - nouveau_bios_run_display_table(dev, script, pclk, dcb, -1); - - if (type == OUTPUT_DP) { - int link = !(dcb->dpconf.sor.link & 1); - if ((mc & 0x000f0000) == 0x00020000) - nv50_sor_dp_calc_tu(dev, or, link, pclk, 18); - else - nv50_sor_dp_calc_tu(dev, or, link, pclk, 24); - } - - if (dcb->type != OUTPUT_ANALOG) { - tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); - tmp &= ~0x00000f0f; - if (script & 0x0100) - tmp |= 0x00000101; - nv_wr32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or), tmp); - } else { - nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); - } - - disp->irq.dcb = dcb; - disp->irq.pclk = pclk; - disp->irq.script = script; - -ack: - nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); - nv_wr32(dev, 0x610030, 0x80000000); -} - -/* If programming a TMDS output on a SOR that can also be configured for - * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off. - * - * It looks like the VBIOS TMDS scripts make an attempt at this, however, - * the VBIOS scripts on at least one board I have only switch it off on - * link 0, causing a blank display if the output has previously been - * programmed for DisplayPort. - */ -static void -nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) -{ - int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1); - struct drm_encoder *encoder; - u32 tmp; - - if (dcb->type != OUTPUT_TMDS) - return; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (nv_encoder->dcb->type == OUTPUT_DP && - nv_encoder->dcb->or & (1 << or)) { - tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)); - tmp &= ~NV50_SOR_DP_CTRL_ENABLED; - nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp); - break; - } - } -} - -static void -nv50_display_unk40_handler(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - struct dcb_entry *dcb = disp->irq.dcb; - u16 script = disp->irq.script; - u32 unk30 = nv_rd32(dev, 0x610030), pclk = disp->irq.pclk; - - NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); - disp->irq.dcb = NULL; - if (!dcb) - goto ack; - - nouveau_bios_run_display_table(dev, script, -pclk, dcb, -1); - nv50_display_unk40_dp_set_tmds(dev, dcb); - -ack: - nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); - nv_wr32(dev, 0x610030, 0x80000000); - nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) | 8); -} - -static void -nv50_display_bh(unsigned long data) -{ - struct drm_device *dev = (struct drm_device *)data; - - for (;;) { - uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); - uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); - - NV_DEBUG_KMS(dev, "PDISPLAY_INTR_BH 0x%08x 0x%08x\n", intr0, intr1); - - if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK10) - nv50_display_unk10_handler(dev); - else - if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK20) - nv50_display_unk20_handler(dev); - else - if (intr1 & NV50_PDISPLAY_INTR_1_CLK_UNK40) - nv50_display_unk40_handler(dev); - else - break; - } - - nv_wr32(dev, NV03_PMC_INTR_EN_0, 1); -} - -static void -nv50_display_error_handler(struct drm_device *dev) -{ - u32 channels = (nv_rd32(dev, NV50_PDISPLAY_INTR_0) & 0x001f0000) >> 16; - u32 addr, data; - int chid; - - for (chid = 0; chid < 5; chid++) { - if (!(channels & (1 << chid))) - continue; - - nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000 << chid); - addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid)); - data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA(chid)); - NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x " - "(0x%04x 0x%02x)\n", chid, - addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf); - - nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid), 0x90000000); - } -} - -static void -nv50_display_isr(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - uint32_t delayed = 0; - - while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { - uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); - uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); - uint32_t clock; - - NV_DEBUG_KMS(dev, "PDISPLAY_INTR 0x%08x 0x%08x\n", intr0, intr1); - - if (!intr0 && !(intr1 & ~delayed)) - break; - - if (intr0 & 0x001f0000) { - nv50_display_error_handler(dev); - intr0 &= ~0x001f0000; - } - - if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) { - nv50_display_vblank_handler(dev, intr1); - intr1 &= ~NV50_PDISPLAY_INTR_1_VBLANK_CRTC; - } - - clock = (intr1 & (NV50_PDISPLAY_INTR_1_CLK_UNK10 | - NV50_PDISPLAY_INTR_1_CLK_UNK20 | - NV50_PDISPLAY_INTR_1_CLK_UNK40)); - if (clock) { - nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); - tasklet_schedule(&disp->tasklet); - delayed |= clock; - intr1 &= ~clock; - } - - if (intr0) { - NV_ERROR(dev, "unknown PDISPLAY_INTR_0: 0x%08x\n", intr0); - nv_wr32(dev, NV50_PDISPLAY_INTR_0, intr0); - } - - if (intr1) { - NV_ERROR(dev, - "unknown PDISPLAY_INTR_1: 0x%08x\n", intr1); - nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr1); - } - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.h deleted file mode 100644 index 5d3dd14d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_display.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NV50_DISPLAY_H__ -#define __NV50_DISPLAY_H__ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_reg.h" -#include "nouveau_crtc.h" -#include "nv50_evo.h" - -struct nv50_display_crtc { - struct nouveau_channel *sync; - struct { - struct nouveau_bo *bo; - u32 offset; - u16 value; - } sem; -}; - -struct nv50_display { - struct nouveau_channel *master; - struct nouveau_gpuobj *ntfy; - - struct nv50_display_crtc crtc[2]; - - struct tasklet_struct tasklet; - struct { - struct dcb_entry *dcb; - u16 script; - u32 pclk; - } irq; -}; - -static inline struct nv50_display * -nv50_display(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return dev_priv->engine.display.priv; -} - -int nv50_display_early_init(struct drm_device *dev); -void nv50_display_late_takedown(struct drm_device *dev); -int nv50_display_create(struct drm_device *dev); -int nv50_display_init(struct drm_device *dev); -void nv50_display_fini(struct drm_device *dev); -void nv50_display_destroy(struct drm_device *dev); -int nv50_crtc_blank(struct nouveau_crtc *, bool blank); -int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); - -u32 nv50_display_active_crtcs(struct drm_device *); - -int nv50_display_sync(struct drm_device *); -int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, - struct nouveau_channel *chan); -void nv50_display_flip_stop(struct drm_crtc *); - -int nv50_evo_create(struct drm_device *dev); -void nv50_evo_destroy(struct drm_device *dev); -int nv50_evo_init(struct drm_device *dev); -void nv50_evo_fini(struct drm_device *dev); -void nv50_evo_dmaobj_init(struct nouveau_gpuobj *, u32 memtype, u64 base, - u64 size); -int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 handle, u32 memtype, - u64 base, u64 size, struct nouveau_gpuobj **); - -#endif /* __NV50_DISPLAY_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.c deleted file mode 100644 index 9b962e98..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_ramht.h" -#include "nv50_display.h" - -static void -nv50_evo_channel_del(struct nouveau_channel **pevo) -{ - struct nouveau_channel *evo = *pevo; - - if (!evo) - return; - *pevo = NULL; - - nouveau_ramht_ref(NULL, &evo->ramht, evo); - nouveau_gpuobj_channel_takedown(evo); - nouveau_bo_unmap(evo->pushbuf_bo); - nouveau_bo_ref(NULL, &evo->pushbuf_bo); - - if (evo->user) - iounmap(evo->user); - - kfree(evo); -} - -void -nv50_evo_dmaobj_init(struct nouveau_gpuobj *obj, u32 memtype, u64 base, u64 size) -{ - struct drm_nouveau_private *dev_priv = obj->dev->dev_private; - u32 flags5; - - if (dev_priv->chipset < 0xc0) { - /* not supported on 0x50, specified in format mthd */ - if (dev_priv->chipset == 0x50) - memtype = 0; - flags5 = 0x00010000; - } else { - if (memtype & 0x80000000) - flags5 = 0x00000000; /* large pages */ - else - flags5 = 0x00020000; - } - - nv50_gpuobj_dma_init(obj, 0, 0x3d, base, size, NV_MEM_TARGET_VRAM, - NV_MEM_ACCESS_RW, (memtype >> 8) & 0xff, 0); - nv_wo32(obj, 0x14, flags5); - dev_priv->engine.instmem.flush(obj->dev); -} - -int -nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 handle, u32 memtype, - u64 base, u64 size, struct nouveau_gpuobj **pobj) -{ - struct nv50_display *disp = nv50_display(evo->dev); - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(evo->dev, disp->master, 6*4, 32, 0, &obj); - if (ret) - return ret; - obj->engine = NVOBJ_ENGINE_DISPLAY; - - nv50_evo_dmaobj_init(obj, memtype, base, size); - - ret = nouveau_ramht_insert(evo, handle, obj); - if (ret) - goto out; - - if (pobj) - nouveau_gpuobj_ref(obj, pobj); -out: - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static int -nv50_evo_channel_new(struct drm_device *dev, int chid, - struct nouveau_channel **pevo) -{ - struct nv50_display *disp = nv50_display(dev); - struct nouveau_channel *evo; - int ret; - - evo = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL); - if (!evo) - return -ENOMEM; - *pevo = evo; - - evo->id = chid; - evo->dev = dev; - evo->user_get = 4; - evo->user_put = 0; - - ret = nouveau_bo_new(dev, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, - &evo->pushbuf_bo); - if (ret == 0) - ret = nouveau_bo_pin(evo->pushbuf_bo, TTM_PL_FLAG_VRAM); - if (ret) { - NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret); - nv50_evo_channel_del(pevo); - return ret; - } - - ret = nouveau_bo_map(evo->pushbuf_bo); - if (ret) { - NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret); - nv50_evo_channel_del(pevo); - return ret; - } - - evo->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV50_PDISPLAY_USER(evo->id), PAGE_SIZE); - if (!evo->user) { - NV_ERROR(dev, "Error mapping EVO control regs.\n"); - nv50_evo_channel_del(pevo); - return -ENOMEM; - } - - /* bind primary evo channel's ramht to the channel */ - if (disp->master && evo != disp->master) - nouveau_ramht_ref(disp->master->ramht, &evo->ramht, NULL); - - return 0; -} - -static int -nv50_evo_channel_init(struct nouveau_channel *evo) -{ - struct drm_device *dev = evo->dev; - int id = evo->id, ret, i; - u64 pushbuf = evo->pushbuf_bo->bo.offset; - u32 tmp; - - tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)); - if ((tmp & 0x009f0000) == 0x00020000) - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00800000); - - tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)); - if ((tmp & 0x003f0000) == 0x00030000) - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00600000); - - /* initialise fifo */ - nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(id), pushbuf >> 8 | - NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | - NV50_PDISPLAY_EVO_DMA_CB_VALID); - nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000); - nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(id), id); - nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), NV50_PDISPLAY_EVO_CTRL_DMA, - NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); - - nv_wr32(dev, NV50_PDISPLAY_USER_PUT(id), 0x00000000); - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 | - NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); - if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) { - NV_ERROR(dev, "EvoCh %d init timeout: 0x%08x\n", id, - nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); - return -EBUSY; - } - - /* enable error reporting on the channel */ - nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); - - evo->dma.max = (4096/4) - 2; - evo->dma.max &= ~7; - evo->dma.put = 0; - evo->dma.cur = evo->dma.put; - evo->dma.free = evo->dma.max - evo->dma.cur; - - ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS); - if (ret) - return ret; - - for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) - OUT_RING(evo, 0); - - return 0; -} - -static void -nv50_evo_channel_fini(struct nouveau_channel *evo) -{ - struct drm_device *dev = evo->dev; - int id = evo->id; - - nv_mask(dev, 0x610028, 0x00010001 << id, 0x00000000); - nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00001010, 0x00001000); - nv_wr32(dev, NV50_PDISPLAY_INTR_0, (1 << id)); - nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00000003, 0x00000000); - if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x001e0000, 0x00000000)) { - NV_ERROR(dev, "EvoCh %d takedown timeout: 0x%08x\n", id, - nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); - } -} - -void -nv50_evo_destroy(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - int i; - - for (i = 0; i < 2; i++) { - if (disp->crtc[i].sem.bo) { - nouveau_bo_unmap(disp->crtc[i].sem.bo); - nouveau_bo_ref(NULL, &disp->crtc[i].sem.bo); - } - nv50_evo_channel_del(&disp->crtc[i].sync); - } - nouveau_gpuobj_ref(NULL, &disp->ntfy); - nv50_evo_channel_del(&disp->master); -} - -int -nv50_evo_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_display *disp = nv50_display(dev); - struct nouveau_gpuobj *ramht = NULL; - struct nouveau_channel *evo; - int ret, i, j; - - /* create primary evo channel, the one we use for modesetting - * purporses - */ - ret = nv50_evo_channel_new(dev, 0, &disp->master); - if (ret) - return ret; - evo = disp->master; - - /* setup object management on it, any other evo channel will - * use this also as there's no per-channel support on the - * hardware - */ - ret = nouveau_gpuobj_new(dev, NULL, 32768, 65536, - NVOBJ_FLAG_ZERO_ALLOC, &evo->ramin); - if (ret) { - NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); - goto err; - } - - ret = drm_mm_init(&evo->ramin_heap, 0, 32768); - if (ret) { - NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); - goto err; - } - - ret = nouveau_gpuobj_new(dev, evo, 4096, 16, 0, &ramht); - if (ret) { - NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); - goto err; - } - - ret = nouveau_ramht_new(dev, ramht, &evo->ramht); - nouveau_gpuobj_ref(NULL, &ramht); - if (ret) - goto err; - - /* not sure exactly what this is.. - * - * the first dword of the structure is used by nvidia to wait on - * full completion of an EVO "update" command. - * - * method 0x8c on the master evo channel will fill a lot more of - * this structure with some undefined info - */ - ret = nouveau_gpuobj_new(dev, disp->master, 0x1000, 0, - NVOBJ_FLAG_ZERO_ALLOC, &disp->ntfy); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(disp->master, NvEvoSync, 0x0000, - disp->ntfy->vinst, disp->ntfy->size, NULL); - if (ret) - goto err; - - /* create some default objects for the scanout memtypes we support */ - ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000, - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000, - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 | - (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00), - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 | - (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00), - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - /* create "display sync" channels and other structures we need - * to implement page flipping - */ - for (i = 0; i < 2; i++) { - struct nv50_display_crtc *dispc = &disp->crtc[i]; - u64 offset; - - ret = nv50_evo_channel_new(dev, 1 + i, &dispc->sync); - if (ret) - goto err; - - ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, - 0, 0x0000, &dispc->sem.bo); - if (!ret) { - ret = nouveau_bo_pin(dispc->sem.bo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(dispc->sem.bo); - if (ret) - nouveau_bo_ref(NULL, &dispc->sem.bo); - offset = dispc->sem.bo->bo.offset; - } - - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoSync, 0x0000, - offset, 4096, NULL); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000, - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 | - (dev_priv->chipset < 0xc0 ? - 0x7a00 : 0xfe00), - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 | - (dev_priv->chipset < 0xc0 ? - 0x7000 : 0xfe00), - 0, dev_priv->vram_size, NULL); - if (ret) - goto err; - - for (j = 0; j < 4096; j += 4) - nouveau_bo_wr32(dispc->sem.bo, j / 4, 0x74b1e000); - dispc->sem.offset = 0; - } - - return 0; - -err: - nv50_evo_destroy(dev); - return ret; -} - -int -nv50_evo_init(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - int ret, i; - - ret = nv50_evo_channel_init(disp->master); - if (ret) - return ret; - - for (i = 0; i < 2; i++) { - ret = nv50_evo_channel_init(disp->crtc[i].sync); - if (ret) - return ret; - } - - return 0; -} - -void -nv50_evo_fini(struct drm_device *dev) -{ - struct nv50_display *disp = nv50_display(dev); - int i; - - for (i = 0; i < 2; i++) { - if (disp->crtc[i].sync) - nv50_evo_channel_fini(disp->crtc[i].sync); - } - - if (disp->master) - nv50_evo_channel_fini(disp->master); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.h deleted file mode 100644 index 771d879b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_evo.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __NV50_EVO_H__ -#define __NV50_EVO_H__ - -#define NV50_EVO_UPDATE 0x00000080 -#define NV50_EVO_UNK84 0x00000084 -#define NV50_EVO_UNK84_NOTIFY 0x40000000 -#define NV50_EVO_UNK84_NOTIFY_DISABLED 0x00000000 -#define NV50_EVO_UNK84_NOTIFY_ENABLED 0x40000000 -#define NV50_EVO_DMA_NOTIFY 0x00000088 -#define NV50_EVO_DMA_NOTIFY_HANDLE 0xffffffff -#define NV50_EVO_DMA_NOTIFY_HANDLE_NONE 0x00000000 -#define NV50_EVO_UNK8C 0x0000008C - -#define NV50_EVO_DAC(n, r) ((n) * 0x80 + NV50_EVO_DAC_##r) -#define NV50_EVO_DAC_MODE_CTRL 0x00000400 -#define NV50_EVO_DAC_MODE_CTRL_CRTC0 0x00000001 -#define NV50_EVO_DAC_MODE_CTRL_CRTC1 0x00000002 -#define NV50_EVO_DAC_MODE_CTRL2 0x00000404 -#define NV50_EVO_DAC_MODE_CTRL2_NHSYNC 0x00000001 -#define NV50_EVO_DAC_MODE_CTRL2_NVSYNC 0x00000002 - -#define NV50_EVO_SOR(n, r) ((n) * 0x40 + NV50_EVO_SOR_##r) -#define NV50_EVO_SOR_MODE_CTRL 0x00000600 -#define NV50_EVO_SOR_MODE_CTRL_CRTC0 0x00000001 -#define NV50_EVO_SOR_MODE_CTRL_CRTC1 0x00000002 -#define NV50_EVO_SOR_MODE_CTRL_TMDS 0x00000100 -#define NV50_EVO_SOR_MODE_CTRL_TMDS_DUAL_LINK 0x00000400 -#define NV50_EVO_SOR_MODE_CTRL_NHSYNC 0x00001000 -#define NV50_EVO_SOR_MODE_CTRL_NVSYNC 0x00002000 - -#define NV50_EVO_CRTC(n, r) ((n) * 0x400 + NV50_EVO_CRTC_##r) -#define NV84_EVO_CRTC(n, r) ((n) * 0x400 + NV84_EVO_CRTC_##r) -#define NV50_EVO_CRTC_UNK0800 0x00000800 -#define NV50_EVO_CRTC_CLOCK 0x00000804 -#define NV50_EVO_CRTC_INTERLACE 0x00000808 -#define NV50_EVO_CRTC_DISPLAY_START 0x00000810 -#define NV50_EVO_CRTC_DISPLAY_TOTAL 0x00000814 -#define NV50_EVO_CRTC_SYNC_DURATION 0x00000818 -#define NV50_EVO_CRTC_SYNC_START_TO_BLANK_END 0x0000081c -#define NV50_EVO_CRTC_UNK0820 0x00000820 -#define NV50_EVO_CRTC_UNK0824 0x00000824 -#define NV50_EVO_CRTC_UNK082C 0x0000082c -#define NV50_EVO_CRTC_CLUT_MODE 0x00000840 -/* You can't have a palette in 8 bit mode (=OFF) */ -#define NV50_EVO_CRTC_CLUT_MODE_BLANK 0x00000000 -#define NV50_EVO_CRTC_CLUT_MODE_OFF 0x80000000 -#define NV50_EVO_CRTC_CLUT_MODE_ON 0xC0000000 -#define NV50_EVO_CRTC_CLUT_OFFSET 0x00000844 -#define NV84_EVO_CRTC_CLUT_DMA 0x0000085C -#define NV84_EVO_CRTC_CLUT_DMA_HANDLE 0xffffffff -#define NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE 0x00000000 -#define NV50_EVO_CRTC_FB_OFFSET 0x00000860 -#define NV50_EVO_CRTC_FB_SIZE 0x00000868 -#define NV50_EVO_CRTC_FB_CONFIG 0x0000086c -#define NV50_EVO_CRTC_FB_CONFIG_MODE 0x00100000 -#define NV50_EVO_CRTC_FB_CONFIG_MODE_TILE 0x00000000 -#define NV50_EVO_CRTC_FB_CONFIG_MODE_PITCH 0x00100000 -#define NV50_EVO_CRTC_FB_DEPTH 0x00000870 -#define NV50_EVO_CRTC_FB_DEPTH_8 0x00001e00 -#define NV50_EVO_CRTC_FB_DEPTH_15 0x0000e900 -#define NV50_EVO_CRTC_FB_DEPTH_16 0x0000e800 -#define NV50_EVO_CRTC_FB_DEPTH_24 0x0000cf00 -#define NV50_EVO_CRTC_FB_DEPTH_30 0x0000d100 -#define NV50_EVO_CRTC_FB_DMA 0x00000874 -#define NV50_EVO_CRTC_FB_DMA_HANDLE 0xffffffff -#define NV50_EVO_CRTC_FB_DMA_HANDLE_NONE 0x00000000 -#define NV50_EVO_CRTC_CURSOR_CTRL 0x00000880 -#define NV50_EVO_CRTC_CURSOR_CTRL_HIDE 0x05000000 -#define NV50_EVO_CRTC_CURSOR_CTRL_SHOW 0x85000000 -#define NV50_EVO_CRTC_CURSOR_OFFSET 0x00000884 -#define NV84_EVO_CRTC_CURSOR_DMA 0x0000089c -#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE 0xffffffff -#define NV84_EVO_CRTC_CURSOR_DMA_HANDLE_NONE 0x00000000 -#define NV50_EVO_CRTC_DITHER_CTRL 0x000008a0 -#define NV50_EVO_CRTC_DITHER_CTRL_OFF 0x00000000 -#define NV50_EVO_CRTC_DITHER_CTRL_ON 0x00000011 -#define NV50_EVO_CRTC_SCALE_CTRL 0x000008a4 -#define NV50_EVO_CRTC_SCALE_CTRL_INACTIVE 0x00000000 -#define NV50_EVO_CRTC_SCALE_CTRL_ACTIVE 0x00000009 -#define NV50_EVO_CRTC_COLOR_CTRL 0x000008a8 -#define NV50_EVO_CRTC_COLOR_CTRL_VIBRANCE 0x000fff00 -#define NV50_EVO_CRTC_COLOR_CTRL_HUE 0xfff00000 -#define NV50_EVO_CRTC_FB_POS 0x000008c0 -#define NV50_EVO_CRTC_REAL_RES 0x000008c8 -#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET 0x000008d4 -#define NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(x, y) \ - ((((unsigned)y << 16) & 0xFFFF0000) | (((unsigned)x) & 0x0000FFFF)) -/* Both of these are needed, otherwise nothing happens. */ -#define NV50_EVO_CRTC_SCALE_RES1 0x000008d8 -#define NV50_EVO_CRTC_SCALE_RES2 0x000008dc -#define NV50_EVO_CRTC_UNK900 0x00000900 -#define NV50_EVO_CRTC_UNK904 0x00000904 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fb.c deleted file mode 100644 index bdd2afe2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fb.c +++ /dev/null @@ -1,294 +0,0 @@ -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -struct nv50_fb_priv { - struct page *r100c08_page; - dma_addr_t r100c08; -}; - -static void -nv50_fb_destroy(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nv50_fb_priv *priv = pfb->priv; - - if (drm_mm_initialized(&pfb->tag_heap)) - drm_mm_takedown(&pfb->tag_heap); - - if (priv->r100c08_page) { - pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - __free_page(priv->r100c08_page); - } - - kfree(priv); - pfb->priv = NULL; -} - -static int -nv50_fb_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nv50_fb_priv *priv; - u32 tagmem; - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - pfb->priv = priv; - - priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (!priv->r100c08_page) { - nv50_fb_destroy(dev); - return -ENOMEM; - } - - priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) { - nv50_fb_destroy(dev); - return -EFAULT; - } - - tagmem = nv_rd32(dev, 0x100320); - NV_DEBUG(dev, "%d tags available\n", tagmem); - ret = drm_mm_init(&pfb->tag_heap, 0, tagmem); - if (ret) { - nv50_fb_destroy(dev); - return ret; - } - - return 0; -} - -int -nv50_fb_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_fb_priv *priv; - int ret; - - if (!dev_priv->engine.fb.priv) { - ret = nv50_fb_create(dev); - if (ret) - return ret; - } - priv = dev_priv->engine.fb.priv; - - /* Not a clue what this is exactly. Without pointing it at a - * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) - * cause IOMMU "read from address 0" errors (rh#561267) - */ - nv_wr32(dev, 0x100c08, priv->r100c08 >> 8); - - /* This is needed to get meaningful information from 100c90 - * on traps. No idea what these values mean exactly. */ - switch (dev_priv->chipset) { - case 0x50: - nv_wr32(dev, 0x100c90, 0x000707ff); - break; - case 0xa3: - case 0xa5: - case 0xa8: - nv_wr32(dev, 0x100c90, 0x000d0fff); - break; - case 0xaf: - nv_wr32(dev, 0x100c90, 0x089d1fff); - break; - default: - nv_wr32(dev, 0x100c90, 0x001d07ff); - break; - } - - return 0; -} - -void -nv50_fb_takedown(struct drm_device *dev) -{ - nv50_fb_destroy(dev); -} - -static struct nouveau_enum vm_dispatch_subclients[] = { - { 0x00000000, "GRCTX", NULL }, - { 0x00000001, "NOTIFY", NULL }, - { 0x00000002, "QUERY", NULL }, - { 0x00000003, "COND", NULL }, - { 0x00000004, "M2M_IN", NULL }, - { 0x00000005, "M2M_OUT", NULL }, - { 0x00000006, "M2M_NOTIFY", NULL }, - {} -}; - -static struct nouveau_enum vm_ccache_subclients[] = { - { 0x00000000, "CB", NULL }, - { 0x00000001, "TIC", NULL }, - { 0x00000002, "TSC", NULL }, - {} -}; - -static struct nouveau_enum vm_prop_subclients[] = { - { 0x00000000, "RT0", NULL }, - { 0x00000001, "RT1", NULL }, - { 0x00000002, "RT2", NULL }, - { 0x00000003, "RT3", NULL }, - { 0x00000004, "RT4", NULL }, - { 0x00000005, "RT5", NULL }, - { 0x00000006, "RT6", NULL }, - { 0x00000007, "RT7", NULL }, - { 0x00000008, "ZETA", NULL }, - { 0x00000009, "LOCAL", NULL }, - { 0x0000000a, "GLOBAL", NULL }, - { 0x0000000b, "STACK", NULL }, - { 0x0000000c, "DST2D", NULL }, - {} -}; - -static struct nouveau_enum vm_pfifo_subclients[] = { - { 0x00000000, "PUSHBUF", NULL }, - { 0x00000001, "SEMAPHORE", NULL }, - {} -}; - -static struct nouveau_enum vm_bar_subclients[] = { - { 0x00000000, "FB", NULL }, - { 0x00000001, "IN", NULL }, - {} -}; - -static struct nouveau_enum vm_client[] = { - { 0x00000000, "STRMOUT", NULL }, - { 0x00000003, "DISPATCH", vm_dispatch_subclients }, - { 0x00000004, "PFIFO_WRITE", NULL }, - { 0x00000005, "CCACHE", vm_ccache_subclients }, - { 0x00000006, "PPPP", NULL }, - { 0x00000007, "CLIPID", NULL }, - { 0x00000008, "PFIFO_READ", NULL }, - { 0x00000009, "VFETCH", NULL }, - { 0x0000000a, "TEXTURE", NULL }, - { 0x0000000b, "PROP", vm_prop_subclients }, - { 0x0000000c, "PVP", NULL }, - { 0x0000000d, "PBSP", NULL }, - { 0x0000000e, "PCRYPT", NULL }, - { 0x0000000f, "PCOUNTER", NULL }, - { 0x00000011, "PDAEMON", NULL }, - {} -}; - -static struct nouveau_enum vm_engine[] = { - { 0x00000000, "PGRAPH", NULL }, - { 0x00000001, "PVP", NULL }, - { 0x00000004, "PEEPHOLE", NULL }, - { 0x00000005, "PFIFO", vm_pfifo_subclients }, - { 0x00000006, "BAR", vm_bar_subclients }, - { 0x00000008, "PPPP", NULL }, - { 0x00000009, "PBSP", NULL }, - { 0x0000000a, "PCRYPT", NULL }, - { 0x0000000b, "PCOUNTER", NULL }, - { 0x0000000c, "SEMAPHORE_BG", NULL }, - { 0x0000000d, "PCOPY", NULL }, - { 0x0000000e, "PDAEMON", NULL }, - {} -}; - -static struct nouveau_enum vm_fault[] = { - { 0x00000000, "PT_NOT_PRESENT", NULL }, - { 0x00000001, "PT_TOO_SHORT", NULL }, - { 0x00000002, "PAGE_NOT_PRESENT", NULL }, - { 0x00000003, "PAGE_SYSTEM_ONLY", NULL }, - { 0x00000004, "PAGE_READ_ONLY", NULL }, - { 0x00000006, "NULL_DMAOBJ", NULL }, - { 0x00000007, "WRONG_MEMTYPE", NULL }, - { 0x0000000b, "VRAM_LIMIT", NULL }, - { 0x0000000f, "DMAOBJ_LIMIT", NULL }, - {} -}; - -void -nv50_fb_vm_trap(struct drm_device *dev, int display) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - const struct nouveau_enum *en, *cl; - unsigned long flags; - u32 trap[6], idx, chinst; - u8 st0, st1, st2, st3; - int i, ch; - - idx = nv_rd32(dev, 0x100c90); - if (!(idx & 0x80000000)) - return; - idx &= 0x00ffffff; - - for (i = 0; i < 6; i++) { - nv_wr32(dev, 0x100c90, idx | i << 24); - trap[i] = nv_rd32(dev, 0x100c94); - } - nv_wr32(dev, 0x100c90, idx | 0x80000000); - - if (!display) - return; - - /* lookup channel id */ - chinst = (trap[2] << 16) | trap[1]; - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { - struct nouveau_channel *chan = dev_priv->channels.ptr[ch]; - - if (!chan || !chan->ramin) - continue; - - if (chinst == chan->ramin->vinst >> 12) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - - /* decode status bits into something more useful */ - if (dev_priv->chipset < 0xa3 || - dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) { - st0 = (trap[0] & 0x0000000f) >> 0; - st1 = (trap[0] & 0x000000f0) >> 4; - st2 = (trap[0] & 0x00000f00) >> 8; - st3 = (trap[0] & 0x0000f000) >> 12; - } else { - st0 = (trap[0] & 0x000000ff) >> 0; - st1 = (trap[0] & 0x0000ff00) >> 8; - st2 = (trap[0] & 0x00ff0000) >> 16; - st3 = (trap[0] & 0xff000000) >> 24; - } - - NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ", - (trap[5] & 0x00000100) ? "read" : "write", - trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst); - - en = nouveau_enum_find(vm_engine, st0); - if (en) - printk("%s/", en->name); - else - printk("%02x/", st0); - - cl = nouveau_enum_find(vm_client, st2); - if (cl) - printk("%s/", cl->name); - else - printk("%02x/", st2); - - if (cl && cl->data) cl = nouveau_enum_find(cl->data, st3); - else if (en && en->data) cl = nouveau_enum_find(en->data, st3); - else cl = NULL; - if (cl) - printk("%s", cl->name); - else - printk("%02x", st3); - - printk(" reason: "); - en = nouveau_enum_find(vm_fault, st1); - if (en) - printk("%s\n", en->name); - else - printk("0x%08x\n", st1); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fbcon.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fbcon.c deleted file mode 100644 index dc75a720..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_ramht.h" -#include "nouveau_fbcon.h" -#include "nouveau_mm.h" - -int -nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret; - - ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11); - if (ret) - return ret; - - if (rect->rop != ROP_COPY) { - BEGIN_RING(chan, NvSub2D, 0x02ac, 1); - OUT_RING(chan, 1); - } - BEGIN_RING(chan, NvSub2D, 0x0588, 1); - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) - OUT_RING(chan, ((uint32_t *)info->pseudo_palette)[rect->color]); - else - OUT_RING(chan, rect->color); - BEGIN_RING(chan, NvSub2D, 0x0600, 4); - OUT_RING(chan, rect->dx); - OUT_RING(chan, rect->dy); - OUT_RING(chan, rect->dx + rect->width); - OUT_RING(chan, rect->dy + rect->height); - if (rect->rop != ROP_COPY) { - BEGIN_RING(chan, NvSub2D, 0x02ac, 1); - OUT_RING(chan, 3); - } - FIRE_RING(chan); - return 0; -} - -int -nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret; - - ret = RING_SPACE(chan, 12); - if (ret) - return ret; - - BEGIN_RING(chan, NvSub2D, 0x0110, 1); - OUT_RING(chan, 0); - BEGIN_RING(chan, NvSub2D, 0x08b0, 4); - OUT_RING(chan, region->dx); - OUT_RING(chan, region->dy); - OUT_RING(chan, region->width); - OUT_RING(chan, region->height); - BEGIN_RING(chan, NvSub2D, 0x08d0, 4); - OUT_RING(chan, 0); - OUT_RING(chan, region->sx); - OUT_RING(chan, 0); - OUT_RING(chan, region->sy); - FIRE_RING(chan); - return 0; -} - -int -nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - uint32_t width, dwords, *data = (uint32_t *)image->data; - uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); - uint32_t *palette = info->pseudo_palette; - int ret; - - if (image->depth != 1) - return -ENODEV; - - ret = RING_SPACE(chan, 11); - if (ret) - return ret; - - width = ALIGN(image->width, 32); - dwords = (width * image->height) >> 5; - - BEGIN_RING(chan, NvSub2D, 0x0814, 2); - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - OUT_RING(chan, palette[image->bg_color] | mask); - OUT_RING(chan, palette[image->fg_color] | mask); - } else { - OUT_RING(chan, image->bg_color); - OUT_RING(chan, image->fg_color); - } - BEGIN_RING(chan, NvSub2D, 0x0838, 2); - OUT_RING(chan, image->width); - OUT_RING(chan, image->height); - BEGIN_RING(chan, NvSub2D, 0x0850, 4); - OUT_RING(chan, 0); - OUT_RING(chan, image->dx); - OUT_RING(chan, 0); - OUT_RING(chan, image->dy); - - while (dwords) { - int push = dwords > 2047 ? 2047 : dwords; - - ret = RING_SPACE(chan, push + 1); - if (ret) - return ret; - - dwords -= push; - - BEGIN_RING(chan, NvSub2D, 0x40000860, push); - OUT_RINGp(chan, data, push); - data += push; - } - - FIRE_RING(chan); - return 0; -} - -int -nv50_fbcon_accel_init(struct fb_info *info) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb; - int ret, format; - - switch (info->var.bits_per_pixel) { - case 8: - format = 0xf3; - break; - case 15: - format = 0xf8; - break; - case 16: - format = 0xe8; - break; - case 32: - switch (info->var.transp.length) { - case 0: /* depth 24 */ - case 8: /* depth 32, just use 24.. */ - format = 0xe6; - break; - case 2: /* depth 30 */ - format = 0xd1; - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } - - ret = nouveau_gpuobj_gr_new(dev_priv->channel, Nv2D, 0x502d); - if (ret) - return ret; - - ret = RING_SPACE(chan, 59); - if (ret) { - nouveau_fbcon_gpu_lockup(info); - return ret; - } - - BEGIN_RING(chan, NvSub2D, 0x0000, 1); - OUT_RING(chan, Nv2D); - BEGIN_RING(chan, NvSub2D, 0x0180, 4); - OUT_RING(chan, NvNotify0); - OUT_RING(chan, chan->vram_handle); - OUT_RING(chan, chan->vram_handle); - OUT_RING(chan, chan->vram_handle); - BEGIN_RING(chan, NvSub2D, 0x0290, 1); - OUT_RING(chan, 0); - BEGIN_RING(chan, NvSub2D, 0x0888, 1); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x02ac, 1); - OUT_RING(chan, 3); - BEGIN_RING(chan, NvSub2D, 0x02a0, 1); - OUT_RING(chan, 0x55); - BEGIN_RING(chan, NvSub2D, 0x08c0, 4); - OUT_RING(chan, 0); - OUT_RING(chan, 1); - OUT_RING(chan, 0); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0580, 2); - OUT_RING(chan, 4); - OUT_RING(chan, format); - BEGIN_RING(chan, NvSub2D, 0x02e8, 2); - OUT_RING(chan, 2); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0804, 1); - OUT_RING(chan, format); - BEGIN_RING(chan, NvSub2D, 0x0800, 1); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0808, 3); - OUT_RING(chan, 0); - OUT_RING(chan, 0); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x081c, 1); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0840, 4); - OUT_RING(chan, 0); - OUT_RING(chan, 1); - OUT_RING(chan, 0); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0200, 2); - OUT_RING(chan, format); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0214, 5); - OUT_RING(chan, info->fix.line_length); - OUT_RING(chan, info->var.xres_virtual); - OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb->vma.offset)); - OUT_RING(chan, lower_32_bits(fb->vma.offset)); - BEGIN_RING(chan, NvSub2D, 0x0230, 2); - OUT_RING(chan, format); - OUT_RING(chan, 1); - BEGIN_RING(chan, NvSub2D, 0x0244, 5); - OUT_RING(chan, info->fix.line_length); - OUT_RING(chan, info->var.xres_virtual); - OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb->vma.offset)); - OUT_RING(chan, lower_32_bits(fb->vma.offset)); - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fifo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fifo.c deleted file mode 100644 index 3bc2a565..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_fifo.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" -#include "nouveau_vm.h" - -static void -nv50_fifo_playlist_update(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_gpuobj *cur; - int i, nr; - - NV_DEBUG(dev, "\n"); - - cur = pfifo->playlist[pfifo->cur_playlist]; - pfifo->cur_playlist = !pfifo->cur_playlist; - - /* We never schedule channel 0 or 127 */ - for (i = 1, nr = 0; i < 127; i++) { - if (dev_priv->channels.ptr[i] && - dev_priv->channels.ptr[i]->ramfc) { - nv_wo32(cur, (nr * 4), i); - nr++; - } - } - dev_priv->engine.instmem.flush(dev); - - nv_wr32(dev, 0x32f4, cur->vinst >> 12); - nv_wr32(dev, 0x32ec, nr); - nv_wr32(dev, 0x2500, 0x101); -} - -static void -nv50_fifo_channel_enable(struct drm_device *dev, int channel) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channels.ptr[channel]; - uint32_t inst; - - NV_DEBUG(dev, "ch%d\n", channel); - - if (dev_priv->chipset == 0x50) - inst = chan->ramfc->vinst >> 12; - else - inst = chan->ramfc->vinst >> 8; - - nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst | - NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED); -} - -static void -nv50_fifo_channel_disable(struct drm_device *dev, int channel) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t inst; - - NV_DEBUG(dev, "ch%d\n", channel); - - if (dev_priv->chipset == 0x50) - inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80; - else - inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84; - nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst); -} - -static void -nv50_fifo_init_reset(struct drm_device *dev) -{ - uint32_t pmc_e = NV_PMC_ENABLE_PFIFO; - - NV_DEBUG(dev, "\n"); - - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); - nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); -} - -static void -nv50_fifo_init_intr(struct drm_device *dev) -{ - NV_DEBUG(dev, "\n"); - - nouveau_irq_register(dev, 8, nv04_fifo_isr); - nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF); - nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); -} - -static void -nv50_fifo_init_context_table(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i; - - NV_DEBUG(dev, "\n"); - - for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { - if (dev_priv->channels.ptr[i]) - nv50_fifo_channel_enable(dev, i); - else - nv50_fifo_channel_disable(dev, i); - } - - nv50_fifo_playlist_update(dev); -} - -static void -nv50_fifo_init_regs__nv(struct drm_device *dev) -{ - NV_DEBUG(dev, "\n"); - - nv_wr32(dev, 0x250c, 0x6f3cfc34); -} - -static void -nv50_fifo_init_regs(struct drm_device *dev) -{ - NV_DEBUG(dev, "\n"); - - nv_wr32(dev, 0x2500, 0); - nv_wr32(dev, 0x3250, 0); - nv_wr32(dev, 0x3220, 0); - nv_wr32(dev, 0x3204, 0); - nv_wr32(dev, 0x3210, 0); - nv_wr32(dev, 0x3270, 0); - nv_wr32(dev, 0x2044, 0x01003fff); - - /* Enable dummy channels setup by nv50_instmem.c */ - nv50_fifo_channel_enable(dev, 0); - nv50_fifo_channel_enable(dev, 127); -} - -int -nv50_fifo_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - int ret; - - NV_DEBUG(dev, "\n"); - - if (pfifo->playlist[0]) { - pfifo->cur_playlist = !pfifo->cur_playlist; - goto just_reset; - } - - ret = nouveau_gpuobj_new(dev, NULL, 128*4, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, - &pfifo->playlist[0]); - if (ret) { - NV_ERROR(dev, "error creating playlist 0: %d\n", ret); - return ret; - } - - ret = nouveau_gpuobj_new(dev, NULL, 128*4, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, - &pfifo->playlist[1]); - if (ret) { - nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); - NV_ERROR(dev, "error creating playlist 1: %d\n", ret); - return ret; - } - -just_reset: - nv50_fifo_init_reset(dev); - nv50_fifo_init_intr(dev); - nv50_fifo_init_context_table(dev); - nv50_fifo_init_regs__nv(dev); - nv50_fifo_init_regs(dev); - dev_priv->engine.fifo.enable(dev); - dev_priv->engine.fifo.reassign(dev, true); - - return 0; -} - -void -nv50_fifo_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - - NV_DEBUG(dev, "\n"); - - if (!pfifo->playlist[0]) - return; - - nv_wr32(dev, 0x2140, 0x00000000); - nouveau_irq_unregister(dev, 8); - - nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); - nouveau_gpuobj_ref(NULL, &pfifo->playlist[1]); -} - -int -nv50_fifo_channel_id(struct drm_device *dev) -{ - return nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH1) & - NV50_PFIFO_CACHE1_PUSH1_CHID_MASK; -} - -int -nv50_fifo_create_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramfc = NULL; - uint64_t ib_offset = chan->pushbuf_base + chan->dma.ib_base * 4; - unsigned long flags; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - if (dev_priv->chipset == 0x50) { - ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst, - chan->ramin->vinst, 0x100, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, - &chan->ramfc); - if (ret) - return ret; - - ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst + 0x0400, - chan->ramin->vinst + 0x0400, - 4096, 0, &chan->cache); - if (ret) - return ret; - } else { - ret = nouveau_gpuobj_new(dev, chan, 0x100, 256, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &chan->ramfc); - if (ret) - return ret; - - ret = nouveau_gpuobj_new(dev, chan, 4096, 1024, - 0, &chan->cache); - if (ret) - return ret; - } - ramfc = chan->ramfc; - - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV50_USER(chan->id), PAGE_SIZE); - if (!chan->user) - return -ENOMEM; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - - nv_wo32(ramfc, 0x48, chan->pushbuf->cinst >> 4); - nv_wo32(ramfc, 0x80, ((chan->ramht->bits - 9) << 27) | - (4 << 24) /* SEARCH_FULL */ | - (chan->ramht->gpuobj->cinst >> 4)); - nv_wo32(ramfc, 0x44, 0x01003fff); - nv_wo32(ramfc, 0x60, 0x7fffffff); - nv_wo32(ramfc, 0x40, 0x00000000); - nv_wo32(ramfc, 0x7c, 0x30000001); - nv_wo32(ramfc, 0x78, 0x00000000); - nv_wo32(ramfc, 0x3c, 0x403f6078); - nv_wo32(ramfc, 0x50, lower_32_bits(ib_offset)); - nv_wo32(ramfc, 0x54, upper_32_bits(ib_offset) | - drm_order(chan->dma.ib_max + 1) << 16); - - if (dev_priv->chipset != 0x50) { - nv_wo32(chan->ramin, 0, chan->id); - nv_wo32(chan->ramin, 4, chan->ramfc->vinst >> 8); - - nv_wo32(ramfc, 0x88, chan->cache->vinst >> 10); - nv_wo32(ramfc, 0x98, chan->ramin->vinst >> 12); - } - - dev_priv->engine.instmem.flush(dev); - - nv50_fifo_channel_enable(dev, chan->id); - nv50_fifo_playlist_update(dev); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - return 0; -} - -void -nv50_fifo_destroy_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_gpuobj *ramfc = NULL; - unsigned long flags; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - pfifo->reassign(dev, false); - - /* Unload the context if it's the currently active one */ - if (pfifo->channel_id(dev) == chan->id) { - pfifo->disable(dev); - pfifo->unload_context(dev); - pfifo->enable(dev); - } - - /* This will ensure the channel is seen as disabled. */ - nouveau_gpuobj_ref(chan->ramfc, &ramfc); - nouveau_gpuobj_ref(NULL, &chan->ramfc); - nv50_fifo_channel_disable(dev, chan->id); - - /* Dummy channel, also used on ch 127 */ - if (chan->id == 0) - nv50_fifo_channel_disable(dev, 127); - nv50_fifo_playlist_update(dev); - - pfifo->reassign(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - /* Free the channel resources */ - if (chan->user) { - iounmap(chan->user); - chan->user = NULL; - } - nouveau_gpuobj_ref(NULL, &ramfc); - nouveau_gpuobj_ref(NULL, &chan->cache); -} - -int -nv50_fifo_load_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramfc = chan->ramfc; - struct nouveau_gpuobj *cache = chan->cache; - int ptr, cnt; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - nv_wr32(dev, 0x3330, nv_ro32(ramfc, 0x00)); - nv_wr32(dev, 0x3334, nv_ro32(ramfc, 0x04)); - nv_wr32(dev, 0x3240, nv_ro32(ramfc, 0x08)); - nv_wr32(dev, 0x3320, nv_ro32(ramfc, 0x0c)); - nv_wr32(dev, 0x3244, nv_ro32(ramfc, 0x10)); - nv_wr32(dev, 0x3328, nv_ro32(ramfc, 0x14)); - nv_wr32(dev, 0x3368, nv_ro32(ramfc, 0x18)); - nv_wr32(dev, 0x336c, nv_ro32(ramfc, 0x1c)); - nv_wr32(dev, 0x3370, nv_ro32(ramfc, 0x20)); - nv_wr32(dev, 0x3374, nv_ro32(ramfc, 0x24)); - nv_wr32(dev, 0x3378, nv_ro32(ramfc, 0x28)); - nv_wr32(dev, 0x337c, nv_ro32(ramfc, 0x2c)); - nv_wr32(dev, 0x3228, nv_ro32(ramfc, 0x30)); - nv_wr32(dev, 0x3364, nv_ro32(ramfc, 0x34)); - nv_wr32(dev, 0x32a0, nv_ro32(ramfc, 0x38)); - nv_wr32(dev, 0x3224, nv_ro32(ramfc, 0x3c)); - nv_wr32(dev, 0x324c, nv_ro32(ramfc, 0x40)); - nv_wr32(dev, 0x2044, nv_ro32(ramfc, 0x44)); - nv_wr32(dev, 0x322c, nv_ro32(ramfc, 0x48)); - nv_wr32(dev, 0x3234, nv_ro32(ramfc, 0x4c)); - nv_wr32(dev, 0x3340, nv_ro32(ramfc, 0x50)); - nv_wr32(dev, 0x3344, nv_ro32(ramfc, 0x54)); - nv_wr32(dev, 0x3280, nv_ro32(ramfc, 0x58)); - nv_wr32(dev, 0x3254, nv_ro32(ramfc, 0x5c)); - nv_wr32(dev, 0x3260, nv_ro32(ramfc, 0x60)); - nv_wr32(dev, 0x3264, nv_ro32(ramfc, 0x64)); - nv_wr32(dev, 0x3268, nv_ro32(ramfc, 0x68)); - nv_wr32(dev, 0x326c, nv_ro32(ramfc, 0x6c)); - nv_wr32(dev, 0x32e4, nv_ro32(ramfc, 0x70)); - nv_wr32(dev, 0x3248, nv_ro32(ramfc, 0x74)); - nv_wr32(dev, 0x2088, nv_ro32(ramfc, 0x78)); - nv_wr32(dev, 0x2058, nv_ro32(ramfc, 0x7c)); - nv_wr32(dev, 0x2210, nv_ro32(ramfc, 0x80)); - - cnt = nv_ro32(ramfc, 0x84); - for (ptr = 0; ptr < cnt; ptr++) { - nv_wr32(dev, NV40_PFIFO_CACHE1_METHOD(ptr), - nv_ro32(cache, (ptr * 8) + 0)); - nv_wr32(dev, NV40_PFIFO_CACHE1_DATA(ptr), - nv_ro32(cache, (ptr * 8) + 4)); - } - nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, cnt << 2); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0); - - /* guessing that all the 0x34xx regs aren't on NV50 */ - if (dev_priv->chipset != 0x50) { - nv_wr32(dev, 0x340c, nv_ro32(ramfc, 0x88)); - nv_wr32(dev, 0x3400, nv_ro32(ramfc, 0x8c)); - nv_wr32(dev, 0x3404, nv_ro32(ramfc, 0x90)); - nv_wr32(dev, 0x3408, nv_ro32(ramfc, 0x94)); - nv_wr32(dev, 0x3410, nv_ro32(ramfc, 0x98)); - } - - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16)); - return 0; -} - -int -nv50_fifo_unload_context(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_gpuobj *ramfc, *cache; - struct nouveau_channel *chan = NULL; - int chid, get, put, ptr; - - NV_DEBUG(dev, "\n"); - - chid = pfifo->channel_id(dev); - if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1) - return 0; - - chan = dev_priv->channels.ptr[chid]; - if (!chan) { - NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); - return -EINVAL; - } - NV_DEBUG(dev, "ch%d\n", chan->id); - ramfc = chan->ramfc; - cache = chan->cache; - - nv_wo32(ramfc, 0x00, nv_rd32(dev, 0x3330)); - nv_wo32(ramfc, 0x04, nv_rd32(dev, 0x3334)); - nv_wo32(ramfc, 0x08, nv_rd32(dev, 0x3240)); - nv_wo32(ramfc, 0x0c, nv_rd32(dev, 0x3320)); - nv_wo32(ramfc, 0x10, nv_rd32(dev, 0x3244)); - nv_wo32(ramfc, 0x14, nv_rd32(dev, 0x3328)); - nv_wo32(ramfc, 0x18, nv_rd32(dev, 0x3368)); - nv_wo32(ramfc, 0x1c, nv_rd32(dev, 0x336c)); - nv_wo32(ramfc, 0x20, nv_rd32(dev, 0x3370)); - nv_wo32(ramfc, 0x24, nv_rd32(dev, 0x3374)); - nv_wo32(ramfc, 0x28, nv_rd32(dev, 0x3378)); - nv_wo32(ramfc, 0x2c, nv_rd32(dev, 0x337c)); - nv_wo32(ramfc, 0x30, nv_rd32(dev, 0x3228)); - nv_wo32(ramfc, 0x34, nv_rd32(dev, 0x3364)); - nv_wo32(ramfc, 0x38, nv_rd32(dev, 0x32a0)); - nv_wo32(ramfc, 0x3c, nv_rd32(dev, 0x3224)); - nv_wo32(ramfc, 0x40, nv_rd32(dev, 0x324c)); - nv_wo32(ramfc, 0x44, nv_rd32(dev, 0x2044)); - nv_wo32(ramfc, 0x48, nv_rd32(dev, 0x322c)); - nv_wo32(ramfc, 0x4c, nv_rd32(dev, 0x3234)); - nv_wo32(ramfc, 0x50, nv_rd32(dev, 0x3340)); - nv_wo32(ramfc, 0x54, nv_rd32(dev, 0x3344)); - nv_wo32(ramfc, 0x58, nv_rd32(dev, 0x3280)); - nv_wo32(ramfc, 0x5c, nv_rd32(dev, 0x3254)); - nv_wo32(ramfc, 0x60, nv_rd32(dev, 0x3260)); - nv_wo32(ramfc, 0x64, nv_rd32(dev, 0x3264)); - nv_wo32(ramfc, 0x68, nv_rd32(dev, 0x3268)); - nv_wo32(ramfc, 0x6c, nv_rd32(dev, 0x326c)); - nv_wo32(ramfc, 0x70, nv_rd32(dev, 0x32e4)); - nv_wo32(ramfc, 0x74, nv_rd32(dev, 0x3248)); - nv_wo32(ramfc, 0x78, nv_rd32(dev, 0x2088)); - nv_wo32(ramfc, 0x7c, nv_rd32(dev, 0x2058)); - nv_wo32(ramfc, 0x80, nv_rd32(dev, 0x2210)); - - put = (nv_rd32(dev, NV03_PFIFO_CACHE1_PUT) & 0x7ff) >> 2; - get = (nv_rd32(dev, NV03_PFIFO_CACHE1_GET) & 0x7ff) >> 2; - ptr = 0; - while (put != get) { - nv_wo32(cache, ptr + 0, - nv_rd32(dev, NV40_PFIFO_CACHE1_METHOD(get))); - nv_wo32(cache, ptr + 4, - nv_rd32(dev, NV40_PFIFO_CACHE1_DATA(get))); - get = (get + 1) & 0x1ff; - ptr += 8; - } - - /* guessing that all the 0x34xx regs aren't on NV50 */ - if (dev_priv->chipset != 0x50) { - nv_wo32(ramfc, 0x84, ptr >> 3); - nv_wo32(ramfc, 0x88, nv_rd32(dev, 0x340c)); - nv_wo32(ramfc, 0x8c, nv_rd32(dev, 0x3400)); - nv_wo32(ramfc, 0x90, nv_rd32(dev, 0x3404)); - nv_wo32(ramfc, 0x94, nv_rd32(dev, 0x3408)); - nv_wo32(ramfc, 0x98, nv_rd32(dev, 0x3410)); - } - - dev_priv->engine.instmem.flush(dev); - - /*XXX: probably reload ch127 (NULL) state back too */ - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127); - return 0; -} - -void -nv50_fifo_tlb_flush(struct drm_device *dev) -{ - nv50_vm_flush_engine(dev, 5); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_gpio.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_gpio.c deleted file mode 100644 index f429e6a8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_gpio.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_hw.h" -#include "nouveau_gpio.h" - -#include "nv50_display.h" - -static int -nv50_gpio_location(int line, u32 *reg, u32 *shift) -{ - const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; - - if (line >= 32) - return -EINVAL; - - *reg = nv50_gpio_reg[line >> 3]; - *shift = (line & 7) << 2; - return 0; -} - -int -nv50_gpio_drive(struct drm_device *dev, int line, int dir, int out) -{ - u32 reg, shift; - - if (nv50_gpio_location(line, ®, &shift)) - return -EINVAL; - - nv_mask(dev, reg, 7 << shift, (((dir ^ 1) << 1) | out) << shift); - return 0; -} - -int -nv50_gpio_sense(struct drm_device *dev, int line) -{ - u32 reg, shift; - - if (nv50_gpio_location(line, ®, &shift)) - return -EINVAL; - - return !!(nv_rd32(dev, reg) & (4 << shift)); -} - -void -nv50_gpio_irq_enable(struct drm_device *dev, int line, bool on) -{ - u32 reg = line < 16 ? 0xe050 : 0xe070; - u32 mask = 0x00010001 << (line & 0xf); - - nv_wr32(dev, reg + 4, mask); - nv_mask(dev, reg + 0, mask, on ? mask : 0); -} - -int -nvd0_gpio_drive(struct drm_device *dev, int line, int dir, int out) -{ - u32 data = ((dir ^ 1) << 13) | (out << 12); - nv_mask(dev, 0x00d610 + (line * 4), 0x00003000, data); - nv_mask(dev, 0x00d604, 0x00000001, 0x00000001); /* update? */ - return 0; -} - -int -nvd0_gpio_sense(struct drm_device *dev, int line) -{ - return !!(nv_rd32(dev, 0x00d610 + (line * 4)) & 0x00004000); -} - -static void -nv50_gpio_isr(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 intr0, intr1 = 0; - u32 hi, lo; - - intr0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050); - if (dev_priv->chipset >= 0x90) - intr1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070); - - hi = (intr0 & 0x0000ffff) | (intr1 << 16); - lo = (intr0 >> 16) | (intr1 & 0xffff0000); - nouveau_gpio_isr(dev, 0, hi | lo); - - nv_wr32(dev, 0xe054, intr0); - if (dev_priv->chipset >= 0x90) - nv_wr32(dev, 0xe074, intr1); -} - -int -nv50_gpio_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* disable, and ack any pending gpio interrupts */ - nv_wr32(dev, 0xe050, 0x00000000); - nv_wr32(dev, 0xe054, 0xffffffff); - if (dev_priv->chipset >= 0x90) { - nv_wr32(dev, 0xe070, 0x00000000); - nv_wr32(dev, 0xe074, 0xffffffff); - } - - nouveau_irq_register(dev, 21, nv50_gpio_isr); - return 0; -} - -void -nv50_gpio_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nv_wr32(dev, 0xe050, 0x00000000); - if (dev_priv->chipset >= 0x90) - nv_wr32(dev, 0xe070, 0x00000000); - nouveau_irq_unregister(dev, 21); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_graph.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_graph.c deleted file mode 100644 index 33d5711a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_graph.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" -#include "nouveau_grctx.h" -#include "nouveau_dma.h" -#include "nouveau_vm.h" -#include "nv50_evo.h" - -struct nv50_graph_engine { - struct nouveau_exec_engine base; - u32 ctxprog[512]; - u32 ctxprog_size; - u32 grctx_size; -}; - -static void -nv50_graph_fifo_access(struct drm_device *dev, bool enabled) -{ - const uint32_t mask = 0x00010001; - - if (enabled) - nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask); - else - nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask); -} - -static struct nouveau_channel * -nv50_graph_channel(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t inst; - int i; - - /* Be sure we're not in the middle of a context switch or bad things - * will happen, such as unloading the wrong pgraph context. - */ - if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) - NV_ERROR(dev, "Ctxprog is still running\n"); - - inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); - if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) - return NULL; - inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12; - - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - struct nouveau_channel *chan = dev_priv->channels.ptr[i]; - - if (chan && chan->ramin && chan->ramin->vinst == inst) - return chan; - } - - return NULL; -} - -static int -nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst) -{ - uint32_t fifo = nv_rd32(dev, 0x400500); - - nv_wr32(dev, 0x400500, fifo & ~1); - nv_wr32(dev, 0x400784, inst); - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x40); - nv_wr32(dev, 0x400320, nv_rd32(dev, 0x400320) | 0x11); - nv_wr32(dev, 0x400040, 0xffffffff); - (void)nv_rd32(dev, 0x400040); - nv_wr32(dev, 0x400040, 0x00000000); - nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 1); - - if (nouveau_wait_for_idle(dev)) - nv_wr32(dev, 0x40032c, inst | (1<<31)); - nv_wr32(dev, 0x400500, fifo); - - return 0; -} - -static int -nv50_graph_unload_context(struct drm_device *dev) -{ - uint32_t inst; - - inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); - if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) - return 0; - inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE; - - nouveau_wait_for_idle(dev); - nv_wr32(dev, 0x400784, inst); - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20); - nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01); - nouveau_wait_for_idle(dev); - - nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst); - return 0; -} - -static int -nv50_graph_init(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_graph_engine *pgraph = nv_engine(dev, engine); - u32 units = nv_rd32(dev, 0x001540); - int i; - - NV_DEBUG(dev, "\n"); - - /* master reset */ - nv_mask(dev, 0x000200, 0x00201000, 0x00000000); - nv_mask(dev, 0x000200, 0x00201000, 0x00201000); - nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ - - /* reset/enable traps and interrupts */ - nv_wr32(dev, 0x400804, 0xc0000000); - nv_wr32(dev, 0x406800, 0xc0000000); - nv_wr32(dev, 0x400c04, 0xc0000000); - nv_wr32(dev, 0x401800, 0xc0000000); - nv_wr32(dev, 0x405018, 0xc0000000); - nv_wr32(dev, 0x402000, 0xc0000000); - for (i = 0; i < 16; i++) { - if (!(units & (1 << i))) - continue; - - if (dev_priv->chipset < 0xa0) { - nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); - nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); - nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); - } else { - nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); - nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); - nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); - } - } - - nv_wr32(dev, 0x400108, 0xffffffff); - nv_wr32(dev, 0x400138, 0xffffffff); - nv_wr32(dev, 0x400100, 0xffffffff); - nv_wr32(dev, 0x40013c, 0xffffffff); - nv_wr32(dev, 0x400500, 0x00010001); - - /* upload context program, initialise ctxctl defaults */ - nv_wr32(dev, 0x400324, 0x00000000); - for (i = 0; i < pgraph->ctxprog_size; i++) - nv_wr32(dev, 0x400328, pgraph->ctxprog[i]); - nv_wr32(dev, 0x400824, 0x00000000); - nv_wr32(dev, 0x400828, 0x00000000); - nv_wr32(dev, 0x40082c, 0x00000000); - nv_wr32(dev, 0x400830, 0x00000000); - nv_wr32(dev, 0x400724, 0x00000000); - nv_wr32(dev, 0x40032c, 0x00000000); - nv_wr32(dev, 0x400320, 4); /* CTXCTL_CMD = NEWCTXDMA */ - - /* some unknown zcull magic */ - switch (dev_priv->chipset & 0xf0) { - case 0x50: - case 0x80: - case 0x90: - nv_wr32(dev, 0x402ca8, 0x00000800); - break; - case 0xa0: - default: - nv_wr32(dev, 0x402cc0, 0x00000000); - if (dev_priv->chipset == 0xa0 || - dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) { - nv_wr32(dev, 0x402ca8, 0x00000802); - } else { - nv_wr32(dev, 0x402cc0, 0x00000000); - nv_wr32(dev, 0x402ca8, 0x00000002); - } - - break; - } - - /* zero out zcull regions */ - for (i = 0; i < 8; i++) { - nv_wr32(dev, 0x402c20 + (i * 8), 0x00000000); - nv_wr32(dev, 0x402c24 + (i * 8), 0x00000000); - nv_wr32(dev, 0x402c28 + (i * 8), 0x00000000); - nv_wr32(dev, 0x402c2c + (i * 8), 0x00000000); - } - - return 0; -} - -static int -nv50_graph_fini(struct drm_device *dev, int engine, bool suspend) -{ - nv_mask(dev, 0x400500, 0x00010001, 0x00000000); - if (!nv_wait(dev, 0x400700, ~0, 0) && suspend) { - nv_mask(dev, 0x400500, 0x00010001, 0x00010001); - return -EBUSY; - } - nv50_graph_unload_context(dev); - nv_wr32(dev, 0x40013c, 0x00000000); - return 0; -} - -static int -nv50_graph_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; - struct nouveau_gpuobj *grctx = NULL; - struct nv50_graph_engine *pgraph = nv_engine(dev, engine); - struct nouveau_grctx ctx = {}; - int hdr, ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 0, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &grctx); - if (ret) - return ret; - - hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; - nv_wo32(ramin, hdr + 0x00, 0x00190002); - nv_wo32(ramin, hdr + 0x04, grctx->vinst + grctx->size - 1); - nv_wo32(ramin, hdr + 0x08, grctx->vinst); - nv_wo32(ramin, hdr + 0x0c, 0); - nv_wo32(ramin, hdr + 0x10, 0); - nv_wo32(ramin, hdr + 0x14, 0x00010000); - - ctx.dev = chan->dev; - ctx.mode = NOUVEAU_GRCTX_VALS; - ctx.data = grctx; - nv50_grctx_init(&ctx); - - nv_wo32(grctx, 0x00000, chan->ramin->vinst >> 12); - - dev_priv->engine.instmem.flush(dev); - - atomic_inc(&chan->vm->engref[NVOBJ_ENGINE_GR]); - chan->engctx[NVOBJ_ENGINE_GR] = grctx; - return 0; -} - -static void -nv50_graph_context_del(struct nouveau_channel *chan, int engine) -{ - struct nouveau_gpuobj *grctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; - unsigned long flags; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - if (!chan->ramin) - return; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - pfifo->reassign(dev, false); - nv50_graph_fifo_access(dev, false); - - if (nv50_graph_channel(dev) == chan) - nv50_graph_unload_context(dev); - - for (i = hdr; i < hdr + 24; i += 4) - nv_wo32(chan->ramin, i, 0); - dev_priv->engine.instmem.flush(dev); - - nv50_graph_fifo_access(dev, true); - pfifo->reassign(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - nouveau_gpuobj_ref(NULL, &grctx); - - atomic_dec(&chan->vm->engref[engine]); - chan->engctx[engine] = NULL; -} - -static int -nv50_graph_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - obj->engine = 1; - obj->class = class; - - nv_wo32(obj, 0x00, class); - nv_wo32(obj, 0x04, 0x00000000); - nv_wo32(obj, 0x08, 0x00000000); - nv_wo32(obj, 0x0c, 0x00000000); - dev_priv->engine.instmem.flush(dev); - - ret = nouveau_ramht_insert(chan, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static void -nv50_graph_context_switch(struct drm_device *dev) -{ - uint32_t inst; - - nv50_graph_unload_context(dev); - - inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_NEXT); - inst &= NV50_PGRAPH_CTXCTL_NEXT_INSTANCE; - nv50_graph_do_load_context(dev, inst); - - nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, - NV40_PGRAPH_INTR_EN) | NV_PGRAPH_INTR_CONTEXT_SWITCH); -} - -static int -nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - struct nouveau_gpuobj *gpuobj; - - gpuobj = nouveau_ramht_find(chan, data); - if (!gpuobj) - return -ENOENT; - - if (nouveau_notifier_offset(gpuobj, NULL)) - return -EINVAL; - - chan->nvsw.vblsem = gpuobj; - chan->nvsw.vblsem_offset = ~0; - return 0; -} - -static int -nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - if (nouveau_notifier_offset(chan->nvsw.vblsem, &data)) - return -ERANGE; - - chan->nvsw.vblsem_offset = data >> 2; - return 0; -} - -static int -nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - chan->nvsw.vblsem_rval = data; - return 0; -} - -static int -nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) - return -EINVAL; - - drm_vblank_get(dev, data); - - chan->nvsw.vblsem_head = data; - list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); - - return 0; -} - -static int -nv50_graph_nvsw_mthd_page_flip(struct nouveau_channel *chan, - u32 class, u32 mthd, u32 data) -{ - nouveau_finish_page_flip(chan, NULL); - return 0; -} - - -static void -nv50_graph_tlb_flush(struct drm_device *dev, int engine) -{ - nv50_vm_flush_engine(dev, 0); -} - -static void -nv84_graph_tlb_flush(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; - bool idle, timeout = false; - unsigned long flags; - u64 start; - u32 tmp; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, 0x400500, 0x00000001, 0x00000000); - - start = ptimer->read(dev); - do { - idle = true; - - for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) { - if ((tmp & 7) == 1) - idle = false; - } - - for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) { - if ((tmp & 7) == 1) - idle = false; - } - - for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) { - if ((tmp & 7) == 1) - idle = false; - } - } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000)); - - if (timeout) { - NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: " - "0x%08x 0x%08x 0x%08x 0x%08x\n", - nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380), - nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388)); - } - - nv50_vm_flush_engine(dev, 0); - - nv_mask(dev, 0x400500, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); -} - -static struct nouveau_enum nv50_mp_exec_error_names[] = { - { 3, "STACK_UNDERFLOW", NULL }, - { 4, "QUADON_ACTIVE", NULL }, - { 8, "TIMEOUT", NULL }, - { 0x10, "INVALID_OPCODE", NULL }, - { 0x40, "BREAKPOINT", NULL }, - {} -}; - -static struct nouveau_bitfield nv50_graph_trap_m2mf[] = { - { 0x00000001, "NOTIFY" }, - { 0x00000002, "IN" }, - { 0x00000004, "OUT" }, - {} -}; - -static struct nouveau_bitfield nv50_graph_trap_vfetch[] = { - { 0x00000001, "FAULT" }, - {} -}; - -static struct nouveau_bitfield nv50_graph_trap_strmout[] = { - { 0x00000001, "FAULT" }, - {} -}; - -static struct nouveau_bitfield nv50_graph_trap_ccache[] = { - { 0x00000001, "FAULT" }, - {} -}; - -/* There must be a *lot* of these. Will take some time to gather them up. */ -struct nouveau_enum nv50_data_error_names[] = { - { 0x00000003, "INVALID_QUERY_OR_TEXTURE", NULL }, - { 0x00000004, "INVALID_VALUE", NULL }, - { 0x00000005, "INVALID_ENUM", NULL }, - { 0x00000008, "INVALID_OBJECT", NULL }, - { 0x00000009, "READ_ONLY_OBJECT", NULL }, - { 0x0000000a, "SUPERVISOR_OBJECT", NULL }, - { 0x0000000b, "INVALID_ADDRESS_ALIGNMENT", NULL }, - { 0x0000000c, "INVALID_BITFIELD", NULL }, - { 0x0000000d, "BEGIN_END_ACTIVE", NULL }, - { 0x0000000e, "SEMANTIC_COLOR_BACK_OVER_LIMIT", NULL }, - { 0x0000000f, "VIEWPORT_ID_NEEDS_GP", NULL }, - { 0x00000010, "RT_DOUBLE_BIND", NULL }, - { 0x00000011, "RT_TYPES_MISMATCH", NULL }, - { 0x00000012, "RT_LINEAR_WITH_ZETA", NULL }, - { 0x00000015, "FP_TOO_FEW_REGS", NULL }, - { 0x00000016, "ZETA_FORMAT_CSAA_MISMATCH", NULL }, - { 0x00000017, "RT_LINEAR_WITH_MSAA", NULL }, - { 0x00000018, "FP_INTERPOLANT_START_OVER_LIMIT", NULL }, - { 0x00000019, "SEMANTIC_LAYER_OVER_LIMIT", NULL }, - { 0x0000001a, "RT_INVALID_ALIGNMENT", NULL }, - { 0x0000001b, "SAMPLER_OVER_LIMIT", NULL }, - { 0x0000001c, "TEXTURE_OVER_LIMIT", NULL }, - { 0x0000001e, "GP_TOO_MANY_OUTPUTS", NULL }, - { 0x0000001f, "RT_BPP128_WITH_MS8", NULL }, - { 0x00000021, "Z_OUT_OF_BOUNDS", NULL }, - { 0x00000023, "XY_OUT_OF_BOUNDS", NULL }, - { 0x00000027, "CP_MORE_PARAMS_THAN_SHARED", NULL }, - { 0x00000028, "CP_NO_REG_SPACE_STRIPED", NULL }, - { 0x00000029, "CP_NO_REG_SPACE_PACKED", NULL }, - { 0x0000002a, "CP_NOT_ENOUGH_WARPS", NULL }, - { 0x0000002b, "CP_BLOCK_SIZE_MISMATCH", NULL }, - { 0x0000002c, "CP_NOT_ENOUGH_LOCAL_WARPS", NULL }, - { 0x0000002d, "CP_NOT_ENOUGH_STACK_WARPS", NULL }, - { 0x0000002e, "CP_NO_BLOCKDIM_LATCH", NULL }, - { 0x00000031, "ENG2D_FORMAT_MISMATCH", NULL }, - { 0x0000003f, "PRIMITIVE_ID_NEEDS_GP", NULL }, - { 0x00000044, "SEMANTIC_VIEWPORT_OVER_LIMIT", NULL }, - { 0x00000045, "SEMANTIC_COLOR_FRONT_OVER_LIMIT", NULL }, - { 0x00000046, "LAYER_ID_NEEDS_GP", NULL }, - { 0x00000047, "SEMANTIC_CLIP_OVER_LIMIT", NULL }, - { 0x00000048, "SEMANTIC_PTSZ_OVER_LIMIT", NULL }, - {} -}; - -static struct nouveau_bitfield nv50_graph_intr[] = { - { 0x00000001, "NOTIFY" }, - { 0x00000002, "COMPUTE_QUERY" }, - { 0x00000010, "ILLEGAL_MTHD" }, - { 0x00000020, "ILLEGAL_CLASS" }, - { 0x00000040, "DOUBLE_NOTIFY" }, - { 0x00001000, "CONTEXT_SWITCH" }, - { 0x00010000, "BUFFER_NOTIFY" }, - { 0x00100000, "DATA_ERROR" }, - { 0x00200000, "TRAP" }, - { 0x01000000, "SINGLE_STEP" }, - {} -}; - -static void -nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t units = nv_rd32(dev, 0x1540); - uint32_t addr, mp10, status, pc, oplow, ophigh; - int i; - int mps = 0; - for (i = 0; i < 4; i++) { - if (!(units & 1 << (i+24))) - continue; - if (dev_priv->chipset < 0xa0) - addr = 0x408200 + (tpid << 12) + (i << 7); - else - addr = 0x408100 + (tpid << 11) + (i << 7); - mp10 = nv_rd32(dev, addr + 0x10); - status = nv_rd32(dev, addr + 0x14); - if (!status) - continue; - if (display) { - nv_rd32(dev, addr + 0x20); - pc = nv_rd32(dev, addr + 0x24); - oplow = nv_rd32(dev, addr + 0x70); - ophigh = nv_rd32(dev, addr + 0x74); - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " - "TP %d MP %d: ", tpid, i); - nouveau_enum_print(nv50_mp_exec_error_names, status); - printk(" at %06x warp %d, opcode %08x %08x\n", - pc&0xffffff, pc >> 24, - oplow, ophigh); - } - nv_wr32(dev, addr + 0x10, mp10); - nv_wr32(dev, addr + 0x14, 0); - mps++; - } - if (!mps && display) - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: " - "No MPs claiming errors?\n", tpid); -} - -static void -nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, - uint32_t ustatus_new, int display, const char *name) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int tps = 0; - uint32_t units = nv_rd32(dev, 0x1540); - int i, r; - uint32_t ustatus_addr, ustatus; - for (i = 0; i < 16; i++) { - if (!(units & (1 << i))) - continue; - if (dev_priv->chipset < 0xa0) - ustatus_addr = ustatus_old + (i << 12); - else - ustatus_addr = ustatus_new + (i << 11); - ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff; - if (!ustatus) - continue; - tps++; - switch (type) { - case 6: /* texture error... unknown for now */ - if (display) { - NV_ERROR(dev, "magic set %d:\n", i); - for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - } - break; - case 7: /* MP error */ - if (ustatus & 0x04030000) { - nv50_pgraph_mp_trap(dev, i, display); - ustatus &= ~0x04030000; - } - break; - case 8: /* TPDMA error */ - { - uint32_t e0c = nv_rd32(dev, ustatus_addr + 4); - uint32_t e10 = nv_rd32(dev, ustatus_addr + 8); - uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc); - uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10); - uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); - uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); - uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); - /* 2d engine destination */ - if (ustatus & 0x00000010) { - if (display) { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", - i, e14, e10); - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000010; - } - /* Render target */ - if (ustatus & 0x00000040) { - if (display) { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", - i, e14, e10); - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000040; - } - /* CUDA memory: l[], g[] or stack. */ - if (ustatus & 0x00000080) { - if (display) { - if (e18 & 0x80000000) { - /* g[] read fault? */ - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", - i, e14, e10 | ((e18 >> 24) & 0x1f)); - e18 &= ~0x1f000000; - } else if (e18 & 0xc) { - /* g[] write fault? */ - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", - i, e14, e10 | ((e18 >> 7) & 0x1f)); - e18 &= ~0x00000f80; - } else { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", - i, e14, e10); - } - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000080; - } - } - break; - } - if (ustatus) { - if (display) - NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); - } - nv_wr32(dev, ustatus_addr, 0xc0000000); - } - - if (!tps && display) - NV_INFO(dev, "%s - No TPs claiming errors?\n", name); -} - -static int -nv50_pgraph_trap_handler(struct drm_device *dev, u32 display, u64 inst, u32 chid) -{ - u32 status = nv_rd32(dev, 0x400108); - u32 ustatus; - - if (!status && display) { - NV_INFO(dev, "PGRAPH - TRAP: no units reporting traps?\n"); - return 1; - } - - /* DISPATCH: Relays commands to other units and handles NOTIFY, - * COND, QUERY. If you get a trap from it, the command is still stuck - * in DISPATCH and you need to do something about it. */ - if (status & 0x001) { - ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n"); - } - - nv_wr32(dev, 0x400500, 0x00000000); - - /* Known to be triggered by screwed up NOTIFY and COND... */ - if (ustatus & 0x00000001) { - u32 addr = nv_rd32(dev, 0x400808); - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00001ffc); - u32 datal = nv_rd32(dev, 0x40080c); - u32 datah = nv_rd32(dev, 0x400810); - u32 class = nv_rd32(dev, 0x400814); - u32 r848 = nv_rd32(dev, 0x400848); - - NV_INFO(dev, "PGRAPH - TRAP DISPATCH_FAULT\n"); - if (display && (addr & 0x80000000)) { - NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) " - "subc %d class 0x%04x mthd 0x%04x " - "data 0x%08x%08x " - "400808 0x%08x 400848 0x%08x\n", - chid, inst, subc, class, mthd, datah, - datal, addr, r848); - } else - if (display) { - NV_INFO(dev, "PGRAPH - no stuck command?\n"); - } - - nv_wr32(dev, 0x400808, 0); - nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3); - nv_wr32(dev, 0x400848, 0); - ustatus &= ~0x00000001; - } - - if (ustatus & 0x00000002) { - u32 addr = nv_rd32(dev, 0x40084c); - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00001ffc); - u32 data = nv_rd32(dev, 0x40085c); - u32 class = nv_rd32(dev, 0x400814); - - NV_INFO(dev, "PGRAPH - TRAP DISPATCH_QUERY\n"); - if (display && (addr & 0x80000000)) { - NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) " - "subc %d class 0x%04x mthd 0x%04x " - "data 0x%08x 40084c 0x%08x\n", - chid, inst, subc, class, mthd, - data, addr); - } else - if (display) { - NV_INFO(dev, "PGRAPH - no stuck command?\n"); - } - - nv_wr32(dev, 0x40084c, 0); - ustatus &= ~0x00000002; - } - - if (ustatus && display) { - NV_INFO(dev, "PGRAPH - TRAP_DISPATCH (unknown " - "0x%08x)\n", ustatus); - } - - nv_wr32(dev, 0x400804, 0xc0000000); - nv_wr32(dev, 0x400108, 0x001); - status &= ~0x001; - if (!status) - return 0; - } - - /* M2MF: Memory to memory copy engine. */ - if (status & 0x002) { - u32 ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff; - if (display) { - NV_INFO(dev, "PGRAPH - TRAP_M2MF"); - nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - TRAP_M2MF %08x %08x %08x %08x\n", - nv_rd32(dev, 0x406804), nv_rd32(dev, 0x406808), - nv_rd32(dev, 0x40680c), nv_rd32(dev, 0x406810)); - - } - - /* No sane way found yet -- just reset the bugger. */ - nv_wr32(dev, 0x400040, 2); - nv_wr32(dev, 0x400040, 0); - nv_wr32(dev, 0x406800, 0xc0000000); - nv_wr32(dev, 0x400108, 0x002); - status &= ~0x002; - } - - /* VFETCH: Fetches data from vertex buffers. */ - if (status & 0x004) { - u32 ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff; - if (display) { - NV_INFO(dev, "PGRAPH - TRAP_VFETCH"); - nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - TRAP_VFETCH %08x %08x %08x %08x\n", - nv_rd32(dev, 0x400c00), nv_rd32(dev, 0x400c08), - nv_rd32(dev, 0x400c0c), nv_rd32(dev, 0x400c10)); - } - - nv_wr32(dev, 0x400c04, 0xc0000000); - nv_wr32(dev, 0x400108, 0x004); - status &= ~0x004; - } - - /* STRMOUT: DirectX streamout / OpenGL transform feedback. */ - if (status & 0x008) { - ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff; - if (display) { - NV_INFO(dev, "PGRAPH - TRAP_STRMOUT"); - nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - TRAP_STRMOUT %08x %08x %08x %08x\n", - nv_rd32(dev, 0x401804), nv_rd32(dev, 0x401808), - nv_rd32(dev, 0x40180c), nv_rd32(dev, 0x401810)); - - } - - /* No sane way found yet -- just reset the bugger. */ - nv_wr32(dev, 0x400040, 0x80); - nv_wr32(dev, 0x400040, 0); - nv_wr32(dev, 0x401800, 0xc0000000); - nv_wr32(dev, 0x400108, 0x008); - status &= ~0x008; - } - - /* CCACHE: Handles code and c[] caches and fills them. */ - if (status & 0x010) { - ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff; - if (display) { - NV_INFO(dev, "PGRAPH - TRAP_CCACHE"); - nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus); - printk("\n"); - NV_INFO(dev, "PGRAPH - TRAP_CCACHE %08x %08x %08x %08x" - " %08x %08x %08x\n", - nv_rd32(dev, 0x405000), nv_rd32(dev, 0x405004), - nv_rd32(dev, 0x405008), nv_rd32(dev, 0x40500c), - nv_rd32(dev, 0x405010), nv_rd32(dev, 0x405014), - nv_rd32(dev, 0x40501c)); - - } - - nv_wr32(dev, 0x405018, 0xc0000000); - nv_wr32(dev, 0x400108, 0x010); - status &= ~0x010; - } - - /* Unknown, not seen yet... 0x402000 is the only trap status reg - * remaining, so try to handle it anyway. Perhaps related to that - * unknown DMA slot on tesla? */ - if (status & 0x20) { - ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; - if (display) - NV_INFO(dev, "PGRAPH - TRAP_UNKC04 0x%08x\n", ustatus); - nv_wr32(dev, 0x402000, 0xc0000000); - /* no status modifiction on purpose */ - } - - /* TEXTURE: CUDA texturing units */ - if (status & 0x040) { - nv50_pgraph_tp_trap(dev, 6, 0x408900, 0x408600, display, - "PGRAPH - TRAP_TEXTURE"); - nv_wr32(dev, 0x400108, 0x040); - status &= ~0x040; - } - - /* MP: CUDA execution engines. */ - if (status & 0x080) { - nv50_pgraph_tp_trap(dev, 7, 0x408314, 0x40831c, display, - "PGRAPH - TRAP_MP"); - nv_wr32(dev, 0x400108, 0x080); - status &= ~0x080; - } - - /* TPDMA: Handles TP-initiated uncached memory accesses: - * l[], g[], stack, 2d surfaces, render targets. */ - if (status & 0x100) { - nv50_pgraph_tp_trap(dev, 8, 0x408e08, 0x408708, display, - "PGRAPH - TRAP_TPDMA"); - nv_wr32(dev, 0x400108, 0x100); - status &= ~0x100; - } - - if (status) { - if (display) - NV_INFO(dev, "PGRAPH - TRAP: unknown 0x%08x\n", status); - nv_wr32(dev, 0x400108, status); - } - - return 1; -} - -int -nv50_graph_isr_chid(struct drm_device *dev, u64 inst) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan; - unsigned long flags; - int i; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->ramin) - continue; - - if (inst == chan->ramin->vinst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return i; -} - -static void -nv50_graph_isr(struct drm_device *dev) -{ - u32 stat; - - while ((stat = nv_rd32(dev, 0x400100))) { - u64 inst = (u64)(nv_rd32(dev, 0x40032c) & 0x0fffffff) << 12; - u32 chid = nv50_graph_isr_chid(dev, inst); - u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); - u32 subc = (addr & 0x00070000) >> 16; - u32 mthd = (addr & 0x00001ffc); - u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); - u32 class = nv_rd32(dev, 0x400814); - u32 show = stat; - - if (stat & 0x00000010) { - if (!nouveau_gpuobj_mthd_call2(dev, chid, class, - mthd, data)) - show &= ~0x00000010; - } - - if (stat & 0x00001000) { - nv_wr32(dev, 0x400500, 0x00000000); - nv_wr32(dev, 0x400100, 0x00001000); - nv_mask(dev, 0x40013c, 0x00001000, 0x00000000); - nv50_graph_context_switch(dev); - stat &= ~0x00001000; - show &= ~0x00001000; - } - - show = (show && nouveau_ratelimit()) ? show : 0; - - if (show & 0x00100000) { - u32 ecode = nv_rd32(dev, 0x400110); - NV_INFO(dev, "PGRAPH - DATA_ERROR "); - nouveau_enum_print(nv50_data_error_names, ecode); - printk("\n"); - } - - if (stat & 0x00200000) { - if (!nv50_pgraph_trap_handler(dev, show, inst, chid)) - show &= ~0x00200000; - } - - nv_wr32(dev, 0x400100, stat); - nv_wr32(dev, 0x400500, 0x00010001); - - if (show) { - NV_INFO(dev, "PGRAPH -"); - nouveau_bitfield_print(nv50_graph_intr, show); - printk("\n"); - NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d " - "class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, subc, class, mthd, data); - nv50_fb_vm_trap(dev, 1); - } - } - - if (nv_rd32(dev, 0x400824) & (1 << 31)) - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); -} - -static void -nv50_graph_destroy(struct drm_device *dev, int engine) -{ - struct nv50_graph_engine *pgraph = nv_engine(dev, engine); - - NVOBJ_ENGINE_DEL(dev, GR); - - nouveau_irq_unregister(dev, 12); - kfree(pgraph); -} - -int -nv50_graph_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_graph_engine *pgraph; - struct nouveau_grctx ctx = {}; - int ret; - - pgraph = kzalloc(sizeof(*pgraph),GFP_KERNEL); - if (!pgraph) - return -ENOMEM; - - ctx.dev = dev; - ctx.mode = NOUVEAU_GRCTX_PROG; - ctx.data = pgraph->ctxprog; - ctx.ctxprog_max = ARRAY_SIZE(pgraph->ctxprog); - - ret = nv50_grctx_init(&ctx); - if (ret) { - NV_ERROR(dev, "PGRAPH: ctxprog build failed\n"); - kfree(pgraph); - return 0; - } - - pgraph->grctx_size = ctx.ctxvals_pos * 4; - pgraph->ctxprog_size = ctx.ctxprog_len; - - pgraph->base.destroy = nv50_graph_destroy; - pgraph->base.init = nv50_graph_init; - pgraph->base.fini = nv50_graph_fini; - pgraph->base.context_new = nv50_graph_context_new; - pgraph->base.context_del = nv50_graph_context_del; - pgraph->base.object_new = nv50_graph_object_new; - if (dev_priv->chipset == 0x50 || dev_priv->chipset == 0xac) - pgraph->base.tlb_flush = nv50_graph_tlb_flush; - else - pgraph->base.tlb_flush = nv84_graph_tlb_flush; - - nouveau_irq_register(dev, 12, nv50_graph_isr); - - /* NVSW really doesn't live here... */ - NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ - NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem); - NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset); - NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val); - NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release); - NVOBJ_MTHD (dev, 0x506e, 0x0500, nv50_graph_nvsw_mthd_page_flip); - - NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); - NVOBJ_CLASS(dev, 0x0030, GR); /* null */ - NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */ - NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */ - - /* tesla */ - if (dev_priv->chipset == 0x50) - NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */ - else - if (dev_priv->chipset < 0xa0) - NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */ - else { - switch (dev_priv->chipset) { - case 0xa0: - case 0xaa: - case 0xac: - NVOBJ_CLASS(dev, 0x8397, GR); - break; - case 0xa3: - case 0xa5: - case 0xa8: - NVOBJ_CLASS(dev, 0x8597, GR); - break; - case 0xaf: - NVOBJ_CLASS(dev, 0x8697, GR); - break; - } - } - - /* compute */ - NVOBJ_CLASS(dev, 0x50c0, GR); - if (dev_priv->chipset > 0xa0 && - dev_priv->chipset != 0xaa && - dev_priv->chipset != 0xac) - NVOBJ_CLASS(dev, 0x85c0, GR); - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_grctx.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_grctx.c deleted file mode 100644 index 4b46d696..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_grctx.c +++ /dev/null @@ -1,3333 +0,0 @@ -/* - * Copyright 2009 Marcin Kościelnicki - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#define CP_FLAG_CLEAR 0 -#define CP_FLAG_SET 1 -#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) -#define CP_FLAG_SWAP_DIRECTION_LOAD 0 -#define CP_FLAG_SWAP_DIRECTION_SAVE 1 -#define CP_FLAG_UNK01 ((0 * 32) + 1) -#define CP_FLAG_UNK01_CLEAR 0 -#define CP_FLAG_UNK01_SET 1 -#define CP_FLAG_UNK03 ((0 * 32) + 3) -#define CP_FLAG_UNK03_CLEAR 0 -#define CP_FLAG_UNK03_SET 1 -#define CP_FLAG_USER_SAVE ((0 * 32) + 5) -#define CP_FLAG_USER_SAVE_NOT_PENDING 0 -#define CP_FLAG_USER_SAVE_PENDING 1 -#define CP_FLAG_USER_LOAD ((0 * 32) + 6) -#define CP_FLAG_USER_LOAD_NOT_PENDING 0 -#define CP_FLAG_USER_LOAD_PENDING 1 -#define CP_FLAG_UNK0B ((0 * 32) + 0xb) -#define CP_FLAG_UNK0B_CLEAR 0 -#define CP_FLAG_UNK0B_SET 1 -#define CP_FLAG_XFER_SWITCH ((0 * 32) + 0xe) -#define CP_FLAG_XFER_SWITCH_DISABLE 0 -#define CP_FLAG_XFER_SWITCH_ENABLE 1 -#define CP_FLAG_STATE ((0 * 32) + 0x1c) -#define CP_FLAG_STATE_STOPPED 0 -#define CP_FLAG_STATE_RUNNING 1 -#define CP_FLAG_UNK1D ((0 * 32) + 0x1d) -#define CP_FLAG_UNK1D_CLEAR 0 -#define CP_FLAG_UNK1D_SET 1 -#define CP_FLAG_UNK20 ((1 * 32) + 0) -#define CP_FLAG_UNK20_CLEAR 0 -#define CP_FLAG_UNK20_SET 1 -#define CP_FLAG_STATUS ((2 * 32) + 0) -#define CP_FLAG_STATUS_BUSY 0 -#define CP_FLAG_STATUS_IDLE 1 -#define CP_FLAG_AUTO_SAVE ((2 * 32) + 4) -#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 -#define CP_FLAG_AUTO_SAVE_PENDING 1 -#define CP_FLAG_AUTO_LOAD ((2 * 32) + 5) -#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 -#define CP_FLAG_AUTO_LOAD_PENDING 1 -#define CP_FLAG_NEWCTX ((2 * 32) + 10) -#define CP_FLAG_NEWCTX_BUSY 0 -#define CP_FLAG_NEWCTX_DONE 1 -#define CP_FLAG_XFER ((2 * 32) + 11) -#define CP_FLAG_XFER_IDLE 0 -#define CP_FLAG_XFER_BUSY 1 -#define CP_FLAG_ALWAYS ((2 * 32) + 13) -#define CP_FLAG_ALWAYS_FALSE 0 -#define CP_FLAG_ALWAYS_TRUE 1 -#define CP_FLAG_INTR ((2 * 32) + 15) -#define CP_FLAG_INTR_NOT_PENDING 0 -#define CP_FLAG_INTR_PENDING 1 - -#define CP_CTX 0x00100000 -#define CP_CTX_COUNT 0x000f0000 -#define CP_CTX_COUNT_SHIFT 16 -#define CP_CTX_REG 0x00003fff -#define CP_LOAD_SR 0x00200000 -#define CP_LOAD_SR_VALUE 0x000fffff -#define CP_BRA 0x00400000 -#define CP_BRA_IP 0x0001ff00 -#define CP_BRA_IP_SHIFT 8 -#define CP_BRA_IF_CLEAR 0x00000080 -#define CP_BRA_FLAG 0x0000007f -#define CP_WAIT 0x00500000 -#define CP_WAIT_SET 0x00000080 -#define CP_WAIT_FLAG 0x0000007f -#define CP_SET 0x00700000 -#define CP_SET_1 0x00000080 -#define CP_SET_FLAG 0x0000007f -#define CP_NEWCTX 0x00600004 -#define CP_NEXT_TO_SWAP 0x00600005 -#define CP_SET_CONTEXT_POINTER 0x00600006 -#define CP_SET_XFER_POINTER 0x00600007 -#define CP_ENABLE 0x00600009 -#define CP_END 0x0060000c -#define CP_NEXT_TO_CURRENT 0x0060000d -#define CP_DISABLE1 0x0090ffff -#define CP_DISABLE2 0x0091ffff -#define CP_XFER_1 0x008000ff -#define CP_XFER_2 0x008800ff -#define CP_SEEK_1 0x00c000ff -#define CP_SEEK_2 0x00c800ff - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_grctx.h" - -#define IS_NVA3F(x) (((x) > 0xa0 && (x) < 0xaa) || (x) == 0xaf) -#define IS_NVAAF(x) ((x) >= 0xaa && (x) <= 0xac) - -/* - * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's - * the GPU itself that does context-switching, but it needs a special - * microcode to do it. And it's the driver's task to supply this microcode, - * further known as ctxprog, as well as the initial context values, known - * as ctxvals. - * - * Without ctxprog, you cannot switch contexts. Not even in software, since - * the majority of context [xfer strands] isn't accessible directly. You're - * stuck with a single channel, and you also suffer all the problems resulting - * from missing ctxvals, since you cannot load them. - * - * Without ctxvals, you're stuck with PGRAPH's default context. It's enough to - * run 2d operations, but trying to utilise 3d or CUDA will just lock you up, - * since you don't have... some sort of needed setup. - * - * Nouveau will just disable acceleration if not given ctxprog + ctxvals, since - * it's too much hassle to handle no-ctxprog as a special case. - */ - -/* - * How ctxprogs work. - * - * The ctxprog is written in its own kind of microcode, with very small and - * crappy set of available commands. You upload it to a small [512 insns] - * area of memory on PGRAPH, and it'll be run when PFIFO wants PGRAPH to - * switch channel. or when the driver explicitely requests it. Stuff visible - * to ctxprog consists of: PGRAPH MMIO registers, PGRAPH context strands, - * the per-channel context save area in VRAM [known as ctxvals or grctx], - * 4 flags registers, a scratch register, two grctx pointers, plus many - * random poorly-understood details. - * - * When ctxprog runs, it's supposed to check what operations are asked of it, - * save old context if requested, optionally reset PGRAPH and switch to the - * new channel, and load the new context. Context consists of three major - * parts: subset of MMIO registers and two "xfer areas". - */ - -/* TODO: - * - document unimplemented bits compared to nvidia - * - NVAx: make a TP subroutine, use it. - * - use 0x4008fc instead of 0x1540? - */ - -enum cp_label { - cp_check_load = 1, - cp_setup_auto_load, - cp_setup_load, - cp_setup_save, - cp_swap_state, - cp_prepare_exit, - cp_exit, -}; - -static void nv50_graph_construct_mmio(struct nouveau_grctx *ctx); -static void nv50_graph_construct_xfer1(struct nouveau_grctx *ctx); -static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx); - -/* Main function: construct the ctxprog skeleton, call the other functions. */ - -int -nv50_grctx_init(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - - switch (dev_priv->chipset) { - case 0x50: - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0x98: - case 0xa0: - case 0xa3: - case 0xa5: - case 0xa8: - case 0xaa: - case 0xac: - case 0xaf: - break; - default: - NV_ERROR(ctx->dev, "I don't know how to make a ctxprog for " - "your NV%x card.\n", dev_priv->chipset); - NV_ERROR(ctx->dev, "Disabling acceleration. Please contact " - "the devs.\n"); - return -ENOSYS; - } - - cp_set (ctx, STATE, RUNNING); - cp_set (ctx, XFER_SWITCH, ENABLE); - /* decide whether we're loading/unloading the context */ - cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); - cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); - - cp_name(ctx, cp_check_load); - cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); - cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); - cp_bra (ctx, ALWAYS, TRUE, cp_exit); - - /* setup for context load */ - cp_name(ctx, cp_setup_auto_load); - cp_out (ctx, CP_DISABLE1); - cp_out (ctx, CP_DISABLE2); - cp_out (ctx, CP_ENABLE); - cp_out (ctx, CP_NEXT_TO_SWAP); - cp_set (ctx, UNK01, SET); - cp_name(ctx, cp_setup_load); - cp_out (ctx, CP_NEWCTX); - cp_wait(ctx, NEWCTX, BUSY); - cp_set (ctx, UNK1D, CLEAR); - cp_set (ctx, SWAP_DIRECTION, LOAD); - cp_bra (ctx, UNK0B, SET, cp_prepare_exit); - cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); - - /* setup for context save */ - cp_name(ctx, cp_setup_save); - cp_set (ctx, UNK1D, SET); - cp_wait(ctx, STATUS, BUSY); - cp_wait(ctx, INTR, PENDING); - cp_bra (ctx, STATUS, BUSY, cp_setup_save); - cp_set (ctx, UNK01, SET); - cp_set (ctx, SWAP_DIRECTION, SAVE); - - /* general PGRAPH state */ - cp_name(ctx, cp_swap_state); - cp_set (ctx, UNK03, SET); - cp_pos (ctx, 0x00004/4); - cp_ctx (ctx, 0x400828, 1); /* needed. otherwise, flickering happens. */ - cp_pos (ctx, 0x00100/4); - nv50_graph_construct_mmio(ctx); - nv50_graph_construct_xfer1(ctx); - nv50_graph_construct_xfer2(ctx); - - cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); - - cp_set (ctx, UNK20, SET); - cp_set (ctx, SWAP_DIRECTION, SAVE); /* no idea why this is needed, but fixes at least one lockup. */ - cp_lsr (ctx, ctx->ctxvals_base); - cp_out (ctx, CP_SET_XFER_POINTER); - cp_lsr (ctx, 4); - cp_out (ctx, CP_SEEK_1); - cp_out (ctx, CP_XFER_1); - cp_wait(ctx, XFER, BUSY); - - /* pre-exit state updates */ - cp_name(ctx, cp_prepare_exit); - cp_set (ctx, UNK01, CLEAR); - cp_set (ctx, UNK03, CLEAR); - cp_set (ctx, UNK1D, CLEAR); - - cp_bra (ctx, USER_SAVE, PENDING, cp_exit); - cp_out (ctx, CP_NEXT_TO_CURRENT); - - cp_name(ctx, cp_exit); - cp_set (ctx, USER_SAVE, NOT_PENDING); - cp_set (ctx, USER_LOAD, NOT_PENDING); - cp_set (ctx, XFER_SWITCH, DISABLE); - cp_set (ctx, STATE, STOPPED); - cp_out (ctx, CP_END); - ctx->ctxvals_pos += 0x400; /* padding... no idea why you need it */ - - return 0; -} - -/* - * Constructs MMIO part of ctxprog and ctxvals. Just a matter of knowing which - * registers to save/restore and the default values for them. - */ - -static void -nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx); - -static void -nv50_graph_construct_mmio(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i, j; - int offset, base; - uint32_t units = nv_rd32 (ctx->dev, 0x1540); - - /* 0800: DISPATCH */ - cp_ctx(ctx, 0x400808, 7); - gr_def(ctx, 0x400814, 0x00000030); - cp_ctx(ctx, 0x400834, 0x32); - if (dev_priv->chipset == 0x50) { - gr_def(ctx, 0x400834, 0xff400040); - gr_def(ctx, 0x400838, 0xfff00080); - gr_def(ctx, 0x40083c, 0xfff70090); - gr_def(ctx, 0x400840, 0xffe806a8); - } - gr_def(ctx, 0x400844, 0x00000002); - if (IS_NVA3F(dev_priv->chipset)) - gr_def(ctx, 0x400894, 0x00001000); - gr_def(ctx, 0x4008e8, 0x00000003); - gr_def(ctx, 0x4008ec, 0x00001000); - if (dev_priv->chipset == 0x50) - cp_ctx(ctx, 0x400908, 0xb); - else if (dev_priv->chipset < 0xa0) - cp_ctx(ctx, 0x400908, 0xc); - else - cp_ctx(ctx, 0x400908, 0xe); - - if (dev_priv->chipset >= 0xa0) - cp_ctx(ctx, 0x400b00, 0x1); - if (IS_NVA3F(dev_priv->chipset)) { - cp_ctx(ctx, 0x400b10, 0x1); - gr_def(ctx, 0x400b10, 0x0001629d); - cp_ctx(ctx, 0x400b20, 0x1); - gr_def(ctx, 0x400b20, 0x0001629d); - } - - nv50_graph_construct_mmio_ddata(ctx); - - /* 0C00: VFETCH */ - cp_ctx(ctx, 0x400c08, 0x2); - gr_def(ctx, 0x400c08, 0x0000fe0c); - - /* 1000 */ - if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, 0x401008, 0x4); - gr_def(ctx, 0x401014, 0x00001000); - } else if (!IS_NVA3F(dev_priv->chipset)) { - cp_ctx(ctx, 0x401008, 0x5); - gr_def(ctx, 0x401018, 0x00001000); - } else { - cp_ctx(ctx, 0x401008, 0x5); - gr_def(ctx, 0x401018, 0x00004000); - } - - /* 1400 */ - cp_ctx(ctx, 0x401400, 0x8); - cp_ctx(ctx, 0x401424, 0x3); - if (dev_priv->chipset == 0x50) - gr_def(ctx, 0x40142c, 0x0001fd87); - else - gr_def(ctx, 0x40142c, 0x00000187); - cp_ctx(ctx, 0x401540, 0x5); - gr_def(ctx, 0x401550, 0x00001018); - - /* 1800: STREAMOUT */ - cp_ctx(ctx, 0x401814, 0x1); - gr_def(ctx, 0x401814, 0x000000ff); - if (dev_priv->chipset == 0x50) { - cp_ctx(ctx, 0x40181c, 0xe); - gr_def(ctx, 0x401850, 0x00000004); - } else if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, 0x40181c, 0xf); - gr_def(ctx, 0x401854, 0x00000004); - } else { - cp_ctx(ctx, 0x40181c, 0x13); - gr_def(ctx, 0x401864, 0x00000004); - } - - /* 1C00 */ - cp_ctx(ctx, 0x401c00, 0x1); - switch (dev_priv->chipset) { - case 0x50: - gr_def(ctx, 0x401c00, 0x0001005f); - break; - case 0x84: - case 0x86: - case 0x94: - gr_def(ctx, 0x401c00, 0x044d00df); - break; - case 0x92: - case 0x96: - case 0x98: - case 0xa0: - case 0xaa: - case 0xac: - gr_def(ctx, 0x401c00, 0x042500df); - break; - case 0xa3: - case 0xa5: - case 0xa8: - case 0xaf: - gr_def(ctx, 0x401c00, 0x142500df); - break; - } - - /* 2000 */ - - /* 2400 */ - cp_ctx(ctx, 0x402400, 0x1); - if (dev_priv->chipset == 0x50) - cp_ctx(ctx, 0x402408, 0x1); - else - cp_ctx(ctx, 0x402408, 0x2); - gr_def(ctx, 0x402408, 0x00000600); - - /* 2800: CSCHED */ - cp_ctx(ctx, 0x402800, 0x1); - if (dev_priv->chipset == 0x50) - gr_def(ctx, 0x402800, 0x00000006); - - /* 2C00: ZCULL */ - cp_ctx(ctx, 0x402c08, 0x6); - if (dev_priv->chipset != 0x50) - gr_def(ctx, 0x402c14, 0x01000000); - gr_def(ctx, 0x402c18, 0x000000ff); - if (dev_priv->chipset == 0x50) - cp_ctx(ctx, 0x402ca0, 0x1); - else - cp_ctx(ctx, 0x402ca0, 0x2); - if (dev_priv->chipset < 0xa0) - gr_def(ctx, 0x402ca0, 0x00000400); - else if (!IS_NVA3F(dev_priv->chipset)) - gr_def(ctx, 0x402ca0, 0x00000800); - else - gr_def(ctx, 0x402ca0, 0x00000400); - cp_ctx(ctx, 0x402cac, 0x4); - - /* 3000: ENG2D */ - cp_ctx(ctx, 0x403004, 0x1); - gr_def(ctx, 0x403004, 0x00000001); - - /* 3400 */ - if (dev_priv->chipset >= 0xa0) { - cp_ctx(ctx, 0x403404, 0x1); - gr_def(ctx, 0x403404, 0x00000001); - } - - /* 5000: CCACHE */ - cp_ctx(ctx, 0x405000, 0x1); - switch (dev_priv->chipset) { - case 0x50: - gr_def(ctx, 0x405000, 0x00300080); - break; - case 0x84: - case 0xa0: - case 0xa3: - case 0xa5: - case 0xa8: - case 0xaa: - case 0xac: - case 0xaf: - gr_def(ctx, 0x405000, 0x000e0080); - break; - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0x98: - gr_def(ctx, 0x405000, 0x00000080); - break; - } - cp_ctx(ctx, 0x405014, 0x1); - gr_def(ctx, 0x405014, 0x00000004); - cp_ctx(ctx, 0x40501c, 0x1); - cp_ctx(ctx, 0x405024, 0x1); - cp_ctx(ctx, 0x40502c, 0x1); - - /* 6000? */ - if (dev_priv->chipset == 0x50) - cp_ctx(ctx, 0x4063e0, 0x1); - - /* 6800: M2MF */ - if (dev_priv->chipset < 0x90) { - cp_ctx(ctx, 0x406814, 0x2b); - gr_def(ctx, 0x406818, 0x00000f80); - gr_def(ctx, 0x406860, 0x007f0080); - gr_def(ctx, 0x40689c, 0x007f0080); - } else { - cp_ctx(ctx, 0x406814, 0x4); - if (dev_priv->chipset == 0x98) - gr_def(ctx, 0x406818, 0x00000f80); - else - gr_def(ctx, 0x406818, 0x00001f80); - if (IS_NVA3F(dev_priv->chipset)) - gr_def(ctx, 0x40681c, 0x00000030); - cp_ctx(ctx, 0x406830, 0x3); - } - - /* 7000: per-ROP group state */ - for (i = 0; i < 8; i++) { - if (units & (1<<(i+16))) { - cp_ctx(ctx, 0x407000 + (i<<8), 3); - if (dev_priv->chipset == 0x50) - gr_def(ctx, 0x407000 + (i<<8), 0x1b74f820); - else if (dev_priv->chipset != 0xa5) - gr_def(ctx, 0x407000 + (i<<8), 0x3b74f821); - else - gr_def(ctx, 0x407000 + (i<<8), 0x7b74f821); - gr_def(ctx, 0x407004 + (i<<8), 0x89058001); - - if (dev_priv->chipset == 0x50) { - cp_ctx(ctx, 0x407010 + (i<<8), 1); - } else if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, 0x407010 + (i<<8), 2); - gr_def(ctx, 0x407010 + (i<<8), 0x00001000); - gr_def(ctx, 0x407014 + (i<<8), 0x0000001f); - } else { - cp_ctx(ctx, 0x407010 + (i<<8), 3); - gr_def(ctx, 0x407010 + (i<<8), 0x00001000); - if (dev_priv->chipset != 0xa5) - gr_def(ctx, 0x407014 + (i<<8), 0x000000ff); - else - gr_def(ctx, 0x407014 + (i<<8), 0x000001ff); - } - - cp_ctx(ctx, 0x407080 + (i<<8), 4); - if (dev_priv->chipset != 0xa5) - gr_def(ctx, 0x407080 + (i<<8), 0x027c10fa); - else - gr_def(ctx, 0x407080 + (i<<8), 0x827c10fa); - if (dev_priv->chipset == 0x50) - gr_def(ctx, 0x407084 + (i<<8), 0x000000c0); - else - gr_def(ctx, 0x407084 + (i<<8), 0x400000c0); - gr_def(ctx, 0x407088 + (i<<8), 0xb7892080); - - if (dev_priv->chipset < 0xa0) - cp_ctx(ctx, 0x407094 + (i<<8), 1); - else if (!IS_NVA3F(dev_priv->chipset)) - cp_ctx(ctx, 0x407094 + (i<<8), 3); - else { - cp_ctx(ctx, 0x407094 + (i<<8), 4); - gr_def(ctx, 0x4070a0 + (i<<8), 1); - } - } - } - - cp_ctx(ctx, 0x407c00, 0x3); - if (dev_priv->chipset < 0x90) - gr_def(ctx, 0x407c00, 0x00010040); - else if (dev_priv->chipset < 0xa0) - gr_def(ctx, 0x407c00, 0x00390040); - else - gr_def(ctx, 0x407c00, 0x003d0040); - gr_def(ctx, 0x407c08, 0x00000022); - if (dev_priv->chipset >= 0xa0) { - cp_ctx(ctx, 0x407c10, 0x3); - cp_ctx(ctx, 0x407c20, 0x1); - cp_ctx(ctx, 0x407c2c, 0x1); - } - - if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, 0x407d00, 0x9); - } else { - cp_ctx(ctx, 0x407d00, 0x15); - } - if (dev_priv->chipset == 0x98) - gr_def(ctx, 0x407d08, 0x00380040); - else { - if (dev_priv->chipset < 0x90) - gr_def(ctx, 0x407d08, 0x00010040); - else if (dev_priv->chipset < 0xa0) - gr_def(ctx, 0x407d08, 0x00390040); - else - gr_def(ctx, 0x407d08, 0x003d0040); - gr_def(ctx, 0x407d0c, 0x00000022); - } - - /* 8000+: per-TP state */ - for (i = 0; i < 10; i++) { - if (units & (1<chipset < 0xa0) - base = 0x408000 + (i<<12); - else - base = 0x408000 + (i<<11); - if (dev_priv->chipset < 0xa0) - offset = base + 0xc00; - else - offset = base + 0x80; - cp_ctx(ctx, offset + 0x00, 1); - gr_def(ctx, offset + 0x00, 0x0000ff0a); - cp_ctx(ctx, offset + 0x08, 1); - - /* per-MP state */ - for (j = 0; j < (dev_priv->chipset < 0xa0 ? 2 : 4); j++) { - if (!(units & (1 << (j+24)))) continue; - if (dev_priv->chipset < 0xa0) - offset = base + 0x200 + (j<<7); - else - offset = base + 0x100 + (j<<7); - cp_ctx(ctx, offset, 0x20); - gr_def(ctx, offset + 0x00, 0x01800000); - gr_def(ctx, offset + 0x04, 0x00160000); - gr_def(ctx, offset + 0x08, 0x01800000); - gr_def(ctx, offset + 0x18, 0x0003ffff); - switch (dev_priv->chipset) { - case 0x50: - gr_def(ctx, offset + 0x1c, 0x00080000); - break; - case 0x84: - gr_def(ctx, offset + 0x1c, 0x00880000); - break; - case 0x86: - gr_def(ctx, offset + 0x1c, 0x018c0000); - break; - case 0x92: - case 0x96: - case 0x98: - gr_def(ctx, offset + 0x1c, 0x118c0000); - break; - case 0x94: - gr_def(ctx, offset + 0x1c, 0x10880000); - break; - case 0xa0: - case 0xa5: - gr_def(ctx, offset + 0x1c, 0x310c0000); - break; - case 0xa3: - case 0xa8: - case 0xaa: - case 0xac: - case 0xaf: - gr_def(ctx, offset + 0x1c, 0x300c0000); - break; - } - gr_def(ctx, offset + 0x40, 0x00010401); - if (dev_priv->chipset == 0x50) - gr_def(ctx, offset + 0x48, 0x00000040); - else - gr_def(ctx, offset + 0x48, 0x00000078); - gr_def(ctx, offset + 0x50, 0x000000bf); - gr_def(ctx, offset + 0x58, 0x00001210); - if (dev_priv->chipset == 0x50) - gr_def(ctx, offset + 0x5c, 0x00000080); - else - gr_def(ctx, offset + 0x5c, 0x08000080); - if (dev_priv->chipset >= 0xa0) - gr_def(ctx, offset + 0x68, 0x0000003e); - } - - if (dev_priv->chipset < 0xa0) - cp_ctx(ctx, base + 0x300, 0x4); - else - cp_ctx(ctx, base + 0x300, 0x5); - if (dev_priv->chipset == 0x50) - gr_def(ctx, base + 0x304, 0x00007070); - else if (dev_priv->chipset < 0xa0) - gr_def(ctx, base + 0x304, 0x00027070); - else if (!IS_NVA3F(dev_priv->chipset)) - gr_def(ctx, base + 0x304, 0x01127070); - else - gr_def(ctx, base + 0x304, 0x05127070); - - if (dev_priv->chipset < 0xa0) - cp_ctx(ctx, base + 0x318, 1); - else - cp_ctx(ctx, base + 0x320, 1); - if (dev_priv->chipset == 0x50) - gr_def(ctx, base + 0x318, 0x0003ffff); - else if (dev_priv->chipset < 0xa0) - gr_def(ctx, base + 0x318, 0x03ffffff); - else - gr_def(ctx, base + 0x320, 0x07ffffff); - - if (dev_priv->chipset < 0xa0) - cp_ctx(ctx, base + 0x324, 5); - else - cp_ctx(ctx, base + 0x328, 4); - - if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, base + 0x340, 9); - offset = base + 0x340; - } else if (!IS_NVA3F(dev_priv->chipset)) { - cp_ctx(ctx, base + 0x33c, 0xb); - offset = base + 0x344; - } else { - cp_ctx(ctx, base + 0x33c, 0xd); - offset = base + 0x344; - } - gr_def(ctx, offset + 0x0, 0x00120407); - gr_def(ctx, offset + 0x4, 0x05091507); - if (dev_priv->chipset == 0x84) - gr_def(ctx, offset + 0x8, 0x05100202); - else - gr_def(ctx, offset + 0x8, 0x05010202); - gr_def(ctx, offset + 0xc, 0x00030201); - if (dev_priv->chipset == 0xa3) - cp_ctx(ctx, base + 0x36c, 1); - - cp_ctx(ctx, base + 0x400, 2); - gr_def(ctx, base + 0x404, 0x00000040); - cp_ctx(ctx, base + 0x40c, 2); - gr_def(ctx, base + 0x40c, 0x0d0c0b0a); - gr_def(ctx, base + 0x410, 0x00141210); - - if (dev_priv->chipset < 0xa0) - offset = base + 0x800; - else - offset = base + 0x500; - cp_ctx(ctx, offset, 6); - gr_def(ctx, offset + 0x0, 0x000001f0); - gr_def(ctx, offset + 0x4, 0x00000001); - gr_def(ctx, offset + 0x8, 0x00000003); - if (dev_priv->chipset == 0x50 || IS_NVAAF(dev_priv->chipset)) - gr_def(ctx, offset + 0xc, 0x00008000); - gr_def(ctx, offset + 0x14, 0x00039e00); - cp_ctx(ctx, offset + 0x1c, 2); - if (dev_priv->chipset == 0x50) - gr_def(ctx, offset + 0x1c, 0x00000040); - else - gr_def(ctx, offset + 0x1c, 0x00000100); - gr_def(ctx, offset + 0x20, 0x00003800); - - if (dev_priv->chipset >= 0xa0) { - cp_ctx(ctx, base + 0x54c, 2); - if (!IS_NVA3F(dev_priv->chipset)) - gr_def(ctx, base + 0x54c, 0x003fe006); - else - gr_def(ctx, base + 0x54c, 0x003fe007); - gr_def(ctx, base + 0x550, 0x003fe000); - } - - if (dev_priv->chipset < 0xa0) - offset = base + 0xa00; - else - offset = base + 0x680; - cp_ctx(ctx, offset, 1); - gr_def(ctx, offset, 0x00404040); - - if (dev_priv->chipset < 0xa0) - offset = base + 0xe00; - else - offset = base + 0x700; - cp_ctx(ctx, offset, 2); - if (dev_priv->chipset < 0xa0) - gr_def(ctx, offset, 0x0077f005); - else if (dev_priv->chipset == 0xa5) - gr_def(ctx, offset, 0x6cf7f007); - else if (dev_priv->chipset == 0xa8) - gr_def(ctx, offset, 0x6cfff007); - else if (dev_priv->chipset == 0xac) - gr_def(ctx, offset, 0x0cfff007); - else - gr_def(ctx, offset, 0x0cf7f007); - if (dev_priv->chipset == 0x50) - gr_def(ctx, offset + 0x4, 0x00007fff); - else if (dev_priv->chipset < 0xa0) - gr_def(ctx, offset + 0x4, 0x003f7fff); - else - gr_def(ctx, offset + 0x4, 0x02bf7fff); - cp_ctx(ctx, offset + 0x2c, 1); - if (dev_priv->chipset == 0x50) { - cp_ctx(ctx, offset + 0x50, 9); - gr_def(ctx, offset + 0x54, 0x000003ff); - gr_def(ctx, offset + 0x58, 0x00000003); - gr_def(ctx, offset + 0x5c, 0x00000003); - gr_def(ctx, offset + 0x60, 0x000001ff); - gr_def(ctx, offset + 0x64, 0x0000001f); - gr_def(ctx, offset + 0x68, 0x0000000f); - gr_def(ctx, offset + 0x6c, 0x0000000f); - } else if (dev_priv->chipset < 0xa0) { - cp_ctx(ctx, offset + 0x50, 1); - cp_ctx(ctx, offset + 0x70, 1); - } else { - cp_ctx(ctx, offset + 0x50, 1); - cp_ctx(ctx, offset + 0x60, 5); - } - } - } -} - -static void -dd_emit(struct nouveau_grctx *ctx, int num, uint32_t val) { - int i; - if (val && ctx->mode == NOUVEAU_GRCTX_VALS) - for (i = 0; i < num; i++) - nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + i), val); - ctx->ctxvals_pos += num; -} - -static void -nv50_graph_construct_mmio_ddata(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int base, num; - base = ctx->ctxvals_pos; - - /* tesla state */ - dd_emit(ctx, 1, 0); /* 00000001 UNK0F90 */ - dd_emit(ctx, 1, 0); /* 00000001 UNK135C */ - - /* SRC_TIC state */ - dd_emit(ctx, 1, 0); /* 00000007 SRC_TILE_MODE_Z */ - dd_emit(ctx, 1, 2); /* 00000007 SRC_TILE_MODE_Y */ - dd_emit(ctx, 1, 1); /* 00000001 SRC_LINEAR #1 */ - dd_emit(ctx, 1, 0); /* 000000ff SRC_ADDRESS_HIGH */ - dd_emit(ctx, 1, 0); /* 00000001 SRC_SRGB */ - if (dev_priv->chipset >= 0x94) - dd_emit(ctx, 1, 0); /* 00000003 eng2d UNK0258 */ - dd_emit(ctx, 1, 1); /* 00000fff SRC_DEPTH */ - dd_emit(ctx, 1, 0x100); /* 0000ffff SRC_HEIGHT */ - - /* turing state */ - dd_emit(ctx, 1, 0); /* 0000000f TEXTURES_LOG2 */ - dd_emit(ctx, 1, 0); /* 0000000f SAMPLERS_LOG2 */ - dd_emit(ctx, 1, 0); /* 000000ff CB_DEF_ADDRESS_HIGH */ - dd_emit(ctx, 1, 0); /* ffffffff CB_DEF_ADDRESS_LOW */ - dd_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */ - dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */ - dd_emit(ctx, 1, 1); /* 0000ffff BLOCK_ALLOC_THREADS */ - dd_emit(ctx, 1, 1); /* 00000001 LANES32 */ - dd_emit(ctx, 1, 0); /* 000000ff UNK370 */ - dd_emit(ctx, 1, 0); /* 000000ff USER_PARAM_UNK */ - dd_emit(ctx, 1, 0); /* 000000ff USER_PARAM_COUNT */ - dd_emit(ctx, 1, 1); /* 000000ff UNK384 bits 8-15 */ - dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ - dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ - dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */ - dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_X */ - dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_XMY */ - dd_emit(ctx, 1, 0); /* 00000001 BLOCKDIM_XMY_OVERFLOW */ - dd_emit(ctx, 1, 1); /* 0003ffff BLOCKDIM_XMYMZ */ - dd_emit(ctx, 1, 1); /* 000007ff BLOCKDIM_Y */ - dd_emit(ctx, 1, 1); /* 0000007f BLOCKDIM_Z */ - dd_emit(ctx, 1, 4); /* 000000ff CP_REG_ALLOC_TEMP */ - dd_emit(ctx, 1, 1); /* 00000001 BLOCKDIM_DIRTY */ - if (IS_NVA3F(dev_priv->chipset)) - dd_emit(ctx, 1, 0); /* 00000003 UNK03E8 */ - dd_emit(ctx, 1, 1); /* 0000007f BLOCK_ALLOC_HALFWARPS */ - dd_emit(ctx, 1, 1); /* 00000007 LOCAL_WARPS_NO_CLAMP */ - dd_emit(ctx, 1, 7); /* 00000007 LOCAL_WARPS_LOG_ALLOC */ - dd_emit(ctx, 1, 1); /* 00000007 STACK_WARPS_NO_CLAMP */ - dd_emit(ctx, 1, 7); /* 00000007 STACK_WARPS_LOG_ALLOC */ - dd_emit(ctx, 1, 1); /* 00001fff BLOCK_ALLOC_REGSLOTS_PACKED */ - dd_emit(ctx, 1, 1); /* 00001fff BLOCK_ALLOC_REGSLOTS_STRIDED */ - dd_emit(ctx, 1, 1); /* 000007ff BLOCK_ALLOC_THREADS */ - - /* compat 2d state */ - if (dev_priv->chipset == 0x50) { - dd_emit(ctx, 4, 0); /* 0000ffff clip X, Y, W, H */ - - dd_emit(ctx, 1, 1); /* ffffffff chroma COLOR_FORMAT */ - - dd_emit(ctx, 1, 1); /* ffffffff pattern COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff pattern SHAPE */ - dd_emit(ctx, 1, 1); /* ffffffff pattern PATTERN_SELECT */ - - dd_emit(ctx, 1, 0xa); /* ffffffff surf2d SRC_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff surf2d DMA_SRC */ - dd_emit(ctx, 1, 0); /* 000000ff surf2d SRC_ADDRESS_HIGH */ - dd_emit(ctx, 1, 0); /* ffffffff surf2d SRC_ADDRESS_LOW */ - dd_emit(ctx, 1, 0x40); /* 0000ffff surf2d SRC_PITCH */ - dd_emit(ctx, 1, 0); /* 0000000f surf2d SRC_TILE_MODE_Z */ - dd_emit(ctx, 1, 2); /* 0000000f surf2d SRC_TILE_MODE_Y */ - dd_emit(ctx, 1, 0x100); /* ffffffff surf2d SRC_HEIGHT */ - dd_emit(ctx, 1, 1); /* 00000001 surf2d SRC_LINEAR */ - dd_emit(ctx, 1, 0x100); /* ffffffff surf2d SRC_WIDTH */ - - dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_B_X */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_B_Y */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_C_X */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_C_Y */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_D_X */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect CLIP_D_Y */ - dd_emit(ctx, 1, 1); /* ffffffff gdirect COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff gdirect OPERATION */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect POINT_X */ - dd_emit(ctx, 1, 0); /* 0000ffff gdirect POINT_Y */ - - dd_emit(ctx, 1, 0); /* 0000ffff blit SRC_Y */ - dd_emit(ctx, 1, 0); /* ffffffff blit OPERATION */ - - dd_emit(ctx, 1, 0); /* ffffffff ifc OPERATION */ - - dd_emit(ctx, 1, 0); /* ffffffff iifc INDEX_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff iifc LUT_OFFSET */ - dd_emit(ctx, 1, 4); /* ffffffff iifc COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff iifc OPERATION */ - } - - /* m2mf state */ - dd_emit(ctx, 1, 0); /* ffffffff m2mf LINE_COUNT */ - dd_emit(ctx, 1, 0); /* ffffffff m2mf LINE_LENGTH_IN */ - dd_emit(ctx, 2, 0); /* ffffffff m2mf OFFSET_IN, OFFSET_OUT */ - dd_emit(ctx, 1, 1); /* ffffffff m2mf TILING_DEPTH_OUT */ - dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_HEIGHT_OUT */ - dd_emit(ctx, 1, 0); /* ffffffff m2mf TILING_POSITION_OUT_Z */ - dd_emit(ctx, 1, 1); /* 00000001 m2mf LINEAR_OUT */ - dd_emit(ctx, 2, 0); /* 0000ffff m2mf TILING_POSITION_OUT_X, Y */ - dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_OUT */ - dd_emit(ctx, 1, 1); /* ffffffff m2mf TILING_DEPTH_IN */ - dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_HEIGHT_IN */ - dd_emit(ctx, 1, 0); /* ffffffff m2mf TILING_POSITION_IN_Z */ - dd_emit(ctx, 1, 1); /* 00000001 m2mf LINEAR_IN */ - dd_emit(ctx, 2, 0); /* 0000ffff m2mf TILING_POSITION_IN_X, Y */ - dd_emit(ctx, 1, 0x100); /* ffffffff m2mf TILING_PITCH_IN */ - - /* more compat 2d state */ - if (dev_priv->chipset == 0x50) { - dd_emit(ctx, 1, 1); /* ffffffff line COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff line OPERATION */ - - dd_emit(ctx, 1, 1); /* ffffffff triangle COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff triangle OPERATION */ - - dd_emit(ctx, 1, 0); /* 0000000f sifm TILE_MODE_Z */ - dd_emit(ctx, 1, 2); /* 0000000f sifm TILE_MODE_Y */ - dd_emit(ctx, 1, 0); /* 000000ff sifm FORMAT_FILTER */ - dd_emit(ctx, 1, 1); /* 000000ff sifm FORMAT_ORIGIN */ - dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_PITCH */ - dd_emit(ctx, 1, 1); /* 00000001 sifm SRC_LINEAR */ - dd_emit(ctx, 1, 0); /* 000000ff sifm SRC_OFFSET_HIGH */ - dd_emit(ctx, 1, 0); /* ffffffff sifm SRC_OFFSET */ - dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_HEIGHT */ - dd_emit(ctx, 1, 0); /* 0000ffff sifm SRC_WIDTH */ - dd_emit(ctx, 1, 3); /* ffffffff sifm COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff sifm OPERATION */ - - dd_emit(ctx, 1, 0); /* ffffffff sifc OPERATION */ - } - - /* tesla state */ - dd_emit(ctx, 1, 0); /* 0000000f GP_TEXTURES_LOG2 */ - dd_emit(ctx, 1, 0); /* 0000000f GP_SAMPLERS_LOG2 */ - dd_emit(ctx, 1, 0); /* 000000ff */ - dd_emit(ctx, 1, 0); /* ffffffff */ - dd_emit(ctx, 1, 4); /* 000000ff UNK12B0_0 */ - dd_emit(ctx, 1, 0x70); /* 000000ff UNK12B0_1 */ - dd_emit(ctx, 1, 0x80); /* 000000ff UNK12B0_3 */ - dd_emit(ctx, 1, 0); /* 000000ff UNK12B0_2 */ - dd_emit(ctx, 1, 0); /* 0000000f FP_TEXTURES_LOG2 */ - dd_emit(ctx, 1, 0); /* 0000000f FP_SAMPLERS_LOG2 */ - if (IS_NVA3F(dev_priv->chipset)) { - dd_emit(ctx, 1, 0); /* ffffffff */ - dd_emit(ctx, 1, 0); /* 0000007f MULTISAMPLE_SAMPLES_LOG2 */ - } else { - dd_emit(ctx, 1, 0); /* 0000000f MULTISAMPLE_SAMPLES_LOG2 */ - } - dd_emit(ctx, 1, 0xc); /* 000000ff SEMANTIC_COLOR.BFC0_ID */ - if (dev_priv->chipset != 0x50) - dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_COLOR.CLMP_EN */ - dd_emit(ctx, 1, 8); /* 000000ff SEMANTIC_COLOR.COLR_NR */ - dd_emit(ctx, 1, 0x14); /* 000000ff SEMANTIC_COLOR.FFC0_ID */ - if (dev_priv->chipset == 0x50) { - dd_emit(ctx, 1, 0); /* 000000ff SEMANTIC_LAYER */ - dd_emit(ctx, 1, 0); /* 00000001 */ - } else { - dd_emit(ctx, 1, 0); /* 00000001 SEMANTIC_PTSZ.ENABLE */ - dd_emit(ctx, 1, 0x29); /* 000000ff SEMANTIC_PTSZ.PTSZ_ID */ - dd_emit(ctx, 1, 0x27); /* 000000ff SEMANTIC_PRIM */ - dd_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ - dd_emit(ctx, 1, 8); /* 0000000f SMENATIC_CLIP.CLIP_HIGH */ - dd_emit(ctx, 1, 4); /* 000000ff SEMANTIC_CLIP.CLIP_LO */ - dd_emit(ctx, 1, 0x27); /* 000000ff UNK0FD4 */ - dd_emit(ctx, 1, 0); /* 00000001 UNK1900 */ - } - dd_emit(ctx, 1, 0); /* 00000007 RT_CONTROL_MAP0 */ - dd_emit(ctx, 1, 1); /* 00000007 RT_CONTROL_MAP1 */ - dd_emit(ctx, 1, 2); /* 00000007 RT_CONTROL_MAP2 */ - dd_emit(ctx, 1, 3); /* 00000007 RT_CONTROL_MAP3 */ - dd_emit(ctx, 1, 4); /* 00000007 RT_CONTROL_MAP4 */ - dd_emit(ctx, 1, 5); /* 00000007 RT_CONTROL_MAP5 */ - dd_emit(ctx, 1, 6); /* 00000007 RT_CONTROL_MAP6 */ - dd_emit(ctx, 1, 7); /* 00000007 RT_CONTROL_MAP7 */ - dd_emit(ctx, 1, 1); /* 0000000f RT_CONTROL_COUNT */ - dd_emit(ctx, 8, 0); /* 00000001 RT_HORIZ_UNK */ - dd_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */ - dd_emit(ctx, 1, 0xcf); /* 000000ff RT_FORMAT */ - dd_emit(ctx, 7, 0); /* 000000ff RT_FORMAT */ - if (dev_priv->chipset != 0x50) - dd_emit(ctx, 3, 0); /* 1, 1, 1 */ - else - dd_emit(ctx, 2, 0); /* 1, 1 */ - dd_emit(ctx, 1, 0); /* ffffffff GP_ENABLE */ - dd_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT*/ - dd_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ - dd_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - if (IS_NVA3F(dev_priv->chipset)) { - dd_emit(ctx, 1, 3); /* 00000003 */ - dd_emit(ctx, 1, 0); /* 00000001 UNK1418. Alone. */ - } - if (dev_priv->chipset != 0x50) - dd_emit(ctx, 1, 3); /* 00000003 UNK15AC */ - dd_emit(ctx, 1, 1); /* ffffffff RASTERIZE_ENABLE */ - dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.EXPORTS_Z */ - if (dev_priv->chipset != 0x50) - dd_emit(ctx, 1, 0); /* 00000001 FP_CONTROL.MULTIPLE_RESULTS */ - dd_emit(ctx, 1, 0x12); /* 000000ff FP_INTERPOLANT_CTRL.COUNT */ - dd_emit(ctx, 1, 0x10); /* 000000ff FP_INTERPOLANT_CTRL.COUNT_NONFLAT */ - dd_emit(ctx, 1, 0xc); /* 000000ff FP_INTERPOLANT_CTRL.OFFSET */ - dd_emit(ctx, 1, 1); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.W */ - dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.X */ - dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.Y */ - dd_emit(ctx, 1, 0); /* 00000001 FP_INTERPOLANT_CTRL.UMASK.Z */ - dd_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */ - dd_emit(ctx, 1, 2); /* ffffffff REG_MODE */ - dd_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ - if (dev_priv->chipset >= 0xa0) - dd_emit(ctx, 1, 0); /* ffffffff */ - dd_emit(ctx, 1, 0); /* 00000001 GP_BUILTIN_RESULT_EN.LAYER_IDX */ - dd_emit(ctx, 1, 0); /* ffffffff STRMOUT_ENABLE */ - dd_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ - dd_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ - dd_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE*/ - if (dev_priv->chipset != 0x50) - dd_emit(ctx, 8, 0); /* 00000001 */ - if (dev_priv->chipset >= 0xa0) { - dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.COMP */ - dd_emit(ctx, 1, 1); /* 00000007 VTX_ATTR_DEFINE.SIZE */ - dd_emit(ctx, 1, 2); /* 00000007 VTX_ATTR_DEFINE.TYPE */ - dd_emit(ctx, 1, 0); /* 000000ff VTX_ATTR_DEFINE.ATTR */ - } - dd_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - dd_emit(ctx, 1, 0x14); /* 0000001f ZETA_FORMAT */ - dd_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - dd_emit(ctx, 1, 0); /* 0000000f VP_TEXTURES_LOG2 */ - dd_emit(ctx, 1, 0); /* 0000000f VP_SAMPLERS_LOG2 */ - if (IS_NVA3F(dev_priv->chipset)) - dd_emit(ctx, 1, 0); /* 00000001 */ - dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_BACK */ - if (dev_priv->chipset >= 0xa0) - dd_emit(ctx, 1, 0); /* 00000003 VTX_ATTR_DEFINE.SIZE - 1 */ - dd_emit(ctx, 1, 0); /* 0000ffff CB_ADDR_INDEX */ - if (dev_priv->chipset >= 0xa0) - dd_emit(ctx, 1, 0); /* 00000003 */ - dd_emit(ctx, 1, 0); /* 00000001 CULL_FACE_ENABLE */ - dd_emit(ctx, 1, 1); /* 00000003 CULL_FACE */ - dd_emit(ctx, 1, 0); /* 00000001 FRONT_FACE */ - dd_emit(ctx, 1, 2); /* 00000003 POLYGON_MODE_FRONT */ - dd_emit(ctx, 1, 0x1000); /* 00007fff UNK141C */ - if (dev_priv->chipset != 0x50) { - dd_emit(ctx, 1, 0xe00); /* 7fff */ - dd_emit(ctx, 1, 0x1000); /* 7fff */ - dd_emit(ctx, 1, 0x1e00); /* 7fff */ - } - dd_emit(ctx, 1, 0); /* 00000001 BEGIN_END_ACTIVE */ - dd_emit(ctx, 1, 1); /* 00000001 POLYGON_MODE_??? */ - dd_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP / 4 rounded up */ - dd_emit(ctx, 1, 1); /* 000000ff FP_REG_ALLOC_TEMP... without /4? */ - dd_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP / 4 rounded up */ - dd_emit(ctx, 1, 1); /* 00000001 */ - dd_emit(ctx, 1, 0); /* 00000001 */ - dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK0 nonempty */ - dd_emit(ctx, 1, 0); /* 00000001 VTX_ATTR_MASK_UNK1 nonempty */ - dd_emit(ctx, 1, 0x200); /* 0003ffff GP_VERTEX_OUTPUT_COUNT*GP_REG_ALLOC_RESULT */ - if (IS_NVA3F(dev_priv->chipset)) - dd_emit(ctx, 1, 0x200); - dd_emit(ctx, 1, 0); /* 00000001 */ - if (dev_priv->chipset < 0xa0) { - dd_emit(ctx, 1, 1); /* 00000001 */ - dd_emit(ctx, 1, 0x70); /* 000000ff */ - dd_emit(ctx, 1, 0x80); /* 000000ff */ - dd_emit(ctx, 1, 0); /* 000000ff */ - dd_emit(ctx, 1, 0); /* 00000001 */ - dd_emit(ctx, 1, 1); /* 00000001 */ - dd_emit(ctx, 1, 0x70); /* 000000ff */ - dd_emit(ctx, 1, 0x80); /* 000000ff */ - dd_emit(ctx, 1, 0); /* 000000ff */ - } else { - dd_emit(ctx, 1, 1); /* 00000001 */ - dd_emit(ctx, 1, 0xf0); /* 000000ff */ - dd_emit(ctx, 1, 0xff); /* 000000ff */ - dd_emit(ctx, 1, 0); /* 000000ff */ - dd_emit(ctx, 1, 0); /* 00000001 */ - dd_emit(ctx, 1, 1); /* 00000001 */ - dd_emit(ctx, 1, 0xf0); /* 000000ff */ - dd_emit(ctx, 1, 0xff); /* 000000ff */ - dd_emit(ctx, 1, 0); /* 000000ff */ - dd_emit(ctx, 1, 9); /* 0000003f UNK114C.COMP,SIZE */ - } - - /* eng2d state */ - dd_emit(ctx, 1, 0); /* 00000001 eng2d COLOR_KEY_ENABLE */ - dd_emit(ctx, 1, 0); /* 00000007 eng2d COLOR_KEY_FORMAT */ - dd_emit(ctx, 1, 1); /* ffffffff eng2d DST_DEPTH */ - dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d DST_FORMAT */ - dd_emit(ctx, 1, 0); /* ffffffff eng2d DST_LAYER */ - dd_emit(ctx, 1, 1); /* 00000001 eng2d DST_LINEAR */ - dd_emit(ctx, 1, 0); /* 00000007 eng2d PATTERN_COLOR_FORMAT */ - dd_emit(ctx, 1, 0); /* 00000007 eng2d OPERATION */ - dd_emit(ctx, 1, 0); /* 00000003 eng2d PATTERN_SELECT */ - dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d SIFC_FORMAT */ - dd_emit(ctx, 1, 0); /* 00000001 eng2d SIFC_BITMAP_ENABLE */ - dd_emit(ctx, 1, 2); /* 00000003 eng2d SIFC_BITMAP_UNK808 */ - dd_emit(ctx, 1, 0); /* ffffffff eng2d BLIT_DU_DX_FRACT */ - dd_emit(ctx, 1, 1); /* ffffffff eng2d BLIT_DU_DX_INT */ - dd_emit(ctx, 1, 0); /* ffffffff eng2d BLIT_DV_DY_FRACT */ - dd_emit(ctx, 1, 1); /* ffffffff eng2d BLIT_DV_DY_INT */ - dd_emit(ctx, 1, 0); /* 00000001 eng2d BLIT_CONTROL_FILTER */ - dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d DRAW_COLOR_FORMAT */ - dd_emit(ctx, 1, 0xcf); /* 000000ff eng2d SRC_FORMAT */ - dd_emit(ctx, 1, 1); /* 00000001 eng2d SRC_LINEAR #2 */ - - num = ctx->ctxvals_pos - base; - ctx->ctxvals_pos = base; - if (IS_NVA3F(dev_priv->chipset)) - cp_ctx(ctx, 0x404800, num); - else - cp_ctx(ctx, 0x405400, num); -} - -/* - * xfer areas. These are a pain. - * - * There are 2 xfer areas: the first one is big and contains all sorts of - * stuff, the second is small and contains some per-TP context. - * - * Each area is split into 8 "strands". The areas, when saved to grctx, - * are made of 8-word blocks. Each block contains a single word from - * each strand. The strands are independent of each other, their - * addresses are unrelated to each other, and data in them is closely - * packed together. The strand layout varies a bit between cards: here - * and there, a single word is thrown out in the middle and the whole - * strand is offset by a bit from corresponding one on another chipset. - * For this reason, addresses of stuff in strands are almost useless. - * Knowing sequence of stuff and size of gaps between them is much more - * useful, and that's how we build the strands in our generator. - * - * NVA0 takes this mess to a whole new level by cutting the old strands - * into a few dozen pieces [known as genes], rearranging them randomly, - * and putting them back together to make new strands. Hopefully these - * genes correspond more or less directly to the same PGRAPH subunits - * as in 400040 register. - * - * The most common value in default context is 0, and when the genes - * are separated by 0's, gene bounduaries are quite speculative... - * some of them can be clearly deduced, others can be guessed, and yet - * others won't be resolved without figuring out the real meaning of - * given ctxval. For the same reason, ending point of each strand - * is unknown. Except for strand 0, which is the longest strand and - * its end corresponds to end of the whole xfer. - * - * An unsolved mystery is the seek instruction: it takes an argument - * in bits 8-18, and that argument is clearly the place in strands to - * seek to... but the offsets don't seem to correspond to offsets as - * seen in grctx. Perhaps there's another, real, not randomly-changing - * addressing in strands, and the xfer insn just happens to skip over - * the unused bits? NV10-NV30 PIPE comes to mind... - * - * As far as I know, there's no way to access the xfer areas directly - * without the help of ctxprog. - */ - -static void -xf_emit(struct nouveau_grctx *ctx, int num, uint32_t val) { - int i; - if (val && ctx->mode == NOUVEAU_GRCTX_VALS) - for (i = 0; i < num; i++) - nv_wo32(ctx->data, 4 * (ctx->ctxvals_pos + (i << 3)), val); - ctx->ctxvals_pos += num << 3; -} - -/* Gene declarations... */ - -static void nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx); -static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx); -static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx); - -static void -nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - int offset; - int size = 0; - uint32_t units = nv_rd32 (ctx->dev, 0x1540); - - offset = (ctx->ctxvals_pos+0x3f)&~0x3f; - ctx->ctxvals_base = offset; - - if (dev_priv->chipset < 0xa0) { - /* Strand 0 */ - ctx->ctxvals_pos = offset; - nv50_graph_construct_gene_dispatch(ctx); - nv50_graph_construct_gene_m2mf(ctx); - nv50_graph_construct_gene_unk24xx(ctx); - nv50_graph_construct_gene_clipid(ctx); - nv50_graph_construct_gene_zcull(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 1 */ - ctx->ctxvals_pos = offset + 0x1; - nv50_graph_construct_gene_vfetch(ctx); - nv50_graph_construct_gene_eng2d(ctx); - nv50_graph_construct_gene_csched(ctx); - nv50_graph_construct_gene_ropm1(ctx); - nv50_graph_construct_gene_ropm2(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 2 */ - ctx->ctxvals_pos = offset + 0x2; - nv50_graph_construct_gene_ccache(ctx); - nv50_graph_construct_gene_unk1cxx(ctx); - nv50_graph_construct_gene_strmout(ctx); - nv50_graph_construct_gene_unk14xx(ctx); - nv50_graph_construct_gene_unk10xx(ctx); - nv50_graph_construct_gene_unk34xx(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 3: per-ROP group state */ - ctx->ctxvals_pos = offset + 3; - for (i = 0; i < 6; i++) - if (units & (1 << (i + 16))) - nv50_graph_construct_gene_ropc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strands 4-7: per-TP state */ - for (i = 0; i < 4; i++) { - ctx->ctxvals_pos = offset + 4 + i; - if (units & (1 << (2 * i))) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << (2 * i + 1))) - nv50_graph_construct_xfer_tp(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - } - } else { - /* Strand 0 */ - ctx->ctxvals_pos = offset; - nv50_graph_construct_gene_dispatch(ctx); - nv50_graph_construct_gene_m2mf(ctx); - nv50_graph_construct_gene_unk34xx(ctx); - nv50_graph_construct_gene_csched(ctx); - nv50_graph_construct_gene_unk1cxx(ctx); - nv50_graph_construct_gene_strmout(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 1 */ - ctx->ctxvals_pos = offset + 1; - nv50_graph_construct_gene_unk10xx(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 2 */ - ctx->ctxvals_pos = offset + 2; - if (dev_priv->chipset == 0xa0) - nv50_graph_construct_gene_unk14xx(ctx); - nv50_graph_construct_gene_unk24xx(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 3 */ - ctx->ctxvals_pos = offset + 3; - nv50_graph_construct_gene_vfetch(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 4 */ - ctx->ctxvals_pos = offset + 4; - nv50_graph_construct_gene_ccache(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 5 */ - ctx->ctxvals_pos = offset + 5; - nv50_graph_construct_gene_ropm2(ctx); - nv50_graph_construct_gene_ropm1(ctx); - /* per-ROP context */ - for (i = 0; i < 8; i++) - if (units & (1<<(i+16))) - nv50_graph_construct_gene_ropc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 6 */ - ctx->ctxvals_pos = offset + 6; - nv50_graph_construct_gene_zcull(ctx); - nv50_graph_construct_gene_clipid(ctx); - nv50_graph_construct_gene_eng2d(ctx); - if (units & (1 << 0)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 1)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 2)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 3)) - nv50_graph_construct_xfer_tp(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 7 */ - ctx->ctxvals_pos = offset + 7; - if (dev_priv->chipset == 0xa0) { - if (units & (1 << 4)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 5)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 6)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 7)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 8)) - nv50_graph_construct_xfer_tp(ctx); - if (units & (1 << 9)) - nv50_graph_construct_xfer_tp(ctx); - } else { - nv50_graph_construct_gene_unk14xx(ctx); - } - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - } - - ctx->ctxvals_pos = offset + size * 8; - ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f; - cp_lsr (ctx, offset); - cp_out (ctx, CP_SET_XFER_POINTER); - cp_lsr (ctx, size); - cp_out (ctx, CP_SEEK_1); - cp_out (ctx, CP_XFER_1); - cp_wait(ctx, XFER, BUSY); -} - -/* - * non-trivial demagiced parts of ctx init go here - */ - -static void -nv50_graph_construct_gene_dispatch(struct nouveau_grctx *ctx) -{ - /* start of strand 0 */ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* SEEK */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 5, 0); - else if (!IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 6, 0); - else - xf_emit(ctx, 4, 0); - /* SEEK */ - /* the PGRAPH's internal FIFO */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 8*3, 0); - else - xf_emit(ctx, 0x100*3, 0); - /* and another bonus slot?!? */ - xf_emit(ctx, 3, 0); - /* and YET ANOTHER bonus slot? */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 3, 0); - /* SEEK */ - /* CTX_SWITCH: caches of gr objects bound to subchannels. 8 values, last used index */ - xf_emit(ctx, 9, 0); - /* SEEK */ - xf_emit(ctx, 9, 0); - /* SEEK */ - xf_emit(ctx, 9, 0); - /* SEEK */ - xf_emit(ctx, 9, 0); - /* SEEK */ - if (dev_priv->chipset < 0x90) - xf_emit(ctx, 4, 0); - /* SEEK */ - xf_emit(ctx, 2, 0); - /* SEEK */ - xf_emit(ctx, 6*2, 0); - xf_emit(ctx, 2, 0); - /* SEEK */ - xf_emit(ctx, 2, 0); - /* SEEK */ - xf_emit(ctx, 6*2, 0); - xf_emit(ctx, 2, 0); - /* SEEK */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 0x1c, 0); - else if (dev_priv->chipset < 0xa0) - xf_emit(ctx, 0x1e, 0); - else - xf_emit(ctx, 0x22, 0); - /* SEEK */ - xf_emit(ctx, 0x15, 0); -} - -static void -nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx) -{ - /* Strand 0, right after dispatch */ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int smallm2mf = 0; - if (dev_priv->chipset < 0x92 || dev_priv->chipset == 0x98) - smallm2mf = 1; - /* SEEK */ - xf_emit (ctx, 1, 0); /* DMA_NOTIFY instance >> 4 */ - xf_emit (ctx, 1, 0); /* DMA_BUFFER_IN instance >> 4 */ - xf_emit (ctx, 1, 0); /* DMA_BUFFER_OUT instance >> 4 */ - xf_emit (ctx, 1, 0); /* OFFSET_IN */ - xf_emit (ctx, 1, 0); /* OFFSET_OUT */ - xf_emit (ctx, 1, 0); /* PITCH_IN */ - xf_emit (ctx, 1, 0); /* PITCH_OUT */ - xf_emit (ctx, 1, 0); /* LINE_LENGTH */ - xf_emit (ctx, 1, 0); /* LINE_COUNT */ - xf_emit (ctx, 1, 0x21); /* FORMAT: bits 0-4 INPUT_INC, bits 5-9 OUTPUT_INC */ - xf_emit (ctx, 1, 1); /* LINEAR_IN */ - xf_emit (ctx, 1, 0x2); /* TILING_MODE_IN: bits 0-2 y tiling, bits 3-5 z tiling */ - xf_emit (ctx, 1, 0x100); /* TILING_PITCH_IN */ - xf_emit (ctx, 1, 0x100); /* TILING_HEIGHT_IN */ - xf_emit (ctx, 1, 1); /* TILING_DEPTH_IN */ - xf_emit (ctx, 1, 0); /* TILING_POSITION_IN_Z */ - xf_emit (ctx, 1, 0); /* TILING_POSITION_IN */ - xf_emit (ctx, 1, 1); /* LINEAR_OUT */ - xf_emit (ctx, 1, 0x2); /* TILING_MODE_OUT: bits 0-2 y tiling, bits 3-5 z tiling */ - xf_emit (ctx, 1, 0x100); /* TILING_PITCH_OUT */ - xf_emit (ctx, 1, 0x100); /* TILING_HEIGHT_OUT */ - xf_emit (ctx, 1, 1); /* TILING_DEPTH_OUT */ - xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT_Z */ - xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT */ - xf_emit (ctx, 1, 0); /* OFFSET_IN_HIGH */ - xf_emit (ctx, 1, 0); /* OFFSET_OUT_HIGH */ - /* SEEK */ - if (smallm2mf) - xf_emit(ctx, 0x40, 0); /* 20 * ffffffff, 3ffff */ - else - xf_emit(ctx, 0x100, 0); /* 80 * ffffffff, 3ffff */ - xf_emit(ctx, 4, 0); /* 1f/7f, 0, 1f/7f, 0 [1f for smallm2mf, 7f otherwise] */ - /* SEEK */ - if (smallm2mf) - xf_emit(ctx, 0x400, 0); /* ffffffff */ - else - xf_emit(ctx, 0x800, 0); /* ffffffff */ - xf_emit(ctx, 4, 0); /* ff/1ff, 0, 0, 0 [ff for smallm2mf, 1ff otherwise] */ - /* SEEK */ - xf_emit(ctx, 0x40, 0); /* 20 * bits ffffffff, 3ffff */ - xf_emit(ctx, 0x6, 0); /* 1f, 0, 1f, 0, 1f, 0 */ -} - -static void -nv50_graph_construct_gene_ccache(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - xf_emit(ctx, 2, 0); /* RO */ - xf_emit(ctx, 0x800, 0); /* ffffffff */ - switch (dev_priv->chipset) { - case 0x50: - case 0x92: - case 0xa0: - xf_emit(ctx, 0x2b, 0); - break; - case 0x84: - xf_emit(ctx, 0x29, 0); - break; - case 0x94: - case 0x96: - case 0xa3: - xf_emit(ctx, 0x27, 0); - break; - case 0x86: - case 0x98: - case 0xa5: - case 0xa8: - case 0xaa: - case 0xac: - case 0xaf: - xf_emit(ctx, 0x25, 0); - break; - } - /* CB bindings, 0x80 of them. first word is address >> 8, second is - * size >> 4 | valid << 24 */ - xf_emit(ctx, 0x100, 0); /* ffffffff CB_DEF */ - xf_emit(ctx, 1, 0); /* 0000007f CB_ADDR_BUFFER */ - xf_emit(ctx, 1, 0); /* 0 */ - xf_emit(ctx, 0x30, 0); /* ff SET_PROGRAM_CB */ - xf_emit(ctx, 1, 0); /* 3f last SET_PROGRAM_CB */ - xf_emit(ctx, 4, 0); /* RO */ - xf_emit(ctx, 0x100, 0); /* ffffffff */ - xf_emit(ctx, 8, 0); /* 1f, 0, 0, ... */ - xf_emit(ctx, 8, 0); /* ffffffff */ - xf_emit(ctx, 4, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 3 */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_CODE_CB */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_TIC */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_TSC */ - xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */ - xf_emit(ctx, 1, 0); /* 000000ff TIC_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff TIC_ADDRESS_LOW */ - xf_emit(ctx, 1, 0x3fffff); /* 003fffff TIC_LIMIT */ - xf_emit(ctx, 1, 0); /* 000000ff TSC_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff TSC_ADDRESS_LOW */ - xf_emit(ctx, 1, 0x1fff); /* 000fffff TSC_LIMIT */ - xf_emit(ctx, 1, 0); /* 000000ff VP_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff VP_ADDRESS_LOW */ - xf_emit(ctx, 1, 0); /* 00ffffff VP_START_ID */ - xf_emit(ctx, 1, 0); /* 000000ff CB_DEF_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff CB_DEF_ADDRESS_LOW */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0); /* 000000ff GP_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff GP_ADDRESS_LOW */ - xf_emit(ctx, 1, 0); /* 00ffffff GP_START_ID */ - xf_emit(ctx, 1, 0); /* 000000ff FP_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff FP_ADDRESS_LOW */ - xf_emit(ctx, 1, 0); /* 00ffffff FP_START_ID */ -} - -static void -nv50_graph_construct_gene_unk10xx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - /* end of area 2 on pre-NVA0, area 1 on NVAx */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ - xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0x3ff); - else - xf_emit(ctx, 1, 0x7ff); /* 000007ff */ - xf_emit(ctx, 1, 0); /* 111/113 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - for (i = 0; i < 8; i++) { - switch (dev_priv->chipset) { - case 0x50: - case 0x86: - case 0x98: - case 0xaa: - case 0xac: - xf_emit(ctx, 0xa0, 0); /* ffffffff */ - break; - case 0x84: - case 0x92: - case 0x94: - case 0x96: - xf_emit(ctx, 0x120, 0); - break; - case 0xa5: - case 0xa8: - xf_emit(ctx, 0x100, 0); /* ffffffff */ - break; - case 0xa0: - case 0xa3: - case 0xaf: - xf_emit(ctx, 0x400, 0); /* ffffffff */ - break; - } - xf_emit(ctx, 4, 0); /* 3f, 0, 0, 0 */ - xf_emit(ctx, 4, 0); /* ffffffff */ - } - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ - xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_TEMP */ - xf_emit(ctx, 1, 1); /* 00000001 RASTERIZE_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0x27); /* 000000ff UNK0FD4 */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ -} - -static void -nv50_graph_construct_gene_unk34xx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* end of area 2 on pre-NVA0, area 1 on NVAx */ - xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */ - xf_emit(ctx, 1, 0); /* 00000003 VIEWPORT_CLIP_MODE */ - xf_emit(ctx, 0x10, 0x04000000); /* 07ffffff VIEWPORT_CLIP_HORIZ*8, VIEWPORT_CLIP_VERT*8 */ - xf_emit(ctx, 1, 0); /* 00000001 POLYGON_STIPPLE_ENABLE */ - xf_emit(ctx, 0x20, 0); /* ffffffff POLYGON_STIPPLE */ - xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0D64 */ - xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0DF4 */ - xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0x1fe21); /* 0001ffff tesla UNK0FAC */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 0x0fac6881); - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 1); - xf_emit(ctx, 3, 0); - } -} - -static void -nv50_graph_construct_gene_unk14xx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */ - if (dev_priv->chipset != 0x50) { - xf_emit(ctx, 5, 0); /* ffffffff */ - xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 2, 4); /* 7f, ff */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - } - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* 000000ff VP_CLIP_DISTANCE_ENABLE */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 0); /* 3ff */ - xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1940 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */ - xf_emit(ctx, 1, 0x804); /* 00000fff SEMANTIC_CLIP */ - xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 0x7f); /* 000000ff tesla UNK0FFC */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 1); /* 00000001 SHADE_MODEL */ - xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0D7C */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0F8C */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0); /* 0000000f */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */ - else - xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */ - xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ - xf_emit(ctx, 0x30, 0); /* ffffffff VIEWPORT_SCALE: X0, Y0, Z0, X1, Y1, ... */ - xf_emit(ctx, 3, 0); /* f, 0, 0 */ - xf_emit(ctx, 3, 0); /* ffffffff last VIEWPORT_SCALE? */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 1); /* 00000001 VIEWPORT_TRANSFORM_EN */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ - xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 0x30, 0); /* ffffffff VIEWPORT_TRANSLATE */ - xf_emit(ctx, 3, 0); /* f, 0, 0 */ - xf_emit(ctx, 3, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 2, 0x88); /* 000001ff tesla UNK19D8 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ - xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ - xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ - xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ - xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0); /* 0000000f */ - xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ - xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ - if (dev_priv->chipset != 0x50) { - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - } - xf_emit(ctx, 0x20, 0); /* 10xbits ffffffff, 3fffff. SCISSOR_* */ - xf_emit(ctx, 1, 0); /* f */ - xf_emit(ctx, 1, 0); /* 0? */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 003fffff */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0x52); /* 000001ff SEMANTIC_PTSZ */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 0x26); /* 000000ff SEMANTIC_LAYER */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ - xf_emit(ctx, 1, 0); /* 0000000f */ -} - -static void -nv50_graph_construct_gene_zcull(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* end of strand 0 on pre-NVA0, beginning of strand 6 on NVAx */ - /* SEEK */ - xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */ - xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ - xf_emit(ctx, 2, 0x04000000); /* 07ffffff tesla UNK0D6C */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 0); /* 00000001 CLIPID_ENABLE */ - xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ - xf_emit(ctx, 1, 0); /* 0000ffff */ - xf_emit(ctx, 1, 0); /* 00000001 UNK0FB0 */ - xf_emit(ctx, 1, 0); /* 00000001 POLYGON_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 0); /* 000000ff CLEAR_STENCIL */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ - xf_emit(ctx, 1, 0); /* 00000007 */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1108 */ - xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */ - /* SEEK */ - xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ - xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ - xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ - xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ - xf_emit(ctx, 1, 0x10); /* 7f/ff/3ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* 00000001 VIEWPORT_CLIP_RECTS_EN */ - xf_emit(ctx, 1, 3); /* 00000003 FP_CTRL_UNK196C */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1968 */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 0); /* 0fffffff tesla UNK1104 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK151C */ -} - -static void -nv50_graph_construct_gene_clipid(struct nouveau_grctx *ctx) -{ - /* middle of strand 0 on pre-NVA0 [after 24xx], middle of area 6 on NVAx */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* 00000007 UNK0FB4 */ - /* SEEK */ - xf_emit(ctx, 4, 0); /* 07ffffff CLIPID_REGION_HORIZ */ - xf_emit(ctx, 4, 0); /* 07ffffff CLIPID_REGION_VERT */ - xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ - xf_emit(ctx, 2, 0x04000000); /* 07ffffff UNK1508 */ - xf_emit(ctx, 1, 0); /* 00000001 CLIPID_ENABLE */ - xf_emit(ctx, 1, 0x80); /* 00003fff CLIPID_WIDTH */ - xf_emit(ctx, 1, 0); /* 000000ff CLIPID_ID */ - xf_emit(ctx, 1, 0); /* 000000ff CLIPID_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff CLIPID_ADDRESS_LOW */ - xf_emit(ctx, 1, 0x80); /* 00003fff CLIPID_HEIGHT */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_CLIPID */ -} - -static void -nv50_graph_construct_gene_unk24xx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - /* middle of strand 0 on pre-NVA0 [after m2mf], end of strand 2 on NVAx */ - /* SEEK */ - xf_emit(ctx, 0x33, 0); - /* SEEK */ - xf_emit(ctx, 2, 0); - /* SEEK */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 4, 0); /* RO */ - xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ - xf_emit(ctx, 1, 0); /* 1ff */ - xf_emit(ctx, 8, 0); /* 0? */ - xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ - - xf_emit(ctx, 4, 0); /* RO */ - xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ - xf_emit(ctx, 1, 0); /* 1ff */ - xf_emit(ctx, 8, 0); /* 0? */ - xf_emit(ctx, 9, 0); /* ffffffff, 7ff */ - } else { - xf_emit(ctx, 0xc, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ - xf_emit(ctx, 1, 0); /* 1ff */ - xf_emit(ctx, 8, 0); /* 0? */ - - /* SEEK */ - xf_emit(ctx, 0xc, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */ - xf_emit(ctx, 1, 0); /* 1ff */ - xf_emit(ctx, 8, 0); /* 0? */ - } - /* SEEK */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ - xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ - xf_emit(ctx, 1, 1); /* 00000001 */ - /* SEEK */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 2, 4); /* 000000ff */ - xf_emit(ctx, 1, 0x80c14); /* 01ffffff SEMANTIC_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 0x27); /* 000000ff SEMANTIC_PRIM_ID */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f */ - xf_emit(ctx, 1, 1); /* 00000001 */ - for (i = 0; i < 10; i++) { - /* SEEK */ - xf_emit(ctx, 0x40, 0); /* ffffffff */ - xf_emit(ctx, 0x10, 0); /* 3, 0, 0.... */ - xf_emit(ctx, 0x10, 0); /* ffffffff */ - } - /* SEEK */ - xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_CTRL */ - xf_emit(ctx, 1, 1); /* 00000001 */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 4, 0); /* ffffffff NOPERSPECTIVE_BITMAP */ - xf_emit(ctx, 0x10, 0); /* 00ffffff POINT_COORD_REPLACE_MAP */ - xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 0); /* 000003ff */ -} - -static void -nv50_graph_construct_gene_vfetch(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int acnt = 0x10, rep, i; - /* beginning of strand 1 on pre-NVA0, strand 3 on NVAx */ - if (IS_NVA3F(dev_priv->chipset)) - acnt = 0x20; - /* SEEK */ - if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK13A4 */ - xf_emit(ctx, 1, 1); /* 00000fff tesla UNK1318 */ - } - xf_emit(ctx, 1, 0); /* ffffffff VERTEX_BUFFER_FIRST */ - xf_emit(ctx, 1, 0); /* 00000001 PRIMITIVE_RESTART_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 UNK0DE8 */ - xf_emit(ctx, 1, 0); /* ffffffff PRIMITIVE_RESTART_INDEX */ - xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, acnt/8, 0); /* ffffffff VTX_ATR_MASK_UNK0DD0 */ - xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ - xf_emit(ctx, 1, 0x20); /* 0000ffff tesla UNK129C */ - xf_emit(ctx, 1, 0); /* 000000ff turing UNK370??? */ - xf_emit(ctx, 1, 0); /* 0000ffff turing USER_PARAM_COUNT */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0xb, 0); /* RO */ - else if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 0x9, 0); /* RO */ - else - xf_emit(ctx, 0x8, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* 00000001 EDGE_FLAG */ - xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ - /* SEEK */ - xf_emit(ctx, 0xc, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* 7f/ff */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ - xf_emit(ctx, 1, 4); /* 000001ff UNK1A28 */ - xf_emit(ctx, 1, 8); /* 000001ff UNK0DF0 */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0x3ff); /* 3ff tesla UNK0D68 */ - else - xf_emit(ctx, 1, 0x7ff); /* 7ff tesla UNK0D68 */ - if (dev_priv->chipset == 0xa8) - xf_emit(ctx, 1, 0x1e00); /* 7fff */ - /* SEEK */ - xf_emit(ctx, 0xc, 0); /* RO or close */ - /* SEEK */ - xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ - if (dev_priv->chipset > 0x50 && dev_priv->chipset < 0xa0) - xf_emit(ctx, 2, 0); /* ffffffff */ - else - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0FD8 */ - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 0x10, 0); /* 0? */ - xf_emit(ctx, 2, 0); /* weird... */ - xf_emit(ctx, 2, 0); /* RO */ - } else { - xf_emit(ctx, 8, 0); /* 0? */ - xf_emit(ctx, 1, 0); /* weird... */ - xf_emit(ctx, 2, 0); /* RO */ - } - /* SEEK */ - xf_emit(ctx, 1, 0); /* ffffffff VB_ELEMENT_BASE */ - xf_emit(ctx, 1, 0); /* ffffffff UNK1438 */ - xf_emit(ctx, acnt, 0); /* 1 tesla UNK1000 */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1118? */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */ - xf_emit(ctx, 1, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_UNK90C */ - xf_emit(ctx, 1, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* RO */ - xf_emit(ctx, 2, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK111C? */ - xf_emit(ctx, 1, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* 000000ff UNK15F4_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff UNK15F4_ADDRESS_LOW */ - xf_emit(ctx, 1, 0); /* 000000ff UNK0F84_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff UNK0F84_ADDRESS_LOW */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* 00003fff VERTEX_ARRAY_ATTRIB_OFFSET */ - xf_emit(ctx, 3, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* 00000fff VERTEX_ARRAY_STRIDE */ - xf_emit(ctx, 3, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_ARRAY_LOW */ - xf_emit(ctx, 3, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_ARRAY_HIGH */ - xf_emit(ctx, 3, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* ffffffff VERTEX_LIMIT_LOW */ - xf_emit(ctx, 3, 0); /* f/1f */ - /* SEEK */ - xf_emit(ctx, acnt, 0); /* 000000ff VERTEX_LIMIT_HIGH */ - xf_emit(ctx, 3, 0); /* f/1f */ - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, acnt, 0); /* f */ - xf_emit(ctx, 3, 0); /* f/1f */ - } - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 2, 0); /* RO */ - else - xf_emit(ctx, 5, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* ffff DMA_VTXBUF */ - /* SEEK */ - if (dev_priv->chipset < 0xa0) { - xf_emit(ctx, 0x41, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 0x11, 0); /* RO */ - } else if (!IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x50, 0); /* RO */ - else - xf_emit(ctx, 0x58, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, 1, 1); /* 1 UNK0DEC */ - /* SEEK */ - xf_emit(ctx, acnt*4, 0); /* ffffffff VTX_ATTR */ - xf_emit(ctx, 4, 0); /* f/1f, 0, 0, 0 */ - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x1d, 0); /* RO */ - else - xf_emit(ctx, 0x16, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ - /* SEEK */ - if (dev_priv->chipset < 0xa0) - xf_emit(ctx, 8, 0); /* RO */ - else if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0xc, 0); /* RO */ - else - xf_emit(ctx, 7, 0); /* RO */ - /* SEEK */ - xf_emit(ctx, 0xa, 0); /* RO */ - if (dev_priv->chipset == 0xa0) - rep = 0xc; - else - rep = 4; - for (i = 0; i < rep; i++) { - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x20, 0); /* ffffffff */ - xf_emit(ctx, 0x200, 0); /* ffffffff */ - xf_emit(ctx, 4, 0); /* 7f/ff, 0, 0, 0 */ - xf_emit(ctx, 4, 0); /* ffffffff */ - } - /* SEEK */ - xf_emit(ctx, 1, 0); /* 113/111 */ - xf_emit(ctx, 1, 0xf); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, (acnt/8)-1, 0); /* ffffffff VP_ATTR_EN */ - xf_emit(ctx, acnt/8, 0); /* ffffffff VTX_ATTR_MASK_UNK0DD0 */ - xf_emit(ctx, 1, 0); /* 0000000f VP_GP_BUILTIN_ATTR_EN */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - /* SEEK */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 7, 0); /* weird... */ - else - xf_emit(ctx, 5, 0); /* weird... */ -} - -static void -nv50_graph_construct_gene_eng2d(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* middle of strand 1 on pre-NVA0 [after vfetch], middle of strand 6 on NVAx */ - /* SEEK */ - xf_emit(ctx, 2, 0); /* 0001ffff CLIP_X, CLIP_Y */ - xf_emit(ctx, 2, 0); /* 0000ffff CLIP_W, CLIP_H */ - xf_emit(ctx, 1, 0); /* 00000001 CLIP_ENABLE */ - if (dev_priv->chipset < 0xa0) { - /* this is useless on everything but the original NV50, - * guess they forgot to nuke it. Or just didn't bother. */ - xf_emit(ctx, 2, 0); /* 0000ffff IFC_CLIP_X, Y */ - xf_emit(ctx, 2, 1); /* 0000ffff IFC_CLIP_W, H */ - xf_emit(ctx, 1, 0); /* 00000001 IFC_CLIP_ENABLE */ - } - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - xf_emit(ctx, 1, 0x100); /* 0001ffff DST_WIDTH */ - xf_emit(ctx, 1, 0x100); /* 0001ffff DST_HEIGHT */ - xf_emit(ctx, 1, 0x11); /* 3f[NV50]/7f[NV84+] DST_FORMAT */ - xf_emit(ctx, 1, 0); /* 0001ffff DRAW_POINT_X */ - xf_emit(ctx, 1, 8); /* 0000000f DRAW_UNK58C */ - xf_emit(ctx, 1, 0); /* 000fffff SIFC_DST_X_FRACT */ - xf_emit(ctx, 1, 0); /* 0001ffff SIFC_DST_X_INT */ - xf_emit(ctx, 1, 0); /* 000fffff SIFC_DST_Y_FRACT */ - xf_emit(ctx, 1, 0); /* 0001ffff SIFC_DST_Y_INT */ - xf_emit(ctx, 1, 0); /* 000fffff SIFC_DX_DU_FRACT */ - xf_emit(ctx, 1, 1); /* 0001ffff SIFC_DX_DU_INT */ - xf_emit(ctx, 1, 0); /* 000fffff SIFC_DY_DV_FRACT */ - xf_emit(ctx, 1, 1); /* 0001ffff SIFC_DY_DV_INT */ - xf_emit(ctx, 1, 1); /* 0000ffff SIFC_WIDTH */ - xf_emit(ctx, 1, 1); /* 0000ffff SIFC_HEIGHT */ - xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */ - xf_emit(ctx, 1, 2); /* 00000003 SIFC_BITMAP_UNK808 */ - xf_emit(ctx, 1, 0); /* 00000003 SIFC_BITMAP_LINE_PACK_MODE */ - xf_emit(ctx, 1, 0); /* 00000001 SIFC_BITMAP_LSB_FIRST */ - xf_emit(ctx, 1, 0); /* 00000001 SIFC_BITMAP_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000ffff BLIT_DST_X */ - xf_emit(ctx, 1, 0); /* 0000ffff BLIT_DST_Y */ - xf_emit(ctx, 1, 0); /* 000fffff BLIT_DU_DX_FRACT */ - xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DU_DX_INT */ - xf_emit(ctx, 1, 0); /* 000fffff BLIT_DV_DY_FRACT */ - xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DV_DY_INT */ - xf_emit(ctx, 1, 1); /* 0000ffff BLIT_DST_W */ - xf_emit(ctx, 1, 1); /* 0000ffff BLIT_DST_H */ - xf_emit(ctx, 1, 0); /* 000fffff BLIT_SRC_X_FRACT */ - xf_emit(ctx, 1, 0); /* 0001ffff BLIT_SRC_X_INT */ - xf_emit(ctx, 1, 0); /* 000fffff BLIT_SRC_Y_FRACT */ - xf_emit(ctx, 1, 0); /* 00000001 UNK888 */ - xf_emit(ctx, 1, 4); /* 0000003f UNK884 */ - xf_emit(ctx, 1, 0); /* 00000007 UNK880 */ - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK0FB8 */ - xf_emit(ctx, 1, 0x15); /* 000000ff tesla UNK128C */ - xf_emit(ctx, 2, 0); /* 00000007, ffff0ff3 */ - xf_emit(ctx, 1, 0); /* 00000001 UNK260 */ - xf_emit(ctx, 1, 0x4444480); /* 1fffffff UNK870 */ - /* SEEK */ - xf_emit(ctx, 0x10, 0); - /* SEEK */ - xf_emit(ctx, 0x27, 0); -} - -static void -nv50_graph_construct_gene_csched(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* middle of strand 1 on pre-NVA0 [after eng2d], middle of strand 0 on NVAx */ - /* SEEK */ - xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY... what is it doing here??? */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1924 */ - xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 0); /* 000003ff */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* ffffffff turing UNK364 */ - xf_emit(ctx, 1, 0); /* 0000000f turing UNK36C */ - xf_emit(ctx, 1, 0); /* 0000ffff USER_PARAM_COUNT */ - xf_emit(ctx, 1, 0x100); /* 00ffffff turing UNK384 */ - xf_emit(ctx, 1, 0); /* 0000000f turing UNK2A0 */ - xf_emit(ctx, 1, 0); /* 0000ffff GRIDID */ - xf_emit(ctx, 1, 0x10001); /* ffffffff GRIDDIM_XY */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0x10001); /* ffffffff BLOCKDIM_XY */ - xf_emit(ctx, 1, 1); /* 0000ffff BLOCKDIM_Z */ - xf_emit(ctx, 1, 0x10001); /* 00ffffff BLOCK_ALLOC */ - xf_emit(ctx, 1, 1); /* 00000001 LANES32 */ - xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ - xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ - /* SEEK */ - xf_emit(ctx, 0x40, 0); /* ffffffff USER_PARAM */ - switch (dev_priv->chipset) { - case 0x50: - case 0x92: - xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ - xf_emit(ctx, 0x80, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 0x10*2, 0); /* ffffffff, 1f */ - break; - case 0x84: - xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ - xf_emit(ctx, 0x60, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 0xc*2, 0); /* ffffffff, 1f */ - break; - case 0x94: - case 0x96: - xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ - xf_emit(ctx, 0x40, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 8*2, 0); /* ffffffff, 1f */ - break; - case 0x86: - case 0x98: - xf_emit(ctx, 4, 0); /* f, 0, 0, 0 */ - xf_emit(ctx, 0x10, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 2*2, 0); /* ffffffff, 1f */ - break; - case 0xa0: - xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ - xf_emit(ctx, 0xf0, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 0x1e*2, 0); /* ffffffff, 1f */ - break; - case 0xa3: - xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ - xf_emit(ctx, 0x60, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 0xc*2, 0); /* ffffffff, 1f */ - break; - case 0xa5: - case 0xaf: - xf_emit(ctx, 8, 0); /* 7, 0, 0, 0, ... */ - xf_emit(ctx, 0x30, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 6*2, 0); /* ffffffff, 1f */ - break; - case 0xaa: - xf_emit(ctx, 0x12, 0); - break; - case 0xa8: - case 0xac: - xf_emit(ctx, 4, 0); /* f, 0, 0, 0 */ - xf_emit(ctx, 0x10, 0); /* fff */ - xf_emit(ctx, 2, 0); /* ff, fff */ - xf_emit(ctx, 2*2, 0); /* ffffffff, 1f */ - break; - } - xf_emit(ctx, 1, 0); /* 0000000f */ - xf_emit(ctx, 1, 0); /* 00000000 */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 0000001f */ - xf_emit(ctx, 4, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 00000003 turing UNK35C */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 4, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 00000003 turing UNK35C */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 000000ff */ -} - -static void -nv50_graph_construct_gene_unk1cxx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ - xf_emit(ctx, 1, 0x3f800000); /* ffffffff LINE_WIDTH */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1658 */ - xf_emit(ctx, 1, 0); /* 00000001 POLYGON_SMOOTH_ENABLE */ - xf_emit(ctx, 3, 0); /* 00000001 POLYGON_OFFSET_*_ENABLE */ - xf_emit(ctx, 1, 4); /* 0000000f CULL_MODE */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK165C */ - xf_emit(ctx, 0x10, 0); /* 00000001 SCISSOR_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ - xf_emit(ctx, 1, 0); /* ffffffff POLYGON_OFFSET_UNITS */ - xf_emit(ctx, 1, 0); /* ffffffff POLYGON_OFFSET_FACTOR */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */ - xf_emit(ctx, 2, 0); /* 07ffffff SCREEN_SCISSOR */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0x11); /* 0000007f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 0000007f RT_FORMAT */ - xf_emit(ctx, 8, 0); /* 00000001 RT_HORIZ_LINEAR */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 3); /* 00000003 UNK16B4 */ - else if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 1); /* 00000001 UNK16B4 */ - xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */ - xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ - xf_emit(ctx, 2, 0x04000000); /* 07ffffff tesla UNK0D6C */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ - xf_emit(ctx, 1, 5); /* 0000000f UNK1408 */ - xf_emit(ctx, 1, 0x52); /* 000001ff SEMANTIC_PTSZ */ - xf_emit(ctx, 1, 0); /* ffffffff POINT_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 00000007 tesla UNK0FB4 */ - if (dev_priv->chipset != 0x50) { - xf_emit(ctx, 1, 0); /* 3ff */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK1110 */ - } - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */ - xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ - xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ - xf_emit(ctx, 1, 0x10); /* 000000ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 0x20, 0); /* 07ffffff VIEWPORT_HORIZ, then VIEWPORT_VERT. (W&0x3fff)<<13 | (X&0x1fff). */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK187C */ - xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ - xf_emit(ctx, 1, 0x8100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 5); /* 0000000f tesla UNK1220 */ - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 000000ff tesla UNK1A20 */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ - xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ - if (dev_priv->chipset < 0xa0) - xf_emit(ctx, 0x1c, 0); /* RO */ - else if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x9, 0); - xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ - xf_emit(ctx, 1, 0); /* 00000003 WINDOW_ORIGIN */ - if (dev_priv->chipset != 0x50) { - xf_emit(ctx, 1, 3); /* 00000003 tesla UNK1100 */ - xf_emit(ctx, 1, 0); /* 3ff */ - } - /* XXX: the following block could belong either to unk1cxx, or - * to STRMOUT. Rather hard to tell. */ - if (dev_priv->chipset < 0xa0) - xf_emit(ctx, 0x25, 0); - else - xf_emit(ctx, 0x3b, 0); -} - -static void -nv50_graph_construct_gene_strmout(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */ - xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */ - xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */ - if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */ - xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */ - } - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 4); /* 0000007f VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0x3ff); /* 000003ff tesla UNK0D68 */ - else - xf_emit(ctx, 1, 0x7ff); /* 000007ff tesla UNK0D68 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - /* SEEK */ - xf_emit(ctx, 1, 0x102); /* 0000ffff STRMOUT_BUFFER_CTRL */ - xf_emit(ctx, 1, 0); /* ffffffff STRMOUT_PRIMITIVE_COUNT */ - xf_emit(ctx, 4, 0); /* 000000ff STRMOUT_ADDRESS_HIGH */ - xf_emit(ctx, 4, 0); /* ffffffff STRMOUT_ADDRESS_LOW */ - xf_emit(ctx, 4, 4); /* 000000ff STRMOUT_NUM_ATTRIBS */ - if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 4, 0); /* ffffffff UNK1A8C */ - xf_emit(ctx, 4, 0); /* ffffffff UNK1780 */ - } - xf_emit(ctx, 1, 0); /* 0000ffff DMA_STRMOUT */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ - xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ - xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW QUERY_COUNTER */ - xf_emit(ctx, 2, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - /* SEEK */ - xf_emit(ctx, 0x20, 0); /* ffffffff STRMOUT_MAP */ - xf_emit(ctx, 1, 0); /* 0000000f */ - xf_emit(ctx, 1, 0); /* 00000000? */ - xf_emit(ctx, 2, 0); /* ffffffff */ -} - -static void -nv50_graph_construct_gene_ropm1(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */ - xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ -} - -static void -nv50_graph_construct_gene_ropm2(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - /* SEEK */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 2, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ - xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW, COUNTER */ - xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ - xf_emit(ctx, 1, 0); /* 7 */ - /* SEEK */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_QUERY */ - xf_emit(ctx, 1, 0); /* 000000ff QUERY_ADDRESS_HIGH */ - xf_emit(ctx, 2, 0); /* ffffffff QUERY_ADDRESS_LOW, COUNTER */ - xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0D64 */ - xf_emit(ctx, 1, 0x4e3bfdf); /* ffffffff UNK0DF4 */ - xf_emit(ctx, 1, 0); /* 00000001 eng2d UNK260 */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 0); /* 00000007 */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 0x11); /* 000000ff tesla UNK1968 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ -} - -static void -nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int magic2; - if (dev_priv->chipset == 0x50) { - magic2 = 0x00003e60; - } else if (!IS_NVA3F(dev_priv->chipset)) { - magic2 = 0x001ffe67; - } else { - magic2 = 0x00087e67; - } - xf_emit(ctx, 1, 0); /* f/7 MUTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - if (dev_priv->chipset >= 0xa0 && !IS_NVAAF(dev_priv->chipset)) - xf_emit(ctx, 1, 0x15); /* 000000ff */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ - xf_emit(ctx, 1, 0x10); /* 3ff/ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x92 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 3, 0); /* ff, ffffffff, ffffffff */ - xf_emit(ctx, 1, 4); /* 7 */ - xf_emit(ctx, 1, 0x400); /* fffffff */ - xf_emit(ctx, 1, 0x300); /* ffff */ - xf_emit(ctx, 1, 0x1001); /* 1fff */ - if (dev_priv->chipset != 0xa0) { - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 0); /* 0000000f UNK15C8 */ - else - xf_emit(ctx, 1, 0x15); /* ff */ - } - } - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ - xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1900 */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ - xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 0x10, 0); /* ffffffff DEPTH_RANGE_NEAR */ - xf_emit(ctx, 0x10, 0x3f800000); /* ffffffff DEPTH_RANGE_FAR */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_BACK_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_FUNC_REF */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 2, 0); /* ffffffff DEPTH_BOUNDS */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000007 DEPTH_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0); /* 000000ff CLEAR_STENCIL */ - xf_emit(ctx, 1, 0); /* 00000007 STENCIL_FRONT_FUNC_FUNC */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_FUNC_REF */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 1, 0x10); /* 7f/ff VIEW_VOLUME_CLIP_CTRL */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 0x3f); /* 0000003f UNK1590 */ - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 2, 0); /* ffff0ff3, ffff */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff CLEAR_DEPTH */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ - if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 2, 0); - xf_emit(ctx, 1, 0x1001); - xf_emit(ctx, 0xb, 0); - } else { - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - } - xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 1, 0x11); /* 3f/7f */ - xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ - if (dev_priv->chipset != 0x50) { - xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */ - xf_emit(ctx, 1, 0); /* 000000ff */ - } - xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ - xf_emit(ctx, 2, 1); /* 00000007 BLEND_EQUATION_RGB, ALPHA */ - xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK12E4 */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ - xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1140 */ - xf_emit(ctx, 2, 0); /* 00000001 */ - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* 0000000f */ - xf_emit(ctx, 1, 0); /* 00000003 */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 2, 0); /* 00000001 */ - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - } else if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 2, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* 00000003 */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 2, 0); /* 00000001 */ - } else { - xf_emit(ctx, 1, 0); /* 00000007 MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1430 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - } - xf_emit(ctx, 4, 0); /* ffffffff CLEAR_COLOR */ - xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR A R G B */ - xf_emit(ctx, 1, 0); /* 00000fff eng2d UNK2B0 */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 2, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ - xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */ - xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f LOGIC_OP */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 0); /* 00000001 UNK12E4? NVA3+ only? */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK15C4 */ - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1140 */ - } - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - xf_emit(ctx, 1, 0); /* 00000007 PATTERN_COLOR_FORMAT */ - xf_emit(ctx, 2, 0); /* ffffffff PATTERN_MONO_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 PATTERN_MONO_FORMAT */ - xf_emit(ctx, 2, 0); /* ffffffff PATTERN_MONO_BITMAP */ - xf_emit(ctx, 1, 0); /* 00000003 PATTERN_SELECT */ - xf_emit(ctx, 1, 0); /* 000000ff ROP */ - xf_emit(ctx, 1, 0); /* ffffffff BETA1 */ - xf_emit(ctx, 1, 0); /* ffffffff BETA4 */ - xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ - xf_emit(ctx, 0x50, 0); /* 10x ffffff, ffffff, ffffff, ffffff, 3 PATTERN */ -} - -static void -nv50_graph_construct_xfer_unk84xx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int magic3; - switch (dev_priv->chipset) { - case 0x50: - magic3 = 0x1000; - break; - case 0x86: - case 0x98: - case 0xa8: - case 0xaa: - case 0xac: - case 0xaf: - magic3 = 0x1e00; - break; - default: - magic3 = 0; - } - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 7f/ff[NVA0+] VP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0); /* 111/113[NVA0+] */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x1f, 0); /* ffffffff */ - else if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 0x0f, 0); /* ffffffff */ - else - xf_emit(ctx, 0x10, 0); /* fffffff VP_RESULT_MAP_1 up */ - xf_emit(ctx, 2, 0); /* f/1f[NVA3], fffffff/ffffffff[NVA0+] */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 0x03020100); /* ffffffff */ - else - xf_emit(ctx, 1, 0x00608080); /* fffffff VP_RESULT_MAP_0 */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 2, 0); /* 111/113, 7f/ff */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ - if (magic3) - xf_emit(ctx, 1, magic3); /* 00007fff tesla UNK141C */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0); /* 111/113 */ - xf_emit(ctx, 0x1f, 0); /* ffffffff GP_RESULT_MAP_1 up */ - xf_emit(ctx, 1, 0); /* 0000001f */ - xf_emit(ctx, 1, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 0x80); /* 0000ffff GP_VERTEX_OUTPUT_COUNT */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0x03020100); /* ffffffff GP_RESULT_MAP_0 */ - xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ - if (magic3) - xf_emit(ctx, 1, magic3); /* 7fff tesla UNK141C */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0); /* 111/113 */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ - xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK13A0 */ - xf_emit(ctx, 1, 4); /* 7f/ff VP_REG_ALLOC_RESULT */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - xf_emit(ctx, 1, 0); /* 111/113 */ - if (dev_priv->chipset == 0x94 || dev_priv->chipset == 0x96) - xf_emit(ctx, 0x1020, 0); /* 4 x (0x400 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */ - else if (dev_priv->chipset < 0xa0) - xf_emit(ctx, 0xa20, 0); /* 4 x (0x280 x 0xffffffff, ff, 0, 0, 0, 4 x ffffffff) */ - else if (!IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x210, 0); /* ffffffff */ - else - xf_emit(ctx, 0x410, 0); /* ffffffff */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 000000ff GP_RESULT_MAP_SIZE */ - xf_emit(ctx, 1, 3); /* 00000003 GP_OUTPUT_PRIMITIVE_TYPE */ - xf_emit(ctx, 1, 0); /* 00000001 PROVOKING_VERTEX_LAST */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ -} - -static void -nv50_graph_construct_xfer_tprop(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int magic1, magic2; - if (dev_priv->chipset == 0x50) { - magic1 = 0x3ff; - magic2 = 0x00003e60; - } else if (!IS_NVA3F(dev_priv->chipset)) { - magic1 = 0x7ff; - magic2 = 0x001ffe67; - } else { - magic1 = 0x7ff; - magic2 = 0x00087e67; - } - xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* ffffffff ALPHA_TEST_REF */ - xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000000f UNK16A0 */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_BACK_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_BACK_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 4, 0); /* ffffffff BLEND_COLOR */ - xf_emit(ctx, 1, 0); /* 00000001 UNK19C0 */ - xf_emit(ctx, 1, 0); /* 00000001 UNK0FDC */ - xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ - xf_emit(ctx, 1, 0); /* ff[NV50]/3ff[NV84+] */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ - xf_emit(ctx, 3, 0); /* 00000007 STENCIL_FRONT_OP_FAIL, ZFAIL, ZPASS */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_BACK_ENABLE */ - xf_emit(ctx, 2, 0); /* 00007fff WINDOW_OFFSET_XY */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ - xf_emit(ctx, 1, 0); /* 7 */ - xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff COLOR_KEY */ - xf_emit(ctx, 1, 0); /* 00000001 COLOR_KEY_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 COLOR_KEY_FORMAT */ - xf_emit(ctx, 2, 0); /* ffffffff SIFC_BITMAP_COLOR */ - xf_emit(ctx, 1, 1); /* 00000001 SIFC_BITMAP_WRITE_BIT0_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */ - xf_emit(ctx, 1, 0); /* 00000003 */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1298 */ - } else if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK16B4 */ - xf_emit(ctx, 1, 0); /* 00000003 */ - } else { - xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ - } - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ - xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_SRC_RGB */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_DST_RGB */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_SRC_ALPHA */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_DST_ALPHA */ - xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ - } - xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ - xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ - xf_emit(ctx, 1, 0); /* 7 */ - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - xf_emit(ctx, 1, 0); /* 00000007 OPERATION */ - xf_emit(ctx, 1, 0xcf); /* 000000ff SIFC_FORMAT */ - xf_emit(ctx, 1, 0xcf); /* 000000ff DRAW_COLOR_FORMAT */ - xf_emit(ctx, 1, 0xcf); /* 000000ff SRC_FORMAT */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - xf_emit(ctx, 1, 0); /* 7/f[NVA3] MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 8, 1); /* 00000001 UNK19E0 */ - xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0); /* ff */ - else - xf_emit(ctx, 3, 0); /* 1, 7, 3ff */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - xf_emit(ctx, 1, 0); /* 000fffff BLIT_DU_DX_FRACT */ - xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DU_DX_INT */ - xf_emit(ctx, 1, 0); /* 000fffff BLIT_DV_DY_FRACT */ - xf_emit(ctx, 1, 1); /* 0001ffff BLIT_DV_DY_INT */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, magic1); /* 3ff/7ff tesla UNK0D68 */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 8, 0); /* 0000ffff DMA_COLOR */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_GLOBAL */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_LOCAL */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_STACK */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_DST */ - xf_emit(ctx, 1, 0); /* 7 */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 8, 0); /* 000000ff RT_ADDRESS_HIGH */ - xf_emit(ctx, 8, 0); /* ffffffff RT_LAYER_STRIDE */ - xf_emit(ctx, 8, 0); /* ffffffff RT_ADDRESS_LOW */ - xf_emit(ctx, 8, 8); /* 0000007f RT_TILE_MODE */ - xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 8, 0x400); /* 0fffffff RT_HORIZ */ - xf_emit(ctx, 8, 0x300); /* 0000ffff RT_VERT */ - xf_emit(ctx, 1, 1); /* 00001fff RT_ARRAY_MODE */ - xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 1, 0x20); /* 00000fff DST_TILE_MODE */ - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 0x100); /* 0001ffff DST_HEIGHT */ - xf_emit(ctx, 1, 0); /* 000007ff DST_LAYER */ - xf_emit(ctx, 1, 1); /* 00000001 DST_LINEAR */ - xf_emit(ctx, 1, 0); /* ffffffff DST_ADDRESS_LOW */ - xf_emit(ctx, 1, 0); /* 000000ff DST_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0x40); /* 0007ffff DST_PITCH */ - xf_emit(ctx, 1, 0x100); /* 0001ffff DST_WIDTH */ - xf_emit(ctx, 1, 0); /* 0000ffff */ - xf_emit(ctx, 1, 3); /* 00000003 tesla UNK15AC */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ - xf_emit(ctx, 1, 0); /* 00000007 */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 2); /* 00000003 tesla UNK143C */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_ZETA */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 2, 0); /* ffff, ff/3ff */ - xf_emit(ctx, 1, 0); /* 0001ffff GP_BUILTIN_RESULT_EN */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 0); /* 000000ff STENCIL_FRONT_MASK */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* ffffffff ZETA_LAYER_STRIDE */ - xf_emit(ctx, 1, 0); /* 000000ff ZETA_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff ZETA_ADDRESS_LOW */ - xf_emit(ctx, 1, 4); /* 00000007 ZETA_TILE_MODE */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - xf_emit(ctx, 1, 0x400); /* 0fffffff ZETA_HORIZ */ - xf_emit(ctx, 1, 0x300); /* 0000ffff ZETA_VERT */ - xf_emit(ctx, 1, 0x1001); /* 00001fff ZETA_ARRAY_MODE */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 0); /* 00000001 */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 0x11); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 3f/7f RT_FORMAT */ - xf_emit(ctx, 1, 0x0fac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0xf); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 7, 0); /* 0000000f COLOR_MASK */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000003 UNK0F90 */ - xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ - xf_emit(ctx, 1, 0); /* 7 */ - xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - } - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 0x0fac6881); /* fffffff */ - xf_emit(ctx, 1, magic2); /* 001fffff tesla UNK0F78 */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_BOUNDS_EN */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE_ENABLE */ - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK0FB0 */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000001 STENCIL_FRONT_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK15B4 */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK19CC */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0); /* 00000001 SAMPLECNT_ENABLE */ - xf_emit(ctx, 1, 0); /* 0000000f ZETA_FORMAT */ - xf_emit(ctx, 1, 1); /* 00000001 ZETA_ENABLE */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* 0000000f tesla UNK15C8 */ - } - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A3C */ - if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 3, 0); /* 7/f, 1, ffff0ff3 */ - xf_emit(ctx, 1, 0xfac6881); /* fffffff */ - xf_emit(ctx, 4, 0); /* 1, 1, 1, 3ff */ - xf_emit(ctx, 1, 4); /* 7 */ - xf_emit(ctx, 1, 0); /* 1 */ - xf_emit(ctx, 2, 1); /* 1 */ - xf_emit(ctx, 2, 0); /* 7, f */ - xf_emit(ctx, 1, 1); /* 1 */ - xf_emit(ctx, 1, 0); /* 7/f */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 0x9, 0); /* 1 */ - else - xf_emit(ctx, 0x8, 0); /* 1 */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 8, 1); /* 1 */ - xf_emit(ctx, 1, 0x11); /* 7f */ - xf_emit(ctx, 7, 0); /* 7f */ - xf_emit(ctx, 1, 0xfac6881); /* fffffff */ - xf_emit(ctx, 1, 0xf); /* f */ - xf_emit(ctx, 7, 0); /* f */ - xf_emit(ctx, 1, 0x11); /* 7f */ - xf_emit(ctx, 1, 1); /* 1 */ - xf_emit(ctx, 5, 0); /* 1, 7, 3ff, 3, 7 */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - } - } -} - -static void -nv50_graph_construct_xfer_tex(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - xf_emit(ctx, 2, 0); /* 1 LINKED_TSC. yes, 2. */ - if (dev_priv->chipset != 0x50) - xf_emit(ctx, 1, 0); /* 3 */ - xf_emit(ctx, 1, 1); /* 1ffff BLIT_DU_DX_INT */ - xf_emit(ctx, 1, 0); /* fffff BLIT_DU_DX_FRACT */ - xf_emit(ctx, 1, 1); /* 1ffff BLIT_DV_DY_INT */ - xf_emit(ctx, 1, 0); /* fffff BLIT_DV_DY_FRACT */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 1, 0); /* 3 BLIT_CONTROL */ - else - xf_emit(ctx, 2, 0); /* 3ff, 1 */ - xf_emit(ctx, 1, 0x2a712488); /* ffffffff SRC_TIC_0 */ - xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_1 */ - xf_emit(ctx, 1, 0x4085c000); /* ffffffff SRC_TIC_2 */ - xf_emit(ctx, 1, 0x40); /* ffffffff SRC_TIC_3 */ - xf_emit(ctx, 1, 0x100); /* ffffffff SRC_TIC_4 */ - xf_emit(ctx, 1, 0x10100); /* ffffffff SRC_TIC_5 */ - xf_emit(ctx, 1, 0x02800000); /* ffffffff SRC_TIC_6 */ - xf_emit(ctx, 1, 0); /* ffffffff SRC_TIC_7 */ - if (dev_priv->chipset == 0x50) { - xf_emit(ctx, 1, 0); /* 00000001 turing UNK358 */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */ - xf_emit(ctx, 1, 0); /* 00000003 turing UNK37C tesla UNK1690 */ - xf_emit(ctx, 1, 0); /* 00000003 BLIT_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000001 turing UNK32C tesla UNK0F94 */ - } else if (!IS_NVAAF(dev_priv->chipset)) { - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34? */ - xf_emit(ctx, 1, 0); /* 00000003 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - xf_emit(ctx, 1, 0); /* 00000003 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1664 / turing UNK03E8 */ - xf_emit(ctx, 1, 0); /* 00000003 */ - xf_emit(ctx, 1, 0); /* 000003ff */ - } else { - xf_emit(ctx, 0x6, 0); - } - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_TEXTURE */ - xf_emit(ctx, 1, 0); /* 0000ffff DMA_SRC */ -} - -static void -nv50_graph_construct_xfer_unk8cxx(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 2, 0); /* 7, ffff0ff3 */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE */ - xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0D64 */ - xf_emit(ctx, 1, 0x04e3bfdf); /* ffffffff UNK0DF4 */ - xf_emit(ctx, 1, 1); /* 00000001 UNK15B4 */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK0F98 */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1668 */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_STIPPLE_ENABLE */ - xf_emit(ctx, 1, 0x00ffff00); /* 00ffffff LINE_STIPPLE_PATTERN */ - xf_emit(ctx, 1, 0); /* 00000001 POLYGON_SMOOTH_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 UNK1534 */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1658 */ - xf_emit(ctx, 1, 0); /* 00000001 LINE_SMOOTH_ENABLE */ - xf_emit(ctx, 1, 0); /* ffff0ff3 */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 DEPTH_WRITE */ - xf_emit(ctx, 1, 1); /* 00000001 UNK15B4 */ - xf_emit(ctx, 1, 0); /* 00000001 POINT_SPRITE_ENABLE */ - xf_emit(ctx, 1, 1); /* 00000001 tesla UNK165C */ - xf_emit(ctx, 1, 0x30201000); /* ffffffff tesla UNK1670 */ - xf_emit(ctx, 1, 0x70605040); /* ffffffff tesla UNK1670 */ - xf_emit(ctx, 1, 0xb8a89888); /* ffffffff tesla UNK1670 */ - xf_emit(ctx, 1, 0xf8e8d8c8); /* ffffffff tesla UNK1670 */ - xf_emit(ctx, 1, 0); /* 00000001 VERTEX_TWO_SIDE_ENABLE */ - xf_emit(ctx, 1, 0x1a); /* 0000001f POLYGON_MODE */ -} - -static void -nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - if (dev_priv->chipset < 0xa0) { - nv50_graph_construct_xfer_unk84xx(ctx); - nv50_graph_construct_xfer_tprop(ctx); - nv50_graph_construct_xfer_tex(ctx); - nv50_graph_construct_xfer_unk8cxx(ctx); - } else { - nv50_graph_construct_xfer_tex(ctx); - nv50_graph_construct_xfer_tprop(ctx); - nv50_graph_construct_xfer_unk8cxx(ctx); - nv50_graph_construct_xfer_unk84xx(ctx); - } -} - -static void -nv50_graph_construct_xfer_mpc(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i, mpcnt = 2; - switch (dev_priv->chipset) { - case 0x98: - case 0xaa: - mpcnt = 1; - break; - case 0x50: - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0xa8: - case 0xac: - mpcnt = 2; - break; - case 0xa0: - case 0xa3: - case 0xa5: - case 0xaf: - mpcnt = 3; - break; - } - for (i = 0; i < mpcnt; i++) { - xf_emit(ctx, 1, 0); /* ff */ - xf_emit(ctx, 1, 0x80); /* ffffffff tesla UNK1404 */ - xf_emit(ctx, 1, 0x80007004); /* ffffffff tesla UNK12B0 */ - xf_emit(ctx, 1, 0x04000400); /* ffffffff */ - if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 1, 0xc0); /* 00007fff tesla UNK152C */ - xf_emit(ctx, 1, 0x1000); /* 0000ffff tesla UNK0D60 */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A30 */ - if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset == 0xa8 || IS_NVAAF(dev_priv->chipset)) { - xf_emit(ctx, 1, 0xe00); /* 7fff */ - xf_emit(ctx, 1, 0x1e00); /* 7fff */ - } - xf_emit(ctx, 1, 1); /* 000000ff VP_REG_ALLOC_TEMP */ - xf_emit(ctx, 1, 0); /* 00000001 LINKED_TSC */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 2, 0x1000); /* 7fff tesla UNK141C */ - xf_emit(ctx, 1, 1); /* 000000ff GP_REG_ALLOC_TEMP */ - xf_emit(ctx, 1, 0); /* 00000001 GP_ENABLE */ - xf_emit(ctx, 1, 4); /* 000000ff FP_REG_ALLOC_TEMP */ - xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ - if (IS_NVAAF(dev_priv->chipset)) - xf_emit(ctx, 0xb, 0); /* RO */ - else if (dev_priv->chipset >= 0xa0) - xf_emit(ctx, 0xc, 0); /* RO */ - else - xf_emit(ctx, 0xa, 0); /* RO */ - } - xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - if (dev_priv->chipset >= 0xa0) { - xf_emit(ctx, 1, 0x1fe21); /* 0003ffff tesla UNK0FAC */ - } - xf_emit(ctx, 3, 0); /* 7fff, 0, 0 */ - xf_emit(ctx, 1, 0); /* 00000001 tesla UNK1534 */ - xf_emit(ctx, 1, 0); /* 7/f MULTISAMPLE_SAMPLES_LOG2 */ - xf_emit(ctx, 4, 0xffff); /* 0000ffff MSAA_MASK */ - xf_emit(ctx, 1, 1); /* 00000001 LANES32 */ - xf_emit(ctx, 1, 0x10001); /* 00ffffff BLOCK_ALLOC */ - xf_emit(ctx, 1, 0x10001); /* ffffffff BLOCKDIM_XY */ - xf_emit(ctx, 1, 1); /* 0000ffff BLOCKDIM_Z */ - xf_emit(ctx, 1, 0); /* ffffffff SHARED_SIZE */ - xf_emit(ctx, 1, 0x1fe21); /* 1ffff/3ffff[NVA0+] tesla UNk0FAC */ - xf_emit(ctx, 1, 0); /* ffffffff tesla UNK1A34 */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 1); /* 0000001f tesla UNK169C */ - xf_emit(ctx, 1, 0); /* ff/3ff */ - xf_emit(ctx, 1, 0); /* 1 LINKED_TSC */ - xf_emit(ctx, 1, 0); /* ff FP_ADDRESS_HIGH */ - xf_emit(ctx, 1, 0); /* ffffffff FP_ADDRESS_LOW */ - xf_emit(ctx, 1, 0x08100c12); /* 1fffffff FP_INTERPOLANT_CTRL */ - xf_emit(ctx, 1, 4); /* 00000007 FP_CONTROL */ - xf_emit(ctx, 1, 0); /* 000000ff FRAG_COLOR_CLAMP_EN */ - xf_emit(ctx, 1, 2); /* 00000003 REG_MODE */ - xf_emit(ctx, 1, 0x11); /* 0000007f RT_FORMAT */ - xf_emit(ctx, 7, 0); /* 0000007f RT_FORMAT */ - xf_emit(ctx, 1, 0); /* 00000007 */ - xf_emit(ctx, 1, 0xfac6881); /* 0fffffff RT_CONTROL */ - xf_emit(ctx, 1, 0); /* 00000003 MULTISAMPLE_CTRL */ - if (IS_NVA3F(dev_priv->chipset)) - xf_emit(ctx, 1, 3); /* 00000003 tesla UNK16B4 */ - xf_emit(ctx, 1, 0); /* 00000001 ALPHA_TEST_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000007 ALPHA_TEST_FUNC */ - xf_emit(ctx, 1, 0); /* 00000001 FRAMEBUFFER_SRGB */ - xf_emit(ctx, 1, 4); /* ffffffff tesla UNK1400 */ - xf_emit(ctx, 8, 0); /* 00000001 BLEND_ENABLE */ - xf_emit(ctx, 1, 0); /* 00000001 LOGIC_OP_ENABLE */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_RGB */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_RGB */ - xf_emit(ctx, 1, 2); /* 0000001f BLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 1, 1); /* 0000001f BLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 1, 1); /* 00000007 BLEND_EQUATION_ALPHA */ - xf_emit(ctx, 1, 1); /* 00000001 UNK133C */ - if (IS_NVA3F(dev_priv->chipset)) { - xf_emit(ctx, 1, 0); /* 00000001 UNK12E4 */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_RGB */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_RGB */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_RGB */ - xf_emit(ctx, 8, 2); /* 0000001f IBLEND_FUNC_SRC_ALPHA */ - xf_emit(ctx, 8, 1); /* 0000001f IBLEND_FUNC_DST_ALPHA */ - xf_emit(ctx, 8, 1); /* 00000007 IBLEND_EQUATION_ALPHA */ - xf_emit(ctx, 8, 1); /* 00000001 IBLEND_UNK00 */ - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK1928 */ - xf_emit(ctx, 1, 0); /* 00000001 UNK1140 */ - } - xf_emit(ctx, 1, 0); /* 00000003 tesla UNK0F90 */ - xf_emit(ctx, 1, 4); /* 000000ff FP_RESULT_COUNT */ - /* XXX: demagic this part some day */ - if (dev_priv->chipset == 0x50) - xf_emit(ctx, 0x3a0, 0); - else if (dev_priv->chipset < 0x94) - xf_emit(ctx, 0x3a2, 0); - else if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa) - xf_emit(ctx, 0x39f, 0); - else - xf_emit(ctx, 0x3a3, 0); - xf_emit(ctx, 1, 0x11); /* 3f/7f DST_FORMAT */ - xf_emit(ctx, 1, 0); /* 7 OPERATION */ - xf_emit(ctx, 1, 1); /* 1 DST_LINEAR */ - xf_emit(ctx, 0x2d, 0); -} - -static void -nv50_graph_construct_xfer2(struct nouveau_grctx *ctx) -{ - struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; - int i; - uint32_t offset; - uint32_t units = nv_rd32 (ctx->dev, 0x1540); - int size = 0; - - offset = (ctx->ctxvals_pos+0x3f)&~0x3f; - - if (dev_priv->chipset < 0xa0) { - for (i = 0; i < 8; i++) { - ctx->ctxvals_pos = offset + i; - /* that little bugger belongs to csched. No idea - * what it's doing here. */ - if (i == 0) - xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */ - if (units & (1 << i)) - nv50_graph_construct_xfer_mpc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - } - } else { - /* Strand 0: TPs 0, 1 */ - ctx->ctxvals_pos = offset; - /* that little bugger belongs to csched. No idea - * what it's doing here. */ - xf_emit(ctx, 1, 0x08100c12); /* FP_INTERPOLANT_CTRL */ - if (units & (1 << 0)) - nv50_graph_construct_xfer_mpc(ctx); - if (units & (1 << 1)) - nv50_graph_construct_xfer_mpc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 1: TPs 2, 3 */ - ctx->ctxvals_pos = offset + 1; - if (units & (1 << 2)) - nv50_graph_construct_xfer_mpc(ctx); - if (units & (1 << 3)) - nv50_graph_construct_xfer_mpc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 2: TPs 4, 5, 6 */ - ctx->ctxvals_pos = offset + 2; - if (units & (1 << 4)) - nv50_graph_construct_xfer_mpc(ctx); - if (units & (1 << 5)) - nv50_graph_construct_xfer_mpc(ctx); - if (units & (1 << 6)) - nv50_graph_construct_xfer_mpc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - - /* Strand 3: TPs 7, 8, 9 */ - ctx->ctxvals_pos = offset + 3; - if (units & (1 << 7)) - nv50_graph_construct_xfer_mpc(ctx); - if (units & (1 << 8)) - nv50_graph_construct_xfer_mpc(ctx); - if (units & (1 << 9)) - nv50_graph_construct_xfer_mpc(ctx); - if ((ctx->ctxvals_pos-offset)/8 > size) - size = (ctx->ctxvals_pos-offset)/8; - } - ctx->ctxvals_pos = offset + size * 8; - ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f; - cp_lsr (ctx, offset); - cp_out (ctx, CP_SET_XFER_POINTER); - cp_lsr (ctx, size); - cp_out (ctx, CP_SEEK_2); - cp_out (ctx, CP_XFER_2); - cp_wait(ctx, XFER, BUSY); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_instmem.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_instmem.c deleted file mode 100644 index a7c12c94..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_instmem.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" - -#include "nouveau_drv.h" -#include "nouveau_vm.h" - -#define BAR1_VM_BASE 0x0020000000ULL -#define BAR1_VM_SIZE pci_resource_len(dev->pdev, 1) -#define BAR3_VM_BASE 0x0000000000ULL -#define BAR3_VM_SIZE pci_resource_len(dev->pdev, 3) - -struct nv50_instmem_priv { - uint32_t save1700[5]; /* 0x1700->0x1710 */ - - struct nouveau_gpuobj *bar1_dmaobj; - struct nouveau_gpuobj *bar3_dmaobj; -}; - -static void -nv50_channel_del(struct nouveau_channel **pchan) -{ - struct nouveau_channel *chan; - - chan = *pchan; - *pchan = NULL; - if (!chan) - return; - - nouveau_gpuobj_ref(NULL, &chan->ramfc); - nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); - nouveau_gpuobj_ref(NULL, &chan->vm_pd); - if (drm_mm_initialized(&chan->ramin_heap)) - drm_mm_takedown(&chan->ramin_heap); - nouveau_gpuobj_ref(NULL, &chan->ramin); - kfree(chan); -} - -static int -nv50_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm, - struct nouveau_channel **pchan) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; - u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200; - struct nouveau_channel *chan; - int ret, i; - - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) - return -ENOMEM; - chan->dev = dev; - - ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin); - if (ret) { - nv50_channel_del(&chan); - return ret; - } - - ret = drm_mm_init(&chan->ramin_heap, 0x6000, chan->ramin->size); - if (ret) { - nv50_channel_del(&chan); - return ret; - } - - ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : - chan->ramin->pinst + pgd, - chan->ramin->vinst + pgd, - 0x4000, NVOBJ_FLAG_ZERO_ALLOC, - &chan->vm_pd); - if (ret) { - nv50_channel_del(&chan); - return ret; - } - - for (i = 0; i < 0x4000; i += 8) { - nv_wo32(chan->vm_pd, i + 0, 0x00000000); - nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe); - } - - ret = nouveau_vm_ref(vm, &chan->vm, chan->vm_pd); - if (ret) { - nv50_channel_del(&chan); - return ret; - } - - ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : - chan->ramin->pinst + fc, - chan->ramin->vinst + fc, 0x100, - NVOBJ_FLAG_ZERO_ALLOC, &chan->ramfc); - if (ret) { - nv50_channel_del(&chan); - return ret; - } - - *pchan = chan; - return 0; -} - -int -nv50_instmem_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_instmem_priv *priv; - struct nouveau_channel *chan; - struct nouveau_vm *vm; - int ret, i; - u32 tmp; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - dev_priv->engine.instmem.priv = priv; - - /* Save state, will restore at takedown. */ - for (i = 0x1700; i <= 0x1710; i += 4) - priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); - - /* Global PRAMIN heap */ - ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_size); - if (ret) { - NV_ERROR(dev, "Failed to init RAMIN heap\n"); - goto error; - } - - /* BAR3 */ - ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE, - &dev_priv->bar3_vm); - if (ret) - goto error; - - ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8, - 0x1000, NVOBJ_FLAG_DONT_MAP | - NVOBJ_FLAG_ZERO_ALLOC, - &dev_priv->bar3_vm->pgt[0].obj[0]); - if (ret) - goto error; - dev_priv->bar3_vm->pgt[0].refcount[0] = 1; - - nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]); - - ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan); - if (ret) - goto error; - dev_priv->channels.ptr[0] = dev_priv->channels.ptr[127] = chan; - - ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR3_VM_BASE, BAR3_VM_SIZE, - NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM, - NV_MEM_TYPE_VM, NV_MEM_COMP_VM, - &priv->bar3_dmaobj); - if (ret) - goto error; - - nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12)); - nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12)); - nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4)); - - dev_priv->engine.instmem.flush(dev); - dev_priv->ramin_available = true; - - tmp = nv_ro32(chan->ramin, 0); - nv_wo32(chan->ramin, 0, ~tmp); - if (nv_ro32(chan->ramin, 0) != ~tmp) { - NV_ERROR(dev, "PRAMIN readback failed\n"); - ret = -EIO; - goto error; - } - nv_wo32(chan->ramin, 0, tmp); - - /* BAR1 */ - ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, &vm); - if (ret) - goto error; - - ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, chan->vm_pd); - if (ret) - goto error; - nouveau_vm_ref(NULL, &vm, NULL); - - ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR1_VM_BASE, BAR1_VM_SIZE, - NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM, - NV_MEM_TYPE_VM, NV_MEM_COMP_VM, - &priv->bar1_dmaobj); - if (ret) - goto error; - - nv_wr32(dev, 0x001708, 0x80000000 | (priv->bar1_dmaobj->cinst >> 4)); - for (i = 0; i < 8; i++) - nv_wr32(dev, 0x1900 + (i*4), 0); - - /* Create shared channel VM, space is reserved at the beginning - * to catch "NULL pointer" references - */ - ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL, - &dev_priv->chan_vm); - if (ret) - return ret; - - return 0; - -error: - nv50_instmem_takedown(dev); - return ret; -} - -void -nv50_instmem_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - struct nouveau_channel *chan = dev_priv->channels.ptr[0]; - int i; - - NV_DEBUG(dev, "\n"); - - if (!priv) - return; - - dev_priv->ramin_available = false; - - nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL); - - for (i = 0x1700; i <= 0x1710; i += 4) - nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); - - nouveau_gpuobj_ref(NULL, &priv->bar3_dmaobj); - nouveau_gpuobj_ref(NULL, &priv->bar1_dmaobj); - - nouveau_vm_ref(NULL, &dev_priv->bar1_vm, chan->vm_pd); - dev_priv->channels.ptr[127] = 0; - nv50_channel_del(&dev_priv->channels.ptr[0]); - - nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]); - nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL); - - if (drm_mm_initialized(&dev_priv->ramin_heap)) - drm_mm_takedown(&dev_priv->ramin_heap); - - dev_priv->engine.instmem.priv = NULL; - kfree(priv); -} - -int -nv50_instmem_suspend(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - dev_priv->ramin_available = false; - return 0; -} - -void -nv50_instmem_resume(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - struct nouveau_channel *chan = dev_priv->channels.ptr[0]; - int i; - - /* Poke the relevant regs, and pray it works :) */ - nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12)); - nv_wr32(dev, NV50_PUNK_UNK1710, 0); - nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) | - NV50_PUNK_BAR_CFG_BASE_VALID); - nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->bar1_dmaobj->cinst >> 4) | - NV50_PUNK_BAR1_CTXDMA_VALID); - nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->bar3_dmaobj->cinst >> 4) | - NV50_PUNK_BAR3_CTXDMA_VALID); - - for (i = 0; i < 8; i++) - nv_wr32(dev, 0x1900 + (i*4), 0); - - dev_priv->ramin_available = true; -} - -struct nv50_gpuobj_node { - struct nouveau_mem *vram; - struct nouveau_vma chan_vma; - u32 align; -}; - -int -nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan, - u32 size, u32 align) -{ - struct drm_device *dev = gpuobj->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - struct nv50_gpuobj_node *node = NULL; - int ret; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - node->align = align; - - size = (size + 4095) & ~4095; - align = max(align, (u32)4096); - - ret = vram->get(dev, size, align, 0, 0, &node->vram); - if (ret) { - kfree(node); - return ret; - } - - gpuobj->vinst = node->vram->offset; - - if (gpuobj->flags & NVOBJ_FLAG_VM) { - u32 flags = NV_MEM_ACCESS_RW; - if (!(gpuobj->flags & NVOBJ_FLAG_VM_USER)) - flags |= NV_MEM_ACCESS_SYS; - - ret = nouveau_vm_get(chan->vm, size, 12, flags, - &node->chan_vma); - if (ret) { - vram->put(dev, &node->vram); - kfree(node); - return ret; - } - - nouveau_vm_map(&node->chan_vma, node->vram); - gpuobj->linst = node->chan_vma.offset; - } - - gpuobj->size = size; - gpuobj->node = node; - return 0; -} - -void -nv50_instmem_put(struct nouveau_gpuobj *gpuobj) -{ - struct drm_device *dev = gpuobj->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - struct nv50_gpuobj_node *node; - - node = gpuobj->node; - gpuobj->node = NULL; - - if (node->chan_vma.node) { - nouveau_vm_unmap(&node->chan_vma); - nouveau_vm_put(&node->chan_vma); - } - vram->put(dev, &node->vram); - kfree(node); -} - -int -nv50_instmem_map(struct nouveau_gpuobj *gpuobj) -{ - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct nv50_gpuobj_node *node = gpuobj->node; - int ret; - - ret = nouveau_vm_get(dev_priv->bar3_vm, gpuobj->size, 12, - NV_MEM_ACCESS_RW, &node->vram->bar_vma); - if (ret) - return ret; - - nouveau_vm_map(&node->vram->bar_vma, node->vram); - gpuobj->pinst = node->vram->bar_vma.offset; - return 0; -} - -void -nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) -{ - struct nv50_gpuobj_node *node = gpuobj->node; - - if (node->vram->bar_vma.node) { - nouveau_vm_unmap(&node->vram->bar_vma); - nouveau_vm_put(&node->vram->bar_vma); - } -} - -void -nv50_instmem_flush(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x00330c, 0x00000001); - if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); - spin_unlock_irqrestore(&dev_priv->vm_lock, flags); -} - -void -nv84_instmem_flush(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x070000, 0x00000001); - if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); - spin_unlock_irqrestore(&dev_priv->vm_lock, flags); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mc.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mc.c deleted file mode 100644 index e0a9c3fa..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mc.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2007 Ben Skeggs. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" - -int -nv50_mc_init(struct drm_device *dev) -{ - nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); - return 0; -} - -void nv50_mc_takedown(struct drm_device *dev) -{ -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mpeg.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mpeg.c deleted file mode 100644 index b57a2d18..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_mpeg.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_ramht.h" - -struct nv50_mpeg_engine { - struct nouveau_exec_engine base; -}; - -static inline u32 -CTX_PTR(struct drm_device *dev, u32 offset) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset == 0x50) - offset += 0x0260; - else - offset += 0x0060; - - return offset; -} - -static int -nv50_mpeg_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; - struct nouveau_gpuobj *ctx = NULL; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - ret = nouveau_gpuobj_new(dev, chan, 128 * 4, 0, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &ctx); - if (ret) - return ret; - - nv_wo32(ramin, CTX_PTR(dev, 0x00), 0x80190002); - nv_wo32(ramin, CTX_PTR(dev, 0x04), ctx->vinst + ctx->size - 1); - nv_wo32(ramin, CTX_PTR(dev, 0x08), ctx->vinst); - nv_wo32(ramin, CTX_PTR(dev, 0x0c), 0); - nv_wo32(ramin, CTX_PTR(dev, 0x10), 0); - nv_wo32(ramin, CTX_PTR(dev, 0x14), 0x00010000); - - nv_wo32(ctx, 0x70, 0x00801ec1); - nv_wo32(ctx, 0x7c, 0x0000037c); - dev_priv->engine.instmem.flush(dev); - - chan->engctx[engine] = ctx; - return 0; -} - -static void -nv50_mpeg_context_del(struct nouveau_channel *chan, int engine) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_gpuobj *ctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - unsigned long flags; - u32 inst, i; - - if (!chan->ramin) - return; - - inst = chan->ramin->vinst >> 12; - inst |= 0x80000000; - - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); - if (nv_rd32(dev, 0x00b318) == inst) - nv_mask(dev, 0x00b318, 0x80000000, 0x00000000); - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - - for (i = 0x00; i <= 0x14; i += 4) - nv_wo32(chan->ramin, CTX_PTR(dev, i), 0x00000000); - nouveau_gpuobj_ref(NULL, &ctx); - chan->engctx[engine] = NULL; -} - -static int -nv50_mpeg_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - obj->engine = 2; - obj->class = class; - - nv_wo32(obj, 0x00, class); - nv_wo32(obj, 0x04, 0x00000000); - nv_wo32(obj, 0x08, 0x00000000); - nv_wo32(obj, 0x0c, 0x00000000); - dev_priv->engine.instmem.flush(dev); - - ret = nouveau_ramht_insert(chan, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static void -nv50_mpeg_tlb_flush(struct drm_device *dev, int engine) -{ - nv50_vm_flush_engine(dev, 0x08); -} - -static int -nv50_mpeg_init(struct drm_device *dev, int engine) -{ - nv_wr32(dev, 0x00b32c, 0x00000000); - nv_wr32(dev, 0x00b314, 0x00000100); - nv_wr32(dev, 0x00b0e0, 0x0000001a); - - nv_wr32(dev, 0x00b220, 0x00000044); - nv_wr32(dev, 0x00b300, 0x00801ec1); - nv_wr32(dev, 0x00b390, 0x00000000); - nv_wr32(dev, 0x00b394, 0x00000000); - nv_wr32(dev, 0x00b398, 0x00000000); - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001); - - nv_wr32(dev, 0x00b100, 0xffffffff); - nv_wr32(dev, 0x00b140, 0xffffffff); - - if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200)); - return -EBUSY; - } - - return 0; -} - -static int -nv50_mpeg_fini(struct drm_device *dev, int engine, bool suspend) -{ - /*XXX: context save for s/r */ - nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000); - nv_wr32(dev, 0x00b140, 0x00000000); - return 0; -} - -static void -nv50_mpeg_isr(struct drm_device *dev) -{ - u32 stat = nv_rd32(dev, 0x00b100); - u32 type = nv_rd32(dev, 0x00b230); - u32 mthd = nv_rd32(dev, 0x00b234); - u32 data = nv_rd32(dev, 0x00b238); - u32 show = stat; - - if (stat & 0x01000000) { - /* happens on initial binding of the object */ - if (type == 0x00000020 && mthd == 0x0000) { - nv_wr32(dev, 0x00b308, 0x00000100); - show &= ~0x01000000; - } - } - - if (show && nouveau_ratelimit()) { - NV_INFO(dev, "PMPEG - 0x%08x 0x%08x 0x%08x 0x%08x\n", - stat, type, mthd, data); - } - - nv_wr32(dev, 0x00b100, stat); - nv_wr32(dev, 0x00b230, 0x00000001); - nv50_fb_vm_trap(dev, 1); -} - -static void -nv50_vpe_isr(struct drm_device *dev) -{ - if (nv_rd32(dev, 0x00b100)) - nv50_mpeg_isr(dev); - - if (nv_rd32(dev, 0x00b800)) { - u32 stat = nv_rd32(dev, 0x00b800); - NV_INFO(dev, "PMSRCH: 0x%08x\n", stat); - nv_wr32(dev, 0xb800, stat); - } -} - -static void -nv50_mpeg_destroy(struct drm_device *dev, int engine) -{ - struct nv50_mpeg_engine *pmpeg = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 0); - - NVOBJ_ENGINE_DEL(dev, MPEG); - kfree(pmpeg); -} - -int -nv50_mpeg_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_mpeg_engine *pmpeg; - - pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL); - if (!pmpeg) - return -ENOMEM; - - pmpeg->base.destroy = nv50_mpeg_destroy; - pmpeg->base.init = nv50_mpeg_init; - pmpeg->base.fini = nv50_mpeg_fini; - pmpeg->base.context_new = nv50_mpeg_context_new; - pmpeg->base.context_del = nv50_mpeg_context_del; - pmpeg->base.object_new = nv50_mpeg_object_new; - pmpeg->base.tlb_flush = nv50_mpeg_tlb_flush; - - if (dev_priv->chipset == 0x50) { - nouveau_irq_register(dev, 0, nv50_vpe_isr); - NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base); - NVOBJ_CLASS(dev, 0x3174, MPEG); -#if 0 - NVOBJ_ENGINE_ADD(dev, ME, &pme->base); - NVOBJ_CLASS(dev, 0x4075, ME); -#endif - } else { - nouveau_irq_register(dev, 0, nv50_mpeg_isr); - NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base); - NVOBJ_CLASS(dev, 0x8274, MPEG); - } - - return 0; - -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_pm.c deleted file mode 100644 index d020ed49..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_pm.c +++ /dev/null @@ -1,886 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_bios.h" -#include "nouveau_hw.h" -#include "nouveau_pm.h" -#include "nouveau_hwsq.h" -#include "nv50_display.h" - -enum clk_src { - clk_src_crystal, - clk_src_href, - clk_src_hclk, - clk_src_hclkm3, - clk_src_hclkm3d2, - clk_src_host, - clk_src_nvclk, - clk_src_sclk, - clk_src_mclk, - clk_src_vdec, - clk_src_dom6 -}; - -static u32 read_clk(struct drm_device *, enum clk_src); - -static u32 -read_div(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - switch (dev_priv->chipset) { - case 0x50: /* it exists, but only has bit 31, not the dividers.. */ - case 0x84: - case 0x86: - case 0x98: - case 0xa0: - return nv_rd32(dev, 0x004700); - case 0x92: - case 0x94: - case 0x96: - return nv_rd32(dev, 0x004800); - default: - return 0x00000000; - } -} - -static u32 -read_pll_src(struct drm_device *dev, u32 base) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 coef, ref = read_clk(dev, clk_src_crystal); - u32 rsel = nv_rd32(dev, 0x00e18c); - int P, N, M, id; - - switch (dev_priv->chipset) { - case 0x50: - case 0xa0: - switch (base) { - case 0x4020: - case 0x4028: id = !!(rsel & 0x00000004); break; - case 0x4008: id = !!(rsel & 0x00000008); break; - case 0x4030: id = 0; break; - default: - NV_ERROR(dev, "ref: bad pll 0x%06x\n", base); - return 0; - } - - coef = nv_rd32(dev, 0x00e81c + (id * 0x0c)); - ref *= (coef & 0x01000000) ? 2 : 4; - P = (coef & 0x00070000) >> 16; - N = ((coef & 0x0000ff00) >> 8) + 1; - M = ((coef & 0x000000ff) >> 0) + 1; - break; - case 0x84: - case 0x86: - case 0x92: - coef = nv_rd32(dev, 0x00e81c); - P = (coef & 0x00070000) >> 16; - N = (coef & 0x0000ff00) >> 8; - M = (coef & 0x000000ff) >> 0; - break; - case 0x94: - case 0x96: - case 0x98: - rsel = nv_rd32(dev, 0x00c050); - switch (base) { - case 0x4020: rsel = (rsel & 0x00000003) >> 0; break; - case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break; - case 0x4028: rsel = (rsel & 0x00001800) >> 11; break; - case 0x4030: rsel = 3; break; - default: - NV_ERROR(dev, "ref: bad pll 0x%06x\n", base); - return 0; - } - - switch (rsel) { - case 0: id = 1; break; - case 1: return read_clk(dev, clk_src_crystal); - case 2: return read_clk(dev, clk_src_href); - case 3: id = 0; break; - } - - coef = nv_rd32(dev, 0x00e81c + (id * 0x28)); - P = (nv_rd32(dev, 0x00e824 + (id * 0x28)) >> 16) & 7; - P += (coef & 0x00070000) >> 16; - N = (coef & 0x0000ff00) >> 8; - M = (coef & 0x000000ff) >> 0; - break; - default: - BUG_ON(1); - } - - if (M) - return (ref * N / M) >> P; - return 0; -} - -static u32 -read_pll_ref(struct drm_device *dev, u32 base) -{ - u32 src, mast = nv_rd32(dev, 0x00c040); - - switch (base) { - case 0x004028: - src = !!(mast & 0x00200000); - break; - case 0x004020: - src = !!(mast & 0x00400000); - break; - case 0x004008: - src = !!(mast & 0x00010000); - break; - case 0x004030: - src = !!(mast & 0x02000000); - break; - case 0x00e810: - return read_clk(dev, clk_src_crystal); - default: - NV_ERROR(dev, "bad pll 0x%06x\n", base); - return 0; - } - - if (src) - return read_clk(dev, clk_src_href); - return read_pll_src(dev, base); -} - -static u32 -read_pll(struct drm_device *dev, u32 base) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 mast = nv_rd32(dev, 0x00c040); - u32 ctrl = nv_rd32(dev, base + 0); - u32 coef = nv_rd32(dev, base + 4); - u32 ref = read_pll_ref(dev, base); - u32 clk = 0; - int N1, N2, M1, M2; - - if (base == 0x004028 && (mast & 0x00100000)) { - /* wtf, appears to only disable post-divider on nva0 */ - if (dev_priv->chipset != 0xa0) - return read_clk(dev, clk_src_dom6); - } - - N2 = (coef & 0xff000000) >> 24; - M2 = (coef & 0x00ff0000) >> 16; - N1 = (coef & 0x0000ff00) >> 8; - M1 = (coef & 0x000000ff); - if ((ctrl & 0x80000000) && M1) { - clk = ref * N1 / M1; - if ((ctrl & 0x40000100) == 0x40000000) { - if (M2) - clk = clk * N2 / M2; - else - clk = 0; - } - } - - return clk; -} - -static u32 -read_clk(struct drm_device *dev, enum clk_src src) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 mast = nv_rd32(dev, 0x00c040); - u32 P = 0; - - switch (src) { - case clk_src_crystal: - return dev_priv->crystal; - case clk_src_href: - return 100000; /* PCIE reference clock */ - case clk_src_hclk: - return read_clk(dev, clk_src_href) * 27778 / 10000; - case clk_src_hclkm3: - return read_clk(dev, clk_src_hclk) * 3; - case clk_src_hclkm3d2: - return read_clk(dev, clk_src_hclk) * 3 / 2; - case clk_src_host: - switch (mast & 0x30000000) { - case 0x00000000: return read_clk(dev, clk_src_href); - case 0x10000000: break; - case 0x20000000: /* !0x50 */ - case 0x30000000: return read_clk(dev, clk_src_hclk); - } - break; - case clk_src_nvclk: - if (!(mast & 0x00100000)) - P = (nv_rd32(dev, 0x004028) & 0x00070000) >> 16; - switch (mast & 0x00000003) { - case 0x00000000: return read_clk(dev, clk_src_crystal) >> P; - case 0x00000001: return read_clk(dev, clk_src_dom6); - case 0x00000002: return read_pll(dev, 0x004020) >> P; - case 0x00000003: return read_pll(dev, 0x004028) >> P; - } - break; - case clk_src_sclk: - P = (nv_rd32(dev, 0x004020) & 0x00070000) >> 16; - switch (mast & 0x00000030) { - case 0x00000000: - if (mast & 0x00000080) - return read_clk(dev, clk_src_host) >> P; - return read_clk(dev, clk_src_crystal) >> P; - case 0x00000010: break; - case 0x00000020: return read_pll(dev, 0x004028) >> P; - case 0x00000030: return read_pll(dev, 0x004020) >> P; - } - break; - case clk_src_mclk: - P = (nv_rd32(dev, 0x004008) & 0x00070000) >> 16; - if (nv_rd32(dev, 0x004008) & 0x00000200) { - switch (mast & 0x0000c000) { - case 0x00000000: - return read_clk(dev, clk_src_crystal) >> P; - case 0x00008000: - case 0x0000c000: - return read_clk(dev, clk_src_href) >> P; - } - } else { - return read_pll(dev, 0x004008) >> P; - } - break; - case clk_src_vdec: - P = (read_div(dev) & 0x00000700) >> 8; - switch (dev_priv->chipset) { - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0xa0: - switch (mast & 0x00000c00) { - case 0x00000000: - if (dev_priv->chipset == 0xa0) /* wtf?? */ - return read_clk(dev, clk_src_nvclk) >> P; - return read_clk(dev, clk_src_crystal) >> P; - case 0x00000400: - return 0; - case 0x00000800: - if (mast & 0x01000000) - return read_pll(dev, 0x004028) >> P; - return read_pll(dev, 0x004030) >> P; - case 0x00000c00: - return read_clk(dev, clk_src_nvclk) >> P; - } - break; - case 0x98: - switch (mast & 0x00000c00) { - case 0x00000000: - return read_clk(dev, clk_src_nvclk) >> P; - case 0x00000400: - return 0; - case 0x00000800: - return read_clk(dev, clk_src_hclkm3d2) >> P; - case 0x00000c00: - return read_clk(dev, clk_src_mclk) >> P; - } - break; - } - break; - case clk_src_dom6: - switch (dev_priv->chipset) { - case 0x50: - case 0xa0: - return read_pll(dev, 0x00e810) >> 2; - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0x98: - P = (read_div(dev) & 0x00000007) >> 0; - switch (mast & 0x0c000000) { - case 0x00000000: return read_clk(dev, clk_src_href); - case 0x04000000: break; - case 0x08000000: return read_clk(dev, clk_src_hclk); - case 0x0c000000: - return read_clk(dev, clk_src_hclkm3) >> P; - } - break; - default: - break; - } - default: - break; - } - - NV_DEBUG(dev, "unknown clock source %d 0x%08x\n", src, mast); - return 0; -} - -int -nv50_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - if (dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) - return 0; - - perflvl->core = read_clk(dev, clk_src_nvclk); - perflvl->shader = read_clk(dev, clk_src_sclk); - perflvl->memory = read_clk(dev, clk_src_mclk); - if (dev_priv->chipset != 0x50) { - perflvl->vdec = read_clk(dev, clk_src_vdec); - perflvl->dom6 = read_clk(dev, clk_src_dom6); - } - - return 0; -} - -struct nv50_pm_state { - struct nouveau_pm_level *perflvl; - struct hwsq_ucode eclk_hwsq; - struct hwsq_ucode mclk_hwsq; - u32 mscript; - u32 mmast; - u32 mctrl; - u32 mcoef; -}; - -static u32 -calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll, - u32 clk, int *N1, int *M1, int *log2P) -{ - struct nouveau_pll_vals coef; - int ret; - - ret = get_pll_limits(dev, reg, pll); - if (ret) - return 0; - - pll->vco2.maxfreq = 0; - pll->refclk = read_pll_ref(dev, reg); - if (!pll->refclk) - return 0; - - ret = nouveau_calc_pll_mnp(dev, pll, clk, &coef); - if (ret == 0) - return 0; - - *N1 = coef.N1; - *M1 = coef.M1; - *log2P = coef.log2P; - return ret; -} - -static inline u32 -calc_div(u32 src, u32 target, int *div) -{ - u32 clk0 = src, clk1 = src; - for (*div = 0; *div <= 7; (*div)++) { - if (clk0 <= target) { - clk1 = clk0 << (*div ? 1 : 0); - break; - } - clk0 >>= 1; - } - - if (target - clk0 <= clk1 - target) - return clk0; - (*div)--; - return clk1; -} - -static inline u32 -clk_same(u32 a, u32 b) -{ - return ((a / 1000) == (b / 1000)); -} - -static void -mclk_precharge(struct nouveau_mem_exec_func *exec) -{ - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - - hwsq_wr32(hwsq, 0x1002d4, 0x00000001); -} - -static void -mclk_refresh(struct nouveau_mem_exec_func *exec) -{ - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - - hwsq_wr32(hwsq, 0x1002d0, 0x00000001); -} - -static void -mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable) -{ - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - - hwsq_wr32(hwsq, 0x100210, enable ? 0x80000000 : 0x00000000); -} - -static void -mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable) -{ - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - - hwsq_wr32(hwsq, 0x1002dc, enable ? 0x00000001 : 0x00000000); -} - -static void -mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec) -{ - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - - if (nsec > 1000) - hwsq_usec(hwsq, (nsec + 500) / 1000); -} - -static u32 -mclk_mrg(struct nouveau_mem_exec_func *exec, int mr) -{ - if (mr <= 1) - return nv_rd32(exec->dev, 0x1002c0 + ((mr - 0) * 4)); - if (mr <= 3) - return nv_rd32(exec->dev, 0x1002e0 + ((mr - 2) * 4)); - return 0; -} - -static void -mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) -{ - struct drm_nouveau_private *dev_priv = exec->dev->dev_private; - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - - if (mr <= 1) { - if (dev_priv->vram_rank_B) - hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data); - hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data); - } else - if (mr <= 3) { - if (dev_priv->vram_rank_B) - hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data); - hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data); - } -} - -static void -mclk_clock_set(struct nouveau_mem_exec_func *exec) -{ - struct nv50_pm_state *info = exec->priv; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - u32 ctrl = nv_rd32(exec->dev, 0x004008); - - info->mmast = nv_rd32(exec->dev, 0x00c040); - info->mmast &= ~0xc0000000; /* get MCLK_2 from HREF */ - info->mmast |= 0x0000c000; /* use MCLK_2 as MPLL_BYPASS clock */ - - hwsq_wr32(hwsq, 0xc040, info->mmast); - hwsq_wr32(hwsq, 0x4008, ctrl | 0x00000200); /* bypass MPLL */ - if (info->mctrl & 0x80000000) - hwsq_wr32(hwsq, 0x400c, info->mcoef); - hwsq_wr32(hwsq, 0x4008, info->mctrl); -} - -static void -mclk_timing_set(struct nouveau_mem_exec_func *exec) -{ - struct drm_device *dev = exec->dev; - struct nv50_pm_state *info = exec->priv; - struct nouveau_pm_level *perflvl = info->perflvl; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - int i; - - for (i = 0; i < 9; i++) { - u32 reg = 0x100220 + (i * 4); - u32 val = nv_rd32(dev, reg); - if (val != perflvl->timing.reg[i]) - hwsq_wr32(hwsq, reg, perflvl->timing.reg[i]); - } -} - -static int -calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl, - struct nv50_pm_state *info) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 crtc_mask = nv50_display_active_crtcs(dev); - struct nouveau_mem_exec_func exec = { - .dev = dev, - .precharge = mclk_precharge, - .refresh = mclk_refresh, - .refresh_auto = mclk_refresh_auto, - .refresh_self = mclk_refresh_self, - .wait = mclk_wait, - .mrg = mclk_mrg, - .mrs = mclk_mrs, - .clock_set = mclk_clock_set, - .timing_set = mclk_timing_set, - .priv = info - }; - struct hwsq_ucode *hwsq = &info->mclk_hwsq; - struct pll_lims pll; - int N, M, P; - int ret; - - /* use pcie refclock if possible, otherwise use mpll */ - info->mctrl = nv_rd32(dev, 0x004008); - info->mctrl &= ~0x81ff0200; - if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) { - info->mctrl |= 0x00000200 | (pll.log2p_bias << 19); - } else { - ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P); - if (ret == 0) - return -EINVAL; - - info->mctrl |= 0x80000000 | (P << 22) | (P << 16); - info->mctrl |= pll.log2p_bias << 19; - info->mcoef = (N << 8) | M; - } - - /* build the ucode which will reclock the memory for us */ - hwsq_init(hwsq); - if (crtc_mask) { - hwsq_op5f(hwsq, crtc_mask, 0x00); /* wait for scanout */ - hwsq_op5f(hwsq, crtc_mask, 0x01); /* wait for vblank */ - } - if (dev_priv->chipset >= 0x92) - hwsq_wr32(hwsq, 0x611200, 0x00003300); /* disable scanout */ - hwsq_setf(hwsq, 0x10, 0); /* disable bus access */ - hwsq_op5f(hwsq, 0x00, 0x01); /* no idea :s */ - - ret = nouveau_mem_exec(&exec, perflvl); - if (ret) - return ret; - - hwsq_setf(hwsq, 0x10, 1); /* enable bus access */ - hwsq_op5f(hwsq, 0x00, 0x00); /* no idea, reverse of 0x00, 0x01? */ - if (dev_priv->chipset >= 0x92) - hwsq_wr32(hwsq, 0x611200, 0x00003330); /* enable scanout */ - hwsq_fini(hwsq); - return 0; -} - -void * -nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nv50_pm_state *info; - struct hwsq_ucode *hwsq; - struct pll_lims pll; - u32 out, mast, divs, ctrl; - int clk, ret = -EINVAL; - int N, M, P1, P2; - - if (dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) - return ERR_PTR(-ENODEV); - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return ERR_PTR(-ENOMEM); - info->perflvl = perflvl; - - /* memory: build hwsq ucode which we'll use to reclock memory. - * use pcie refclock if possible, otherwise use mpll */ - info->mclk_hwsq.len = 0; - if (perflvl->memory) { - ret = calc_mclk(dev, perflvl, info); - if (ret) - goto error; - info->mscript = perflvl->memscript; - } - - divs = read_div(dev); - mast = info->mmast; - - /* start building HWSQ script for engine reclocking */ - hwsq = &info->eclk_hwsq; - hwsq_init(hwsq); - hwsq_setf(hwsq, 0x10, 0); /* disable bus access */ - hwsq_op5f(hwsq, 0x00, 0x01); /* wait for access disabled? */ - - /* vdec/dom6: switch to "safe" clocks temporarily */ - if (perflvl->vdec) { - mast &= ~0x00000c00; - divs &= ~0x00000700; - } - - if (perflvl->dom6) { - mast &= ~0x0c000000; - divs &= ~0x00000007; - } - - hwsq_wr32(hwsq, 0x00c040, mast); - - /* vdec: avoid modifying xpll until we know exactly how the other - * clock domains work, i suspect at least some of them can also be - * tied to xpll... - */ - if (perflvl->vdec) { - /* see how close we can get using nvclk as a source */ - clk = calc_div(perflvl->core, perflvl->vdec, &P1); - - /* see how close we can get using xpll/hclk as a source */ - if (dev_priv->chipset != 0x98) - out = read_pll(dev, 0x004030); - else - out = read_clk(dev, clk_src_hclkm3d2); - out = calc_div(out, perflvl->vdec, &P2); - - /* select whichever gets us closest */ - if (abs((int)perflvl->vdec - clk) <= - abs((int)perflvl->vdec - out)) { - if (dev_priv->chipset != 0x98) - mast |= 0x00000c00; - divs |= P1 << 8; - } else { - mast |= 0x00000800; - divs |= P2 << 8; - } - } - - /* dom6: nfi what this is, but we're limited to various combinations - * of the host clock frequency - */ - if (perflvl->dom6) { - if (clk_same(perflvl->dom6, read_clk(dev, clk_src_href))) { - mast |= 0x00000000; - } else - if (clk_same(perflvl->dom6, read_clk(dev, clk_src_hclk))) { - mast |= 0x08000000; - } else { - clk = read_clk(dev, clk_src_hclk) * 3; - clk = calc_div(clk, perflvl->dom6, &P1); - - mast |= 0x0c000000; - divs |= P1; - } - } - - /* vdec/dom6: complete switch to new clocks */ - switch (dev_priv->chipset) { - case 0x92: - case 0x94: - case 0x96: - hwsq_wr32(hwsq, 0x004800, divs); - break; - default: - hwsq_wr32(hwsq, 0x004700, divs); - break; - } - - hwsq_wr32(hwsq, 0x00c040, mast); - - /* core/shader: make sure sclk/nvclk are disconnected from their - * PLLs (nvclk to dom6, sclk to hclk) - */ - if (dev_priv->chipset < 0x92) - mast = (mast & ~0x001000b0) | 0x00100080; - else - mast = (mast & ~0x000000b3) | 0x00000081; - - hwsq_wr32(hwsq, 0x00c040, mast); - - /* core: for the moment at least, always use nvpll */ - clk = calc_pll(dev, 0x4028, &pll, perflvl->core, &N, &M, &P1); - if (clk == 0) - goto error; - - ctrl = nv_rd32(dev, 0x004028) & ~0xc03f0100; - mast &= ~0x00100000; - mast |= 3; - - hwsq_wr32(hwsq, 0x004028, 0x80000000 | (P1 << 19) | (P1 << 16) | ctrl); - hwsq_wr32(hwsq, 0x00402c, (N << 8) | M); - - /* shader: tie to nvclk if possible, otherwise use spll. have to be - * very careful that the shader clock is at least twice the core, or - * some chipsets will be very unhappy. i expect most or all of these - * cases will be handled by tying to nvclk, but it's possible there's - * corners - */ - ctrl = nv_rd32(dev, 0x004020) & ~0xc03f0100; - - if (P1-- && perflvl->shader == (perflvl->core << 1)) { - hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl); - hwsq_wr32(hwsq, 0x00c040, 0x00000020 | mast); - } else { - clk = calc_pll(dev, 0x4020, &pll, perflvl->shader, &N, &M, &P1); - if (clk == 0) - goto error; - ctrl |= 0x80000000; - - hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl); - hwsq_wr32(hwsq, 0x004024, (N << 8) | M); - hwsq_wr32(hwsq, 0x00c040, 0x00000030 | mast); - } - - hwsq_setf(hwsq, 0x10, 1); /* enable bus access */ - hwsq_op5f(hwsq, 0x00, 0x00); /* wait for access enabled? */ - hwsq_fini(hwsq); - - return info; -error: - kfree(info); - return ERR_PTR(ret); -} - -static int -prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 hwsq_data, hwsq_kick; - int i; - - if (dev_priv->chipset < 0x94) { - hwsq_data = 0x001400; - hwsq_kick = 0x00000003; - } else { - hwsq_data = 0x080000; - hwsq_kick = 0x00000001; - } - /* upload hwsq ucode */ - nv_mask(dev, 0x001098, 0x00000008, 0x00000000); - nv_wr32(dev, 0x001304, 0x00000000); - if (dev_priv->chipset >= 0x92) - nv_wr32(dev, 0x001318, 0x00000000); - for (i = 0; i < hwsq->len / 4; i++) - nv_wr32(dev, hwsq_data + (i * 4), hwsq->ptr.u32[i]); - nv_mask(dev, 0x001098, 0x00000018, 0x00000018); - - /* launch, and wait for completion */ - nv_wr32(dev, 0x00130c, hwsq_kick); - if (!nv_wait(dev, 0x001308, 0x00000100, 0x00000000)) { - NV_ERROR(dev, "hwsq ucode exec timed out\n"); - NV_ERROR(dev, "0x001308: 0x%08x\n", nv_rd32(dev, 0x001308)); - for (i = 0; i < hwsq->len / 4; i++) { - NV_ERROR(dev, "0x%06x: 0x%08x\n", 0x1400 + (i * 4), - nv_rd32(dev, 0x001400 + (i * 4))); - } - - return -EIO; - } - - return 0; -} - -int -nv50_pm_clocks_set(struct drm_device *dev, void *data) -{ - struct nv50_pm_state *info = data; - struct bit_entry M; - int ret = -EBUSY; - - /* halt and idle execution engines */ - nv_mask(dev, 0x002504, 0x00000001, 0x00000001); - if (!nv_wait(dev, 0x002504, 0x00000010, 0x00000010)) - goto resume; - if (!nv_wait(dev, 0x00251c, 0x0000003f, 0x0000003f)) - goto resume; - - /* program memory clock, if necessary - must come before engine clock - * reprogramming due to how we construct the hwsq scripts in pre() - */ - if (info->mclk_hwsq.len) { - /* execute some scripts that do ??? from the vbios.. */ - if (!bit_table(dev, 'M', &M) && M.version == 1) { - if (M.length >= 6) - nouveau_bios_init_exec(dev, ROM16(M.data[5])); - if (M.length >= 8) - nouveau_bios_init_exec(dev, ROM16(M.data[7])); - if (M.length >= 10) - nouveau_bios_init_exec(dev, ROM16(M.data[9])); - nouveau_bios_init_exec(dev, info->mscript); - } - - ret = prog_hwsq(dev, &info->mclk_hwsq); - if (ret) - goto resume; - } - - /* program engine clocks */ - ret = prog_hwsq(dev, &info->eclk_hwsq); - -resume: - nv_mask(dev, 0x002504, 0x00000001, 0x00000000); - kfree(info); - return ret; -} - -static int -pwm_info(struct drm_device *dev, int *line, int *ctrl, int *indx) -{ - if (*line == 0x04) { - *ctrl = 0x00e100; - *line = 4; - *indx = 0; - } else - if (*line == 0x09) { - *ctrl = 0x00e100; - *line = 9; - *indx = 1; - } else - if (*line == 0x10) { - *ctrl = 0x00e28c; - *line = 0; - *indx = 0; - } else { - NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", *line); - return -ENODEV; - } - - return 0; -} - -int -nv50_pm_pwm_get(struct drm_device *dev, int line, u32 *divs, u32 *duty) -{ - int ctrl, id, ret = pwm_info(dev, &line, &ctrl, &id); - if (ret) - return ret; - - if (nv_rd32(dev, ctrl) & (1 << line)) { - *divs = nv_rd32(dev, 0x00e114 + (id * 8)); - *duty = nv_rd32(dev, 0x00e118 + (id * 8)); - return 0; - } - - return -EINVAL; -} - -int -nv50_pm_pwm_set(struct drm_device *dev, int line, u32 divs, u32 duty) -{ - int ctrl, id, ret = pwm_info(dev, &line, &ctrl, &id); - if (ret) - return ret; - - nv_mask(dev, ctrl, 0x00010001 << line, 0x00000001 << line); - nv_wr32(dev, 0x00e114 + (id * 8), divs); - nv_wr32(dev, 0x00e118 + (id * 8), duty | 0x80000000); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_sor.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_sor.c deleted file mode 100644 index 27464021..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_sor.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright (C) 2008 Maarten Maathuis. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) -#include "nouveau_reg.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_encoder.h" -#include "nouveau_connector.h" -#include "nouveau_crtc.h" -#include "nv50_display.h" - -static u32 -nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ - static const u8 nv50[] = { 16, 8, 0, 24 }; - if (dev_priv->chipset == 0xaf) - return nvaf[lane]; - return nv50[lane]; -} - -static void -nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_entry *dcb, u8 pattern) -{ - u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - nv_mask(dev, NV50_SOR_DP_CTRL(or, link), 0x0f000000, pattern << 24); -} - -static void -nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb, - u8 lane, u8 swing, u8 preem) -{ - u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - u32 shift = nv50_sor_dp_lane_map(dev, dcb, lane); - u32 mask = 0x000000ff << shift; - u8 *table, *entry, *config; - - table = nouveau_dp_bios_data(dev, dcb, &entry); - if (!table || (table[0] != 0x20 && table[0] != 0x21)) { - NV_ERROR(dev, "PDISP: unsupported DP table for chipset\n"); - return; - } - - config = entry + table[4]; - while (config[0] != swing || config[1] != preem) { - config += table[5]; - if (config >= entry + table[4] + entry[4] * table[5]) - return; - } - - nv_mask(dev, NV50_SOR_DP_UNK118(or, link), mask, config[2] << shift); - nv_mask(dev, NV50_SOR_DP_UNK120(or, link), mask, config[3] << shift); - nv_mask(dev, NV50_SOR_DP_UNK130(or, link), 0x0000ff00, config[4] << 8); -} - -static void -nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc, - int link_nr, u32 link_bw, bool enhframe) -{ - u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - u32 dpctrl = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)) & ~0x001f4000; - u32 clksor = nv_rd32(dev, 0x614300 + (or * 0x800)) & ~0x000c0000; - u8 *table, *entry, mask; - int i; - - table = nouveau_dp_bios_data(dev, dcb, &entry); - if (!table || (table[0] != 0x20 && table[0] != 0x21)) { - NV_ERROR(dev, "PDISP: unsupported DP table for chipset\n"); - return; - } - - entry = ROMPTR(dev, entry[10]); - if (entry) { - while (link_bw < ROM16(entry[0]) * 10) - entry += 4; - - nouveau_bios_run_init_table(dev, ROM16(entry[2]), dcb, crtc); - } - - dpctrl |= ((1 << link_nr) - 1) << 16; - if (enhframe) - dpctrl |= 0x00004000; - - if (link_bw > 162000) - clksor |= 0x00040000; - - nv_wr32(dev, 0x614300 + (or * 0x800), clksor); - nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), dpctrl); - - mask = 0; - for (i = 0; i < link_nr; i++) - mask |= 1 << (nv50_sor_dp_lane_map(dev, dcb, i) >> 3); - nv_mask(dev, NV50_SOR_DP_UNK130(or, link), 0x0000000f, mask); -} - -static void -nv50_sor_dp_link_get(struct drm_device *dev, u32 or, u32 link, u32 *nr, u32 *bw) -{ - u32 dpctrl = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link)) & 0x000f0000; - u32 clksor = nv_rd32(dev, 0x614300 + (or * 0x800)); - if (clksor & 0x000c0000) - *bw = 270000; - else - *bw = 162000; - - if (dpctrl > 0x00030000) *nr = 4; - else if (dpctrl > 0x00010000) *nr = 2; - else *nr = 1; -} - -void -nv50_sor_dp_calc_tu(struct drm_device *dev, int or, int link, u32 clk, u32 bpp) -{ - const u32 symbol = 100000; - int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0; - int TU, VTUi, VTUf, VTUa; - u64 link_data_rate, link_ratio, unk; - u32 best_diff = 64 * symbol; - u32 link_nr, link_bw, r; - - /* calculate packed data rate for each lane */ - nv50_sor_dp_link_get(dev, or, link, &link_nr, &link_bw); - link_data_rate = (clk * bpp / 8) / link_nr; - - /* calculate ratio of packed data rate to link symbol rate */ - link_ratio = link_data_rate * symbol; - r = do_div(link_ratio, link_bw); - - for (TU = 64; TU >= 32; TU--) { - /* calculate average number of valid symbols in each TU */ - u32 tu_valid = link_ratio * TU; - u32 calc, diff; - - /* find a hw representation for the fraction.. */ - VTUi = tu_valid / symbol; - calc = VTUi * symbol; - diff = tu_valid - calc; - if (diff) { - if (diff >= (symbol / 2)) { - VTUf = symbol / (symbol - diff); - if (symbol - (VTUf * diff)) - VTUf++; - - if (VTUf <= 15) { - VTUa = 1; - calc += symbol - (symbol / VTUf); - } else { - VTUa = 0; - VTUf = 1; - calc += symbol; - } - } else { - VTUa = 0; - VTUf = min((int)(symbol / diff), 15); - calc += symbol / VTUf; - } - - diff = calc - tu_valid; - } else { - /* no remainder, but the hw doesn't like the fractional - * part to be zero. decrement the integer part and - * have the fraction add a whole symbol back - */ - VTUa = 0; - VTUf = 1; - VTUi--; - } - - if (diff < best_diff) { - best_diff = diff; - bestTU = TU; - bestVTUa = VTUa; - bestVTUf = VTUf; - bestVTUi = VTUi; - if (diff == 0) - break; - } - } - - if (!bestTU) { - NV_ERROR(dev, "DP: unable to find suitable config\n"); - return; - } - - /* XXX close to vbios numbers, but not right */ - unk = (symbol - link_ratio) * bestTU; - unk *= link_ratio; - r = do_div(unk, symbol); - r = do_div(unk, symbol); - unk += 6; - - nv_mask(dev, NV50_SOR_DP_CTRL(or, link), 0x000001fc, bestTU << 2); - nv_mask(dev, NV50_SOR_DP_SCFG(or, link), 0x010f7f3f, bestVTUa << 24 | - bestVTUf << 16 | - bestVTUi << 8 | - unk); -} -static void -nv50_sor_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_channel *evo = nv50_display(dev)->master; - int ret; - - if (!nv_encoder->crtc) - return; - nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true); - - NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or); - - ret = RING_SPACE(evo, 4); - if (ret) { - NV_ERROR(dev, "no space while disconnecting SOR\n"); - return; - } - BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); - OUT_RING (evo, 0); - BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); - OUT_RING (evo, 0); - - nouveau_hdmi_mode_set(encoder, NULL); - - nv_encoder->crtc = NULL; - nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; -} - -static void -nv50_sor_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_encoder *enc; - uint32_t val; - int or = nv_encoder->or; - - NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode); - - nv_encoder->last_dpms = mode; - list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nvenc = nouveau_encoder(enc); - - if (nvenc == nv_encoder || - (nvenc->dcb->type != OUTPUT_TMDS && - nvenc->dcb->type != OUTPUT_LVDS && - nvenc->dcb->type != OUTPUT_DP) || - nvenc->dcb->or != nv_encoder->dcb->or) - continue; - - if (nvenc->last_dpms == DRM_MODE_DPMS_ON) - return; - } - - /* wait for it to be done */ - if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), - NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING, 0)) { - NV_ERROR(dev, "timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or); - NV_ERROR(dev, "SOR_DPMS_CTRL(%d) = 0x%08x\n", or, - nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or))); - } - - val = nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or)); - - if (mode == DRM_MODE_DPMS_ON) - val |= NV50_PDISPLAY_SOR_DPMS_CTRL_ON; - else - val &= ~NV50_PDISPLAY_SOR_DPMS_CTRL_ON; - - nv_wr32(dev, NV50_PDISPLAY_SOR_DPMS_CTRL(or), val | - NV50_PDISPLAY_SOR_DPMS_CTRL_PENDING); - if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or), - NV50_PDISPLAY_SOR_DPMS_STATE_WAIT, 0)) { - NV_ERROR(dev, "timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or); - NV_ERROR(dev, "SOR_DPMS_STATE(%d) = 0x%08x\n", or, - nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or))); - } - - if (nv_encoder->dcb->type == OUTPUT_DP) { - struct dp_train_func func = { - .link_set = nv50_sor_dp_link_set, - .train_set = nv50_sor_dp_train_set, - .train_adj = nv50_sor_dp_train_adj - }; - - nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func); - } -} - -static void -nv50_sor_save(struct drm_encoder *encoder) -{ - NV_ERROR(encoder->dev, "!!\n"); -} - -static void -nv50_sor_restore(struct drm_encoder *encoder) -{ - NV_ERROR(encoder->dev, "!!\n"); -} - -static bool -nv50_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *connector; - - NV_DEBUG_KMS(encoder->dev, "or %d\n", nv_encoder->or); - - connector = nouveau_encoder_connector_get(nv_encoder); - if (!connector) { - NV_ERROR(encoder->dev, "Encoder has no connector\n"); - return false; - } - - if (connector->scaling_mode != DRM_MODE_SCALE_NONE && - connector->native_mode) - drm_mode_copy(adjusted_mode, connector->native_mode); - - return true; -} - -static void -nv50_sor_prepare(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - nv50_sor_disconnect(encoder); - if (nv_encoder->dcb->type == OUTPUT_DP) { - /* avoid race between link training and supervisor intr */ - nv50_display_sync(encoder->dev); - } -} - -static void -nv50_sor_commit(struct drm_encoder *encoder) -{ -} - -static void -nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, - struct drm_display_mode *mode) -{ - struct nouveau_channel *evo = nv50_display(encoder->dev)->master; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc); - struct nouveau_connector *nv_connector; - uint32_t mode_ctl = 0; - int ret; - - NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n", - nv_encoder->or, nv_encoder->dcb->type, crtc->index); - nv_encoder->crtc = encoder->crtc; - - switch (nv_encoder->dcb->type) { - case OUTPUT_TMDS: - if (nv_encoder->dcb->sorconf.link & 1) { - if (mode->clock < 165000) - mode_ctl = 0x0100; - else - mode_ctl = 0x0500; - } else - mode_ctl = 0x0200; - - nouveau_hdmi_mode_set(encoder, mode); - break; - case OUTPUT_DP: - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (nv_connector && nv_connector->base.display_info.bpc == 6) { - nv_encoder->dp.datarate = mode->clock * 18 / 8; - mode_ctl |= 0x00020000; - } else { - nv_encoder->dp.datarate = mode->clock * 24 / 8; - mode_ctl |= 0x00050000; - } - - if (nv_encoder->dcb->sorconf.link & 1) - mode_ctl |= 0x00000800; - else - mode_ctl |= 0x00000900; - break; - default: - break; - } - - if (crtc->index == 1) - mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC1; - else - mode_ctl |= NV50_EVO_SOR_MODE_CTRL_CRTC0; - - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NHSYNC; - - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC; - - nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); - - ret = RING_SPACE(evo, 2); - if (ret) { - NV_ERROR(dev, "no space while connecting SOR\n"); - nv_encoder->crtc = NULL; - return; - } - BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1); - OUT_RING(evo, mode_ctl); -} - -static struct drm_crtc * -nv50_sor_crtc_get(struct drm_encoder *encoder) -{ - return nouveau_encoder(encoder)->crtc; -} - -static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = { - .dpms = nv50_sor_dpms, - .save = nv50_sor_save, - .restore = nv50_sor_restore, - .mode_fixup = nv50_sor_mode_fixup, - .prepare = nv50_sor_prepare, - .commit = nv50_sor_commit, - .mode_set = nv50_sor_mode_set, - .get_crtc = nv50_sor_crtc_get, - .detect = NULL, - .disable = nv50_sor_disconnect -}; - -static void -nv50_sor_destroy(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - - if (!encoder) - return; - - NV_DEBUG_KMS(encoder->dev, "\n"); - - drm_encoder_cleanup(encoder); - - kfree(nv_encoder); -} - -static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { - .destroy = nv50_sor_destroy, -}; - -int -nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry) -{ - struct nouveau_encoder *nv_encoder = NULL; - struct drm_device *dev = connector->dev; - struct drm_encoder *encoder; - int type; - - NV_DEBUG_KMS(dev, "\n"); - - switch (entry->type) { - case OUTPUT_TMDS: - case OUTPUT_DP: - type = DRM_MODE_ENCODER_TMDS; - break; - case OUTPUT_LVDS: - type = DRM_MODE_ENCODER_LVDS; - break; - default: - return -EINVAL; - } - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - encoder = to_drm_encoder(nv_encoder); - - nv_encoder->dcb = entry; - nv_encoder->or = ffs(entry->or) - 1; - nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; - - drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type); - drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs); - - encoder->possible_crtcs = entry->heads; - encoder->possible_clones = 0; - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vm.c deleted file mode 100644 index 44fbac9c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vm.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_vm.h" - -void -nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, - struct nouveau_gpuobj *pgt[2]) -{ - u64 phys = 0xdeadcafe00000000ULL; - u32 coverage = 0; - - if (pgt[0]) { - phys = 0x00000003 | pgt[0]->vinst; /* present, 4KiB pages */ - coverage = (pgt[0]->size >> 3) << 12; - } else - if (pgt[1]) { - phys = 0x00000001 | pgt[1]->vinst; /* present */ - coverage = (pgt[1]->size >> 3) << 16; - } - - if (phys & 1) { - if (coverage <= 32 * 1024 * 1024) - phys |= 0x60; - else if (coverage <= 64 * 1024 * 1024) - phys |= 0x40; - else if (coverage <= 128 * 1024 * 1024) - phys |= 0x20; - } - - nv_wo32(pgd, (pde * 8) + 0, lower_32_bits(phys)); - nv_wo32(pgd, (pde * 8) + 4, upper_32_bits(phys)); -} - -static inline u64 -vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target) -{ - phys |= 1; /* present */ - phys |= (u64)memtype << 40; - phys |= target << 4; - if (vma->access & NV_MEM_ACCESS_SYS) - phys |= (1 << 6); - if (!(vma->access & NV_MEM_ACCESS_WO)) - phys |= (1 << 3); - return phys; -} - -void -nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) -{ - struct drm_nouveau_private *dev_priv = vma->vm->dev->dev_private; - u32 comp = (mem->memtype & 0x180) >> 7; - u32 block, target; - int i; - - /* IGPs don't have real VRAM, re-target to stolen system memory */ - target = 0; - if (dev_priv->vram_sys_base) { - phys += dev_priv->vram_sys_base; - target = 3; - } - - phys = vm_addr(vma, phys, mem->memtype, target); - pte <<= 3; - cnt <<= 3; - - while (cnt) { - u32 offset_h = upper_32_bits(phys); - u32 offset_l = lower_32_bits(phys); - - for (i = 7; i >= 0; i--) { - block = 1 << (i + 3); - if (cnt >= block && !(pte & (block - 1))) - break; - } - offset_l |= (i << 7); - - phys += block << (vma->node->type - 3); - cnt -= block; - if (comp) { - u32 tag = mem->tag->start + ((delta >> 16) * comp); - offset_h |= (tag << 17); - delta += block << (vma->node->type - 3); - } - - while (block) { - nv_wo32(pgt, pte + 0, offset_l); - nv_wo32(pgt, pte + 4, offset_h); - pte += 8; - block -= 8; - } - } -} - -void -nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 3 : 2; - pte <<= 3; - while (cnt--) { - u64 phys = vm_addr(vma, (u64)*list++, mem->memtype, target); - nv_wo32(pgt, pte + 0, lower_32_bits(phys)); - nv_wo32(pgt, pte + 4, upper_32_bits(phys)); - pte += 8; - } -} - -void -nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) -{ - pte <<= 3; - while (cnt--) { - nv_wo32(pgt, pte + 0, 0x00000000); - nv_wo32(pgt, pte + 4, 0x00000000); - pte += 8; - } -} - -void -nv50_vm_flush(struct nouveau_vm *vm) -{ - struct drm_nouveau_private *dev_priv = vm->dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - int i; - - pinstmem->flush(vm->dev); - - /* BAR */ - if (vm == dev_priv->bar1_vm || vm == dev_priv->bar3_vm) { - nv50_vm_flush_engine(vm->dev, 6); - return; - } - - pfifo->tlb_flush(vm->dev); - for (i = 0; i < NVOBJ_ENGINE_NR; i++) { - if (atomic_read(&vm->engref[i])) - dev_priv->eng[i]->tlb_flush(vm->dev, i); - } -} - -void -nv50_vm_flush_engine(struct drm_device *dev, int engine) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->vm_lock, flags); - nv_wr32(dev, 0x100c80, (engine << 16) | 1); - if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) - NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); - spin_unlock_irqrestore(&dev_priv->vm_lock, flags); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vram.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vram.c deleted file mode 100644 index 9ed9ae39..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv50_vram.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_mm.h" - -static int types[0x80] = { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0 -}; - -bool -nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags) -{ - int type = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8; - - if (likely(type < ARRAY_SIZE(types) && types[type])) - return true; - return false; -} - -void -nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_mm *mm = &dev_priv->engine.vram.mm; - struct nouveau_mm_node *this; - struct nouveau_mem *mem; - - mem = *pmem; - *pmem = NULL; - if (unlikely(mem == NULL)) - return; - - mutex_lock(&mm->mutex); - while (!list_empty(&mem->regions)) { - this = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); - - list_del(&this->rl_entry); - nouveau_mm_put(mm, this); - } - - if (mem->tag) { - drm_mm_put_block(mem->tag); - mem->tag = NULL; - } - mutex_unlock(&mm->mutex); - - kfree(mem); -} - -int -nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc, - u32 memtype, struct nouveau_mem **pmem) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_mm *mm = &dev_priv->engine.vram.mm; - struct nouveau_mm_node *r; - struct nouveau_mem *mem; - int comp = (memtype & 0x300) >> 8; - int type = (memtype & 0x07f); - int ret; - - if (!types[type]) - return -EINVAL; - size >>= 12; - align >>= 12; - size_nc >>= 12; - - mem = kzalloc(sizeof(*mem), GFP_KERNEL); - if (!mem) - return -ENOMEM; - - mutex_lock(&mm->mutex); - if (comp) { - if (align == 16) { - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - int n = (size >> 4) * comp; - - mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0); - if (mem->tag) - mem->tag = drm_mm_get_block(mem->tag, n, 0); - } - - if (unlikely(!mem->tag)) - comp = 0; - } - - INIT_LIST_HEAD(&mem->regions); - mem->dev = dev_priv->dev; - mem->memtype = (comp << 7) | type; - mem->size = size; - - do { - ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r); - if (ret) { - mutex_unlock(&mm->mutex); - nv50_vram_del(dev, &mem); - return ret; - } - - list_add_tail(&r->rl_entry, &mem->regions); - size -= r->length; - } while (size); - mutex_unlock(&mm->mutex); - - r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); - mem->offset = (u64)r->offset << 12; - *pmem = mem; - return 0; -} - -static u32 -nv50_vram_rblock(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i, parts, colbits, rowbitsa, rowbitsb, banks; - u64 rowsize, predicted; - u32 r0, r4, rt, ru, rblock_size; - - r0 = nv_rd32(dev, 0x100200); - r4 = nv_rd32(dev, 0x100204); - rt = nv_rd32(dev, 0x100250); - ru = nv_rd32(dev, 0x001540); - NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru); - - for (i = 0, parts = 0; i < 8; i++) { - if (ru & (0x00010000 << i)) - parts++; - } - - colbits = (r4 & 0x0000f000) >> 12; - rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; - rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; - banks = 1 << (((r4 & 0x03000000) >> 24) + 2); - - rowsize = parts * banks * (1 << colbits) * 8; - predicted = rowsize << rowbitsa; - if (r0 & 0x00000004) - predicted += rowsize << rowbitsb; - - if (predicted != dev_priv->vram_size) { - NV_WARN(dev, "memory controller reports %dMiB VRAM\n", - (u32)(dev_priv->vram_size >> 20)); - NV_WARN(dev, "we calculated %dMiB VRAM\n", - (u32)(predicted >> 20)); - } - - rblock_size = rowsize; - if (rt & 1) - rblock_size *= 3; - - NV_DEBUG(dev, "rblock %d bytes\n", rblock_size); - return rblock_size; -} - -int -nv50_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ - const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ - u32 pfb714 = nv_rd32(dev, 0x100714); - u32 rblock, length; - - switch (pfb714 & 0x00000007) { - case 0: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; - case 1: - if (nouveau_mem_vbios_type(dev) == NV_MEM_TYPE_DDR3) - dev_priv->vram_type = NV_MEM_TYPE_DDR3; - else - dev_priv->vram_type = NV_MEM_TYPE_DDR2; - break; - case 2: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; - case 3: dev_priv->vram_type = NV_MEM_TYPE_GDDR4; break; - case 4: dev_priv->vram_type = NV_MEM_TYPE_GDDR5; break; - default: - break; - } - - dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x100200) & 0x4); - dev_priv->vram_size = nv_rd32(dev, 0x10020c); - dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; - dev_priv->vram_size &= 0xffffffff00ULL; - - /* IGPs, no funky reordering happens here, they don't have VRAM */ - if (dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac || - dev_priv->chipset == 0xaf) { - dev_priv->vram_sys_base = (u64)nv_rd32(dev, 0x100e10) << 12; - rblock = 4096 >> 12; - } else { - rblock = nv50_vram_rblock(dev) >> 12; - } - - length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail; - - return nouveau_mm_init(&vram->mm, rsvd_head, length, rblock); -} - -void -nv50_vram_fini(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - - nouveau_mm_fini(&vram->mm); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_bsp.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_bsp.c deleted file mode 100644 index 74875739..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_bsp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" - -/*XXX: This stub is currently used on NV98+ also, as soon as this becomes - * more than just an enable/disable stub this needs to be split out to - * nv98_bsp.c... - */ - -struct nv84_bsp_engine { - struct nouveau_exec_engine base; -}; - -static int -nv84_bsp_fini(struct drm_device *dev, int engine, bool suspend) -{ - if (!(nv_rd32(dev, 0x000200) & 0x00008000)) - return 0; - - nv_mask(dev, 0x000200, 0x00008000, 0x00000000); - return 0; -} - -static int -nv84_bsp_init(struct drm_device *dev, int engine) -{ - nv_mask(dev, 0x000200, 0x00008000, 0x00000000); - nv_mask(dev, 0x000200, 0x00008000, 0x00008000); - return 0; -} - -static void -nv84_bsp_destroy(struct drm_device *dev, int engine) -{ - struct nv84_bsp_engine *pbsp = nv_engine(dev, engine); - - NVOBJ_ENGINE_DEL(dev, BSP); - - kfree(pbsp); -} - -int -nv84_bsp_create(struct drm_device *dev) -{ - struct nv84_bsp_engine *pbsp; - - pbsp = kzalloc(sizeof(*pbsp), GFP_KERNEL); - if (!pbsp) - return -ENOMEM; - - pbsp->base.destroy = nv84_bsp_destroy; - pbsp->base.init = nv84_bsp_init; - pbsp->base.fini = nv84_bsp_fini; - - NVOBJ_ENGINE_ADD(dev, BSP, &pbsp->base); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_crypt.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_crypt.c deleted file mode 100644 index edece9c6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_crypt.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" - -struct nv84_crypt_engine { - struct nouveau_exec_engine base; -}; - -static int -nv84_crypt_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; - struct nouveau_gpuobj *ctx; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &ctx); - if (ret) - return ret; - - nv_wo32(ramin, 0xa0, 0x00190000); - nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1); - nv_wo32(ramin, 0xa8, ctx->vinst); - nv_wo32(ramin, 0xac, 0); - nv_wo32(ramin, 0xb0, 0); - nv_wo32(ramin, 0xb4, 0); - dev_priv->engine.instmem.flush(dev); - - atomic_inc(&chan->vm->engref[engine]); - chan->engctx[engine] = ctx; - return 0; -} - -static void -nv84_crypt_context_del(struct nouveau_channel *chan, int engine) -{ - struct nouveau_gpuobj *ctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - u32 inst; - - inst = (chan->ramin->vinst >> 12); - inst |= 0x80000000; - - /* mark context as invalid if still on the hardware, not - * doing this causes issues the next time PCRYPT is used, - * unsurprisingly :) - */ - nv_wr32(dev, 0x10200c, 0x00000000); - if (nv_rd32(dev, 0x102188) == inst) - nv_mask(dev, 0x102188, 0x80000000, 0x00000000); - if (nv_rd32(dev, 0x10218c) == inst) - nv_mask(dev, 0x10218c, 0x80000000, 0x00000000); - nv_wr32(dev, 0x10200c, 0x00000010); - - nouveau_gpuobj_ref(NULL, &ctx); - - atomic_dec(&chan->vm->engref[engine]); - chan->engctx[engine] = NULL; -} - -static int -nv84_crypt_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); - if (ret) - return ret; - obj->engine = 5; - obj->class = class; - - nv_wo32(obj, 0x00, class); - dev_priv->engine.instmem.flush(dev); - - ret = nouveau_ramht_insert(chan, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - -static void -nv84_crypt_tlb_flush(struct drm_device *dev, int engine) -{ - nv50_vm_flush_engine(dev, 0x0a); -} - -static void -nv84_crypt_isr(struct drm_device *dev) -{ - u32 stat = nv_rd32(dev, 0x102130); - u32 mthd = nv_rd32(dev, 0x102190); - u32 data = nv_rd32(dev, 0x102194); - u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff; - int show = nouveau_ratelimit(); - - if (show) { - NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n", - stat, mthd, data, inst); - } - - nv_wr32(dev, 0x102130, stat); - nv_wr32(dev, 0x10200c, 0x10); - - nv50_fb_vm_trap(dev, show); -} - -static int -nv84_crypt_fini(struct drm_device *dev, int engine, bool suspend) -{ - nv_wr32(dev, 0x102140, 0x00000000); - return 0; -} - -static int -nv84_crypt_init(struct drm_device *dev, int engine) -{ - nv_mask(dev, 0x000200, 0x00004000, 0x00000000); - nv_mask(dev, 0x000200, 0x00004000, 0x00004000); - - nv_wr32(dev, 0x102130, 0xffffffff); - nv_wr32(dev, 0x102140, 0xffffffbf); - - nv_wr32(dev, 0x10200c, 0x00000010); - return 0; -} - -static void -nv84_crypt_destroy(struct drm_device *dev, int engine) -{ - struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine); - - NVOBJ_ENGINE_DEL(dev, CRYPT); - - nouveau_irq_unregister(dev, 14); - kfree(pcrypt); -} - -int -nv84_crypt_create(struct drm_device *dev) -{ - struct nv84_crypt_engine *pcrypt; - - pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL); - if (!pcrypt) - return -ENOMEM; - - pcrypt->base.destroy = nv84_crypt_destroy; - pcrypt->base.init = nv84_crypt_init; - pcrypt->base.fini = nv84_crypt_fini; - pcrypt->base.context_new = nv84_crypt_context_new; - pcrypt->base.context_del = nv84_crypt_context_del; - pcrypt->base.object_new = nv84_crypt_object_new; - pcrypt->base.tlb_flush = nv84_crypt_tlb_flush; - - nouveau_irq_register(dev, 14, nv84_crypt_isr); - - NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base); - NVOBJ_CLASS (dev, 0x74c1, CRYPT); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_vp.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_vp.c deleted file mode 100644 index 6570d300..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv84_vp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" - -/*XXX: This stub is currently used on NV98+ also, as soon as this becomes - * more than just an enable/disable stub this needs to be split out to - * nv98_vp.c... - */ - -struct nv84_vp_engine { - struct nouveau_exec_engine base; -}; - -static int -nv84_vp_fini(struct drm_device *dev, int engine, bool suspend) -{ - if (!(nv_rd32(dev, 0x000200) & 0x00020000)) - return 0; - - nv_mask(dev, 0x000200, 0x00020000, 0x00000000); - return 0; -} - -static int -nv84_vp_init(struct drm_device *dev, int engine) -{ - nv_mask(dev, 0x000200, 0x00020000, 0x00000000); - nv_mask(dev, 0x000200, 0x00020000, 0x00020000); - return 0; -} - -static void -nv84_vp_destroy(struct drm_device *dev, int engine) -{ - struct nv84_vp_engine *pvp = nv_engine(dev, engine); - - NVOBJ_ENGINE_DEL(dev, VP); - - kfree(pvp); -} - -int -nv84_vp_create(struct drm_device *dev) -{ - struct nv84_vp_engine *pvp; - - pvp = kzalloc(sizeof(*pvp), GFP_KERNEL); - if (!pvp) - return -ENOMEM; - - pvp->base.destroy = nv84_vp_destroy; - pvp->base.init = nv84_vp_init; - pvp->base.fini = nv84_vp_fini; - - NVOBJ_ENGINE_ADD(dev, VP, &pvp->base); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_crypt.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_crypt.c deleted file mode 100644 index db94ff0a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_crypt.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" - -struct nv98_crypt_engine { - struct nouveau_exec_engine base; -}; - -static int -nv98_crypt_fini(struct drm_device *dev, int engine, bool suspend) -{ - if (!(nv_rd32(dev, 0x000200) & 0x00004000)) - return 0; - - nv_mask(dev, 0x000200, 0x00004000, 0x00000000); - return 0; -} - -static int -nv98_crypt_init(struct drm_device *dev, int engine) -{ - nv_mask(dev, 0x000200, 0x00004000, 0x00000000); - nv_mask(dev, 0x000200, 0x00004000, 0x00004000); - return 0; -} - -static void -nv98_crypt_destroy(struct drm_device *dev, int engine) -{ - struct nv98_crypt_engine *pcrypt = nv_engine(dev, engine); - - NVOBJ_ENGINE_DEL(dev, CRYPT); - - kfree(pcrypt); -} - -int -nv98_crypt_create(struct drm_device *dev) -{ - struct nv98_crypt_engine *pcrypt; - - pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL); - if (!pcrypt) - return -ENOMEM; - - pcrypt->base.destroy = nv98_crypt_destroy; - pcrypt->base.init = nv98_crypt_init; - pcrypt->base.fini = nv98_crypt_fini; - - NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_ppp.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_ppp.c deleted file mode 100644 index a987dd6e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nv98_ppp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" - -struct nv98_ppp_engine { - struct nouveau_exec_engine base; -}; - -static int -nv98_ppp_fini(struct drm_device *dev, int engine, bool suspend) -{ - if (!(nv_rd32(dev, 0x000200) & 0x00000002)) - return 0; - - nv_mask(dev, 0x000200, 0x00000002, 0x00000000); - return 0; -} - -static int -nv98_ppp_init(struct drm_device *dev, int engine) -{ - nv_mask(dev, 0x000200, 0x00000002, 0x00000000); - nv_mask(dev, 0x000200, 0x00000002, 0x00000002); - return 0; -} - -static void -nv98_ppp_destroy(struct drm_device *dev, int engine) -{ - struct nv98_ppp_engine *pppp = nv_engine(dev, engine); - - NVOBJ_ENGINE_DEL(dev, PPP); - - kfree(pppp); -} - -int -nv98_ppp_create(struct drm_device *dev) -{ - struct nv98_ppp_engine *pppp; - - pppp = kzalloc(sizeof(*pppp), GFP_KERNEL); - if (!pppp) - return -ENOMEM; - - pppp->base.destroy = nv98_ppp_destroy; - pppp->base.init = nv98_ppp_init; - pppp->base.fini = nv98_ppp_fini; - - NVOBJ_ENGINE_ADD(dev, PPP, &pppp->base); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.c deleted file mode 100644 index 8f356d58..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" -#include "nva3_copy.fuc.h" - -struct nva3_copy_engine { - struct nouveau_exec_engine base; -}; - -static int -nva3_copy_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; - struct nouveau_gpuobj *ctx = NULL; - int ret; - - NV_DEBUG(dev, "ch%d\n", chan->id); - - ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &ctx); - if (ret) - return ret; - - nv_wo32(ramin, 0xc0, 0x00190000); - nv_wo32(ramin, 0xc4, ctx->vinst + ctx->size - 1); - nv_wo32(ramin, 0xc8, ctx->vinst); - nv_wo32(ramin, 0xcc, 0x00000000); - nv_wo32(ramin, 0xd0, 0x00000000); - nv_wo32(ramin, 0xd4, 0x00000000); - dev_priv->engine.instmem.flush(dev); - - atomic_inc(&chan->vm->engref[engine]); - chan->engctx[engine] = ctx; - return 0; -} - -static int -nva3_copy_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - struct nouveau_gpuobj *ctx = chan->engctx[engine]; - - /* fuc engine doesn't need an object, our ramht code does.. */ - ctx->engine = 3; - ctx->class = class; - return nouveau_ramht_insert(chan, handle, ctx); -} - -static void -nva3_copy_context_del(struct nouveau_channel *chan, int engine) -{ - struct nouveau_gpuobj *ctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - u32 inst; - - inst = (chan->ramin->vinst >> 12); - inst |= 0x40000000; - - /* disable fifo access */ - nv_wr32(dev, 0x104048, 0x00000000); - /* mark channel as unloaded if it's currently active */ - if (nv_rd32(dev, 0x104050) == inst) - nv_mask(dev, 0x104050, 0x40000000, 0x00000000); - /* mark next channel as invalid if it's about to be loaded */ - if (nv_rd32(dev, 0x104054) == inst) - nv_mask(dev, 0x104054, 0x40000000, 0x00000000); - /* restore fifo access */ - nv_wr32(dev, 0x104048, 0x00000003); - - for (inst = 0xc0; inst <= 0xd4; inst += 4) - nv_wo32(chan->ramin, inst, 0x00000000); - - nouveau_gpuobj_ref(NULL, &ctx); - - atomic_dec(&chan->vm->engref[engine]); - chan->engctx[engine] = ctx; -} - -static void -nva3_copy_tlb_flush(struct drm_device *dev, int engine) -{ - nv50_vm_flush_engine(dev, 0x0d); -} - -static int -nva3_copy_init(struct drm_device *dev, int engine) -{ - int i; - - nv_mask(dev, 0x000200, 0x00002000, 0x00000000); - nv_mask(dev, 0x000200, 0x00002000, 0x00002000); - nv_wr32(dev, 0x104014, 0xffffffff); /* disable all interrupts */ - - /* upload ucode */ - nv_wr32(dev, 0x1041c0, 0x01000000); - for (i = 0; i < sizeof(nva3_pcopy_data) / 4; i++) - nv_wr32(dev, 0x1041c4, nva3_pcopy_data[i]); - - nv_wr32(dev, 0x104180, 0x01000000); - for (i = 0; i < sizeof(nva3_pcopy_code) / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(dev, 0x104188, i >> 6); - nv_wr32(dev, 0x104184, nva3_pcopy_code[i]); - } - - /* start it running */ - nv_wr32(dev, 0x10410c, 0x00000000); - nv_wr32(dev, 0x104104, 0x00000000); /* ENTRY */ - nv_wr32(dev, 0x104100, 0x00000002); /* TRIGGER */ - return 0; -} - -static int -nva3_copy_fini(struct drm_device *dev, int engine, bool suspend) -{ - nv_mask(dev, 0x104048, 0x00000003, 0x00000000); - - /* trigger fuc context unload */ - nv_wait(dev, 0x104008, 0x0000000c, 0x00000000); - nv_mask(dev, 0x104054, 0x40000000, 0x00000000); - nv_wr32(dev, 0x104000, 0x00000008); - nv_wait(dev, 0x104008, 0x00000008, 0x00000000); - - nv_wr32(dev, 0x104014, 0xffffffff); - return 0; -} - -static struct nouveau_enum nva3_copy_isr_error_name[] = { - { 0x0001, "ILLEGAL_MTHD" }, - { 0x0002, "INVALID_ENUM" }, - { 0x0003, "INVALID_BITFIELD" }, - {} -}; - -static void -nva3_copy_isr(struct drm_device *dev) -{ - u32 dispatch = nv_rd32(dev, 0x10401c); - u32 stat = nv_rd32(dev, 0x104008) & dispatch & ~(dispatch >> 16); - u32 inst = nv_rd32(dev, 0x104050) & 0x3fffffff; - u32 ssta = nv_rd32(dev, 0x104040) & 0x0000ffff; - u32 addr = nv_rd32(dev, 0x104040) >> 16; - u32 mthd = (addr & 0x07ff) << 2; - u32 subc = (addr & 0x3800) >> 11; - u32 data = nv_rd32(dev, 0x104044); - int chid = nv50_graph_isr_chid(dev, inst); - - if (stat & 0x00000040) { - NV_INFO(dev, "PCOPY: DISPATCH_ERROR ["); - nouveau_enum_print(nva3_copy_isr_error_name, ssta); - printk("] ch %d [0x%08x] subc %d mthd 0x%04x data 0x%08x\n", - chid, inst, subc, mthd, data); - nv_wr32(dev, 0x104004, 0x00000040); - stat &= ~0x00000040; - } - - if (stat) { - NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat); - nv_wr32(dev, 0x104004, stat); - } - nv50_fb_vm_trap(dev, 1); -} - -static void -nva3_copy_destroy(struct drm_device *dev, int engine) -{ - struct nva3_copy_engine *pcopy = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, 22); - - NVOBJ_ENGINE_DEL(dev, COPY0); - kfree(pcopy); -} - -int -nva3_copy_create(struct drm_device *dev) -{ - struct nva3_copy_engine *pcopy; - - pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL); - if (!pcopy) - return -ENOMEM; - - pcopy->base.destroy = nva3_copy_destroy; - pcopy->base.init = nva3_copy_init; - pcopy->base.fini = nva3_copy_fini; - pcopy->base.context_new = nva3_copy_context_new; - pcopy->base.context_del = nva3_copy_context_del; - pcopy->base.object_new = nva3_copy_object_new; - pcopy->base.tlb_flush = nva3_copy_tlb_flush; - - nouveau_irq_register(dev, 22, nva3_copy_isr); - - NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base); - NVOBJ_CLASS(dev, 0x85b5, COPY0); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc deleted file mode 100644 index abc36626..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc +++ /dev/null @@ -1,872 +0,0 @@ -/* fuc microcode for copy engine on nva3- chipsets - * - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -/* To build for nva3:nvc0 - * m4 -DNVA3 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nva3_copy.fuc.h - * - * To build for nvc0- - * m4 -DNVC0 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_copy.fuc.h - */ - -ifdef(`NVA3', -.section #nva3_pcopy_data -, -.section #nvc0_pcopy_data -) - -ctx_object: .b32 0 -ifdef(`NVA3', -ctx_dma: -ctx_dma_query: .b32 0 -ctx_dma_src: .b32 0 -ctx_dma_dst: .b32 0 -,) -.equ #ctx_dma_count 3 -ctx_query_address_high: .b32 0 -ctx_query_address_low: .b32 0 -ctx_query_counter: .b32 0 -ctx_src_address_high: .b32 0 -ctx_src_address_low: .b32 0 -ctx_src_pitch: .b32 0 -ctx_src_tile_mode: .b32 0 -ctx_src_xsize: .b32 0 -ctx_src_ysize: .b32 0 -ctx_src_zsize: .b32 0 -ctx_src_zoff: .b32 0 -ctx_src_xoff: .b32 0 -ctx_src_yoff: .b32 0 -ctx_src_cpp: .b32 0 -ctx_dst_address_high: .b32 0 -ctx_dst_address_low: .b32 0 -ctx_dst_pitch: .b32 0 -ctx_dst_tile_mode: .b32 0 -ctx_dst_xsize: .b32 0 -ctx_dst_ysize: .b32 0 -ctx_dst_zsize: .b32 0 -ctx_dst_zoff: .b32 0 -ctx_dst_xoff: .b32 0 -ctx_dst_yoff: .b32 0 -ctx_dst_cpp: .b32 0 -ctx_format: .b32 0 -ctx_swz_const0: .b32 0 -ctx_swz_const1: .b32 0 -ctx_xcnt: .b32 0 -ctx_ycnt: .b32 0 -.align 256 - -dispatch_table: -// mthd 0x0000, NAME -.b16 0x000 1 -.b32 #ctx_object ~0xffffffff -// mthd 0x0100, NOP -.b16 0x040 1 -.b32 0x00010000 + #cmd_nop ~0xffffffff -// mthd 0x0140, PM_TRIGGER -.b16 0x050 1 -.b32 0x00010000 + #cmd_pm_trigger ~0xffffffff -ifdef(`NVA3', ` -// mthd 0x0180-0x018c, DMA_ -.b16 0x060 #ctx_dma_count -dispatch_dma: -.b32 0x00010000 + #cmd_dma ~0xffffffff -.b32 0x00010000 + #cmd_dma ~0xffffffff -.b32 0x00010000 + #cmd_dma ~0xffffffff -',) -// mthd 0x0200-0x0218, SRC_TILE -.b16 0x80 7 -.b32 #ctx_src_tile_mode ~0x00000fff -.b32 #ctx_src_xsize ~0x0007ffff -.b32 #ctx_src_ysize ~0x00001fff -.b32 #ctx_src_zsize ~0x000007ff -.b32 #ctx_src_zoff ~0x00000fff -.b32 #ctx_src_xoff ~0x0007ffff -.b32 #ctx_src_yoff ~0x00001fff -// mthd 0x0220-0x0238, DST_TILE -.b16 0x88 7 -.b32 #ctx_dst_tile_mode ~0x00000fff -.b32 #ctx_dst_xsize ~0x0007ffff -.b32 #ctx_dst_ysize ~0x00001fff -.b32 #ctx_dst_zsize ~0x000007ff -.b32 #ctx_dst_zoff ~0x00000fff -.b32 #ctx_dst_xoff ~0x0007ffff -.b32 #ctx_dst_yoff ~0x00001fff -// mthd 0x0300-0x0304, EXEC, WRCACHE_FLUSH -.b16 0xc0 2 -.b32 0x00010000 + #cmd_exec ~0xffffffff -.b32 0x00010000 + #cmd_wrcache_flush ~0xffffffff -// mthd 0x030c-0x0340, various stuff -.b16 0xc3 14 -.b32 #ctx_src_address_high ~0x000000ff -.b32 #ctx_src_address_low ~0xfffffff0 -.b32 #ctx_dst_address_high ~0x000000ff -.b32 #ctx_dst_address_low ~0xfffffff0 -.b32 #ctx_src_pitch ~0x0007ffff -.b32 #ctx_dst_pitch ~0x0007ffff -.b32 #ctx_xcnt ~0x0000ffff -.b32 #ctx_ycnt ~0x00001fff -.b32 #ctx_format ~0x0333ffff -.b32 #ctx_swz_const0 ~0xffffffff -.b32 #ctx_swz_const1 ~0xffffffff -.b32 #ctx_query_address_high ~0x000000ff -.b32 #ctx_query_address_low ~0xffffffff -.b32 #ctx_query_counter ~0xffffffff -.b16 0x800 0 - -ifdef(`NVA3', -.section #nva3_pcopy_code -, -.section #nvc0_pcopy_code -) - -main: - clear b32 $r0 - mov $sp $r0 - - // setup i0 handler and route fifo and ctxswitch to it - mov $r1 #ih - mov $iv0 $r1 - mov $r1 0x400 - movw $r2 0xfff3 - sethi $r2 0 - iowr I[$r1 + 0x300] $r2 - - // enable interrupts - or $r2 0xc - iowr I[$r1] $r2 - bset $flags ie0 - - // enable fifo access and context switching - mov $r1 0x1200 - mov $r2 3 - iowr I[$r1] $r2 - - // sleep forever, waking for interrupts - bset $flags $p0 - spin: - sleep $p0 - bra #spin - -// i0 handler -ih: - iord $r1 I[$r0 + 0x200] - - and $r2 $r1 0x00000008 - bra e #ih_no_chsw - call #chsw - ih_no_chsw: - and $r2 $r1 0x00000004 - bra e #ih_no_cmd - call #dispatch - - ih_no_cmd: - and $r1 $r1 0x0000000c - iowr I[$r0 + 0x100] $r1 - iret - -// $p1 direction (0 = unload, 1 = load) -// $r3 channel -swctx: - mov $r4 0x7700 - mov $xtargets $r4 -ifdef(`NVA3', ` - // target 7 hardcoded to ctx dma object - mov $xdbase $r0 -', ` // NVC0 - // read SCRATCH3 to decide if we are PCOPY0 or PCOPY1 - mov $r4 0x2100 - iord $r4 I[$r4 + 0] - and $r4 1 - shl b32 $r4 4 - add b32 $r4 0x30 - - // channel is in vram - mov $r15 0x61c - shl b32 $r15 6 - mov $r5 0x114 - iowrs I[$r15] $r5 - - // read 16-byte PCOPYn info, containing context pointer, from channel - shl b32 $r5 $r3 4 - add b32 $r5 2 - mov $xdbase $r5 - mov $r5 $sp - // get a chunk of stack space, aligned to 256 byte boundary - sub b32 $r5 0x100 - mov $r6 0xff - not b32 $r6 - and $r5 $r6 - sethi $r5 0x00020000 - xdld $r4 $r5 - xdwait - sethi $r5 0 - - // set context pointer, from within channel VM - mov $r14 0 - iowrs I[$r15] $r14 - ld b32 $r4 D[$r5 + 0] - shr b32 $r4 8 - ld b32 $r6 D[$r5 + 4] - shl b32 $r6 24 - or $r4 $r6 - mov $xdbase $r4 -') - // 256-byte context, at start of data segment - mov b32 $r4 $r0 - sethi $r4 0x60000 - - // swap! - bra $p1 #swctx_load - xdst $r0 $r4 - bra #swctx_done - swctx_load: - xdld $r0 $r4 - swctx_done: - xdwait - ret - -chsw: - // read current channel - mov $r2 0x1400 - iord $r3 I[$r2] - - // if it's active, unload it and return - xbit $r15 $r3 0x1e - bra e #chsw_no_unload - bclr $flags $p1 - call #swctx - bclr $r3 0x1e - iowr I[$r2] $r3 - mov $r4 1 - iowr I[$r2 + 0x200] $r4 - ret - - // read next channel - chsw_no_unload: - iord $r3 I[$r2 + 0x100] - - // is there a channel waiting to be loaded? - xbit $r13 $r3 0x1e - bra e #chsw_finish_load - bset $flags $p1 - call #swctx -ifdef(`NVA3', - // load dma objects back into TARGET regs - mov $r5 #ctx_dma - mov $r6 #ctx_dma_count - chsw_load_ctx_dma: - ld b32 $r7 D[$r5 + $r6 * 4] - add b32 $r8 $r6 0x180 - shl b32 $r8 8 - iowr I[$r8] $r7 - sub b32 $r6 1 - bra nc #chsw_load_ctx_dma -,) - - chsw_finish_load: - mov $r3 2 - iowr I[$r2 + 0x200] $r3 - ret - -dispatch: - // read incoming fifo command - mov $r3 0x1900 - iord $r2 I[$r3 + 0x100] - iord $r3 I[$r3 + 0x000] - and $r4 $r2 0x7ff - // $r2 will be used to store exception data - shl b32 $r2 0x10 - - // lookup method in the dispatch table, ILLEGAL_MTHD if not found - mov $r5 #dispatch_table - clear b32 $r6 - clear b32 $r7 - dispatch_loop: - ld b16 $r6 D[$r5 + 0] - ld b16 $r7 D[$r5 + 2] - add b32 $r5 4 - cmpu b32 $r4 $r6 - bra c #dispatch_illegal_mthd - add b32 $r7 $r6 - cmpu b32 $r4 $r7 - bra c #dispatch_valid_mthd - sub b32 $r7 $r6 - shl b32 $r7 3 - add b32 $r5 $r7 - bra #dispatch_loop - - // ensure no bits set in reserved fields, INVALID_BITFIELD - dispatch_valid_mthd: - sub b32 $r4 $r6 - shl b32 $r4 3 - add b32 $r4 $r5 - ld b32 $r5 D[$r4 + 4] - and $r5 $r3 - cmpu b32 $r5 0 - bra ne #dispatch_invalid_bitfield - - // depending on dispatch flags: execute method, or save data as state - ld b16 $r5 D[$r4 + 0] - ld b16 $r6 D[$r4 + 2] - cmpu b32 $r6 0 - bra ne #dispatch_cmd - st b32 D[$r5] $r3 - bra #dispatch_done - dispatch_cmd: - bclr $flags $p1 - call $r5 - bra $p1 #dispatch_error - bra #dispatch_done - - dispatch_invalid_bitfield: - or $r2 2 - dispatch_illegal_mthd: - or $r2 1 - - // store exception data in SCRATCH0/SCRATCH1, signal hostirq - dispatch_error: - mov $r4 0x1000 - iowr I[$r4 + 0x000] $r2 - iowr I[$r4 + 0x100] $r3 - mov $r2 0x40 - iowr I[$r0] $r2 - hostirq_wait: - iord $r2 I[$r0 + 0x200] - and $r2 0x40 - cmpu b32 $r2 0 - bra ne #hostirq_wait - - dispatch_done: - mov $r2 0x1d00 - mov $r3 1 - iowr I[$r2] $r3 - ret - -// No-operation -// -// Inputs: -// $r1: irqh state -// $r2: hostirq state -// $r3: data -// $r4: dispatch table entry -// Outputs: -// $r1: irqh state -// $p1: set on error -// $r2: hostirq state -// $r3: data -cmd_nop: - ret - -// PM_TRIGGER -// -// Inputs: -// $r1: irqh state -// $r2: hostirq state -// $r3: data -// $r4: dispatch table entry -// Outputs: -// $r1: irqh state -// $p1: set on error -// $r2: hostirq state -// $r3: data -cmd_pm_trigger: - mov $r2 0x2200 - clear b32 $r3 - sethi $r3 0x20000 - iowr I[$r2] $r3 - ret - -ifdef(`NVA3', -// SET_DMA_* method handler -// -// Inputs: -// $r1: irqh state -// $r2: hostirq state -// $r3: data -// $r4: dispatch table entry -// Outputs: -// $r1: irqh state -// $p1: set on error -// $r2: hostirq state -// $r3: data -cmd_dma: - sub b32 $r4 #dispatch_dma - shr b32 $r4 1 - bset $r3 0x1e - st b32 D[$r4 + #ctx_dma] $r3 - add b32 $r4 0x600 - shl b32 $r4 6 - iowr I[$r4] $r3 - ret -,) - -// Calculates the hw swizzle mask and adjusts the surface's xcnt to match -// -cmd_exec_set_format: - // zero out a chunk of the stack to store the swizzle into - add $sp -0x10 - st b32 D[$sp + 0x00] $r0 - st b32 D[$sp + 0x04] $r0 - st b32 D[$sp + 0x08] $r0 - st b32 D[$sp + 0x0c] $r0 - - // extract cpp, src_ncomp and dst_ncomp from FORMAT - ld b32 $r4 D[$r0 + #ctx_format] - extr $r5 $r4 16:17 - add b32 $r5 1 - extr $r6 $r4 20:21 - add b32 $r6 1 - extr $r7 $r4 24:25 - add b32 $r7 1 - - // convert FORMAT swizzle mask to hw swizzle mask - bclr $flags $p2 - clear b32 $r8 - clear b32 $r9 - ncomp_loop: - and $r10 $r4 0xf - shr b32 $r4 4 - clear b32 $r11 - bpc_loop: - cmpu b8 $r10 4 - bra nc #cmp_c0 - mulu $r12 $r10 $r5 - add b32 $r12 $r11 - bset $flags $p2 - bra #bpc_next - cmp_c0: - bra ne #cmp_c1 - mov $r12 0x10 - add b32 $r12 $r11 - bra #bpc_next - cmp_c1: - cmpu b8 $r10 6 - bra nc #cmp_zero - mov $r12 0x14 - add b32 $r12 $r11 - bra #bpc_next - cmp_zero: - mov $r12 0x80 - bpc_next: - st b8 D[$sp + $r8] $r12 - add b32 $r8 1 - add b32 $r11 1 - cmpu b32 $r11 $r5 - bra c #bpc_loop - add b32 $r9 1 - cmpu b32 $r9 $r7 - bra c #ncomp_loop - - // SRC_XCNT = (xcnt * src_cpp), or 0 if no src ref in swz (hw will hang) - mulu $r6 $r5 - st b32 D[$r0 + #ctx_src_cpp] $r6 - ld b32 $r8 D[$r0 + #ctx_xcnt] - mulu $r6 $r8 - bra $p2 #dst_xcnt - clear b32 $r6 - - dst_xcnt: - mulu $r7 $r5 - st b32 D[$r0 + #ctx_dst_cpp] $r7 - mulu $r7 $r8 - - mov $r5 0x810 - shl b32 $r5 6 - iowr I[$r5 + 0x000] $r6 - iowr I[$r5 + 0x100] $r7 - add b32 $r5 0x800 - ld b32 $r6 D[$r0 + #ctx_dst_cpp] - sub b32 $r6 1 - shl b32 $r6 8 - ld b32 $r7 D[$r0 + #ctx_src_cpp] - sub b32 $r7 1 - or $r6 $r7 - iowr I[$r5 + 0x000] $r6 - add b32 $r5 0x100 - ld b32 $r6 D[$sp + 0x00] - iowr I[$r5 + 0x000] $r6 - ld b32 $r6 D[$sp + 0x04] - iowr I[$r5 + 0x100] $r6 - ld b32 $r6 D[$sp + 0x08] - iowr I[$r5 + 0x200] $r6 - ld b32 $r6 D[$sp + 0x0c] - iowr I[$r5 + 0x300] $r6 - add b32 $r5 0x400 - ld b32 $r6 D[$r0 + #ctx_swz_const0] - iowr I[$r5 + 0x000] $r6 - ld b32 $r6 D[$r0 + #ctx_swz_const1] - iowr I[$r5 + 0x100] $r6 - add $sp 0x10 - ret - -// Setup to handle a tiled surface -// -// Calculates a number of parameters the hardware requires in order -// to correctly handle tiling. -// -// Offset calculation is performed as follows (Tp/Th/Td from TILE_MODE): -// nTx = round_up(w * cpp, 1 << Tp) >> Tp -// nTy = round_up(h, 1 << Th) >> Th -// Txo = (x * cpp) & ((1 << Tp) - 1) -// Tx = (x * cpp) >> Tp -// Tyo = y & ((1 << Th) - 1) -// Ty = y >> Th -// Tzo = z & ((1 << Td) - 1) -// Tz = z >> Td -// -// off = (Tzo << Tp << Th) + (Tyo << Tp) + Txo -// off += ((Tz * nTy * nTx)) + (Ty * nTx) + Tx) << Td << Th << Tp; -// -// Inputs: -// $r4: hw command (0x104800) -// $r5: ctx offset adjustment for src/dst selection -// $p2: set if dst surface -// -cmd_exec_set_surface_tiled: - // translate TILE_MODE into Tp, Th, Td shift values - ld b32 $r7 D[$r5 + #ctx_src_tile_mode] - extr $r9 $r7 8:11 - extr $r8 $r7 4:7 -ifdef(`NVA3', - add b32 $r8 2 -, - add b32 $r8 3 -) - extr $r7 $r7 0:3 - cmp b32 $r7 0xe - bra ne #xtile64 - mov $r7 4 - bra #xtileok - xtile64: - xbit $r7 $flags $p2 - add b32 $r7 17 - bset $r4 $r7 - mov $r7 6 - xtileok: - - // Op = (x * cpp) & ((1 << Tp) - 1) - // Tx = (x * cpp) >> Tp - ld b32 $r10 D[$r5 + #ctx_src_xoff] - ld b32 $r11 D[$r5 + #ctx_src_cpp] - mulu $r10 $r11 - mov $r11 1 - shl b32 $r11 $r7 - sub b32 $r11 1 - and $r12 $r10 $r11 - shr b32 $r10 $r7 - - // Tyo = y & ((1 << Th) - 1) - // Ty = y >> Th - ld b32 $r13 D[$r5 + #ctx_src_yoff] - mov $r14 1 - shl b32 $r14 $r8 - sub b32 $r14 1 - and $r11 $r13 $r14 - shr b32 $r13 $r8 - - // YTILE = ((1 << Th) << 12) | ((1 << Th) - Tyo) - add b32 $r14 1 - shl b32 $r15 $r14 12 - sub b32 $r14 $r11 - or $r15 $r14 - xbit $r6 $flags $p2 - add b32 $r6 0x208 - shl b32 $r6 8 - iowr I[$r6 + 0x000] $r15 - - // Op += Tyo << Tp - shl b32 $r11 $r7 - add b32 $r12 $r11 - - // nTx = ((w * cpp) + ((1 << Tp) - 1) >> Tp) - ld b32 $r15 D[$r5 + #ctx_src_xsize] - ld b32 $r11 D[$r5 + #ctx_src_cpp] - mulu $r15 $r11 - mov $r11 1 - shl b32 $r11 $r7 - sub b32 $r11 1 - add b32 $r15 $r11 - shr b32 $r15 $r7 - push $r15 - - // nTy = (h + ((1 << Th) - 1)) >> Th - ld b32 $r15 D[$r5 + #ctx_src_ysize] - mov $r11 1 - shl b32 $r11 $r8 - sub b32 $r11 1 - add b32 $r15 $r11 - shr b32 $r15 $r8 - push $r15 - - // Tys = Tp + Th - // CFG_YZ_TILE_SIZE = ((1 << Th) >> 2) << Td - add b32 $r7 $r8 - sub b32 $r8 2 - mov $r11 1 - shl b32 $r11 $r8 - shl b32 $r11 $r9 - - // Tzo = z & ((1 << Td) - 1) - // Tz = z >> Td - // Op += Tzo << Tys - // Ts = Tys + Td - ld b32 $r8 D[$r5 + #ctx_src_zoff] - mov $r14 1 - shl b32 $r14 $r9 - sub b32 $r14 1 - and $r15 $r8 $r14 - shl b32 $r15 $r7 - add b32 $r12 $r15 - add b32 $r7 $r9 - shr b32 $r8 $r9 - - // Ot = ((Tz * nTy * nTx) + (Ty * nTx) + Tx) << Ts - pop $r15 - pop $r9 - mulu $r13 $r9 - add b32 $r10 $r13 - mulu $r8 $r9 - mulu $r8 $r15 - add b32 $r10 $r8 - shl b32 $r10 $r7 - - // PITCH = (nTx - 1) << Ts - sub b32 $r9 1 - shl b32 $r9 $r7 - iowr I[$r6 + 0x200] $r9 - - // SRC_ADDRESS_LOW = (Ot + Op) & 0xffffffff - // CFG_ADDRESS_HIGH |= ((Ot + Op) >> 32) << 16 - ld b32 $r7 D[$r5 + #ctx_src_address_low] - ld b32 $r8 D[$r5 + #ctx_src_address_high] - add b32 $r10 $r12 - add b32 $r7 $r10 - adc b32 $r8 0 - shl b32 $r8 16 - or $r8 $r11 - sub b32 $r6 0x600 - iowr I[$r6 + 0x000] $r7 - add b32 $r6 0x400 - iowr I[$r6 + 0x000] $r8 - ret - -// Setup to handle a linear surface -// -// Nothing to see here.. Sets ADDRESS and PITCH, pretty non-exciting -// -cmd_exec_set_surface_linear: - xbit $r6 $flags $p2 - add b32 $r6 0x202 - shl b32 $r6 8 - ld b32 $r7 D[$r5 + #ctx_src_address_low] - iowr I[$r6 + 0x000] $r7 - add b32 $r6 0x400 - ld b32 $r7 D[$r5 + #ctx_src_address_high] - shl b32 $r7 16 - iowr I[$r6 + 0x000] $r7 - add b32 $r6 0x400 - ld b32 $r7 D[$r5 + #ctx_src_pitch] - iowr I[$r6 + 0x000] $r7 - ret - -// wait for regs to be available for use -cmd_exec_wait: - push $r0 - push $r1 - mov $r0 0x800 - shl b32 $r0 6 - loop: - iord $r1 I[$r0] - and $r1 1 - bra ne #loop - pop $r1 - pop $r0 - ret - -cmd_exec_query: - // if QUERY_SHORT not set, write out { -, 0, TIME_LO, TIME_HI } - xbit $r4 $r3 13 - bra ne #query_counter - call #cmd_exec_wait - mov $r4 0x80c - shl b32 $r4 6 - ld b32 $r5 D[$r0 + #ctx_query_address_low] - add b32 $r5 4 - iowr I[$r4 + 0x000] $r5 - iowr I[$r4 + 0x100] $r0 - mov $r5 0xc - iowr I[$r4 + 0x200] $r5 - add b32 $r4 0x400 - ld b32 $r5 D[$r0 + #ctx_query_address_high] - shl b32 $r5 16 - iowr I[$r4 + 0x000] $r5 - add b32 $r4 0x500 - mov $r5 0x00000b00 - sethi $r5 0x00010000 - iowr I[$r4 + 0x000] $r5 - mov $r5 0x00004040 - shl b32 $r5 1 - sethi $r5 0x80800000 - iowr I[$r4 + 0x100] $r5 - mov $r5 0x00001110 - sethi $r5 0x13120000 - iowr I[$r4 + 0x200] $r5 - mov $r5 0x00001514 - sethi $r5 0x17160000 - iowr I[$r4 + 0x300] $r5 - mov $r5 0x00002601 - sethi $r5 0x00010000 - mov $r4 0x800 - shl b32 $r4 6 - iowr I[$r4 + 0x000] $r5 - - // write COUNTER - query_counter: - call #cmd_exec_wait - mov $r4 0x80c - shl b32 $r4 6 - ld b32 $r5 D[$r0 + #ctx_query_address_low] - iowr I[$r4 + 0x000] $r5 - iowr I[$r4 + 0x100] $r0 - mov $r5 0x4 - iowr I[$r4 + 0x200] $r5 - add b32 $r4 0x400 - ld b32 $r5 D[$r0 + #ctx_query_address_high] - shl b32 $r5 16 - iowr I[$r4 + 0x000] $r5 - add b32 $r4 0x500 - mov $r5 0x00000300 - iowr I[$r4 + 0x000] $r5 - mov $r5 0x00001110 - sethi $r5 0x13120000 - iowr I[$r4 + 0x100] $r5 - ld b32 $r5 D[$r0 + #ctx_query_counter] - add b32 $r4 0x500 - iowr I[$r4 + 0x000] $r5 - mov $r5 0x00002601 - sethi $r5 0x00010000 - mov $r4 0x800 - shl b32 $r4 6 - iowr I[$r4 + 0x000] $r5 - ret - -// Execute a copy operation -// -// Inputs: -// $r1: irqh state -// $r2: hostirq state -// $r3: data -// 000002000 QUERY_SHORT -// 000001000 QUERY -// 000000100 DST_LINEAR -// 000000010 SRC_LINEAR -// 000000001 FORMAT -// $r4: dispatch table entry -// Outputs: -// $r1: irqh state -// $p1: set on error -// $r2: hostirq state -// $r3: data -cmd_exec: - call #cmd_exec_wait - - // if format requested, call function to calculate it, otherwise - // fill in cpp/xcnt for both surfaces as if (cpp == 1) - xbit $r15 $r3 0 - bra e #cmd_exec_no_format - call #cmd_exec_set_format - mov $r4 0x200 - bra #cmd_exec_init_src_surface - cmd_exec_no_format: - mov $r6 0x810 - shl b32 $r6 6 - mov $r7 1 - st b32 D[$r0 + #ctx_src_cpp] $r7 - st b32 D[$r0 + #ctx_dst_cpp] $r7 - ld b32 $r7 D[$r0 + #ctx_xcnt] - iowr I[$r6 + 0x000] $r7 - iowr I[$r6 + 0x100] $r7 - clear b32 $r4 - - cmd_exec_init_src_surface: - bclr $flags $p2 - clear b32 $r5 - xbit $r15 $r3 4 - bra e #src_tiled - call #cmd_exec_set_surface_linear - bra #cmd_exec_init_dst_surface - src_tiled: - call #cmd_exec_set_surface_tiled - bset $r4 7 - - cmd_exec_init_dst_surface: - bset $flags $p2 - mov $r5 #ctx_dst_address_high - #ctx_src_address_high - xbit $r15 $r3 8 - bra e #dst_tiled - call #cmd_exec_set_surface_linear - bra #cmd_exec_kick - dst_tiled: - call #cmd_exec_set_surface_tiled - bset $r4 8 - - cmd_exec_kick: - mov $r5 0x800 - shl b32 $r5 6 - ld b32 $r6 D[$r0 + #ctx_ycnt] - iowr I[$r5 + 0x100] $r6 - mov $r6 0x0041 - // SRC_TARGET = 1, DST_TARGET = 2 - sethi $r6 0x44000000 - or $r4 $r6 - iowr I[$r5] $r4 - - // if requested, queue up a QUERY write after the copy has completed - xbit $r15 $r3 12 - bra e #cmd_exec_done - call #cmd_exec_query - - cmd_exec_done: - ret - -// Flush write cache -// -// Inputs: -// $r1: irqh state -// $r2: hostirq state -// $r3: data -// $r4: dispatch table entry -// Outputs: -// $r1: irqh state -// $p1: set on error -// $r2: hostirq state -// $r3: data -cmd_wrcache_flush: - mov $r2 0x2200 - clear b32 $r3 - sethi $r3 0x10000 - iowr I[$r2] $r3 - ret - -.align 0x100 diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc.h deleted file mode 100644 index 1f33fbdc..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_copy.fuc.h +++ /dev/null @@ -1,534 +0,0 @@ -uint32_t nva3_pcopy_data[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00010000, - 0x00000000, - 0x00000000, - 0x00010040, - 0x00010160, - 0x00000000, - 0x00010050, - 0x00010162, - 0x00000000, - 0x00030060, - 0x00010170, - 0x00000000, - 0x00010170, - 0x00000000, - 0x00010170, - 0x00000000, - 0x00070080, - 0x00000028, - 0xfffff000, - 0x0000002c, - 0xfff80000, - 0x00000030, - 0xffffe000, - 0x00000034, - 0xfffff800, - 0x00000038, - 0xfffff000, - 0x0000003c, - 0xfff80000, - 0x00000040, - 0xffffe000, - 0x00070088, - 0x00000054, - 0xfffff000, - 0x00000058, - 0xfff80000, - 0x0000005c, - 0xffffe000, - 0x00000060, - 0xfffff800, - 0x00000064, - 0xfffff000, - 0x00000068, - 0xfff80000, - 0x0000006c, - 0xffffe000, - 0x000200c0, - 0x00010492, - 0x00000000, - 0x0001051b, - 0x00000000, - 0x000e00c3, - 0x0000001c, - 0xffffff00, - 0x00000020, - 0x0000000f, - 0x00000048, - 0xffffff00, - 0x0000004c, - 0x0000000f, - 0x00000024, - 0xfff80000, - 0x00000050, - 0xfff80000, - 0x00000080, - 0xffff0000, - 0x00000084, - 0xffffe000, - 0x00000074, - 0xfccc0000, - 0x00000078, - 0x00000000, - 0x0000007c, - 0x00000000, - 0x00000010, - 0xffffff00, - 0x00000014, - 0x00000000, - 0x00000018, - 0x00000000, - 0x00000800, -}; - -uint32_t nva3_pcopy_code[] = { - 0x04fe04bd, - 0x3517f000, - 0xf10010fe, - 0xf1040017, - 0xf0fff327, - 0x12d00023, - 0x0c25f0c0, - 0xf40012d0, - 0x17f11031, - 0x27f01200, - 0x0012d003, - 0xf40031f4, - 0x0ef40028, - 0x8001cffd, - 0xf40812c4, - 0x21f4060b, - 0x0412c472, - 0xf4060bf4, - 0x11c4c321, - 0x4001d00c, - 0x47f101f8, - 0x4bfe7700, - 0x0007fe00, - 0xf00204b9, - 0x01f40643, - 0x0604fa09, - 0xfa060ef4, - 0x03f80504, - 0x27f100f8, - 0x23cf1400, - 0x1e3fc800, - 0xf4170bf4, - 0x21f40132, - 0x1e3af052, - 0xf00023d0, - 0x24d00147, - 0xcf00f880, - 0x3dc84023, - 0x220bf41e, - 0xf40131f4, - 0x57f05221, - 0x0367f004, - 0xa07856bc, - 0xb6018068, - 0x87d00884, - 0x0162b600, - 0xf0f018f4, - 0x23d00237, - 0xf100f880, - 0xcf190037, - 0x33cf4032, - 0xff24e400, - 0x1024b607, - 0x010057f1, - 0x74bd64bd, - 0x58005658, - 0x50b60157, - 0x0446b804, - 0xbb4d08f4, - 0x47b80076, - 0x0f08f404, - 0xb60276bb, - 0x57bb0374, - 0xdf0ef400, - 0xb60246bb, - 0x45bb0344, - 0x01459800, - 0xb00453fd, - 0x1bf40054, - 0x00455820, - 0xb0014658, - 0x1bf40064, - 0x00538009, - 0xf4300ef4, - 0x55f90132, - 0xf40c01f4, - 0x25f0250e, - 0x0125f002, - 0x100047f1, - 0xd00042d0, - 0x27f04043, - 0x0002d040, - 0xf08002cf, - 0x24b04024, - 0xf71bf400, - 0x1d0027f1, - 0xd00137f0, - 0x00f80023, - 0x27f100f8, - 0x34bd2200, - 0xd00233f0, - 0x00f80023, - 0x012842b7, - 0xf00145b6, - 0x43801e39, - 0x0040b701, - 0x0644b606, - 0xf80043d0, - 0xf030f400, - 0xb00001b0, - 0x01b00101, - 0x0301b002, - 0xc71d0498, - 0x50b63045, - 0x3446c701, - 0xc70160b6, - 0x70b63847, - 0x0232f401, - 0x94bd84bd, - 0xb60f4ac4, - 0xb4bd0445, - 0xf404a430, - 0xa5ff0f18, - 0x00cbbbc0, - 0xf40231f4, - 0x1bf4220e, - 0x10c7f00c, - 0xf400cbbb, - 0xa430160e, - 0x0c18f406, - 0xbb14c7f0, - 0x0ef400cb, - 0x80c7f107, - 0x01c83800, - 0xb60180b6, - 0xb5b801b0, - 0xc308f404, - 0xb80190b6, - 0x08f40497, - 0x0065fdb2, - 0x98110680, - 0x68fd2008, - 0x0502f400, - 0x75fd64bd, - 0x1c078000, - 0xf10078fd, - 0xb6081057, - 0x56d00654, - 0x4057d000, - 0x080050b7, - 0xb61c0698, - 0x64b60162, - 0x11079808, - 0xfd0172b6, - 0x56d00567, - 0x0050b700, - 0x0060b401, - 0xb40056d0, - 0x56d00160, - 0x0260b440, - 0xb48056d0, - 0x56d00360, - 0x0050b7c0, - 0x1e069804, - 0x980056d0, - 0x56d01f06, - 0x1030f440, - 0x579800f8, - 0x6879c70a, - 0xb66478c7, - 0x77c70280, - 0x0e76b060, - 0xf0091bf4, - 0x0ef40477, - 0x027cf00f, - 0xfd1170b6, - 0x77f00947, - 0x0f5a9806, - 0xfd115b98, - 0xb7f000ab, - 0x04b7bb01, - 0xff01b2b6, - 0xa7bbc4ab, - 0x105d9805, - 0xbb01e7f0, - 0xe2b604e8, - 0xb4deff01, - 0xb605d8bb, - 0xef9401e0, - 0x02ebbb0c, - 0xf005fefd, - 0x60b7026c, - 0x64b60208, - 0x006fd008, - 0xbb04b7bb, - 0x5f9800cb, - 0x115b980b, - 0xf000fbfd, - 0xb7bb01b7, - 0x01b2b604, - 0xbb00fbbb, - 0xf0f905f7, - 0xf00c5f98, - 0xb8bb01b7, - 0x01b2b604, - 0xbb00fbbb, - 0xf0f905f8, - 0xb60078bb, - 0xb7f00282, - 0x04b8bb01, - 0x9804b9bb, - 0xe7f00e58, - 0x04e9bb01, - 0xff01e2b6, - 0xf7bbf48e, - 0x00cfbb04, - 0xbb0079bb, - 0xf0fc0589, - 0xd9fd90fc, - 0x00adbb00, - 0xfd0089fd, - 0xa8bb008f, - 0x04a7bb00, - 0xbb0192b6, - 0x69d00497, - 0x08579880, - 0xbb075898, - 0x7abb00ac, - 0x0081b600, - 0xfd1084b6, - 0x62b7058b, - 0x67d00600, - 0x0060b700, - 0x0068d004, - 0x6cf000f8, - 0x0260b702, - 0x0864b602, - 0xd0085798, - 0x60b70067, - 0x57980400, - 0x1074b607, - 0xb70067d0, - 0x98040060, - 0x67d00957, - 0xf900f800, - 0xf110f900, - 0xb6080007, - 0x01cf0604, - 0x0114f000, - 0xfcfa1bf4, - 0xf800fc10, - 0x0d34c800, - 0xf5701bf4, - 0xf103ab21, - 0xb6080c47, - 0x05980644, - 0x0450b605, - 0xd00045d0, - 0x57f04040, - 0x8045d00c, - 0x040040b7, - 0xb6040598, - 0x45d01054, - 0x0040b700, - 0x0057f105, - 0x0153f00b, - 0xf10045d0, - 0xb6404057, - 0x53f10154, - 0x45d08080, - 0x1057f140, - 0x1253f111, - 0x8045d013, - 0x151457f1, - 0x171653f1, - 0xf1c045d0, - 0xf0260157, - 0x47f10153, - 0x44b60800, - 0x0045d006, - 0x03ab21f5, - 0x080c47f1, - 0x980644b6, - 0x45d00505, - 0x4040d000, - 0xd00457f0, - 0x40b78045, - 0x05980400, - 0x1054b604, - 0xb70045d0, - 0xf1050040, - 0xd0030057, - 0x57f10045, - 0x53f11110, - 0x45d01312, - 0x06059840, - 0x050040b7, - 0xf10045d0, - 0xf0260157, - 0x47f10153, - 0x44b60800, - 0x0045d006, - 0x21f500f8, - 0x3fc803ab, - 0x0e0bf400, - 0x018921f5, - 0x020047f1, - 0xf11e0ef4, - 0xb6081067, - 0x77f00664, - 0x11078001, - 0x981c0780, - 0x67d02007, - 0x4067d000, - 0x32f444bd, - 0xc854bd02, - 0x0bf4043f, - 0x8221f50a, - 0x0a0ef403, - 0x027621f5, - 0xf40749f0, - 0x57f00231, - 0x083fc82c, - 0xf50a0bf4, - 0xf4038221, - 0x21f50a0e, - 0x49f00276, - 0x0057f108, - 0x0654b608, - 0xd0210698, - 0x67f04056, - 0x0063f141, - 0x0546fd44, - 0xc80054d0, - 0x0bf40c3f, - 0xc521f507, - 0xf100f803, - 0xbd220027, - 0x0133f034, - 0xf80023d0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_pm.c deleted file mode 100644 index 9e636e6e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nva3_pm.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_bios.h" -#include "nouveau_pm.h" - -static u32 read_clk(struct drm_device *, int, bool); -static u32 read_pll(struct drm_device *, int, u32); - -static u32 -read_vco(struct drm_device *dev, int clk) -{ - u32 sctl = nv_rd32(dev, 0x4120 + (clk * 4)); - if ((sctl & 0x00000030) != 0x00000030) - return read_pll(dev, 0x41, 0x00e820); - return read_pll(dev, 0x42, 0x00e8a0); -} - -static u32 -read_clk(struct drm_device *dev, int clk, bool ignore_en) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 sctl, sdiv, sclk; - - /* refclk for the 0xe8xx plls is a fixed frequency */ - if (clk >= 0x40) { - if (dev_priv->chipset == 0xaf) { - /* no joke.. seriously.. sigh.. */ - return nv_rd32(dev, 0x00471c) * 1000; - } - - return dev_priv->crystal; - } - - sctl = nv_rd32(dev, 0x4120 + (clk * 4)); - if (!ignore_en && !(sctl & 0x00000100)) - return 0; - - switch (sctl & 0x00003000) { - case 0x00000000: - return dev_priv->crystal; - case 0x00002000: - if (sctl & 0x00000040) - return 108000; - return 100000; - case 0x00003000: - sclk = read_vco(dev, clk); - sdiv = ((sctl & 0x003f0000) >> 16) + 2; - return (sclk * 2) / sdiv; - default: - return 0; - } -} - -static u32 -read_pll(struct drm_device *dev, int clk, u32 pll) -{ - u32 ctrl = nv_rd32(dev, pll + 0); - u32 sclk = 0, P = 1, N = 1, M = 1; - - if (!(ctrl & 0x00000008)) { - if (ctrl & 0x00000001) { - u32 coef = nv_rd32(dev, pll + 4); - M = (coef & 0x000000ff) >> 0; - N = (coef & 0x0000ff00) >> 8; - P = (coef & 0x003f0000) >> 16; - - /* no post-divider on these.. */ - if ((pll & 0x00ff00) == 0x00e800) - P = 1; - - sclk = read_clk(dev, 0x00 + clk, false); - } - } else { - sclk = read_clk(dev, 0x10 + clk, false); - } - - return sclk * N / (M * P); -} - -struct creg { - u32 clk; - u32 pll; -}; - -static int -calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg) -{ - struct pll_lims limits; - u32 oclk, sclk, sdiv; - int P, N, M, diff; - int ret; - - reg->pll = 0; - reg->clk = 0; - if (!khz) { - NV_DEBUG(dev, "no clock for 0x%04x/0x%02x\n", pll, clk); - return 0; - } - - switch (khz) { - case 27000: - reg->clk = 0x00000100; - return khz; - case 100000: - reg->clk = 0x00002100; - return khz; - case 108000: - reg->clk = 0x00002140; - return khz; - default: - sclk = read_vco(dev, clk); - sdiv = min((sclk * 2) / (khz - 2999), (u32)65); - /* if the clock has a PLL attached, and we can get a within - * [-2, 3) MHz of a divider, we'll disable the PLL and use - * the divider instead. - * - * divider can go as low as 2, limited here because NVIDIA - * and the VBIOS on my NVA8 seem to prefer using the PLL - * for 810MHz - is there a good reason? - */ - if (sdiv > 4) { - oclk = (sclk * 2) / sdiv; - diff = khz - oclk; - if (!pll || (diff >= -2000 && diff < 3000)) { - reg->clk = (((sdiv - 2) << 16) | 0x00003100); - return oclk; - } - } - - if (!pll) { - NV_ERROR(dev, "bad freq %02x: %d %d\n", clk, khz, sclk); - return -ERANGE; - } - - break; - } - - ret = get_pll_limits(dev, pll, &limits); - if (ret) - return ret; - - limits.refclk = read_clk(dev, clk - 0x10, true); - if (!limits.refclk) - return -EINVAL; - - ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P); - if (ret >= 0) { - reg->clk = nv_rd32(dev, 0x4120 + (clk * 4)); - reg->pll = (P << 16) | (N << 8) | M; - } - return ret; -} - -static void -prog_pll(struct drm_device *dev, int clk, u32 pll, struct creg *reg) -{ - const u32 src0 = 0x004120 + (clk * 4); - const u32 src1 = 0x004160 + (clk * 4); - const u32 ctrl = pll + 0; - const u32 coef = pll + 4; - u32 cntl; - - if (!reg->clk && !reg->pll) { - NV_DEBUG(dev, "no clock for %02x\n", clk); - return; - } - - cntl = nv_rd32(dev, ctrl) & 0xfffffff2; - if (reg->pll) { - nv_mask(dev, src0, 0x00000101, 0x00000101); - nv_wr32(dev, coef, reg->pll); - nv_wr32(dev, ctrl, cntl | 0x00000015); - nv_mask(dev, src1, 0x00000100, 0x00000000); - nv_mask(dev, src1, 0x00000001, 0x00000000); - } else { - nv_mask(dev, src1, 0x003f3141, 0x00000101 | reg->clk); - nv_wr32(dev, ctrl, cntl | 0x0000001d); - nv_mask(dev, ctrl, 0x00000001, 0x00000000); - nv_mask(dev, src0, 0x00000100, 0x00000000); - nv_mask(dev, src0, 0x00000001, 0x00000000); - } -} - -static void -prog_clk(struct drm_device *dev, int clk, struct creg *reg) -{ - if (!reg->clk) { - NV_DEBUG(dev, "no clock for %02x\n", clk); - return; - } - - nv_mask(dev, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | reg->clk); -} - -int -nva3_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - perflvl->core = read_pll(dev, 0x00, 0x4200); - perflvl->shader = read_pll(dev, 0x01, 0x4220); - perflvl->memory = read_pll(dev, 0x02, 0x4000); - perflvl->unka0 = read_clk(dev, 0x20, false); - perflvl->vdec = read_clk(dev, 0x21, false); - perflvl->daemon = read_clk(dev, 0x25, false); - perflvl->copy = perflvl->core; - return 0; -} - -struct nva3_pm_state { - struct creg nclk; - struct creg sclk; - struct creg mclk; - struct creg vdec; - struct creg unka0; -}; - -void * -nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct nva3_pm_state *info; - int ret; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return ERR_PTR(-ENOMEM); - - ret = calc_clk(dev, 0x10, 0x4200, perflvl->core, &info->nclk); - if (ret < 0) - goto out; - - ret = calc_clk(dev, 0x11, 0x4220, perflvl->shader, &info->sclk); - if (ret < 0) - goto out; - - ret = calc_clk(dev, 0x12, 0x4000, perflvl->memory, &info->mclk); - if (ret < 0) - goto out; - - ret = calc_clk(dev, 0x20, 0x0000, perflvl->unka0, &info->unka0); - if (ret < 0) - goto out; - - ret = calc_clk(dev, 0x21, 0x0000, perflvl->vdec, &info->vdec); - if (ret < 0) - goto out; - -out: - if (ret < 0) { - kfree(info); - info = ERR_PTR(ret); - } - return info; -} - -static bool -nva3_pm_grcp_idle(void *data) -{ - struct drm_device *dev = data; - - if (!(nv_rd32(dev, 0x400304) & 0x00000001)) - return true; - if (nv_rd32(dev, 0x400308) == 0x0050001c) - return true; - return false; -} - -int -nva3_pm_clocks_set(struct drm_device *dev, void *pre_state) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nva3_pm_state *info = pre_state; - unsigned long flags; - int ret = -EAGAIN; - - /* prevent any new grctx switches from starting */ - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - nv_wr32(dev, 0x400324, 0x00000000); - nv_wr32(dev, 0x400328, 0x0050001c); /* wait flag 0x1c */ - /* wait for any pending grctx switches to complete */ - if (!nv_wait_cb(dev, nva3_pm_grcp_idle, dev)) { - NV_ERROR(dev, "pm: ctxprog didn't go idle\n"); - goto cleanup; - } - /* freeze PFIFO */ - nv_mask(dev, 0x002504, 0x00000001, 0x00000001); - if (!nv_wait(dev, 0x002504, 0x00000010, 0x00000010)) { - NV_ERROR(dev, "pm: fifo didn't go idle\n"); - goto cleanup; - } - - prog_pll(dev, 0x00, 0x004200, &info->nclk); - prog_pll(dev, 0x01, 0x004220, &info->sclk); - prog_clk(dev, 0x20, &info->unka0); - prog_clk(dev, 0x21, &info->vdec); - - if (info->mclk.clk || info->mclk.pll) { - nv_wr32(dev, 0x100210, 0); - nv_wr32(dev, 0x1002dc, 1); - nv_wr32(dev, 0x004018, 0x00001000); - prog_pll(dev, 0x02, 0x004000, &info->mclk); - if (nv_rd32(dev, 0x4000) & 0x00000008) - nv_wr32(dev, 0x004018, 0x1000d000); - else - nv_wr32(dev, 0x004018, 0x10005000); - nv_wr32(dev, 0x1002dc, 0); - nv_wr32(dev, 0x100210, 0x80000000); - } - - ret = 0; - -cleanup: - /* unfreeze PFIFO */ - nv_mask(dev, 0x002504, 0x00000001, 0x00000000); - /* restore ctxprog to normal */ - nv_wr32(dev, 0x400324, 0x00000000); - nv_wr32(dev, 0x400328, 0x0070009c); /* set flag 0x1c */ - /* unblock it if necessary */ - if (nv_rd32(dev, 0x400308) == 0x0050001c) - nv_mask(dev, 0x400824, 0x10000000, 0x10000000); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - kfree(info); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.c deleted file mode 100644 index dddf006f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_util.h" -#include "nouveau_vm.h" -#include "nouveau_ramht.h" -#include "nvc0_copy.fuc.h" - -struct nvc0_copy_engine { - struct nouveau_exec_engine base; - u32 irq; - u32 pmc; - u32 fuc; - u32 ctx; -}; - -static int -nvc0_copy_context_new(struct nouveau_channel *chan, int engine) -{ - struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine); - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramin = chan->ramin; - struct nouveau_gpuobj *ctx = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, chan, 256, 256, - NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER | - NVOBJ_FLAG_ZERO_ALLOC, &ctx); - if (ret) - return ret; - - nv_wo32(ramin, pcopy->ctx + 0, lower_32_bits(ctx->linst)); - nv_wo32(ramin, pcopy->ctx + 4, upper_32_bits(ctx->linst)); - dev_priv->engine.instmem.flush(dev); - - chan->engctx[engine] = ctx; - return 0; -} - -static int -nvc0_copy_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - return 0; -} - -static void -nvc0_copy_context_del(struct nouveau_channel *chan, int engine) -{ - struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine); - struct nouveau_gpuobj *ctx = chan->engctx[engine]; - struct drm_device *dev = chan->dev; - u32 inst; - - inst = (chan->ramin->vinst >> 12); - inst |= 0x40000000; - - /* disable fifo access */ - nv_wr32(dev, pcopy->fuc + 0x048, 0x00000000); - /* mark channel as unloaded if it's currently active */ - if (nv_rd32(dev, pcopy->fuc + 0x050) == inst) - nv_mask(dev, pcopy->fuc + 0x050, 0x40000000, 0x00000000); - /* mark next channel as invalid if it's about to be loaded */ - if (nv_rd32(dev, pcopy->fuc + 0x054) == inst) - nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000); - /* restore fifo access */ - nv_wr32(dev, pcopy->fuc + 0x048, 0x00000003); - - nv_wo32(chan->ramin, pcopy->ctx + 0, 0x00000000); - nv_wo32(chan->ramin, pcopy->ctx + 4, 0x00000000); - nouveau_gpuobj_ref(NULL, &ctx); - - chan->engctx[engine] = ctx; -} - -static int -nvc0_copy_init(struct drm_device *dev, int engine) -{ - struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); - int i; - - nv_mask(dev, 0x000200, pcopy->pmc, 0x00000000); - nv_mask(dev, 0x000200, pcopy->pmc, pcopy->pmc); - nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff); - - nv_wr32(dev, pcopy->fuc + 0x1c0, 0x01000000); - for (i = 0; i < sizeof(nvc0_pcopy_data) / 4; i++) - nv_wr32(dev, pcopy->fuc + 0x1c4, nvc0_pcopy_data[i]); - - nv_wr32(dev, pcopy->fuc + 0x180, 0x01000000); - for (i = 0; i < sizeof(nvc0_pcopy_code) / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(dev, pcopy->fuc + 0x188, i >> 6); - nv_wr32(dev, pcopy->fuc + 0x184, nvc0_pcopy_code[i]); - } - - nv_wr32(dev, pcopy->fuc + 0x084, engine - NVOBJ_ENGINE_COPY0); - nv_wr32(dev, pcopy->fuc + 0x10c, 0x00000000); - nv_wr32(dev, pcopy->fuc + 0x104, 0x00000000); /* ENTRY */ - nv_wr32(dev, pcopy->fuc + 0x100, 0x00000002); /* TRIGGER */ - return 0; -} - -static int -nvc0_copy_fini(struct drm_device *dev, int engine, bool suspend) -{ - struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); - - nv_mask(dev, pcopy->fuc + 0x048, 0x00000003, 0x00000000); - - /* trigger fuc context unload */ - nv_wait(dev, pcopy->fuc + 0x008, 0x0000000c, 0x00000000); - nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000); - nv_wr32(dev, pcopy->fuc + 0x000, 0x00000008); - nv_wait(dev, pcopy->fuc + 0x008, 0x00000008, 0x00000000); - - nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff); - return 0; -} - -static struct nouveau_enum nvc0_copy_isr_error_name[] = { - { 0x0001, "ILLEGAL_MTHD" }, - { 0x0002, "INVALID_ENUM" }, - { 0x0003, "INVALID_BITFIELD" }, - {} -}; - -static void -nvc0_copy_isr(struct drm_device *dev, int engine) -{ - struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); - u32 disp = nv_rd32(dev, pcopy->fuc + 0x01c); - u32 stat = nv_rd32(dev, pcopy->fuc + 0x008) & disp & ~(disp >> 16); - u64 inst = (u64)(nv_rd32(dev, pcopy->fuc + 0x050) & 0x0fffffff) << 12; - u32 chid = nvc0_graph_isr_chid(dev, inst); - u32 ssta = nv_rd32(dev, pcopy->fuc + 0x040) & 0x0000ffff; - u32 addr = nv_rd32(dev, pcopy->fuc + 0x040) >> 16; - u32 mthd = (addr & 0x07ff) << 2; - u32 subc = (addr & 0x3800) >> 11; - u32 data = nv_rd32(dev, pcopy->fuc + 0x044); - - if (stat & 0x00000040) { - NV_INFO(dev, "PCOPY: DISPATCH_ERROR ["); - nouveau_enum_print(nvc0_copy_isr_error_name, ssta); - printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n", - chid, inst, subc, mthd, data); - nv_wr32(dev, pcopy->fuc + 0x004, 0x00000040); - stat &= ~0x00000040; - } - - if (stat) { - NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat); - nv_wr32(dev, pcopy->fuc + 0x004, stat); - } -} - -static void -nvc0_copy_isr_0(struct drm_device *dev) -{ - nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY0); -} - -static void -nvc0_copy_isr_1(struct drm_device *dev) -{ - nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY1); -} - -static void -nvc0_copy_destroy(struct drm_device *dev, int engine) -{ - struct nvc0_copy_engine *pcopy = nv_engine(dev, engine); - - nouveau_irq_unregister(dev, pcopy->irq); - - if (engine == NVOBJ_ENGINE_COPY0) - NVOBJ_ENGINE_DEL(dev, COPY0); - else - NVOBJ_ENGINE_DEL(dev, COPY1); - kfree(pcopy); -} - -int -nvc0_copy_create(struct drm_device *dev, int engine) -{ - struct nvc0_copy_engine *pcopy; - - pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL); - if (!pcopy) - return -ENOMEM; - - pcopy->base.destroy = nvc0_copy_destroy; - pcopy->base.init = nvc0_copy_init; - pcopy->base.fini = nvc0_copy_fini; - pcopy->base.context_new = nvc0_copy_context_new; - pcopy->base.context_del = nvc0_copy_context_del; - pcopy->base.object_new = nvc0_copy_object_new; - - if (engine == 0) { - pcopy->irq = 5; - pcopy->pmc = 0x00000040; - pcopy->fuc = 0x104000; - pcopy->ctx = 0x0230; - nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_0); - NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base); - NVOBJ_CLASS(dev, 0x90b5, COPY0); - } else { - pcopy->irq = 6; - pcopy->pmc = 0x00000080; - pcopy->fuc = 0x105000; - pcopy->ctx = 0x0240; - nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_1); - NVOBJ_ENGINE_ADD(dev, COPY1, &pcopy->base); - NVOBJ_CLASS(dev, 0x90b8, COPY1); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h deleted file mode 100644 index a8d17458..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h +++ /dev/null @@ -1,527 +0,0 @@ -uint32_t nvc0_pcopy_data[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00010000, - 0x00000000, - 0x00000000, - 0x00010040, - 0x0001019f, - 0x00000000, - 0x00010050, - 0x000101a1, - 0x00000000, - 0x00070080, - 0x0000001c, - 0xfffff000, - 0x00000020, - 0xfff80000, - 0x00000024, - 0xffffe000, - 0x00000028, - 0xfffff800, - 0x0000002c, - 0xfffff000, - 0x00000030, - 0xfff80000, - 0x00000034, - 0xffffe000, - 0x00070088, - 0x00000048, - 0xfffff000, - 0x0000004c, - 0xfff80000, - 0x00000050, - 0xffffe000, - 0x00000054, - 0xfffff800, - 0x00000058, - 0xfffff000, - 0x0000005c, - 0xfff80000, - 0x00000060, - 0xffffe000, - 0x000200c0, - 0x000104b8, - 0x00000000, - 0x00010541, - 0x00000000, - 0x000e00c3, - 0x00000010, - 0xffffff00, - 0x00000014, - 0x0000000f, - 0x0000003c, - 0xffffff00, - 0x00000040, - 0x0000000f, - 0x00000018, - 0xfff80000, - 0x00000044, - 0xfff80000, - 0x00000074, - 0xffff0000, - 0x00000078, - 0xffffe000, - 0x00000068, - 0xfccc0000, - 0x0000006c, - 0x00000000, - 0x00000070, - 0x00000000, - 0x00000004, - 0xffffff00, - 0x00000008, - 0x00000000, - 0x0000000c, - 0x00000000, - 0x00000800, -}; - -uint32_t nvc0_pcopy_code[] = { - 0x04fe04bd, - 0x3517f000, - 0xf10010fe, - 0xf1040017, - 0xf0fff327, - 0x12d00023, - 0x0c25f0c0, - 0xf40012d0, - 0x17f11031, - 0x27f01200, - 0x0012d003, - 0xf40031f4, - 0x0ef40028, - 0x8001cffd, - 0xf40812c4, - 0x21f4060b, - 0x0412c4ca, - 0xf5070bf4, - 0xc4010221, - 0x01d00c11, - 0xf101f840, - 0xfe770047, - 0x47f1004b, - 0x44cf2100, - 0x0144f000, - 0xb60444b6, - 0xf7f13040, - 0xf4b6061c, - 0x1457f106, - 0x00f5d101, - 0xb6043594, - 0x57fe0250, - 0x0145fe00, - 0x010052b7, - 0x00ff67f1, - 0x56fd60bd, - 0x0253f004, - 0xf80545fa, - 0x0053f003, - 0xd100e7f0, - 0x549800fe, - 0x0845b600, - 0xb6015698, - 0x46fd1864, - 0x0047fe05, - 0xf00204b9, - 0x01f40643, - 0x0604fa09, - 0xfa060ef4, - 0x03f80504, - 0x27f100f8, - 0x23cf1400, - 0x1e3fc800, - 0xf4170bf4, - 0x21f40132, - 0x1e3af053, - 0xf00023d0, - 0x24d00147, - 0xcf00f880, - 0x3dc84023, - 0x090bf41e, - 0xf40131f4, - 0x37f05321, - 0x8023d002, - 0x37f100f8, - 0x32cf1900, - 0x0033cf40, - 0x07ff24e4, - 0xf11024b6, - 0xbd010057, - 0x5874bd64, - 0x57580056, - 0x0450b601, - 0xf40446b8, - 0x76bb4d08, - 0x0447b800, - 0xbb0f08f4, - 0x74b60276, - 0x0057bb03, - 0xbbdf0ef4, - 0x44b60246, - 0x0045bb03, - 0xfd014598, - 0x54b00453, - 0x201bf400, - 0x58004558, - 0x64b00146, - 0x091bf400, - 0xf4005380, - 0x32f4300e, - 0xf455f901, - 0x0ef40c01, - 0x0225f025, - 0xf10125f0, - 0xd0100047, - 0x43d00042, - 0x4027f040, - 0xcf0002d0, - 0x24f08002, - 0x0024b040, - 0xf1f71bf4, - 0xf01d0027, - 0x23d00137, - 0xf800f800, - 0x0027f100, - 0xf034bd22, - 0x23d00233, - 0xf400f800, - 0x01b0f030, - 0x0101b000, - 0xb00201b0, - 0x04980301, - 0x3045c71a, - 0xc70150b6, - 0x60b63446, - 0x3847c701, - 0xf40170b6, - 0x84bd0232, - 0x4ac494bd, - 0x0445b60f, - 0xa430b4bd, - 0x0f18f404, - 0xbbc0a5ff, - 0x31f400cb, - 0x220ef402, - 0xf00c1bf4, - 0xcbbb10c7, - 0x160ef400, - 0xf406a430, - 0xc7f00c18, - 0x00cbbb14, - 0xf1070ef4, - 0x380080c7, - 0x80b601c8, - 0x01b0b601, - 0xf404b5b8, - 0x90b6c308, - 0x0497b801, - 0xfdb208f4, - 0x06800065, - 0x1d08980e, - 0xf40068fd, - 0x64bd0502, - 0x800075fd, - 0x78fd1907, - 0x1057f100, - 0x0654b608, - 0xd00056d0, - 0x50b74057, - 0x06980800, - 0x0162b619, - 0x980864b6, - 0x72b60e07, - 0x0567fd01, - 0xb70056d0, - 0xb4010050, - 0x56d00060, - 0x0160b400, - 0xb44056d0, - 0x56d00260, - 0x0360b480, - 0xb7c056d0, - 0x98040050, - 0x56d01b06, - 0x1c069800, - 0xf44056d0, - 0x00f81030, - 0xc7075798, - 0x78c76879, - 0x0380b664, - 0xb06077c7, - 0x1bf40e76, - 0x0477f009, - 0xf00f0ef4, - 0x70b6027c, - 0x0947fd11, - 0x980677f0, - 0x5b980c5a, - 0x00abfd0e, - 0xbb01b7f0, - 0xb2b604b7, - 0xc4abff01, - 0x9805a7bb, - 0xe7f00d5d, - 0x04e8bb01, - 0xff01e2b6, - 0xd8bbb4de, - 0x01e0b605, - 0xbb0cef94, - 0xfefd02eb, - 0x026cf005, - 0x020860b7, - 0xd00864b6, - 0xb7bb006f, - 0x00cbbb04, - 0x98085f98, - 0xfbfd0e5b, - 0x01b7f000, - 0xb604b7bb, - 0xfbbb01b2, - 0x05f7bb00, - 0x5f98f0f9, - 0x01b7f009, - 0xb604b8bb, - 0xfbbb01b2, - 0x05f8bb00, - 0x78bbf0f9, - 0x0282b600, - 0xbb01b7f0, - 0xb9bb04b8, - 0x0b589804, - 0xbb01e7f0, - 0xe2b604e9, - 0xf48eff01, - 0xbb04f7bb, - 0x79bb00cf, - 0x0589bb00, - 0x90fcf0fc, - 0xbb00d9fd, - 0x89fd00ad, - 0x008ffd00, - 0xbb00a8bb, - 0x92b604a7, - 0x0497bb01, - 0x988069d0, - 0x58980557, - 0x00acbb04, - 0xb6007abb, - 0x84b60081, - 0x058bfd10, - 0x060062b7, - 0xb70067d0, - 0xd0040060, - 0x00f80068, - 0xb7026cf0, - 0xb6020260, - 0x57980864, - 0x0067d005, - 0x040060b7, - 0xb6045798, - 0x67d01074, - 0x0060b700, - 0x06579804, - 0xf80067d0, - 0xf900f900, - 0x0007f110, - 0x0604b608, - 0xf00001cf, - 0x1bf40114, - 0xfc10fcfa, - 0xc800f800, - 0x1bf40d34, - 0xd121f570, - 0x0c47f103, - 0x0644b608, - 0xb6020598, - 0x45d00450, - 0x4040d000, - 0xd00c57f0, - 0x40b78045, - 0x05980400, - 0x1054b601, - 0xb70045d0, - 0xf1050040, - 0xf00b0057, - 0x45d00153, - 0x4057f100, - 0x0154b640, - 0x808053f1, - 0xf14045d0, - 0xf1111057, - 0xd0131253, - 0x57f18045, - 0x53f11514, - 0x45d01716, - 0x0157f1c0, - 0x0153f026, - 0x080047f1, - 0xd00644b6, - 0x21f50045, - 0x47f103d1, - 0x44b6080c, - 0x02059806, - 0xd00045d0, - 0x57f04040, - 0x8045d004, - 0x040040b7, - 0xb6010598, - 0x45d01054, - 0x0040b700, - 0x0057f105, - 0x0045d003, - 0x111057f1, - 0x131253f1, - 0x984045d0, - 0x40b70305, - 0x45d00500, - 0x0157f100, - 0x0153f026, - 0x080047f1, - 0xd00644b6, - 0x00f80045, - 0x03d121f5, - 0xf4003fc8, - 0x21f50e0b, - 0x47f101af, - 0x0ef40200, - 0x1067f11e, - 0x0664b608, - 0x800177f0, - 0x07800e07, - 0x1d079819, - 0xd00067d0, - 0x44bd4067, - 0xbd0232f4, - 0x043fc854, - 0xf50a0bf4, - 0xf403a821, - 0x21f50a0e, - 0x49f0029c, - 0x0231f407, - 0xc82c57f0, - 0x0bf4083f, - 0xa821f50a, - 0x0a0ef403, - 0x029c21f5, - 0xf10849f0, - 0xb6080057, - 0x06980654, - 0x4056d01e, - 0xf14167f0, - 0xfd440063, - 0x54d00546, - 0x0c3fc800, - 0xf5070bf4, - 0xf803eb21, - 0x0027f100, - 0xf034bd22, - 0x23d00133, - 0x0000f800, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fb.c deleted file mode 100644 index f704e942..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fb.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "drm.h" -#include "nouveau_drv.h" -#include "nouveau_drm.h" - -struct nvc0_fb_priv { - struct page *r100c10_page; - dma_addr_t r100c10; -}; - -static inline void -nvc0_mfb_subp_isr(struct drm_device *dev, int unit, int subp) -{ - u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400); - u32 stat = nv_rd32(dev, subp_base + 0x020); - - if (stat) { - NV_INFO(dev, "PMFB%d_SUBP%d: 0x%08x\n", unit, subp, stat); - nv_wr32(dev, subp_base + 0x020, stat); - } -} - -static void -nvc0_mfb_isr(struct drm_device *dev) -{ - u32 units = nv_rd32(dev, 0x00017c); - while (units) { - u32 subp, unit = ffs(units) - 1; - for (subp = 0; subp < 2; subp++) - nvc0_mfb_subp_isr(dev, unit, subp); - units &= ~(1 << unit); - } - - /* we do something horribly wrong and upset PMFB a lot, so mask off - * interrupts from it after the first one until it's fixed - */ - nv_mask(dev, 0x000640, 0x02000000, 0x00000000); -} - -static void -nvc0_fb_destroy(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nvc0_fb_priv *priv = pfb->priv; - - nouveau_irq_unregister(dev, 25); - - if (priv->r100c10_page) { - pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - __free_page(priv->r100c10_page); - } - - kfree(priv); - pfb->priv = NULL; -} - -static int -nvc0_fb_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nvc0_fb_priv *priv; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - pfb->priv = priv; - - priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (!priv->r100c10_page) { - nvc0_fb_destroy(dev); - return -ENOMEM; - } - - priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) { - nvc0_fb_destroy(dev); - return -EFAULT; - } - - nouveau_irq_register(dev, 25, nvc0_mfb_isr); - return 0; -} - -int -nvc0_fb_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_fb_priv *priv; - int ret; - - if (!dev_priv->engine.fb.priv) { - ret = nvc0_fb_create(dev); - if (ret) - return ret; - } - priv = dev_priv->engine.fb.priv; - - nv_wr32(dev, 0x100c10, priv->r100c10 >> 8); - return 0; -} - -void -nvc0_fb_takedown(struct drm_device *dev) -{ - nvc0_fb_destroy(dev); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fbcon.c deleted file mode 100644 index a495e481..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_dma.h" -#include "nouveau_ramht.h" -#include "nouveau_fbcon.h" -#include "nouveau_mm.h" - -int -nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret; - - ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11); - if (ret) - return ret; - - if (rect->rop != ROP_COPY) { - BEGIN_NVC0(chan, 2, NvSub2D, 0x02ac, 1); - OUT_RING (chan, 1); - } - BEGIN_NVC0(chan, 2, NvSub2D, 0x0588, 1); - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) - OUT_RING (chan, ((uint32_t *)info->pseudo_palette)[rect->color]); - else - OUT_RING (chan, rect->color); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0600, 4); - OUT_RING (chan, rect->dx); - OUT_RING (chan, rect->dy); - OUT_RING (chan, rect->dx + rect->width); - OUT_RING (chan, rect->dy + rect->height); - if (rect->rop != ROP_COPY) { - BEGIN_NVC0(chan, 2, NvSub2D, 0x02ac, 1); - OUT_RING (chan, 3); - } - FIRE_RING(chan); - return 0; -} - -int -nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - int ret; - - ret = RING_SPACE(chan, 12); - if (ret) - return ret; - - BEGIN_NVC0(chan, 2, NvSub2D, 0x0110, 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, 2, NvSub2D, 0x08b0, 4); - OUT_RING (chan, region->dx); - OUT_RING (chan, region->dy); - OUT_RING (chan, region->width); - OUT_RING (chan, region->height); - BEGIN_NVC0(chan, 2, NvSub2D, 0x08d0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, region->sx); - OUT_RING (chan, 0); - OUT_RING (chan, region->sy); - FIRE_RING(chan); - return 0; -} - -int -nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - uint32_t width, dwords, *data = (uint32_t *)image->data; - uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); - uint32_t *palette = info->pseudo_palette; - int ret; - - if (image->depth != 1) - return -ENODEV; - - ret = RING_SPACE(chan, 11); - if (ret) - return ret; - - width = ALIGN(image->width, 32); - dwords = (width * image->height) >> 5; - - BEGIN_NVC0(chan, 2, NvSub2D, 0x0814, 2); - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - OUT_RING (chan, palette[image->bg_color] | mask); - OUT_RING (chan, palette[image->fg_color] | mask); - } else { - OUT_RING (chan, image->bg_color); - OUT_RING (chan, image->fg_color); - } - BEGIN_NVC0(chan, 2, NvSub2D, 0x0838, 2); - OUT_RING (chan, image->width); - OUT_RING (chan, image->height); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0850, 4); - OUT_RING (chan, 0); - OUT_RING (chan, image->dx); - OUT_RING (chan, 0); - OUT_RING (chan, image->dy); - - while (dwords) { - int push = dwords > 2047 ? 2047 : dwords; - - ret = RING_SPACE(chan, push + 1); - if (ret) - return ret; - - dwords -= push; - - BEGIN_NVC0(chan, 6, NvSub2D, 0x0860, push); - OUT_RINGp(chan, data, push); - data += push; - } - - FIRE_RING(chan); - return 0; -} - -int -nvc0_fbcon_accel_init(struct fb_info *info) -{ - struct nouveau_fbdev *nfbdev = info->par; - struct drm_device *dev = nfbdev->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channel; - struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb; - int ret, format; - - ret = nouveau_gpuobj_gr_new(chan, 0x902d, 0x902d); - if (ret) - return ret; - - switch (info->var.bits_per_pixel) { - case 8: - format = 0xf3; - break; - case 15: - format = 0xf8; - break; - case 16: - format = 0xe8; - break; - case 32: - switch (info->var.transp.length) { - case 0: /* depth 24 */ - case 8: /* depth 32, just use 24.. */ - format = 0xe6; - break; - case 2: /* depth 30 */ - format = 0xd1; - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } - - ret = RING_SPACE(chan, 60); - if (ret) { - WARN_ON(1); - nouveau_fbcon_gpu_lockup(info); - return ret; - } - - BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1); - OUT_RING (chan, 0x0000902d); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2); - OUT_RING (chan, upper_32_bits(chan->notifier_vma.offset)); - OUT_RING (chan, lower_32_bits(chan->notifier_vma.offset)); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0290, 1); - OUT_RING (chan, 0); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0888, 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, 2, NvSub2D, 0x02ac, 1); - OUT_RING (chan, 3); - BEGIN_NVC0(chan, 2, NvSub2D, 0x02a0, 1); - OUT_RING (chan, 0x55); - BEGIN_NVC0(chan, 2, NvSub2D, 0x08c0, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0580, 2); - OUT_RING (chan, 4); - OUT_RING (chan, format); - BEGIN_NVC0(chan, 2, NvSub2D, 0x02e8, 2); - OUT_RING (chan, 2); - OUT_RING (chan, 1); - - BEGIN_NVC0(chan, 2, NvSub2D, 0x0804, 1); - OUT_RING (chan, format); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0800, 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0808, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, 2, NvSub2D, 0x081c, 1); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0840, 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0200, 10); - OUT_RING (chan, format); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, info->fix.line_length); - OUT_RING (chan, info->var.xres_virtual); - OUT_RING (chan, info->var.yres_virtual); - OUT_RING (chan, upper_32_bits(fb->vma.offset)); - OUT_RING (chan, lower_32_bits(fb->vma.offset)); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0230, 10); - OUT_RING (chan, format); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, info->fix.line_length); - OUT_RING (chan, info->var.xres_virtual); - OUT_RING (chan, info->var.yres_virtual); - OUT_RING (chan, upper_32_bits(fb->vma.offset)); - OUT_RING (chan, lower_32_bits(fb->vma.offset)); - FIRE_RING (chan); - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fifo.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fifo.c deleted file mode 100644 index 50d68a7a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_fifo.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_mm.h" - -static void nvc0_fifo_isr(struct drm_device *); - -struct nvc0_fifo_priv { - struct nouveau_gpuobj *playlist[2]; - int cur_playlist; - struct nouveau_vma user_vma; - int spoon_nr; -}; - -struct nvc0_fifo_chan { - struct nouveau_gpuobj *user; - struct nouveau_gpuobj *ramfc; -}; - -static void -nvc0_fifo_playlist_update(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nvc0_fifo_priv *priv = pfifo->priv; - struct nouveau_gpuobj *cur; - int i, p; - - cur = priv->playlist[priv->cur_playlist]; - priv->cur_playlist = !priv->cur_playlist; - - for (i = 0, p = 0; i < 128; i++) { - if (!(nv_rd32(dev, 0x3004 + (i * 8)) & 1)) - continue; - nv_wo32(cur, p + 0, i); - nv_wo32(cur, p + 4, 0x00000004); - p += 8; - } - pinstmem->flush(dev); - - nv_wr32(dev, 0x002270, cur->vinst >> 12); - nv_wr32(dev, 0x002274, 0x01f00000 | (p >> 3)); - if (!nv_wait(dev, 0x00227c, 0x00100000, 0x00000000)) - NV_ERROR(dev, "PFIFO - playlist update failed\n"); -} - -void -nvc0_fifo_disable(struct drm_device *dev) -{ -} - -void -nvc0_fifo_enable(struct drm_device *dev) -{ -} - -bool -nvc0_fifo_reassign(struct drm_device *dev, bool enable) -{ - return false; -} - -bool -nvc0_fifo_cache_pull(struct drm_device *dev, bool enable) -{ - return false; -} - -int -nvc0_fifo_channel_id(struct drm_device *dev) -{ - return 127; -} - -int -nvc0_fifo_create_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nvc0_fifo_priv *priv = pfifo->priv; - struct nvc0_fifo_chan *fifoch; - u64 ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4; - int ret; - - chan->fifo_priv = kzalloc(sizeof(*fifoch), GFP_KERNEL); - if (!chan->fifo_priv) - return -ENOMEM; - fifoch = chan->fifo_priv; - - /* allocate vram for control regs, map into polling area */ - ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &fifoch->user); - if (ret) - goto error; - - nouveau_vm_map_at(&priv->user_vma, chan->id * 0x1000, - *(struct nouveau_mem **)fifoch->user->node); - - chan->user = ioremap_wc(pci_resource_start(dev->pdev, 1) + - priv->user_vma.offset + (chan->id * 0x1000), - PAGE_SIZE); - if (!chan->user) { - ret = -ENOMEM; - goto error; - } - - /* ramfc */ - ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst, - chan->ramin->vinst, 0x100, - NVOBJ_FLAG_ZERO_ALLOC, &fifoch->ramfc); - if (ret) - goto error; - - nv_wo32(fifoch->ramfc, 0x08, lower_32_bits(fifoch->user->vinst)); - nv_wo32(fifoch->ramfc, 0x0c, upper_32_bits(fifoch->user->vinst)); - nv_wo32(fifoch->ramfc, 0x10, 0x0000face); - nv_wo32(fifoch->ramfc, 0x30, 0xfffff902); - nv_wo32(fifoch->ramfc, 0x48, lower_32_bits(ib_virt)); - nv_wo32(fifoch->ramfc, 0x4c, drm_order(chan->dma.ib_max + 1) << 16 | - upper_32_bits(ib_virt)); - nv_wo32(fifoch->ramfc, 0x54, 0x00000002); - nv_wo32(fifoch->ramfc, 0x84, 0x20400000); - nv_wo32(fifoch->ramfc, 0x94, 0x30000001); - nv_wo32(fifoch->ramfc, 0x9c, 0x00000100); - nv_wo32(fifoch->ramfc, 0xa4, 0x1f1f1f1f); - nv_wo32(fifoch->ramfc, 0xa8, 0x1f1f1f1f); - nv_wo32(fifoch->ramfc, 0xac, 0x0000001f); - nv_wo32(fifoch->ramfc, 0xb8, 0xf8000000); - nv_wo32(fifoch->ramfc, 0xf8, 0x10003080); /* 0x002310 */ - nv_wo32(fifoch->ramfc, 0xfc, 0x10000010); /* 0x002350 */ - pinstmem->flush(dev); - - nv_wr32(dev, 0x003000 + (chan->id * 8), 0xc0000000 | - (chan->ramin->vinst >> 12)); - nv_wr32(dev, 0x003004 + (chan->id * 8), 0x001f0001); - nvc0_fifo_playlist_update(dev); - return 0; - -error: - pfifo->destroy_context(chan); - return ret; -} - -void -nvc0_fifo_destroy_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - struct nvc0_fifo_chan *fifoch; - - nv_mask(dev, 0x003004 + (chan->id * 8), 0x00000001, 0x00000000); - nv_wr32(dev, 0x002634, chan->id); - if (!nv_wait(dev, 0x0002634, 0xffffffff, chan->id)) - NV_WARN(dev, "0x2634 != chid: 0x%08x\n", nv_rd32(dev, 0x2634)); - - nvc0_fifo_playlist_update(dev); - - nv_wr32(dev, 0x003000 + (chan->id * 8), 0x00000000); - - if (chan->user) { - iounmap(chan->user); - chan->user = NULL; - } - - fifoch = chan->fifo_priv; - chan->fifo_priv = NULL; - if (!fifoch) - return; - - nouveau_gpuobj_ref(NULL, &fifoch->ramfc); - nouveau_gpuobj_ref(NULL, &fifoch->user); - kfree(fifoch); -} - -int -nvc0_fifo_load_context(struct nouveau_channel *chan) -{ - return 0; -} - -int -nvc0_fifo_unload_context(struct drm_device *dev) -{ - int i; - - for (i = 0; i < 128; i++) { - if (!(nv_rd32(dev, 0x003004 + (i * 8)) & 1)) - continue; - - nv_mask(dev, 0x003004 + (i * 8), 0x00000001, 0x00000000); - nv_wr32(dev, 0x002634, i); - if (!nv_wait(dev, 0x002634, 0xffffffff, i)) { - NV_INFO(dev, "PFIFO: kick ch %d failed: 0x%08x\n", - i, nv_rd32(dev, 0x002634)); - return -EBUSY; - } - } - - return 0; -} - -static void -nvc0_fifo_destroy(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nvc0_fifo_priv *priv; - - priv = pfifo->priv; - if (!priv) - return; - - nouveau_vm_put(&priv->user_vma); - nouveau_gpuobj_ref(NULL, &priv->playlist[1]); - nouveau_gpuobj_ref(NULL, &priv->playlist[0]); - kfree(priv); -} - -void -nvc0_fifo_takedown(struct drm_device *dev) -{ - nv_wr32(dev, 0x002140, 0x00000000); - nvc0_fifo_destroy(dev); -} - -static int -nvc0_fifo_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nvc0_fifo_priv *priv; - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - pfifo->priv = priv; - - ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000, 0, - &priv->playlist[0]); - if (ret) - goto error; - - ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000, 0, - &priv->playlist[1]); - if (ret) - goto error; - - ret = nouveau_vm_get(dev_priv->bar1_vm, pfifo->channels * 0x1000, - 12, NV_MEM_ACCESS_RW, &priv->user_vma); - if (ret) - goto error; - - nouveau_irq_register(dev, 8, nvc0_fifo_isr); - NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ - return 0; - -error: - nvc0_fifo_destroy(dev); - return ret; -} - -int -nvc0_fifo_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_channel *chan; - struct nvc0_fifo_priv *priv; - int ret, i; - - if (!pfifo->priv) { - ret = nvc0_fifo_create(dev); - if (ret) - return ret; - } - priv = pfifo->priv; - - /* reset PFIFO, enable all available PSUBFIFO areas */ - nv_mask(dev, 0x000200, 0x00000100, 0x00000000); - nv_mask(dev, 0x000200, 0x00000100, 0x00000100); - nv_wr32(dev, 0x000204, 0xffffffff); - nv_wr32(dev, 0x002204, 0xffffffff); - - priv->spoon_nr = hweight32(nv_rd32(dev, 0x002204)); - NV_DEBUG(dev, "PFIFO: %d subfifo(s)\n", priv->spoon_nr); - - /* assign engines to subfifos */ - if (priv->spoon_nr >= 3) { - nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */ - nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */ - nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */ - nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */ - nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */ - nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */ - } - - /* PSUBFIFO[n] */ - for (i = 0; i < priv->spoon_nr; i++) { - nv_mask(dev, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); - nv_wr32(dev, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ - nv_wr32(dev, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTR_EN */ - } - - nv_mask(dev, 0x002200, 0x00000001, 0x00000001); - nv_wr32(dev, 0x002254, 0x10000000 | priv->user_vma.offset >> 12); - - nv_wr32(dev, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ - nv_wr32(dev, 0x002100, 0xffffffff); - nv_wr32(dev, 0x002140, 0xbfffffff); - - /* restore PFIFO context table */ - for (i = 0; i < 128; i++) { - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->fifo_priv) - continue; - - nv_wr32(dev, 0x003000 + (i * 8), 0xc0000000 | - (chan->ramin->vinst >> 12)); - nv_wr32(dev, 0x003004 + (i * 8), 0x001f0001); - } - nvc0_fifo_playlist_update(dev); - - return 0; -} - -struct nouveau_enum nvc0_fifo_fault_unit[] = { - { 0x00, "PGRAPH" }, - { 0x03, "PEEPHOLE" }, - { 0x04, "BAR1" }, - { 0x05, "BAR3" }, - { 0x07, "PFIFO" }, - { 0x10, "PBSP" }, - { 0x11, "PPPP" }, - { 0x13, "PCOUNTER" }, - { 0x14, "PVP" }, - { 0x15, "PCOPY0" }, - { 0x16, "PCOPY1" }, - { 0x17, "PDAEMON" }, - {} -}; - -struct nouveau_enum nvc0_fifo_fault_reason[] = { - { 0x00, "PT_NOT_PRESENT" }, - { 0x01, "PT_TOO_SHORT" }, - { 0x02, "PAGE_NOT_PRESENT" }, - { 0x03, "VM_LIMIT_EXCEEDED" }, - { 0x04, "NO_CHANNEL" }, - { 0x05, "PAGE_SYSTEM_ONLY" }, - { 0x06, "PAGE_READ_ONLY" }, - { 0x0a, "COMPRESSED_SYSRAM" }, - { 0x0c, "INVALID_STORAGE_TYPE" }, - {} -}; - -struct nouveau_enum nvc0_fifo_fault_hubclient[] = { - { 0x01, "PCOPY0" }, - { 0x02, "PCOPY1" }, - { 0x04, "DISPATCH" }, - { 0x05, "CTXCTL" }, - { 0x06, "PFIFO" }, - { 0x07, "BAR_READ" }, - { 0x08, "BAR_WRITE" }, - { 0x0b, "PVP" }, - { 0x0c, "PPPP" }, - { 0x0d, "PBSP" }, - { 0x11, "PCOUNTER" }, - { 0x12, "PDAEMON" }, - { 0x14, "CCACHE" }, - { 0x15, "CCACHE_POST" }, - {} -}; - -struct nouveau_enum nvc0_fifo_fault_gpcclient[] = { - { 0x01, "TEX" }, - { 0x0c, "ESETUP" }, - { 0x0e, "CTXCTL" }, - { 0x0f, "PROP" }, - {} -}; - -struct nouveau_bitfield nvc0_fifo_subfifo_intr[] = { -/* { 0x00008000, "" } seen with null ib push */ - { 0x00200000, "ILLEGAL_MTHD" }, - { 0x00800000, "EMPTY_SUBC" }, - {} -}; - -static void -nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit) -{ - u32 inst = nv_rd32(dev, 0x2800 + (unit * 0x10)); - u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10)); - u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10)); - u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10)); - u32 client = (stat & 0x00001f00) >> 8; - - NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [", - (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo); - nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f); - printk("] from "); - nouveau_enum_print(nvc0_fifo_fault_unit, unit); - if (stat & 0x00000040) { - printk("/"); - nouveau_enum_print(nvc0_fifo_fault_hubclient, client); - } else { - printk("/GPC%d/", (stat & 0x1f000000) >> 24); - nouveau_enum_print(nvc0_fifo_fault_gpcclient, client); - } - printk(" on channel 0x%010llx\n", (u64)inst << 12); -} - -static int -nvc0_fifo_page_flip(struct drm_device *dev, u32 chid) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) { - chan = dev_priv->channels.ptr[chid]; - if (likely(chan)) - ret = nouveau_finish_page_flip(chan, NULL); - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return ret; -} - -static void -nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) -{ - u32 stat = nv_rd32(dev, 0x040108 + (unit * 0x2000)); - u32 addr = nv_rd32(dev, 0x0400c0 + (unit * 0x2000)); - u32 data = nv_rd32(dev, 0x0400c4 + (unit * 0x2000)); - u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; - u32 subc = (addr & 0x00070000); - u32 mthd = (addr & 0x00003ffc); - u32 show = stat; - - if (stat & 0x00200000) { - if (mthd == 0x0054) { - if (!nvc0_fifo_page_flip(dev, chid)) - show &= ~0x00200000; - } - } - - if (show) { - NV_INFO(dev, "PFIFO%d:", unit); - nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show); - NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n", - unit, chid, subc, mthd, data); - } - - nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); - nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); -} - -static void -nvc0_fifo_isr(struct drm_device *dev) -{ - u32 stat = nv_rd32(dev, 0x002100); - - if (stat & 0x00000100) { - NV_INFO(dev, "PFIFO: unknown status 0x00000100\n"); - nv_wr32(dev, 0x002100, 0x00000100); - stat &= ~0x00000100; - } - - if (stat & 0x10000000) { - u32 units = nv_rd32(dev, 0x00259c); - u32 u = units; - - while (u) { - int i = ffs(u) - 1; - nvc0_fifo_isr_vm_fault(dev, i); - u &= ~(1 << i); - } - - nv_wr32(dev, 0x00259c, units); - stat &= ~0x10000000; - } - - if (stat & 0x20000000) { - u32 units = nv_rd32(dev, 0x0025a0); - u32 u = units; - - while (u) { - int i = ffs(u) - 1; - nvc0_fifo_isr_subfifo_intr(dev, i); - u &= ~(1 << i); - } - - nv_wr32(dev, 0x0025a0, units); - stat &= ~0x20000000; - } - - if (stat & 0x40000000) { - NV_INFO(dev, "PFIFO: unknown status 0x40000000\n"); - nv_mask(dev, 0x002a00, 0x00000000, 0x00000000); - stat &= ~0x40000000; - } - - if (stat) { - NV_INFO(dev, "PFIFO: unhandled status 0x%08x\n", stat); - nv_wr32(dev, 0x002100, stat); - nv_wr32(dev, 0x002140, 0); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.c deleted file mode 100644 index 9066102d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include -#include - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_mm.h" - -#include "nvc0_graph.h" -#include "nvc0_grhub.fuc.h" -#include "nvc0_grgpc.fuc.h" - -static void -nvc0_graph_ctxctl_debug_unit(struct drm_device *dev, u32 base) -{ - NV_INFO(dev, "PGRAPH: %06x - done 0x%08x\n", base, - nv_rd32(dev, base + 0x400)); - NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base, - nv_rd32(dev, base + 0x800), nv_rd32(dev, base + 0x804), - nv_rd32(dev, base + 0x808), nv_rd32(dev, base + 0x80c)); - NV_INFO(dev, "PGRAPH: %06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base, - nv_rd32(dev, base + 0x810), nv_rd32(dev, base + 0x814), - nv_rd32(dev, base + 0x818), nv_rd32(dev, base + 0x81c)); -} - -static void -nvc0_graph_ctxctl_debug(struct drm_device *dev) -{ - u32 gpcnr = nv_rd32(dev, 0x409604) & 0xffff; - u32 gpc; - - nvc0_graph_ctxctl_debug_unit(dev, 0x409000); - for (gpc = 0; gpc < gpcnr; gpc++) - nvc0_graph_ctxctl_debug_unit(dev, 0x502000 + (gpc * 0x8000)); -} - -static int -nvc0_graph_load_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - - nv_wr32(dev, 0x409840, 0x00000030); - nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); - nv_wr32(dev, 0x409504, 0x00000003); - if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) - NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); - - return 0; -} - -static int -nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan) -{ - nv_wr32(dev, 0x409840, 0x00000003); - nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12); - nv_wr32(dev, 0x409504, 0x00000009); - if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) { - NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n"); - return -EBUSY; - } - - return 0; -} - -static int -nvc0_graph_construct_context(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); - struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - int ret, i; - u32 *ctx; - - ctx = kmalloc(priv->grctx_size, GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - if (!nouveau_ctxfw) { - nv_wr32(dev, 0x409840, 0x80000000); - nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); - nv_wr32(dev, 0x409504, 0x00000001); - if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) { - NV_ERROR(dev, "PGRAPH: HUB_SET_CHAN timeout\n"); - nvc0_graph_ctxctl_debug(dev); - ret = -EBUSY; - goto err; - } - } else { - nvc0_graph_load_context(chan); - - nv_wo32(grch->grctx, 0x1c, 1); - nv_wo32(grch->grctx, 0x20, 0); - nv_wo32(grch->grctx, 0x28, 0); - nv_wo32(grch->grctx, 0x2c, 0); - dev_priv->engine.instmem.flush(dev); - } - - ret = nvc0_grctx_generate(chan); - if (ret) - goto err; - - if (!nouveau_ctxfw) { - nv_wr32(dev, 0x409840, 0x80000000); - nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); - nv_wr32(dev, 0x409504, 0x00000002); - if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) { - NV_ERROR(dev, "PGRAPH: HUB_CTX_SAVE timeout\n"); - nvc0_graph_ctxctl_debug(dev); - ret = -EBUSY; - goto err; - } - } else { - ret = nvc0_graph_unload_context_to(dev, chan->ramin->vinst); - if (ret) - goto err; - } - - for (i = 0; i < priv->grctx_size; i += 4) - ctx[i / 4] = nv_ro32(grch->grctx, i); - - priv->grctx_vals = ctx; - return 0; - -err: - kfree(ctx); - return ret; -} - -static int -nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) -{ - struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); - struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i = 0, gpc, tp, ret; - - ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM, - &grch->unk408004); - if (ret) - return ret; - - ret = nouveau_gpuobj_new(dev, chan, 0x8000, 256, NVOBJ_FLAG_VM, - &grch->unk40800c); - if (ret) - return ret; - - ret = nouveau_gpuobj_new(dev, chan, 384 * 1024, 4096, - NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER, - &grch->unk418810); - if (ret) - return ret; - - ret = nouveau_gpuobj_new(dev, chan, 0x1000, 0, NVOBJ_FLAG_VM, - &grch->mmio); - if (ret) - return ret; - - - nv_wo32(grch->mmio, i++ * 4, 0x00408004); - nv_wo32(grch->mmio, i++ * 4, grch->unk408004->linst >> 8); - nv_wo32(grch->mmio, i++ * 4, 0x00408008); - nv_wo32(grch->mmio, i++ * 4, 0x80000018); - - nv_wo32(grch->mmio, i++ * 4, 0x0040800c); - nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->linst >> 8); - nv_wo32(grch->mmio, i++ * 4, 0x00408010); - nv_wo32(grch->mmio, i++ * 4, 0x80000000); - - nv_wo32(grch->mmio, i++ * 4, 0x00418810); - nv_wo32(grch->mmio, i++ * 4, 0x80000000 | grch->unk418810->linst >> 12); - nv_wo32(grch->mmio, i++ * 4, 0x00419848); - nv_wo32(grch->mmio, i++ * 4, 0x10000000 | grch->unk418810->linst >> 12); - - nv_wo32(grch->mmio, i++ * 4, 0x00419004); - nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->linst >> 8); - nv_wo32(grch->mmio, i++ * 4, 0x00419008); - nv_wo32(grch->mmio, i++ * 4, 0x00000000); - - nv_wo32(grch->mmio, i++ * 4, 0x00418808); - nv_wo32(grch->mmio, i++ * 4, grch->unk408004->linst >> 8); - nv_wo32(grch->mmio, i++ * 4, 0x0041880c); - nv_wo32(grch->mmio, i++ * 4, 0x80000018); - - if (dev_priv->chipset != 0xc1) { - u32 magic = 0x02180000; - nv_wo32(grch->mmio, i++ * 4, 0x00405830); - nv_wo32(grch->mmio, i++ * 4, magic); - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { - u32 reg = TP_UNIT(gpc, tp, 0x520); - nv_wo32(grch->mmio, i++ * 4, reg); - nv_wo32(grch->mmio, i++ * 4, magic); - magic += 0x0324; - } - } - } else { - u32 magic = 0x02180000; - nv_wo32(grch->mmio, i++ * 4, 0x00405830); - nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218); - nv_wo32(grch->mmio, i++ * 4, 0x004064c4); - nv_wo32(grch->mmio, i++ * 4, 0x0086ffff); - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { - u32 reg = TP_UNIT(gpc, tp, 0x520); - nv_wo32(grch->mmio, i++ * 4, reg); - nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic); - magic += 0x0324; - } - for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { - u32 reg = TP_UNIT(gpc, tp, 0x544); - nv_wo32(grch->mmio, i++ * 4, reg); - nv_wo32(grch->mmio, i++ * 4, magic); - magic += 0x0324; - } - } - } - - grch->mmio_nr = i / 2; - return 0; -} - -static int -nvc0_graph_context_new(struct nouveau_channel *chan, int engine) -{ - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct nvc0_graph_priv *priv = nv_engine(dev, engine); - struct nvc0_graph_chan *grch; - struct nouveau_gpuobj *grctx; - int ret, i; - - grch = kzalloc(sizeof(*grch), GFP_KERNEL); - if (!grch) - return -ENOMEM; - chan->engctx[NVOBJ_ENGINE_GR] = grch; - - ret = nouveau_gpuobj_new(dev, chan, priv->grctx_size, 256, - NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC, - &grch->grctx); - if (ret) - goto error; - grctx = grch->grctx; - - ret = nvc0_graph_create_context_mmio_list(chan); - if (ret) - goto error; - - nv_wo32(chan->ramin, 0x0210, lower_32_bits(grctx->linst) | 4); - nv_wo32(chan->ramin, 0x0214, upper_32_bits(grctx->linst)); - pinstmem->flush(dev); - - if (!priv->grctx_vals) { - ret = nvc0_graph_construct_context(chan); - if (ret) - goto error; - } - - for (i = 0; i < priv->grctx_size; i += 4) - nv_wo32(grctx, i, priv->grctx_vals[i / 4]); - - if (!nouveau_ctxfw) { - nv_wo32(grctx, 0x00, grch->mmio_nr); - nv_wo32(grctx, 0x04, grch->mmio->linst >> 8); - } else { - nv_wo32(grctx, 0xf4, 0); - nv_wo32(grctx, 0xf8, 0); - nv_wo32(grctx, 0x10, grch->mmio_nr); - nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->linst)); - nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->linst)); - nv_wo32(grctx, 0x1c, 1); - nv_wo32(grctx, 0x20, 0); - nv_wo32(grctx, 0x28, 0); - nv_wo32(grctx, 0x2c, 0); - } - pinstmem->flush(dev); - return 0; - -error: - priv->base.context_del(chan, engine); - return ret; -} - -static void -nvc0_graph_context_del(struct nouveau_channel *chan, int engine) -{ - struct nvc0_graph_chan *grch = chan->engctx[engine]; - - nouveau_gpuobj_ref(NULL, &grch->mmio); - nouveau_gpuobj_ref(NULL, &grch->unk418810); - nouveau_gpuobj_ref(NULL, &grch->unk40800c); - nouveau_gpuobj_ref(NULL, &grch->unk408004); - nouveau_gpuobj_ref(NULL, &grch->grctx); - chan->engctx[engine] = NULL; -} - -static int -nvc0_graph_object_new(struct nouveau_channel *chan, int engine, - u32 handle, u16 class) -{ - return 0; -} - -static int -nvc0_graph_fini(struct drm_device *dev, int engine, bool suspend) -{ - return 0; -} - -static void -nvc0_graph_init_obj418880(struct drm_device *dev) -{ - struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - int i; - - nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000); - nv_wr32(dev, GPC_BCAST(0x08a4), 0x00000000); - for (i = 0; i < 4; i++) - nv_wr32(dev, GPC_BCAST(0x0888) + (i * 4), 0x00000000); - nv_wr32(dev, GPC_BCAST(0x08b4), priv->unk4188b4->vinst >> 8); - nv_wr32(dev, GPC_BCAST(0x08b8), priv->unk4188b8->vinst >> 8); -} - -static void -nvc0_graph_init_regs(struct drm_device *dev) -{ - nv_wr32(dev, 0x400080, 0x003083c2); - nv_wr32(dev, 0x400088, 0x00006fe7); - nv_wr32(dev, 0x40008c, 0x00000000); - nv_wr32(dev, 0x400090, 0x00000030); - nv_wr32(dev, 0x40013c, 0x013901f7); - nv_wr32(dev, 0x400140, 0x00000100); - nv_wr32(dev, 0x400144, 0x00000000); - nv_wr32(dev, 0x400148, 0x00000110); - nv_wr32(dev, 0x400138, 0x00000000); - nv_wr32(dev, 0x400130, 0x00000000); - nv_wr32(dev, 0x400134, 0x00000000); - nv_wr32(dev, 0x400124, 0x00000002); -} - -static void -nvc0_graph_init_gpc_0(struct drm_device *dev) -{ - struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tp_total); - u32 data[TP_MAX / 8]; - u8 tpnr[GPC_MAX]; - int i, gpc, tpc; - - nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */ - - /* - * TP ROP UNKVAL(magic_not_rop_nr) - * 450: 4/0/0/0 2 3 - * 460: 3/4/0/0 4 1 - * 465: 3/4/4/0 4 7 - * 470: 3/3/4/4 5 5 - * 480: 3/4/4/4 6 6 - */ - - memset(data, 0x00, sizeof(data)); - memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); - for (i = 0, gpc = -1; i < priv->tp_total; i++) { - do { - gpc = (gpc + 1) % priv->gpc_nr; - } while (!tpnr[gpc]); - tpc = priv->tp_nr[gpc] - tpnr[gpc]--; - - data[i / 8] |= tpc << ((i % 8) * 4); - } - - nv_wr32(dev, GPC_BCAST(0x0980), data[0]); - nv_wr32(dev, GPC_BCAST(0x0984), data[1]); - nv_wr32(dev, GPC_BCAST(0x0988), data[2]); - nv_wr32(dev, GPC_BCAST(0x098c), data[3]); - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 | - priv->tp_nr[gpc]); - nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tp_total); - nv_wr32(dev, GPC_UNIT(gpc, 0x0918), magicgpc918); - } - - nv_wr32(dev, GPC_BCAST(0x1bd4), magicgpc918); - nv_wr32(dev, GPC_BCAST(0x08ac), nv_rd32(dev, 0x100800)); -} - -static void -nvc0_graph_init_units(struct drm_device *dev) -{ - nv_wr32(dev, 0x409c24, 0x000f0000); - nv_wr32(dev, 0x404000, 0xc0000000); /* DISPATCH */ - nv_wr32(dev, 0x404600, 0xc0000000); /* M2MF */ - nv_wr32(dev, 0x408030, 0xc0000000); - nv_wr32(dev, 0x40601c, 0xc0000000); - nv_wr32(dev, 0x404490, 0xc0000000); /* MACRO */ - nv_wr32(dev, 0x406018, 0xc0000000); - nv_wr32(dev, 0x405840, 0xc0000000); - nv_wr32(dev, 0x405844, 0x00ffffff); - nv_mask(dev, 0x419cc0, 0x00000008, 0x00000008); - nv_mask(dev, 0x419eb4, 0x00001000, 0x00001000); -} - -static void -nvc0_graph_init_gpc_1(struct drm_device *dev) -{ - struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - int gpc, tp; - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - nv_wr32(dev, GPC_UNIT(gpc, 0x0420), 0xc0000000); - nv_wr32(dev, GPC_UNIT(gpc, 0x0900), 0xc0000000); - nv_wr32(dev, GPC_UNIT(gpc, 0x1028), 0xc0000000); - nv_wr32(dev, GPC_UNIT(gpc, 0x0824), 0xc0000000); - for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { - nv_wr32(dev, TP_UNIT(gpc, tp, 0x508), 0xffffffff); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x50c), 0xffffffff); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x224), 0xc0000000); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x48c), 0xc0000000); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x084), 0xc0000000); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x644), 0x001ffffe); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x64c), 0x0000000f); - } - nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff); - nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff); - } -} - -static void -nvc0_graph_init_rop(struct drm_device *dev) -{ - struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - int rop; - - for (rop = 0; rop < priv->rop_nr; rop++) { - nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000); - nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000); - nv_wr32(dev, ROP_UNIT(rop, 0x204), 0xffffffff); - nv_wr32(dev, ROP_UNIT(rop, 0x208), 0xffffffff); - } -} - -static void -nvc0_graph_init_fuc(struct drm_device *dev, u32 fuc_base, - struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data) -{ - int i; - - nv_wr32(dev, fuc_base + 0x01c0, 0x01000000); - for (i = 0; i < data->size / 4; i++) - nv_wr32(dev, fuc_base + 0x01c4, data->data[i]); - - nv_wr32(dev, fuc_base + 0x0180, 0x01000000); - for (i = 0; i < code->size / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(dev, fuc_base + 0x0188, i >> 6); - nv_wr32(dev, fuc_base + 0x0184, code->data[i]); - } -} - -static int -nvc0_graph_init_ctxctl(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR); - u32 r000260; - int i; - - if (!nouveau_ctxfw) { - /* load HUB microcode */ - r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000); - nv_wr32(dev, 0x4091c0, 0x01000000); - for (i = 0; i < sizeof(nvc0_grhub_data) / 4; i++) - nv_wr32(dev, 0x4091c4, nvc0_grhub_data[i]); - - nv_wr32(dev, 0x409180, 0x01000000); - for (i = 0; i < sizeof(nvc0_grhub_code) / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(dev, 0x409188, i >> 6); - nv_wr32(dev, 0x409184, nvc0_grhub_code[i]); - } - - /* load GPC microcode */ - nv_wr32(dev, 0x41a1c0, 0x01000000); - for (i = 0; i < sizeof(nvc0_grgpc_data) / 4; i++) - nv_wr32(dev, 0x41a1c4, nvc0_grgpc_data[i]); - - nv_wr32(dev, 0x41a180, 0x01000000); - for (i = 0; i < sizeof(nvc0_grgpc_code) / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(dev, 0x41a188, i >> 6); - nv_wr32(dev, 0x41a184, nvc0_grgpc_code[i]); - } - nv_wr32(dev, 0x000260, r000260); - - /* start HUB ucode running, it'll init the GPCs */ - nv_wr32(dev, 0x409800, dev_priv->chipset); - nv_wr32(dev, 0x40910c, 0x00000000); - nv_wr32(dev, 0x409100, 0x00000002); - if (!nv_wait(dev, 0x409800, 0x80000000, 0x80000000)) { - NV_ERROR(dev, "PGRAPH: HUB_INIT timed out\n"); - nvc0_graph_ctxctl_debug(dev); - return -EBUSY; - } - - priv->grctx_size = nv_rd32(dev, 0x409804); - return 0; - } - - /* load fuc microcode */ - r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000); - nvc0_graph_init_fuc(dev, 0x409000, &priv->fuc409c, &priv->fuc409d); - nvc0_graph_init_fuc(dev, 0x41a000, &priv->fuc41ac, &priv->fuc41ad); - nv_wr32(dev, 0x000260, r000260); - - /* start both of them running */ - nv_wr32(dev, 0x409840, 0xffffffff); - nv_wr32(dev, 0x41a10c, 0x00000000); - nv_wr32(dev, 0x40910c, 0x00000000); - nv_wr32(dev, 0x41a100, 0x00000002); - nv_wr32(dev, 0x409100, 0x00000002); - if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000001)) - NV_INFO(dev, "0x409800 wait failed\n"); - - nv_wr32(dev, 0x409840, 0xffffffff); - nv_wr32(dev, 0x409500, 0x7fffffff); - nv_wr32(dev, 0x409504, 0x00000021); - - nv_wr32(dev, 0x409840, 0xffffffff); - nv_wr32(dev, 0x409500, 0x00000000); - nv_wr32(dev, 0x409504, 0x00000010); - if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) { - NV_ERROR(dev, "fuc09 req 0x10 timeout\n"); - return -EBUSY; - } - priv->grctx_size = nv_rd32(dev, 0x409800); - - nv_wr32(dev, 0x409840, 0xffffffff); - nv_wr32(dev, 0x409500, 0x00000000); - nv_wr32(dev, 0x409504, 0x00000016); - if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) { - NV_ERROR(dev, "fuc09 req 0x16 timeout\n"); - return -EBUSY; - } - - nv_wr32(dev, 0x409840, 0xffffffff); - nv_wr32(dev, 0x409500, 0x00000000); - nv_wr32(dev, 0x409504, 0x00000025); - if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) { - NV_ERROR(dev, "fuc09 req 0x25 timeout\n"); - return -EBUSY; - } - - return 0; -} - -static int -nvc0_graph_init(struct drm_device *dev, int engine) -{ - int ret; - - nv_mask(dev, 0x000200, 0x18001000, 0x00000000); - nv_mask(dev, 0x000200, 0x18001000, 0x18001000); - - nvc0_graph_init_obj418880(dev); - nvc0_graph_init_regs(dev); - /*nvc0_graph_init_unitplemented_magics(dev);*/ - nvc0_graph_init_gpc_0(dev); - /*nvc0_graph_init_unitplemented_c242(dev);*/ - - nv_wr32(dev, 0x400500, 0x00010001); - nv_wr32(dev, 0x400100, 0xffffffff); - nv_wr32(dev, 0x40013c, 0xffffffff); - - nvc0_graph_init_units(dev); - nvc0_graph_init_gpc_1(dev); - nvc0_graph_init_rop(dev); - - nv_wr32(dev, 0x400108, 0xffffffff); - nv_wr32(dev, 0x400138, 0xffffffff); - nv_wr32(dev, 0x400118, 0xffffffff); - nv_wr32(dev, 0x400130, 0xffffffff); - nv_wr32(dev, 0x40011c, 0xffffffff); - nv_wr32(dev, 0x400134, 0xffffffff); - nv_wr32(dev, 0x400054, 0x34ce3464); - - ret = nvc0_graph_init_ctxctl(dev); - if (ret) - return ret; - - return 0; -} - -int -nvc0_graph_isr_chid(struct drm_device *dev, u64 inst) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan; - unsigned long flags; - int i; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->ramin) - continue; - - if (inst == chan->ramin->vinst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return i; -} - -static void -nvc0_graph_ctxctl_isr(struct drm_device *dev) -{ - u32 ustat = nv_rd32(dev, 0x409c18); - - if (ustat & 0x00000001) - NV_INFO(dev, "PGRAPH: CTXCTRL ucode error\n"); - if (ustat & 0x00080000) - NV_INFO(dev, "PGRAPH: CTXCTRL watchdog timeout\n"); - if (ustat & ~0x00080001) - NV_INFO(dev, "PGRAPH: CTXCTRL 0x%08x\n", ustat); - - nvc0_graph_ctxctl_debug(dev); - nv_wr32(dev, 0x409c20, ustat); -} - -static void -nvc0_graph_isr(struct drm_device *dev) -{ - u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12; - u32 chid = nvc0_graph_isr_chid(dev, inst); - u32 stat = nv_rd32(dev, 0x400100); - u32 addr = nv_rd32(dev, 0x400704); - u32 mthd = (addr & 0x00003ffc); - u32 subc = (addr & 0x00070000) >> 16; - u32 data = nv_rd32(dev, 0x400708); - u32 code = nv_rd32(dev, 0x400110); - u32 class = nv_rd32(dev, 0x404200 + (subc * 4)); - - if (stat & 0x00000010) { - if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) { - NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] " - "subc %d class 0x%04x mthd 0x%04x " - "data 0x%08x\n", - chid, inst, subc, class, mthd, data); - } - nv_wr32(dev, 0x400100, 0x00000010); - stat &= ~0x00000010; - } - - if (stat & 0x00000020) { - NV_INFO(dev, "PGRAPH: ILLEGAL_CLASS ch %d [0x%010llx] subc %d " - "class 0x%04x mthd 0x%04x data 0x%08x\n", - chid, inst, subc, class, mthd, data); - nv_wr32(dev, 0x400100, 0x00000020); - stat &= ~0x00000020; - } - - if (stat & 0x00100000) { - NV_INFO(dev, "PGRAPH: DATA_ERROR ["); - nouveau_enum_print(nv50_data_error_names, code); - printk("] ch %d [0x%010llx] subc %d class 0x%04x " - "mthd 0x%04x data 0x%08x\n", - chid, inst, subc, class, mthd, data); - nv_wr32(dev, 0x400100, 0x00100000); - stat &= ~0x00100000; - } - - if (stat & 0x00200000) { - u32 trap = nv_rd32(dev, 0x400108); - NV_INFO(dev, "PGRAPH: TRAP ch %d status 0x%08x\n", chid, trap); - nv_wr32(dev, 0x400108, trap); - nv_wr32(dev, 0x400100, 0x00200000); - stat &= ~0x00200000; - } - - if (stat & 0x00080000) { - nvc0_graph_ctxctl_isr(dev); - nv_wr32(dev, 0x400100, 0x00080000); - stat &= ~0x00080000; - } - - if (stat) { - NV_INFO(dev, "PGRAPH: unknown stat 0x%08x\n", stat); - nv_wr32(dev, 0x400100, stat); - } - - nv_wr32(dev, 0x400500, 0x00010001); -} - -static int -nvc0_graph_create_fw(struct drm_device *dev, const char *fwname, - struct nvc0_graph_fuc *fuc) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - const struct firmware *fw; - char f[32]; - int ret; - - snprintf(f, sizeof(f), "nouveau/nv%02x_%s", dev_priv->chipset, fwname); - ret = request_firmware(&fw, f, &dev->pdev->dev); - if (ret) { - snprintf(f, sizeof(f), "nouveau/%s", fwname); - ret = request_firmware(&fw, f, &dev->pdev->dev); - if (ret) { - NV_ERROR(dev, "failed to load %s\n", fwname); - return ret; - } - } - - fuc->size = fw->size; - fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL); - release_firmware(fw); - return (fuc->data != NULL) ? 0 : -ENOMEM; -} - -static void -nvc0_graph_destroy_fw(struct nvc0_graph_fuc *fuc) -{ - if (fuc->data) { - kfree(fuc->data); - fuc->data = NULL; - } -} - -static void -nvc0_graph_destroy(struct drm_device *dev, int engine) -{ - struct nvc0_graph_priv *priv = nv_engine(dev, engine); - - if (nouveau_ctxfw) { - nvc0_graph_destroy_fw(&priv->fuc409c); - nvc0_graph_destroy_fw(&priv->fuc409d); - nvc0_graph_destroy_fw(&priv->fuc41ac); - nvc0_graph_destroy_fw(&priv->fuc41ad); - } - - nouveau_irq_unregister(dev, 12); - - nouveau_gpuobj_ref(NULL, &priv->unk4188b8); - nouveau_gpuobj_ref(NULL, &priv->unk4188b4); - - if (priv->grctx_vals) - kfree(priv->grctx_vals); - - NVOBJ_ENGINE_DEL(dev, GR); - kfree(priv); -} - -int -nvc0_graph_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_graph_priv *priv; - int ret, gpc, i; - u32 fermi; - - fermi = nvc0_graph_class(dev); - if (!fermi) { - NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n"); - return 0; - } - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->base.destroy = nvc0_graph_destroy; - priv->base.init = nvc0_graph_init; - priv->base.fini = nvc0_graph_fini; - priv->base.context_new = nvc0_graph_context_new; - priv->base.context_del = nvc0_graph_context_del; - priv->base.object_new = nvc0_graph_object_new; - - NVOBJ_ENGINE_ADD(dev, GR, &priv->base); - nouveau_irq_register(dev, 12, nvc0_graph_isr); - - if (nouveau_ctxfw) { - NV_INFO(dev, "PGRAPH: using external firmware\n"); - if (nvc0_graph_create_fw(dev, "fuc409c", &priv->fuc409c) || - nvc0_graph_create_fw(dev, "fuc409d", &priv->fuc409d) || - nvc0_graph_create_fw(dev, "fuc41ac", &priv->fuc41ac) || - nvc0_graph_create_fw(dev, "fuc41ad", &priv->fuc41ad)) { - ret = 0; - goto error; - } - } - - ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4); - if (ret) - goto error; - - ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8); - if (ret) - goto error; - - for (i = 0; i < 0x1000; i += 4) { - nv_wo32(priv->unk4188b4, i, 0x00000010); - nv_wo32(priv->unk4188b8, i, 0x00000010); - } - - priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f; - priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16; - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608)); - priv->tp_total += priv->tp_nr[gpc]; - } - - /*XXX: these need figuring out... */ - switch (dev_priv->chipset) { - case 0xc0: - if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ - priv->magic_not_rop_nr = 0x07; - } else - if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ - priv->magic_not_rop_nr = 0x05; - } else - if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ - priv->magic_not_rop_nr = 0x06; - } - break; - case 0xc3: /* 450, 4/0/0/0, 2 */ - priv->magic_not_rop_nr = 0x03; - break; - case 0xc4: /* 460, 3/4/0/0, 4 */ - priv->magic_not_rop_nr = 0x01; - break; - case 0xc1: /* 2/0/0/0, 1 */ - priv->magic_not_rop_nr = 0x01; - break; - case 0xc8: /* 4/4/3/4, 5 */ - priv->magic_not_rop_nr = 0x06; - break; - case 0xce: /* 4/4/0/0, 4 */ - priv->magic_not_rop_nr = 0x03; - break; - case 0xcf: /* 4/0/0/0, 3 */ - priv->magic_not_rop_nr = 0x03; - break; - case 0xd9: /* 1/0/0/0, 1 */ - priv->magic_not_rop_nr = 0x01; - break; - } - - if (!priv->magic_not_rop_nr) { - NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", - priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], - priv->tp_nr[3], priv->rop_nr); - priv->magic_not_rop_nr = 0x00; - } - - NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ - NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ - NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ - if (fermi >= 0x9197) - NVOBJ_CLASS(dev, 0x9197, GR); /* 3D (NVC1-) */ - if (fermi >= 0x9297) - NVOBJ_CLASS(dev, 0x9297, GR); /* 3D (NVC8-) */ - NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */ - return 0; - -error: - nvc0_graph_destroy(dev, NVOBJ_ENGINE_GR); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.fuc b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.fuc deleted file mode 100644 index e6b22884..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.fuc +++ /dev/null @@ -1,400 +0,0 @@ -/* fuc microcode util functions for nvc0 PGRAPH - * - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)') -define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))') - -ifdef(`include_code', ` -// Error codes -define(`E_BAD_COMMAND', 0x01) -define(`E_CMD_OVERFLOW', 0x02) - -// Util macros to help with debugging ucode hangs etc -define(`T_WAIT', 0) -define(`T_MMCTX', 1) -define(`T_STRWAIT', 2) -define(`T_STRINIT', 3) -define(`T_AUTO', 4) -define(`T_CHAN', 5) -define(`T_LOAD', 6) -define(`T_SAVE', 7) -define(`T_LCHAN', 8) -define(`T_LCTXH', 9) - -define(`trace_set', ` - mov $r8 0x83c - shl b32 $r8 6 - clear b32 $r9 - bset $r9 $1 - iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] -') - -define(`trace_clr', ` - mov $r8 0x85c - shl b32 $r8 6 - clear b32 $r9 - bset $r9 $1 - iowr I[$r8 + 0x000] $r9 // CC_SCRATCH[7] -') - -// queue_put - add request to queue -// -// In : $r13 queue pointer -// $r14 command -// $r15 data -// -queue_put: - // make sure we have space.. - ld b32 $r8 D[$r13 + 0x0] // GET - ld b32 $r9 D[$r13 + 0x4] // PUT - xor $r8 8 - cmpu b32 $r8 $r9 - bra ne #queue_put_next - mov $r15 E_CMD_OVERFLOW - call #error - ret - - // store cmd/data on queue - queue_put_next: - and $r8 $r9 7 - shl b32 $r8 3 - add b32 $r8 $r13 - add b32 $r8 8 - st b32 D[$r8 + 0x0] $r14 - st b32 D[$r8 + 0x4] $r15 - - // update PUT - add b32 $r9 1 - and $r9 0xf - st b32 D[$r13 + 0x4] $r9 - ret - -// queue_get - fetch request from queue -// -// In : $r13 queue pointer -// -// Out: $p1 clear on success (data available) -// $r14 command -// $r15 data -// -queue_get: - bset $flags $p1 - ld b32 $r8 D[$r13 + 0x0] // GET - ld b32 $r9 D[$r13 + 0x4] // PUT - cmpu b32 $r8 $r9 - bra e #queue_get_done - // fetch first cmd/data pair - and $r9 $r8 7 - shl b32 $r9 3 - add b32 $r9 $r13 - add b32 $r9 8 - ld b32 $r14 D[$r9 + 0x0] - ld b32 $r15 D[$r9 + 0x4] - - // update GET - add b32 $r8 1 - and $r8 0xf - st b32 D[$r13 + 0x0] $r8 - bclr $flags $p1 -queue_get_done: - ret - -// nv_rd32 - read 32-bit value from nv register -// -// In : $r14 register -// Out: $r15 value -// -nv_rd32: - mov $r11 0x728 - shl b32 $r11 6 - mov b32 $r12 $r14 - bset $r12 31 // MMIO_CTRL_PENDING - iowr I[$r11 + 0x000] $r12 // MMIO_CTRL - nv_rd32_wait: - iord $r12 I[$r11 + 0x000] - xbit $r12 $r12 31 - bra ne #nv_rd32_wait - mov $r10 6 // DONE_MMIO_RD - call #wait_doneo - iord $r15 I[$r11 + 0x100] // MMIO_RDVAL - ret - -// nv_wr32 - write 32-bit value to nv register -// -// In : $r14 register -// $r15 value -// -nv_wr32: - mov $r11 0x728 - shl b32 $r11 6 - iowr I[$r11 + 0x200] $r15 // MMIO_WRVAL - mov b32 $r12 $r14 - bset $r12 31 // MMIO_CTRL_PENDING - bset $r12 30 // MMIO_CTRL_WRITE - iowr I[$r11 + 0x000] $r12 // MMIO_CTRL - nv_wr32_wait: - iord $r12 I[$r11 + 0x000] - xbit $r12 $r12 31 - bra ne #nv_wr32_wait - ret - -// (re)set watchdog timer -// -// In : $r15 timeout -// -watchdog_reset: - mov $r8 0x430 - shl b32 $r8 6 - bset $r15 31 - iowr I[$r8 + 0x000] $r15 - ret - -// clear watchdog timer -watchdog_clear: - mov $r8 0x430 - shl b32 $r8 6 - iowr I[$r8 + 0x000] $r0 - ret - -// wait_done{z,o} - wait on FUC_DONE bit to become clear/set -// -// In : $r10 bit to wait on -// -define(`wait_done', ` -$1: - trace_set(T_WAIT); - mov $r8 0x818 - shl b32 $r8 6 - iowr I[$r8 + 0x000] $r10 // CC_SCRATCH[6] = wait bit - wait_done_$1: - mov $r8 0x400 - shl b32 $r8 6 - iord $r8 I[$r8 + 0x000] // DONE - xbit $r8 $r8 $r10 - bra $2 #wait_done_$1 - trace_clr(T_WAIT) - ret -') -wait_done(wait_donez, ne) -wait_done(wait_doneo, e) - -// mmctx_size - determine size of a mmio list transfer -// -// In : $r14 mmio list head -// $r15 mmio list tail -// Out: $r15 transfer size (in bytes) -// -mmctx_size: - clear b32 $r9 - nv_mmctx_size_loop: - ld b32 $r8 D[$r14] - shr b32 $r8 26 - add b32 $r8 1 - shl b32 $r8 2 - add b32 $r9 $r8 - add b32 $r14 4 - cmpu b32 $r14 $r15 - bra ne #nv_mmctx_size_loop - mov b32 $r15 $r9 - ret - -// mmctx_xfer - execute a list of mmio transfers -// -// In : $r10 flags -// bit 0: direction (0 = save, 1 = load) -// bit 1: set if first transfer -// bit 2: set if last transfer -// $r11 base -// $r12 mmio list head -// $r13 mmio list tail -// $r14 multi_stride -// $r15 multi_mask -// -mmctx_xfer: - trace_set(T_MMCTX) - mov $r8 0x710 - shl b32 $r8 6 - clear b32 $r9 - or $r11 $r11 - bra e #mmctx_base_disabled - iowr I[$r8 + 0x000] $r11 // MMCTX_BASE - bset $r9 0 // BASE_EN - mmctx_base_disabled: - or $r14 $r14 - bra e #mmctx_multi_disabled - iowr I[$r8 + 0x200] $r14 // MMCTX_MULTI_STRIDE - iowr I[$r8 + 0x300] $r15 // MMCTX_MULTI_MASK - bset $r9 1 // MULTI_EN - mmctx_multi_disabled: - add b32 $r8 0x100 - - xbit $r11 $r10 0 - shl b32 $r11 16 // DIR - bset $r11 12 // QLIMIT = 0x10 - xbit $r14 $r10 1 - shl b32 $r14 17 - or $r11 $r14 // START_TRIGGER - iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL - - // loop over the mmio list, and send requests to the hw - mmctx_exec_loop: - // wait for space in mmctx queue - mmctx_wait_free: - iord $r14 I[$r8 + 0x000] // MMCTX_CTRL - and $r14 0x1f - bra e #mmctx_wait_free - - // queue up an entry - ld b32 $r14 D[$r12] - or $r14 $r9 - iowr I[$r8 + 0x300] $r14 - add b32 $r12 4 - cmpu b32 $r12 $r13 - bra ne #mmctx_exec_loop - - xbit $r11 $r10 2 - bra ne #mmctx_stop - // wait for queue to empty - mmctx_fini_wait: - iord $r11 I[$r8 + 0x000] // MMCTX_CTRL - and $r11 0x1f - cmpu b32 $r11 0x10 - bra ne #mmctx_fini_wait - mov $r10 2 // DONE_MMCTX - call #wait_donez - bra #mmctx_done - mmctx_stop: - xbit $r11 $r10 0 - shl b32 $r11 16 // DIR - bset $r11 12 // QLIMIT = 0x10 - bset $r11 18 // STOP_TRIGGER - iowr I[$r8 + 0x000] $r11 // MMCTX_CTRL - mmctx_stop_wait: - // wait for STOP_TRIGGER to clear - iord $r11 I[$r8 + 0x000] // MMCTX_CTRL - xbit $r11 $r11 18 - bra ne #mmctx_stop_wait - mmctx_done: - trace_clr(T_MMCTX) - ret - -// Wait for DONE_STRAND -// -strand_wait: - push $r10 - mov $r10 2 - call #wait_donez - pop $r10 - ret - -// unknown - call before issuing strand commands -// -strand_pre: - mov $r8 0x4afc - sethi $r8 0x20000 - mov $r9 0xc - iowr I[$r8] $r9 - call #strand_wait - ret - -// unknown - call after issuing strand commands -// -strand_post: - mov $r8 0x4afc - sethi $r8 0x20000 - mov $r9 0xd - iowr I[$r8] $r9 - call #strand_wait - ret - -// Selects strand set?! -// -// In: $r14 id -// -strand_set: - mov $r10 0x4ffc - sethi $r10 0x20000 - sub b32 $r11 $r10 0x500 - mov $r12 0xf - iowr I[$r10 + 0x000] $r12 // 0x93c = 0xf - mov $r12 0xb - iowr I[$r11 + 0x000] $r12 // 0x928 = 0xb - call #strand_wait - iowr I[$r10 + 0x000] $r14 // 0x93c = - mov $r12 0xa - iowr I[$r11 + 0x000] $r12 // 0x928 = 0xa - call #strand_wait - ret - -// Initialise strand context data -// -// In : $r15 context base -// Out: $r15 context size (in bytes) -// -// Strandset(?) 3 hardcoded currently -// -strand_ctx_init: - trace_set(T_STRINIT) - call #strand_pre - mov $r14 3 - call #strand_set - mov $r10 0x46fc - sethi $r10 0x20000 - add b32 $r11 $r10 0x400 - iowr I[$r10 + 0x100] $r0 // STRAND_FIRST_GENE = 0 - mov $r12 1 - iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_FIRST_GENE - call #strand_wait - sub b32 $r12 $r0 1 - iowr I[$r10 + 0x000] $r12 // STRAND_GENE_CNT = 0xffffffff - mov $r12 2 - iowr I[$r11 + 0x000] $r12 // STRAND_CMD = LATCH_GENE_CNT - call #strand_wait - call #strand_post - - // read the size of each strand, poke the context offset of - // each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry - // about it later then. - mov $r8 0x880 - shl b32 $r8 6 - iord $r9 I[$r8 + 0x000] // STRANDS - add b32 $r8 0x2200 - shr b32 $r14 $r15 8 - ctx_init_strand_loop: - iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE - iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE - iord $r10 I[$r8 + 0x200] // STRAND_SIZE - shr b32 $r10 6 - add b32 $r10 1 - add b32 $r14 $r10 - add b32 $r8 4 - sub b32 $r9 1 - bra ne #ctx_init_strand_loop - - shl b32 $r14 8 - sub b32 $r15 $r14 $r15 - trace_clr(T_STRINIT) - ret -') diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.h deleted file mode 100644 index 91d44ea6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_graph.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#ifndef __NVC0_GRAPH_H__ -#define __NVC0_GRAPH_H__ - -#define GPC_MAX 4 -#define TP_MAX 32 - -#define ROP_BCAST(r) (0x408800 + (r)) -#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) -#define GPC_BCAST(r) (0x418000 + (r)) -#define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r)) -#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) - -struct nvc0_graph_fuc { - u32 *data; - u32 size; -}; - -struct nvc0_graph_priv { - struct nouveau_exec_engine base; - - struct nvc0_graph_fuc fuc409c; - struct nvc0_graph_fuc fuc409d; - struct nvc0_graph_fuc fuc41ac; - struct nvc0_graph_fuc fuc41ad; - - u8 gpc_nr; - u8 rop_nr; - u8 tp_nr[GPC_MAX]; - u8 tp_total; - - u32 grctx_size; - u32 *grctx_vals; - struct nouveau_gpuobj *unk4188b4; - struct nouveau_gpuobj *unk4188b8; - - u8 magic_not_rop_nr; -}; - -struct nvc0_graph_chan { - struct nouveau_gpuobj *grctx; - struct nouveau_gpuobj *unk408004; /* 0x418810 too */ - struct nouveau_gpuobj *unk40800c; /* 0x419004 too */ - struct nouveau_gpuobj *unk418810; /* 0x419848 too */ - struct nouveau_gpuobj *mmio; - int mmio_nr; -}; - -int nvc0_grctx_generate(struct nouveau_channel *); - -/* nvc0_graph.c uses this also to determine supported chipsets */ -static inline u32 -nvc0_graph_class(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - switch (dev_priv->chipset) { - case 0xc0: - case 0xc3: - case 0xc4: - case 0xce: /* guess, mmio trace shows only 0x9097 state */ - case 0xcf: /* guess, mmio trace shows only 0x9097 state */ - return 0x9097; - case 0xc1: - return 0x9197; - case 0xc8: - case 0xd9: - return 0x9297; - default: - return 0; - } -} - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grctx.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grctx.c deleted file mode 100644 index de77842b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grctx.c +++ /dev/null @@ -1,2878 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_mm.h" -#include "nvc0_graph.h" - -static void -nv_icmd(struct drm_device *dev, u32 icmd, u32 data) -{ - nv_wr32(dev, 0x400204, data); - nv_wr32(dev, 0x400200, icmd); - while (nv_rd32(dev, 0x400700) & 2) {} -} - -static void -nv_mthd(struct drm_device *dev, u32 class, u32 mthd, u32 data) -{ - nv_wr32(dev, 0x40448c, data); - nv_wr32(dev, 0x404488, 0x80000000 | (mthd << 14) | class); -} - -static void -nvc0_grctx_generate_9097(struct drm_device *dev) -{ - u32 fermi = nvc0_graph_class(dev); - u32 mthd; - - nv_mthd(dev, 0x9097, 0x0800, 0x00000000); - nv_mthd(dev, 0x9097, 0x0840, 0x00000000); - nv_mthd(dev, 0x9097, 0x0880, 0x00000000); - nv_mthd(dev, 0x9097, 0x08c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0900, 0x00000000); - nv_mthd(dev, 0x9097, 0x0940, 0x00000000); - nv_mthd(dev, 0x9097, 0x0980, 0x00000000); - nv_mthd(dev, 0x9097, 0x09c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0804, 0x00000000); - nv_mthd(dev, 0x9097, 0x0844, 0x00000000); - nv_mthd(dev, 0x9097, 0x0884, 0x00000000); - nv_mthd(dev, 0x9097, 0x08c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0904, 0x00000000); - nv_mthd(dev, 0x9097, 0x0944, 0x00000000); - nv_mthd(dev, 0x9097, 0x0984, 0x00000000); - nv_mthd(dev, 0x9097, 0x09c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0808, 0x00000400); - nv_mthd(dev, 0x9097, 0x0848, 0x00000400); - nv_mthd(dev, 0x9097, 0x0888, 0x00000400); - nv_mthd(dev, 0x9097, 0x08c8, 0x00000400); - nv_mthd(dev, 0x9097, 0x0908, 0x00000400); - nv_mthd(dev, 0x9097, 0x0948, 0x00000400); - nv_mthd(dev, 0x9097, 0x0988, 0x00000400); - nv_mthd(dev, 0x9097, 0x09c8, 0x00000400); - nv_mthd(dev, 0x9097, 0x080c, 0x00000300); - nv_mthd(dev, 0x9097, 0x084c, 0x00000300); - nv_mthd(dev, 0x9097, 0x088c, 0x00000300); - nv_mthd(dev, 0x9097, 0x08cc, 0x00000300); - nv_mthd(dev, 0x9097, 0x090c, 0x00000300); - nv_mthd(dev, 0x9097, 0x094c, 0x00000300); - nv_mthd(dev, 0x9097, 0x098c, 0x00000300); - nv_mthd(dev, 0x9097, 0x09cc, 0x00000300); - nv_mthd(dev, 0x9097, 0x0810, 0x000000cf); - nv_mthd(dev, 0x9097, 0x0850, 0x00000000); - nv_mthd(dev, 0x9097, 0x0890, 0x00000000); - nv_mthd(dev, 0x9097, 0x08d0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0910, 0x00000000); - nv_mthd(dev, 0x9097, 0x0950, 0x00000000); - nv_mthd(dev, 0x9097, 0x0990, 0x00000000); - nv_mthd(dev, 0x9097, 0x09d0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0814, 0x00000040); - nv_mthd(dev, 0x9097, 0x0854, 0x00000040); - nv_mthd(dev, 0x9097, 0x0894, 0x00000040); - nv_mthd(dev, 0x9097, 0x08d4, 0x00000040); - nv_mthd(dev, 0x9097, 0x0914, 0x00000040); - nv_mthd(dev, 0x9097, 0x0954, 0x00000040); - nv_mthd(dev, 0x9097, 0x0994, 0x00000040); - nv_mthd(dev, 0x9097, 0x09d4, 0x00000040); - nv_mthd(dev, 0x9097, 0x0818, 0x00000001); - nv_mthd(dev, 0x9097, 0x0858, 0x00000001); - nv_mthd(dev, 0x9097, 0x0898, 0x00000001); - nv_mthd(dev, 0x9097, 0x08d8, 0x00000001); - nv_mthd(dev, 0x9097, 0x0918, 0x00000001); - nv_mthd(dev, 0x9097, 0x0958, 0x00000001); - nv_mthd(dev, 0x9097, 0x0998, 0x00000001); - nv_mthd(dev, 0x9097, 0x09d8, 0x00000001); - nv_mthd(dev, 0x9097, 0x081c, 0x00000000); - nv_mthd(dev, 0x9097, 0x085c, 0x00000000); - nv_mthd(dev, 0x9097, 0x089c, 0x00000000); - nv_mthd(dev, 0x9097, 0x08dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x091c, 0x00000000); - nv_mthd(dev, 0x9097, 0x095c, 0x00000000); - nv_mthd(dev, 0x9097, 0x099c, 0x00000000); - nv_mthd(dev, 0x9097, 0x09dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0820, 0x00000000); - nv_mthd(dev, 0x9097, 0x0860, 0x00000000); - nv_mthd(dev, 0x9097, 0x08a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x08e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0920, 0x00000000); - nv_mthd(dev, 0x9097, 0x0960, 0x00000000); - nv_mthd(dev, 0x9097, 0x09a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x09e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x2700, 0x00000000); - nv_mthd(dev, 0x9097, 0x2720, 0x00000000); - nv_mthd(dev, 0x9097, 0x2740, 0x00000000); - nv_mthd(dev, 0x9097, 0x2760, 0x00000000); - nv_mthd(dev, 0x9097, 0x2780, 0x00000000); - nv_mthd(dev, 0x9097, 0x27a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x27c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x27e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x2704, 0x00000000); - nv_mthd(dev, 0x9097, 0x2724, 0x00000000); - nv_mthd(dev, 0x9097, 0x2744, 0x00000000); - nv_mthd(dev, 0x9097, 0x2764, 0x00000000); - nv_mthd(dev, 0x9097, 0x2784, 0x00000000); - nv_mthd(dev, 0x9097, 0x27a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x27c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x27e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x2708, 0x00000000); - nv_mthd(dev, 0x9097, 0x2728, 0x00000000); - nv_mthd(dev, 0x9097, 0x2748, 0x00000000); - nv_mthd(dev, 0x9097, 0x2768, 0x00000000); - nv_mthd(dev, 0x9097, 0x2788, 0x00000000); - nv_mthd(dev, 0x9097, 0x27a8, 0x00000000); - nv_mthd(dev, 0x9097, 0x27c8, 0x00000000); - nv_mthd(dev, 0x9097, 0x27e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x270c, 0x00000000); - nv_mthd(dev, 0x9097, 0x272c, 0x00000000); - nv_mthd(dev, 0x9097, 0x274c, 0x00000000); - nv_mthd(dev, 0x9097, 0x276c, 0x00000000); - nv_mthd(dev, 0x9097, 0x278c, 0x00000000); - nv_mthd(dev, 0x9097, 0x27ac, 0x00000000); - nv_mthd(dev, 0x9097, 0x27cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x27ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x2710, 0x00014000); - nv_mthd(dev, 0x9097, 0x2730, 0x00014000); - nv_mthd(dev, 0x9097, 0x2750, 0x00014000); - nv_mthd(dev, 0x9097, 0x2770, 0x00014000); - nv_mthd(dev, 0x9097, 0x2790, 0x00014000); - nv_mthd(dev, 0x9097, 0x27b0, 0x00014000); - nv_mthd(dev, 0x9097, 0x27d0, 0x00014000); - nv_mthd(dev, 0x9097, 0x27f0, 0x00014000); - nv_mthd(dev, 0x9097, 0x2714, 0x00000040); - nv_mthd(dev, 0x9097, 0x2734, 0x00000040); - nv_mthd(dev, 0x9097, 0x2754, 0x00000040); - nv_mthd(dev, 0x9097, 0x2774, 0x00000040); - nv_mthd(dev, 0x9097, 0x2794, 0x00000040); - nv_mthd(dev, 0x9097, 0x27b4, 0x00000040); - nv_mthd(dev, 0x9097, 0x27d4, 0x00000040); - nv_mthd(dev, 0x9097, 0x27f4, 0x00000040); - nv_mthd(dev, 0x9097, 0x1c00, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c10, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c20, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c30, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c40, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c50, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c60, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c70, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c80, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c90, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ca0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cb0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cc0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cd0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ce0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cf0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c04, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c14, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c24, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c34, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c44, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c54, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c64, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c74, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c84, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c94, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ca4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cb4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cc4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cd4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ce4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cf4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c08, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c18, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c28, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c38, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c48, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c58, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c68, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c78, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c88, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c98, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ca8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cb8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cc8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cd8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ce8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cf8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c0c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c1c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c2c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c3c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c4c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c5c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c6c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c7c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1c9c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cac, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cbc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ccc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cdc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cec, 0x00000000); - nv_mthd(dev, 0x9097, 0x1cfc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d00, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d10, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d20, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d30, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d40, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d50, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d60, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d70, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d80, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d90, 0x00000000); - nv_mthd(dev, 0x9097, 0x1da0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1db0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dc0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dd0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1de0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1df0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d04, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d14, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d24, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d34, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d44, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d54, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d64, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d74, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d84, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d94, 0x00000000); - nv_mthd(dev, 0x9097, 0x1da4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1db4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dc4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dd4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1de4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1df4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d08, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d18, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d28, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d38, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d48, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d58, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d68, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d78, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d88, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d98, 0x00000000); - nv_mthd(dev, 0x9097, 0x1da8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1db8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dc8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dd8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1de8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1df8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d0c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d1c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d2c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d3c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d4c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d5c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d6c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d7c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1d9c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dac, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dbc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dcc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ddc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dec, 0x00000000); - nv_mthd(dev, 0x9097, 0x1dfc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f00, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f08, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f10, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f18, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f20, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f28, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f30, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f38, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f40, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f48, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f50, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f58, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f60, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f68, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f70, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f78, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f04, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f0c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f14, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f1c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f24, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f2c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f34, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f3c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f44, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f4c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f54, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f5c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f64, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f6c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f74, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f7c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f80, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f88, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f90, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f98, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fa0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fa8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fb0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fb8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fc0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fc8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fd0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fd8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fe0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fe8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ff0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ff8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f84, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f94, 0x00000000); - nv_mthd(dev, 0x9097, 0x1f9c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fa4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fac, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fb4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fbc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fc4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fcc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fd4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fdc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fe4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1fec, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ff4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1ffc, 0x00000000); - nv_mthd(dev, 0x9097, 0x2200, 0x00000022); - nv_mthd(dev, 0x9097, 0x2210, 0x00000022); - nv_mthd(dev, 0x9097, 0x2220, 0x00000022); - nv_mthd(dev, 0x9097, 0x2230, 0x00000022); - nv_mthd(dev, 0x9097, 0x2240, 0x00000022); - nv_mthd(dev, 0x9097, 0x2000, 0x00000000); - nv_mthd(dev, 0x9097, 0x2040, 0x00000011); - nv_mthd(dev, 0x9097, 0x2080, 0x00000020); - nv_mthd(dev, 0x9097, 0x20c0, 0x00000030); - nv_mthd(dev, 0x9097, 0x2100, 0x00000040); - nv_mthd(dev, 0x9097, 0x2140, 0x00000051); - nv_mthd(dev, 0x9097, 0x200c, 0x00000001); - nv_mthd(dev, 0x9097, 0x204c, 0x00000001); - nv_mthd(dev, 0x9097, 0x208c, 0x00000001); - nv_mthd(dev, 0x9097, 0x20cc, 0x00000001); - nv_mthd(dev, 0x9097, 0x210c, 0x00000001); - nv_mthd(dev, 0x9097, 0x214c, 0x00000001); - nv_mthd(dev, 0x9097, 0x2010, 0x00000000); - nv_mthd(dev, 0x9097, 0x2050, 0x00000000); - nv_mthd(dev, 0x9097, 0x2090, 0x00000001); - nv_mthd(dev, 0x9097, 0x20d0, 0x00000002); - nv_mthd(dev, 0x9097, 0x2110, 0x00000003); - nv_mthd(dev, 0x9097, 0x2150, 0x00000004); - nv_mthd(dev, 0x9097, 0x0380, 0x00000000); - nv_mthd(dev, 0x9097, 0x03a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x03c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x03e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0384, 0x00000000); - nv_mthd(dev, 0x9097, 0x03a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x03c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x03e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0388, 0x00000000); - nv_mthd(dev, 0x9097, 0x03a8, 0x00000000); - nv_mthd(dev, 0x9097, 0x03c8, 0x00000000); - nv_mthd(dev, 0x9097, 0x03e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x038c, 0x00000000); - nv_mthd(dev, 0x9097, 0x03ac, 0x00000000); - nv_mthd(dev, 0x9097, 0x03cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x03ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x0700, 0x00000000); - nv_mthd(dev, 0x9097, 0x0710, 0x00000000); - nv_mthd(dev, 0x9097, 0x0720, 0x00000000); - nv_mthd(dev, 0x9097, 0x0730, 0x00000000); - nv_mthd(dev, 0x9097, 0x0704, 0x00000000); - nv_mthd(dev, 0x9097, 0x0714, 0x00000000); - nv_mthd(dev, 0x9097, 0x0724, 0x00000000); - nv_mthd(dev, 0x9097, 0x0734, 0x00000000); - nv_mthd(dev, 0x9097, 0x0708, 0x00000000); - nv_mthd(dev, 0x9097, 0x0718, 0x00000000); - nv_mthd(dev, 0x9097, 0x0728, 0x00000000); - nv_mthd(dev, 0x9097, 0x0738, 0x00000000); - nv_mthd(dev, 0x9097, 0x2800, 0x00000000); - nv_mthd(dev, 0x9097, 0x2804, 0x00000000); - nv_mthd(dev, 0x9097, 0x2808, 0x00000000); - nv_mthd(dev, 0x9097, 0x280c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2810, 0x00000000); - nv_mthd(dev, 0x9097, 0x2814, 0x00000000); - nv_mthd(dev, 0x9097, 0x2818, 0x00000000); - nv_mthd(dev, 0x9097, 0x281c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2820, 0x00000000); - nv_mthd(dev, 0x9097, 0x2824, 0x00000000); - nv_mthd(dev, 0x9097, 0x2828, 0x00000000); - nv_mthd(dev, 0x9097, 0x282c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2830, 0x00000000); - nv_mthd(dev, 0x9097, 0x2834, 0x00000000); - nv_mthd(dev, 0x9097, 0x2838, 0x00000000); - nv_mthd(dev, 0x9097, 0x283c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2840, 0x00000000); - nv_mthd(dev, 0x9097, 0x2844, 0x00000000); - nv_mthd(dev, 0x9097, 0x2848, 0x00000000); - nv_mthd(dev, 0x9097, 0x284c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2850, 0x00000000); - nv_mthd(dev, 0x9097, 0x2854, 0x00000000); - nv_mthd(dev, 0x9097, 0x2858, 0x00000000); - nv_mthd(dev, 0x9097, 0x285c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2860, 0x00000000); - nv_mthd(dev, 0x9097, 0x2864, 0x00000000); - nv_mthd(dev, 0x9097, 0x2868, 0x00000000); - nv_mthd(dev, 0x9097, 0x286c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2870, 0x00000000); - nv_mthd(dev, 0x9097, 0x2874, 0x00000000); - nv_mthd(dev, 0x9097, 0x2878, 0x00000000); - nv_mthd(dev, 0x9097, 0x287c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2880, 0x00000000); - nv_mthd(dev, 0x9097, 0x2884, 0x00000000); - nv_mthd(dev, 0x9097, 0x2888, 0x00000000); - nv_mthd(dev, 0x9097, 0x288c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2890, 0x00000000); - nv_mthd(dev, 0x9097, 0x2894, 0x00000000); - nv_mthd(dev, 0x9097, 0x2898, 0x00000000); - nv_mthd(dev, 0x9097, 0x289c, 0x00000000); - nv_mthd(dev, 0x9097, 0x28a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x28a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x28a8, 0x00000000); - nv_mthd(dev, 0x9097, 0x28ac, 0x00000000); - nv_mthd(dev, 0x9097, 0x28b0, 0x00000000); - nv_mthd(dev, 0x9097, 0x28b4, 0x00000000); - nv_mthd(dev, 0x9097, 0x28b8, 0x00000000); - nv_mthd(dev, 0x9097, 0x28bc, 0x00000000); - nv_mthd(dev, 0x9097, 0x28c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x28c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x28c8, 0x00000000); - nv_mthd(dev, 0x9097, 0x28cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x28d0, 0x00000000); - nv_mthd(dev, 0x9097, 0x28d4, 0x00000000); - nv_mthd(dev, 0x9097, 0x28d8, 0x00000000); - nv_mthd(dev, 0x9097, 0x28dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x28e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x28e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x28e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x28ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x28f0, 0x00000000); - nv_mthd(dev, 0x9097, 0x28f4, 0x00000000); - nv_mthd(dev, 0x9097, 0x28f8, 0x00000000); - nv_mthd(dev, 0x9097, 0x28fc, 0x00000000); - nv_mthd(dev, 0x9097, 0x2900, 0x00000000); - nv_mthd(dev, 0x9097, 0x2904, 0x00000000); - nv_mthd(dev, 0x9097, 0x2908, 0x00000000); - nv_mthd(dev, 0x9097, 0x290c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2910, 0x00000000); - nv_mthd(dev, 0x9097, 0x2914, 0x00000000); - nv_mthd(dev, 0x9097, 0x2918, 0x00000000); - nv_mthd(dev, 0x9097, 0x291c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2920, 0x00000000); - nv_mthd(dev, 0x9097, 0x2924, 0x00000000); - nv_mthd(dev, 0x9097, 0x2928, 0x00000000); - nv_mthd(dev, 0x9097, 0x292c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2930, 0x00000000); - nv_mthd(dev, 0x9097, 0x2934, 0x00000000); - nv_mthd(dev, 0x9097, 0x2938, 0x00000000); - nv_mthd(dev, 0x9097, 0x293c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2940, 0x00000000); - nv_mthd(dev, 0x9097, 0x2944, 0x00000000); - nv_mthd(dev, 0x9097, 0x2948, 0x00000000); - nv_mthd(dev, 0x9097, 0x294c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2950, 0x00000000); - nv_mthd(dev, 0x9097, 0x2954, 0x00000000); - nv_mthd(dev, 0x9097, 0x2958, 0x00000000); - nv_mthd(dev, 0x9097, 0x295c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2960, 0x00000000); - nv_mthd(dev, 0x9097, 0x2964, 0x00000000); - nv_mthd(dev, 0x9097, 0x2968, 0x00000000); - nv_mthd(dev, 0x9097, 0x296c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2970, 0x00000000); - nv_mthd(dev, 0x9097, 0x2974, 0x00000000); - nv_mthd(dev, 0x9097, 0x2978, 0x00000000); - nv_mthd(dev, 0x9097, 0x297c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2980, 0x00000000); - nv_mthd(dev, 0x9097, 0x2984, 0x00000000); - nv_mthd(dev, 0x9097, 0x2988, 0x00000000); - nv_mthd(dev, 0x9097, 0x298c, 0x00000000); - nv_mthd(dev, 0x9097, 0x2990, 0x00000000); - nv_mthd(dev, 0x9097, 0x2994, 0x00000000); - nv_mthd(dev, 0x9097, 0x2998, 0x00000000); - nv_mthd(dev, 0x9097, 0x299c, 0x00000000); - nv_mthd(dev, 0x9097, 0x29a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x29a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x29a8, 0x00000000); - nv_mthd(dev, 0x9097, 0x29ac, 0x00000000); - nv_mthd(dev, 0x9097, 0x29b0, 0x00000000); - nv_mthd(dev, 0x9097, 0x29b4, 0x00000000); - nv_mthd(dev, 0x9097, 0x29b8, 0x00000000); - nv_mthd(dev, 0x9097, 0x29bc, 0x00000000); - nv_mthd(dev, 0x9097, 0x29c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x29c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x29c8, 0x00000000); - nv_mthd(dev, 0x9097, 0x29cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x29d0, 0x00000000); - nv_mthd(dev, 0x9097, 0x29d4, 0x00000000); - nv_mthd(dev, 0x9097, 0x29d8, 0x00000000); - nv_mthd(dev, 0x9097, 0x29dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x29e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x29e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x29e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x29ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x29f0, 0x00000000); - nv_mthd(dev, 0x9097, 0x29f4, 0x00000000); - nv_mthd(dev, 0x9097, 0x29f8, 0x00000000); - nv_mthd(dev, 0x9097, 0x29fc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a00, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a20, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a40, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a60, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a80, 0x00000000); - nv_mthd(dev, 0x9097, 0x0aa0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ac0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ae0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b00, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b20, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b40, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b60, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b80, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ba0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bc0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0be0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a04, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a24, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a44, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a64, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a84, 0x00000000); - nv_mthd(dev, 0x9097, 0x0aa4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ac4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ae4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b04, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b24, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b44, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b64, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b84, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ba4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bc4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0be4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a08, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a28, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a48, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a68, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a88, 0x00000000); - nv_mthd(dev, 0x9097, 0x0aa8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ac8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ae8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b08, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b28, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b48, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b68, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b88, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ba8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bc8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0be8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a0c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a2c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a4c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a6c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0aac, 0x00000000); - nv_mthd(dev, 0x9097, 0x0acc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0aec, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b0c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b2c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b4c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b6c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bac, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bcc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bec, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a10, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a30, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a50, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a70, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a90, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ab0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ad0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0af0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b10, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b30, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b50, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b70, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b90, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bb0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bd0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bf0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a14, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a34, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a54, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a74, 0x00000000); - nv_mthd(dev, 0x9097, 0x0a94, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ab4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ad4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0af4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b14, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b34, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b54, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b74, 0x00000000); - nv_mthd(dev, 0x9097, 0x0b94, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bb4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bd4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0bf4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c00, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c10, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c20, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c30, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c40, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c50, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c60, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c70, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c80, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c90, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ca0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cb0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cc0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cd0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ce0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cf0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c04, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c14, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c24, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c34, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c44, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c54, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c64, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c74, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c84, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c94, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ca4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cb4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cc4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cd4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ce4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cf4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c08, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c18, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c28, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c38, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c48, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c58, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c68, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c78, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c88, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c98, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ca8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cb8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cc8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cd8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ce8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0cf8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0c0c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c1c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c2c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c3c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c4c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c5c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c6c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c7c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c8c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0c9c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0cac, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0cbc, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0ccc, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0cdc, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0cec, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0cfc, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0d00, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d08, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d10, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d18, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d20, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d28, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d30, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d38, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d04, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d0c, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d14, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d1c, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d24, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d2c, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d34, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d3c, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e00, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e10, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e20, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e30, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e40, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e50, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e60, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e70, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e80, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e90, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ea0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0eb0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ec0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ed0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ee0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ef0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0e04, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e14, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e24, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e34, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e44, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e54, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e64, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e74, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e84, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e94, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ea4, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0eb4, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ec4, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ed4, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ee4, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ef4, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e08, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e18, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e28, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e38, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e48, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e58, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e68, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e78, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e88, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0e98, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ea8, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0eb8, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ec8, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ed8, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ee8, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0ef8, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d40, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d48, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d50, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d58, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d44, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d4c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d54, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d5c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1e00, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e20, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e40, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e60, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e80, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ea0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ec0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ee0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e04, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e24, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e44, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e64, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e84, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ea4, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ec4, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ee4, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e08, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e28, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e48, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e68, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e88, 0x00000002); - nv_mthd(dev, 0x9097, 0x1ea8, 0x00000002); - nv_mthd(dev, 0x9097, 0x1ec8, 0x00000002); - nv_mthd(dev, 0x9097, 0x1ee8, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e0c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e2c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e4c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e6c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e8c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1eac, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ecc, 0x00000001); - nv_mthd(dev, 0x9097, 0x1eec, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e10, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e30, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e50, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e70, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e90, 0x00000001); - nv_mthd(dev, 0x9097, 0x1eb0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ed0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ef0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e14, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e34, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e54, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e74, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e94, 0x00000002); - nv_mthd(dev, 0x9097, 0x1eb4, 0x00000002); - nv_mthd(dev, 0x9097, 0x1ed4, 0x00000002); - nv_mthd(dev, 0x9097, 0x1ef4, 0x00000002); - nv_mthd(dev, 0x9097, 0x1e18, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e38, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e58, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e78, 0x00000001); - nv_mthd(dev, 0x9097, 0x1e98, 0x00000001); - nv_mthd(dev, 0x9097, 0x1eb8, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ed8, 0x00000001); - nv_mthd(dev, 0x9097, 0x1ef8, 0x00000001); - if (fermi == 0x9097) { - for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4) - nv_mthd(dev, 0x9097, mthd, 0x00000000); - } - nv_mthd(dev, 0x9097, 0x030c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1944, 0x00000000); - nv_mthd(dev, 0x9097, 0x1514, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d68, 0x0000ffff); - nv_mthd(dev, 0x9097, 0x121c, 0x0fac6881); - nv_mthd(dev, 0x9097, 0x0fac, 0x00000001); - nv_mthd(dev, 0x9097, 0x1538, 0x00000001); - nv_mthd(dev, 0x9097, 0x0fe0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0fe4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0fe8, 0x00000014); - nv_mthd(dev, 0x9097, 0x0fec, 0x00000040); - nv_mthd(dev, 0x9097, 0x0ff0, 0x00000000); - nv_mthd(dev, 0x9097, 0x179c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1228, 0x00000400); - nv_mthd(dev, 0x9097, 0x122c, 0x00000300); - nv_mthd(dev, 0x9097, 0x1230, 0x00010001); - nv_mthd(dev, 0x9097, 0x07f8, 0x00000000); - nv_mthd(dev, 0x9097, 0x15b4, 0x00000001); - nv_mthd(dev, 0x9097, 0x15cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1534, 0x00000000); - nv_mthd(dev, 0x9097, 0x0fb0, 0x00000000); - nv_mthd(dev, 0x9097, 0x15d0, 0x00000000); - nv_mthd(dev, 0x9097, 0x153c, 0x00000000); - nv_mthd(dev, 0x9097, 0x16b4, 0x00000003); - nv_mthd(dev, 0x9097, 0x0fbc, 0x0000ffff); - nv_mthd(dev, 0x9097, 0x0fc0, 0x0000ffff); - nv_mthd(dev, 0x9097, 0x0fc4, 0x0000ffff); - nv_mthd(dev, 0x9097, 0x0fc8, 0x0000ffff); - nv_mthd(dev, 0x9097, 0x0df8, 0x00000000); - nv_mthd(dev, 0x9097, 0x0dfc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1948, 0x00000000); - nv_mthd(dev, 0x9097, 0x1970, 0x00000001); - nv_mthd(dev, 0x9097, 0x161c, 0x000009f0); - nv_mthd(dev, 0x9097, 0x0dcc, 0x00000010); - nv_mthd(dev, 0x9097, 0x163c, 0x00000000); - nv_mthd(dev, 0x9097, 0x15e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1160, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1164, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1168, 0x25e00040); - nv_mthd(dev, 0x9097, 0x116c, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1170, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1174, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1178, 0x25e00040); - nv_mthd(dev, 0x9097, 0x117c, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1180, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1184, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1188, 0x25e00040); - nv_mthd(dev, 0x9097, 0x118c, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1190, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1194, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1198, 0x25e00040); - nv_mthd(dev, 0x9097, 0x119c, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11a0, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11a4, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11a8, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11ac, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11b0, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11b4, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11b8, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11bc, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11c0, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11c4, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11c8, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11cc, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11d0, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11d4, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11d8, 0x25e00040); - nv_mthd(dev, 0x9097, 0x11dc, 0x25e00040); - nv_mthd(dev, 0x9097, 0x1880, 0x00000000); - nv_mthd(dev, 0x9097, 0x1884, 0x00000000); - nv_mthd(dev, 0x9097, 0x1888, 0x00000000); - nv_mthd(dev, 0x9097, 0x188c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1890, 0x00000000); - nv_mthd(dev, 0x9097, 0x1894, 0x00000000); - nv_mthd(dev, 0x9097, 0x1898, 0x00000000); - nv_mthd(dev, 0x9097, 0x189c, 0x00000000); - nv_mthd(dev, 0x9097, 0x18a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x18a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x18a8, 0x00000000); - nv_mthd(dev, 0x9097, 0x18ac, 0x00000000); - nv_mthd(dev, 0x9097, 0x18b0, 0x00000000); - nv_mthd(dev, 0x9097, 0x18b4, 0x00000000); - nv_mthd(dev, 0x9097, 0x18b8, 0x00000000); - nv_mthd(dev, 0x9097, 0x18bc, 0x00000000); - nv_mthd(dev, 0x9097, 0x18c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x18c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x18c8, 0x00000000); - nv_mthd(dev, 0x9097, 0x18cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x18d0, 0x00000000); - nv_mthd(dev, 0x9097, 0x18d4, 0x00000000); - nv_mthd(dev, 0x9097, 0x18d8, 0x00000000); - nv_mthd(dev, 0x9097, 0x18dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x18e0, 0x00000000); - nv_mthd(dev, 0x9097, 0x18e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x18e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x18ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x18f0, 0x00000000); - nv_mthd(dev, 0x9097, 0x18f4, 0x00000000); - nv_mthd(dev, 0x9097, 0x18f8, 0x00000000); - nv_mthd(dev, 0x9097, 0x18fc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f84, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f88, 0x00000000); - nv_mthd(dev, 0x9097, 0x17c8, 0x00000000); - nv_mthd(dev, 0x9097, 0x17cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x17d0, 0x000000ff); - nv_mthd(dev, 0x9097, 0x17d4, 0xffffffff); - nv_mthd(dev, 0x9097, 0x17d8, 0x00000002); - nv_mthd(dev, 0x9097, 0x17dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x15f4, 0x00000000); - nv_mthd(dev, 0x9097, 0x15f8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1434, 0x00000000); - nv_mthd(dev, 0x9097, 0x1438, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d74, 0x00000000); - nv_mthd(dev, 0x9097, 0x0dec, 0x00000001); - nv_mthd(dev, 0x9097, 0x13a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1318, 0x00000001); - nv_mthd(dev, 0x9097, 0x1644, 0x00000000); - nv_mthd(dev, 0x9097, 0x0748, 0x00000000); - nv_mthd(dev, 0x9097, 0x0de8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1648, 0x00000000); - nv_mthd(dev, 0x9097, 0x12a4, 0x00000000); - nv_mthd(dev, 0x9097, 0x1120, 0x00000000); - nv_mthd(dev, 0x9097, 0x1124, 0x00000000); - nv_mthd(dev, 0x9097, 0x1128, 0x00000000); - nv_mthd(dev, 0x9097, 0x112c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1118, 0x00000000); - nv_mthd(dev, 0x9097, 0x164c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1658, 0x00000000); - nv_mthd(dev, 0x9097, 0x1910, 0x00000290); - nv_mthd(dev, 0x9097, 0x1518, 0x00000000); - nv_mthd(dev, 0x9097, 0x165c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1520, 0x00000000); - nv_mthd(dev, 0x9097, 0x1604, 0x00000000); - nv_mthd(dev, 0x9097, 0x1570, 0x00000000); - nv_mthd(dev, 0x9097, 0x13b0, 0x3f800000); - nv_mthd(dev, 0x9097, 0x13b4, 0x3f800000); - nv_mthd(dev, 0x9097, 0x020c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1670, 0x30201000); - nv_mthd(dev, 0x9097, 0x1674, 0x70605040); - nv_mthd(dev, 0x9097, 0x1678, 0xb8a89888); - nv_mthd(dev, 0x9097, 0x167c, 0xf8e8d8c8); - nv_mthd(dev, 0x9097, 0x166c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1680, 0x00ffff00); - nv_mthd(dev, 0x9097, 0x12d0, 0x00000003); - nv_mthd(dev, 0x9097, 0x12d4, 0x00000002); - nv_mthd(dev, 0x9097, 0x1684, 0x00000000); - nv_mthd(dev, 0x9097, 0x1688, 0x00000000); - nv_mthd(dev, 0x9097, 0x0dac, 0x00001b02); - nv_mthd(dev, 0x9097, 0x0db0, 0x00001b02); - nv_mthd(dev, 0x9097, 0x0db4, 0x00000000); - nv_mthd(dev, 0x9097, 0x168c, 0x00000000); - nv_mthd(dev, 0x9097, 0x15bc, 0x00000000); - nv_mthd(dev, 0x9097, 0x156c, 0x00000000); - nv_mthd(dev, 0x9097, 0x187c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1110, 0x00000001); - nv_mthd(dev, 0x9097, 0x0dc0, 0x00000000); - nv_mthd(dev, 0x9097, 0x0dc4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0dc8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1234, 0x00000000); - nv_mthd(dev, 0x9097, 0x1690, 0x00000000); - nv_mthd(dev, 0x9097, 0x12ac, 0x00000001); - nv_mthd(dev, 0x9097, 0x02c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0790, 0x00000000); - nv_mthd(dev, 0x9097, 0x0794, 0x00000000); - nv_mthd(dev, 0x9097, 0x0798, 0x00000000); - nv_mthd(dev, 0x9097, 0x079c, 0x00000000); - nv_mthd(dev, 0x9097, 0x07a0, 0x00000000); - nv_mthd(dev, 0x9097, 0x077c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1000, 0x00000010); - nv_mthd(dev, 0x9097, 0x10fc, 0x00000000); - nv_mthd(dev, 0x9097, 0x1290, 0x00000000); - nv_mthd(dev, 0x9097, 0x0218, 0x00000010); - nv_mthd(dev, 0x9097, 0x12d8, 0x00000000); - nv_mthd(dev, 0x9097, 0x12dc, 0x00000010); - nv_mthd(dev, 0x9097, 0x0d94, 0x00000001); - nv_mthd(dev, 0x9097, 0x155c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1560, 0x00000000); - nv_mthd(dev, 0x9097, 0x1564, 0x00001fff); - nv_mthd(dev, 0x9097, 0x1574, 0x00000000); - nv_mthd(dev, 0x9097, 0x1578, 0x00000000); - nv_mthd(dev, 0x9097, 0x157c, 0x003fffff); - nv_mthd(dev, 0x9097, 0x1354, 0x00000000); - nv_mthd(dev, 0x9097, 0x1664, 0x00000000); - nv_mthd(dev, 0x9097, 0x1610, 0x00000012); - nv_mthd(dev, 0x9097, 0x1608, 0x00000000); - nv_mthd(dev, 0x9097, 0x160c, 0x00000000); - nv_mthd(dev, 0x9097, 0x162c, 0x00000003); - nv_mthd(dev, 0x9097, 0x0210, 0x00000000); - nv_mthd(dev, 0x9097, 0x0320, 0x00000000); - nv_mthd(dev, 0x9097, 0x0324, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0328, 0x3f800000); - nv_mthd(dev, 0x9097, 0x032c, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0330, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0334, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0338, 0x3f800000); - nv_mthd(dev, 0x9097, 0x0750, 0x00000000); - nv_mthd(dev, 0x9097, 0x0760, 0x39291909); - nv_mthd(dev, 0x9097, 0x0764, 0x79695949); - nv_mthd(dev, 0x9097, 0x0768, 0xb9a99989); - nv_mthd(dev, 0x9097, 0x076c, 0xf9e9d9c9); - nv_mthd(dev, 0x9097, 0x0770, 0x30201000); - nv_mthd(dev, 0x9097, 0x0774, 0x70605040); - nv_mthd(dev, 0x9097, 0x0778, 0x00009080); - nv_mthd(dev, 0x9097, 0x0780, 0x39291909); - nv_mthd(dev, 0x9097, 0x0784, 0x79695949); - nv_mthd(dev, 0x9097, 0x0788, 0xb9a99989); - nv_mthd(dev, 0x9097, 0x078c, 0xf9e9d9c9); - nv_mthd(dev, 0x9097, 0x07d0, 0x30201000); - nv_mthd(dev, 0x9097, 0x07d4, 0x70605040); - nv_mthd(dev, 0x9097, 0x07d8, 0x00009080); - nv_mthd(dev, 0x9097, 0x037c, 0x00000001); - nv_mthd(dev, 0x9097, 0x0740, 0x00000000); - nv_mthd(dev, 0x9097, 0x0744, 0x00000000); - nv_mthd(dev, 0x9097, 0x2600, 0x00000000); - nv_mthd(dev, 0x9097, 0x1918, 0x00000000); - nv_mthd(dev, 0x9097, 0x191c, 0x00000900); - nv_mthd(dev, 0x9097, 0x1920, 0x00000405); - nv_mthd(dev, 0x9097, 0x1308, 0x00000001); - nv_mthd(dev, 0x9097, 0x1924, 0x00000000); - nv_mthd(dev, 0x9097, 0x13ac, 0x00000000); - nv_mthd(dev, 0x9097, 0x192c, 0x00000001); - nv_mthd(dev, 0x9097, 0x193c, 0x00002c1c); - nv_mthd(dev, 0x9097, 0x0d7c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x02c0, 0x00000001); - nv_mthd(dev, 0x9097, 0x1510, 0x00000000); - nv_mthd(dev, 0x9097, 0x1940, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ff4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0ff8, 0x00000000); - nv_mthd(dev, 0x9097, 0x194c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1950, 0x00000000); - nv_mthd(dev, 0x9097, 0x1968, 0x00000000); - nv_mthd(dev, 0x9097, 0x1590, 0x0000003f); - nv_mthd(dev, 0x9097, 0x07e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x07ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x07f0, 0x00000000); - nv_mthd(dev, 0x9097, 0x07f4, 0x00000000); - nv_mthd(dev, 0x9097, 0x196c, 0x00000011); - nv_mthd(dev, 0x9097, 0x197c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0fcc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0fd0, 0x00000000); - nv_mthd(dev, 0x9097, 0x02d8, 0x00000040); - nv_mthd(dev, 0x9097, 0x1980, 0x00000080); - nv_mthd(dev, 0x9097, 0x1504, 0x00000080); - nv_mthd(dev, 0x9097, 0x1984, 0x00000000); - nv_mthd(dev, 0x9097, 0x0300, 0x00000001); - nv_mthd(dev, 0x9097, 0x13a8, 0x00000000); - nv_mthd(dev, 0x9097, 0x12ec, 0x00000000); - nv_mthd(dev, 0x9097, 0x1310, 0x00000000); - nv_mthd(dev, 0x9097, 0x1314, 0x00000001); - nv_mthd(dev, 0x9097, 0x1380, 0x00000000); - nv_mthd(dev, 0x9097, 0x1384, 0x00000001); - nv_mthd(dev, 0x9097, 0x1388, 0x00000001); - nv_mthd(dev, 0x9097, 0x138c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1390, 0x00000001); - nv_mthd(dev, 0x9097, 0x1394, 0x00000000); - nv_mthd(dev, 0x9097, 0x139c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1398, 0x00000000); - nv_mthd(dev, 0x9097, 0x1594, 0x00000000); - nv_mthd(dev, 0x9097, 0x1598, 0x00000001); - nv_mthd(dev, 0x9097, 0x159c, 0x00000001); - nv_mthd(dev, 0x9097, 0x15a0, 0x00000001); - nv_mthd(dev, 0x9097, 0x15a4, 0x00000001); - nv_mthd(dev, 0x9097, 0x0f54, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f58, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f5c, 0x00000000); - nv_mthd(dev, 0x9097, 0x19bc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f9c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0fa0, 0x00000000); - nv_mthd(dev, 0x9097, 0x12cc, 0x00000000); - nv_mthd(dev, 0x9097, 0x12e8, 0x00000000); - nv_mthd(dev, 0x9097, 0x130c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1360, 0x00000000); - nv_mthd(dev, 0x9097, 0x1364, 0x00000000); - nv_mthd(dev, 0x9097, 0x1368, 0x00000000); - nv_mthd(dev, 0x9097, 0x136c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1370, 0x00000000); - nv_mthd(dev, 0x9097, 0x1374, 0x00000000); - nv_mthd(dev, 0x9097, 0x1378, 0x00000000); - nv_mthd(dev, 0x9097, 0x137c, 0x00000000); - nv_mthd(dev, 0x9097, 0x133c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1340, 0x00000001); - nv_mthd(dev, 0x9097, 0x1344, 0x00000002); - nv_mthd(dev, 0x9097, 0x1348, 0x00000001); - nv_mthd(dev, 0x9097, 0x134c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1350, 0x00000002); - nv_mthd(dev, 0x9097, 0x1358, 0x00000001); - nv_mthd(dev, 0x9097, 0x12e4, 0x00000000); - nv_mthd(dev, 0x9097, 0x131c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1320, 0x00000000); - nv_mthd(dev, 0x9097, 0x1324, 0x00000000); - nv_mthd(dev, 0x9097, 0x1328, 0x00000000); - nv_mthd(dev, 0x9097, 0x19c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1140, 0x00000000); - nv_mthd(dev, 0x9097, 0x19c4, 0x00000000); - nv_mthd(dev, 0x9097, 0x19c8, 0x00001500); - nv_mthd(dev, 0x9097, 0x135c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f90, 0x00000000); - nv_mthd(dev, 0x9097, 0x19e0, 0x00000001); - nv_mthd(dev, 0x9097, 0x19e4, 0x00000001); - nv_mthd(dev, 0x9097, 0x19e8, 0x00000001); - nv_mthd(dev, 0x9097, 0x19ec, 0x00000001); - nv_mthd(dev, 0x9097, 0x19f0, 0x00000001); - nv_mthd(dev, 0x9097, 0x19f4, 0x00000001); - nv_mthd(dev, 0x9097, 0x19f8, 0x00000001); - nv_mthd(dev, 0x9097, 0x19fc, 0x00000001); - nv_mthd(dev, 0x9097, 0x19cc, 0x00000001); - nv_mthd(dev, 0x9097, 0x15b8, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a00, 0x00001111); - nv_mthd(dev, 0x9097, 0x1a04, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a08, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a0c, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a10, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a14, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a18, 0x00000000); - nv_mthd(dev, 0x9097, 0x1a1c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d6c, 0xffff0000); - nv_mthd(dev, 0x9097, 0x0d70, 0xffff0000); - nv_mthd(dev, 0x9097, 0x10f8, 0x00001010); - nv_mthd(dev, 0x9097, 0x0d80, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d84, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d88, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d8c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0d90, 0x00000000); - nv_mthd(dev, 0x9097, 0x0da0, 0x00000000); - nv_mthd(dev, 0x9097, 0x1508, 0x80000000); - nv_mthd(dev, 0x9097, 0x150c, 0x40000000); - nv_mthd(dev, 0x9097, 0x1668, 0x00000000); - nv_mthd(dev, 0x9097, 0x0318, 0x00000008); - nv_mthd(dev, 0x9097, 0x031c, 0x00000008); - nv_mthd(dev, 0x9097, 0x0d9c, 0x00000001); - nv_mthd(dev, 0x9097, 0x07dc, 0x00000000); - nv_mthd(dev, 0x9097, 0x074c, 0x00000055); - nv_mthd(dev, 0x9097, 0x1420, 0x00000003); - nv_mthd(dev, 0x9097, 0x17bc, 0x00000000); - nv_mthd(dev, 0x9097, 0x17c0, 0x00000000); - nv_mthd(dev, 0x9097, 0x17c4, 0x00000001); - nv_mthd(dev, 0x9097, 0x1008, 0x00000008); - nv_mthd(dev, 0x9097, 0x100c, 0x00000040); - nv_mthd(dev, 0x9097, 0x1010, 0x0000012c); - nv_mthd(dev, 0x9097, 0x0d60, 0x00000040); - nv_mthd(dev, 0x9097, 0x075c, 0x00000003); - nv_mthd(dev, 0x9097, 0x1018, 0x00000020); - nv_mthd(dev, 0x9097, 0x101c, 0x00000001); - nv_mthd(dev, 0x9097, 0x1020, 0x00000020); - nv_mthd(dev, 0x9097, 0x1024, 0x00000001); - nv_mthd(dev, 0x9097, 0x1444, 0x00000000); - nv_mthd(dev, 0x9097, 0x1448, 0x00000000); - nv_mthd(dev, 0x9097, 0x144c, 0x00000000); - nv_mthd(dev, 0x9097, 0x0360, 0x20164010); - nv_mthd(dev, 0x9097, 0x0364, 0x00000020); - nv_mthd(dev, 0x9097, 0x0368, 0x00000000); - nv_mthd(dev, 0x9097, 0x0de4, 0x00000000); - nv_mthd(dev, 0x9097, 0x0204, 0x00000006); - nv_mthd(dev, 0x9097, 0x0208, 0x00000000); - nv_mthd(dev, 0x9097, 0x02cc, 0x003fffff); - nv_mthd(dev, 0x9097, 0x02d0, 0x00000c48); - nv_mthd(dev, 0x9097, 0x1220, 0x00000005); - nv_mthd(dev, 0x9097, 0x0fdc, 0x00000000); - nv_mthd(dev, 0x9097, 0x0f98, 0x00300008); - nv_mthd(dev, 0x9097, 0x1284, 0x04000080); - nv_mthd(dev, 0x9097, 0x1450, 0x00300008); - nv_mthd(dev, 0x9097, 0x1454, 0x04000080); - nv_mthd(dev, 0x9097, 0x0214, 0x00000000); - /* in trace, right after 0x90c0, not here */ - nv_mthd(dev, 0x9097, 0x3410, 0x80002006); -} - -static void -nvc0_grctx_generate_9197(struct drm_device *dev) -{ - u32 fermi = nvc0_graph_class(dev); - u32 mthd; - - if (fermi == 0x9197) { - for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4) - nv_mthd(dev, 0x9197, mthd, 0x00000000); - } - nv_mthd(dev, 0x9197, 0x02e4, 0x0000b001); -} - -static void -nvc0_grctx_generate_9297(struct drm_device *dev) -{ - u32 fermi = nvc0_graph_class(dev); - u32 mthd; - - if (fermi == 0x9297) { - for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4) - nv_mthd(dev, 0x9297, mthd, 0x00000000); - } - nv_mthd(dev, 0x9297, 0x036c, 0x00000000); - nv_mthd(dev, 0x9297, 0x0370, 0x00000000); - nv_mthd(dev, 0x9297, 0x07a4, 0x00000000); - nv_mthd(dev, 0x9297, 0x07a8, 0x00000000); - nv_mthd(dev, 0x9297, 0x0374, 0x00000000); - nv_mthd(dev, 0x9297, 0x0378, 0x00000020); -} - -static void -nvc0_grctx_generate_902d(struct drm_device *dev) -{ - nv_mthd(dev, 0x902d, 0x0200, 0x000000cf); - nv_mthd(dev, 0x902d, 0x0204, 0x00000001); - nv_mthd(dev, 0x902d, 0x0208, 0x00000020); - nv_mthd(dev, 0x902d, 0x020c, 0x00000001); - nv_mthd(dev, 0x902d, 0x0210, 0x00000000); - nv_mthd(dev, 0x902d, 0x0214, 0x00000080); - nv_mthd(dev, 0x902d, 0x0218, 0x00000100); - nv_mthd(dev, 0x902d, 0x021c, 0x00000100); - nv_mthd(dev, 0x902d, 0x0220, 0x00000000); - nv_mthd(dev, 0x902d, 0x0224, 0x00000000); - nv_mthd(dev, 0x902d, 0x0230, 0x000000cf); - nv_mthd(dev, 0x902d, 0x0234, 0x00000001); - nv_mthd(dev, 0x902d, 0x0238, 0x00000020); - nv_mthd(dev, 0x902d, 0x023c, 0x00000001); - nv_mthd(dev, 0x902d, 0x0244, 0x00000080); - nv_mthd(dev, 0x902d, 0x0248, 0x00000100); - nv_mthd(dev, 0x902d, 0x024c, 0x00000100); -} - -static void -nvc0_grctx_generate_9039(struct drm_device *dev) -{ - nv_mthd(dev, 0x9039, 0x030c, 0x00000000); - nv_mthd(dev, 0x9039, 0x0310, 0x00000000); - nv_mthd(dev, 0x9039, 0x0314, 0x00000000); - nv_mthd(dev, 0x9039, 0x0320, 0x00000000); - nv_mthd(dev, 0x9039, 0x0238, 0x00000000); - nv_mthd(dev, 0x9039, 0x023c, 0x00000000); - nv_mthd(dev, 0x9039, 0x0318, 0x00000000); - nv_mthd(dev, 0x9039, 0x031c, 0x00000000); -} - -static void -nvc0_grctx_generate_90c0(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i; - - for (i = 0; dev_priv->chipset == 0xd9 && i < 4; i++) { - nv_mthd(dev, 0x90c0, 0x2700 + (i * 0x40), 0x00000000); - nv_mthd(dev, 0x90c0, 0x2720 + (i * 0x40), 0x00000000); - nv_mthd(dev, 0x90c0, 0x2704 + (i * 0x40), 0x00000000); - nv_mthd(dev, 0x90c0, 0x2724 + (i * 0x40), 0x00000000); - nv_mthd(dev, 0x90c0, 0x2708 + (i * 0x40), 0x00000000); - nv_mthd(dev, 0x90c0, 0x2728 + (i * 0x40), 0x00000000); - } - nv_mthd(dev, 0x90c0, 0x270c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x272c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x274c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x276c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x278c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x27ac, 0x00000000); - nv_mthd(dev, 0x90c0, 0x27cc, 0x00000000); - nv_mthd(dev, 0x90c0, 0x27ec, 0x00000000); - for (i = 0; dev_priv->chipset == 0xd9 && i < 4; i++) { - nv_mthd(dev, 0x90c0, 0x2710 + (i * 0x40), 0x00014000); - nv_mthd(dev, 0x90c0, 0x2730 + (i * 0x40), 0x00014000); - nv_mthd(dev, 0x90c0, 0x2714 + (i * 0x40), 0x00000040); - nv_mthd(dev, 0x90c0, 0x2734 + (i * 0x40), 0x00000040); - } - nv_mthd(dev, 0x90c0, 0x030c, 0x00000001); - nv_mthd(dev, 0x90c0, 0x1944, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0758, 0x00000100); - nv_mthd(dev, 0x90c0, 0x02c4, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0790, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0794, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0798, 0x00000000); - nv_mthd(dev, 0x90c0, 0x079c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x07a0, 0x00000000); - nv_mthd(dev, 0x90c0, 0x077c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0204, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0208, 0x00000000); - nv_mthd(dev, 0x90c0, 0x020c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0214, 0x00000000); - nv_mthd(dev, 0x90c0, 0x024c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x0d94, 0x00000001); - nv_mthd(dev, 0x90c0, 0x1608, 0x00000000); - nv_mthd(dev, 0x90c0, 0x160c, 0x00000000); - nv_mthd(dev, 0x90c0, 0x1664, 0x00000000); -} - -static void -nvc0_grctx_generate_dispatch(struct drm_device *dev) -{ - int i; - - nv_wr32(dev, 0x404004, 0x00000000); - nv_wr32(dev, 0x404008, 0x00000000); - nv_wr32(dev, 0x40400c, 0x00000000); - nv_wr32(dev, 0x404010, 0x00000000); - nv_wr32(dev, 0x404014, 0x00000000); - nv_wr32(dev, 0x404018, 0x00000000); - nv_wr32(dev, 0x40401c, 0x00000000); - nv_wr32(dev, 0x404020, 0x00000000); - nv_wr32(dev, 0x404024, 0x00000000); - nv_wr32(dev, 0x404028, 0x00000000); - nv_wr32(dev, 0x40402c, 0x00000000); - nv_wr32(dev, 0x404044, 0x00000000); - nv_wr32(dev, 0x404094, 0x00000000); - nv_wr32(dev, 0x404098, 0x00000000); - nv_wr32(dev, 0x40409c, 0x00000000); - nv_wr32(dev, 0x4040a0, 0x00000000); - nv_wr32(dev, 0x4040a4, 0x00000000); - nv_wr32(dev, 0x4040a8, 0x00000000); - nv_wr32(dev, 0x4040ac, 0x00000000); - nv_wr32(dev, 0x4040b0, 0x00000000); - nv_wr32(dev, 0x4040b4, 0x00000000); - nv_wr32(dev, 0x4040b8, 0x00000000); - nv_wr32(dev, 0x4040bc, 0x00000000); - nv_wr32(dev, 0x4040c0, 0x00000000); - nv_wr32(dev, 0x4040c4, 0x00000000); - nv_wr32(dev, 0x4040c8, 0xf0000087); - nv_wr32(dev, 0x4040d4, 0x00000000); - nv_wr32(dev, 0x4040d8, 0x00000000); - nv_wr32(dev, 0x4040dc, 0x00000000); - nv_wr32(dev, 0x4040e0, 0x00000000); - nv_wr32(dev, 0x4040e4, 0x00000000); - nv_wr32(dev, 0x4040e8, 0x00001000); - nv_wr32(dev, 0x4040f8, 0x00000000); - nv_wr32(dev, 0x404130, 0x00000000); - nv_wr32(dev, 0x404134, 0x00000000); - nv_wr32(dev, 0x404138, 0x20000040); - nv_wr32(dev, 0x404150, 0x0000002e); - nv_wr32(dev, 0x404154, 0x00000400); - nv_wr32(dev, 0x404158, 0x00000200); - nv_wr32(dev, 0x404164, 0x00000055); - nv_wr32(dev, 0x404168, 0x00000000); - nv_wr32(dev, 0x404174, 0x00000000); - nv_wr32(dev, 0x404178, 0x00000000); - nv_wr32(dev, 0x40417c, 0x00000000); - for (i = 0; i < 8; i++) - nv_wr32(dev, 0x404200 + (i * 4), 0x00000000); /* subc */ -} - -static void -nvc0_grctx_generate_macro(struct drm_device *dev) -{ - nv_wr32(dev, 0x404404, 0x00000000); - nv_wr32(dev, 0x404408, 0x00000000); - nv_wr32(dev, 0x40440c, 0x00000000); - nv_wr32(dev, 0x404410, 0x00000000); - nv_wr32(dev, 0x404414, 0x00000000); - nv_wr32(dev, 0x404418, 0x00000000); - nv_wr32(dev, 0x40441c, 0x00000000); - nv_wr32(dev, 0x404420, 0x00000000); - nv_wr32(dev, 0x404424, 0x00000000); - nv_wr32(dev, 0x404428, 0x00000000); - nv_wr32(dev, 0x40442c, 0x00000000); - nv_wr32(dev, 0x404430, 0x00000000); - nv_wr32(dev, 0x404434, 0x00000000); - nv_wr32(dev, 0x404438, 0x00000000); - nv_wr32(dev, 0x404460, 0x00000000); - nv_wr32(dev, 0x404464, 0x00000000); - nv_wr32(dev, 0x404468, 0x00ffffff); - nv_wr32(dev, 0x40446c, 0x00000000); - nv_wr32(dev, 0x404480, 0x00000001); - nv_wr32(dev, 0x404498, 0x00000001); -} - -static void -nvc0_grctx_generate_m2mf(struct drm_device *dev) -{ - nv_wr32(dev, 0x404604, 0x00000015); - nv_wr32(dev, 0x404608, 0x00000000); - nv_wr32(dev, 0x40460c, 0x00002e00); - nv_wr32(dev, 0x404610, 0x00000100); - nv_wr32(dev, 0x404618, 0x00000000); - nv_wr32(dev, 0x40461c, 0x00000000); - nv_wr32(dev, 0x404620, 0x00000000); - nv_wr32(dev, 0x404624, 0x00000000); - nv_wr32(dev, 0x404628, 0x00000000); - nv_wr32(dev, 0x40462c, 0x00000000); - nv_wr32(dev, 0x404630, 0x00000000); - nv_wr32(dev, 0x404634, 0x00000000); - nv_wr32(dev, 0x404638, 0x00000004); - nv_wr32(dev, 0x40463c, 0x00000000); - nv_wr32(dev, 0x404640, 0x00000000); - nv_wr32(dev, 0x404644, 0x00000000); - nv_wr32(dev, 0x404648, 0x00000000); - nv_wr32(dev, 0x40464c, 0x00000000); - nv_wr32(dev, 0x404650, 0x00000000); - nv_wr32(dev, 0x404654, 0x00000000); - nv_wr32(dev, 0x404658, 0x00000000); - nv_wr32(dev, 0x40465c, 0x007f0100); - nv_wr32(dev, 0x404660, 0x00000000); - nv_wr32(dev, 0x404664, 0x00000000); - nv_wr32(dev, 0x404668, 0x00000000); - nv_wr32(dev, 0x40466c, 0x00000000); - nv_wr32(dev, 0x404670, 0x00000000); - nv_wr32(dev, 0x404674, 0x00000000); - nv_wr32(dev, 0x404678, 0x00000000); - nv_wr32(dev, 0x40467c, 0x00000002); - nv_wr32(dev, 0x404680, 0x00000000); - nv_wr32(dev, 0x404684, 0x00000000); - nv_wr32(dev, 0x404688, 0x00000000); - nv_wr32(dev, 0x40468c, 0x00000000); - nv_wr32(dev, 0x404690, 0x00000000); - nv_wr32(dev, 0x404694, 0x00000000); - nv_wr32(dev, 0x404698, 0x00000000); - nv_wr32(dev, 0x40469c, 0x00000000); - nv_wr32(dev, 0x4046a0, 0x007f0080); - nv_wr32(dev, 0x4046a4, 0x00000000); - nv_wr32(dev, 0x4046a8, 0x00000000); - nv_wr32(dev, 0x4046ac, 0x00000000); - nv_wr32(dev, 0x4046b0, 0x00000000); - nv_wr32(dev, 0x4046b4, 0x00000000); - nv_wr32(dev, 0x4046b8, 0x00000000); - nv_wr32(dev, 0x4046bc, 0x00000000); - nv_wr32(dev, 0x4046c0, 0x00000000); - nv_wr32(dev, 0x4046c4, 0x00000000); - nv_wr32(dev, 0x4046c8, 0x00000000); - nv_wr32(dev, 0x4046cc, 0x00000000); - nv_wr32(dev, 0x4046d0, 0x00000000); - nv_wr32(dev, 0x4046d4, 0x00000000); - nv_wr32(dev, 0x4046d8, 0x00000000); - nv_wr32(dev, 0x4046dc, 0x00000000); - nv_wr32(dev, 0x4046e0, 0x00000000); - nv_wr32(dev, 0x4046e4, 0x00000000); - nv_wr32(dev, 0x4046e8, 0x00000000); - nv_wr32(dev, 0x4046f0, 0x00000000); - nv_wr32(dev, 0x4046f4, 0x00000000); -} - -static void -nvc0_grctx_generate_unk47xx(struct drm_device *dev) -{ - nv_wr32(dev, 0x404700, 0x00000000); - nv_wr32(dev, 0x404704, 0x00000000); - nv_wr32(dev, 0x404708, 0x00000000); - nv_wr32(dev, 0x40470c, 0x00000000); - nv_wr32(dev, 0x404710, 0x00000000); - nv_wr32(dev, 0x404714, 0x00000000); - nv_wr32(dev, 0x404718, 0x00000000); - nv_wr32(dev, 0x40471c, 0x00000000); - nv_wr32(dev, 0x404720, 0x00000000); - nv_wr32(dev, 0x404724, 0x00000000); - nv_wr32(dev, 0x404728, 0x00000000); - nv_wr32(dev, 0x40472c, 0x00000000); - nv_wr32(dev, 0x404730, 0x00000000); - nv_wr32(dev, 0x404734, 0x00000100); - nv_wr32(dev, 0x404738, 0x00000000); - nv_wr32(dev, 0x40473c, 0x00000000); - nv_wr32(dev, 0x404740, 0x00000000); - nv_wr32(dev, 0x404744, 0x00000000); - nv_wr32(dev, 0x404748, 0x00000000); - nv_wr32(dev, 0x40474c, 0x00000000); - nv_wr32(dev, 0x404750, 0x00000000); - nv_wr32(dev, 0x404754, 0x00000000); -} - -static void -nvc0_grctx_generate_shaders(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->chipset == 0xd9) { - nv_wr32(dev, 0x405800, 0x0f8000bf); - nv_wr32(dev, 0x405830, 0x02180218); - nv_wr32(dev, 0x405834, 0x08000000); - } else - if (dev_priv->chipset == 0xc1) { - nv_wr32(dev, 0x405800, 0x0f8000bf); - nv_wr32(dev, 0x405830, 0x02180218); - nv_wr32(dev, 0x405834, 0x00000000); - } else { - nv_wr32(dev, 0x405800, 0x078000bf); - nv_wr32(dev, 0x405830, 0x02180000); - nv_wr32(dev, 0x405834, 0x00000000); - } - nv_wr32(dev, 0x405838, 0x00000000); - nv_wr32(dev, 0x405854, 0x00000000); - nv_wr32(dev, 0x405870, 0x00000001); - nv_wr32(dev, 0x405874, 0x00000001); - nv_wr32(dev, 0x405878, 0x00000001); - nv_wr32(dev, 0x40587c, 0x00000001); - nv_wr32(dev, 0x405a00, 0x00000000); - nv_wr32(dev, 0x405a04, 0x00000000); - nv_wr32(dev, 0x405a18, 0x00000000); -} - -static void -nvc0_grctx_generate_unk60xx(struct drm_device *dev) -{ - nv_wr32(dev, 0x406020, 0x000103c1); - nv_wr32(dev, 0x406028, 0x00000001); - nv_wr32(dev, 0x40602c, 0x00000001); - nv_wr32(dev, 0x406030, 0x00000001); - nv_wr32(dev, 0x406034, 0x00000001); -} - -static void -nvc0_grctx_generate_unk64xx(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - nv_wr32(dev, 0x4064a8, 0x00000000); - nv_wr32(dev, 0x4064ac, 0x00003fff); - nv_wr32(dev, 0x4064b4, 0x00000000); - nv_wr32(dev, 0x4064b8, 0x00000000); - if (dev_priv->chipset == 0xd9) - nv_wr32(dev, 0x4064bc, 0x00000000); - if (dev_priv->chipset == 0xc1 || - dev_priv->chipset == 0xd9) { - nv_wr32(dev, 0x4064c0, 0x80140078); - nv_wr32(dev, 0x4064c4, 0x0086ffff); - } -} - -static void -nvc0_grctx_generate_tpbus(struct drm_device *dev) -{ - nv_wr32(dev, 0x407804, 0x00000023); - nv_wr32(dev, 0x40780c, 0x0a418820); - nv_wr32(dev, 0x407810, 0x062080e6); - nv_wr32(dev, 0x407814, 0x020398a4); - nv_wr32(dev, 0x407818, 0x0e629062); - nv_wr32(dev, 0x40781c, 0x0a418820); - nv_wr32(dev, 0x407820, 0x000000e6); - nv_wr32(dev, 0x4078bc, 0x00000103); -} - -static void -nvc0_grctx_generate_ccache(struct drm_device *dev) -{ - nv_wr32(dev, 0x408000, 0x00000000); - nv_wr32(dev, 0x408004, 0x00000000); - nv_wr32(dev, 0x408008, 0x00000018); - nv_wr32(dev, 0x40800c, 0x00000000); - nv_wr32(dev, 0x408010, 0x00000000); - nv_wr32(dev, 0x408014, 0x00000069); - nv_wr32(dev, 0x408018, 0xe100e100); - nv_wr32(dev, 0x408064, 0x00000000); -} - -static void -nvc0_grctx_generate_rop(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chipset = dev_priv->chipset; - - /* ROPC_BROADCAST */ - nv_wr32(dev, 0x408800, 0x02802a3c); - nv_wr32(dev, 0x408804, 0x00000040); - if (chipset == 0xd9) { - nv_wr32(dev, 0x408808, 0x1043e005); - nv_wr32(dev, 0x408900, 0x3080b801); - nv_wr32(dev, 0x408904, 0x1043e005); - nv_wr32(dev, 0x408908, 0x00c8102f); - } else - if (chipset == 0xc1) { - nv_wr32(dev, 0x408808, 0x1003e005); - nv_wr32(dev, 0x408900, 0x3080b801); - nv_wr32(dev, 0x408904, 0x62000001); - nv_wr32(dev, 0x408908, 0x00c80929); - } else { - nv_wr32(dev, 0x408808, 0x0003e00d); - nv_wr32(dev, 0x408900, 0x3080b801); - nv_wr32(dev, 0x408904, 0x02000001); - nv_wr32(dev, 0x408908, 0x00c80929); - } - nv_wr32(dev, 0x40890c, 0x00000000); - nv_wr32(dev, 0x408980, 0x0000011d); -} - -static void -nvc0_grctx_generate_gpc(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chipset = dev_priv->chipset; - int i; - - /* GPC_BROADCAST */ - nv_wr32(dev, 0x418380, 0x00000016); - nv_wr32(dev, 0x418400, 0x38004e00); - nv_wr32(dev, 0x418404, 0x71e0ffff); - nv_wr32(dev, 0x418408, 0x00000000); - nv_wr32(dev, 0x41840c, 0x00001008); - nv_wr32(dev, 0x418410, 0x0fff0fff); - nv_wr32(dev, 0x418414, chipset != 0xd9 ? 0x00200fff : 0x02200fff); - nv_wr32(dev, 0x418450, 0x00000000); - nv_wr32(dev, 0x418454, 0x00000000); - nv_wr32(dev, 0x418458, 0x00000000); - nv_wr32(dev, 0x41845c, 0x00000000); - nv_wr32(dev, 0x418460, 0x00000000); - nv_wr32(dev, 0x418464, 0x00000000); - nv_wr32(dev, 0x418468, 0x00000001); - nv_wr32(dev, 0x41846c, 0x00000000); - nv_wr32(dev, 0x418470, 0x00000000); - nv_wr32(dev, 0x418600, 0x0000001f); - nv_wr32(dev, 0x418684, 0x0000000f); - nv_wr32(dev, 0x418700, 0x00000002); - nv_wr32(dev, 0x418704, 0x00000080); - nv_wr32(dev, 0x418708, 0x00000000); - nv_wr32(dev, 0x41870c, chipset != 0xd9 ? 0x07c80000 : 0x00000000); - nv_wr32(dev, 0x418710, 0x00000000); - nv_wr32(dev, 0x418800, chipset != 0xd9 ? 0x0006860a : 0x7006860a); - nv_wr32(dev, 0x418808, 0x00000000); - nv_wr32(dev, 0x41880c, 0x00000000); - nv_wr32(dev, 0x418810, 0x00000000); - nv_wr32(dev, 0x418828, 0x00008442); - if (chipset == 0xc1 || chipset == 0xd9) - nv_wr32(dev, 0x418830, 0x10000001); - else - nv_wr32(dev, 0x418830, 0x00000001); - nv_wr32(dev, 0x4188d8, 0x00000008); - nv_wr32(dev, 0x4188e0, 0x01000000); - nv_wr32(dev, 0x4188e8, 0x00000000); - nv_wr32(dev, 0x4188ec, 0x00000000); - nv_wr32(dev, 0x4188f0, 0x00000000); - nv_wr32(dev, 0x4188f4, 0x00000000); - nv_wr32(dev, 0x4188f8, 0x00000000); - if (chipset == 0xd9) - nv_wr32(dev, 0x4188fc, 0x20100008); - else if (chipset == 0xc1) - nv_wr32(dev, 0x4188fc, 0x00100018); - else - nv_wr32(dev, 0x4188fc, 0x00100000); - nv_wr32(dev, 0x41891c, 0x00ff00ff); - nv_wr32(dev, 0x418924, 0x00000000); - nv_wr32(dev, 0x418928, 0x00ffff00); - nv_wr32(dev, 0x41892c, 0x0000ff00); - for (i = 0; i < 8; i++) { - nv_wr32(dev, 0x418a00 + (i * 0x20), 0x00000000); - nv_wr32(dev, 0x418a04 + (i * 0x20), 0x00000000); - nv_wr32(dev, 0x418a08 + (i * 0x20), 0x00000000); - nv_wr32(dev, 0x418a0c + (i * 0x20), 0x00010000); - nv_wr32(dev, 0x418a10 + (i * 0x20), 0x00000000); - nv_wr32(dev, 0x418a14 + (i * 0x20), 0x00000000); - nv_wr32(dev, 0x418a18 + (i * 0x20), 0x00000000); - } - nv_wr32(dev, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006); - nv_wr32(dev, 0x418b08, 0x0a418820); - nv_wr32(dev, 0x418b0c, 0x062080e6); - nv_wr32(dev, 0x418b10, 0x020398a4); - nv_wr32(dev, 0x418b14, 0x0e629062); - nv_wr32(dev, 0x418b18, 0x0a418820); - nv_wr32(dev, 0x418b1c, 0x000000e6); - nv_wr32(dev, 0x418bb8, 0x00000103); - nv_wr32(dev, 0x418c08, 0x00000001); - nv_wr32(dev, 0x418c10, 0x00000000); - nv_wr32(dev, 0x418c14, 0x00000000); - nv_wr32(dev, 0x418c18, 0x00000000); - nv_wr32(dev, 0x418c1c, 0x00000000); - nv_wr32(dev, 0x418c20, 0x00000000); - nv_wr32(dev, 0x418c24, 0x00000000); - nv_wr32(dev, 0x418c28, 0x00000000); - nv_wr32(dev, 0x418c2c, 0x00000000); - if (chipset == 0xc1 || chipset == 0xd9) - nv_wr32(dev, 0x418c6c, 0x00000001); - nv_wr32(dev, 0x418c80, 0x20200004); - nv_wr32(dev, 0x418c8c, 0x00000001); - nv_wr32(dev, 0x419000, 0x00000780); - nv_wr32(dev, 0x419004, 0x00000000); - nv_wr32(dev, 0x419008, 0x00000000); - nv_wr32(dev, 0x419014, 0x00000004); -} - -static void -nvc0_grctx_generate_tp(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int chipset = dev_priv->chipset; - - /* GPC_BROADCAST.TP_BROADCAST */ - nv_wr32(dev, 0x419818, 0x00000000); - nv_wr32(dev, 0x41983c, 0x00038bc7); - nv_wr32(dev, 0x419848, 0x00000000); - if (chipset == 0xc1 || chipset == 0xd9) - nv_wr32(dev, 0x419864, 0x00000129); - else - nv_wr32(dev, 0x419864, 0x0000012a); - nv_wr32(dev, 0x419888, 0x00000000); - nv_wr32(dev, 0x419a00, 0x000001f0); - nv_wr32(dev, 0x419a04, 0x00000001); - nv_wr32(dev, 0x419a08, 0x00000023); - nv_wr32(dev, 0x419a0c, 0x00020000); - nv_wr32(dev, 0x419a10, 0x00000000); - nv_wr32(dev, 0x419a14, 0x00000200); - nv_wr32(dev, 0x419a1c, 0x00000000); - nv_wr32(dev, 0x419a20, 0x00000800); - if (chipset == 0xd9) - nv_wr32(dev, 0x00419ac4, 0x0017f440); - else if (chipset != 0xc0 && chipset != 0xc8) - nv_wr32(dev, 0x00419ac4, 0x0007f440); - nv_wr32(dev, 0x419b00, 0x0a418820); - nv_wr32(dev, 0x419b04, 0x062080e6); - nv_wr32(dev, 0x419b08, 0x020398a4); - nv_wr32(dev, 0x419b0c, 0x0e629062); - nv_wr32(dev, 0x419b10, 0x0a418820); - nv_wr32(dev, 0x419b14, 0x000000e6); - nv_wr32(dev, 0x419bd0, 0x00900103); - if (chipset == 0xc1 || chipset == 0xd9) - nv_wr32(dev, 0x419be0, 0x00400001); - else - nv_wr32(dev, 0x419be0, 0x00000001); - nv_wr32(dev, 0x419be4, 0x00000000); - nv_wr32(dev, 0x419c00, chipset != 0xd9 ? 0x00000002 : 0x0000000a); - nv_wr32(dev, 0x419c04, 0x00000006); - nv_wr32(dev, 0x419c08, 0x00000002); - nv_wr32(dev, 0x419c20, 0x00000000); - if (dev_priv->chipset == 0xd9) { - nv_wr32(dev, 0x419c24, 0x00084210); - nv_wr32(dev, 0x419c28, 0x3cf3cf3c); - nv_wr32(dev, 0x419cb0, 0x00020048); - } else - if (chipset == 0xce || chipset == 0xcf) { - nv_wr32(dev, 0x419cb0, 0x00020048); - } else { - nv_wr32(dev, 0x419cb0, 0x00060048); - } - nv_wr32(dev, 0x419ce8, 0x00000000); - nv_wr32(dev, 0x419cf4, 0x00000183); - if (chipset == 0xc1 || chipset == 0xd9) - nv_wr32(dev, 0x419d20, 0x12180000); - else - nv_wr32(dev, 0x419d20, 0x02180000); - nv_wr32(dev, 0x419d24, 0x00001fff); - if (chipset == 0xc1 || chipset == 0xd9) - nv_wr32(dev, 0x419d44, 0x02180218); - nv_wr32(dev, 0x419e04, 0x00000000); - nv_wr32(dev, 0x419e08, 0x00000000); - nv_wr32(dev, 0x419e0c, 0x00000000); - nv_wr32(dev, 0x419e10, 0x00000002); - nv_wr32(dev, 0x419e44, 0x001beff2); - nv_wr32(dev, 0x419e48, 0x00000000); - nv_wr32(dev, 0x419e4c, 0x0000000f); - nv_wr32(dev, 0x419e50, 0x00000000); - nv_wr32(dev, 0x419e54, 0x00000000); - nv_wr32(dev, 0x419e58, 0x00000000); - nv_wr32(dev, 0x419e5c, 0x00000000); - nv_wr32(dev, 0x419e60, 0x00000000); - nv_wr32(dev, 0x419e64, 0x00000000); - nv_wr32(dev, 0x419e68, 0x00000000); - nv_wr32(dev, 0x419e6c, 0x00000000); - nv_wr32(dev, 0x419e70, 0x00000000); - nv_wr32(dev, 0x419e74, 0x00000000); - nv_wr32(dev, 0x419e78, 0x00000000); - nv_wr32(dev, 0x419e7c, 0x00000000); - nv_wr32(dev, 0x419e80, 0x00000000); - nv_wr32(dev, 0x419e84, 0x00000000); - nv_wr32(dev, 0x419e88, 0x00000000); - nv_wr32(dev, 0x419e8c, 0x00000000); - nv_wr32(dev, 0x419e90, 0x00000000); - nv_wr32(dev, 0x419e98, 0x00000000); - if (chipset != 0xc0 && chipset != 0xc8) - nv_wr32(dev, 0x419ee0, 0x00011110); - nv_wr32(dev, 0x419f50, 0x00000000); - nv_wr32(dev, 0x419f54, 0x00000000); - if (chipset != 0xc0 && chipset != 0xc8) - nv_wr32(dev, 0x419f58, 0x00000000); -} - -int -nvc0_grctx_generate(struct nouveau_channel *chan) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); - struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; - struct drm_device *dev = chan->dev; - int i, gpc, tp, id; - u32 fermi = nvc0_graph_class(dev); - u32 r000260, tmp; - - r000260 = nv_rd32(dev, 0x000260); - nv_wr32(dev, 0x000260, r000260 & ~1); - nv_wr32(dev, 0x400208, 0x00000000); - - nvc0_grctx_generate_dispatch(dev); - nvc0_grctx_generate_macro(dev); - nvc0_grctx_generate_m2mf(dev); - nvc0_grctx_generate_unk47xx(dev); - nvc0_grctx_generate_shaders(dev); - nvc0_grctx_generate_unk60xx(dev); - nvc0_grctx_generate_unk64xx(dev); - nvc0_grctx_generate_tpbus(dev); - nvc0_grctx_generate_ccache(dev); - nvc0_grctx_generate_rop(dev); - nvc0_grctx_generate_gpc(dev); - nvc0_grctx_generate_tp(dev); - - nv_wr32(dev, 0x404154, 0x00000000); - - /* fuc "mmio list" writes */ - for (i = 0; i < grch->mmio_nr * 8; i += 8) { - u32 reg = nv_ro32(grch->mmio, i + 0); - nv_wr32(dev, reg, nv_ro32(grch->mmio, i + 4)); - } - - for (tp = 0, id = 0; tp < 4; tp++) { - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - if (tp < priv->tp_nr[gpc]) { - nv_wr32(dev, TP_UNIT(gpc, tp, 0x698), id); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x4e8), id); - nv_wr32(dev, GPC_UNIT(gpc, 0x0c10 + tp * 4), id); - nv_wr32(dev, TP_UNIT(gpc, tp, 0x088), id); - id++; - } - - nv_wr32(dev, GPC_UNIT(gpc, 0x0c08), priv->tp_nr[gpc]); - nv_wr32(dev, GPC_UNIT(gpc, 0x0c8c), priv->tp_nr[gpc]); - } - } - - tmp = 0; - for (i = 0; i < priv->gpc_nr; i++) - tmp |= priv->tp_nr[i] << (i * 4); - nv_wr32(dev, 0x406028, tmp); - nv_wr32(dev, 0x405870, tmp); - - nv_wr32(dev, 0x40602c, 0x00000000); - nv_wr32(dev, 0x405874, 0x00000000); - nv_wr32(dev, 0x406030, 0x00000000); - nv_wr32(dev, 0x405878, 0x00000000); - nv_wr32(dev, 0x406034, 0x00000000); - nv_wr32(dev, 0x40587c, 0x00000000); - - if (1) { - u8 tpnr[GPC_MAX], data[TP_MAX]; - - memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); - memset(data, 0x1f, sizeof(data)); - - gpc = -1; - for (tp = 0; tp < priv->tp_total; tp++) { - do { - gpc = (gpc + 1) % priv->gpc_nr; - } while (!tpnr[gpc]); - tpnr[gpc]--; - data[tp] = gpc; - } - - for (i = 0; i < 4; i++) - nv_wr32(dev, 0x4060a8 + (i * 4), ((u32 *)data)[i]); - } - - if (1) { - u32 data[6] = {}, data2[2] = {}; - u8 tpnr[GPC_MAX]; - u8 shift, ntpcv; - - /* calculate first set of magics */ - memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); - - gpc = -1; - for (tp = 0; tp < priv->tp_total; tp++) { - do { - gpc = (gpc + 1) % priv->gpc_nr; - } while (!tpnr[gpc]); - tpnr[gpc]--; - - data[tp / 6] |= gpc << ((tp % 6) * 5); - } - - for (; tp < 32; tp++) - data[tp / 6] |= 7 << ((tp % 6) * 5); - - /* and the second... */ - shift = 0; - ntpcv = priv->tp_total; - while (!(ntpcv & (1 << 4))) { - ntpcv <<= 1; - shift++; - } - - data2[0] = (ntpcv << 16); - data2[0] |= (shift << 21); - data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); - for (i = 1; i < 7; i++) - data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); - - /* GPC_BROADCAST */ - nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | - priv->magic_not_rop_nr); - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x418b08 + (i * 4), data[i]); - - /* GPC_BROADCAST.TP_BROADCAST */ - nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | - priv->magic_not_rop_nr | - data2[0]); - nv_wr32(dev, 0x419be4, data2[1]); - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x419b00 + (i * 4), data[i]); - - /* UNK78xx */ - nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) | - priv->magic_not_rop_nr); - for (i = 0; i < 6; i++) - nv_wr32(dev, 0x40780c + (i * 4), data[i]); - } - - if (1) { - u32 tp_mask = 0, tp_set = 0; - u8 tpnr[GPC_MAX], a, b; - - memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); - for (gpc = 0; gpc < priv->gpc_nr; gpc++) - tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); - - for (i = 0, gpc = -1, b = -1; i < 32; i++) { - a = (i * (priv->tp_total - 1)) / 32; - if (a != b) { - b = a; - do { - gpc = (gpc + 1) % priv->gpc_nr; - } while (!tpnr[gpc]); - tp = priv->tp_nr[gpc] - tpnr[gpc]--; - - tp_set |= 1 << ((gpc * 8) + tp); - } - - nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); - nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask); - } - } - - nv_wr32(dev, 0x400208, 0x80000000); - - nv_icmd(dev, 0x00001000, 0x00000004); - nv_icmd(dev, 0x000000a9, 0x0000ffff); - nv_icmd(dev, 0x00000038, 0x0fac6881); - nv_icmd(dev, 0x0000003d, 0x00000001); - nv_icmd(dev, 0x000000e8, 0x00000400); - nv_icmd(dev, 0x000000e9, 0x00000400); - nv_icmd(dev, 0x000000ea, 0x00000400); - nv_icmd(dev, 0x000000eb, 0x00000400); - nv_icmd(dev, 0x000000ec, 0x00000400); - nv_icmd(dev, 0x000000ed, 0x00000400); - nv_icmd(dev, 0x000000ee, 0x00000400); - nv_icmd(dev, 0x000000ef, 0x00000400); - nv_icmd(dev, 0x00000078, 0x00000300); - nv_icmd(dev, 0x00000079, 0x00000300); - nv_icmd(dev, 0x0000007a, 0x00000300); - nv_icmd(dev, 0x0000007b, 0x00000300); - nv_icmd(dev, 0x0000007c, 0x00000300); - nv_icmd(dev, 0x0000007d, 0x00000300); - nv_icmd(dev, 0x0000007e, 0x00000300); - nv_icmd(dev, 0x0000007f, 0x00000300); - nv_icmd(dev, 0x00000050, 0x00000011); - nv_icmd(dev, 0x00000058, 0x00000008); - nv_icmd(dev, 0x00000059, 0x00000008); - nv_icmd(dev, 0x0000005a, 0x00000008); - nv_icmd(dev, 0x0000005b, 0x00000008); - nv_icmd(dev, 0x0000005c, 0x00000008); - nv_icmd(dev, 0x0000005d, 0x00000008); - nv_icmd(dev, 0x0000005e, 0x00000008); - nv_icmd(dev, 0x0000005f, 0x00000008); - nv_icmd(dev, 0x00000208, 0x00000001); - nv_icmd(dev, 0x00000209, 0x00000001); - nv_icmd(dev, 0x0000020a, 0x00000001); - nv_icmd(dev, 0x0000020b, 0x00000001); - nv_icmd(dev, 0x0000020c, 0x00000001); - nv_icmd(dev, 0x0000020d, 0x00000001); - nv_icmd(dev, 0x0000020e, 0x00000001); - nv_icmd(dev, 0x0000020f, 0x00000001); - nv_icmd(dev, 0x00000081, 0x00000001); - nv_icmd(dev, 0x00000085, 0x00000004); - nv_icmd(dev, 0x00000088, 0x00000400); - nv_icmd(dev, 0x00000090, 0x00000300); - nv_icmd(dev, 0x00000098, 0x00001001); - nv_icmd(dev, 0x000000e3, 0x00000001); - nv_icmd(dev, 0x000000da, 0x00000001); - nv_icmd(dev, 0x000000f8, 0x00000003); - nv_icmd(dev, 0x000000fa, 0x00000001); - nv_icmd(dev, 0x0000009f, 0x0000ffff); - nv_icmd(dev, 0x000000a0, 0x0000ffff); - nv_icmd(dev, 0x000000a1, 0x0000ffff); - nv_icmd(dev, 0x000000a2, 0x0000ffff); - nv_icmd(dev, 0x000000b1, 0x00000001); - nv_icmd(dev, 0x000000b2, 0x00000000); - nv_icmd(dev, 0x000000b3, 0x00000000); - nv_icmd(dev, 0x000000b4, 0x00000000); - nv_icmd(dev, 0x000000b5, 0x00000000); - nv_icmd(dev, 0x000000b6, 0x00000000); - nv_icmd(dev, 0x000000b7, 0x00000000); - nv_icmd(dev, 0x000000b8, 0x00000000); - nv_icmd(dev, 0x000000b9, 0x00000000); - nv_icmd(dev, 0x000000ba, 0x00000000); - nv_icmd(dev, 0x000000bb, 0x00000000); - nv_icmd(dev, 0x000000bc, 0x00000000); - nv_icmd(dev, 0x000000bd, 0x00000000); - nv_icmd(dev, 0x000000be, 0x00000000); - nv_icmd(dev, 0x000000bf, 0x00000000); - nv_icmd(dev, 0x000000c0, 0x00000000); - nv_icmd(dev, 0x000000c1, 0x00000000); - nv_icmd(dev, 0x000000c2, 0x00000000); - nv_icmd(dev, 0x000000c3, 0x00000000); - nv_icmd(dev, 0x000000c4, 0x00000000); - nv_icmd(dev, 0x000000c5, 0x00000000); - nv_icmd(dev, 0x000000c6, 0x00000000); - nv_icmd(dev, 0x000000c7, 0x00000000); - nv_icmd(dev, 0x000000c8, 0x00000000); - nv_icmd(dev, 0x000000c9, 0x00000000); - nv_icmd(dev, 0x000000ca, 0x00000000); - nv_icmd(dev, 0x000000cb, 0x00000000); - nv_icmd(dev, 0x000000cc, 0x00000000); - nv_icmd(dev, 0x000000cd, 0x00000000); - nv_icmd(dev, 0x000000ce, 0x00000000); - nv_icmd(dev, 0x000000cf, 0x00000000); - nv_icmd(dev, 0x000000d0, 0x00000000); - nv_icmd(dev, 0x000000d1, 0x00000000); - nv_icmd(dev, 0x000000d2, 0x00000000); - nv_icmd(dev, 0x000000d3, 0x00000000); - nv_icmd(dev, 0x000000d4, 0x00000000); - nv_icmd(dev, 0x000000d5, 0x00000000); - nv_icmd(dev, 0x000000d6, 0x00000000); - nv_icmd(dev, 0x000000d7, 0x00000000); - nv_icmd(dev, 0x000000d8, 0x00000000); - nv_icmd(dev, 0x000000d9, 0x00000000); - nv_icmd(dev, 0x00000210, 0x00000040); - nv_icmd(dev, 0x00000211, 0x00000040); - nv_icmd(dev, 0x00000212, 0x00000040); - nv_icmd(dev, 0x00000213, 0x00000040); - nv_icmd(dev, 0x00000214, 0x00000040); - nv_icmd(dev, 0x00000215, 0x00000040); - nv_icmd(dev, 0x00000216, 0x00000040); - nv_icmd(dev, 0x00000217, 0x00000040); - if (dev_priv->chipset == 0xd9) { - for (i = 0x0400; i <= 0x0417; i++) - nv_icmd(dev, i, 0x00000040); - } - nv_icmd(dev, 0x00000218, 0x0000c080); - nv_icmd(dev, 0x00000219, 0x0000c080); - nv_icmd(dev, 0x0000021a, 0x0000c080); - nv_icmd(dev, 0x0000021b, 0x0000c080); - nv_icmd(dev, 0x0000021c, 0x0000c080); - nv_icmd(dev, 0x0000021d, 0x0000c080); - nv_icmd(dev, 0x0000021e, 0x0000c080); - nv_icmd(dev, 0x0000021f, 0x0000c080); - if (dev_priv->chipset == 0xd9) { - for (i = 0x0440; i <= 0x0457; i++) - nv_icmd(dev, i, 0x0000c080); - } - nv_icmd(dev, 0x000000ad, 0x0000013e); - nv_icmd(dev, 0x000000e1, 0x00000010); - nv_icmd(dev, 0x00000290, 0x00000000); - nv_icmd(dev, 0x00000291, 0x00000000); - nv_icmd(dev, 0x00000292, 0x00000000); - nv_icmd(dev, 0x00000293, 0x00000000); - nv_icmd(dev, 0x00000294, 0x00000000); - nv_icmd(dev, 0x00000295, 0x00000000); - nv_icmd(dev, 0x00000296, 0x00000000); - nv_icmd(dev, 0x00000297, 0x00000000); - nv_icmd(dev, 0x00000298, 0x00000000); - nv_icmd(dev, 0x00000299, 0x00000000); - nv_icmd(dev, 0x0000029a, 0x00000000); - nv_icmd(dev, 0x0000029b, 0x00000000); - nv_icmd(dev, 0x0000029c, 0x00000000); - nv_icmd(dev, 0x0000029d, 0x00000000); - nv_icmd(dev, 0x0000029e, 0x00000000); - nv_icmd(dev, 0x0000029f, 0x00000000); - nv_icmd(dev, 0x000003b0, 0x00000000); - nv_icmd(dev, 0x000003b1, 0x00000000); - nv_icmd(dev, 0x000003b2, 0x00000000); - nv_icmd(dev, 0x000003b3, 0x00000000); - nv_icmd(dev, 0x000003b4, 0x00000000); - nv_icmd(dev, 0x000003b5, 0x00000000); - nv_icmd(dev, 0x000003b6, 0x00000000); - nv_icmd(dev, 0x000003b7, 0x00000000); - nv_icmd(dev, 0x000003b8, 0x00000000); - nv_icmd(dev, 0x000003b9, 0x00000000); - nv_icmd(dev, 0x000003ba, 0x00000000); - nv_icmd(dev, 0x000003bb, 0x00000000); - nv_icmd(dev, 0x000003bc, 0x00000000); - nv_icmd(dev, 0x000003bd, 0x00000000); - nv_icmd(dev, 0x000003be, 0x00000000); - nv_icmd(dev, 0x000003bf, 0x00000000); - nv_icmd(dev, 0x000002a0, 0x00000000); - nv_icmd(dev, 0x000002a1, 0x00000000); - nv_icmd(dev, 0x000002a2, 0x00000000); - nv_icmd(dev, 0x000002a3, 0x00000000); - nv_icmd(dev, 0x000002a4, 0x00000000); - nv_icmd(dev, 0x000002a5, 0x00000000); - nv_icmd(dev, 0x000002a6, 0x00000000); - nv_icmd(dev, 0x000002a7, 0x00000000); - nv_icmd(dev, 0x000002a8, 0x00000000); - nv_icmd(dev, 0x000002a9, 0x00000000); - nv_icmd(dev, 0x000002aa, 0x00000000); - nv_icmd(dev, 0x000002ab, 0x00000000); - nv_icmd(dev, 0x000002ac, 0x00000000); - nv_icmd(dev, 0x000002ad, 0x00000000); - nv_icmd(dev, 0x000002ae, 0x00000000); - nv_icmd(dev, 0x000002af, 0x00000000); - nv_icmd(dev, 0x00000420, 0x00000000); - nv_icmd(dev, 0x00000421, 0x00000000); - nv_icmd(dev, 0x00000422, 0x00000000); - nv_icmd(dev, 0x00000423, 0x00000000); - nv_icmd(dev, 0x00000424, 0x00000000); - nv_icmd(dev, 0x00000425, 0x00000000); - nv_icmd(dev, 0x00000426, 0x00000000); - nv_icmd(dev, 0x00000427, 0x00000000); - nv_icmd(dev, 0x00000428, 0x00000000); - nv_icmd(dev, 0x00000429, 0x00000000); - nv_icmd(dev, 0x0000042a, 0x00000000); - nv_icmd(dev, 0x0000042b, 0x00000000); - nv_icmd(dev, 0x0000042c, 0x00000000); - nv_icmd(dev, 0x0000042d, 0x00000000); - nv_icmd(dev, 0x0000042e, 0x00000000); - nv_icmd(dev, 0x0000042f, 0x00000000); - nv_icmd(dev, 0x000002b0, 0x00000000); - nv_icmd(dev, 0x000002b1, 0x00000000); - nv_icmd(dev, 0x000002b2, 0x00000000); - nv_icmd(dev, 0x000002b3, 0x00000000); - nv_icmd(dev, 0x000002b4, 0x00000000); - nv_icmd(dev, 0x000002b5, 0x00000000); - nv_icmd(dev, 0x000002b6, 0x00000000); - nv_icmd(dev, 0x000002b7, 0x00000000); - nv_icmd(dev, 0x000002b8, 0x00000000); - nv_icmd(dev, 0x000002b9, 0x00000000); - nv_icmd(dev, 0x000002ba, 0x00000000); - nv_icmd(dev, 0x000002bb, 0x00000000); - nv_icmd(dev, 0x000002bc, 0x00000000); - nv_icmd(dev, 0x000002bd, 0x00000000); - nv_icmd(dev, 0x000002be, 0x00000000); - nv_icmd(dev, 0x000002bf, 0x00000000); - nv_icmd(dev, 0x00000430, 0x00000000); - nv_icmd(dev, 0x00000431, 0x00000000); - nv_icmd(dev, 0x00000432, 0x00000000); - nv_icmd(dev, 0x00000433, 0x00000000); - nv_icmd(dev, 0x00000434, 0x00000000); - nv_icmd(dev, 0x00000435, 0x00000000); - nv_icmd(dev, 0x00000436, 0x00000000); - nv_icmd(dev, 0x00000437, 0x00000000); - nv_icmd(dev, 0x00000438, 0x00000000); - nv_icmd(dev, 0x00000439, 0x00000000); - nv_icmd(dev, 0x0000043a, 0x00000000); - nv_icmd(dev, 0x0000043b, 0x00000000); - nv_icmd(dev, 0x0000043c, 0x00000000); - nv_icmd(dev, 0x0000043d, 0x00000000); - nv_icmd(dev, 0x0000043e, 0x00000000); - nv_icmd(dev, 0x0000043f, 0x00000000); - nv_icmd(dev, 0x000002c0, 0x00000000); - nv_icmd(dev, 0x000002c1, 0x00000000); - nv_icmd(dev, 0x000002c2, 0x00000000); - nv_icmd(dev, 0x000002c3, 0x00000000); - nv_icmd(dev, 0x000002c4, 0x00000000); - nv_icmd(dev, 0x000002c5, 0x00000000); - nv_icmd(dev, 0x000002c6, 0x00000000); - nv_icmd(dev, 0x000002c7, 0x00000000); - nv_icmd(dev, 0x000002c8, 0x00000000); - nv_icmd(dev, 0x000002c9, 0x00000000); - nv_icmd(dev, 0x000002ca, 0x00000000); - nv_icmd(dev, 0x000002cb, 0x00000000); - nv_icmd(dev, 0x000002cc, 0x00000000); - nv_icmd(dev, 0x000002cd, 0x00000000); - nv_icmd(dev, 0x000002ce, 0x00000000); - nv_icmd(dev, 0x000002cf, 0x00000000); - nv_icmd(dev, 0x000004d0, 0x00000000); - nv_icmd(dev, 0x000004d1, 0x00000000); - nv_icmd(dev, 0x000004d2, 0x00000000); - nv_icmd(dev, 0x000004d3, 0x00000000); - nv_icmd(dev, 0x000004d4, 0x00000000); - nv_icmd(dev, 0x000004d5, 0x00000000); - nv_icmd(dev, 0x000004d6, 0x00000000); - nv_icmd(dev, 0x000004d7, 0x00000000); - nv_icmd(dev, 0x000004d8, 0x00000000); - nv_icmd(dev, 0x000004d9, 0x00000000); - nv_icmd(dev, 0x000004da, 0x00000000); - nv_icmd(dev, 0x000004db, 0x00000000); - nv_icmd(dev, 0x000004dc, 0x00000000); - nv_icmd(dev, 0x000004dd, 0x00000000); - nv_icmd(dev, 0x000004de, 0x00000000); - nv_icmd(dev, 0x000004df, 0x00000000); - nv_icmd(dev, 0x00000720, 0x00000000); - nv_icmd(dev, 0x00000721, 0x00000000); - nv_icmd(dev, 0x00000722, 0x00000000); - nv_icmd(dev, 0x00000723, 0x00000000); - nv_icmd(dev, 0x00000724, 0x00000000); - nv_icmd(dev, 0x00000725, 0x00000000); - nv_icmd(dev, 0x00000726, 0x00000000); - nv_icmd(dev, 0x00000727, 0x00000000); - nv_icmd(dev, 0x00000728, 0x00000000); - nv_icmd(dev, 0x00000729, 0x00000000); - nv_icmd(dev, 0x0000072a, 0x00000000); - nv_icmd(dev, 0x0000072b, 0x00000000); - nv_icmd(dev, 0x0000072c, 0x00000000); - nv_icmd(dev, 0x0000072d, 0x00000000); - nv_icmd(dev, 0x0000072e, 0x00000000); - nv_icmd(dev, 0x0000072f, 0x00000000); - nv_icmd(dev, 0x000008c0, 0x00000000); - nv_icmd(dev, 0x000008c1, 0x00000000); - nv_icmd(dev, 0x000008c2, 0x00000000); - nv_icmd(dev, 0x000008c3, 0x00000000); - nv_icmd(dev, 0x000008c4, 0x00000000); - nv_icmd(dev, 0x000008c5, 0x00000000); - nv_icmd(dev, 0x000008c6, 0x00000000); - nv_icmd(dev, 0x000008c7, 0x00000000); - nv_icmd(dev, 0x000008c8, 0x00000000); - nv_icmd(dev, 0x000008c9, 0x00000000); - nv_icmd(dev, 0x000008ca, 0x00000000); - nv_icmd(dev, 0x000008cb, 0x00000000); - nv_icmd(dev, 0x000008cc, 0x00000000); - nv_icmd(dev, 0x000008cd, 0x00000000); - nv_icmd(dev, 0x000008ce, 0x00000000); - nv_icmd(dev, 0x000008cf, 0x00000000); - nv_icmd(dev, 0x00000890, 0x00000000); - nv_icmd(dev, 0x00000891, 0x00000000); - nv_icmd(dev, 0x00000892, 0x00000000); - nv_icmd(dev, 0x00000893, 0x00000000); - nv_icmd(dev, 0x00000894, 0x00000000); - nv_icmd(dev, 0x00000895, 0x00000000); - nv_icmd(dev, 0x00000896, 0x00000000); - nv_icmd(dev, 0x00000897, 0x00000000); - nv_icmd(dev, 0x00000898, 0x00000000); - nv_icmd(dev, 0x00000899, 0x00000000); - nv_icmd(dev, 0x0000089a, 0x00000000); - nv_icmd(dev, 0x0000089b, 0x00000000); - nv_icmd(dev, 0x0000089c, 0x00000000); - nv_icmd(dev, 0x0000089d, 0x00000000); - nv_icmd(dev, 0x0000089e, 0x00000000); - nv_icmd(dev, 0x0000089f, 0x00000000); - nv_icmd(dev, 0x000008e0, 0x00000000); - nv_icmd(dev, 0x000008e1, 0x00000000); - nv_icmd(dev, 0x000008e2, 0x00000000); - nv_icmd(dev, 0x000008e3, 0x00000000); - nv_icmd(dev, 0x000008e4, 0x00000000); - nv_icmd(dev, 0x000008e5, 0x00000000); - nv_icmd(dev, 0x000008e6, 0x00000000); - nv_icmd(dev, 0x000008e7, 0x00000000); - nv_icmd(dev, 0x000008e8, 0x00000000); - nv_icmd(dev, 0x000008e9, 0x00000000); - nv_icmd(dev, 0x000008ea, 0x00000000); - nv_icmd(dev, 0x000008eb, 0x00000000); - nv_icmd(dev, 0x000008ec, 0x00000000); - nv_icmd(dev, 0x000008ed, 0x00000000); - nv_icmd(dev, 0x000008ee, 0x00000000); - nv_icmd(dev, 0x000008ef, 0x00000000); - nv_icmd(dev, 0x000008a0, 0x00000000); - nv_icmd(dev, 0x000008a1, 0x00000000); - nv_icmd(dev, 0x000008a2, 0x00000000); - nv_icmd(dev, 0x000008a3, 0x00000000); - nv_icmd(dev, 0x000008a4, 0x00000000); - nv_icmd(dev, 0x000008a5, 0x00000000); - nv_icmd(dev, 0x000008a6, 0x00000000); - nv_icmd(dev, 0x000008a7, 0x00000000); - nv_icmd(dev, 0x000008a8, 0x00000000); - nv_icmd(dev, 0x000008a9, 0x00000000); - nv_icmd(dev, 0x000008aa, 0x00000000); - nv_icmd(dev, 0x000008ab, 0x00000000); - nv_icmd(dev, 0x000008ac, 0x00000000); - nv_icmd(dev, 0x000008ad, 0x00000000); - nv_icmd(dev, 0x000008ae, 0x00000000); - nv_icmd(dev, 0x000008af, 0x00000000); - nv_icmd(dev, 0x000008f0, 0x00000000); - nv_icmd(dev, 0x000008f1, 0x00000000); - nv_icmd(dev, 0x000008f2, 0x00000000); - nv_icmd(dev, 0x000008f3, 0x00000000); - nv_icmd(dev, 0x000008f4, 0x00000000); - nv_icmd(dev, 0x000008f5, 0x00000000); - nv_icmd(dev, 0x000008f6, 0x00000000); - nv_icmd(dev, 0x000008f7, 0x00000000); - nv_icmd(dev, 0x000008f8, 0x00000000); - nv_icmd(dev, 0x000008f9, 0x00000000); - nv_icmd(dev, 0x000008fa, 0x00000000); - nv_icmd(dev, 0x000008fb, 0x00000000); - nv_icmd(dev, 0x000008fc, 0x00000000); - nv_icmd(dev, 0x000008fd, 0x00000000); - nv_icmd(dev, 0x000008fe, 0x00000000); - nv_icmd(dev, 0x000008ff, 0x00000000); - nv_icmd(dev, 0x0000094c, 0x000000ff); - nv_icmd(dev, 0x0000094d, 0xffffffff); - nv_icmd(dev, 0x0000094e, 0x00000002); - nv_icmd(dev, 0x000002ec, 0x00000001); - nv_icmd(dev, 0x00000303, 0x00000001); - nv_icmd(dev, 0x000002e6, 0x00000001); - nv_icmd(dev, 0x00000466, 0x00000052); - nv_icmd(dev, 0x00000301, 0x3f800000); - nv_icmd(dev, 0x00000304, 0x30201000); - nv_icmd(dev, 0x00000305, 0x70605040); - nv_icmd(dev, 0x00000306, 0xb8a89888); - nv_icmd(dev, 0x00000307, 0xf8e8d8c8); - nv_icmd(dev, 0x0000030a, 0x00ffff00); - nv_icmd(dev, 0x0000030b, 0x0000001a); - nv_icmd(dev, 0x0000030c, 0x00000001); - nv_icmd(dev, 0x00000318, 0x00000001); - nv_icmd(dev, 0x00000340, 0x00000000); - nv_icmd(dev, 0x00000375, 0x00000001); - nv_icmd(dev, 0x00000351, 0x00000100); - nv_icmd(dev, 0x0000037d, 0x00000006); - nv_icmd(dev, 0x000003a0, 0x00000002); - nv_icmd(dev, 0x000003aa, 0x00000001); - nv_icmd(dev, 0x000003a9, 0x00000001); - nv_icmd(dev, 0x00000380, 0x00000001); - nv_icmd(dev, 0x00000360, 0x00000040); - nv_icmd(dev, 0x00000366, 0x00000000); - nv_icmd(dev, 0x00000367, 0x00000000); - nv_icmd(dev, 0x00000368, 0x00001fff); - nv_icmd(dev, 0x00000370, 0x00000000); - nv_icmd(dev, 0x00000371, 0x00000000); - nv_icmd(dev, 0x00000372, 0x003fffff); - nv_icmd(dev, 0x0000037a, 0x00000012); - nv_icmd(dev, 0x000005e0, 0x00000022); - nv_icmd(dev, 0x000005e1, 0x00000022); - nv_icmd(dev, 0x000005e2, 0x00000022); - nv_icmd(dev, 0x000005e3, 0x00000022); - nv_icmd(dev, 0x000005e4, 0x00000022); - nv_icmd(dev, 0x00000619, 0x00000003); - nv_icmd(dev, 0x00000811, 0x00000003); - nv_icmd(dev, 0x00000812, 0x00000004); - nv_icmd(dev, 0x00000813, 0x00000006); - nv_icmd(dev, 0x00000814, 0x00000008); - nv_icmd(dev, 0x00000815, 0x0000000b); - nv_icmd(dev, 0x00000800, 0x00000001); - nv_icmd(dev, 0x00000801, 0x00000001); - nv_icmd(dev, 0x00000802, 0x00000001); - nv_icmd(dev, 0x00000803, 0x00000001); - nv_icmd(dev, 0x00000804, 0x00000001); - nv_icmd(dev, 0x00000805, 0x00000001); - nv_icmd(dev, 0x00000632, 0x00000001); - nv_icmd(dev, 0x00000633, 0x00000002); - nv_icmd(dev, 0x00000634, 0x00000003); - nv_icmd(dev, 0x00000635, 0x00000004); - nv_icmd(dev, 0x00000654, 0x3f800000); - nv_icmd(dev, 0x00000657, 0x3f800000); - nv_icmd(dev, 0x00000655, 0x3f800000); - nv_icmd(dev, 0x00000656, 0x3f800000); - nv_icmd(dev, 0x000006cd, 0x3f800000); - nv_icmd(dev, 0x000007f5, 0x3f800000); - nv_icmd(dev, 0x000007dc, 0x39291909); - nv_icmd(dev, 0x000007dd, 0x79695949); - nv_icmd(dev, 0x000007de, 0xb9a99989); - nv_icmd(dev, 0x000007df, 0xf9e9d9c9); - nv_icmd(dev, 0x000007e8, 0x00003210); - nv_icmd(dev, 0x000007e9, 0x00007654); - nv_icmd(dev, 0x000007ea, 0x00000098); - nv_icmd(dev, 0x000007ec, 0x39291909); - nv_icmd(dev, 0x000007ed, 0x79695949); - nv_icmd(dev, 0x000007ee, 0xb9a99989); - nv_icmd(dev, 0x000007ef, 0xf9e9d9c9); - nv_icmd(dev, 0x000007f0, 0x00003210); - nv_icmd(dev, 0x000007f1, 0x00007654); - nv_icmd(dev, 0x000007f2, 0x00000098); - nv_icmd(dev, 0x000005a5, 0x00000001); - nv_icmd(dev, 0x00000980, 0x00000000); - nv_icmd(dev, 0x00000981, 0x00000000); - nv_icmd(dev, 0x00000982, 0x00000000); - nv_icmd(dev, 0x00000983, 0x00000000); - nv_icmd(dev, 0x00000984, 0x00000000); - nv_icmd(dev, 0x00000985, 0x00000000); - nv_icmd(dev, 0x00000986, 0x00000000); - nv_icmd(dev, 0x00000987, 0x00000000); - nv_icmd(dev, 0x00000988, 0x00000000); - nv_icmd(dev, 0x00000989, 0x00000000); - nv_icmd(dev, 0x0000098a, 0x00000000); - nv_icmd(dev, 0x0000098b, 0x00000000); - nv_icmd(dev, 0x0000098c, 0x00000000); - nv_icmd(dev, 0x0000098d, 0x00000000); - nv_icmd(dev, 0x0000098e, 0x00000000); - nv_icmd(dev, 0x0000098f, 0x00000000); - nv_icmd(dev, 0x00000990, 0x00000000); - nv_icmd(dev, 0x00000991, 0x00000000); - nv_icmd(dev, 0x00000992, 0x00000000); - nv_icmd(dev, 0x00000993, 0x00000000); - nv_icmd(dev, 0x00000994, 0x00000000); - nv_icmd(dev, 0x00000995, 0x00000000); - nv_icmd(dev, 0x00000996, 0x00000000); - nv_icmd(dev, 0x00000997, 0x00000000); - nv_icmd(dev, 0x00000998, 0x00000000); - nv_icmd(dev, 0x00000999, 0x00000000); - nv_icmd(dev, 0x0000099a, 0x00000000); - nv_icmd(dev, 0x0000099b, 0x00000000); - nv_icmd(dev, 0x0000099c, 0x00000000); - nv_icmd(dev, 0x0000099d, 0x00000000); - nv_icmd(dev, 0x0000099e, 0x00000000); - nv_icmd(dev, 0x0000099f, 0x00000000); - nv_icmd(dev, 0x000009a0, 0x00000000); - nv_icmd(dev, 0x000009a1, 0x00000000); - nv_icmd(dev, 0x000009a2, 0x00000000); - nv_icmd(dev, 0x000009a3, 0x00000000); - nv_icmd(dev, 0x000009a4, 0x00000000); - nv_icmd(dev, 0x000009a5, 0x00000000); - nv_icmd(dev, 0x000009a6, 0x00000000); - nv_icmd(dev, 0x000009a7, 0x00000000); - nv_icmd(dev, 0x000009a8, 0x00000000); - nv_icmd(dev, 0x000009a9, 0x00000000); - nv_icmd(dev, 0x000009aa, 0x00000000); - nv_icmd(dev, 0x000009ab, 0x00000000); - nv_icmd(dev, 0x000009ac, 0x00000000); - nv_icmd(dev, 0x000009ad, 0x00000000); - nv_icmd(dev, 0x000009ae, 0x00000000); - nv_icmd(dev, 0x000009af, 0x00000000); - nv_icmd(dev, 0x000009b0, 0x00000000); - nv_icmd(dev, 0x000009b1, 0x00000000); - nv_icmd(dev, 0x000009b2, 0x00000000); - nv_icmd(dev, 0x000009b3, 0x00000000); - nv_icmd(dev, 0x000009b4, 0x00000000); - nv_icmd(dev, 0x000009b5, 0x00000000); - nv_icmd(dev, 0x000009b6, 0x00000000); - nv_icmd(dev, 0x000009b7, 0x00000000); - nv_icmd(dev, 0x000009b8, 0x00000000); - nv_icmd(dev, 0x000009b9, 0x00000000); - nv_icmd(dev, 0x000009ba, 0x00000000); - nv_icmd(dev, 0x000009bb, 0x00000000); - nv_icmd(dev, 0x000009bc, 0x00000000); - nv_icmd(dev, 0x000009bd, 0x00000000); - nv_icmd(dev, 0x000009be, 0x00000000); - nv_icmd(dev, 0x000009bf, 0x00000000); - nv_icmd(dev, 0x000009c0, 0x00000000); - nv_icmd(dev, 0x000009c1, 0x00000000); - nv_icmd(dev, 0x000009c2, 0x00000000); - nv_icmd(dev, 0x000009c3, 0x00000000); - nv_icmd(dev, 0x000009c4, 0x00000000); - nv_icmd(dev, 0x000009c5, 0x00000000); - nv_icmd(dev, 0x000009c6, 0x00000000); - nv_icmd(dev, 0x000009c7, 0x00000000); - nv_icmd(dev, 0x000009c8, 0x00000000); - nv_icmd(dev, 0x000009c9, 0x00000000); - nv_icmd(dev, 0x000009ca, 0x00000000); - nv_icmd(dev, 0x000009cb, 0x00000000); - nv_icmd(dev, 0x000009cc, 0x00000000); - nv_icmd(dev, 0x000009cd, 0x00000000); - nv_icmd(dev, 0x000009ce, 0x00000000); - nv_icmd(dev, 0x000009cf, 0x00000000); - nv_icmd(dev, 0x000009d0, 0x00000000); - nv_icmd(dev, 0x000009d1, 0x00000000); - nv_icmd(dev, 0x000009d2, 0x00000000); - nv_icmd(dev, 0x000009d3, 0x00000000); - nv_icmd(dev, 0x000009d4, 0x00000000); - nv_icmd(dev, 0x000009d5, 0x00000000); - nv_icmd(dev, 0x000009d6, 0x00000000); - nv_icmd(dev, 0x000009d7, 0x00000000); - nv_icmd(dev, 0x000009d8, 0x00000000); - nv_icmd(dev, 0x000009d9, 0x00000000); - nv_icmd(dev, 0x000009da, 0x00000000); - nv_icmd(dev, 0x000009db, 0x00000000); - nv_icmd(dev, 0x000009dc, 0x00000000); - nv_icmd(dev, 0x000009dd, 0x00000000); - nv_icmd(dev, 0x000009de, 0x00000000); - nv_icmd(dev, 0x000009df, 0x00000000); - nv_icmd(dev, 0x000009e0, 0x00000000); - nv_icmd(dev, 0x000009e1, 0x00000000); - nv_icmd(dev, 0x000009e2, 0x00000000); - nv_icmd(dev, 0x000009e3, 0x00000000); - nv_icmd(dev, 0x000009e4, 0x00000000); - nv_icmd(dev, 0x000009e5, 0x00000000); - nv_icmd(dev, 0x000009e6, 0x00000000); - nv_icmd(dev, 0x000009e7, 0x00000000); - nv_icmd(dev, 0x000009e8, 0x00000000); - nv_icmd(dev, 0x000009e9, 0x00000000); - nv_icmd(dev, 0x000009ea, 0x00000000); - nv_icmd(dev, 0x000009eb, 0x00000000); - nv_icmd(dev, 0x000009ec, 0x00000000); - nv_icmd(dev, 0x000009ed, 0x00000000); - nv_icmd(dev, 0x000009ee, 0x00000000); - nv_icmd(dev, 0x000009ef, 0x00000000); - nv_icmd(dev, 0x000009f0, 0x00000000); - nv_icmd(dev, 0x000009f1, 0x00000000); - nv_icmd(dev, 0x000009f2, 0x00000000); - nv_icmd(dev, 0x000009f3, 0x00000000); - nv_icmd(dev, 0x000009f4, 0x00000000); - nv_icmd(dev, 0x000009f5, 0x00000000); - nv_icmd(dev, 0x000009f6, 0x00000000); - nv_icmd(dev, 0x000009f7, 0x00000000); - nv_icmd(dev, 0x000009f8, 0x00000000); - nv_icmd(dev, 0x000009f9, 0x00000000); - nv_icmd(dev, 0x000009fa, 0x00000000); - nv_icmd(dev, 0x000009fb, 0x00000000); - nv_icmd(dev, 0x000009fc, 0x00000000); - nv_icmd(dev, 0x000009fd, 0x00000000); - nv_icmd(dev, 0x000009fe, 0x00000000); - nv_icmd(dev, 0x000009ff, 0x00000000); - nv_icmd(dev, 0x00000468, 0x00000004); - nv_icmd(dev, 0x0000046c, 0x00000001); - nv_icmd(dev, 0x00000470, 0x00000000); - nv_icmd(dev, 0x00000471, 0x00000000); - nv_icmd(dev, 0x00000472, 0x00000000); - nv_icmd(dev, 0x00000473, 0x00000000); - nv_icmd(dev, 0x00000474, 0x00000000); - nv_icmd(dev, 0x00000475, 0x00000000); - nv_icmd(dev, 0x00000476, 0x00000000); - nv_icmd(dev, 0x00000477, 0x00000000); - nv_icmd(dev, 0x00000478, 0x00000000); - nv_icmd(dev, 0x00000479, 0x00000000); - nv_icmd(dev, 0x0000047a, 0x00000000); - nv_icmd(dev, 0x0000047b, 0x00000000); - nv_icmd(dev, 0x0000047c, 0x00000000); - nv_icmd(dev, 0x0000047d, 0x00000000); - nv_icmd(dev, 0x0000047e, 0x00000000); - nv_icmd(dev, 0x0000047f, 0x00000000); - nv_icmd(dev, 0x00000480, 0x00000000); - nv_icmd(dev, 0x00000481, 0x00000000); - nv_icmd(dev, 0x00000482, 0x00000000); - nv_icmd(dev, 0x00000483, 0x00000000); - nv_icmd(dev, 0x00000484, 0x00000000); - nv_icmd(dev, 0x00000485, 0x00000000); - nv_icmd(dev, 0x00000486, 0x00000000); - nv_icmd(dev, 0x00000487, 0x00000000); - nv_icmd(dev, 0x00000488, 0x00000000); - nv_icmd(dev, 0x00000489, 0x00000000); - nv_icmd(dev, 0x0000048a, 0x00000000); - nv_icmd(dev, 0x0000048b, 0x00000000); - nv_icmd(dev, 0x0000048c, 0x00000000); - nv_icmd(dev, 0x0000048d, 0x00000000); - nv_icmd(dev, 0x0000048e, 0x00000000); - nv_icmd(dev, 0x0000048f, 0x00000000); - nv_icmd(dev, 0x00000490, 0x00000000); - nv_icmd(dev, 0x00000491, 0x00000000); - nv_icmd(dev, 0x00000492, 0x00000000); - nv_icmd(dev, 0x00000493, 0x00000000); - nv_icmd(dev, 0x00000494, 0x00000000); - nv_icmd(dev, 0x00000495, 0x00000000); - nv_icmd(dev, 0x00000496, 0x00000000); - nv_icmd(dev, 0x00000497, 0x00000000); - nv_icmd(dev, 0x00000498, 0x00000000); - nv_icmd(dev, 0x00000499, 0x00000000); - nv_icmd(dev, 0x0000049a, 0x00000000); - nv_icmd(dev, 0x0000049b, 0x00000000); - nv_icmd(dev, 0x0000049c, 0x00000000); - nv_icmd(dev, 0x0000049d, 0x00000000); - nv_icmd(dev, 0x0000049e, 0x00000000); - nv_icmd(dev, 0x0000049f, 0x00000000); - nv_icmd(dev, 0x000004a0, 0x00000000); - nv_icmd(dev, 0x000004a1, 0x00000000); - nv_icmd(dev, 0x000004a2, 0x00000000); - nv_icmd(dev, 0x000004a3, 0x00000000); - nv_icmd(dev, 0x000004a4, 0x00000000); - nv_icmd(dev, 0x000004a5, 0x00000000); - nv_icmd(dev, 0x000004a6, 0x00000000); - nv_icmd(dev, 0x000004a7, 0x00000000); - nv_icmd(dev, 0x000004a8, 0x00000000); - nv_icmd(dev, 0x000004a9, 0x00000000); - nv_icmd(dev, 0x000004aa, 0x00000000); - nv_icmd(dev, 0x000004ab, 0x00000000); - nv_icmd(dev, 0x000004ac, 0x00000000); - nv_icmd(dev, 0x000004ad, 0x00000000); - nv_icmd(dev, 0x000004ae, 0x00000000); - nv_icmd(dev, 0x000004af, 0x00000000); - nv_icmd(dev, 0x000004b0, 0x00000000); - nv_icmd(dev, 0x000004b1, 0x00000000); - nv_icmd(dev, 0x000004b2, 0x00000000); - nv_icmd(dev, 0x000004b3, 0x00000000); - nv_icmd(dev, 0x000004b4, 0x00000000); - nv_icmd(dev, 0x000004b5, 0x00000000); - nv_icmd(dev, 0x000004b6, 0x00000000); - nv_icmd(dev, 0x000004b7, 0x00000000); - nv_icmd(dev, 0x000004b8, 0x00000000); - nv_icmd(dev, 0x000004b9, 0x00000000); - nv_icmd(dev, 0x000004ba, 0x00000000); - nv_icmd(dev, 0x000004bb, 0x00000000); - nv_icmd(dev, 0x000004bc, 0x00000000); - nv_icmd(dev, 0x000004bd, 0x00000000); - nv_icmd(dev, 0x000004be, 0x00000000); - nv_icmd(dev, 0x000004bf, 0x00000000); - nv_icmd(dev, 0x000004c0, 0x00000000); - nv_icmd(dev, 0x000004c1, 0x00000000); - nv_icmd(dev, 0x000004c2, 0x00000000); - nv_icmd(dev, 0x000004c3, 0x00000000); - nv_icmd(dev, 0x000004c4, 0x00000000); - nv_icmd(dev, 0x000004c5, 0x00000000); - nv_icmd(dev, 0x000004c6, 0x00000000); - nv_icmd(dev, 0x000004c7, 0x00000000); - nv_icmd(dev, 0x000004c8, 0x00000000); - nv_icmd(dev, 0x000004c9, 0x00000000); - nv_icmd(dev, 0x000004ca, 0x00000000); - nv_icmd(dev, 0x000004cb, 0x00000000); - nv_icmd(dev, 0x000004cc, 0x00000000); - nv_icmd(dev, 0x000004cd, 0x00000000); - nv_icmd(dev, 0x000004ce, 0x00000000); - nv_icmd(dev, 0x000004cf, 0x00000000); - nv_icmd(dev, 0x00000510, 0x3f800000); - nv_icmd(dev, 0x00000511, 0x3f800000); - nv_icmd(dev, 0x00000512, 0x3f800000); - nv_icmd(dev, 0x00000513, 0x3f800000); - nv_icmd(dev, 0x00000514, 0x3f800000); - nv_icmd(dev, 0x00000515, 0x3f800000); - nv_icmd(dev, 0x00000516, 0x3f800000); - nv_icmd(dev, 0x00000517, 0x3f800000); - nv_icmd(dev, 0x00000518, 0x3f800000); - nv_icmd(dev, 0x00000519, 0x3f800000); - nv_icmd(dev, 0x0000051a, 0x3f800000); - nv_icmd(dev, 0x0000051b, 0x3f800000); - nv_icmd(dev, 0x0000051c, 0x3f800000); - nv_icmd(dev, 0x0000051d, 0x3f800000); - nv_icmd(dev, 0x0000051e, 0x3f800000); - nv_icmd(dev, 0x0000051f, 0x3f800000); - nv_icmd(dev, 0x00000520, 0x000002b6); - nv_icmd(dev, 0x00000529, 0x00000001); - nv_icmd(dev, 0x00000530, 0xffff0000); - nv_icmd(dev, 0x00000531, 0xffff0000); - nv_icmd(dev, 0x00000532, 0xffff0000); - nv_icmd(dev, 0x00000533, 0xffff0000); - nv_icmd(dev, 0x00000534, 0xffff0000); - nv_icmd(dev, 0x00000535, 0xffff0000); - nv_icmd(dev, 0x00000536, 0xffff0000); - nv_icmd(dev, 0x00000537, 0xffff0000); - nv_icmd(dev, 0x00000538, 0xffff0000); - nv_icmd(dev, 0x00000539, 0xffff0000); - nv_icmd(dev, 0x0000053a, 0xffff0000); - nv_icmd(dev, 0x0000053b, 0xffff0000); - nv_icmd(dev, 0x0000053c, 0xffff0000); - nv_icmd(dev, 0x0000053d, 0xffff0000); - nv_icmd(dev, 0x0000053e, 0xffff0000); - nv_icmd(dev, 0x0000053f, 0xffff0000); - nv_icmd(dev, 0x00000585, 0x0000003f); - nv_icmd(dev, 0x00000576, 0x00000003); - if (dev_priv->chipset == 0xc1 || - dev_priv->chipset == 0xd9) - nv_icmd(dev, 0x0000057b, 0x00000059); - nv_icmd(dev, 0x00000586, 0x00000040); - nv_icmd(dev, 0x00000582, 0x00000080); - nv_icmd(dev, 0x00000583, 0x00000080); - nv_icmd(dev, 0x000005c2, 0x00000001); - nv_icmd(dev, 0x00000638, 0x00000001); - nv_icmd(dev, 0x00000639, 0x00000001); - nv_icmd(dev, 0x0000063a, 0x00000002); - nv_icmd(dev, 0x0000063b, 0x00000001); - nv_icmd(dev, 0x0000063c, 0x00000001); - nv_icmd(dev, 0x0000063d, 0x00000002); - nv_icmd(dev, 0x0000063e, 0x00000001); - nv_icmd(dev, 0x000008b8, 0x00000001); - nv_icmd(dev, 0x000008b9, 0x00000001); - nv_icmd(dev, 0x000008ba, 0x00000001); - nv_icmd(dev, 0x000008bb, 0x00000001); - nv_icmd(dev, 0x000008bc, 0x00000001); - nv_icmd(dev, 0x000008bd, 0x00000001); - nv_icmd(dev, 0x000008be, 0x00000001); - nv_icmd(dev, 0x000008bf, 0x00000001); - nv_icmd(dev, 0x00000900, 0x00000001); - nv_icmd(dev, 0x00000901, 0x00000001); - nv_icmd(dev, 0x00000902, 0x00000001); - nv_icmd(dev, 0x00000903, 0x00000001); - nv_icmd(dev, 0x00000904, 0x00000001); - nv_icmd(dev, 0x00000905, 0x00000001); - nv_icmd(dev, 0x00000906, 0x00000001); - nv_icmd(dev, 0x00000907, 0x00000001); - nv_icmd(dev, 0x00000908, 0x00000002); - nv_icmd(dev, 0x00000909, 0x00000002); - nv_icmd(dev, 0x0000090a, 0x00000002); - nv_icmd(dev, 0x0000090b, 0x00000002); - nv_icmd(dev, 0x0000090c, 0x00000002); - nv_icmd(dev, 0x0000090d, 0x00000002); - nv_icmd(dev, 0x0000090e, 0x00000002); - nv_icmd(dev, 0x0000090f, 0x00000002); - nv_icmd(dev, 0x00000910, 0x00000001); - nv_icmd(dev, 0x00000911, 0x00000001); - nv_icmd(dev, 0x00000912, 0x00000001); - nv_icmd(dev, 0x00000913, 0x00000001); - nv_icmd(dev, 0x00000914, 0x00000001); - nv_icmd(dev, 0x00000915, 0x00000001); - nv_icmd(dev, 0x00000916, 0x00000001); - nv_icmd(dev, 0x00000917, 0x00000001); - nv_icmd(dev, 0x00000918, 0x00000001); - nv_icmd(dev, 0x00000919, 0x00000001); - nv_icmd(dev, 0x0000091a, 0x00000001); - nv_icmd(dev, 0x0000091b, 0x00000001); - nv_icmd(dev, 0x0000091c, 0x00000001); - nv_icmd(dev, 0x0000091d, 0x00000001); - nv_icmd(dev, 0x0000091e, 0x00000001); - nv_icmd(dev, 0x0000091f, 0x00000001); - nv_icmd(dev, 0x00000920, 0x00000002); - nv_icmd(dev, 0x00000921, 0x00000002); - nv_icmd(dev, 0x00000922, 0x00000002); - nv_icmd(dev, 0x00000923, 0x00000002); - nv_icmd(dev, 0x00000924, 0x00000002); - nv_icmd(dev, 0x00000925, 0x00000002); - nv_icmd(dev, 0x00000926, 0x00000002); - nv_icmd(dev, 0x00000927, 0x00000002); - nv_icmd(dev, 0x00000928, 0x00000001); - nv_icmd(dev, 0x00000929, 0x00000001); - nv_icmd(dev, 0x0000092a, 0x00000001); - nv_icmd(dev, 0x0000092b, 0x00000001); - nv_icmd(dev, 0x0000092c, 0x00000001); - nv_icmd(dev, 0x0000092d, 0x00000001); - nv_icmd(dev, 0x0000092e, 0x00000001); - nv_icmd(dev, 0x0000092f, 0x00000001); - nv_icmd(dev, 0x00000648, 0x00000001); - nv_icmd(dev, 0x00000649, 0x00000001); - nv_icmd(dev, 0x0000064a, 0x00000001); - nv_icmd(dev, 0x0000064b, 0x00000001); - nv_icmd(dev, 0x0000064c, 0x00000001); - nv_icmd(dev, 0x0000064d, 0x00000001); - nv_icmd(dev, 0x0000064e, 0x00000001); - nv_icmd(dev, 0x0000064f, 0x00000001); - nv_icmd(dev, 0x00000650, 0x00000001); - nv_icmd(dev, 0x00000658, 0x0000000f); - nv_icmd(dev, 0x000007ff, 0x0000000a); - nv_icmd(dev, 0x0000066a, 0x40000000); - nv_icmd(dev, 0x0000066b, 0x10000000); - nv_icmd(dev, 0x0000066c, 0xffff0000); - nv_icmd(dev, 0x0000066d, 0xffff0000); - nv_icmd(dev, 0x000007af, 0x00000008); - nv_icmd(dev, 0x000007b0, 0x00000008); - nv_icmd(dev, 0x000007f6, 0x00000001); - nv_icmd(dev, 0x000006b2, 0x00000055); - nv_icmd(dev, 0x000007ad, 0x00000003); - nv_icmd(dev, 0x00000937, 0x00000001); - nv_icmd(dev, 0x00000971, 0x00000008); - nv_icmd(dev, 0x00000972, 0x00000040); - nv_icmd(dev, 0x00000973, 0x0000012c); - nv_icmd(dev, 0x0000097c, 0x00000040); - nv_icmd(dev, 0x00000979, 0x00000003); - nv_icmd(dev, 0x00000975, 0x00000020); - nv_icmd(dev, 0x00000976, 0x00000001); - nv_icmd(dev, 0x00000977, 0x00000020); - nv_icmd(dev, 0x00000978, 0x00000001); - nv_icmd(dev, 0x00000957, 0x00000003); - nv_icmd(dev, 0x0000095e, 0x20164010); - nv_icmd(dev, 0x0000095f, 0x00000020); - if (dev_priv->chipset == 0xd9) - nv_icmd(dev, 0x0000097d, 0x00000020); - nv_icmd(dev, 0x00000683, 0x00000006); - nv_icmd(dev, 0x00000685, 0x003fffff); - nv_icmd(dev, 0x00000687, 0x00000c48); - nv_icmd(dev, 0x000006a0, 0x00000005); - nv_icmd(dev, 0x00000840, 0x00300008); - nv_icmd(dev, 0x00000841, 0x04000080); - nv_icmd(dev, 0x00000842, 0x00300008); - nv_icmd(dev, 0x00000843, 0x04000080); - nv_icmd(dev, 0x00000818, 0x00000000); - nv_icmd(dev, 0x00000819, 0x00000000); - nv_icmd(dev, 0x0000081a, 0x00000000); - nv_icmd(dev, 0x0000081b, 0x00000000); - nv_icmd(dev, 0x0000081c, 0x00000000); - nv_icmd(dev, 0x0000081d, 0x00000000); - nv_icmd(dev, 0x0000081e, 0x00000000); - nv_icmd(dev, 0x0000081f, 0x00000000); - nv_icmd(dev, 0x00000848, 0x00000000); - nv_icmd(dev, 0x00000849, 0x00000000); - nv_icmd(dev, 0x0000084a, 0x00000000); - nv_icmd(dev, 0x0000084b, 0x00000000); - nv_icmd(dev, 0x0000084c, 0x00000000); - nv_icmd(dev, 0x0000084d, 0x00000000); - nv_icmd(dev, 0x0000084e, 0x00000000); - nv_icmd(dev, 0x0000084f, 0x00000000); - nv_icmd(dev, 0x00000850, 0x00000000); - nv_icmd(dev, 0x00000851, 0x00000000); - nv_icmd(dev, 0x00000852, 0x00000000); - nv_icmd(dev, 0x00000853, 0x00000000); - nv_icmd(dev, 0x00000854, 0x00000000); - nv_icmd(dev, 0x00000855, 0x00000000); - nv_icmd(dev, 0x00000856, 0x00000000); - nv_icmd(dev, 0x00000857, 0x00000000); - nv_icmd(dev, 0x00000738, 0x00000000); - nv_icmd(dev, 0x000006aa, 0x00000001); - nv_icmd(dev, 0x000006ab, 0x00000002); - nv_icmd(dev, 0x000006ac, 0x00000080); - nv_icmd(dev, 0x000006ad, 0x00000100); - nv_icmd(dev, 0x000006ae, 0x00000100); - nv_icmd(dev, 0x000006b1, 0x00000011); - nv_icmd(dev, 0x000006bb, 0x000000cf); - nv_icmd(dev, 0x000006ce, 0x2a712488); - nv_icmd(dev, 0x00000739, 0x4085c000); - nv_icmd(dev, 0x0000073a, 0x00000080); - nv_icmd(dev, 0x00000786, 0x80000100); - nv_icmd(dev, 0x0000073c, 0x00010100); - nv_icmd(dev, 0x0000073d, 0x02800000); - nv_icmd(dev, 0x00000787, 0x000000cf); - nv_icmd(dev, 0x0000078c, 0x00000008); - nv_icmd(dev, 0x00000792, 0x00000001); - nv_icmd(dev, 0x00000794, 0x00000001); - nv_icmd(dev, 0x00000795, 0x00000001); - nv_icmd(dev, 0x00000796, 0x00000001); - nv_icmd(dev, 0x00000797, 0x000000cf); - nv_icmd(dev, 0x00000836, 0x00000001); - nv_icmd(dev, 0x0000079a, 0x00000002); - nv_icmd(dev, 0x00000833, 0x04444480); - nv_icmd(dev, 0x000007a1, 0x00000001); - nv_icmd(dev, 0x000007a3, 0x00000001); - nv_icmd(dev, 0x000007a4, 0x00000001); - nv_icmd(dev, 0x000007a5, 0x00000001); - nv_icmd(dev, 0x00000831, 0x00000004); - nv_icmd(dev, 0x0000080c, 0x00000002); - nv_icmd(dev, 0x0000080d, 0x00000100); - nv_icmd(dev, 0x0000080e, 0x00000100); - nv_icmd(dev, 0x0000080f, 0x00000001); - nv_icmd(dev, 0x00000823, 0x00000002); - nv_icmd(dev, 0x00000824, 0x00000100); - nv_icmd(dev, 0x00000825, 0x00000100); - nv_icmd(dev, 0x00000826, 0x00000001); - nv_icmd(dev, 0x0000095d, 0x00000001); - nv_icmd(dev, 0x0000082b, 0x00000004); - nv_icmd(dev, 0x00000942, 0x00010001); - nv_icmd(dev, 0x00000943, 0x00000001); - nv_icmd(dev, 0x00000944, 0x00000022); - nv_icmd(dev, 0x000007c5, 0x00010001); - nv_icmd(dev, 0x00000834, 0x00000001); - nv_icmd(dev, 0x000007c7, 0x00000001); - nv_icmd(dev, 0x0000c1b0, 0x0000000f); - nv_icmd(dev, 0x0000c1b1, 0x0000000f); - nv_icmd(dev, 0x0000c1b2, 0x0000000f); - nv_icmd(dev, 0x0000c1b3, 0x0000000f); - nv_icmd(dev, 0x0000c1b4, 0x0000000f); - nv_icmd(dev, 0x0000c1b5, 0x0000000f); - nv_icmd(dev, 0x0000c1b6, 0x0000000f); - nv_icmd(dev, 0x0000c1b7, 0x0000000f); - nv_icmd(dev, 0x0000c1b8, 0x0fac6881); - nv_icmd(dev, 0x0000c1b9, 0x00fac688); - nv_icmd(dev, 0x0001e100, 0x00000001); - nv_icmd(dev, 0x00001000, 0x00000002); - nv_icmd(dev, 0x000006aa, 0x00000001); - nv_icmd(dev, 0x000006ad, 0x00000100); - nv_icmd(dev, 0x000006ae, 0x00000100); - nv_icmd(dev, 0x000006b1, 0x00000011); - nv_icmd(dev, 0x0000078c, 0x00000008); - nv_icmd(dev, 0x00000792, 0x00000001); - nv_icmd(dev, 0x00000794, 0x00000001); - nv_icmd(dev, 0x00000795, 0x00000001); - nv_icmd(dev, 0x00000796, 0x00000001); - nv_icmd(dev, 0x00000797, 0x000000cf); - nv_icmd(dev, 0x0000079a, 0x00000002); - nv_icmd(dev, 0x00000833, 0x04444480); - nv_icmd(dev, 0x000007a1, 0x00000001); - nv_icmd(dev, 0x000007a3, 0x00000001); - nv_icmd(dev, 0x000007a4, 0x00000001); - nv_icmd(dev, 0x000007a5, 0x00000001); - nv_icmd(dev, 0x00000831, 0x00000004); - nv_icmd(dev, 0x0001e100, 0x00000001); - nv_icmd(dev, 0x00001000, 0x00000014); - nv_icmd(dev, 0x00000351, 0x00000100); - nv_icmd(dev, 0x00000957, 0x00000003); - nv_icmd(dev, 0x0000095d, 0x00000001); - nv_icmd(dev, 0x0000082b, 0x00000004); - nv_icmd(dev, 0x00000942, 0x00010001); - nv_icmd(dev, 0x00000943, 0x00000001); - nv_icmd(dev, 0x000007c5, 0x00010001); - nv_icmd(dev, 0x00000834, 0x00000001); - nv_icmd(dev, 0x000007c7, 0x00000001); - nv_icmd(dev, 0x0001e100, 0x00000001); - nv_icmd(dev, 0x00001000, 0x00000001); - nv_icmd(dev, 0x0000080c, 0x00000002); - nv_icmd(dev, 0x0000080d, 0x00000100); - nv_icmd(dev, 0x0000080e, 0x00000100); - nv_icmd(dev, 0x0000080f, 0x00000001); - nv_icmd(dev, 0x00000823, 0x00000002); - nv_icmd(dev, 0x00000824, 0x00000100); - nv_icmd(dev, 0x00000825, 0x00000100); - nv_icmd(dev, 0x00000826, 0x00000001); - nv_icmd(dev, 0x0001e100, 0x00000001); - nv_wr32(dev, 0x400208, 0x00000000); - nv_wr32(dev, 0x404154, 0x00000400); - - nvc0_grctx_generate_9097(dev); - if (fermi >= 0x9197) - nvc0_grctx_generate_9197(dev); - if (fermi >= 0x9297) - nvc0_grctx_generate_9297(dev); - nvc0_grctx_generate_902d(dev); - nvc0_grctx_generate_9039(dev); - nvc0_grctx_generate_90c0(dev); - - nv_wr32(dev, 0x000260, r000260); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc deleted file mode 100644 index 15272be3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc +++ /dev/null @@ -1,539 +0,0 @@ -/* fuc microcode for nvc0 PGRAPH/GPC - * - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -/* To build: - * m4 nvc0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_grgpc.fuc.h - */ - -/* TODO - * - bracket certain functions with scratch writes, useful for debugging - * - watchdog timer around ctx operations - */ - -.section #nvc0_grgpc_data -include(`nvc0_graph.fuc') -gpc_id: .b32 0 -gpc_mmio_list_head: .b32 0 -gpc_mmio_list_tail: .b32 0 - -tpc_count: .b32 0 -tpc_mask: .b32 0 -tpc_mmio_list_head: .b32 0 -tpc_mmio_list_tail: .b32 0 - -cmd_queue: queue_init - -// chipset descriptions -chipsets: -.b8 0xc0 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc0_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvc0_tpc_mmio_tail -.b8 0xc1 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc1_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvc1_tpc_mmio_tail -.b8 0xc3 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc0_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvc3_tpc_mmio_tail -.b8 0xc4 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc0_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvc3_tpc_mmio_tail -.b8 0xc8 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc0_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvc0_tpc_mmio_tail -.b8 0xce 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc0_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvc3_tpc_mmio_tail -.b8 0xcf 0 0 0 -.b16 #nvc0_gpc_mmio_head -.b16 #nvc0_gpc_mmio_tail -.b16 #nvc0_tpc_mmio_head -.b16 #nvcf_tpc_mmio_tail -.b8 0xd9 0 0 0 -.b16 #nvd9_gpc_mmio_head -.b16 #nvd9_gpc_mmio_tail -.b16 #nvd9_tpc_mmio_head -.b16 #nvd9_tpc_mmio_tail -.b8 0 0 0 0 - -// GPC mmio lists -nvc0_gpc_mmio_head: -mmctx_data(0x000380, 1) -mmctx_data(0x000400, 6) -mmctx_data(0x000450, 9) -mmctx_data(0x000600, 1) -mmctx_data(0x000684, 1) -mmctx_data(0x000700, 5) -mmctx_data(0x000800, 1) -mmctx_data(0x000808, 3) -mmctx_data(0x000828, 1) -mmctx_data(0x000830, 1) -mmctx_data(0x0008d8, 1) -mmctx_data(0x0008e0, 1) -mmctx_data(0x0008e8, 6) -mmctx_data(0x00091c, 1) -mmctx_data(0x000924, 3) -mmctx_data(0x000b00, 1) -mmctx_data(0x000b08, 6) -mmctx_data(0x000bb8, 1) -mmctx_data(0x000c08, 1) -mmctx_data(0x000c10, 8) -mmctx_data(0x000c80, 1) -mmctx_data(0x000c8c, 1) -mmctx_data(0x001000, 3) -mmctx_data(0x001014, 1) -nvc0_gpc_mmio_tail: -mmctx_data(0x000c6c, 1); -nvc1_gpc_mmio_tail: - -nvd9_gpc_mmio_head: -mmctx_data(0x000380, 1) -mmctx_data(0x000400, 2) -mmctx_data(0x00040c, 3) -mmctx_data(0x000450, 9) -mmctx_data(0x000600, 1) -mmctx_data(0x000684, 1) -mmctx_data(0x000700, 5) -mmctx_data(0x000800, 1) -mmctx_data(0x000808, 3) -mmctx_data(0x000828, 1) -mmctx_data(0x000830, 1) -mmctx_data(0x0008d8, 1) -mmctx_data(0x0008e0, 1) -mmctx_data(0x0008e8, 6) -mmctx_data(0x00091c, 1) -mmctx_data(0x000924, 3) -mmctx_data(0x000b00, 1) -mmctx_data(0x000b08, 6) -mmctx_data(0x000bb8, 1) -mmctx_data(0x000c08, 1) -mmctx_data(0x000c10, 8) -mmctx_data(0x000c6c, 1) -mmctx_data(0x000c80, 1) -mmctx_data(0x000c8c, 1) -mmctx_data(0x001000, 3) -mmctx_data(0x001014, 1) -nvd9_gpc_mmio_tail: - -// TPC mmio lists -nvc0_tpc_mmio_head: -mmctx_data(0x000018, 1) -mmctx_data(0x00003c, 1) -mmctx_data(0x000048, 1) -mmctx_data(0x000064, 1) -mmctx_data(0x000088, 1) -mmctx_data(0x000200, 6) -mmctx_data(0x00021c, 2) -mmctx_data(0x000300, 6) -mmctx_data(0x0003d0, 1) -mmctx_data(0x0003e0, 2) -mmctx_data(0x000400, 3) -mmctx_data(0x000420, 1) -mmctx_data(0x0004b0, 1) -mmctx_data(0x0004e8, 1) -mmctx_data(0x0004f4, 1) -mmctx_data(0x000520, 2) -mmctx_data(0x000604, 4) -mmctx_data(0x000644, 20) -mmctx_data(0x000698, 1) -mmctx_data(0x000750, 2) -nvc0_tpc_mmio_tail: -mmctx_data(0x000758, 1) -mmctx_data(0x0002c4, 1) -mmctx_data(0x0006e0, 1) -nvcf_tpc_mmio_tail: -mmctx_data(0x0004bc, 1) -nvc3_tpc_mmio_tail: -mmctx_data(0x000544, 1) -nvc1_tpc_mmio_tail: - -nvd9_tpc_mmio_head: -mmctx_data(0x000018, 1) -mmctx_data(0x00003c, 1) -mmctx_data(0x000048, 1) -mmctx_data(0x000064, 1) -mmctx_data(0x000088, 1) -mmctx_data(0x000200, 6) -mmctx_data(0x00021c, 2) -mmctx_data(0x0002c4, 1) -mmctx_data(0x000300, 6) -mmctx_data(0x0003d0, 1) -mmctx_data(0x0003e0, 2) -mmctx_data(0x000400, 3) -mmctx_data(0x000420, 3) -mmctx_data(0x0004b0, 1) -mmctx_data(0x0004e8, 1) -mmctx_data(0x0004f4, 1) -mmctx_data(0x000520, 2) -mmctx_data(0x000544, 1) -mmctx_data(0x000604, 4) -mmctx_data(0x000644, 20) -mmctx_data(0x000698, 1) -mmctx_data(0x0006e0, 1) -mmctx_data(0x000750, 3) -nvd9_tpc_mmio_tail: - -.section #nvc0_grgpc_code -bra #init -define(`include_code') -include(`nvc0_graph.fuc') - -// reports an exception to the host -// -// In: $r15 error code (see nvc0_graph.fuc) -// -error: - push $r14 - mov $r14 -0x67ec // 0x9814 - sethi $r14 0x400000 - call #nv_wr32 // HUB_CTXCTL_CC_SCRATCH[5] = error code - add b32 $r14 0x41c - mov $r15 1 - call #nv_wr32 // HUB_CTXCTL_INTR_UP_SET - pop $r14 - ret - -// GPC fuc initialisation, executed by triggering ucode start, will -// fall through to main loop after completion. -// -// Input: -// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh) -// CC_SCRATCH[1]: context base -// -// Output: -// CC_SCRATCH[0]: -// 31:31: set to signal completion -// CC_SCRATCH[1]: -// 31:0: GPC context size -// -init: - clear b32 $r0 - mov $sp $r0 - - // enable fifo access - mov $r1 0x1200 - mov $r2 2 - iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE - - // setup i0 handler, and route all interrupts to it - mov $r1 #ih - mov $iv0 $r1 - mov $r1 0x400 - iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH - - // enable fifo interrupt - mov $r2 4 - iowr I[$r1 + 0x000] $r2 // INTR_EN_SET - - // enable interrupts - bset $flags ie0 - - // figure out which GPC we are, and how many TPCs we have - mov $r1 0x608 - shl b32 $r1 6 - iord $r2 I[$r1 + 0x000] // UNITS - mov $r3 1 - and $r2 0x1f - shl b32 $r3 $r2 - sub b32 $r3 1 - st b32 D[$r0 + #tpc_count] $r2 - st b32 D[$r0 + #tpc_mask] $r3 - add b32 $r1 0x400 - iord $r2 I[$r1 + 0x000] // MYINDEX - st b32 D[$r0 + #gpc_id] $r2 - - // find context data for this chipset - mov $r2 0x800 - shl b32 $r2 6 - iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0] - mov $r1 #chipsets - 12 - init_find_chipset: - add b32 $r1 12 - ld b32 $r3 D[$r1 + 0x00] - cmpu b32 $r3 $r2 - bra e #init_context - cmpu b32 $r3 0 - bra ne #init_find_chipset - // unknown chipset - ret - - // initialise context base, and size tracking - init_context: - mov $r2 0x800 - shl b32 $r2 6 - iord $r2 I[$r2 + 0x100] // CC_SCRATCH[1], initial base - clear b32 $r3 // track GPC context size here - - // set mmctx base addresses now so we don't have to do it later, - // they don't currently ever change - mov $r4 0x700 - shl b32 $r4 6 - shr b32 $r5 $r2 8 - iowr I[$r4 + 0x000] $r5 // MMCTX_SAVE_SWBASE - iowr I[$r4 + 0x100] $r5 // MMCTX_LOAD_SWBASE - - // calculate GPC mmio context size, store the chipset-specific - // mmio list pointers somewhere we can get at them later without - // re-parsing the chipset list - clear b32 $r14 - clear b32 $r15 - ld b16 $r14 D[$r1 + 4] - ld b16 $r15 D[$r1 + 6] - st b16 D[$r0 + #gpc_mmio_list_head] $r14 - st b16 D[$r0 + #gpc_mmio_list_tail] $r15 - call #mmctx_size - add b32 $r2 $r15 - add b32 $r3 $r15 - - // calculate per-TPC mmio context size, store the list pointers - ld b16 $r14 D[$r1 + 8] - ld b16 $r15 D[$r1 + 10] - st b16 D[$r0 + #tpc_mmio_list_head] $r14 - st b16 D[$r0 + #tpc_mmio_list_tail] $r15 - call #mmctx_size - ld b32 $r14 D[$r0 + #tpc_count] - mulu $r14 $r15 - add b32 $r2 $r14 - add b32 $r3 $r14 - - // round up base/size to 256 byte boundary (for strand SWBASE) - add b32 $r4 0x1300 - shr b32 $r3 2 - iowr I[$r4 + 0x000] $r3 // MMCTX_LOAD_COUNT, wtf for?!? - shr b32 $r2 8 - shr b32 $r3 6 - add b32 $r2 1 - add b32 $r3 1 - shl b32 $r2 8 - shl b32 $r3 8 - - // calculate size of strand context data - mov b32 $r15 $r2 - call #strand_ctx_init - add b32 $r3 $r15 - - // save context size, and tell HUB we're done - mov $r1 0x800 - shl b32 $r1 6 - iowr I[$r1 + 0x100] $r3 // CC_SCRATCH[1] = context size - add b32 $r1 0x800 - clear b32 $r2 - bset $r2 31 - iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000 - -// Main program loop, very simple, sleeps until woken up by the interrupt -// handler, pulls a command from the queue and executes its handler -// -main: - bset $flags $p0 - sleep $p0 - mov $r13 #cmd_queue - call #queue_get - bra $p1 #main - - // 0x0000-0x0003 are all context transfers - cmpu b32 $r14 0x04 - bra nc #main_not_ctx_xfer - // fetch $flags and mask off $p1/$p2 - mov $r1 $flags - mov $r2 0x0006 - not b32 $r2 - and $r1 $r2 - // set $p1/$p2 according to transfer type - shl b32 $r14 1 - or $r1 $r14 - mov $flags $r1 - // transfer context data - call #ctx_xfer - bra #main - - main_not_ctx_xfer: - shl b32 $r15 $r14 16 - or $r15 E_BAD_COMMAND - call #error - bra #main - -// interrupt handler -ih: - push $r8 - mov $r8 $flags - push $r8 - push $r9 - push $r10 - push $r11 - push $r13 - push $r14 - push $r15 - - // incoming fifo command? - iord $r10 I[$r0 + 0x200] // INTR - and $r11 $r10 0x00000004 - bra e #ih_no_fifo - // queue incoming fifo command for later processing - mov $r11 0x1900 - mov $r13 #cmd_queue - iord $r14 I[$r11 + 0x100] // FIFO_CMD - iord $r15 I[$r11 + 0x000] // FIFO_DATA - call #queue_put - add b32 $r11 0x400 - mov $r14 1 - iowr I[$r11 + 0x000] $r14 // FIFO_ACK - - // ack, and wake up main() - ih_no_fifo: - iowr I[$r0 + 0x100] $r10 // INTR_ACK - - pop $r15 - pop $r14 - pop $r13 - pop $r11 - pop $r10 - pop $r9 - pop $r8 - mov $flags $r8 - pop $r8 - bclr $flags $p0 - iret - -// Set this GPC's bit in HUB_BAR, used to signal completion of various -// activities to the HUB fuc -// -hub_barrier_done: - mov $r15 1 - ld b32 $r14 D[$r0 + #gpc_id] - shl b32 $r15 $r14 - mov $r14 -0x6be8 // 0x409418 - HUB_BAR_SET - sethi $r14 0x400000 - call #nv_wr32 - ret - -// Disables various things, waits a bit, and re-enables them.. -// -// Not sure how exactly this helps, perhaps "ENABLE" is not such a -// good description for the bits we turn off? Anyways, without this, -// funny things happen. -// -ctx_redswitch: - mov $r14 0x614 - shl b32 $r14 6 - mov $r15 0x020 - iowr I[$r14] $r15 // GPC_RED_SWITCH = POWER - mov $r15 8 - ctx_redswitch_delay: - sub b32 $r15 1 - bra ne #ctx_redswitch_delay - mov $r15 0xa20 - iowr I[$r14] $r15 // GPC_RED_SWITCH = UNK11, ENABLE, POWER - ret - -// Transfer GPC context data between GPU and storage area -// -// In: $r15 context base address -// $p1 clear on save, set on load -// $p2 set if opposite direction done/will be done, so: -// on save it means: "a load will follow this save" -// on load it means: "a save preceeded this load" -// -ctx_xfer: - // set context base address - mov $r1 0xa04 - shl b32 $r1 6 - iowr I[$r1 + 0x000] $r15// MEM_BASE - bra not $p1 #ctx_xfer_not_load - call #ctx_redswitch - ctx_xfer_not_load: - - // strands - mov $r1 0x4afc - sethi $r1 0x20000 - mov $r2 0xc - iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c - call #strand_wait - mov $r2 0x47fc - sethi $r2 0x20000 - iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00 - xbit $r2 $flags $p1 - add b32 $r2 3 - iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD) - - // mmio context - xbit $r10 $flags $p1 // direction - or $r10 2 // first - mov $r11 0x0000 - sethi $r11 0x500000 - ld b32 $r12 D[$r0 + #gpc_id] - shl b32 $r12 15 - add b32 $r11 $r12 // base = NV_PGRAPH_GPCn - ld b32 $r12 D[$r0 + #gpc_mmio_list_head] - ld b32 $r13 D[$r0 + #gpc_mmio_list_tail] - mov $r14 0 // not multi - call #mmctx_xfer - - // per-TPC mmio context - xbit $r10 $flags $p1 // direction - or $r10 4 // last - mov $r11 0x4000 - sethi $r11 0x500000 // base = NV_PGRAPH_GPC0_TPC0 - ld b32 $r12 D[$r0 + #gpc_id] - shl b32 $r12 15 - add b32 $r11 $r12 // base = NV_PGRAPH_GPCn_TPC0 - ld b32 $r12 D[$r0 + #tpc_mmio_list_head] - ld b32 $r13 D[$r0 + #tpc_mmio_list_tail] - ld b32 $r15 D[$r0 + #tpc_mask] - mov $r14 0x800 // stride = 0x800 - call #mmctx_xfer - - // wait for strands to finish - call #strand_wait - - // if load, or a save without a load following, do some - // unknown stuff that's done after finishing a block of - // strand commands - bra $p1 #ctx_xfer_post - bra not $p2 #ctx_xfer_done - ctx_xfer_post: - mov $r1 0x4afc - sethi $r1 0x20000 - mov $r2 0xd - iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0d - call #strand_wait - - // mark completion in HUB's barrier - ctx_xfer_done: - call #hub_barrier_done - ret - -.align 256 diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h deleted file mode 100644 index a988b8ad..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grgpc.fuc.h +++ /dev/null @@ -1,538 +0,0 @@ -uint32_t nvc0_grgpc_data[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000000c0, - 0x012800c8, - 0x01e40194, - 0x000000c1, - 0x012c00c8, - 0x01f80194, - 0x000000c3, - 0x012800c8, - 0x01f40194, - 0x000000c4, - 0x012800c8, - 0x01f40194, - 0x000000c8, - 0x012800c8, - 0x01e40194, - 0x000000ce, - 0x012800c8, - 0x01f40194, - 0x000000cf, - 0x012800c8, - 0x01f00194, - 0x000000d9, - 0x0194012c, - 0x025401f8, - 0x00000000, - 0x00000380, - 0x14000400, - 0x20000450, - 0x00000600, - 0x00000684, - 0x10000700, - 0x00000800, - 0x08000808, - 0x00000828, - 0x00000830, - 0x000008d8, - 0x000008e0, - 0x140008e8, - 0x0000091c, - 0x08000924, - 0x00000b00, - 0x14000b08, - 0x00000bb8, - 0x00000c08, - 0x1c000c10, - 0x00000c80, - 0x00000c8c, - 0x08001000, - 0x00001014, - 0x00000c6c, - 0x00000380, - 0x04000400, - 0x0800040c, - 0x20000450, - 0x00000600, - 0x00000684, - 0x10000700, - 0x00000800, - 0x08000808, - 0x00000828, - 0x00000830, - 0x000008d8, - 0x000008e0, - 0x140008e8, - 0x0000091c, - 0x08000924, - 0x00000b00, - 0x14000b08, - 0x00000bb8, - 0x00000c08, - 0x1c000c10, - 0x00000c6c, - 0x00000c80, - 0x00000c8c, - 0x08001000, - 0x00001014, - 0x00000018, - 0x0000003c, - 0x00000048, - 0x00000064, - 0x00000088, - 0x14000200, - 0x0400021c, - 0x14000300, - 0x000003d0, - 0x040003e0, - 0x08000400, - 0x00000420, - 0x000004b0, - 0x000004e8, - 0x000004f4, - 0x04000520, - 0x0c000604, - 0x4c000644, - 0x00000698, - 0x04000750, - 0x00000758, - 0x000002c4, - 0x000006e0, - 0x000004bc, - 0x00000544, - 0x00000018, - 0x0000003c, - 0x00000048, - 0x00000064, - 0x00000088, - 0x14000200, - 0x0400021c, - 0x000002c4, - 0x14000300, - 0x000003d0, - 0x040003e0, - 0x08000400, - 0x08000420, - 0x000004b0, - 0x000004e8, - 0x000004f4, - 0x04000520, - 0x00000544, - 0x0c000604, - 0x4c000644, - 0x00000698, - 0x000006e0, - 0x08000750, -}; - -uint32_t nvc0_grgpc_code[] = { - 0x03060ef5, - 0x9800d898, - 0x86f001d9, - 0x0489b808, - 0xf00c1bf4, - 0x21f502f7, - 0x00f802ec, - 0xb60798c4, - 0x8dbb0384, - 0x0880b600, - 0x80008e80, - 0x90b6018f, - 0x0f94f001, - 0xf801d980, - 0x0131f400, - 0x9800d898, - 0x89b801d9, - 0x210bf404, - 0xb60789c4, - 0x9dbb0394, - 0x0890b600, - 0x98009e98, - 0x80b6019f, - 0x0f84f001, - 0xf400d880, - 0x00f80132, - 0x0728b7f1, - 0xb906b4b6, - 0xc9f002ec, - 0x00bcd01f, - 0xc800bccf, - 0x1bf41fcc, - 0x06a7f0fa, - 0x010321f5, - 0xf840bfcf, - 0x28b7f100, - 0x06b4b607, - 0xb980bfd0, - 0xc9f002ec, - 0x1ec9f01f, - 0xcf00bcd0, - 0xccc800bc, - 0xfa1bf41f, - 0x87f100f8, - 0x84b60430, - 0x1ff9f006, - 0xf8008fd0, - 0x3087f100, - 0x0684b604, - 0xf80080d0, - 0x3c87f100, - 0x0684b608, - 0x99f094bd, - 0x0089d000, - 0x081887f1, - 0xd00684b6, - 0x87f1008a, - 0x84b60400, - 0x0088cf06, - 0xf4888aff, - 0x87f1f31b, - 0x84b6085c, - 0xf094bd06, - 0x89d00099, - 0xf100f800, - 0xb6083c87, - 0x94bd0684, - 0xd00099f0, - 0x87f10089, - 0x84b60818, - 0x008ad006, - 0x040087f1, - 0xcf0684b6, - 0x8aff0088, - 0xf30bf488, - 0x085c87f1, - 0xbd0684b6, - 0x0099f094, - 0xf80089d0, - 0x9894bd00, - 0x85b600e8, - 0x0180b61a, - 0xbb0284b6, - 0xe0b60098, - 0x04efb804, - 0xb9eb1bf4, - 0x00f8029f, - 0x083c87f1, - 0xbd0684b6, - 0x0199f094, - 0xf10089d0, - 0xb6071087, - 0x94bd0684, - 0xf405bbfd, - 0x8bd0090b, - 0x0099f000, - 0xf405eefd, - 0x8ed00c0b, - 0xc08fd080, - 0xb70199f0, - 0xc8010080, - 0xb4b600ab, - 0x0cb9f010, - 0xb601aec8, - 0xbefd11e4, - 0x008bd005, - 0xf0008ecf, - 0x0bf41fe4, - 0x00ce98fa, - 0xd005e9fd, - 0xc0b6c08e, - 0x04cdb804, - 0xc8e81bf4, - 0x1bf402ab, - 0x008bcf18, - 0xb01fb4f0, - 0x1bf410b4, - 0x02a7f0f7, - 0xf4c921f4, - 0xabc81b0e, - 0x10b4b600, - 0xf00cb9f0, - 0x8bd012b9, - 0x008bcf00, - 0xf412bbc8, - 0x87f1fa1b, - 0x84b6085c, - 0xf094bd06, - 0x89d00199, - 0xf900f800, - 0x02a7f0a0, - 0xfcc921f4, - 0xf100f8a0, - 0xf04afc87, - 0x97f00283, - 0x0089d00c, - 0x020721f5, - 0x87f100f8, - 0x83f04afc, - 0x0d97f002, - 0xf50089d0, - 0xf8020721, - 0xfca7f100, - 0x02a3f04f, - 0x0500aba2, - 0xd00fc7f0, - 0xc7f000ac, - 0x00bcd00b, - 0x020721f5, - 0xf000aed0, - 0xbcd00ac7, - 0x0721f500, - 0xf100f802, - 0xb6083c87, - 0x94bd0684, - 0xd00399f0, - 0x21f50089, - 0xe7f00213, - 0x3921f503, - 0xfca7f102, - 0x02a3f046, - 0x0400aba0, - 0xf040a0d0, - 0xbcd001c7, - 0x0721f500, - 0x010c9202, - 0xf000acd0, - 0xbcd002c7, - 0x0721f500, - 0x2621f502, - 0x8087f102, - 0x0684b608, - 0xb70089cf, - 0x95220080, - 0x8ed008fe, - 0x408ed000, - 0xb6808acf, - 0xa0b606a5, - 0x00eabb01, - 0xb60480b6, - 0x1bf40192, - 0x08e4b6e8, - 0xf1f2efbc, - 0xb6085c87, - 0x94bd0684, - 0xd00399f0, - 0x00f80089, - 0xe7f1e0f9, - 0xe3f09814, - 0x8d21f440, - 0x041ce0b7, - 0xf401f7f0, - 0xe0fc8d21, - 0x04bd00f8, - 0xf10004fe, - 0xf0120017, - 0x12d00227, - 0x3e17f100, - 0x0010fe04, - 0x040017f1, - 0xf0c010d0, - 0x12d00427, - 0x1031f400, - 0x060817f1, - 0xcf0614b6, - 0x37f00012, - 0x1f24f001, - 0xb60432bb, - 0x02800132, - 0x04038003, - 0x040010b7, - 0x800012cf, - 0x27f10002, - 0x24b60800, - 0x0022cf06, - 0xb65817f0, - 0x13980c10, - 0x0432b800, - 0xb00b0bf4, - 0x1bf40034, - 0xf100f8f1, - 0xb6080027, - 0x22cf0624, - 0xf134bd40, - 0xb6070047, - 0x25950644, - 0x0045d008, - 0xbd4045d0, - 0x58f4bde4, - 0x1f58021e, - 0x020e4003, - 0xf5040f40, - 0xbb013d21, - 0x3fbb002f, - 0x041e5800, - 0x40051f58, - 0x0f400a0e, - 0x3d21f50c, - 0x030e9801, - 0xbb00effd, - 0x3ebb002e, - 0x0040b700, - 0x0235b613, - 0xb60043d0, - 0x35b60825, - 0x0120b606, - 0xb60130b6, - 0x34b60824, - 0x022fb908, - 0x026321f5, - 0xf1003fbb, - 0xb6080017, - 0x13d00614, - 0x0010b740, - 0xf024bd08, - 0x12d01f29, - 0x0031f400, - 0xf00028f4, - 0x21f41cd7, - 0xf401f439, - 0xf404e4b0, - 0x81fe1e18, - 0x0627f001, - 0x12fd20bd, - 0x01e4b604, - 0xfe051efd, - 0x21f50018, - 0x0ef404c3, - 0x10ef94d3, - 0xf501f5f0, - 0xf402ec21, - 0x80f9c60e, - 0xf90188fe, - 0xf990f980, - 0xf9b0f9a0, - 0xf9e0f9d0, - 0x800acff0, - 0xf404abc4, - 0xb7f11d0b, - 0xd7f01900, - 0x40becf1c, - 0xf400bfcf, - 0xb0b70421, - 0xe7f00400, - 0x00bed001, - 0xfc400ad0, - 0xfce0fcf0, - 0xfcb0fcd0, - 0xfc90fca0, - 0x0088fe80, - 0x32f480fc, - 0xf001f800, - 0x0e9801f7, - 0x04febb00, - 0x9418e7f1, - 0xf440e3f0, - 0x00f88d21, - 0x0614e7f1, - 0xf006e4b6, - 0xefd020f7, - 0x08f7f000, - 0xf401f2b6, - 0xf7f1fd1b, - 0xefd00a20, - 0xf100f800, - 0xb60a0417, - 0x1fd00614, - 0x0711f400, - 0x04a421f5, - 0x4afc17f1, - 0xf00213f0, - 0x12d00c27, - 0x0721f500, - 0xfc27f102, - 0x0223f047, - 0xf00020d0, - 0x20b6012c, - 0x0012d003, - 0xf001acf0, - 0xb7f002a5, - 0x50b3f000, - 0xb6000c98, - 0xbcbb0fc4, - 0x010c9800, - 0xf0020d98, - 0x21f500e7, - 0xacf0015c, - 0x04a5f001, - 0x4000b7f1, - 0x9850b3f0, - 0xc4b6000c, - 0x00bcbb0f, - 0x98050c98, - 0x0f98060d, - 0x00e7f104, - 0x5c21f508, - 0x0721f501, - 0x0601f402, - 0xf11412f4, - 0xf04afc17, - 0x27f00213, - 0x0012d00d, - 0x020721f5, - 0x048f21f5, - 0x000000f8, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc deleted file mode 100644 index 98acddb2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc +++ /dev/null @@ -1,856 +0,0 @@ -/* fuc microcode for nvc0 PGRAPH/HUB - * - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -/* To build: - * m4 nvc0_grhub.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_grhub.fuc.h - */ - -.section #nvc0_grhub_data -include(`nvc0_graph.fuc') -gpc_count: .b32 0 -rop_count: .b32 0 -cmd_queue: queue_init -hub_mmio_list_head: .b32 0 -hub_mmio_list_tail: .b32 0 - -ctx_current: .b32 0 - -chipsets: -.b8 0xc0 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc0_hub_mmio_tail -.b8 0xc1 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc1_hub_mmio_tail -.b8 0xc3 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc0_hub_mmio_tail -.b8 0xc4 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc0_hub_mmio_tail -.b8 0xc8 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc0_hub_mmio_tail -.b8 0xce 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc0_hub_mmio_tail -.b8 0xcf 0 0 0 -.b16 #nvc0_hub_mmio_head -.b16 #nvc0_hub_mmio_tail -.b8 0xd9 0 0 0 -.b16 #nvd9_hub_mmio_head -.b16 #nvd9_hub_mmio_tail -.b8 0 0 0 0 - -nvc0_hub_mmio_head: -mmctx_data(0x17e91c, 2) -mmctx_data(0x400204, 2) -mmctx_data(0x404004, 11) -mmctx_data(0x404044, 1) -mmctx_data(0x404094, 14) -mmctx_data(0x4040d0, 7) -mmctx_data(0x4040f8, 1) -mmctx_data(0x404130, 3) -mmctx_data(0x404150, 3) -mmctx_data(0x404164, 2) -mmctx_data(0x404174, 3) -mmctx_data(0x404200, 8) -mmctx_data(0x404404, 14) -mmctx_data(0x404460, 4) -mmctx_data(0x404480, 1) -mmctx_data(0x404498, 1) -mmctx_data(0x404604, 4) -mmctx_data(0x404618, 32) -mmctx_data(0x404698, 21) -mmctx_data(0x4046f0, 2) -mmctx_data(0x404700, 22) -mmctx_data(0x405800, 1) -mmctx_data(0x405830, 3) -mmctx_data(0x405854, 1) -mmctx_data(0x405870, 4) -mmctx_data(0x405a00, 2) -mmctx_data(0x405a18, 1) -mmctx_data(0x406020, 1) -mmctx_data(0x406028, 4) -mmctx_data(0x4064a8, 2) -mmctx_data(0x4064b4, 2) -mmctx_data(0x407804, 1) -mmctx_data(0x40780c, 6) -mmctx_data(0x4078bc, 1) -mmctx_data(0x408000, 7) -mmctx_data(0x408064, 1) -mmctx_data(0x408800, 3) -mmctx_data(0x408900, 4) -mmctx_data(0x408980, 1) -nvc0_hub_mmio_tail: -mmctx_data(0x4064c0, 2) -nvc1_hub_mmio_tail: - -nvd9_hub_mmio_head: -mmctx_data(0x17e91c, 2) -mmctx_data(0x400204, 2) -mmctx_data(0x404004, 10) -mmctx_data(0x404044, 1) -mmctx_data(0x404094, 14) -mmctx_data(0x4040d0, 7) -mmctx_data(0x4040f8, 1) -mmctx_data(0x404130, 3) -mmctx_data(0x404150, 3) -mmctx_data(0x404164, 2) -mmctx_data(0x404178, 2) -mmctx_data(0x404200, 8) -mmctx_data(0x404404, 14) -mmctx_data(0x404460, 4) -mmctx_data(0x404480, 1) -mmctx_data(0x404498, 1) -mmctx_data(0x404604, 4) -mmctx_data(0x404618, 32) -mmctx_data(0x404698, 21) -mmctx_data(0x4046f0, 2) -mmctx_data(0x404700, 22) -mmctx_data(0x405800, 1) -mmctx_data(0x405830, 3) -mmctx_data(0x405854, 1) -mmctx_data(0x405870, 4) -mmctx_data(0x405a00, 2) -mmctx_data(0x405a18, 1) -mmctx_data(0x406020, 1) -mmctx_data(0x406028, 4) -mmctx_data(0x4064a8, 2) -mmctx_data(0x4064b4, 5) -mmctx_data(0x407804, 1) -mmctx_data(0x40780c, 6) -mmctx_data(0x4078bc, 1) -mmctx_data(0x408000, 7) -mmctx_data(0x408064, 1) -mmctx_data(0x408800, 3) -mmctx_data(0x408900, 4) -mmctx_data(0x408980, 1) -nvd9_hub_mmio_tail: - -.align 256 -chan_data: -chan_mmio_count: .b32 0 -chan_mmio_address: .b32 0 - -.align 256 -xfer_data: .b32 0 - -.section #nvc0_grhub_code -bra #init -define(`include_code') -include(`nvc0_graph.fuc') - -// reports an exception to the host -// -// In: $r15 error code (see nvc0_graph.fuc) -// -error: - push $r14 - mov $r14 0x814 - shl b32 $r14 6 - iowr I[$r14 + 0x000] $r15 // CC_SCRATCH[5] = error code - mov $r14 0xc1c - shl b32 $r14 6 - mov $r15 1 - iowr I[$r14 + 0x000] $r15 // INTR_UP_SET - pop $r14 - ret - -// HUB fuc initialisation, executed by triggering ucode start, will -// fall through to main loop after completion. -// -// Input: -// CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh) -// -// Output: -// CC_SCRATCH[0]: -// 31:31: set to signal completion -// CC_SCRATCH[1]: -// 31:0: total PGRAPH context size -// -init: - clear b32 $r0 - mov $sp $r0 - mov $xdbase $r0 - - // enable fifo access - mov $r1 0x1200 - mov $r2 2 - iowr I[$r1 + 0x000] $r2 // FIFO_ENABLE - - // setup i0 handler, and route all interrupts to it - mov $r1 #ih - mov $iv0 $r1 - mov $r1 0x400 - iowr I[$r1 + 0x300] $r0 // INTR_DISPATCH - - // route HUB_CHANNEL_SWITCH to fuc interrupt 8 - mov $r3 0x404 - shl b32 $r3 6 - mov $r2 0x2003 // { HUB_CHANNEL_SWITCH, ZERO } -> intr 8 - iowr I[$r3 + 0x000] $r2 - - // not sure what these are, route them because NVIDIA does, and - // the IRQ handler will signal the host if we ever get one.. we - // may find out if/why we need to handle these if so.. - // - mov $r2 0x2004 - iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9 - mov $r2 0x200b - iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10 - mov $r2 0x200c - iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15 - - // enable all INTR_UP interrupts - mov $r2 0xc24 - shl b32 $r2 6 - not b32 $r3 $r0 - iowr I[$r2] $r3 - - // enable fifo, ctxsw, 9, 10, 15 interrupts - mov $r2 -0x78fc // 0x8704 - sethi $r2 0 - iowr I[$r1 + 0x000] $r2 // INTR_EN_SET - - // fifo level triggered, rest edge - sub b32 $r1 0x100 - mov $r2 4 - iowr I[$r1] $r2 - - // enable interrupts - bset $flags ie0 - - // fetch enabled GPC/ROP counts - mov $r14 -0x69fc // 0x409604 - sethi $r14 0x400000 - call #nv_rd32 - extr $r1 $r15 16:20 - st b32 D[$r0 + #rop_count] $r1 - and $r15 0x1f - st b32 D[$r0 + #gpc_count] $r15 - - // set BAR_REQMASK to GPC mask - mov $r1 1 - shl b32 $r1 $r15 - sub b32 $r1 1 - mov $r2 0x40c - shl b32 $r2 6 - iowr I[$r2 + 0x000] $r1 - iowr I[$r2 + 0x100] $r1 - - // find context data for this chipset - mov $r2 0x800 - shl b32 $r2 6 - iord $r2 I[$r2 + 0x000] // CC_SCRATCH[0] - mov $r15 #chipsets - 8 - init_find_chipset: - add b32 $r15 8 - ld b32 $r3 D[$r15 + 0x00] - cmpu b32 $r3 $r2 - bra e #init_context - cmpu b32 $r3 0 - bra ne #init_find_chipset - // unknown chipset - ret - - // context size calculation, reserve first 256 bytes for use by fuc - init_context: - mov $r1 256 - - // calculate size of mmio context data - ld b16 $r14 D[$r15 + 4] - ld b16 $r15 D[$r15 + 6] - sethi $r14 0 - st b32 D[$r0 + #hub_mmio_list_head] $r14 - st b32 D[$r0 + #hub_mmio_list_tail] $r15 - call #mmctx_size - - // set mmctx base addresses now so we don't have to do it later, - // they don't (currently) ever change - mov $r3 0x700 - shl b32 $r3 6 - shr b32 $r4 $r1 8 - iowr I[$r3 + 0x000] $r4 // MMCTX_SAVE_SWBASE - iowr I[$r3 + 0x100] $r4 // MMCTX_LOAD_SWBASE - add b32 $r3 0x1300 - add b32 $r1 $r15 - shr b32 $r15 2 - iowr I[$r3 + 0x000] $r15 // MMCTX_LOAD_COUNT, wtf for?!? - - // strands, base offset needs to be aligned to 256 bytes - shr b32 $r1 8 - add b32 $r1 1 - shl b32 $r1 8 - mov b32 $r15 $r1 - call #strand_ctx_init - add b32 $r1 $r15 - - // initialise each GPC in sequence by passing in the offset of its - // context data in GPCn_CC_SCRATCH[1], and starting its FUC (which - // has previously been uploaded by the host) running. - // - // the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31 - // when it has completed, and return the size of its context data - // in GPCn_CC_SCRATCH[1] - // - ld b32 $r3 D[$r0 + #gpc_count] - mov $r4 0x2000 - sethi $r4 0x500000 - init_gpc: - // setup, and start GPC ucode running - add b32 $r14 $r4 0x804 - mov b32 $r15 $r1 - call #nv_wr32 // CC_SCRATCH[1] = ctx offset - add b32 $r14 $r4 0x800 - mov b32 $r15 $r2 - call #nv_wr32 // CC_SCRATCH[0] = chipset - add b32 $r14 $r4 0x10c - clear b32 $r15 - call #nv_wr32 - add b32 $r14 $r4 0x104 - call #nv_wr32 // ENTRY - add b32 $r14 $r4 0x100 - mov $r15 2 // CTRL_START_TRIGGER - call #nv_wr32 // CTRL - - // wait for it to complete, and adjust context size - add b32 $r14 $r4 0x800 - init_gpc_wait: - call #nv_rd32 - xbit $r15 $r15 31 - bra e #init_gpc_wait - add b32 $r14 $r4 0x804 - call #nv_rd32 - add b32 $r1 $r15 - - // next! - add b32 $r4 0x8000 - sub b32 $r3 1 - bra ne #init_gpc - - // save context size, and tell host we're ready - mov $r2 0x800 - shl b32 $r2 6 - iowr I[$r2 + 0x100] $r1 // CC_SCRATCH[1] = context size - add b32 $r2 0x800 - clear b32 $r1 - bset $r1 31 - iowr I[$r2 + 0x000] $r1 // CC_SCRATCH[0] |= 0x80000000 - -// Main program loop, very simple, sleeps until woken up by the interrupt -// handler, pulls a command from the queue and executes its handler -// -main: - // sleep until we have something to do - bset $flags $p0 - sleep $p0 - mov $r13 #cmd_queue - call #queue_get - bra $p1 #main - - // context switch, requested by GPU? - cmpu b32 $r14 0x4001 - bra ne #main_not_ctx_switch - trace_set(T_AUTO) - mov $r1 0xb00 - shl b32 $r1 6 - iord $r2 I[$r1 + 0x100] // CHAN_NEXT - iord $r1 I[$r1 + 0x000] // CHAN_CUR - - xbit $r3 $r1 31 - bra e #chsw_no_prev - xbit $r3 $r2 31 - bra e #chsw_prev_no_next - push $r2 - mov b32 $r2 $r1 - trace_set(T_SAVE) - bclr $flags $p1 - bset $flags $p2 - call #ctx_xfer - trace_clr(T_SAVE); - pop $r2 - trace_set(T_LOAD); - bset $flags $p1 - call #ctx_xfer - trace_clr(T_LOAD); - bra #chsw_done - chsw_prev_no_next: - push $r2 - mov b32 $r2 $r1 - bclr $flags $p1 - bclr $flags $p2 - call #ctx_xfer - pop $r2 - mov $r1 0xb00 - shl b32 $r1 6 - iowr I[$r1] $r2 - bra #chsw_done - chsw_no_prev: - xbit $r3 $r2 31 - bra e #chsw_done - bset $flags $p1 - bclr $flags $p2 - call #ctx_xfer - - // ack the context switch request - chsw_done: - mov $r1 0xb0c - shl b32 $r1 6 - mov $r2 1 - iowr I[$r1 + 0x000] $r2 // 0x409b0c - trace_clr(T_AUTO) - bra #main - - // request to set current channel? (*not* a context switch) - main_not_ctx_switch: - cmpu b32 $r14 0x0001 - bra ne #main_not_ctx_chan - mov b32 $r2 $r15 - call #ctx_chan - bra #main_done - - // request to store current channel context? - main_not_ctx_chan: - cmpu b32 $r14 0x0002 - bra ne #main_not_ctx_save - trace_set(T_SAVE) - bclr $flags $p1 - bclr $flags $p2 - call #ctx_xfer - trace_clr(T_SAVE) - bra #main_done - - main_not_ctx_save: - shl b32 $r15 $r14 16 - or $r15 E_BAD_COMMAND - call #error - bra #main - - main_done: - mov $r1 0x820 - shl b32 $r1 6 - clear b32 $r2 - bset $r2 31 - iowr I[$r1 + 0x000] $r2 // CC_SCRATCH[0] |= 0x80000000 - bra #main - -// interrupt handler -ih: - push $r8 - mov $r8 $flags - push $r8 - push $r9 - push $r10 - push $r11 - push $r13 - push $r14 - push $r15 - - // incoming fifo command? - iord $r10 I[$r0 + 0x200] // INTR - and $r11 $r10 0x00000004 - bra e #ih_no_fifo - // queue incoming fifo command for later processing - mov $r11 0x1900 - mov $r13 #cmd_queue - iord $r14 I[$r11 + 0x100] // FIFO_CMD - iord $r15 I[$r11 + 0x000] // FIFO_DATA - call #queue_put - add b32 $r11 0x400 - mov $r14 1 - iowr I[$r11 + 0x000] $r14 // FIFO_ACK - - // context switch request? - ih_no_fifo: - and $r11 $r10 0x00000100 - bra e #ih_no_ctxsw - // enqueue a context switch for later processing - mov $r13 #cmd_queue - mov $r14 0x4001 - call #queue_put - - // anything we didn't handle, bring it to the host's attention - ih_no_ctxsw: - mov $r11 0x104 - not b32 $r11 - and $r11 $r10 $r11 - bra e #ih_no_other - mov $r10 0xc1c - shl b32 $r10 6 - iowr I[$r10] $r11 // INTR_UP_SET - - // ack, and wake up main() - ih_no_other: - iowr I[$r0 + 0x100] $r10 // INTR_ACK - - pop $r15 - pop $r14 - pop $r13 - pop $r11 - pop $r10 - pop $r9 - pop $r8 - mov $flags $r8 - pop $r8 - bclr $flags $p0 - iret - -// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done -ctx_4160s: - mov $r14 0x4160 - sethi $r14 0x400000 - mov $r15 1 - call #nv_wr32 - ctx_4160s_wait: - call #nv_rd32 - xbit $r15 $r15 4 - bra e #ctx_4160s_wait - ret - -// Without clearing again at end of xfer, some things cause PGRAPH -// to hang with STATUS=0x00000007 until it's cleared.. fbcon can -// still function with it set however... -ctx_4160c: - mov $r14 0x4160 - sethi $r14 0x400000 - clear b32 $r15 - call #nv_wr32 - ret - -// Again, not real sure -// -// In: $r15 value to set 0x404170 to -// -ctx_4170s: - mov $r14 0x4170 - sethi $r14 0x400000 - or $r15 0x10 - call #nv_wr32 - ret - -// Waits for a ctx_4170s() call to complete -// -ctx_4170w: - mov $r14 0x4170 - sethi $r14 0x400000 - call #nv_rd32 - and $r15 0x10 - bra ne #ctx_4170w - ret - -// Disables various things, waits a bit, and re-enables them.. -// -// Not sure how exactly this helps, perhaps "ENABLE" is not such a -// good description for the bits we turn off? Anyways, without this, -// funny things happen. -// -ctx_redswitch: - mov $r14 0x614 - shl b32 $r14 6 - mov $r15 0x270 - iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL - mov $r15 8 - ctx_redswitch_delay: - sub b32 $r15 1 - bra ne #ctx_redswitch_delay - mov $r15 0x770 - iowr I[$r14] $r15 // HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL - ret - -// Not a clue what this is for, except that unless the value is 0x10, the -// strand context is saved (and presumably restored) incorrectly.. -// -// In: $r15 value to set to (0x00/0x10 are used) -// -ctx_86c: - mov $r14 0x86c - shl b32 $r14 6 - iowr I[$r14] $r15 // HUB(0x86c) = val - mov $r14 -0x75ec - sethi $r14 0x400000 - call #nv_wr32 // ROP(0xa14) = val - mov $r14 -0x5794 - sethi $r14 0x410000 - call #nv_wr32 // GPC(0x86c) = val - ret - -// ctx_load - load's a channel's ctxctl data, and selects its vm -// -// In: $r2 channel address -// -ctx_load: - trace_set(T_CHAN) - - // switch to channel, somewhat magic in parts.. - mov $r10 12 // DONE_UNK12 - call #wait_donez - mov $r1 0xa24 - shl b32 $r1 6 - iowr I[$r1 + 0x000] $r0 // 0x409a24 - mov $r3 0xb00 - shl b32 $r3 6 - iowr I[$r3 + 0x100] $r2 // CHAN_NEXT - mov $r1 0xa0c - shl b32 $r1 6 - mov $r4 7 - iowr I[$r1 + 0x000] $r2 // MEM_CHAN - iowr I[$r1 + 0x100] $r4 // MEM_CMD - ctx_chan_wait_0: - iord $r4 I[$r1 + 0x100] - and $r4 0x1f - bra ne #ctx_chan_wait_0 - iowr I[$r3 + 0x000] $r2 // CHAN_CUR - - // load channel header, fetch PGRAPH context pointer - mov $xtargets $r0 - bclr $r2 31 - shl b32 $r2 4 - add b32 $r2 2 - - trace_set(T_LCHAN) - mov $r1 0xa04 - shl b32 $r1 6 - iowr I[$r1 + 0x000] $r2 // MEM_BASE - mov $r1 0xa20 - shl b32 $r1 6 - mov $r2 0x0002 - sethi $r2 0x80000000 - iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vram - mov $r1 0x10 // chan + 0x0210 - mov $r2 #xfer_data - sethi $r2 0x00020000 // 16 bytes - xdld $r1 $r2 - xdwait - trace_clr(T_LCHAN) - - // update current context - ld b32 $r1 D[$r0 + #xfer_data + 4] - shl b32 $r1 24 - ld b32 $r2 D[$r0 + #xfer_data + 0] - shr b32 $r2 8 - or $r1 $r2 - st b32 D[$r0 + #ctx_current] $r1 - - // set transfer base to start of context, and fetch context header - trace_set(T_LCTXH) - mov $r2 0xa04 - shl b32 $r2 6 - iowr I[$r2 + 0x000] $r1 // MEM_BASE - mov $r2 1 - mov $r1 0xa20 - shl b32 $r1 6 - iowr I[$r1 + 0x000] $r2 // MEM_TARGET = vm - mov $r1 #chan_data - sethi $r1 0x00060000 // 256 bytes - xdld $r0 $r1 - xdwait - trace_clr(T_LCTXH) - - trace_clr(T_CHAN) - ret - -// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as -// the active channel for ctxctl, but not actually transfer -// any context data. intended for use only during initial -// context construction. -// -// In: $r2 channel address -// -ctx_chan: - call #ctx_4160s - call #ctx_load - mov $r10 12 // DONE_UNK12 - call #wait_donez - mov $r1 0xa10 - shl b32 $r1 6 - mov $r2 5 - iowr I[$r1 + 0x000] $r2 // MEM_CMD = 5 (???) - ctx_chan_wait: - iord $r2 I[$r1 + 0x000] - or $r2 $r2 - bra ne #ctx_chan_wait - call #ctx_4160c - ret - -// Execute per-context state overrides list -// -// Only executed on the first load of a channel. Might want to look into -// removing this and having the host directly modify the channel's context -// to change this state... The nouveau DRM already builds this list as -// it's definitely needed for NVIDIA's, so we may as well use it for now -// -// Input: $r1 mmio list length -// -ctx_mmio_exec: - // set transfer base to be the mmio list - ld b32 $r3 D[$r0 + #chan_mmio_address] - mov $r2 0xa04 - shl b32 $r2 6 - iowr I[$r2 + 0x000] $r3 // MEM_BASE - - clear b32 $r3 - ctx_mmio_loop: - // fetch next 256 bytes of mmio list if necessary - and $r4 $r3 0xff - bra ne #ctx_mmio_pull - mov $r5 #xfer_data - sethi $r5 0x00060000 // 256 bytes - xdld $r3 $r5 - xdwait - - // execute a single list entry - ctx_mmio_pull: - ld b32 $r14 D[$r4 + #xfer_data + 0x00] - ld b32 $r15 D[$r4 + #xfer_data + 0x04] - call #nv_wr32 - - // next! - add b32 $r3 8 - sub b32 $r1 1 - bra ne #ctx_mmio_loop - - // set transfer base back to the current context - ctx_mmio_done: - ld b32 $r3 D[$r0 + #ctx_current] - iowr I[$r2 + 0x000] $r3 // MEM_BASE - - // disable the mmio list now, we don't need/want to execute it again - st b32 D[$r0 + #chan_mmio_count] $r0 - mov $r1 #chan_data - sethi $r1 0x00060000 // 256 bytes - xdst $r0 $r1 - xdwait - ret - -// Transfer HUB context data between GPU and storage area -// -// In: $r2 channel address -// $p1 clear on save, set on load -// $p2 set if opposite direction done/will be done, so: -// on save it means: "a load will follow this save" -// on load it means: "a save preceeded this load" -// -ctx_xfer: - bra not $p1 #ctx_xfer_pre - bra $p2 #ctx_xfer_pre_load - ctx_xfer_pre: - mov $r15 0x10 - call #ctx_86c - call #ctx_4160s - bra not $p1 #ctx_xfer_exec - - ctx_xfer_pre_load: - mov $r15 2 - call #ctx_4170s - call #ctx_4170w - call #ctx_redswitch - clear b32 $r15 - call #ctx_4170s - call #ctx_load - - // fetch context pointer, and initiate xfer on all GPCs - ctx_xfer_exec: - ld b32 $r1 D[$r0 + #ctx_current] - mov $r2 0x414 - shl b32 $r2 6 - iowr I[$r2 + 0x000] $r0 // BAR_STATUS = reset - mov $r14 -0x5b00 - sethi $r14 0x410000 - mov b32 $r15 $r1 - call #nv_wr32 // GPC_BCAST_WRCMD_DATA = ctx pointer - add b32 $r14 4 - xbit $r15 $flags $p1 - xbit $r2 $flags $p2 - shl b32 $r2 1 - or $r15 $r2 - call #nv_wr32 // GPC_BCAST_WRCMD_CMD = GPC_XFER(type) - - // strands - mov $r1 0x4afc - sethi $r1 0x20000 - mov $r2 0xc - iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x0c - call #strand_wait - mov $r2 0x47fc - sethi $r2 0x20000 - iowr I[$r2] $r0 // STRAND_FIRST_GENE(0x3f) = 0x00 - xbit $r2 $flags $p1 - add b32 $r2 3 - iowr I[$r1] $r2 // STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD) - - // mmio context - xbit $r10 $flags $p1 // direction - or $r10 6 // first, last - mov $r11 0 // base = 0 - ld b32 $r12 D[$r0 + #hub_mmio_list_head] - ld b32 $r13 D[$r0 + #hub_mmio_list_tail] - mov $r14 0 // not multi - call #mmctx_xfer - - // wait for GPCs to all complete - mov $r10 8 // DONE_BAR - call #wait_doneo - - // wait for strand xfer to complete - call #strand_wait - - // post-op - bra $p1 #ctx_xfer_post - mov $r10 12 // DONE_UNK12 - call #wait_donez - mov $r1 0xa10 - shl b32 $r1 6 - mov $r2 5 - iowr I[$r1] $r2 // MEM_CMD - ctx_xfer_post_save_wait: - iord $r2 I[$r1] - or $r2 $r2 - bra ne #ctx_xfer_post_save_wait - - bra $p2 #ctx_xfer_done - ctx_xfer_post: - mov $r15 2 - call #ctx_4170s - clear b32 $r15 - call #ctx_86c - call #strand_post - call #ctx_4170w - clear b32 $r15 - call #ctx_4170s - - bra not $p1 #ctx_xfer_no_post_mmio - ld b32 $r1 D[$r0 + #chan_mmio_count] - or $r1 $r1 - bra e #ctx_xfer_no_post_mmio - call #ctx_mmio_exec - - ctx_xfer_no_post_mmio: - call #ctx_4160c - - ctx_xfer_done: - ret - -.align 256 diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h deleted file mode 100644 index c5ed307a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_grhub.fuc.h +++ /dev/null @@ -1,838 +0,0 @@ -uint32_t nvc0_grhub_data[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x000000c0, - 0x013c00a0, - 0x000000c1, - 0x014000a0, - 0x000000c3, - 0x013c00a0, - 0x000000c4, - 0x013c00a0, - 0x000000c8, - 0x013c00a0, - 0x000000ce, - 0x013c00a0, - 0x000000cf, - 0x013c00a0, - 0x000000d9, - 0x01dc0140, - 0x00000000, - 0x0417e91c, - 0x04400204, - 0x28404004, - 0x00404044, - 0x34404094, - 0x184040d0, - 0x004040f8, - 0x08404130, - 0x08404150, - 0x04404164, - 0x08404174, - 0x1c404200, - 0x34404404, - 0x0c404460, - 0x00404480, - 0x00404498, - 0x0c404604, - 0x7c404618, - 0x50404698, - 0x044046f0, - 0x54404700, - 0x00405800, - 0x08405830, - 0x00405854, - 0x0c405870, - 0x04405a00, - 0x00405a18, - 0x00406020, - 0x0c406028, - 0x044064a8, - 0x044064b4, - 0x00407804, - 0x1440780c, - 0x004078bc, - 0x18408000, - 0x00408064, - 0x08408800, - 0x0c408900, - 0x00408980, - 0x044064c0, - 0x0417e91c, - 0x04400204, - 0x24404004, - 0x00404044, - 0x34404094, - 0x184040d0, - 0x004040f8, - 0x08404130, - 0x08404150, - 0x04404164, - 0x04404178, - 0x1c404200, - 0x34404404, - 0x0c404460, - 0x00404480, - 0x00404498, - 0x0c404604, - 0x7c404618, - 0x50404698, - 0x044046f0, - 0x54404700, - 0x00405800, - 0x08405830, - 0x00405854, - 0x0c405870, - 0x04405a00, - 0x00405a18, - 0x00406020, - 0x0c406028, - 0x044064a8, - 0x104064b4, - 0x00407804, - 0x1440780c, - 0x004078bc, - 0x18408000, - 0x00408064, - 0x08408800, - 0x0c408900, - 0x00408980, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -uint32_t nvc0_grhub_code[] = { - 0x03090ef5, - 0x9800d898, - 0x86f001d9, - 0x0489b808, - 0xf00c1bf4, - 0x21f502f7, - 0x00f802ec, - 0xb60798c4, - 0x8dbb0384, - 0x0880b600, - 0x80008e80, - 0x90b6018f, - 0x0f94f001, - 0xf801d980, - 0x0131f400, - 0x9800d898, - 0x89b801d9, - 0x210bf404, - 0xb60789c4, - 0x9dbb0394, - 0x0890b600, - 0x98009e98, - 0x80b6019f, - 0x0f84f001, - 0xf400d880, - 0x00f80132, - 0x0728b7f1, - 0xb906b4b6, - 0xc9f002ec, - 0x00bcd01f, - 0xc800bccf, - 0x1bf41fcc, - 0x06a7f0fa, - 0x010321f5, - 0xf840bfcf, - 0x28b7f100, - 0x06b4b607, - 0xb980bfd0, - 0xc9f002ec, - 0x1ec9f01f, - 0xcf00bcd0, - 0xccc800bc, - 0xfa1bf41f, - 0x87f100f8, - 0x84b60430, - 0x1ff9f006, - 0xf8008fd0, - 0x3087f100, - 0x0684b604, - 0xf80080d0, - 0x3c87f100, - 0x0684b608, - 0x99f094bd, - 0x0089d000, - 0x081887f1, - 0xd00684b6, - 0x87f1008a, - 0x84b60400, - 0x0088cf06, - 0xf4888aff, - 0x87f1f31b, - 0x84b6085c, - 0xf094bd06, - 0x89d00099, - 0xf100f800, - 0xb6083c87, - 0x94bd0684, - 0xd00099f0, - 0x87f10089, - 0x84b60818, - 0x008ad006, - 0x040087f1, - 0xcf0684b6, - 0x8aff0088, - 0xf30bf488, - 0x085c87f1, - 0xbd0684b6, - 0x0099f094, - 0xf80089d0, - 0x9894bd00, - 0x85b600e8, - 0x0180b61a, - 0xbb0284b6, - 0xe0b60098, - 0x04efb804, - 0xb9eb1bf4, - 0x00f8029f, - 0x083c87f1, - 0xbd0684b6, - 0x0199f094, - 0xf10089d0, - 0xb6071087, - 0x94bd0684, - 0xf405bbfd, - 0x8bd0090b, - 0x0099f000, - 0xf405eefd, - 0x8ed00c0b, - 0xc08fd080, - 0xb70199f0, - 0xc8010080, - 0xb4b600ab, - 0x0cb9f010, - 0xb601aec8, - 0xbefd11e4, - 0x008bd005, - 0xf0008ecf, - 0x0bf41fe4, - 0x00ce98fa, - 0xd005e9fd, - 0xc0b6c08e, - 0x04cdb804, - 0xc8e81bf4, - 0x1bf402ab, - 0x008bcf18, - 0xb01fb4f0, - 0x1bf410b4, - 0x02a7f0f7, - 0xf4c921f4, - 0xabc81b0e, - 0x10b4b600, - 0xf00cb9f0, - 0x8bd012b9, - 0x008bcf00, - 0xf412bbc8, - 0x87f1fa1b, - 0x84b6085c, - 0xf094bd06, - 0x89d00199, - 0xf900f800, - 0x02a7f0a0, - 0xfcc921f4, - 0xf100f8a0, - 0xf04afc87, - 0x97f00283, - 0x0089d00c, - 0x020721f5, - 0x87f100f8, - 0x83f04afc, - 0x0d97f002, - 0xf50089d0, - 0xf8020721, - 0xfca7f100, - 0x02a3f04f, - 0x0500aba2, - 0xd00fc7f0, - 0xc7f000ac, - 0x00bcd00b, - 0x020721f5, - 0xf000aed0, - 0xbcd00ac7, - 0x0721f500, - 0xf100f802, - 0xb6083c87, - 0x94bd0684, - 0xd00399f0, - 0x21f50089, - 0xe7f00213, - 0x3921f503, - 0xfca7f102, - 0x02a3f046, - 0x0400aba0, - 0xf040a0d0, - 0xbcd001c7, - 0x0721f500, - 0x010c9202, - 0xf000acd0, - 0xbcd002c7, - 0x0721f500, - 0x2621f502, - 0x8087f102, - 0x0684b608, - 0xb70089cf, - 0x95220080, - 0x8ed008fe, - 0x408ed000, - 0xb6808acf, - 0xa0b606a5, - 0x00eabb01, - 0xb60480b6, - 0x1bf40192, - 0x08e4b6e8, - 0xf1f2efbc, - 0xb6085c87, - 0x94bd0684, - 0xd00399f0, - 0x00f80089, - 0xe7f1e0f9, - 0xe4b60814, - 0x00efd006, - 0x0c1ce7f1, - 0xf006e4b6, - 0xefd001f7, - 0xf8e0fc00, - 0xfe04bd00, - 0x07fe0004, - 0x0017f100, - 0x0227f012, - 0xf10012d0, - 0xfe05b917, - 0x17f10010, - 0x10d00400, - 0x0437f1c0, - 0x0634b604, - 0x200327f1, - 0xf10032d0, - 0xd0200427, - 0x27f10132, - 0x32d0200b, - 0x0c27f102, - 0x0732d020, - 0x0c2427f1, - 0xb90624b6, - 0x23d00003, - 0x0427f100, - 0x0023f087, - 0xb70012d0, - 0xf0010012, - 0x12d00427, - 0x1031f400, - 0x9604e7f1, - 0xf440e3f0, - 0xf1c76821, - 0x01018090, - 0x801ff4f0, - 0x17f0000f, - 0x041fbb01, - 0xf10112b6, - 0xb6040c27, - 0x21d00624, - 0x4021d000, - 0x080027f1, - 0xcf0624b6, - 0xf7f00022, - 0x08f0b654, - 0xb800f398, - 0x0bf40432, - 0x0034b00b, - 0xf8f11bf4, - 0x0017f100, - 0x02fe5801, - 0xf003ff58, - 0x0e8000e3, - 0x150f8014, - 0x013d21f5, - 0x070037f1, - 0x950634b6, - 0x34d00814, - 0x4034d000, - 0x130030b7, - 0xb6001fbb, - 0x3fd002f5, - 0x0815b600, - 0xb60110b6, - 0x1fb90814, - 0x6321f502, - 0x001fbb02, - 0xf1000398, - 0xf0200047, - 0x4ea05043, - 0x1fb90804, - 0x8d21f402, - 0x08004ea0, - 0xf4022fb9, - 0x4ea08d21, - 0xf4bd010c, - 0xa08d21f4, - 0xf401044e, - 0x4ea08d21, - 0xf7f00100, - 0x8d21f402, - 0x08004ea0, - 0xc86821f4, - 0x0bf41fff, - 0x044ea0fa, - 0x6821f408, - 0xb7001fbb, - 0xb6800040, - 0x1bf40132, - 0x0027f1b4, - 0x0624b608, - 0xb74021d0, - 0xbd080020, - 0x1f19f014, - 0xf40021d0, - 0x28f40031, - 0x08d7f000, - 0xf43921f4, - 0xe4b1f401, - 0x1bf54001, - 0x87f100d1, - 0x84b6083c, - 0xf094bd06, - 0x89d00499, - 0x0017f100, - 0x0614b60b, - 0xcf4012cf, - 0x13c80011, - 0x7e0bf41f, - 0xf41f23c8, - 0x20f95a0b, - 0xf10212b9, - 0xb6083c87, - 0x94bd0684, - 0xd00799f0, - 0x32f40089, - 0x0231f401, - 0x082921f5, - 0x085c87f1, - 0xbd0684b6, - 0x0799f094, - 0xfc0089d0, - 0x3c87f120, - 0x0684b608, - 0x99f094bd, - 0x0089d006, - 0xf50131f4, - 0xf1082921, - 0xb6085c87, - 0x94bd0684, - 0xd00699f0, - 0x0ef40089, - 0xb920f931, - 0x32f40212, - 0x0232f401, - 0x082921f5, - 0x17f120fc, - 0x14b60b00, - 0x0012d006, - 0xc8130ef4, - 0x0bf41f23, - 0x0131f40d, - 0xf50232f4, - 0xf1082921, - 0xb60b0c17, - 0x27f00614, - 0x0012d001, - 0x085c87f1, - 0xbd0684b6, - 0x0499f094, - 0xf50089d0, - 0xb0ff200e, - 0x1bf401e4, - 0x02f2b90d, - 0x07b521f5, - 0xb0420ef4, - 0x1bf402e4, - 0x3c87f12e, - 0x0684b608, - 0x99f094bd, - 0x0089d007, - 0xf40132f4, - 0x21f50232, - 0x87f10829, - 0x84b6085c, - 0xf094bd06, - 0x89d00799, - 0x110ef400, - 0xf010ef94, - 0x21f501f5, - 0x0ef502ec, - 0x17f1fed1, - 0x14b60820, - 0xf024bd06, - 0x12d01f29, - 0xbe0ef500, - 0xfe80f9fe, - 0x80f90188, - 0xa0f990f9, - 0xd0f9b0f9, - 0xf0f9e0f9, - 0xc4800acf, - 0x0bf404ab, - 0x00b7f11d, - 0x08d7f019, - 0xcf40becf, - 0x21f400bf, - 0x00b0b704, - 0x01e7f004, - 0xe400bed0, - 0xf40100ab, - 0xd7f00d0b, - 0x01e7f108, - 0x0421f440, - 0x0104b7f1, - 0xabffb0bd, - 0x0d0bf4b4, - 0x0c1ca7f1, - 0xd006a4b6, - 0x0ad000ab, - 0xfcf0fc40, - 0xfcd0fce0, - 0xfca0fcb0, - 0xfe80fc90, - 0x80fc0088, - 0xf80032f4, - 0x60e7f101, - 0x40e3f041, - 0xf401f7f0, - 0x21f48d21, - 0x04ffc868, - 0xf8fa0bf4, - 0x60e7f100, - 0x40e3f041, - 0x21f4f4bd, - 0xf100f88d, - 0xf04170e7, - 0xf5f040e3, - 0x8d21f410, - 0xe7f100f8, - 0xe3f04170, - 0x6821f440, - 0xf410f4f0, - 0x00f8f31b, - 0x0614e7f1, - 0xf106e4b6, - 0xd00270f7, - 0xf7f000ef, - 0x01f2b608, - 0xf1fd1bf4, - 0xd00770f7, - 0x00f800ef, - 0x086ce7f1, - 0xd006e4b6, - 0xe7f100ef, - 0xe3f08a14, - 0x8d21f440, - 0xa86ce7f1, - 0xf441e3f0, - 0x00f88d21, - 0x083c87f1, - 0xbd0684b6, - 0x0599f094, - 0xf00089d0, - 0x21f40ca7, - 0x2417f1c9, - 0x0614b60a, - 0xf10010d0, - 0xb60b0037, - 0x32d00634, - 0x0c17f140, - 0x0614b60a, - 0xd00747f0, - 0x14d00012, - 0x4014cf40, - 0xf41f44f0, - 0x32d0fa1b, - 0x000bfe00, - 0xb61f2af0, - 0x20b60424, - 0x3c87f102, - 0x0684b608, - 0x99f094bd, - 0x0089d008, - 0x0a0417f1, - 0xd00614b6, - 0x17f10012, - 0x14b60a20, - 0x0227f006, - 0x800023f1, - 0xf00012d0, - 0x27f11017, - 0x23f00300, - 0x0512fa02, - 0x87f103f8, - 0x84b6085c, - 0xf094bd06, - 0x89d00899, - 0xc1019800, - 0x981814b6, - 0x25b6c002, - 0x0512fd08, - 0xf1160180, - 0xb6083c87, - 0x94bd0684, - 0xd00999f0, - 0x27f10089, - 0x24b60a04, - 0x0021d006, - 0xf10127f0, - 0xb60a2017, - 0x12d00614, - 0x0017f100, - 0x0613f002, - 0xf80501fa, - 0x5c87f103, - 0x0684b608, - 0x99f094bd, - 0x0089d009, - 0x085c87f1, - 0xbd0684b6, - 0x0599f094, - 0xf80089d0, - 0x3121f500, - 0xb821f506, - 0x0ca7f006, - 0xf1c921f4, - 0xb60a1017, - 0x27f00614, - 0x0012d005, - 0xfd0012cf, - 0x1bf40522, - 0x4921f5fa, - 0x9800f806, - 0x27f18103, - 0x24b60a04, - 0x0023d006, - 0x34c434bd, - 0x0f1bf4ff, - 0x030057f1, - 0xfa0653f0, - 0x03f80535, - 0x98c04e98, - 0x21f4c14f, - 0x0830b68d, - 0xf40112b6, - 0x0398df1b, - 0x0023d016, - 0xf1800080, - 0xf0020017, - 0x01fa0613, - 0xf803f806, - 0x0611f400, - 0xf01102f4, - 0x21f510f7, - 0x21f50698, - 0x11f40631, - 0x02f7f01c, - 0x065721f5, - 0x066621f5, - 0x067821f5, - 0x21f5f4bd, - 0x21f50657, - 0x019806b8, - 0x1427f116, - 0x0624b604, - 0xf10020d0, - 0xf0a500e7, - 0x1fb941e3, - 0x8d21f402, - 0xf004e0b6, - 0x2cf001fc, - 0x0124b602, - 0xf405f2fd, - 0x17f18d21, - 0x13f04afc, - 0x0c27f002, - 0xf50012d0, - 0xf1020721, - 0xf047fc27, - 0x20d00223, - 0x012cf000, - 0xd00320b6, - 0xacf00012, - 0x06a5f001, - 0x9800b7f0, - 0x0d98140c, - 0x00e7f015, - 0x015c21f5, - 0xf508a7f0, - 0xf5010321, - 0xf4020721, - 0xa7f02201, - 0xc921f40c, - 0x0a1017f1, - 0xf00614b6, - 0x12d00527, - 0x0012cf00, - 0xf40522fd, - 0x02f4fa1b, - 0x02f7f032, - 0x065721f5, - 0x21f5f4bd, - 0x21f50698, - 0x21f50226, - 0xf4bd0666, - 0x065721f5, - 0x981011f4, - 0x11fd8001, - 0x070bf405, - 0x07df21f5, - 0x064921f5, - 0x000000f8, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_instmem.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_instmem.c deleted file mode 100644 index b701c439..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_vm.h" - -struct nvc0_instmem_priv { - struct nouveau_gpuobj *bar1_pgd; - struct nouveau_channel *bar1; - struct nouveau_gpuobj *bar3_pgd; - struct nouveau_channel *bar3; -}; - -int -nvc0_instmem_suspend(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - dev_priv->ramin_available = false; - return 0; -} - -void -nvc0_instmem_resume(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_instmem_priv *priv = dev_priv->engine.instmem.priv; - - nv_mask(dev, 0x100c80, 0x00000001, 0x00000000); - nv_wr32(dev, 0x001704, 0x80000000 | priv->bar1->ramin->vinst >> 12); - nv_wr32(dev, 0x001714, 0xc0000000 | priv->bar3->ramin->vinst >> 12); - dev_priv->ramin_available = true; -} - -static void -nvc0_channel_del(struct nouveau_channel **pchan) -{ - struct nouveau_channel *chan; - - chan = *pchan; - *pchan = NULL; - if (!chan) - return; - - nouveau_vm_ref(NULL, &chan->vm, NULL); - if (drm_mm_initialized(&chan->ramin_heap)) - drm_mm_takedown(&chan->ramin_heap); - nouveau_gpuobj_ref(NULL, &chan->ramin); - kfree(chan); -} - -static int -nvc0_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm, - struct nouveau_channel **pchan, - struct nouveau_gpuobj *pgd, u64 vm_size) -{ - struct nouveau_channel *chan; - int ret; - - chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) - return -ENOMEM; - chan->dev = dev; - - ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin); - if (ret) { - nvc0_channel_del(&chan); - return ret; - } - - ret = drm_mm_init(&chan->ramin_heap, 0x1000, size - 0x1000); - if (ret) { - nvc0_channel_del(&chan); - return ret; - } - - ret = nouveau_vm_ref(vm, &chan->vm, NULL); - if (ret) { - nvc0_channel_del(&chan); - return ret; - } - - nv_wo32(chan->ramin, 0x0200, lower_32_bits(pgd->vinst)); - nv_wo32(chan->ramin, 0x0204, upper_32_bits(pgd->vinst)); - nv_wo32(chan->ramin, 0x0208, lower_32_bits(vm_size - 1)); - nv_wo32(chan->ramin, 0x020c, upper_32_bits(vm_size - 1)); - - *pchan = chan; - return 0; -} - -int -nvc0_instmem_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct pci_dev *pdev = dev->pdev; - struct nvc0_instmem_priv *priv; - struct nouveau_vm *vm = NULL; - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - pinstmem->priv = priv; - - /* BAR3 VM */ - ret = nouveau_vm_new(dev, 0, pci_resource_len(pdev, 3), 0, - &dev_priv->bar3_vm); - if (ret) - goto error; - - ret = nouveau_gpuobj_new(dev, NULL, - (pci_resource_len(pdev, 3) >> 12) * 8, 0, - NVOBJ_FLAG_DONT_MAP | - NVOBJ_FLAG_ZERO_ALLOC, - &dev_priv->bar3_vm->pgt[0].obj[0]); - if (ret) - goto error; - dev_priv->bar3_vm->pgt[0].refcount[0] = 1; - - nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]); - - ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096, - NVOBJ_FLAG_ZERO_ALLOC, &priv->bar3_pgd); - if (ret) - goto error; - - ret = nouveau_vm_ref(dev_priv->bar3_vm, &vm, priv->bar3_pgd); - if (ret) - goto error; - nouveau_vm_ref(NULL, &vm, NULL); - - ret = nvc0_channel_new(dev, 8192, dev_priv->bar3_vm, &priv->bar3, - priv->bar3_pgd, pci_resource_len(dev->pdev, 3)); - if (ret) - goto error; - - /* BAR1 VM */ - ret = nouveau_vm_new(dev, 0, pci_resource_len(pdev, 1), 0, &vm); - if (ret) - goto error; - - ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096, - NVOBJ_FLAG_ZERO_ALLOC, &priv->bar1_pgd); - if (ret) - goto error; - - ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, priv->bar1_pgd); - if (ret) - goto error; - nouveau_vm_ref(NULL, &vm, NULL); - - ret = nvc0_channel_new(dev, 8192, dev_priv->bar1_vm, &priv->bar1, - priv->bar1_pgd, pci_resource_len(dev->pdev, 1)); - if (ret) - goto error; - - /* channel vm */ - ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL, - &dev_priv->chan_vm); - if (ret) - goto error; - - nvc0_instmem_resume(dev); - return 0; -error: - nvc0_instmem_takedown(dev); - return ret; -} - -void -nvc0_instmem_takedown(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_instmem_priv *priv = dev_priv->engine.instmem.priv; - struct nouveau_vm *vm = NULL; - - nvc0_instmem_suspend(dev); - - nv_wr32(dev, 0x1704, 0x00000000); - nv_wr32(dev, 0x1714, 0x00000000); - - nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL); - - nvc0_channel_del(&priv->bar1); - nouveau_vm_ref(NULL, &dev_priv->bar1_vm, priv->bar1_pgd); - nouveau_gpuobj_ref(NULL, &priv->bar1_pgd); - - nvc0_channel_del(&priv->bar3); - nouveau_vm_ref(dev_priv->bar3_vm, &vm, NULL); - nouveau_vm_ref(NULL, &vm, priv->bar3_pgd); - nouveau_gpuobj_ref(NULL, &priv->bar3_pgd); - nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]); - nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL); - - dev_priv->engine.instmem.priv = NULL; - kfree(priv); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_pm.c deleted file mode 100644 index ce65f81b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_pm.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_bios.h" -#include "nouveau_pm.h" - -static u32 read_div(struct drm_device *, int, u32, u32); -static u32 read_pll(struct drm_device *, u32); - -static u32 -read_vco(struct drm_device *dev, u32 dsrc) -{ - u32 ssrc = nv_rd32(dev, dsrc); - if (!(ssrc & 0x00000100)) - return read_pll(dev, 0x00e800); - return read_pll(dev, 0x00e820); -} - -static u32 -read_pll(struct drm_device *dev, u32 pll) -{ - u32 ctrl = nv_rd32(dev, pll + 0); - u32 coef = nv_rd32(dev, pll + 4); - u32 P = (coef & 0x003f0000) >> 16; - u32 N = (coef & 0x0000ff00) >> 8; - u32 M = (coef & 0x000000ff) >> 0; - u32 sclk, doff; - - if (!(ctrl & 0x00000001)) - return 0; - - switch (pll & 0xfff000) { - case 0x00e000: - sclk = 27000; - P = 1; - break; - case 0x137000: - doff = (pll - 0x137000) / 0x20; - sclk = read_div(dev, doff, 0x137120, 0x137140); - break; - case 0x132000: - switch (pll) { - case 0x132000: - sclk = read_pll(dev, 0x132020); - break; - case 0x132020: - sclk = read_div(dev, 0, 0x137320, 0x137330); - break; - default: - return 0; - } - break; - default: - return 0; - } - - return sclk * N / M / P; -} - -static u32 -read_div(struct drm_device *dev, int doff, u32 dsrc, u32 dctl) -{ - u32 ssrc = nv_rd32(dev, dsrc + (doff * 4)); - u32 sctl = nv_rd32(dev, dctl + (doff * 4)); - - switch (ssrc & 0x00000003) { - case 0: - if ((ssrc & 0x00030000) != 0x00030000) - return 27000; - return 108000; - case 2: - return 100000; - case 3: - if (sctl & 0x80000000) { - u32 sclk = read_vco(dev, dsrc + (doff * 4)); - u32 sdiv = (sctl & 0x0000003f) + 2; - return (sclk * 2) / sdiv; - } - - return read_vco(dev, dsrc + (doff * 4)); - default: - return 0; - } -} - -static u32 -read_mem(struct drm_device *dev) -{ - u32 ssel = nv_rd32(dev, 0x1373f0); - if (ssel & 0x00000001) - return read_div(dev, 0, 0x137300, 0x137310); - return read_pll(dev, 0x132000); -} - -static u32 -read_clk(struct drm_device *dev, int clk) -{ - u32 sctl = nv_rd32(dev, 0x137250 + (clk * 4)); - u32 ssel = nv_rd32(dev, 0x137100); - u32 sclk, sdiv; - - if (ssel & (1 << clk)) { - if (clk < 7) - sclk = read_pll(dev, 0x137000 + (clk * 0x20)); - else - sclk = read_pll(dev, 0x1370e0); - sdiv = ((sctl & 0x00003f00) >> 8) + 2; - } else { - sclk = read_div(dev, clk, 0x137160, 0x1371d0); - sdiv = ((sctl & 0x0000003f) >> 0) + 2; - } - - if (sctl & 0x80000000) - return (sclk * 2) / sdiv; - return sclk; -} - -int -nvc0_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - perflvl->shader = read_clk(dev, 0x00); - perflvl->core = perflvl->shader / 2; - perflvl->memory = read_mem(dev); - perflvl->rop = read_clk(dev, 0x01); - perflvl->hub07 = read_clk(dev, 0x02); - perflvl->hub06 = read_clk(dev, 0x07); - perflvl->hub01 = read_clk(dev, 0x08); - perflvl->copy = read_clk(dev, 0x09); - perflvl->daemon = read_clk(dev, 0x0c); - perflvl->vdec = read_clk(dev, 0x0e); - return 0; -} - -struct nvc0_pm_clock { - u32 freq; - u32 ssel; - u32 mdiv; - u32 dsrc; - u32 ddiv; - u32 coef; -}; - -struct nvc0_pm_state { - struct nvc0_pm_clock eng[16]; -}; - -static u32 -calc_div(struct drm_device *dev, int clk, u32 ref, u32 freq, u32 *ddiv) -{ - u32 div = min((ref * 2) / freq, (u32)65); - if (div < 2) - div = 2; - - *ddiv = div - 2; - return (ref * 2) / div; -} - -static u32 -calc_src(struct drm_device *dev, int clk, u32 freq, u32 *dsrc, u32 *ddiv) -{ - u32 sclk; - - /* use one of the fixed frequencies if possible */ - *ddiv = 0x00000000; - switch (freq) { - case 27000: - case 108000: - *dsrc = 0x00000000; - if (freq == 108000) - *dsrc |= 0x00030000; - return freq; - case 100000: - *dsrc = 0x00000002; - return freq; - default: - *dsrc = 0x00000003; - break; - } - - /* otherwise, calculate the closest divider */ - sclk = read_vco(dev, clk); - if (clk < 7) - sclk = calc_div(dev, clk, sclk, freq, ddiv); - return sclk; -} - -static u32 -calc_pll(struct drm_device *dev, int clk, u32 freq, u32 *coef) -{ - struct pll_lims limits; - int N, M, P, ret; - - ret = get_pll_limits(dev, 0x137000 + (clk * 0x20), &limits); - if (ret) - return 0; - - limits.refclk = read_div(dev, clk, 0x137120, 0x137140); - if (!limits.refclk) - return 0; - - ret = nva3_calc_pll(dev, &limits, freq, &N, NULL, &M, &P); - if (ret <= 0) - return 0; - - *coef = (P << 16) | (N << 8) | M; - return ret; -} - -/* A (likely rather simplified and incomplete) view of the clock tree - * - * Key: - * - * S: source select - * D: divider - * P: pll - * F: switch - * - * Engine clocks: - * - * 137250(D) ---- 137100(F0) ---- 137160(S)/1371d0(D) ------------------- ref - * (F1) ---- 1370X0(P) ---- 137120(S)/137140(D) ---- ref - * - * Not all registers exist for all clocks. For example: clocks >= 8 don't - * have their own PLL (all tied to clock 7's PLL when in PLL mode), nor do - * they have the divider at 1371d0, though the source selection at 137160 - * still exists. You must use the divider at 137250 for these instead. - * - * Memory clock: - * - * TBD, read_mem() above is likely very wrong... - * - */ - -static int -calc_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info, u32 freq) -{ - u32 src0, div0, div1D, div1P = 0; - u32 clk0, clk1 = 0; - - /* invalid clock domain */ - if (!freq) - return 0; - - /* first possible path, using only dividers */ - clk0 = calc_src(dev, clk, freq, &src0, &div0); - clk0 = calc_div(dev, clk, clk0, freq, &div1D); - - /* see if we can get any closer using PLLs */ - if (clk0 != freq && (0x00004387 & (1 << clk))) { - if (clk < 7) - clk1 = calc_pll(dev, clk, freq, &info->coef); - else - clk1 = read_pll(dev, 0x1370e0); - clk1 = calc_div(dev, clk, clk1, freq, &div1P); - } - - /* select the method which gets closest to target freq */ - if (abs((int)freq - clk0) <= abs((int)freq - clk1)) { - info->dsrc = src0; - if (div0) { - info->ddiv |= 0x80000000; - info->ddiv |= div0 << 8; - info->ddiv |= div0; - } - if (div1D) { - info->mdiv |= 0x80000000; - info->mdiv |= div1D; - } - info->ssel = 0; - info->freq = clk0; - } else { - if (div1P) { - info->mdiv |= 0x80000000; - info->mdiv |= div1P << 8; - } - info->ssel = (1 << clk); - info->freq = clk1; - } - - return 0; -} - -void * -nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvc0_pm_state *info; - int ret; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return ERR_PTR(-ENOMEM); - - /* NFI why this is still in the performance table, the ROPCs appear - * to get their clock from clock 2 ("hub07", actually hub05 on this - * chip, but, anyway...) as well. nvatiming confirms hub05 and ROP - * are always the same freq with the binary driver even when the - * performance table says they should differ. - */ - if (dev_priv->chipset == 0xd9) - perflvl->rop = 0; - - if ((ret = calc_clk(dev, 0x00, &info->eng[0x00], perflvl->shader)) || - (ret = calc_clk(dev, 0x01, &info->eng[0x01], perflvl->rop)) || - (ret = calc_clk(dev, 0x02, &info->eng[0x02], perflvl->hub07)) || - (ret = calc_clk(dev, 0x07, &info->eng[0x07], perflvl->hub06)) || - (ret = calc_clk(dev, 0x08, &info->eng[0x08], perflvl->hub01)) || - (ret = calc_clk(dev, 0x09, &info->eng[0x09], perflvl->copy)) || - (ret = calc_clk(dev, 0x0c, &info->eng[0x0c], perflvl->daemon)) || - (ret = calc_clk(dev, 0x0e, &info->eng[0x0e], perflvl->vdec))) { - kfree(info); - return ERR_PTR(ret); - } - - return info; -} - -static void -prog_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info) -{ - /* program dividers at 137160/1371d0 first */ - if (clk < 7 && !info->ssel) { - nv_mask(dev, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv); - nv_wr32(dev, 0x137160 + (clk * 0x04), info->dsrc); - } - - /* switch clock to non-pll mode */ - nv_mask(dev, 0x137100, (1 << clk), 0x00000000); - nv_wait(dev, 0x137100, (1 << clk), 0x00000000); - - /* reprogram pll */ - if (clk < 7) { - /* make sure it's disabled first... */ - u32 base = 0x137000 + (clk * 0x20); - u32 ctrl = nv_rd32(dev, base + 0x00); - if (ctrl & 0x00000001) { - nv_mask(dev, base + 0x00, 0x00000004, 0x00000000); - nv_mask(dev, base + 0x00, 0x00000001, 0x00000000); - } - /* program it to new values, if necessary */ - if (info->ssel) { - nv_wr32(dev, base + 0x04, info->coef); - nv_mask(dev, base + 0x00, 0x00000001, 0x00000001); - nv_wait(dev, base + 0x00, 0x00020000, 0x00020000); - nv_mask(dev, base + 0x00, 0x00020004, 0x00000004); - } - } - - /* select pll/non-pll mode, and program final clock divider */ - nv_mask(dev, 0x137100, (1 << clk), info->ssel); - nv_wait(dev, 0x137100, (1 << clk), info->ssel); - nv_mask(dev, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv); -} - -int -nvc0_pm_clocks_set(struct drm_device *dev, void *data) -{ - struct nvc0_pm_state *info = data; - int i; - - for (i = 0; i < 16; i++) { - if (!info->eng[i].freq) - continue; - prog_clk(dev, i, &info->eng[i]); - } - - kfree(info); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vm.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vm.c deleted file mode 100644 index 30d2bd58..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vm.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" - -#include "nouveau_drv.h" -#include "nouveau_vm.h" - -void -nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index, - struct nouveau_gpuobj *pgt[2]) -{ - u32 pde[2] = { 0, 0 }; - - if (pgt[0]) - pde[1] = 0x00000001 | (pgt[0]->vinst >> 8); - if (pgt[1]) - pde[0] = 0x00000001 | (pgt[1]->vinst >> 8); - - nv_wo32(pgd, (index * 8) + 0, pde[0]); - nv_wo32(pgd, (index * 8) + 4, pde[1]); -} - -static inline u64 -nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target) -{ - phys >>= 8; - - phys |= 0x00000001; /* present */ - if (vma->access & NV_MEM_ACCESS_SYS) - phys |= 0x00000002; - - phys |= ((u64)target << 32); - phys |= ((u64)memtype << 36); - - return phys; -} - -void -nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) -{ - u32 next = 1 << (vma->node->type - 8); - - phys = nvc0_vm_addr(vma, phys, mem->memtype, 0); - pte <<= 3; - while (cnt--) { - nv_wo32(pgt, pte + 0, lower_32_bits(phys)); - nv_wo32(pgt, pte + 4, upper_32_bits(phys)); - phys += next; - pte += 8; - } -} - -void -nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, - struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) -{ - u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5; - - pte <<= 3; - while (cnt--) { - u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, target); - nv_wo32(pgt, pte + 0, lower_32_bits(phys)); - nv_wo32(pgt, pte + 4, upper_32_bits(phys)); - pte += 8; - } -} - -void -nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) -{ - pte <<= 3; - while (cnt--) { - nv_wo32(pgt, pte + 0, 0x00000000); - nv_wo32(pgt, pte + 4, 0x00000000); - pte += 8; - } -} - -void -nvc0_vm_flush(struct nouveau_vm *vm) -{ - struct drm_nouveau_private *dev_priv = vm->dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct drm_device *dev = vm->dev; - struct nouveau_vm_pgd *vpgd; - unsigned long flags; - u32 engine; - - engine = 1; - if (vm == dev_priv->bar1_vm || vm == dev_priv->bar3_vm) - engine |= 4; - - pinstmem->flush(vm->dev); - - spin_lock_irqsave(&dev_priv->vm_lock, flags); - list_for_each_entry(vpgd, &vm->pgd_list, head) { - /* looks like maybe a "free flush slots" counter, the - * faster you write to 0x100cbc to more it decreases - */ - if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) { - NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n", - nv_rd32(dev, 0x100c80), engine); - } - nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); - nv_wr32(dev, 0x100cbc, 0x80000000 | engine); - /* wait for flush to be queued? */ - if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) { - NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n", - nv_rd32(dev, 0x100c80), engine); - } - } - spin_unlock_irqrestore(&dev_priv->vm_lock, flags); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vram.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vram.c deleted file mode 100644 index a7eef893..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvc0_vram.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2010 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include "drmP.h" -#include "nouveau_drv.h" -#include "nouveau_mm.h" - -/* 0 = unsupported - * 1 = non-compressed - * 3 = compressed - */ -static const u8 types[256] = { - 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, - 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, - 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, - 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, - 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 -}; - -bool -nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags) -{ - u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8; - return likely((types[memtype] == 1)); -} - -int -nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin, - u32 type, struct nouveau_mem **pmem) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_mm *mm = &dev_priv->engine.vram.mm; - struct nouveau_mm_node *r; - struct nouveau_mem *mem; - int ret; - - size >>= 12; - align >>= 12; - ncmin >>= 12; - - mem = kzalloc(sizeof(*mem), GFP_KERNEL); - if (!mem) - return -ENOMEM; - - INIT_LIST_HEAD(&mem->regions); - mem->dev = dev_priv->dev; - mem->memtype = (type & 0xff); - mem->size = size; - - mutex_lock(&mm->mutex); - do { - ret = nouveau_mm_get(mm, 1, size, ncmin, align, &r); - if (ret) { - mutex_unlock(&mm->mutex); - nv50_vram_del(dev, &mem); - return ret; - } - - list_add_tail(&r->rl_entry, &mem->regions); - size -= r->length; - } while (size); - mutex_unlock(&mm->mutex); - - r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry); - mem->offset = (u64)r->offset << 12; - *pmem = mem; - return 0; -} - -int -nvc0_vram_init(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_vram_engine *vram = &dev_priv->engine.vram; - const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ - const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ - u32 parts = nv_rd32(dev, 0x022438); - u32 pmask = nv_rd32(dev, 0x022554); - u32 bsize = nv_rd32(dev, 0x10f20c); - u32 offset, length; - bool uniform = true; - int ret, part; - - NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); - NV_DEBUG(dev, "parts 0x%08x mask 0x%08x\n", parts, pmask); - - dev_priv->vram_type = nouveau_mem_vbios_type(dev); - dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x10f200) & 0x00000004); - - /* read amount of vram attached to each memory controller */ - for (part = 0; part < parts; part++) { - if (!(pmask & (1 << part))) { - u32 psize = nv_rd32(dev, 0x11020c + (part * 0x1000)); - if (psize != bsize) { - if (psize < bsize) - bsize = psize; - uniform = false; - } - - NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize); - dev_priv->vram_size += (u64)psize << 20; - } - } - - /* if all controllers have the same amount attached, there's no holes */ - if (uniform) { - offset = rsvd_head; - length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail; - return nouveau_mm_init(&vram->mm, offset, length, 1); - } - - /* otherwise, address lowest common amount from 0GiB */ - ret = nouveau_mm_init(&vram->mm, rsvd_head, (bsize << 8) * parts, 1); - if (ret) - return ret; - - /* and the rest starting from (8GiB + common_size) */ - offset = (0x0200000000ULL >> 12) + (bsize << 8); - length = (dev_priv->vram_size >> 12) - (bsize << 8) - rsvd_tail; - - ret = nouveau_mm_init(&vram->mm, offset, length, 0); - if (ret) { - nouveau_mm_fini(&vram->mm); - return ret; - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvd0_display.c b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvd0_display.c deleted file mode 100644 index 02472509..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvd0_display.c +++ /dev/null @@ -1,2113 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Ben Skeggs - */ - -#include - -#include "drmP.h" -#include "drm_crtc_helper.h" - -#include "nouveau_drv.h" -#include "nouveau_connector.h" -#include "nouveau_encoder.h" -#include "nouveau_crtc.h" -#include "nouveau_dma.h" -#include "nouveau_fb.h" -#include "nv50_display.h" - -#define EVO_DMA_NR 9 - -#define EVO_MASTER (0x00) -#define EVO_FLIP(c) (0x01 + (c)) -#define EVO_OVLY(c) (0x05 + (c)) -#define EVO_OIMM(c) (0x09 + (c)) -#define EVO_CURS(c) (0x0d + (c)) - -/* offsets in shared sync bo of various structures */ -#define EVO_SYNC(c, o) ((c) * 0x0100 + (o)) -#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) -#define EVO_FLIP_SEM0(c) EVO_SYNC((c), 0x00) -#define EVO_FLIP_SEM1(c) EVO_SYNC((c), 0x10) - -struct evo { - int idx; - dma_addr_t handle; - u32 *ptr; - struct { - u32 offset; - u16 value; - } sem; -}; - -struct nvd0_display { - struct nouveau_gpuobj *mem; - struct nouveau_bo *sync; - struct evo evo[9]; - - struct tasklet_struct tasklet; - u32 modeset; -}; - -static struct nvd0_display * -nvd0_display(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - return dev_priv->engine.display.priv; -} - -static struct drm_crtc * -nvd0_display_crtc_get(struct drm_encoder *encoder) -{ - return nouveau_encoder(encoder)->crtc; -} - -/****************************************************************************** - * EVO channel helpers - *****************************************************************************/ -static inline int -evo_icmd(struct drm_device *dev, int id, u32 mthd, u32 data) -{ - int ret = 0; - nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000001); - nv_wr32(dev, 0x610704 + (id * 0x10), data); - nv_mask(dev, 0x610704 + (id * 0x10), 0x80000ffc, 0x80000000 | mthd); - if (!nv_wait(dev, 0x610704 + (id * 0x10), 0x80000000, 0x00000000)) - ret = -EBUSY; - nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000000); - return ret; -} - -static u32 * -evo_wait(struct drm_device *dev, int id, int nr) -{ - struct nvd0_display *disp = nvd0_display(dev); - u32 put = nv_rd32(dev, 0x640000 + (id * 0x1000)) / 4; - - if (put + nr >= (PAGE_SIZE / 4)) { - disp->evo[id].ptr[put] = 0x20000000; - - nv_wr32(dev, 0x640000 + (id * 0x1000), 0x00000000); - if (!nv_wait(dev, 0x640004 + (id * 0x1000), ~0, 0x00000000)) { - NV_ERROR(dev, "evo %d dma stalled\n", id); - return NULL; - } - - put = 0; - } - - if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) - NV_INFO(dev, "Evo%d: %p START\n", id, disp->evo[id].ptr + put); - - return disp->evo[id].ptr + put; -} - -static void -evo_kick(u32 *push, struct drm_device *dev, int id) -{ - struct nvd0_display *disp = nvd0_display(dev); - - if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) { - u32 curp = nv_rd32(dev, 0x640000 + (id * 0x1000)) >> 2; - u32 *cur = disp->evo[id].ptr + curp; - - while (cur < push) - NV_INFO(dev, "Evo%d: 0x%08x\n", id, *cur++); - NV_INFO(dev, "Evo%d: %p KICK!\n", id, push); - } - - nv_wr32(dev, 0x640000 + (id * 0x1000), (push - disp->evo[id].ptr) << 2); -} - -#define evo_mthd(p,m,s) *((p)++) = (((s) << 18) | (m)) -#define evo_data(p,d) *((p)++) = (d) - -static int -evo_init_dma(struct drm_device *dev, int ch) -{ - struct nvd0_display *disp = nvd0_display(dev); - u32 flags; - - flags = 0x00000000; - if (ch == EVO_MASTER) - flags |= 0x01000000; - - nv_wr32(dev, 0x610494 + (ch * 0x0010), (disp->evo[ch].handle >> 8) | 3); - nv_wr32(dev, 0x610498 + (ch * 0x0010), 0x00010000); - nv_wr32(dev, 0x61049c + (ch * 0x0010), 0x00000001); - nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000010); - nv_wr32(dev, 0x640000 + (ch * 0x1000), 0x00000000); - nv_wr32(dev, 0x610490 + (ch * 0x0010), 0x00000013 | flags); - if (!nv_wait(dev, 0x610490 + (ch * 0x0010), 0x80000000, 0x00000000)) { - NV_ERROR(dev, "PDISP: ch%d 0x%08x\n", ch, - nv_rd32(dev, 0x610490 + (ch * 0x0010))); - return -EBUSY; - } - - nv_mask(dev, 0x610090, (1 << ch), (1 << ch)); - nv_mask(dev, 0x6100a0, (1 << ch), (1 << ch)); - return 0; -} - -static void -evo_fini_dma(struct drm_device *dev, int ch) -{ - if (!(nv_rd32(dev, 0x610490 + (ch * 0x0010)) & 0x00000010)) - return; - - nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000000); - nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000003, 0x00000000); - nv_wait(dev, 0x610490 + (ch * 0x0010), 0x80000000, 0x00000000); - nv_mask(dev, 0x610090, (1 << ch), 0x00000000); - nv_mask(dev, 0x6100a0, (1 << ch), 0x00000000); -} - -static inline void -evo_piow(struct drm_device *dev, int ch, u16 mthd, u32 data) -{ - nv_wr32(dev, 0x640000 + (ch * 0x1000) + mthd, data); -} - -static int -evo_init_pio(struct drm_device *dev, int ch) -{ - nv_wr32(dev, 0x610490 + (ch * 0x0010), 0x00000001); - if (!nv_wait(dev, 0x610490 + (ch * 0x0010), 0x00010000, 0x00010000)) { - NV_ERROR(dev, "PDISP: ch%d 0x%08x\n", ch, - nv_rd32(dev, 0x610490 + (ch * 0x0010))); - return -EBUSY; - } - - nv_mask(dev, 0x610090, (1 << ch), (1 << ch)); - nv_mask(dev, 0x6100a0, (1 << ch), (1 << ch)); - return 0; -} - -static void -evo_fini_pio(struct drm_device *dev, int ch) -{ - if (!(nv_rd32(dev, 0x610490 + (ch * 0x0010)) & 0x00000001)) - return; - - nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000010, 0x00000010); - nv_mask(dev, 0x610490 + (ch * 0x0010), 0x00000001, 0x00000000); - nv_wait(dev, 0x610490 + (ch * 0x0010), 0x00010000, 0x00000000); - nv_mask(dev, 0x610090, (1 << ch), 0x00000000); - nv_mask(dev, 0x6100a0, (1 << ch), 0x00000000); -} - -static bool -evo_sync_wait(void *data) -{ - return nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000; -} - -static int -evo_sync(struct drm_device *dev, int ch) -{ - struct nvd0_display *disp = nvd0_display(dev); - u32 *push = evo_wait(dev, ch, 8); - if (push) { - nouveau_bo_wr32(disp->sync, EVO_MAST_NTFY, 0x00000000); - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x80000000 | EVO_MAST_NTFY); - evo_mthd(push, 0x0080, 2); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_kick(push, dev, ch); - if (nv_wait_cb(dev, evo_sync_wait, disp->sync)) - return 0; - } - - return -EBUSY; -} - -/****************************************************************************** - * Page flipping channel - *****************************************************************************/ -struct nouveau_bo * -nvd0_display_crtc_sema(struct drm_device *dev, int crtc) -{ - return nvd0_display(dev)->sync; -} - -void -nvd0_display_flip_stop(struct drm_crtc *crtc) -{ - struct nvd0_display *disp = nvd0_display(crtc->dev); - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct evo *evo = &disp->evo[EVO_FLIP(nv_crtc->index)]; - u32 *push; - - push = evo_wait(crtc->dev, evo->idx, 8); - if (push) { - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0094, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00c0, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - evo_kick(push, crtc->dev, evo->idx); - } -} - -int -nvd0_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct nouveau_channel *chan, u32 swap_interval) -{ - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); - struct nvd0_display *disp = nvd0_display(crtc->dev); - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct evo *evo = &disp->evo[EVO_FLIP(nv_crtc->index)]; - u64 offset; - u32 *push; - int ret; - - evo_sync(crtc->dev, EVO_MASTER); - - swap_interval <<= 4; - if (swap_interval == 0) - swap_interval |= 0x100; - - push = evo_wait(crtc->dev, evo->idx, 128); - if (unlikely(push == NULL)) - return -EBUSY; - - /* synchronise with the rendering channel, if necessary */ - if (likely(chan)) { - ret = RING_SPACE(chan, 10); - if (ret) - return ret; - - offset = chan->dispc_vma[nv_crtc->index].offset; - offset += evo->sem.offset; - - BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 0xf00d0000 | evo->sem.value); - OUT_RING (chan, 0x1002); - BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset ^ 0x10)); - OUT_RING (chan, 0x74b1e000); - OUT_RING (chan, 0x1001); - FIRE_RING (chan); - } else { - nouveau_bo_wr32(disp->sync, evo->sem.offset / 4, - 0xf00d0000 | evo->sem.value); - evo_sync(crtc->dev, EVO_MASTER); - } - - /* queue the flip */ - evo_mthd(push, 0x0100, 1); - evo_data(push, 0xfffe0000); - evo_mthd(push, 0x0084, 1); - evo_data(push, swap_interval); - if (!(swap_interval & 0x00000100)) { - evo_mthd(push, 0x00e0, 1); - evo_data(push, 0x40000000); - } - evo_mthd(push, 0x0088, 4); - evo_data(push, evo->sem.offset); - evo_data(push, 0xf00d0000 | evo->sem.value); - evo_data(push, 0x74b1e000); - evo_data(push, NvEvoSync); - evo_mthd(push, 0x00a0, 2); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_mthd(push, 0x00c0, 1); - evo_data(push, nv_fb->r_dma); - evo_mthd(push, 0x0110, 2); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0400, 5); - evo_data(push, nv_fb->nvbo->bo.offset >> 8); - evo_data(push, 0); - evo_data(push, (fb->height << 16) | fb->width); - evo_data(push, nv_fb->r_pitch); - evo_data(push, nv_fb->r_format); - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - evo_kick(push, crtc->dev, evo->idx); - - evo->sem.offset ^= 0x10; - evo->sem.value++; - return 0; -} - -/****************************************************************************** - * CRTC - *****************************************************************************/ -static int -nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) -{ - struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private; - struct drm_device *dev = nv_crtc->base.dev; - struct nouveau_connector *nv_connector; - struct drm_connector *connector; - u32 *push, mode = 0x00; - u32 mthd; - - nv_connector = nouveau_crtc_connector_get(nv_crtc); - connector = &nv_connector->base; - if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) { - if (nv_crtc->base.fb->depth > connector->display_info.bpc * 3) - mode = DITHERING_MODE_DYNAMIC2X2; - } else { - mode = nv_connector->dithering_mode; - } - - if (nv_connector->dithering_depth == DITHERING_DEPTH_AUTO) { - if (connector->display_info.bpc >= 8) - mode |= DITHERING_DEPTH_8BPC; - } else { - mode |= nv_connector->dithering_depth; - } - - if (dev_priv->card_type < NV_E0) - mthd = 0x0490 + (nv_crtc->index * 0x0300); - else - mthd = 0x04a0 + (nv_crtc->index * 0x0300); - - push = evo_wait(dev, EVO_MASTER, 4); - if (push) { - evo_mthd(push, mthd, 1); - evo_data(push, mode); - if (update) { - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - } - evo_kick(push, dev, EVO_MASTER); - } - - return 0; -} - -static int -nvd0_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) -{ - struct drm_display_mode *omode, *umode = &nv_crtc->base.mode; - struct drm_device *dev = nv_crtc->base.dev; - struct drm_crtc *crtc = &nv_crtc->base; - struct nouveau_connector *nv_connector; - int mode = DRM_MODE_SCALE_NONE; - u32 oX, oY, *push; - - /* start off at the resolution we programmed the crtc for, this - * effectively handles NONE/FULL scaling - */ - nv_connector = nouveau_crtc_connector_get(nv_crtc); - if (nv_connector && nv_connector->native_mode) - mode = nv_connector->scaling_mode; - - if (mode != DRM_MODE_SCALE_NONE) - omode = nv_connector->native_mode; - else - omode = umode; - - oX = omode->hdisplay; - oY = omode->vdisplay; - if (omode->flags & DRM_MODE_FLAG_DBLSCAN) - oY *= 2; - - /* add overscan compensation if necessary, will keep the aspect - * ratio the same as the backend mode unless overridden by the - * user setting both hborder and vborder properties. - */ - if (nv_connector && ( nv_connector->underscan == UNDERSCAN_ON || - (nv_connector->underscan == UNDERSCAN_AUTO && - nv_connector->edid && - drm_detect_hdmi_monitor(nv_connector->edid)))) { - u32 bX = nv_connector->underscan_hborder; - u32 bY = nv_connector->underscan_vborder; - u32 aspect = (oY << 19) / oX; - - if (bX) { - oX -= (bX * 2); - if (bY) oY -= (bY * 2); - else oY = ((oX * aspect) + (aspect / 2)) >> 19; - } else { - oX -= (oX >> 4) + 32; - if (bY) oY -= (bY * 2); - else oY = ((oX * aspect) + (aspect / 2)) >> 19; - } - } - - /* handle CENTER/ASPECT scaling, taking into account the areas - * removed already for overscan compensation - */ - switch (mode) { - case DRM_MODE_SCALE_CENTER: - oX = min((u32)umode->hdisplay, oX); - oY = min((u32)umode->vdisplay, oY); - /* fall-through */ - case DRM_MODE_SCALE_ASPECT: - if (oY < oX) { - u32 aspect = (umode->hdisplay << 19) / umode->vdisplay; - oX = ((oY * aspect) + (aspect / 2)) >> 19; - } else { - u32 aspect = (umode->vdisplay << 19) / umode->hdisplay; - oY = ((oX * aspect) + (aspect / 2)) >> 19; - } - break; - default: - break; - } - - push = evo_wait(dev, EVO_MASTER, 8); - if (push) { - evo_mthd(push, 0x04c0 + (nv_crtc->index * 0x300), 3); - evo_data(push, (oY << 16) | oX); - evo_data(push, (oY << 16) | oX); - evo_data(push, (oY << 16) | oX); - evo_mthd(push, 0x0494 + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x04b8 + (nv_crtc->index * 0x300), 1); - evo_data(push, (umode->vdisplay << 16) | umode->hdisplay); - evo_kick(push, dev, EVO_MASTER); - if (update) { - nvd0_display_flip_stop(crtc); - nvd0_display_flip_next(crtc, crtc->fb, NULL, 1); - } - } - - return 0; -} - -static int -nvd0_crtc_set_image(struct nouveau_crtc *nv_crtc, struct drm_framebuffer *fb, - int x, int y, bool update) -{ - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(fb); - u32 *push; - - push = evo_wait(fb->dev, EVO_MASTER, 16); - if (push) { - evo_mthd(push, 0x0460 + (nv_crtc->index * 0x300), 1); - evo_data(push, nvfb->nvbo->bo.offset >> 8); - evo_mthd(push, 0x0468 + (nv_crtc->index * 0x300), 4); - evo_data(push, (fb->height << 16) | fb->width); - evo_data(push, nvfb->r_pitch); - evo_data(push, nvfb->r_format); - evo_data(push, nvfb->r_dma); - evo_mthd(push, 0x04b0 + (nv_crtc->index * 0x300), 1); - evo_data(push, (y << 16) | x); - if (update) { - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - } - evo_kick(push, fb->dev, EVO_MASTER); - } - - nv_crtc->fb.tile_flags = nvfb->r_dma; - return 0; -} - -static void -nvd0_crtc_cursor_show(struct nouveau_crtc *nv_crtc, bool show, bool update) -{ - struct drm_device *dev = nv_crtc->base.dev; - u32 *push = evo_wait(dev, EVO_MASTER, 16); - if (push) { - if (show) { - evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2); - evo_data(push, 0x85000000); - evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); - evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1); - evo_data(push, NvEvoVRAM); - } else { - evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x05000000); - evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x00000000); - } - - if (update) { - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - } - - evo_kick(push, dev, EVO_MASTER); - } -} - -static void -nvd0_crtc_dpms(struct drm_crtc *crtc, int mode) -{ -} - -static void -nvd0_crtc_prepare(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - u32 *push; - - nvd0_display_flip_stop(crtc); - - push = evo_wait(crtc->dev, EVO_MASTER, 2); - if (push) { - evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x03000000); - evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x00000000); - evo_kick(push, crtc->dev, EVO_MASTER); - } - - nvd0_crtc_cursor_show(nv_crtc, false, false); -} - -static void -nvd0_crtc_commit(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - u32 *push; - - push = evo_wait(crtc->dev, EVO_MASTER, 32); - if (push) { - evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1); - evo_data(push, nv_crtc->fb.tile_flags); - evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 4); - evo_data(push, 0x83000000); - evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8); - evo_data(push, 0x00000000); - evo_data(push, 0x00000000); - evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1); - evo_data(push, NvEvoVRAM); - evo_mthd(push, 0x0430 + (nv_crtc->index * 0x300), 1); - evo_data(push, 0xffffff00); - evo_kick(push, crtc->dev, EVO_MASTER); - } - - nvd0_crtc_cursor_show(nv_crtc, nv_crtc->cursor.visible, true); - nvd0_display_flip_next(crtc, crtc->fb, NULL, 1); -} - -static bool -nvd0_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static int -nvd0_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) -{ - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); - int ret; - - ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM); - if (ret) - return ret; - - if (old_fb) { - nvfb = nouveau_framebuffer(old_fb); - nouveau_bo_unpin(nvfb->nvbo); - } - - return 0; -} - -static int -nvd0_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, - struct drm_display_mode *mode, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nouveau_connector *nv_connector; - u32 ilace = (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1; - u32 vscan = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1; - u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks; - u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks; - u32 vblan2e = 0, vblan2s = 1; - u32 *push; - int ret; - - hactive = mode->htotal; - hsynce = mode->hsync_end - mode->hsync_start - 1; - hbackp = mode->htotal - mode->hsync_end; - hblanke = hsynce + hbackp; - hfrontp = mode->hsync_start - mode->hdisplay; - hblanks = mode->htotal - hfrontp - 1; - - vactive = mode->vtotal * vscan / ilace; - vsynce = ((mode->vsync_end - mode->vsync_start) * vscan / ilace) - 1; - vbackp = (mode->vtotal - mode->vsync_end) * vscan / ilace; - vblanke = vsynce + vbackp; - vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace; - vblanks = vactive - vfrontp - 1; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) { - vblan2e = vactive + vsynce + vbackp; - vblan2s = vblan2e + (mode->vdisplay * vscan / ilace); - vactive = (vactive * 2) + 1; - } - - ret = nvd0_crtc_swap_fbs(crtc, old_fb); - if (ret) - return ret; - - push = evo_wait(crtc->dev, EVO_MASTER, 64); - if (push) { - evo_mthd(push, 0x0410 + (nv_crtc->index * 0x300), 6); - evo_data(push, 0x00000000); - evo_data(push, (vactive << 16) | hactive); - evo_data(push, ( vsynce << 16) | hsynce); - evo_data(push, (vblanke << 16) | hblanke); - evo_data(push, (vblanks << 16) | hblanks); - evo_data(push, (vblan2e << 16) | vblan2s); - evo_mthd(push, 0x042c + (nv_crtc->index * 0x300), 1); - evo_data(push, 0x00000000); /* ??? */ - evo_mthd(push, 0x0450 + (nv_crtc->index * 0x300), 3); - evo_data(push, mode->clock * 1000); - evo_data(push, 0x00200000); /* ??? */ - evo_data(push, mode->clock * 1000); - evo_mthd(push, 0x04d0 + (nv_crtc->index * 0x300), 2); - evo_data(push, 0x00000311); - evo_data(push, 0x00000100); - evo_kick(push, crtc->dev, EVO_MASTER); - } - - nv_connector = nouveau_crtc_connector_get(nv_crtc); - nvd0_crtc_set_dither(nv_crtc, false); - nvd0_crtc_set_scale(nv_crtc, false); - nvd0_crtc_set_image(nv_crtc, crtc->fb, x, y, false); - return 0; -} - -static int -nvd0_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - int ret; - - if (!crtc->fb) { - NV_DEBUG_KMS(crtc->dev, "No FB bound\n"); - return 0; - } - - ret = nvd0_crtc_swap_fbs(crtc, old_fb); - if (ret) - return ret; - - nvd0_display_flip_stop(crtc); - nvd0_crtc_set_image(nv_crtc, crtc->fb, x, y, true); - nvd0_display_flip_next(crtc, crtc->fb, NULL, 1); - return 0; -} - -static int -nvd0_crtc_mode_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, int x, int y, - enum mode_set_atomic state) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - nvd0_display_flip_stop(crtc); - nvd0_crtc_set_image(nv_crtc, fb, x, y, true); - return 0; -} - -static void -nvd0_crtc_lut_load(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); - int i; - - for (i = 0; i < 256; i++) { - writew(0x6000 + (nv_crtc->lut.r[i] >> 2), lut + (i * 0x20) + 0); - writew(0x6000 + (nv_crtc->lut.g[i] >> 2), lut + (i * 0x20) + 2); - writew(0x6000 + (nv_crtc->lut.b[i] >> 2), lut + (i * 0x20) + 4); - } -} - -static int -nvd0_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - uint32_t handle, uint32_t width, uint32_t height) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct drm_gem_object *gem; - struct nouveau_bo *nvbo; - bool visible = (handle != 0); - int i, ret = 0; - - if (visible) { - if (width != 64 || height != 64) - return -EINVAL; - - gem = drm_gem_object_lookup(dev, file_priv, handle); - if (unlikely(!gem)) - return -ENOENT; - nvbo = nouveau_gem_object(gem); - - ret = nouveau_bo_map(nvbo); - if (ret == 0) { - for (i = 0; i < 64 * 64; i++) { - u32 v = nouveau_bo_rd32(nvbo, i); - nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, v); - } - nouveau_bo_unmap(nvbo); - } - - drm_gem_object_unreference_unlocked(gem); - } - - if (visible != nv_crtc->cursor.visible) { - nvd0_crtc_cursor_show(nv_crtc, visible, true); - nv_crtc->cursor.visible = visible; - } - - return ret; -} - -static int -nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - int ch = EVO_CURS(nv_crtc->index); - - evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x); - evo_piow(crtc->dev, ch, 0x0080, 0x00000000); - return 0; -} - -static void -nvd0_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, - uint32_t start, uint32_t size) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - u32 end = max(start + size, (u32)256); - u32 i; - - for (i = start; i < end; i++) { - nv_crtc->lut.r[i] = r[i]; - nv_crtc->lut.g[i] = g[i]; - nv_crtc->lut.b[i] = b[i]; - } - - nvd0_crtc_lut_load(crtc); -} - -static void -nvd0_crtc_destroy(struct drm_crtc *crtc) -{ - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - nouveau_bo_unmap(nv_crtc->cursor.nvbo); - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); - nouveau_bo_unmap(nv_crtc->lut.nvbo); - nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); - drm_crtc_cleanup(crtc); - kfree(crtc); -} - -static const struct drm_crtc_helper_funcs nvd0_crtc_hfunc = { - .dpms = nvd0_crtc_dpms, - .prepare = nvd0_crtc_prepare, - .commit = nvd0_crtc_commit, - .mode_fixup = nvd0_crtc_mode_fixup, - .mode_set = nvd0_crtc_mode_set, - .mode_set_base = nvd0_crtc_mode_set_base, - .mode_set_base_atomic = nvd0_crtc_mode_set_base_atomic, - .load_lut = nvd0_crtc_lut_load, -}; - -static const struct drm_crtc_funcs nvd0_crtc_func = { - .cursor_set = nvd0_crtc_cursor_set, - .cursor_move = nvd0_crtc_cursor_move, - .gamma_set = nvd0_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, - .destroy = nvd0_crtc_destroy, - .page_flip = nouveau_crtc_page_flip, -}; - -static void -nvd0_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) -{ -} - -static void -nvd0_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset) -{ -} - -static int -nvd0_crtc_create(struct drm_device *dev, int index) -{ - struct nouveau_crtc *nv_crtc; - struct drm_crtc *crtc; - int ret, i; - - nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); - if (!nv_crtc) - return -ENOMEM; - - nv_crtc->index = index; - nv_crtc->set_dither = nvd0_crtc_set_dither; - nv_crtc->set_scale = nvd0_crtc_set_scale; - nv_crtc->cursor.set_offset = nvd0_cursor_set_offset; - nv_crtc->cursor.set_pos = nvd0_cursor_set_pos; - for (i = 0; i < 256; i++) { - nv_crtc->lut.r[i] = i << 8; - nv_crtc->lut.g[i] = i << 8; - nv_crtc->lut.b[i] = i << 8; - } - - crtc = &nv_crtc->base; - drm_crtc_init(dev, crtc, &nvd0_crtc_func); - drm_crtc_helper_add(crtc, &nvd0_crtc_hfunc); - drm_mode_crtc_set_gamma_size(crtc, 256); - - ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM, - 0, 0x0000, &nv_crtc->cursor.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(nv_crtc->cursor.nvbo); - if (ret) - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); - } - - if (ret) - goto out; - - ret = nouveau_bo_new(dev, 8192, 0x100, TTM_PL_FLAG_VRAM, - 0, 0x0000, &nv_crtc->lut.nvbo); - if (!ret) { - ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(nv_crtc->lut.nvbo); - if (ret) - nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); - } - - if (ret) - goto out; - - nvd0_crtc_lut_load(crtc); - -out: - if (ret) - nvd0_crtc_destroy(crtc); - return ret; -} - -/****************************************************************************** - * DAC - *****************************************************************************/ -static void -nvd0_dac_dpms(struct drm_encoder *encoder, int mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - int or = nv_encoder->or; - u32 dpms_ctrl; - - dpms_ctrl = 0x80000000; - if (mode == DRM_MODE_DPMS_STANDBY || mode == DRM_MODE_DPMS_OFF) - dpms_ctrl |= 0x00000001; - if (mode == DRM_MODE_DPMS_SUSPEND || mode == DRM_MODE_DPMS_OFF) - dpms_ctrl |= 0x00000004; - - nv_wait(dev, 0x61a004 + (or * 0x0800), 0x80000000, 0x00000000); - nv_mask(dev, 0x61a004 + (or * 0x0800), 0xc000007f, dpms_ctrl); - nv_wait(dev, 0x61a004 + (or * 0x0800), 0x80000000, 0x00000000); -} - -static bool -nvd0_dac_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (nv_connector && nv_connector->native_mode) { - if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) { - int id = adjusted_mode->base.id; - *adjusted_mode = *nv_connector->native_mode; - adjusted_mode->base.id = id; - } - } - - return true; -} - -static void -nvd0_dac_commit(struct drm_encoder *encoder) -{ -} - -static void -nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - u32 syncs, magic, *push; - - syncs = 0x00000001; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - syncs |= 0x00000008; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - syncs |= 0x00000010; - - magic = 0x31ec6000 | (nv_crtc->index << 25); - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - magic |= 0x00000001; - - nvd0_dac_dpms(encoder, DRM_MODE_DPMS_ON); - - push = evo_wait(encoder->dev, EVO_MASTER, 8); - if (push) { - evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); - evo_data(push, syncs); - evo_data(push, magic); - evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 2); - evo_data(push, 1 << nv_crtc->index); - evo_data(push, 0x00ff); - evo_kick(push, encoder->dev, EVO_MASTER); - } - - nv_encoder->crtc = encoder->crtc; -} - -static void -nvd0_dac_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - u32 *push; - - if (nv_encoder->crtc) { - nvd0_crtc_prepare(nv_encoder->crtc); - - push = evo_wait(dev, EVO_MASTER, 4); - if (push) { - evo_mthd(push, 0x0180 + (nv_encoder->or * 0x20), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - evo_kick(push, dev, EVO_MASTER); - } - - nv_encoder->crtc = NULL; - } -} - -static enum drm_connector_status -nvd0_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - enum drm_connector_status status = connector_status_disconnected; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - int or = nv_encoder->or; - u32 load; - - nv_wr32(dev, 0x61a00c + (or * 0x800), 0x00100000); - udelay(9500); - nv_wr32(dev, 0x61a00c + (or * 0x800), 0x80000000); - - load = nv_rd32(dev, 0x61a00c + (or * 0x800)); - if ((load & 0x38000000) == 0x38000000) - status = connector_status_connected; - - nv_wr32(dev, 0x61a00c + (or * 0x800), 0x00000000); - return status; -} - -static void -nvd0_dac_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); - kfree(encoder); -} - -static const struct drm_encoder_helper_funcs nvd0_dac_hfunc = { - .dpms = nvd0_dac_dpms, - .mode_fixup = nvd0_dac_mode_fixup, - .prepare = nvd0_dac_disconnect, - .commit = nvd0_dac_commit, - .mode_set = nvd0_dac_mode_set, - .disable = nvd0_dac_disconnect, - .get_crtc = nvd0_display_crtc_get, - .detect = nvd0_dac_detect -}; - -static const struct drm_encoder_funcs nvd0_dac_func = { - .destroy = nvd0_dac_destroy, -}; - -static int -nvd0_dac_create(struct drm_connector *connector, struct dcb_entry *dcbe) -{ - struct drm_device *dev = connector->dev; - struct nouveau_encoder *nv_encoder; - struct drm_encoder *encoder; - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - nv_encoder->dcb = dcbe; - nv_encoder->or = ffs(dcbe->or) - 1; - - encoder = to_drm_encoder(nv_encoder); - encoder->possible_crtcs = dcbe->heads; - encoder->possible_clones = 0; - drm_encoder_init(dev, encoder, &nvd0_dac_func, DRM_MODE_ENCODER_DAC); - drm_encoder_helper_add(encoder, &nvd0_dac_hfunc); - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} - -/****************************************************************************** - * Audio - *****************************************************************************/ -static void -nvd0_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector; - struct drm_device *dev = encoder->dev; - int i, or = nv_encoder->or * 0x30; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (!drm_detect_monitor_audio(nv_connector->edid)) - return; - - nv_mask(dev, 0x10ec10 + or, 0x80000003, 0x80000001); - - drm_edid_to_eld(&nv_connector->base, nv_connector->edid); - if (nv_connector->base.eld[0]) { - u8 *eld = nv_connector->base.eld; - - for (i = 0; i < eld[2] * 4; i++) - nv_wr32(dev, 0x10ec00 + or, (i << 8) | eld[i]); - for (i = eld[2] * 4; i < 0x60; i++) - nv_wr32(dev, 0x10ec00 + or, (i << 8) | 0x00); - - nv_mask(dev, 0x10ec10 + or, 0x80000002, 0x80000002); - } -} - -static void -nvd0_audio_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - int or = nv_encoder->or * 0x30; - - nv_mask(dev, 0x10ec10 + or, 0x80000003, 0x80000000); -} - -/****************************************************************************** - * HDMI - *****************************************************************************/ -static void -nvd0_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nouveau_connector *nv_connector; - struct drm_device *dev = encoder->dev; - int head = nv_crtc->index * 0x800; - u32 rekey = 56; /* binary driver, and tegra constant */ - u32 max_ac_packet; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (!drm_detect_hdmi_monitor(nv_connector->edid)) - return; - - max_ac_packet = mode->htotal - mode->hdisplay; - max_ac_packet -= rekey; - max_ac_packet -= 18; /* constant from tegra */ - max_ac_packet /= 32; - - /* AVI InfoFrame */ - nv_mask(dev, 0x616714 + head, 0x00000001, 0x00000000); - nv_wr32(dev, 0x61671c + head, 0x000d0282); - nv_wr32(dev, 0x616720 + head, 0x0000006f); - nv_wr32(dev, 0x616724 + head, 0x00000000); - nv_wr32(dev, 0x616728 + head, 0x00000000); - nv_wr32(dev, 0x61672c + head, 0x00000000); - nv_mask(dev, 0x616714 + head, 0x00000001, 0x00000001); - - /* ??? InfoFrame? */ - nv_mask(dev, 0x6167a4 + head, 0x00000001, 0x00000000); - nv_wr32(dev, 0x6167ac + head, 0x00000010); - nv_mask(dev, 0x6167a4 + head, 0x00000001, 0x00000001); - - /* HDMI_CTRL */ - nv_mask(dev, 0x616798 + head, 0x401f007f, 0x40000000 | rekey | - max_ac_packet << 16); - - /* NFI, audio doesn't work without it though.. */ - nv_mask(dev, 0x616548 + head, 0x00000070, 0x00000000); - - nvd0_audio_mode_set(encoder, mode); -} - -static void -nvd0_hdmi_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); - struct drm_device *dev = encoder->dev; - int head = nv_crtc->index * 0x800; - - nvd0_audio_disconnect(encoder); - - nv_mask(dev, 0x616798 + head, 0x40000000, 0x00000000); - nv_mask(dev, 0x6167a4 + head, 0x00000001, 0x00000000); - nv_mask(dev, 0x616714 + head, 0x00000001, 0x00000000); -} - -/****************************************************************************** - * SOR - *****************************************************************************/ -static inline u32 -nvd0_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) -{ - static const u8 nvd0[] = { 16, 8, 0, 24 }; - return nvd0[lane]; -} - -static void -nvd0_sor_dp_train_set(struct drm_device *dev, struct dcb_entry *dcb, u8 pattern) -{ - const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - const u32 loff = (or * 0x800) + (link * 0x80); - nv_mask(dev, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); -} - -static void -nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb, - u8 lane, u8 swing, u8 preem) -{ - const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - const u32 loff = (or * 0x800) + (link * 0x80); - u32 shift = nvd0_sor_dp_lane_map(dev, dcb, lane); - u32 mask = 0x000000ff << shift; - u8 *table, *entry, *config = NULL; - - switch (swing) { - case 0: preem += 0; break; - case 1: preem += 4; break; - case 2: preem += 7; break; - case 3: preem += 9; break; - } - - table = nouveau_dp_bios_data(dev, dcb, &entry); - if (table) { - if (table[0] == 0x30) { - config = entry + table[4]; - config += table[5] * preem; - } else - if (table[0] == 0x40) { - config = table + table[1]; - config += table[2] * table[3]; - config += table[6] * preem; - } - } - - if (!config) { - NV_ERROR(dev, "PDISP: unsupported DP table for chipset\n"); - return; - } - - nv_mask(dev, 0x61c118 + loff, mask, config[1] << shift); - nv_mask(dev, 0x61c120 + loff, mask, config[2] << shift); - nv_mask(dev, 0x61c130 + loff, 0x0000ff00, config[3] << 8); - nv_mask(dev, 0x61c13c + loff, 0x00000000, 0x00000000); -} - -static void -nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc, - int link_nr, u32 link_bw, bool enhframe) -{ - const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - const u32 loff = (or * 0x800) + (link * 0x80); - const u32 soff = (or * 0x800); - u32 dpctrl = nv_rd32(dev, 0x61c10c + loff) & ~0x001f4000; - u32 clksor = nv_rd32(dev, 0x612300 + soff) & ~0x007c0000; - u32 script = 0x0000, lane_mask = 0; - u8 *table, *entry; - int i; - - link_bw /= 27000; - - table = nouveau_dp_bios_data(dev, dcb, &entry); - if (table) { - if (table[0] == 0x30) entry = ROMPTR(dev, entry[10]); - else if (table[0] == 0x40) entry = ROMPTR(dev, entry[9]); - else entry = NULL; - - while (entry) { - if (entry[0] >= link_bw) - break; - entry += 3; - } - - nouveau_bios_run_init_table(dev, script, dcb, crtc); - } - - clksor |= link_bw << 18; - dpctrl |= ((1 << link_nr) - 1) << 16; - if (enhframe) - dpctrl |= 0x00004000; - - for (i = 0; i < link_nr; i++) - lane_mask |= 1 << (nvd0_sor_dp_lane_map(dev, dcb, i) >> 3); - - nv_wr32(dev, 0x612300 + soff, clksor); - nv_wr32(dev, 0x61c10c + loff, dpctrl); - nv_mask(dev, 0x61c130 + loff, 0x0000000f, lane_mask); -} - -static void -nvd0_sor_dp_link_get(struct drm_device *dev, struct dcb_entry *dcb, - u32 *link_nr, u32 *link_bw) -{ - const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); - const u32 loff = (or * 0x800) + (link * 0x80); - const u32 soff = (or * 0x800); - u32 dpctrl = nv_rd32(dev, 0x61c10c + loff) & 0x000f0000; - u32 clksor = nv_rd32(dev, 0x612300 + soff); - - if (dpctrl > 0x00030000) *link_nr = 4; - else if (dpctrl > 0x00010000) *link_nr = 2; - else *link_nr = 1; - - *link_bw = (clksor & 0x007c0000) >> 18; - *link_bw *= 27000; -} - -static void -nvd0_sor_dp_calc_tu(struct drm_device *dev, struct dcb_entry *dcb, - u32 crtc, u32 datarate) -{ - const u32 symbol = 100000; - const u32 TU = 64; - u32 link_nr, link_bw; - u64 ratio, value; - - nvd0_sor_dp_link_get(dev, dcb, &link_nr, &link_bw); - - ratio = datarate; - ratio *= symbol; - do_div(ratio, link_nr * link_bw); - - value = (symbol - ratio) * TU; - value *= ratio; - do_div(value, symbol); - do_div(value, symbol); - - value += 5; - value |= 0x08000000; - - nv_wr32(dev, 0x616610 + (crtc * 0x800), value); -} - -static void -nvd0_sor_dpms(struct drm_encoder *encoder, int mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct drm_encoder *partner; - int or = nv_encoder->or; - u32 dpms_ctrl; - - nv_encoder->last_dpms = mode; - - list_for_each_entry(partner, &dev->mode_config.encoder_list, head) { - struct nouveau_encoder *nv_partner = nouveau_encoder(partner); - - if (partner->encoder_type != DRM_MODE_ENCODER_TMDS) - continue; - - if (nv_partner != nv_encoder && - nv_partner->dcb->or == nv_encoder->dcb->or) { - if (nv_partner->last_dpms == DRM_MODE_DPMS_ON) - return; - break; - } - } - - dpms_ctrl = (mode == DRM_MODE_DPMS_ON); - dpms_ctrl |= 0x80000000; - - nv_wait(dev, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000); - nv_mask(dev, 0x61c004 + (or * 0x0800), 0x80000001, dpms_ctrl); - nv_wait(dev, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000); - nv_wait(dev, 0x61c030 + (or * 0x0800), 0x10000000, 0x00000000); - - if (nv_encoder->dcb->type == OUTPUT_DP) { - struct dp_train_func func = { - .link_set = nvd0_sor_dp_link_set, - .train_set = nvd0_sor_dp_train_set, - .train_adj = nvd0_sor_dp_train_adj - }; - - nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func); - } -} - -static bool -nvd0_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_connector *nv_connector; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - if (nv_connector && nv_connector->native_mode) { - if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) { - int id = adjusted_mode->base.id; - *adjusted_mode = *nv_connector->native_mode; - adjusted_mode->base.id = id; - } - } - - return true; -} - -static void -nvd0_sor_disconnect(struct drm_encoder *encoder) -{ - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; - u32 *push; - - if (nv_encoder->crtc) { - nvd0_crtc_prepare(nv_encoder->crtc); - - push = evo_wait(dev, EVO_MASTER, 4); - if (push) { - evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0080, 1); - evo_data(push, 0x00000000); - evo_kick(push, dev, EVO_MASTER); - } - - nvd0_hdmi_disconnect(encoder); - - nv_encoder->crtc = NULL; - nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; - } -} - -static void -nvd0_sor_prepare(struct drm_encoder *encoder) -{ - nvd0_sor_disconnect(encoder); - if (nouveau_encoder(encoder)->dcb->type == OUTPUT_DP) - evo_sync(encoder->dev, EVO_MASTER); -} - -static void -nvd0_sor_commit(struct drm_encoder *encoder) -{ -} - -static void -nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, - struct drm_display_mode *mode) -{ - struct drm_device *dev = encoder->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); - struct nouveau_connector *nv_connector; - struct nvbios *bios = &dev_priv->vbios; - u32 mode_ctrl = (1 << nv_crtc->index); - u32 syncs, magic, *push; - u32 or_config; - - syncs = 0x00000001; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - syncs |= 0x00000008; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - syncs |= 0x00000010; - - magic = 0x31ec6000 | (nv_crtc->index << 25); - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - magic |= 0x00000001; - - nv_connector = nouveau_encoder_connector_get(nv_encoder); - switch (nv_encoder->dcb->type) { - case OUTPUT_TMDS: - if (nv_encoder->dcb->sorconf.link & 1) { - if (mode->clock < 165000) - mode_ctrl |= 0x00000100; - else - mode_ctrl |= 0x00000500; - } else { - mode_ctrl |= 0x00000200; - } - - or_config = (mode_ctrl & 0x00000f00) >> 8; - if (mode->clock >= 165000) - or_config |= 0x0100; - - nvd0_hdmi_mode_set(encoder, mode); - break; - case OUTPUT_LVDS: - or_config = (mode_ctrl & 0x00000f00) >> 8; - if (bios->fp_no_ddc) { - if (bios->fp.dual_link) - or_config |= 0x0100; - if (bios->fp.if_is_24bit) - or_config |= 0x0200; - } else { - if (nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) { - if (((u8 *)nv_connector->edid)[121] == 2) - or_config |= 0x0100; - } else - if (mode->clock >= bios->fp.duallink_transition_clk) { - or_config |= 0x0100; - } - - if (or_config & 0x0100) { - if (bios->fp.strapless_is_24bit & 2) - or_config |= 0x0200; - } else { - if (bios->fp.strapless_is_24bit & 1) - or_config |= 0x0200; - } - - if (nv_connector->base.display_info.bpc == 8) - or_config |= 0x0200; - - } - break; - case OUTPUT_DP: - if (nv_connector->base.display_info.bpc == 6) { - nv_encoder->dp.datarate = mode->clock * 18 / 8; - syncs |= 0x00000140; - } else { - nv_encoder->dp.datarate = mode->clock * 24 / 8; - syncs |= 0x00000180; - } - - if (nv_encoder->dcb->sorconf.link & 1) - mode_ctrl |= 0x00000800; - else - mode_ctrl |= 0x00000900; - - or_config = (mode_ctrl & 0x00000f00) >> 8; - break; - default: - BUG_ON(1); - break; - } - - nvd0_sor_dpms(encoder, DRM_MODE_DPMS_ON); - - if (nv_encoder->dcb->type == OUTPUT_DP) { - nvd0_sor_dp_calc_tu(dev, nv_encoder->dcb, nv_crtc->index, - nv_encoder->dp.datarate); - } - - push = evo_wait(dev, EVO_MASTER, 8); - if (push) { - evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); - evo_data(push, syncs); - evo_data(push, magic); - evo_mthd(push, 0x0200 + (nv_encoder->or * 0x020), 2); - evo_data(push, mode_ctrl); - evo_data(push, or_config); - evo_kick(push, dev, EVO_MASTER); - } - - nv_encoder->crtc = encoder->crtc; -} - -static void -nvd0_sor_destroy(struct drm_encoder *encoder) -{ - drm_encoder_cleanup(encoder); - kfree(encoder); -} - -static const struct drm_encoder_helper_funcs nvd0_sor_hfunc = { - .dpms = nvd0_sor_dpms, - .mode_fixup = nvd0_sor_mode_fixup, - .prepare = nvd0_sor_prepare, - .commit = nvd0_sor_commit, - .mode_set = nvd0_sor_mode_set, - .disable = nvd0_sor_disconnect, - .get_crtc = nvd0_display_crtc_get, -}; - -static const struct drm_encoder_funcs nvd0_sor_func = { - .destroy = nvd0_sor_destroy, -}; - -static int -nvd0_sor_create(struct drm_connector *connector, struct dcb_entry *dcbe) -{ - struct drm_device *dev = connector->dev; - struct nouveau_encoder *nv_encoder; - struct drm_encoder *encoder; - - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); - if (!nv_encoder) - return -ENOMEM; - nv_encoder->dcb = dcbe; - nv_encoder->or = ffs(dcbe->or) - 1; - nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; - - encoder = to_drm_encoder(nv_encoder); - encoder->possible_crtcs = dcbe->heads; - encoder->possible_clones = 0; - drm_encoder_init(dev, encoder, &nvd0_sor_func, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(encoder, &nvd0_sor_hfunc); - - drm_mode_connector_attach_encoder(connector, encoder); - return 0; -} - -/****************************************************************************** - * IRQ - *****************************************************************************/ -static struct dcb_entry * -lookup_dcb(struct drm_device *dev, int id, u32 mc) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int type, or, i, link = -1; - - if (id < 4) { - type = OUTPUT_ANALOG; - or = id; - } else { - switch (mc & 0x00000f00) { - case 0x00000000: link = 0; type = OUTPUT_LVDS; break; - case 0x00000100: link = 0; type = OUTPUT_TMDS; break; - case 0x00000200: link = 1; type = OUTPUT_TMDS; break; - case 0x00000500: link = 0; type = OUTPUT_TMDS; break; - case 0x00000800: link = 0; type = OUTPUT_DP; break; - case 0x00000900: link = 1; type = OUTPUT_DP; break; - default: - NV_ERROR(dev, "PDISP: unknown SOR mc 0x%08x\n", mc); - return NULL; - } - - or = id - 4; - } - - for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { - struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; - if (dcb->type == type && (dcb->or & (1 << or)) && - (link < 0 || link == !(dcb->sorconf.link & 1))) - return dcb; - } - - NV_ERROR(dev, "PDISP: DCB for %d/0x%08x not found\n", id, mc); - return NULL; -} - -static void -nvd0_display_unk1_handler(struct drm_device *dev, u32 crtc, u32 mask) -{ - struct dcb_entry *dcb; - int i; - - for (i = 0; mask && i < 8; i++) { - u32 mcc = nv_rd32(dev, 0x640180 + (i * 0x20)); - if (!(mcc & (1 << crtc))) - continue; - - dcb = lookup_dcb(dev, i, mcc); - if (!dcb) - continue; - - nouveau_bios_run_display_table(dev, 0x0000, -1, dcb, crtc); - } - - nv_wr32(dev, 0x6101d4, 0x00000000); - nv_wr32(dev, 0x6109d4, 0x00000000); - nv_wr32(dev, 0x6101d0, 0x80000000); -} - -static void -nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask) -{ - struct dcb_entry *dcb; - u32 or, tmp, pclk; - int i; - - for (i = 0; mask && i < 8; i++) { - u32 mcc = nv_rd32(dev, 0x640180 + (i * 0x20)); - if (!(mcc & (1 << crtc))) - continue; - - dcb = lookup_dcb(dev, i, mcc); - if (!dcb) - continue; - - nouveau_bios_run_display_table(dev, 0x0000, -2, dcb, crtc); - } - - pclk = nv_rd32(dev, 0x660450 + (crtc * 0x300)) / 1000; - NV_DEBUG_KMS(dev, "PDISP: crtc %d pclk %d mask 0x%08x\n", - crtc, pclk, mask); - if (pclk && (mask & 0x00010000)) { - nv50_crtc_set_clock(dev, crtc, pclk); - } - - for (i = 0; mask && i < 8; i++) { - u32 mcp = nv_rd32(dev, 0x660180 + (i * 0x20)); - u32 cfg = nv_rd32(dev, 0x660184 + (i * 0x20)); - if (!(mcp & (1 << crtc))) - continue; - - dcb = lookup_dcb(dev, i, mcp); - if (!dcb) - continue; - or = ffs(dcb->or) - 1; - - nouveau_bios_run_display_table(dev, cfg, pclk, dcb, crtc); - - nv_wr32(dev, 0x612200 + (crtc * 0x800), 0x00000000); - switch (dcb->type) { - case OUTPUT_ANALOG: - nv_wr32(dev, 0x612280 + (or * 0x800), 0x00000000); - break; - case OUTPUT_TMDS: - case OUTPUT_LVDS: - case OUTPUT_DP: - if (cfg & 0x00000100) - tmp = 0x00000101; - else - tmp = 0x00000000; - - nv_mask(dev, 0x612300 + (or * 0x800), 0x00000707, tmp); - break; - default: - break; - } - - break; - } - - nv_wr32(dev, 0x6101d4, 0x00000000); - nv_wr32(dev, 0x6109d4, 0x00000000); - nv_wr32(dev, 0x6101d0, 0x80000000); -} - -static void -nvd0_display_unk4_handler(struct drm_device *dev, u32 crtc, u32 mask) -{ - struct dcb_entry *dcb; - int pclk, i; - - pclk = nv_rd32(dev, 0x660450 + (crtc * 0x300)) / 1000; - - for (i = 0; mask && i < 8; i++) { - u32 mcp = nv_rd32(dev, 0x660180 + (i * 0x20)); - u32 cfg = nv_rd32(dev, 0x660184 + (i * 0x20)); - if (!(mcp & (1 << crtc))) - continue; - - dcb = lookup_dcb(dev, i, mcp); - if (!dcb) - continue; - - nouveau_bios_run_display_table(dev, cfg, -pclk, dcb, crtc); - } - - nv_wr32(dev, 0x6101d4, 0x00000000); - nv_wr32(dev, 0x6109d4, 0x00000000); - nv_wr32(dev, 0x6101d0, 0x80000000); -} - -static void -nvd0_display_bh(unsigned long data) -{ - struct drm_device *dev = (struct drm_device *)data; - struct nvd0_display *disp = nvd0_display(dev); - u32 mask = 0, crtc = ~0; - int i; - - if (drm_debug & (DRM_UT_DRIVER | DRM_UT_KMS)) { - NV_INFO(dev, "PDISP: modeset req %d\n", disp->modeset); - NV_INFO(dev, " STAT: 0x%08x 0x%08x 0x%08x\n", - nv_rd32(dev, 0x6101d0), - nv_rd32(dev, 0x6101d4), nv_rd32(dev, 0x6109d4)); - for (i = 0; i < 8; i++) { - NV_INFO(dev, " %s%d: 0x%08x 0x%08x\n", - i < 4 ? "DAC" : "SOR", i, - nv_rd32(dev, 0x640180 + (i * 0x20)), - nv_rd32(dev, 0x660180 + (i * 0x20))); - } - } - - while (!mask && ++crtc < dev->mode_config.num_crtc) - mask = nv_rd32(dev, 0x6101d4 + (crtc * 0x800)); - - if (disp->modeset & 0x00000001) - nvd0_display_unk1_handler(dev, crtc, mask); - if (disp->modeset & 0x00000002) - nvd0_display_unk2_handler(dev, crtc, mask); - if (disp->modeset & 0x00000004) - nvd0_display_unk4_handler(dev, crtc, mask); -} - -static void -nvd0_display_intr(struct drm_device *dev) -{ - struct nvd0_display *disp = nvd0_display(dev); - u32 intr = nv_rd32(dev, 0x610088); - int i; - - if (intr & 0x00000001) { - u32 stat = nv_rd32(dev, 0x61008c); - nv_wr32(dev, 0x61008c, stat); - intr &= ~0x00000001; - } - - if (intr & 0x00000002) { - u32 stat = nv_rd32(dev, 0x61009c); - int chid = ffs(stat) - 1; - if (chid >= 0) { - u32 mthd = nv_rd32(dev, 0x6101f0 + (chid * 12)); - u32 data = nv_rd32(dev, 0x6101f4 + (chid * 12)); - u32 unkn = nv_rd32(dev, 0x6101f8 + (chid * 12)); - - NV_INFO(dev, "EvoCh: chid %d mthd 0x%04x data 0x%08x " - "0x%08x 0x%08x\n", - chid, (mthd & 0x0000ffc), data, mthd, unkn); - nv_wr32(dev, 0x61009c, (1 << chid)); - nv_wr32(dev, 0x6101f0 + (chid * 12), 0x90000000); - } - - intr &= ~0x00000002; - } - - if (intr & 0x00100000) { - u32 stat = nv_rd32(dev, 0x6100ac); - - if (stat & 0x00000007) { - disp->modeset = stat; - tasklet_schedule(&disp->tasklet); - - nv_wr32(dev, 0x6100ac, (stat & 0x00000007)); - stat &= ~0x00000007; - } - - if (stat) { - NV_INFO(dev, "PDISP: unknown intr24 0x%08x\n", stat); - nv_wr32(dev, 0x6100ac, stat); - } - - intr &= ~0x00100000; - } - - for (i = 0; i < dev->mode_config.num_crtc; i++) { - u32 mask = 0x01000000 << i; - if (intr & mask) { - u32 stat = nv_rd32(dev, 0x6100bc + (i * 0x800)); - nv_wr32(dev, 0x6100bc + (i * 0x800), stat); - intr &= ~mask; - } - } - - if (intr) - NV_INFO(dev, "PDISP: unknown intr 0x%08x\n", intr); -} - -/****************************************************************************** - * Init - *****************************************************************************/ -void -nvd0_display_fini(struct drm_device *dev) -{ - int i; - - /* fini cursors + overlays + flips */ - for (i = 1; i >= 0; i--) { - evo_fini_pio(dev, EVO_CURS(i)); - evo_fini_pio(dev, EVO_OIMM(i)); - evo_fini_dma(dev, EVO_OVLY(i)); - evo_fini_dma(dev, EVO_FLIP(i)); - } - - /* fini master */ - evo_fini_dma(dev, EVO_MASTER); -} - -int -nvd0_display_init(struct drm_device *dev) -{ - struct nvd0_display *disp = nvd0_display(dev); - int ret, i; - u32 *push; - - if (nv_rd32(dev, 0x6100ac) & 0x00000100) { - nv_wr32(dev, 0x6100ac, 0x00000100); - nv_mask(dev, 0x6194e8, 0x00000001, 0x00000000); - if (!nv_wait(dev, 0x6194e8, 0x00000002, 0x00000000)) { - NV_ERROR(dev, "PDISP: 0x6194e8 0x%08x\n", - nv_rd32(dev, 0x6194e8)); - return -EBUSY; - } - } - - /* nfi what these are exactly, i do know that SOR_MODE_CTRL won't - * work at all unless you do the SOR part below. - */ - for (i = 0; i < 3; i++) { - u32 dac = nv_rd32(dev, 0x61a000 + (i * 0x800)); - nv_wr32(dev, 0x6101c0 + (i * 0x800), dac); - } - - for (i = 0; i < 4; i++) { - u32 sor = nv_rd32(dev, 0x61c000 + (i * 0x800)); - nv_wr32(dev, 0x6301c4 + (i * 0x800), sor); - } - - for (i = 0; i < dev->mode_config.num_crtc; i++) { - u32 crtc0 = nv_rd32(dev, 0x616104 + (i * 0x800)); - u32 crtc1 = nv_rd32(dev, 0x616108 + (i * 0x800)); - u32 crtc2 = nv_rd32(dev, 0x61610c + (i * 0x800)); - nv_wr32(dev, 0x6101b4 + (i * 0x800), crtc0); - nv_wr32(dev, 0x6101b8 + (i * 0x800), crtc1); - nv_wr32(dev, 0x6101bc + (i * 0x800), crtc2); - } - - /* point at our hash table / objects, enable interrupts */ - nv_wr32(dev, 0x610010, (disp->mem->vinst >> 8) | 9); - nv_mask(dev, 0x6100b0, 0x00000307, 0x00000307); - - /* init master */ - ret = evo_init_dma(dev, EVO_MASTER); - if (ret) - goto error; - - /* init flips + overlays + cursors */ - for (i = 0; i < dev->mode_config.num_crtc; i++) { - if ((ret = evo_init_dma(dev, EVO_FLIP(i))) || - (ret = evo_init_dma(dev, EVO_OVLY(i))) || - (ret = evo_init_pio(dev, EVO_OIMM(i))) || - (ret = evo_init_pio(dev, EVO_CURS(i)))) - goto error; - } - - push = evo_wait(dev, EVO_MASTER, 32); - if (!push) { - ret = -EBUSY; - goto error; - } - evo_mthd(push, 0x0088, 1); - evo_data(push, NvEvoSync); - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x00000000); - evo_mthd(push, 0x0084, 1); - evo_data(push, 0x80000000); - evo_mthd(push, 0x008c, 1); - evo_data(push, 0x00000000); - evo_kick(push, dev, EVO_MASTER); - -error: - if (ret) - nvd0_display_fini(dev); - return ret; -} - -void -nvd0_display_destroy(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvd0_display *disp = nvd0_display(dev); - struct pci_dev *pdev = dev->pdev; - int i; - - for (i = 0; i < EVO_DMA_NR; i++) { - struct evo *evo = &disp->evo[i]; - pci_free_consistent(pdev, PAGE_SIZE, evo->ptr, evo->handle); - } - - nouveau_gpuobj_ref(NULL, &disp->mem); - nouveau_bo_unmap(disp->sync); - nouveau_bo_ref(NULL, &disp->sync); - nouveau_irq_unregister(dev, 26); - - dev_priv->engine.display.priv = NULL; - kfree(disp); -} - -int -nvd0_display_create(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; - struct dcb_table *dcb = &dev_priv->vbios.dcb; - struct drm_connector *connector, *tmp; - struct pci_dev *pdev = dev->pdev; - struct nvd0_display *disp; - struct dcb_entry *dcbe; - int crtcs, ret, i; - - disp = kzalloc(sizeof(*disp), GFP_KERNEL); - if (!disp) - return -ENOMEM; - dev_priv->engine.display.priv = disp; - - /* create crtc objects to represent the hw heads */ - crtcs = nv_rd32(dev, 0x022448); - for (i = 0; i < crtcs; i++) { - ret = nvd0_crtc_create(dev, i); - if (ret) - goto out; - } - - /* create encoder/connector objects based on VBIOS DCB table */ - for (i = 0, dcbe = &dcb->entry[0]; i < dcb->entries; i++, dcbe++) { - connector = nouveau_connector_create(dev, dcbe->connector); - if (IS_ERR(connector)) - continue; - - if (dcbe->location != DCB_LOC_ON_CHIP) { - NV_WARN(dev, "skipping off-chip encoder %d/%d\n", - dcbe->type, ffs(dcbe->or) - 1); - continue; - } - - switch (dcbe->type) { - case OUTPUT_TMDS: - case OUTPUT_LVDS: - case OUTPUT_DP: - nvd0_sor_create(connector, dcbe); - break; - case OUTPUT_ANALOG: - nvd0_dac_create(connector, dcbe); - break; - default: - NV_WARN(dev, "skipping unsupported encoder %d/%d\n", - dcbe->type, ffs(dcbe->or) - 1); - continue; - } - } - - /* cull any connectors we created that don't have an encoder */ - list_for_each_entry_safe(connector, tmp, &dev->mode_config.connector_list, head) { - if (connector->encoder_ids[0]) - continue; - - NV_WARN(dev, "%s has no encoders, removing\n", - drm_get_connector_name(connector)); - connector->funcs->destroy(connector); - } - - /* setup interrupt handling */ - tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev); - nouveau_irq_register(dev, 26, nvd0_display_intr); - - /* small shared memory area we use for notifiers and semaphores */ - ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, - 0, 0x0000, &disp->sync); - if (!ret) { - ret = nouveau_bo_pin(disp->sync, TTM_PL_FLAG_VRAM); - if (!ret) - ret = nouveau_bo_map(disp->sync); - if (ret) - nouveau_bo_ref(NULL, &disp->sync); - } - - if (ret) - goto out; - - /* hash table and dma objects for the memory areas we care about */ - ret = nouveau_gpuobj_new(dev, NULL, 0x4000, 0x10000, - NVOBJ_FLAG_ZERO_ALLOC, &disp->mem); - if (ret) - goto out; - - /* create evo dma channels */ - for (i = 0; i < EVO_DMA_NR; i++) { - struct evo *evo = &disp->evo[i]; - u64 offset = disp->sync->bo.offset; - u32 dmao = 0x1000 + (i * 0x100); - u32 hash = 0x0000 + (i * 0x040); - - evo->idx = i; - evo->sem.offset = EVO_SYNC(evo->idx, 0x00); - evo->ptr = pci_alloc_consistent(pdev, PAGE_SIZE, &evo->handle); - if (!evo->ptr) { - ret = -ENOMEM; - goto out; - } - - nv_wo32(disp->mem, dmao + 0x00, 0x00000049); - nv_wo32(disp->mem, dmao + 0x04, (offset + 0x0000) >> 8); - nv_wo32(disp->mem, dmao + 0x08, (offset + 0x0fff) >> 8); - nv_wo32(disp->mem, dmao + 0x0c, 0x00000000); - nv_wo32(disp->mem, dmao + 0x10, 0x00000000); - nv_wo32(disp->mem, dmao + 0x14, 0x00000000); - nv_wo32(disp->mem, hash + 0x00, NvEvoSync); - nv_wo32(disp->mem, hash + 0x04, 0x00000001 | (i << 27) | - ((dmao + 0x00) << 9)); - - nv_wo32(disp->mem, dmao + 0x20, 0x00000049); - nv_wo32(disp->mem, dmao + 0x24, 0x00000000); - nv_wo32(disp->mem, dmao + 0x28, (dev_priv->vram_size - 1) >> 8); - nv_wo32(disp->mem, dmao + 0x2c, 0x00000000); - nv_wo32(disp->mem, dmao + 0x30, 0x00000000); - nv_wo32(disp->mem, dmao + 0x34, 0x00000000); - nv_wo32(disp->mem, hash + 0x08, NvEvoVRAM); - nv_wo32(disp->mem, hash + 0x0c, 0x00000001 | (i << 27) | - ((dmao + 0x20) << 9)); - - nv_wo32(disp->mem, dmao + 0x40, 0x00000009); - nv_wo32(disp->mem, dmao + 0x44, 0x00000000); - nv_wo32(disp->mem, dmao + 0x48, (dev_priv->vram_size - 1) >> 8); - nv_wo32(disp->mem, dmao + 0x4c, 0x00000000); - nv_wo32(disp->mem, dmao + 0x50, 0x00000000); - nv_wo32(disp->mem, dmao + 0x54, 0x00000000); - nv_wo32(disp->mem, hash + 0x10, NvEvoVRAM_LP); - nv_wo32(disp->mem, hash + 0x14, 0x00000001 | (i << 27) | - ((dmao + 0x40) << 9)); - - nv_wo32(disp->mem, dmao + 0x60, 0x0fe00009); - nv_wo32(disp->mem, dmao + 0x64, 0x00000000); - nv_wo32(disp->mem, dmao + 0x68, (dev_priv->vram_size - 1) >> 8); - nv_wo32(disp->mem, dmao + 0x6c, 0x00000000); - nv_wo32(disp->mem, dmao + 0x70, 0x00000000); - nv_wo32(disp->mem, dmao + 0x74, 0x00000000); - nv_wo32(disp->mem, hash + 0x18, NvEvoFB32); - nv_wo32(disp->mem, hash + 0x1c, 0x00000001 | (i << 27) | - ((dmao + 0x60) << 9)); - } - - pinstmem->flush(dev); - -out: - if (ret) - nvd0_display_destroy(dev); - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvreg.h b/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvreg.h deleted file mode 100644 index bbfb1a68..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/nouveau/nvreg.h +++ /dev/null @@ -1,517 +0,0 @@ -/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */ -/* - * Copyright 1996-1997 David J. McKay - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h,v 1.6 2002/01/25 21:56:06 tsi Exp $ */ - -#ifndef __NVREG_H_ -#define __NVREG_H_ - -#define NV_PMC_OFFSET 0x00000000 -#define NV_PMC_SIZE 0x00001000 - -#define NV_PBUS_OFFSET 0x00001000 -#define NV_PBUS_SIZE 0x00001000 - -#define NV_PFIFO_OFFSET 0x00002000 -#define NV_PFIFO_SIZE 0x00002000 - -#define NV_HDIAG_OFFSET 0x00005000 -#define NV_HDIAG_SIZE 0x00001000 - -#define NV_PRAM_OFFSET 0x00006000 -#define NV_PRAM_SIZE 0x00001000 - -#define NV_PVIDEO_OFFSET 0x00008000 -#define NV_PVIDEO_SIZE 0x00001000 - -#define NV_PTIMER_OFFSET 0x00009000 -#define NV_PTIMER_SIZE 0x00001000 - -#define NV_PPM_OFFSET 0x0000A000 -#define NV_PPM_SIZE 0x00001000 - -#define NV_PTV_OFFSET 0x0000D000 -#define NV_PTV_SIZE 0x00001000 - -#define NV_PRMVGA_OFFSET 0x000A0000 -#define NV_PRMVGA_SIZE 0x00020000 - -#define NV_PRMVIO0_OFFSET 0x000C0000 -#define NV_PRMVIO_SIZE 0x00002000 -#define NV_PRMVIO1_OFFSET 0x000C2000 - -#define NV_PFB_OFFSET 0x00100000 -#define NV_PFB_SIZE 0x00001000 - -#define NV_PEXTDEV_OFFSET 0x00101000 -#define NV_PEXTDEV_SIZE 0x00001000 - -#define NV_PME_OFFSET 0x00200000 -#define NV_PME_SIZE 0x00001000 - -#define NV_PROM_OFFSET 0x00300000 -#define NV_PROM_SIZE 0x00010000 - -#define NV_PGRAPH_OFFSET 0x00400000 -#define NV_PGRAPH_SIZE 0x00010000 - -#define NV_PCRTC0_OFFSET 0x00600000 -#define NV_PCRTC0_SIZE 0x00002000 /* empirical */ - -#define NV_PRMCIO0_OFFSET 0x00601000 -#define NV_PRMCIO_SIZE 0x00002000 -#define NV_PRMCIO1_OFFSET 0x00603000 - -#define NV50_DISPLAY_OFFSET 0x00610000 -#define NV50_DISPLAY_SIZE 0x0000FFFF - -#define NV_PRAMDAC0_OFFSET 0x00680000 -#define NV_PRAMDAC0_SIZE 0x00002000 - -#define NV_PRMDIO0_OFFSET 0x00681000 -#define NV_PRMDIO_SIZE 0x00002000 -#define NV_PRMDIO1_OFFSET 0x00683000 - -#define NV_PRAMIN_OFFSET 0x00700000 -#define NV_PRAMIN_SIZE 0x00100000 - -#define NV_FIFO_OFFSET 0x00800000 -#define NV_FIFO_SIZE 0x00800000 - -#define NV_PMC_BOOT_0 0x00000000 -#define NV_PMC_ENABLE 0x00000200 - -#define NV_VIO_VSE2 0x000003c3 -#define NV_VIO_SRX 0x000003c4 - -#define NV_CIO_CRX__COLOR 0x000003d4 -#define NV_CIO_CR__COLOR 0x000003d5 - -#define NV_PBUS_DEBUG_1 0x00001084 -#define NV_PBUS_DEBUG_4 0x00001098 -#define NV_PBUS_DEBUG_DUALHEAD_CTL 0x000010f0 -#define NV_PBUS_POWERCTRL_1 0x00001584 -#define NV_PBUS_POWERCTRL_2 0x00001588 -#define NV_PBUS_POWERCTRL_4 0x00001590 -#define NV_PBUS_PCI_NV_19 0x0000184C -#define NV_PBUS_PCI_NV_20 0x00001850 -# define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED (0 << 0) -# define NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED (1 << 0) - -#define NV_PFIFO_RAMHT 0x00002210 - -#define NV_PTV_TV_INDEX 0x0000d220 -#define NV_PTV_TV_DATA 0x0000d224 -#define NV_PTV_HFILTER 0x0000d310 -#define NV_PTV_HFILTER2 0x0000d390 -#define NV_PTV_VFILTER 0x0000d510 - -#define NV_PRMVIO_MISC__WRITE 0x000c03c2 -#define NV_PRMVIO_SRX 0x000c03c4 -#define NV_PRMVIO_SR 0x000c03c5 -# define NV_VIO_SR_RESET_INDEX 0x00 -# define NV_VIO_SR_CLOCK_INDEX 0x01 -# define NV_VIO_SR_PLANE_MASK_INDEX 0x02 -# define NV_VIO_SR_CHAR_MAP_INDEX 0x03 -# define NV_VIO_SR_MEM_MODE_INDEX 0x04 -#define NV_PRMVIO_MISC__READ 0x000c03cc -#define NV_PRMVIO_GRX 0x000c03ce -#define NV_PRMVIO_GX 0x000c03cf -# define NV_VIO_GX_SR_INDEX 0x00 -# define NV_VIO_GX_SREN_INDEX 0x01 -# define NV_VIO_GX_CCOMP_INDEX 0x02 -# define NV_VIO_GX_ROP_INDEX 0x03 -# define NV_VIO_GX_READ_MAP_INDEX 0x04 -# define NV_VIO_GX_MODE_INDEX 0x05 -# define NV_VIO_GX_MISC_INDEX 0x06 -# define NV_VIO_GX_DONT_CARE_INDEX 0x07 -# define NV_VIO_GX_BIT_MASK_INDEX 0x08 - -#define NV_PCRTC_INTR_0 0x00600100 -# define NV_PCRTC_INTR_0_VBLANK (1 << 0) -#define NV_PCRTC_INTR_EN_0 0x00600140 -#define NV_PCRTC_START 0x00600800 -#define NV_PCRTC_CONFIG 0x00600804 -# define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA (1 << 0) -# define NV04_PCRTC_CONFIG_START_ADDRESS_HSYNC (4 << 0) -# define NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC (2 << 0) -#define NV_PCRTC_CURSOR_CONFIG 0x00600810 -# define NV_PCRTC_CURSOR_CONFIG_ENABLE_ENABLE (1 << 0) -# define NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE (1 << 4) -# define NV_PCRTC_CURSOR_CONFIG_ADDRESS_SPACE_PNVM (1 << 8) -# define NV_PCRTC_CURSOR_CONFIG_CUR_BPP_32 (1 << 12) -# define NV_PCRTC_CURSOR_CONFIG_CUR_PIXELS_64 (1 << 16) -# define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_32 (2 << 24) -# define NV_PCRTC_CURSOR_CONFIG_CUR_LINES_64 (4 << 24) -# define NV_PCRTC_CURSOR_CONFIG_CUR_BLEND_ALPHA (1 << 28) - -/* note: PCRTC_GPIO is not available on nv10, and in fact aliases 0x600810 */ -#define NV_PCRTC_GPIO 0x00600818 -#define NV_PCRTC_GPIO_EXT 0x0060081c -#define NV_PCRTC_830 0x00600830 -#define NV_PCRTC_834 0x00600834 -#define NV_PCRTC_850 0x00600850 -#define NV_PCRTC_ENGINE_CTRL 0x00600860 -# define NV_CRTC_FSEL_I2C (1 << 4) -# define NV_CRTC_FSEL_OVERLAY (1 << 12) - -#define NV_PRMCIO_ARX 0x006013c0 -#define NV_PRMCIO_AR__WRITE 0x006013c0 -#define NV_PRMCIO_AR__READ 0x006013c1 -# define NV_CIO_AR_MODE_INDEX 0x10 -# define NV_CIO_AR_OSCAN_INDEX 0x11 -# define NV_CIO_AR_PLANE_INDEX 0x12 -# define NV_CIO_AR_HPP_INDEX 0x13 -# define NV_CIO_AR_CSEL_INDEX 0x14 -#define NV_PRMCIO_INP0 0x006013c2 -#define NV_PRMCIO_CRX__COLOR 0x006013d4 -#define NV_PRMCIO_CR__COLOR 0x006013d5 - /* Standard VGA CRTC registers */ -# define NV_CIO_CR_HDT_INDEX 0x00 /* horizontal display total */ -# define NV_CIO_CR_HDE_INDEX 0x01 /* horizontal display end */ -# define NV_CIO_CR_HBS_INDEX 0x02 /* horizontal blanking start */ -# define NV_CIO_CR_HBE_INDEX 0x03 /* horizontal blanking end */ -# define NV_CIO_CR_HBE_4_0 4:0 -# define NV_CIO_CR_HRS_INDEX 0x04 /* horizontal retrace start */ -# define NV_CIO_CR_HRE_INDEX 0x05 /* horizontal retrace end */ -# define NV_CIO_CR_HRE_4_0 4:0 -# define NV_CIO_CR_HRE_HBE_5 7:7 -# define NV_CIO_CR_VDT_INDEX 0x06 /* vertical display total */ -# define NV_CIO_CR_OVL_INDEX 0x07 /* overflow bits */ -# define NV_CIO_CR_OVL_VDT_8 0:0 -# define NV_CIO_CR_OVL_VDE_8 1:1 -# define NV_CIO_CR_OVL_VRS_8 2:2 -# define NV_CIO_CR_OVL_VBS_8 3:3 -# define NV_CIO_CR_OVL_VDT_9 5:5 -# define NV_CIO_CR_OVL_VDE_9 6:6 -# define NV_CIO_CR_OVL_VRS_9 7:7 -# define NV_CIO_CR_RSAL_INDEX 0x08 /* normally "preset row scan" */ -# define NV_CIO_CR_CELL_HT_INDEX 0x09 /* cell height?! normally "max scan line" */ -# define NV_CIO_CR_CELL_HT_VBS_9 5:5 -# define NV_CIO_CR_CELL_HT_SCANDBL 7:7 -# define NV_CIO_CR_CURS_ST_INDEX 0x0a /* cursor start */ -# define NV_CIO_CR_CURS_END_INDEX 0x0b /* cursor end */ -# define NV_CIO_CR_SA_HI_INDEX 0x0c /* screen start address high */ -# define NV_CIO_CR_SA_LO_INDEX 0x0d /* screen start address low */ -# define NV_CIO_CR_TCOFF_HI_INDEX 0x0e /* cursor offset high */ -# define NV_CIO_CR_TCOFF_LO_INDEX 0x0f /* cursor offset low */ -# define NV_CIO_CR_VRS_INDEX 0x10 /* vertical retrace start */ -# define NV_CIO_CR_VRE_INDEX 0x11 /* vertical retrace end */ -# define NV_CIO_CR_VRE_3_0 3:0 -# define NV_CIO_CR_VDE_INDEX 0x12 /* vertical display end */ -# define NV_CIO_CR_OFFSET_INDEX 0x13 /* sets screen pitch */ -# define NV_CIO_CR_ULINE_INDEX 0x14 /* underline location */ -# define NV_CIO_CR_VBS_INDEX 0x15 /* vertical blank start */ -# define NV_CIO_CR_VBE_INDEX 0x16 /* vertical blank end */ -# define NV_CIO_CR_MODE_INDEX 0x17 /* crtc mode control */ -# define NV_CIO_CR_LCOMP_INDEX 0x18 /* line compare */ - /* Extended VGA CRTC registers */ -# define NV_CIO_CRE_RPC0_INDEX 0x19 /* repaint control 0 */ -# define NV_CIO_CRE_RPC0_OFFSET_10_8 7:5 -# define NV_CIO_CRE_RPC1_INDEX 0x1a /* repaint control 1 */ -# define NV_CIO_CRE_RPC1_LARGE 2:2 -# define NV_CIO_CRE_FF_INDEX 0x1b /* fifo control */ -# define NV_CIO_CRE_ENH_INDEX 0x1c /* enhanced? */ -# define NV_CIO_SR_LOCK_INDEX 0x1f /* crtc lock */ -# define NV_CIO_SR_UNLOCK_RW_VALUE 0x57 -# define NV_CIO_SR_LOCK_VALUE 0x99 -# define NV_CIO_CRE_FFLWM__INDEX 0x20 /* fifo low water mark */ -# define NV_CIO_CRE_21 0x21 /* vga shadow crtc lock */ -# define NV_CIO_CRE_LSR_INDEX 0x25 /* ? */ -# define NV_CIO_CRE_LSR_VDT_10 0:0 -# define NV_CIO_CRE_LSR_VDE_10 1:1 -# define NV_CIO_CRE_LSR_VRS_10 2:2 -# define NV_CIO_CRE_LSR_VBS_10 3:3 -# define NV_CIO_CRE_LSR_HBE_6 4:4 -# define NV_CIO_CR_ARX_INDEX 0x26 /* attribute index -- ro copy of 0x60.3c0 */ -# define NV_CIO_CRE_CHIP_ID_INDEX 0x27 /* chip revision */ -# define NV_CIO_CRE_PIXEL_INDEX 0x28 -# define NV_CIO_CRE_PIXEL_FORMAT 1:0 -# define NV_CIO_CRE_HEB__INDEX 0x2d /* horizontal extra bits? */ -# define NV_CIO_CRE_HEB_HDT_8 0:0 -# define NV_CIO_CRE_HEB_HDE_8 1:1 -# define NV_CIO_CRE_HEB_HBS_8 2:2 -# define NV_CIO_CRE_HEB_HRS_8 3:3 -# define NV_CIO_CRE_HEB_ILC_8 4:4 -# define NV_CIO_CRE_2E 0x2e /* some scratch or dummy reg to force writes to sink in */ -# define NV_CIO_CRE_HCUR_ADDR2_INDEX 0x2f /* cursor */ -# define NV_CIO_CRE_HCUR_ADDR0_INDEX 0x30 /* pixmap */ -# define NV_CIO_CRE_HCUR_ADDR0_ADR 6:0 -# define NV_CIO_CRE_HCUR_ASI 7:7 -# define NV_CIO_CRE_HCUR_ADDR1_INDEX 0x31 /* address */ -# define NV_CIO_CRE_HCUR_ADDR1_ENABLE 0:0 -# define NV_CIO_CRE_HCUR_ADDR1_CUR_DBL 1:1 -# define NV_CIO_CRE_HCUR_ADDR1_ADR 7:2 -# define NV_CIO_CRE_LCD__INDEX 0x33 -# define NV_CIO_CRE_LCD_LCD_SELECT 0:0 -# define NV_CIO_CRE_LCD_ROUTE_MASK 0x3b -# define NV_CIO_CRE_DDC0_STATUS__INDEX 0x36 -# define NV_CIO_CRE_DDC0_WR__INDEX 0x37 -# define NV_CIO_CRE_ILACE__INDEX 0x39 /* interlace */ -# define NV_CIO_CRE_SCRATCH3__INDEX 0x3b -# define NV_CIO_CRE_SCRATCH4__INDEX 0x3c -# define NV_CIO_CRE_DDC_STATUS__INDEX 0x3e -# define NV_CIO_CRE_DDC_WR__INDEX 0x3f -# define NV_CIO_CRE_EBR_INDEX 0x41 /* extra bits ? (vertical) */ -# define NV_CIO_CRE_EBR_VDT_11 0:0 -# define NV_CIO_CRE_EBR_VDE_11 2:2 -# define NV_CIO_CRE_EBR_VRS_11 4:4 -# define NV_CIO_CRE_EBR_VBS_11 6:6 -# define NV_CIO_CRE_42 0x42 -# define NV_CIO_CRE_42_OFFSET_11 6:6 -# define NV_CIO_CRE_43 0x43 -# define NV_CIO_CRE_44 0x44 /* head control */ -# define NV_CIO_CRE_CSB 0x45 /* colour saturation boost */ -# define NV_CIO_CRE_RCR 0x46 -# define NV_CIO_CRE_RCR_ENDIAN_BIG 7:7 -# define NV_CIO_CRE_47 0x47 /* extended fifo lwm, used on nv30+ */ -# define NV_CIO_CRE_49 0x49 -# define NV_CIO_CRE_4B 0x4b /* given patterns in 0x[2-3][a-c] regs, probably scratch 6 */ -# define NV_CIO_CRE_TVOUT_LATENCY 0x52 -# define NV_CIO_CRE_53 0x53 /* `fp_htiming' according to Haiku */ -# define NV_CIO_CRE_54 0x54 /* `fp_vtiming' according to Haiku */ -# define NV_CIO_CRE_57 0x57 /* index reg for cr58 */ -# define NV_CIO_CRE_58 0x58 /* data reg for cr57 */ -# define NV_CIO_CRE_59 0x59 /* related to on/off-chip-ness of digital outputs */ -# define NV_CIO_CRE_5B 0x5B /* newer colour saturation reg */ -# define NV_CIO_CRE_85 0x85 -# define NV_CIO_CRE_86 0x86 -#define NV_PRMCIO_INP0__COLOR 0x006013da - -#define NV_PRAMDAC_CU_START_POS 0x00680300 -# define NV_PRAMDAC_CU_START_POS_X 15:0 -# define NV_PRAMDAC_CU_START_POS_Y 31:16 -#define NV_RAMDAC_NV10_CURSYNC 0x00680404 - -#define NV_PRAMDAC_NVPLL_COEFF 0x00680500 -#define NV_PRAMDAC_MPLL_COEFF 0x00680504 -#define NV_PRAMDAC_VPLL_COEFF 0x00680508 -# define NV30_RAMDAC_ENABLE_VCO2 (8 << 4) - -#define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050c -# define NV_PRAMDAC_PLL_COEFF_SELECT_USE_VPLL2_TRUE (4 << 0) -# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL (1 << 8) -# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL (2 << 8) -# define NV_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL (4 << 8) -# define NV_PRAMDAC_PLL_COEFF_SELECT_PLL_SOURCE_VPLL2 (8 << 8) -# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1 (1 << 16) -# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1 (2 << 16) -# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK2 (4 << 16) -# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK2 (8 << 16) -# define NV_PRAMDAC_PLL_COEFF_SELECT_TV_CLK_SOURCE_VIP (1 << 20) -# define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 (1 << 28) -# define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK2_RATIO_DB2 (2 << 28) - -#define NV_PRAMDAC_PLL_SETUP_CONTROL 0x00680510 -#define NV_RAMDAC_VPLL2 0x00680520 -#define NV_PRAMDAC_SEL_CLK 0x00680524 -#define NV_RAMDAC_DITHER_NV11 0x00680528 -#define NV_PRAMDAC_DACCLK 0x0068052c -# define NV_PRAMDAC_DACCLK_SEL_DACCLK (1 << 0) - -#define NV_RAMDAC_NVPLL_B 0x00680570 -#define NV_RAMDAC_MPLL_B 0x00680574 -#define NV_RAMDAC_VPLL_B 0x00680578 -#define NV_RAMDAC_VPLL2_B 0x0068057c -# define NV31_RAMDAC_ENABLE_VCO2 (8 << 28) -#define NV_PRAMDAC_580 0x00680580 -# define NV_RAMDAC_580_VPLL1_ACTIVE (1 << 8) -# define NV_RAMDAC_580_VPLL2_ACTIVE (1 << 28) - -#define NV_PRAMDAC_GENERAL_CONTROL 0x00680600 -# define NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON (3 << 4) -# define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL (1 << 8) -# define NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL (1 << 12) -# define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM (2 << 16) -# define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS (1 << 20) -# define NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG (2 << 28) -#define NV_PRAMDAC_TEST_CONTROL 0x00680608 -# define NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED (1 << 12) -# define NV_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF (1 << 16) -# define NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI (1 << 28) -#define NV_PRAMDAC_TESTPOINT_DATA 0x00680610 -# define NV_PRAMDAC_TESTPOINT_DATA_NOTBLANK (8 << 28) -#define NV_PRAMDAC_630 0x00680630 -#define NV_PRAMDAC_634 0x00680634 - -#define NV_PRAMDAC_TV_SETUP 0x00680700 -#define NV_PRAMDAC_TV_VTOTAL 0x00680720 -#define NV_PRAMDAC_TV_VSKEW 0x00680724 -#define NV_PRAMDAC_TV_VSYNC_DELAY 0x00680728 -#define NV_PRAMDAC_TV_HTOTAL 0x0068072c -#define NV_PRAMDAC_TV_HSKEW 0x00680730 -#define NV_PRAMDAC_TV_HSYNC_DELAY 0x00680734 -#define NV_PRAMDAC_TV_HSYNC_DELAY2 0x00680738 - -#define NV_PRAMDAC_TV_SETUP 0x00680700 - -#define NV_PRAMDAC_FP_VDISPLAY_END 0x00680800 -#define NV_PRAMDAC_FP_VTOTAL 0x00680804 -#define NV_PRAMDAC_FP_VCRTC 0x00680808 -#define NV_PRAMDAC_FP_VSYNC_START 0x0068080c -#define NV_PRAMDAC_FP_VSYNC_END 0x00680810 -#define NV_PRAMDAC_FP_VVALID_START 0x00680814 -#define NV_PRAMDAC_FP_VVALID_END 0x00680818 -#define NV_PRAMDAC_FP_HDISPLAY_END 0x00680820 -#define NV_PRAMDAC_FP_HTOTAL 0x00680824 -#define NV_PRAMDAC_FP_HCRTC 0x00680828 -#define NV_PRAMDAC_FP_HSYNC_START 0x0068082c -#define NV_PRAMDAC_FP_HSYNC_END 0x00680830 -#define NV_PRAMDAC_FP_HVALID_START 0x00680834 -#define NV_PRAMDAC_FP_HVALID_END 0x00680838 - -#define NV_RAMDAC_FP_DITHER 0x0068083c -#define NV_PRAMDAC_FP_TG_CONTROL 0x00680848 -# define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_POS (1 << 0) -# define NV_PRAMDAC_FP_TG_CONTROL_VSYNC_DISABLE (2 << 0) -# define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_POS (1 << 4) -# define NV_PRAMDAC_FP_TG_CONTROL_HSYNC_DISABLE (2 << 4) -# define NV_PRAMDAC_FP_TG_CONTROL_MODE_SCALE (0 << 8) -# define NV_PRAMDAC_FP_TG_CONTROL_MODE_CENTER (1 << 8) -# define NV_PRAMDAC_FP_TG_CONTROL_MODE_NATIVE (2 << 8) -# define NV_PRAMDAC_FP_TG_CONTROL_READ_PROG (1 << 20) -# define NV_PRAMDAC_FP_TG_CONTROL_WIDTH_12 (1 << 24) -# define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_POS (1 << 28) -# define NV_PRAMDAC_FP_TG_CONTROL_DISPEN_DISABLE (2 << 28) -#define NV_PRAMDAC_FP_MARGIN_COLOR 0x0068084c -#define NV_PRAMDAC_850 0x00680850 -#define NV_PRAMDAC_85C 0x0068085c -#define NV_PRAMDAC_FP_DEBUG_0 0x00680880 -# define NV_PRAMDAC_FP_DEBUG_0_XSCALE_ENABLE (1 << 0) -# define NV_PRAMDAC_FP_DEBUG_0_YSCALE_ENABLE (1 << 4) -/* This doesn't seem to be essential for tmds, but still often set */ -# define NV_RAMDAC_FP_DEBUG_0_TMDS_ENABLED (8 << 4) -# define NV_PRAMDAC_FP_DEBUG_0_XINTERP_BILINEAR (1 << 8) -# define NV_PRAMDAC_FP_DEBUG_0_YINTERP_BILINEAR (1 << 12) -# define NV_PRAMDAC_FP_DEBUG_0_XWEIGHT_ROUND (1 << 20) -# define NV_PRAMDAC_FP_DEBUG_0_YWEIGHT_ROUND (1 << 24) -# define NV_PRAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK (1 << 28) -#define NV_PRAMDAC_FP_DEBUG_1 0x00680884 -# define NV_PRAMDAC_FP_DEBUG_1_XSCALE_VALUE 11:0 -# define NV_PRAMDAC_FP_DEBUG_1_XSCALE_TESTMODE_ENABLE (1 << 12) -# define NV_PRAMDAC_FP_DEBUG_1_YSCALE_VALUE 27:16 -# define NV_PRAMDAC_FP_DEBUG_1_YSCALE_TESTMODE_ENABLE (1 << 28) -#define NV_PRAMDAC_FP_DEBUG_2 0x00680888 -#define NV_PRAMDAC_FP_DEBUG_3 0x0068088C - -/* see NV_PRAMDAC_INDIR_TMDS in rules.xml */ -#define NV_PRAMDAC_FP_TMDS_CONTROL 0x006808b0 -# define NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE (1 << 16) -#define NV_PRAMDAC_FP_TMDS_DATA 0x006808b4 - -#define NV_PRAMDAC_8C0 0x006808c0 - -/* Some kind of switch */ -#define NV_PRAMDAC_900 0x00680900 -#define NV_PRAMDAC_A20 0x00680A20 -#define NV_PRAMDAC_A24 0x00680A24 -#define NV_PRAMDAC_A34 0x00680A34 - -#define NV_PRAMDAC_CTV 0x00680c00 - -/* names fabricated from NV_USER_DAC info */ -#define NV_PRMDIO_PIXEL_MASK 0x006813c6 -# define NV_PRMDIO_PIXEL_MASK_MASK 0xff -#define NV_PRMDIO_READ_MODE_ADDRESS 0x006813c7 -#define NV_PRMDIO_WRITE_MODE_ADDRESS 0x006813c8 -#define NV_PRMDIO_PALETTE_DATA 0x006813c9 - -#define NV_PGRAPH_DEBUG_0 0x00400080 -#define NV_PGRAPH_DEBUG_1 0x00400084 -#define NV_PGRAPH_DEBUG_2_NV04 0x00400088 -#define NV_PGRAPH_DEBUG_2 0x00400620 -#define NV_PGRAPH_DEBUG_3 0x0040008c -#define NV_PGRAPH_DEBUG_4 0x00400090 -#define NV_PGRAPH_INTR 0x00400100 -#define NV_PGRAPH_INTR_EN 0x00400140 -#define NV_PGRAPH_CTX_CONTROL 0x00400144 -#define NV_PGRAPH_CTX_CONTROL_NV04 0x00400170 -#define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C -#define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540 -#define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544 -#define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548 -#define NV_PGRAPH_BETA_AND 0x00400608 -#define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610 -#define NV_PGRAPH_BOFFSET0 0x00400640 -#define NV_PGRAPH_BOFFSET1 0x00400644 -#define NV_PGRAPH_BOFFSET2 0x00400648 -#define NV_PGRAPH_BLIMIT0 0x00400684 -#define NV_PGRAPH_BLIMIT1 0x00400688 -#define NV_PGRAPH_BLIMIT2 0x0040068c -#define NV_PGRAPH_STATUS 0x00400700 -#define NV_PGRAPH_SURFACE 0x00400710 -#define NV_PGRAPH_STATE 0x00400714 -#define NV_PGRAPH_FIFO 0x00400720 -#define NV_PGRAPH_PATTERN_SHAPE 0x00400810 -#define NV_PGRAPH_TILE 0x00400b00 - -#define NV_PVIDEO_INTR_EN 0x00008140 -#define NV_PVIDEO_BUFFER 0x00008700 -#define NV_PVIDEO_STOP 0x00008704 -#define NV_PVIDEO_UVPLANE_BASE(buff) (0x00008800+(buff)*4) -#define NV_PVIDEO_UVPLANE_LIMIT(buff) (0x00008808+(buff)*4) -#define NV_PVIDEO_UVPLANE_OFFSET_BUFF(buff) (0x00008820+(buff)*4) -#define NV_PVIDEO_BASE(buff) (0x00008900+(buff)*4) -#define NV_PVIDEO_LIMIT(buff) (0x00008908+(buff)*4) -#define NV_PVIDEO_LUMINANCE(buff) (0x00008910+(buff)*4) -#define NV_PVIDEO_CHROMINANCE(buff) (0x00008918+(buff)*4) -#define NV_PVIDEO_OFFSET_BUFF(buff) (0x00008920+(buff)*4) -#define NV_PVIDEO_SIZE_IN(buff) (0x00008928+(buff)*4) -#define NV_PVIDEO_POINT_IN(buff) (0x00008930+(buff)*4) -#define NV_PVIDEO_DS_DX(buff) (0x00008938+(buff)*4) -#define NV_PVIDEO_DT_DY(buff) (0x00008940+(buff)*4) -#define NV_PVIDEO_POINT_OUT(buff) (0x00008948+(buff)*4) -#define NV_PVIDEO_SIZE_OUT(buff) (0x00008950+(buff)*4) -#define NV_PVIDEO_FORMAT(buff) (0x00008958+(buff)*4) -# define NV_PVIDEO_FORMAT_PLANAR (1 << 0) -# define NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8 (1 << 16) -# define NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY (1 << 20) -# define NV_PVIDEO_FORMAT_MATRIX_ITURBT709 (1 << 24) -#define NV_PVIDEO_COLOR_KEY 0x00008B00 - -/* NV04 overlay defines from VIDIX & Haiku */ -#define NV_PVIDEO_INTR_EN_0 0x00680140 -#define NV_PVIDEO_STEP_SIZE 0x00680200 -#define NV_PVIDEO_CONTROL_Y 0x00680204 -#define NV_PVIDEO_CONTROL_X 0x00680208 -#define NV_PVIDEO_BUFF0_START_ADDRESS 0x0068020c -#define NV_PVIDEO_BUFF0_PITCH_LENGTH 0x00680214 -#define NV_PVIDEO_BUFF0_OFFSET 0x0068021c -#define NV_PVIDEO_BUFF1_START_ADDRESS 0x00680210 -#define NV_PVIDEO_BUFF1_PITCH_LENGTH 0x00680218 -#define NV_PVIDEO_BUFF1_OFFSET 0x00680220 -#define NV_PVIDEO_OE_STATE 0x00680224 -#define NV_PVIDEO_SU_STATE 0x00680228 -#define NV_PVIDEO_RM_STATE 0x0068022c -#define NV_PVIDEO_WINDOW_START 0x00680230 -#define NV_PVIDEO_WINDOW_SIZE 0x00680234 -#define NV_PVIDEO_FIFO_THRES_SIZE 0x00680238 -#define NV_PVIDEO_FIFO_BURST_LENGTH 0x0068023c -#define NV_PVIDEO_KEY 0x00680240 -#define NV_PVIDEO_OVERLAY 0x00680244 -#define NV_PVIDEO_RED_CSC_OFFSET 0x00680280 -#define NV_PVIDEO_GREEN_CSC_OFFSET 0x00680284 -#define NV_PVIDEO_BLUE_CSC_OFFSET 0x00680288 -#define NV_PVIDEO_CSC_ADJUST 0x0068028c - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/r128/Makefile deleted file mode 100644 index 1cc72ae3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm -r128-y := r128_drv.o r128_cce.o r128_state.o r128_irq.o - -r128-$(CONFIG_COMPAT) += r128_ioc32.o - -obj-$(CONFIG_DRM_R128) += r128.o diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_cce.c b/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_cce.c deleted file mode 100644 index bcac90b5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_cce.c +++ /dev/null @@ -1,938 +0,0 @@ -/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*- - * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com - */ -/* - * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -#define R128_FIFO_DEBUG 0 - -#define FIRMWARE_NAME "r128/r128_cce.bin" - -MODULE_FIRMWARE(FIRMWARE_NAME); - -static int R128_READ_PLL(struct drm_device *dev, int addr) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - - R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); - return R128_READ(R128_CLOCK_CNTL_DATA); -} - -#if R128_FIFO_DEBUG -static void r128_status(drm_r128_private_t *dev_priv) -{ - printk("GUI_STAT = 0x%08x\n", - (unsigned int)R128_READ(R128_GUI_STAT)); - printk("PM4_STAT = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_STAT)); - printk("PM4_BUFFER_DL_WPTR = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR)); - printk("PM4_BUFFER_DL_RPTR = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR)); - printk("PM4_MICRO_CNTL = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_MICRO_CNTL)); - printk("PM4_BUFFER_CNTL = 0x%08x\n", - (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL)); -} -#endif - -/* ================================================================ - * Engine, FIFO control - */ - -static int r128_do_pixcache_flush(drm_r128_private_t *dev_priv) -{ - u32 tmp; - int i; - - tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL; - R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) - return 0; - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -static int r128_do_wait_for_fifo(drm_r128_private_t *dev_priv, int entries) -{ - int i; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; - if (slots >= entries) - return 0; - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -static int r128_do_wait_for_idle(drm_r128_private_t *dev_priv) -{ - int i, ret; - - ret = r128_do_wait_for_fifo(dev_priv, 64); - if (ret) - return ret; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) { - r128_do_pixcache_flush(dev_priv); - return 0; - } - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -/* ================================================================ - * CCE control, initialization - */ - -/* Load the microcode for the CCE */ -static int r128_cce_load_microcode(drm_r128_private_t *dev_priv) -{ - struct platform_device *pdev; - const struct firmware *fw; - const __be32 *fw_data; - int rc, i; - - DRM_DEBUG("\n"); - - pdev = platform_device_register_simple("r128_cce", 0, NULL, 0); - if (IS_ERR(pdev)) { - printk(KERN_ERR "r128_cce: Failed to register firmware\n"); - return PTR_ERR(pdev); - } - rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); - platform_device_unregister(pdev); - if (rc) { - printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n", - FIRMWARE_NAME); - return rc; - } - - if (fw->size != 256 * 8) { - printk(KERN_ERR - "r128_cce: Bogus length %zu in firmware \"%s\"\n", - fw->size, FIRMWARE_NAME); - rc = -EINVAL; - goto out_release; - } - - r128_do_wait_for_idle(dev_priv); - - fw_data = (const __be32 *)fw->data; - R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); - for (i = 0; i < 256; i++) { - R128_WRITE(R128_PM4_MICROCODE_DATAH, - be32_to_cpup(&fw_data[i * 2])); - R128_WRITE(R128_PM4_MICROCODE_DATAL, - be32_to_cpup(&fw_data[i * 2 + 1])); - } - -out_release: - release_firmware(fw); - return rc; -} - -/* Flush any pending commands to the CCE. This should only be used just - * prior to a wait for idle, as it informs the engine that the command - * stream is ending. - */ -static void r128_do_cce_flush(drm_r128_private_t *dev_priv) -{ - u32 tmp; - - tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE; - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp); -} - -/* Wait for the CCE to go idle. - */ -int r128_do_cce_idle(drm_r128_private_t *dev_priv) -{ - int i; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) { - int pm4stat = R128_READ(R128_PM4_STAT); - if (((pm4stat & R128_PM4_FIFOCNT_MASK) >= - dev_priv->cce_fifo_size) && - !(pm4stat & (R128_PM4_BUSY | - R128_PM4_GUI_ACTIVE))) { - return r128_do_pixcache_flush(dev_priv); - } - } - DRM_UDELAY(1); - } - -#if R128_FIFO_DEBUG - DRM_ERROR("failed!\n"); - r128_status(dev_priv); -#endif - return -EBUSY; -} - -/* Start the Concurrent Command Engine. - */ -static void r128_do_cce_start(drm_r128_private_t *dev_priv) -{ - r128_do_wait_for_idle(dev_priv); - - R128_WRITE(R128_PM4_BUFFER_CNTL, - dev_priv->cce_mode | dev_priv->ring.size_l2qw - | R128_PM4_BUFFER_CNTL_NOUPDATE); - R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */ - R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); - - dev_priv->cce_running = 1; -} - -/* Reset the Concurrent Command Engine. This will not flush any pending - * commands, so you must wait for the CCE command stream to complete - * before calling this routine. - */ -static void r128_do_cce_reset(drm_r128_private_t *dev_priv) -{ - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); - R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); - dev_priv->ring.tail = 0; -} - -/* Stop the Concurrent Command Engine. This will not flush any pending - * commands, so you must flush the command stream and wait for the CCE - * to go idle before calling this routine. - */ -static void r128_do_cce_stop(drm_r128_private_t *dev_priv) -{ - R128_WRITE(R128_PM4_MICRO_CNTL, 0); - R128_WRITE(R128_PM4_BUFFER_CNTL, - R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE); - - dev_priv->cce_running = 0; -} - -/* Reset the engine. This will stop the CCE if it is running. - */ -static int r128_do_engine_reset(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; - - r128_do_pixcache_flush(dev_priv); - - clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX); - mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL); - - R128_WRITE_PLL(R128_MCLK_CNTL, - mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); - - gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL); - - /* Taken from the sample code - do not change */ - R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); - R128_READ(R128_GEN_RESET_CNTL); - R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); - R128_READ(R128_GEN_RESET_CNTL); - - R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl); - R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index); - R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl); - - /* Reset the CCE ring */ - r128_do_cce_reset(dev_priv); - - /* The CCE is no longer running after an engine reset */ - dev_priv->cce_running = 0; - - /* Reset any pending vertex, indirect buffers */ - r128_freelist_reset(dev); - - return 0; -} - -static void r128_cce_init_ring_buffer(struct drm_device *dev, - drm_r128_private_t *dev_priv) -{ - u32 ring_start; - u32 tmp; - - DRM_DEBUG("\n"); - - /* The manual (p. 2) says this address is in "VM space". This - * means it's an offset from the start of AGP space. - */ -#if __OS_HAS_AGP - if (!dev_priv->is_pci) - ring_start = dev_priv->cce_ring->offset - dev->agp->base; - else -#endif - ring_start = dev_priv->cce_ring->offset - - (unsigned long)dev->sg->virtual; - - R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET); - - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); - R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); - - /* Set watermark control */ - R128_WRITE(R128_PM4_BUFFER_WM_CNTL, - ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT) - | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT) - | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT) - | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT)); - - /* Force read. Why? Because it's in the examples... */ - R128_READ(R128_PM4_BUFFER_ADDR); - - /* Turn on bus mastering */ - tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS; - R128_WRITE(R128_BUS_CNTL, tmp); -} - -static int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init) -{ - drm_r128_private_t *dev_priv; - int rc; - - DRM_DEBUG("\n"); - - if (dev->dev_private) { - DRM_DEBUG("called when already initialized\n"); - return -EINVAL; - } - - dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev_priv->is_pci = init->is_pci; - - if (dev_priv->is_pci && !dev->sg) { - DRM_ERROR("PCI GART memory not allocated!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - dev_priv->usec_timeout = init->usec_timeout; - if (dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) { - DRM_DEBUG("TIMEOUT problem!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - dev_priv->cce_mode = init->cce_mode; - - /* GH: Simple idle check. - */ - atomic_set(&dev_priv->idle_count, 0); - - /* We don't support anything other than bus-mastering ring mode, - * but the ring can be in either AGP or PCI space for the ring - * read pointer. - */ - if ((init->cce_mode != R128_PM4_192BM) && - (init->cce_mode != R128_PM4_128BM_64INDBM) && - (init->cce_mode != R128_PM4_64BM_128INDBM) && - (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) { - DRM_DEBUG("Bad cce_mode!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - switch (init->cce_mode) { - case R128_PM4_NONPM4: - dev_priv->cce_fifo_size = 0; - break; - case R128_PM4_192PIO: - case R128_PM4_192BM: - dev_priv->cce_fifo_size = 192; - break; - case R128_PM4_128PIO_64INDBM: - case R128_PM4_128BM_64INDBM: - dev_priv->cce_fifo_size = 128; - break; - case R128_PM4_64PIO_128INDBM: - case R128_PM4_64BM_128INDBM: - case R128_PM4_64PIO_64VCBM_64INDBM: - case R128_PM4_64BM_64VCBM_64INDBM: - case R128_PM4_64PIO_64VCPIO_64INDPIO: - dev_priv->cce_fifo_size = 64; - break; - } - - switch (init->fb_bpp) { - case 16: - dev_priv->color_fmt = R128_DATATYPE_RGB565; - break; - case 32: - default: - dev_priv->color_fmt = R128_DATATYPE_ARGB8888; - break; - } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - switch (init->depth_bpp) { - case 16: - dev_priv->depth_fmt = R128_DATATYPE_RGB565; - break; - case 24: - case 32: - default: - dev_priv->depth_fmt = R128_DATATYPE_ARGB8888; - break; - } - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - dev_priv->span_offset = init->span_offset; - - dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) | - (dev_priv->front_offset >> 5)); - dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) | - (dev_priv->back_offset >> 5)); - dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | - (dev_priv->depth_offset >> 5) | - R128_DST_TILE); - dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) | - (dev_priv->span_offset >> 5)); - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); - if (!dev_priv->mmio) { - DRM_ERROR("could not find mmio region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->cce_ring) { - DRM_ERROR("could not find cce ring region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if (!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find dma buffer region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - - if (!dev_priv->is_pci) { - dev_priv->agp_textures = - drm_core_findmap(dev, init->agp_textures_offset); - if (!dev_priv->agp_textures) { - DRM_ERROR("could not find agp texture region!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -EINVAL; - } - } - - dev_priv->sarea_priv = - (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle + - init->sarea_priv_offset); - -#if __OS_HAS_AGP - if (!dev_priv->is_pci) { - drm_core_ioremap_wc(dev_priv->cce_ring, dev); - drm_core_ioremap_wc(dev_priv->ring_rptr, dev); - drm_core_ioremap_wc(dev->agp_buffer_map, dev); - if (!dev_priv->cce_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { - DRM_ERROR("Could not ioremap agp regions!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -ENOMEM; - } - } else -#endif - { - dev_priv->cce_ring->handle = - (void *)(unsigned long)dev_priv->cce_ring->offset; - dev_priv->ring_rptr->handle = - (void *)(unsigned long)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = - (void *)(unsigned long)dev->agp_buffer_map->offset; - } - -#if __OS_HAS_AGP - if (!dev_priv->is_pci) - dev_priv->cce_buffers_offset = dev->agp->base; - else -#endif - dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual; - - dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle; - dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle - + init->ring_size / sizeof(u32)); - dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; - - dev_priv->ring.high_mark = 128; - - dev_priv->sarea_priv->last_frame = 0; - R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); - - dev_priv->sarea_priv->last_dispatch = 0; - R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch); - -#if __OS_HAS_AGP - if (dev_priv->is_pci) { -#endif - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); - dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; - dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; - dev_priv->gart_info.addr = NULL; - dev_priv->gart_info.bus_addr = 0; - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { - DRM_ERROR("failed to init PCI GART!\n"); - dev->dev_private = (void *)dev_priv; - r128_do_cleanup_cce(dev); - return -ENOMEM; - } - R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); -#if __OS_HAS_AGP - } -#endif - - r128_cce_init_ring_buffer(dev, dev_priv); - rc = r128_cce_load_microcode(dev_priv); - - dev->dev_private = (void *)dev_priv; - - r128_do_engine_reset(dev); - - if (rc) { - DRM_ERROR("Failed to load firmware!\n"); - r128_do_cleanup_cce(dev); - } - - return rc; -} - -int r128_do_cleanup_cce(struct drm_device *dev) -{ - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - if (dev->dev_private) { - drm_r128_private_t *dev_priv = dev->dev_private; - -#if __OS_HAS_AGP - if (!dev_priv->is_pci) { - if (dev_priv->cce_ring != NULL) - drm_core_ioremapfree(dev_priv->cce_ring, dev); - if (dev_priv->ring_rptr != NULL) - drm_core_ioremapfree(dev_priv->ring_rptr, dev); - if (dev->agp_buffer_map != NULL) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } - } else -#endif - { - if (dev_priv->gart_info.bus_addr) - if (!drm_ati_pcigart_cleanup(dev, - &dev_priv->gart_info)) - DRM_ERROR - ("failed to cleanup PCI GART!\n"); - } - - kfree(dev->dev_private); - dev->dev_private = NULL; - } - - return 0; -} - -int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_init_t *init = data; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - switch (init->func) { - case R128_INIT_CCE: - return r128_do_init_cce(dev, init); - case R128_CLEANUP_CCE: - return r128_do_cleanup_cce(dev); - } - - return -EINVAL; -} - -int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { - DRM_DEBUG("while CCE running\n"); - return 0; - } - - r128_do_cce_start(dev_priv); - - return 0; -} - -/* Stop the CCE. The engine must have been idled before calling this - * routine. - */ -int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_cce_stop_t *stop = data; - int ret; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - /* Flush any pending CCE commands. This ensures any outstanding - * commands are exectuted by the engine before we turn it off. - */ - if (stop->flush) - r128_do_cce_flush(dev_priv); - - /* If we fail to make the engine go idle, we return an error - * code so that the DRM ioctl wrapper can try again. - */ - if (stop->idle) { - ret = r128_do_cce_idle(dev_priv); - if (ret) - return ret; - } - - /* Finally, we can turn off the CCE. If the engine isn't idle, - * we will get some dropped triangles as they won't be fully - * rendered before the CCE is shut down. - */ - r128_do_cce_stop(dev_priv); - - /* Reset the engine */ - r128_do_engine_reset(dev); - - return 0; -} - -/* Just reset the CCE ring. Called as part of an X Server engine reset. - */ -int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - r128_do_cce_reset(dev_priv); - - /* The CCE is no longer running after an engine reset */ - dev_priv->cce_running = 0; - - return 0; -} - -int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - if (dev_priv->cce_running) - r128_do_cce_flush(dev_priv); - - return r128_do_cce_idle(dev_priv); -} - -int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev->dev_private); - - return r128_do_engine_reset(dev); -} - -int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - return -EINVAL; -} - -/* ================================================================ - * Freelist management - */ -#define R128_BUFFER_USED 0xffffffff -#define R128_BUFFER_FREE 0 - -#if 0 -static int r128_freelist_init(struct drm_device *dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_freelist_t *entry; - int i; - - dev_priv->head = kzalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL); - if (dev_priv->head == NULL) - return -ENOMEM; - - dev_priv->head->age = R128_BUFFER_USED; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - - entry = kmalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL); - if (!entry) - return -ENOMEM; - - entry->age = R128_BUFFER_FREE; - entry->buf = buf; - entry->prev = dev_priv->head; - entry->next = dev_priv->head->next; - if (!entry->next) - dev_priv->tail = entry; - - buf_priv->discard = 0; - buf_priv->dispatched = 0; - buf_priv->list_entry = entry; - - dev_priv->head->next = entry; - - if (dev_priv->head->next) - dev_priv->head->next->prev = entry; - } - - return 0; - -} -#endif - -static struct drm_buf *r128_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv; - struct drm_buf *buf; - int i, t; - - /* FIXME: Optimize -- use freelist code */ - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if (!buf->file_priv) - return buf; - } - - for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = R128_READ(R128_LAST_DISPATCH_REG); - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - buf_priv = buf->dev_private; - if (buf->pending && buf_priv->age <= done_age) { - /* The buffer has been processed, so it - * can now be used. - */ - buf->pending = 0; - return buf; - } - } - DRM_UDELAY(1); - } - - DRM_DEBUG("returning NULL!\n"); - return NULL; -} - -void r128_freelist_reset(struct drm_device *dev) -{ - struct drm_device_dma *dma = dev->dma; - int i; - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->age = 0; - } -} - -/* ================================================================ - * CCE command submission - */ - -int r128_wait_ring(drm_r128_private_t *dev_priv, int n) -{ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; - int i; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - r128_update_ring_snapshot(dev_priv); - if (ring->space >= n) - return 0; - DRM_UDELAY(1); - } - - /* FIXME: This is being ignored... */ - DRM_ERROR("failed!\n"); - return -EBUSY; -} - -static int r128_cce_get_buffers(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_dma *d) -{ - int i; - struct drm_buf *buf; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = r128_freelist_get(dev); - if (!buf) - return -EAGAIN; - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, - sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, - sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int ret = 0; - struct drm_dma *d = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - d->granted_count = 0; - - if (d->request_count) - ret = r128_cce_get_buffers(dev, file_priv, d); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.c deleted file mode 100644 index 88718fad..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.c +++ /dev/null @@ -1,114 +0,0 @@ -/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*- - * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Gareth Hughes - */ - -#include - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - r128_PCI_IDS -}; - -static const struct file_operations r128_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, -#ifdef CONFIG_COMPAT - .compat_ioctl = r128_compat_ioctl, -#endif - .llseek = noop_llseek, -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, - .dev_priv_size = sizeof(drm_r128_buf_priv_t), - .load = r128_driver_load, - .preclose = r128_driver_preclose, - .lastclose = r128_driver_lastclose, - .get_vblank_counter = r128_get_vblank_counter, - .enable_vblank = r128_enable_vblank, - .disable_vblank = r128_disable_vblank, - .irq_preinstall = r128_driver_irq_preinstall, - .irq_postinstall = r128_driver_irq_postinstall, - .irq_uninstall = r128_driver_irq_uninstall, - .irq_handler = r128_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .ioctls = r128_ioctls, - .dma_ioctl = r128_cce_buffers, - .fops = &r128_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -int r128_driver_load(struct drm_device *dev, unsigned long flags) -{ - pci_set_master(dev->pdev); - return drm_vblank_init(dev, 1); -} - -static struct pci_driver r128_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, -}; - -static int __init r128_init(void) -{ - driver.num_ioctls = r128_max_ioctl; - - return drm_pci_init(&driver, &r128_pci_driver); -} - -static void __exit r128_exit(void) -{ - drm_pci_exit(&driver, &r128_pci_driver); -} - -module_init(r128_init); -module_exit(r128_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.h deleted file mode 100644 index 930c71b2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_drv.h +++ /dev/null @@ -1,530 +0,0 @@ -/* r128_drv.h -- Private header for r128 driver -*- linux-c -*- - * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com - */ -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith - * Kevin E. Martin - * Gareth Hughes - * Michel D�zer - */ - -#ifndef __R128_DRV_H__ -#define __R128_DRV_H__ - -/* General customization: - */ -#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." - -#define DRIVER_NAME "r128" -#define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20030725" - -/* Interface history: - * - * ?? - ?? - * 2.4 - Add support for ycbcr textures (no new ioctls) - * 2.5 - Add FLIP ioctl, disable FULLSCREEN. - */ -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 5 -#define DRIVER_PATCHLEVEL 0 - -#define GET_RING_HEAD(dev_priv) R128_READ(R128_PM4_BUFFER_DL_RPTR) - -typedef struct drm_r128_freelist { - unsigned int age; - struct drm_buf *buf; - struct drm_r128_freelist *next; - struct drm_r128_freelist *prev; -} drm_r128_freelist_t; - -typedef struct drm_r128_ring_buffer { - u32 *start; - u32 *end; - int size; - int size_l2qw; - - u32 tail; - u32 tail_mask; - int space; - - int high_mark; -} drm_r128_ring_buffer_t; - -typedef struct drm_r128_private { - drm_r128_ring_buffer_t ring; - drm_r128_sarea_t *sarea_priv; - - int cce_mode; - int cce_fifo_size; - int cce_running; - - drm_r128_freelist_t *head; - drm_r128_freelist_t *tail; - - int usec_timeout; - int is_pci; - unsigned long cce_buffers_offset; - - atomic_t idle_count; - - int page_flipping; - int current_page; - u32 crtc_offset; - u32 crtc_offset_cntl; - - atomic_t vbl_received; - - u32 color_fmt; - unsigned int front_offset; - unsigned int front_pitch; - unsigned int back_offset; - unsigned int back_pitch; - - u32 depth_fmt; - unsigned int depth_offset; - unsigned int depth_pitch; - unsigned int span_offset; - - u32 front_pitch_offset_c; - u32 back_pitch_offset_c; - u32 depth_pitch_offset_c; - u32 span_pitch_offset_c; - - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *cce_ring; - drm_local_map_t *ring_rptr; - drm_local_map_t *agp_textures; - struct drm_ati_pcigart_info gart_info; -} drm_r128_private_t; - -typedef struct drm_r128_buf_priv { - u32 age; - int prim; - int discard; - int dispatched; - drm_r128_freelist_t *list_entry; -} drm_r128_buf_priv_t; - -extern struct drm_ioctl_desc r128_ioctls[]; -extern int r128_max_ioctl; - - /* r128_cce.c */ -extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); - -extern void r128_freelist_reset(struct drm_device *dev); - -extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n); - -extern int r128_do_cce_idle(drm_r128_private_t *dev_priv); -extern int r128_do_cleanup_cce(struct drm_device *dev); - -extern int r128_enable_vblank(struct drm_device *dev, int crtc); -extern void r128_disable_vblank(struct drm_device *dev, int crtc); -extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); -extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); -extern void r128_driver_irq_preinstall(struct drm_device *dev); -extern int r128_driver_irq_postinstall(struct drm_device *dev); -extern void r128_driver_irq_uninstall(struct drm_device *dev); -extern void r128_driver_lastclose(struct drm_device *dev); -extern int r128_driver_load(struct drm_device *dev, unsigned long flags); -extern void r128_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv); - -extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -/* Register definitions, register access macros and drmAddMap constants - * for Rage 128 kernel driver. - */ - -#define R128_AUX_SC_CNTL 0x1660 -# define R128_AUX1_SC_EN (1 << 0) -# define R128_AUX1_SC_MODE_OR (0 << 1) -# define R128_AUX1_SC_MODE_NAND (1 << 1) -# define R128_AUX2_SC_EN (1 << 2) -# define R128_AUX2_SC_MODE_OR (0 << 3) -# define R128_AUX2_SC_MODE_NAND (1 << 3) -# define R128_AUX3_SC_EN (1 << 4) -# define R128_AUX3_SC_MODE_OR (0 << 5) -# define R128_AUX3_SC_MODE_NAND (1 << 5) -#define R128_AUX1_SC_LEFT 0x1664 -#define R128_AUX1_SC_RIGHT 0x1668 -#define R128_AUX1_SC_TOP 0x166c -#define R128_AUX1_SC_BOTTOM 0x1670 -#define R128_AUX2_SC_LEFT 0x1674 -#define R128_AUX2_SC_RIGHT 0x1678 -#define R128_AUX2_SC_TOP 0x167c -#define R128_AUX2_SC_BOTTOM 0x1680 -#define R128_AUX3_SC_LEFT 0x1684 -#define R128_AUX3_SC_RIGHT 0x1688 -#define R128_AUX3_SC_TOP 0x168c -#define R128_AUX3_SC_BOTTOM 0x1690 - -#define R128_BRUSH_DATA0 0x1480 -#define R128_BUS_CNTL 0x0030 -# define R128_BUS_MASTER_DIS (1 << 6) - -#define R128_CLOCK_CNTL_INDEX 0x0008 -#define R128_CLOCK_CNTL_DATA 0x000c -# define R128_PLL_WR_EN (1 << 7) -#define R128_CONSTANT_COLOR_C 0x1d34 -#define R128_CRTC_OFFSET 0x0224 -#define R128_CRTC_OFFSET_CNTL 0x0228 -# define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16) - -#define R128_DP_GUI_MASTER_CNTL 0x146c -# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) -# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) -# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) -# define R128_GMC_BRUSH_NONE (15 << 4) -# define R128_GMC_DST_16BPP (4 << 8) -# define R128_GMC_DST_24BPP (5 << 8) -# define R128_GMC_DST_32BPP (6 << 8) -# define R128_GMC_DST_DATATYPE_SHIFT 8 -# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) -# define R128_DP_SRC_SOURCE_MEMORY (2 << 24) -# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24) -# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) -# define R128_GMC_AUX_CLIP_DIS (1 << 29) -# define R128_GMC_WR_MSK_DIS (1 << 30) -# define R128_ROP3_S 0x00cc0000 -# define R128_ROP3_P 0x00f00000 -#define R128_DP_WRITE_MASK 0x16cc -#define R128_DST_PITCH_OFFSET_C 0x1c80 -# define R128_DST_TILE (1 << 31) - -#define R128_GEN_INT_CNTL 0x0040 -# define R128_CRTC_VBLANK_INT_EN (1 << 0) -#define R128_GEN_INT_STATUS 0x0044 -# define R128_CRTC_VBLANK_INT (1 << 0) -# define R128_CRTC_VBLANK_INT_AK (1 << 0) -#define R128_GEN_RESET_CNTL 0x00f0 -# define R128_SOFT_RESET_GUI (1 << 0) - -#define R128_GUI_SCRATCH_REG0 0x15e0 -#define R128_GUI_SCRATCH_REG1 0x15e4 -#define R128_GUI_SCRATCH_REG2 0x15e8 -#define R128_GUI_SCRATCH_REG3 0x15ec -#define R128_GUI_SCRATCH_REG4 0x15f0 -#define R128_GUI_SCRATCH_REG5 0x15f4 - -#define R128_GUI_STAT 0x1740 -# define R128_GUI_FIFOCNT_MASK 0x0fff -# define R128_GUI_ACTIVE (1 << 31) - -#define R128_MCLK_CNTL 0x000f -# define R128_FORCE_GCP (1 << 16) -# define R128_FORCE_PIPE3D_CP (1 << 17) -# define R128_FORCE_RCP (1 << 18) - -#define R128_PC_GUI_CTLSTAT 0x1748 -#define R128_PC_NGUI_CTLSTAT 0x0184 -# define R128_PC_FLUSH_GUI (3 << 0) -# define R128_PC_RI_GUI (1 << 2) -# define R128_PC_FLUSH_ALL 0x00ff -# define R128_PC_BUSY (1 << 31) - -#define R128_PCI_GART_PAGE 0x017c -#define R128_PRIM_TEX_CNTL_C 0x1cb0 - -#define R128_SCALE_3D_CNTL 0x1a00 -#define R128_SEC_TEX_CNTL_C 0x1d00 -#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c -#define R128_SETUP_CNTL 0x1bc4 -#define R128_STEN_REF_MASK_C 0x1d40 - -#define R128_TEX_CNTL_C 0x1c9c -# define R128_TEX_CACHE_FLUSH (1 << 23) - -#define R128_WAIT_UNTIL 0x1720 -# define R128_EVENT_CRTC_OFFSET (1 << 0) -#define R128_WINDOW_XY_OFFSET 0x1bcc - -/* CCE registers - */ -#define R128_PM4_BUFFER_OFFSET 0x0700 -#define R128_PM4_BUFFER_CNTL 0x0704 -# define R128_PM4_MASK (15 << 28) -# define R128_PM4_NONPM4 (0 << 28) -# define R128_PM4_192PIO (1 << 28) -# define R128_PM4_192BM (2 << 28) -# define R128_PM4_128PIO_64INDBM (3 << 28) -# define R128_PM4_128BM_64INDBM (4 << 28) -# define R128_PM4_64PIO_128INDBM (5 << 28) -# define R128_PM4_64BM_128INDBM (6 << 28) -# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) -# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) -# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) -# define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27) - -#define R128_PM4_BUFFER_WM_CNTL 0x0708 -# define R128_WMA_SHIFT 0 -# define R128_WMB_SHIFT 8 -# define R128_WMC_SHIFT 16 -# define R128_WB_WM_SHIFT 24 - -#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c -#define R128_PM4_BUFFER_DL_RPTR 0x0710 -#define R128_PM4_BUFFER_DL_WPTR 0x0714 -# define R128_PM4_BUFFER_DL_DONE (1 << 31) - -#define R128_PM4_VC_FPU_SETUP 0x071c - -#define R128_PM4_IW_INDOFF 0x0738 -#define R128_PM4_IW_INDSIZE 0x073c - -#define R128_PM4_STAT 0x07b8 -# define R128_PM4_FIFOCNT_MASK 0x0fff -# define R128_PM4_BUSY (1 << 16) -# define R128_PM4_GUI_ACTIVE (1 << 31) - -#define R128_PM4_MICROCODE_ADDR 0x07d4 -#define R128_PM4_MICROCODE_RADDR 0x07d8 -#define R128_PM4_MICROCODE_DATAH 0x07dc -#define R128_PM4_MICROCODE_DATAL 0x07e0 - -#define R128_PM4_BUFFER_ADDR 0x07f0 -#define R128_PM4_MICRO_CNTL 0x07fc -# define R128_PM4_MICRO_FREERUN (1 << 30) - -#define R128_PM4_FIFO_DATA_EVEN 0x1000 -#define R128_PM4_FIFO_DATA_ODD 0x1004 - -/* CCE command packets - */ -#define R128_CCE_PACKET0 0x00000000 -#define R128_CCE_PACKET1 0x40000000 -#define R128_CCE_PACKET2 0x80000000 -#define R128_CCE_PACKET3 0xC0000000 -# define R128_CNTL_HOSTDATA_BLT 0x00009400 -# define R128_CNTL_PAINT_MULTI 0x00009A00 -# define R128_CNTL_BITBLT_MULTI 0x00009B00 -# define R128_3D_RNDR_GEN_INDX_PRIM 0x00002300 - -#define R128_CCE_PACKET_MASK 0xC0000000 -#define R128_CCE_PACKET_COUNT_MASK 0x3fff0000 -#define R128_CCE_PACKET0_REG_MASK 0x000007ff -#define R128_CCE_PACKET1_REG0_MASK 0x000007ff -#define R128_CCE_PACKET1_REG1_MASK 0x003ff800 - -#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 -#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 -#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 -#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 -#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 -#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 -#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 -#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 -#define R128_CCE_VC_CNTL_NUM_SHIFT 16 - -#define R128_DATATYPE_VQ 0 -#define R128_DATATYPE_CI4 1 -#define R128_DATATYPE_CI8 2 -#define R128_DATATYPE_ARGB1555 3 -#define R128_DATATYPE_RGB565 4 -#define R128_DATATYPE_RGB888 5 -#define R128_DATATYPE_ARGB8888 6 -#define R128_DATATYPE_RGB332 7 -#define R128_DATATYPE_Y8 8 -#define R128_DATATYPE_RGB8 9 -#define R128_DATATYPE_CI16 10 -#define R128_DATATYPE_YVYU422 11 -#define R128_DATATYPE_VYUY422 12 -#define R128_DATATYPE_AYUV444 14 -#define R128_DATATYPE_ARGB4444 15 - -/* Constants */ -#define R128_AGP_OFFSET 0x02000000 - -#define R128_WATERMARK_L 16 -#define R128_WATERMARK_M 8 -#define R128_WATERMARK_N 8 -#define R128_WATERMARK_K 128 - -#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */ - -#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0 -#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1 -#define R128_MAX_VB_AGE 0x7fffffff -#define R128_MAX_VB_VERTS (0xffff) - -#define R128_RING_HIGH_MARK 128 - -#define R128_PERFORMANCE_BOXES 0 - -#define R128_PCIGART_TABLE_SIZE 32768 - -#define R128_READ(reg) DRM_READ32(dev_priv->mmio, (reg)) -#define R128_WRITE(reg, val) DRM_WRITE32(dev_priv->mmio, (reg), (val)) -#define R128_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) -#define R128_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) - -#define R128_WRITE_PLL(addr, val) \ -do { \ - R128_WRITE8(R128_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | R128_PLL_WR_EN); \ - R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ -} while (0) - -#define CCE_PACKET0(reg, n) (R128_CCE_PACKET0 | \ - ((n) << 16) | ((reg) >> 2)) -#define CCE_PACKET1(reg0, reg1) (R128_CCE_PACKET1 | \ - (((reg1) >> 2) << 11) | ((reg0) >> 2)) -#define CCE_PACKET2() (R128_CCE_PACKET2) -#define CCE_PACKET3(pkt, n) (R128_CCE_PACKET3 | \ - (pkt) | ((n) << 16)) - -static __inline__ void r128_update_ring_snapshot(drm_r128_private_t *dev_priv) -{ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; - ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32); - if (ring->space <= 0) - ring->space += ring->size; -} - -/* ================================================================ - * Misc helper macros - */ - -#define DEV_INIT_TEST_WITH_RETURN(_dev_priv) \ -do { \ - if (!_dev_priv) { \ - DRM_ERROR("called with no initialization\n"); \ - return -EINVAL; \ - } \ -} while (0) - -#define RING_SPACE_TEST_WITH_RETURN(dev_priv) \ -do { \ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ - if (ring->space < ring->high_mark) { \ - for (i = 0 ; i < dev_priv->usec_timeout ; i++) { \ - r128_update_ring_snapshot(dev_priv); \ - if (ring->space >= ring->high_mark) \ - goto __ring_space_done; \ - DRM_UDELAY(1); \ - } \ - DRM_ERROR("ring space check failed!\n"); \ - return -EBUSY; \ - } \ - __ring_space_done: \ - ; \ -} while (0) - -#define VB_AGE_TEST_WITH_RETURN(dev_priv) \ -do { \ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \ - if (sarea_priv->last_dispatch >= R128_MAX_VB_AGE) { \ - int __ret = r128_do_cce_idle(dev_priv); \ - if (__ret) \ - return __ret; \ - sarea_priv->last_dispatch = 0; \ - r128_freelist_reset(dev); \ - } \ -} while (0) - -#define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ - OUT_RING(CCE_PACKET0(R128_WAIT_UNTIL, 0)); \ - OUT_RING(R128_EVENT_CRTC_OFFSET); \ -} while (0) - -/* ================================================================ - * Ring control - */ - -#define R128_VERBOSE 0 - -#define RING_LOCALS \ - int write, _nr; unsigned int tail_mask; volatile u32 *ring; - -#define BEGIN_RING(n) do { \ - if (R128_VERBOSE) \ - DRM_INFO("BEGIN_RING(%d)\n", (n)); \ - if (dev_priv->ring.space <= (n) * sizeof(u32)) { \ - COMMIT_RING(); \ - r128_wait_ring(dev_priv, (n) * sizeof(u32)); \ - } \ - _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ - ring = dev_priv->ring.start; \ - write = dev_priv->ring.tail; \ - tail_mask = dev_priv->ring.tail_mask; \ -} while (0) - -/* You can set this to zero if you want. If the card locks up, you'll - * need to keep this set. It works around a bug in early revs of the - * Rage 128 chipset, where the CCE would read 32 dwords past the end of - * the ring buffer before wrapping around. - */ -#define R128_BROKEN_CCE 1 - -#define ADVANCE_RING() do { \ - if (R128_VERBOSE) \ - DRM_INFO("ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ - write, dev_priv->ring.tail); \ - if (R128_BROKEN_CCE && write < 32) \ - memcpy(dev_priv->ring.end, \ - dev_priv->ring.start, \ - write * sizeof(u32)); \ - if (((dev_priv->ring.tail + _nr) & tail_mask) != write) \ - DRM_ERROR( \ - "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ - ((dev_priv->ring.tail + _nr) & tail_mask), \ - write, __LINE__); \ - else \ - dev_priv->ring.tail = write; \ -} while (0) - -#define COMMIT_RING() do { \ - if (R128_VERBOSE) \ - DRM_INFO("COMMIT_RING() tail=0x%06x\n", \ - dev_priv->ring.tail); \ - DRM_MEMORYBARRIER(); \ - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail); \ - R128_READ(R128_PM4_BUFFER_DL_WPTR); \ -} while (0) - -#define OUT_RING(x) do { \ - if (R128_VERBOSE) \ - DRM_INFO(" OUT_RING( 0x%08x ) at 0x%x\n", \ - (unsigned int)(x), write); \ - ring[write++] = cpu_to_le32(x); \ - write &= tail_mask; \ -} while (0) - -#endif /* __R128_DRV_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_ioc32.c b/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_ioc32.c deleted file mode 100644 index 51c99fc4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_ioc32.c +++ /dev/null @@ -1,215 +0,0 @@ -/** - * \file r128_ioc32.c - * - * 32-bit ioctl compatibility routines for the R128 DRM. - * - * \author Dave Airlie with code from patches by Egbert Eich - * - * Copyright (C) Paul Mackerras 2005 - * Copyright (C) Egbert Eich 2003,2004 - * Copyright (C) Dave Airlie 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" - -typedef struct drm_r128_init32 { - int func; - unsigned int sarea_priv_offset; - int is_pci; - int cce_mode; - int cce_secure; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - unsigned int span_offset; - - unsigned int fb_offset; - unsigned int mmio_offset; - unsigned int ring_offset; - unsigned int ring_rptr_offset; - unsigned int buffers_offset; - unsigned int agp_textures_offset; -} drm_r128_init32_t; - -static int compat_r128_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_init32_t init32; - drm_r128_init_t __user *init; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.is_pci, &init->is_pci) - || __put_user(init32.cce_mode, &init->cce_mode) - || __put_user(init32.cce_secure, &init->cce_secure) - || __put_user(init32.ring_size, &init->ring_size) - || __put_user(init32.usec_timeout, &init->usec_timeout) - || __put_user(init32.fb_bpp, &init->fb_bpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_bpp, &init->depth_bpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.span_offset, &init->span_offset) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.ring_offset, &init->ring_offset) - || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset) - || __put_user(init32.agp_textures_offset, - &init->agp_textures_offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_R128_INIT, (unsigned long)init); -} - -typedef struct drm_r128_depth32 { - int func; - int n; - u32 x; - u32 y; - u32 buffer; - u32 mask; -} drm_r128_depth32_t; - -static int compat_r128_depth(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_depth32_t depth32; - drm_r128_depth_t __user *depth; - - if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32))) - return -EFAULT; - - depth = compat_alloc_user_space(sizeof(*depth)); - if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth)) - || __put_user(depth32.func, &depth->func) - || __put_user(depth32.n, &depth->n) - || __put_user((int __user *)(unsigned long)depth32.x, &depth->x) - || __put_user((int __user *)(unsigned long)depth32.y, &depth->y) - || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, - &depth->buffer) - || __put_user((unsigned char __user *)(unsigned long)depth32.mask, - &depth->mask)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_R128_DEPTH, (unsigned long)depth); - -} - -typedef struct drm_r128_stipple32 { - u32 mask; -} drm_r128_stipple32_t; - -static int compat_r128_stipple(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_stipple32_t stipple32; - drm_r128_stipple_t __user *stipple; - - if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32))) - return -EFAULT; - - stipple = compat_alloc_user_space(sizeof(*stipple)); - if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple)) - || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, - &stipple->mask)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); -} - -typedef struct drm_r128_getparam32 { - int param; - u32 value; -} drm_r128_getparam32_t; - -static int compat_r128_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_r128_getparam32_t getparam32; - drm_r128_getparam_t __user *getparam; - - if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) - return -EFAULT; - - getparam = compat_alloc_user_space(sizeof(*getparam)); - if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam)) - || __put_user(getparam32.param, &getparam->param) - || __put_user((void __user *)(unsigned long)getparam32.value, - &getparam->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); -} - -drm_ioctl_compat_t *r128_compat_ioctls[] = { - [DRM_R128_INIT] = compat_r128_init, - [DRM_R128_DEPTH] = compat_r128_depth, - [DRM_R128_STIPPLE] = compat_r128_stipple, - [DRM_R128_GETPARAM] = compat_r128_getparam, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) - fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_irq.c deleted file mode 100644 index 429d5a02..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_irq.c +++ /dev/null @@ -1,116 +0,0 @@ -/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - * Eric Anholt - */ - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -u32 r128_get_vblank_counter(struct drm_device *dev, int crtc) -{ - const drm_r128_private_t *dev_priv = dev->dev_private; - - if (crtc != 0) - return 0; - - return atomic_read(&dev_priv->vbl_received); -} - -irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - int status; - - status = R128_READ(R128_GEN_INT_STATUS); - - /* VBLANK interrupt */ - if (status & R128_CRTC_VBLANK_INT) { - R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); - atomic_inc(&dev_priv->vbl_received); - drm_handle_vblank(dev, 0); - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -int r128_enable_vblank(struct drm_device *dev, int crtc) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - - if (crtc != 0) { - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); - return -EINVAL; - } - - R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN); - return 0; -} - -void r128_disable_vblank(struct drm_device *dev, int crtc) -{ - if (crtc != 0) - DRM_ERROR("%s: bad crtc %d\n", __func__, crtc); - - /* - * FIXME: implement proper interrupt disable by using the vblank - * counter register (if available) - * - * R128_WRITE(R128_GEN_INT_CNTL, - * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN); - */ -} - -void r128_driver_irq_preinstall(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - - /* Disable *all* interrupts */ - R128_WRITE(R128_GEN_INT_CNTL, 0); - /* Clear vblank bit if it's already high */ - R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK); -} - -int r128_driver_irq_postinstall(struct drm_device *dev) -{ - return 0; -} - -void r128_driver_irq_uninstall(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private; - if (!dev_priv) - return; - - /* Disable *all* interrupts */ - R128_WRITE(R128_GEN_INT_CNTL, 0); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_state.c b/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_state.c deleted file mode 100644 index a9e33ce6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/r128/r128_state.c +++ /dev/null @@ -1,1667 +0,0 @@ -/* r128_state.c -- State support for r128 -*- linux-c -*- - * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com - */ -/* - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - */ - -#include "drmP.h" -#include "drm.h" -#include "r128_drm.h" -#include "r128_drv.h" - -/* ================================================================ - * CCE hardware state programming functions - */ - -static void r128_emit_clip_rects(drm_r128_private_t *dev_priv, - struct drm_clip_rect *boxes, int count) -{ - u32 aux_sc_cntl = 0x00000000; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING((count < 3 ? count : 3) * 5 + 2); - - if (count >= 1) { - OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3)); - OUT_RING(boxes[0].x1); - OUT_RING(boxes[0].x2 - 1); - OUT_RING(boxes[0].y1); - OUT_RING(boxes[0].y2 - 1); - - aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR); - } - if (count >= 2) { - OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3)); - OUT_RING(boxes[1].x1); - OUT_RING(boxes[1].x2 - 1); - OUT_RING(boxes[1].y1); - OUT_RING(boxes[1].y2 - 1); - - aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR); - } - if (count >= 3) { - OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3)); - OUT_RING(boxes[2].x1); - OUT_RING(boxes[2].x2 - 1); - OUT_RING(boxes[2].y1); - OUT_RING(boxes[2].y2 - 1); - - aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR); - } - - OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0)); - OUT_RING(aux_sc_cntl); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_core(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0)); - OUT_RING(ctx->scale_3d_cntl); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_context(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(13); - - OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11)); - OUT_RING(ctx->dst_pitch_offset_c); - OUT_RING(ctx->dp_gui_master_cntl_c); - OUT_RING(ctx->sc_top_left_c); - OUT_RING(ctx->sc_bottom_right_c); - OUT_RING(ctx->z_offset_c); - OUT_RING(ctx->z_pitch_c); - OUT_RING(ctx->z_sten_cntl_c); - OUT_RING(ctx->tex_cntl_c); - OUT_RING(ctx->misc_3d_state_cntl_reg); - OUT_RING(ctx->texture_clr_cmp_clr_c); - OUT_RING(ctx->texture_clr_cmp_msk_c); - OUT_RING(ctx->fog_color_c); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(3); - - OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP)); - OUT_RING(ctx->setup_cntl); - OUT_RING(ctx->pm4_vc_fpu_setup); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5); - - OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); - OUT_RING(ctx->dp_write_mask); - - OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1)); - OUT_RING(ctx->sten_ref_mask_c); - OUT_RING(ctx->plane_3d_mask_c); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_window(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0)); - OUT_RING(ctx->window_xy_offset); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_context_regs_t *ctx = &sarea_priv->context_state; - drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0]; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS); - - OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, - 2 + R128_MAX_TEXTURE_LEVELS)); - OUT_RING(tex->tex_cntl); - OUT_RING(tex->tex_combine_cntl); - OUT_RING(ctx->tex_size_pitch_c); - for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) - OUT_RING(tex->tex_offset[i]); - - OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1)); - OUT_RING(ctx->constant_color_c); - OUT_RING(tex->tex_border_color); - - ADVANCE_RING(); -} - -static __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1]; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS); - - OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS)); - OUT_RING(tex->tex_cntl); - OUT_RING(tex->tex_combine_cntl); - for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) - OUT_RING(tex->tex_offset[i]); - - OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0)); - OUT_RING(tex->tex_border_color); - - ADVANCE_RING(); -} - -static void r128_emit_state(drm_r128_private_t *dev_priv) -{ - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty; - - DRM_DEBUG("dirty=0x%08x\n", dirty); - - if (dirty & R128_UPLOAD_CORE) { - r128_emit_core(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_CORE; - } - - if (dirty & R128_UPLOAD_CONTEXT) { - r128_emit_context(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT; - } - - if (dirty & R128_UPLOAD_SETUP) { - r128_emit_setup(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_SETUP; - } - - if (dirty & R128_UPLOAD_MASKS) { - r128_emit_masks(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_MASKS; - } - - if (dirty & R128_UPLOAD_WINDOW) { - r128_emit_window(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_WINDOW; - } - - if (dirty & R128_UPLOAD_TEX0) { - r128_emit_tex0(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_TEX0; - } - - if (dirty & R128_UPLOAD_TEX1) { - r128_emit_tex1(dev_priv); - sarea_priv->dirty &= ~R128_UPLOAD_TEX1; - } - - /* Turn off the texture cache flushing */ - sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; - - sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE; -} - -#if R128_PERFORMANCE_BOXES -/* ================================================================ - * Performance monitoring functions - */ - -static void r128_clear_box(drm_r128_private_t *dev_priv, - int x, int y, int w, int h, int r, int g, int b) -{ - u32 pitch, offset; - u32 fb_bpp, color; - RING_LOCALS; - - switch (dev_priv->fb_bpp) { - case 16: - fb_bpp = R128_GMC_DST_16BPP; - color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); - break; - case 24: - fb_bpp = R128_GMC_DST_24BPP; - color = ((r << 16) | (g << 8) | b); - break; - case 32: - fb_bpp = R128_GMC_DST_32BPP; - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); - break; - default: - return; - } - - offset = dev_priv->back_offset; - pitch = dev_priv->back_pitch >> 3; - - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - fb_bpp | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS); - - OUT_RING((pitch << 21) | (offset >> 5)); - OUT_RING(color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); -} - -static void r128_cce_performance_boxes(drm_r128_private_t *dev_priv) -{ - if (atomic_read(&dev_priv->idle_count) == 0) - r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0); - else - atomic_set(&dev_priv->idle_count, 0); -} - -#endif - -/* ================================================================ - * CCE command dispatch functions - */ - -static void r128_print_dirty(const char *msg, unsigned int flags) -{ - DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", - msg, - flags, - (flags & R128_UPLOAD_CORE) ? "core, " : "", - (flags & R128_UPLOAD_CONTEXT) ? "context, " : "", - (flags & R128_UPLOAD_SETUP) ? "setup, " : "", - (flags & R128_UPLOAD_TEX0) ? "tex0, " : "", - (flags & R128_UPLOAD_TEX1) ? "tex1, " : "", - (flags & R128_UPLOAD_MASKS) ? "masks, " : "", - (flags & R128_UPLOAD_WINDOW) ? "window, " : "", - (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", - (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : ""); -} - -static void r128_cce_dispatch_clear(struct drm_device *dev, - drm_r128_clear_t *clear) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - unsigned int flags = clear->flags; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - if (dev_priv->page_flipping && dev_priv->current_page == 1) { - unsigned int tmp = flags; - - flags &= ~(R128_FRONT | R128_BACK); - if (tmp & R128_FRONT) - flags |= R128_BACK; - if (tmp & R128_BACK) - flags |= R128_FRONT; - } - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", - pbox[i].x1, pbox[i].y1, pbox[i].x2, - pbox[i].y2, flags); - - if (flags & (R128_FRONT | R128_BACK)) { - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0)); - OUT_RING(clear->color_mask); - - ADVANCE_RING(); - } - - if (flags & R128_FRONT) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS); - - OUT_RING(dev_priv->front_pitch_offset_c); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - if (flags & R128_BACK) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS); - - OUT_RING(dev_priv->back_pitch_offset_c); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - if (flags & R128_DEPTH) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(clear->clear_depth); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - } -} - -static void r128_cce_dispatch_swap(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - -#if R128_PERFORMANCE_BOXES - /* Do some trivial performance monitoring... - */ - r128_cce_performance_boxes(dev_priv); -#endif - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - BEGIN_RING(7); - - OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); - OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->color_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS); - - /* Make this work even if front & back are flipped: - */ - if (dev_priv->current_page == 0) { - OUT_RING(dev_priv->back_pitch_offset_c); - OUT_RING(dev_priv->front_pitch_offset_c); - } else { - OUT_RING(dev_priv->front_pitch_offset_c); - OUT_RING(dev_priv->back_pitch_offset_c); - } - - OUT_RING((x << 16) | y); - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->last_frame++; - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); - OUT_RING(dev_priv->sarea_priv->last_frame); - - ADVANCE_RING(); -} - -static void r128_cce_dispatch_flip(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG("page=%d pfCurrentPage=%d\n", - dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); - -#if R128_PERFORMANCE_BOXES - /* Do some trivial performance monitoring... - */ - r128_cce_performance_boxes(dev_priv); -#endif - - BEGIN_RING(4); - - R128_WAIT_UNTIL_PAGE_FLIPPED(); - OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0)); - - if (dev_priv->current_page == 0) - OUT_RING(dev_priv->back_offset); - else - OUT_RING(dev_priv->front_offset); - - ADVANCE_RING(); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - dev_priv->sarea_priv->last_frame++; - dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = - 1 - dev_priv->current_page; - - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0)); - OUT_RING(dev_priv->sarea_priv->last_frame); - - ADVANCE_RING(); -} - -static void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = buf->bus_address; - int size = buf->used; - int prim = buf_priv->prim; - int i = 0; - RING_LOCALS; - DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox); - - if (0) - r128_print_dirty("dispatch_vertex", sarea_priv->dirty); - - if (buf->used) { - buf_priv->dispatched = 1; - - if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) - r128_emit_state(dev_priv); - - do { - /* Emit the next set of up to three cliprects */ - if (i < sarea_priv->nbox) { - r128_emit_clip_rects(dev_priv, - &sarea_priv->boxes[i], - sarea_priv->nbox - i); - } - - /* Emit the vertex buffer rendering commands */ - BEGIN_RING(5); - - OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3)); - OUT_RING(offset); - OUT_RING(size); - OUT_RING(format); - OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST | - (size << R128_CCE_VC_CNTL_NUM_SHIFT)); - - ADVANCE_RING(); - - i += 3; - } while (i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); - OUT_RING(buf_priv->age); - - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; - - sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; -} - -static void r128_cce_dispatch_indirect(struct drm_device *dev, - struct drm_buf *buf, int start, int end) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - RING_LOCALS; - DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); - - if (start != end) { - int offset = buf->bus_address + start; - int dwords = (end - start + 3) / sizeof(u32); - - /* Indirect buffer data must be an even number of - * dwords, so if we've been given an odd number we must - * pad the data with a Type-2 CCE packet. - */ - if (dwords & 1) { - u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = cpu_to_le32(R128_CCE_PACKET2); - } - - buf_priv->dispatched = 1; - - /* Fire off the indirect buffer */ - BEGIN_RING(3); - - OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1)); - OUT_RING(offset); - OUT_RING(dwords); - - ADVANCE_RING(); - } - - if (buf_priv->discard) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the indirect buffer age */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); - OUT_RING(buf_priv->age); - - ADVANCE_RING(); - - buf->pending = 1; - buf->used = 0; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; -} - -static void r128_cce_dispatch_indices(struct drm_device *dev, - struct drm_buf *buf, - int start, int end, int count) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv = buf->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - int format = sarea_priv->vc_format; - int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset; - int prim = buf_priv->prim; - u32 *data; - int dwords; - int i = 0; - RING_LOCALS; - DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count); - - if (0) - r128_print_dirty("dispatch_indices", sarea_priv->dirty); - - if (start != end) { - buf_priv->dispatched = 1; - - if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) - r128_emit_state(dev_priv); - - dwords = (end - start + 3) / sizeof(u32); - - data = (u32 *) ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - - data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, - dwords - 2)); - - data[1] = cpu_to_le32(offset); - data[2] = cpu_to_le32(R128_MAX_VB_VERTS); - data[3] = cpu_to_le32(format); - data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND | - (count << 16))); - - if (count & 0x1) { -#ifdef __LITTLE_ENDIAN - data[dwords - 1] &= 0x0000ffff; -#else - data[dwords - 1] &= 0xffff0000; -#endif - } - - do { - /* Emit the next set of up to three cliprects */ - if (i < sarea_priv->nbox) { - r128_emit_clip_rects(dev_priv, - &sarea_priv->boxes[i], - sarea_priv->nbox - i); - } - - r128_cce_dispatch_indirect(dev, buf, start, end); - - i += 3; - } while (i < sarea_priv->nbox); - } - - if (buf_priv->discard) { - buf_priv->age = dev_priv->sarea_priv->last_dispatch; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0)); - OUT_RING(buf_priv->age); - - ADVANCE_RING(); - - buf->pending = 1; - /* FIXME: Check dispatched field */ - buf_priv->dispatched = 0; - } - - dev_priv->sarea_priv->last_dispatch++; - - sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS; - sarea_priv->nbox = 0; -} - -static int r128_cce_dispatch_blit(struct drm_device *dev, - struct drm_file *file_priv, - drm_r128_blit_t *blit) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - u32 *data; - int dword_shift, dwords; - RING_LOCALS; - DRM_DEBUG("\n"); - - /* The compiler won't optimize away a division by a variable, - * even if the only legal values are powers of two. Thus, we'll - * use a shift instead. - */ - switch (blit->format) { - case R128_DATATYPE_ARGB8888: - dword_shift = 0; - break; - case R128_DATATYPE_ARGB1555: - case R128_DATATYPE_RGB565: - case R128_DATATYPE_ARGB4444: - case R128_DATATYPE_YVYU422: - case R128_DATATYPE_VYUY422: - dword_shift = 1; - break; - case R128_DATATYPE_CI8: - case R128_DATATYPE_RGB8: - dword_shift = 2; - break; - default: - DRM_ERROR("invalid blit format %d\n", blit->format); - return -EINVAL; - } - - /* Flush the pixel cache, and mark the contents as Read Invalid. - * This ensures no pixel data gets mixed up with the texture - * data from the host data blit, otherwise part of the texture - * image may be corrupted. - */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); - OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI); - - ADVANCE_RING(); - - /* Dispatch the indirect buffer. - */ - buf = dma->buflist[blit->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", blit->idx); - return -EINVAL; - } - - buf_priv->discard = 1; - - dwords = (blit->width * blit->height) >> dword_shift; - - data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); - - data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6)); - data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (blit->format << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_HOST_DATA | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS)); - - data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5)); - data[3] = cpu_to_le32(0xffffffff); - data[4] = cpu_to_le32(0xffffffff); - data[5] = cpu_to_le32((blit->y << 16) | blit->x); - data[6] = cpu_to_le32((blit->height << 16) | blit->width); - data[7] = cpu_to_le32(dwords); - - buf->used = (dwords + 8) * sizeof(u32); - - r128_cce_dispatch_indirect(dev, buf, 0, buf->used); - - /* Flush the pixel cache after the blit completes. This ensures - * the texture data is written out to memory before rendering - * continues. - */ - BEGIN_RING(2); - - OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0)); - OUT_RING(R128_PC_FLUSH_GUI); - - ADVANCE_RING(); - - return 0; -} - -/* ================================================================ - * Tiled depth buffer management - * - * FIXME: These should all set the destination write mask for when we - * have hardware stencil support. - */ - -static int r128_cce_dispatch_write_span(struct drm_device *dev, - drm_r128_depth_t *depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, x, y; - u32 *buffer; - u8 *mask; - int i, buffer_size, mask_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) - return -EFAULT; - if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) - return -EFAULT; - - buffer_size = depth->n * sizeof(u32); - buffer = kmalloc(buffer_size, GFP_KERNEL); - if (buffer == NULL) - return -ENOMEM; - if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { - kfree(buffer); - return -EFAULT; - } - - mask_size = depth->n * sizeof(u8); - if (depth->mask) { - mask = kmalloc(mask_size, GFP_KERNEL); - if (mask == NULL) { - kfree(buffer); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { - kfree(buffer); - kfree(mask); - return -EFAULT; - } - - for (i = 0; i < count; i++, x++) { - if (mask[i]) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x << 16) | y); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - kfree(mask); - } else { - for (i = 0; i < count; i++, x++) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x << 16) | y); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - kfree(buffer); - - return 0; -} - -static int r128_cce_dispatch_write_pixels(struct drm_device *dev, - drm_r128_depth_t *depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, *x, *y; - u32 *buffer; - u8 *mask; - int i, xbuf_size, ybuf_size, buffer_size, mask_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - xbuf_size = count * sizeof(*x); - ybuf_size = count * sizeof(*y); - x = kmalloc(xbuf_size, GFP_KERNEL); - if (x == NULL) - return -ENOMEM; - y = kmalloc(ybuf_size, GFP_KERNEL); - if (y == NULL) { - kfree(x); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { - kfree(x); - kfree(y); - return -EFAULT; - } - if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { - kfree(x); - kfree(y); - return -EFAULT; - } - - buffer_size = depth->n * sizeof(u32); - buffer = kmalloc(buffer_size, GFP_KERNEL); - if (buffer == NULL) { - kfree(x); - kfree(y); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { - kfree(x); - kfree(y); - kfree(buffer); - return -EFAULT; - } - - if (depth->mask) { - mask_size = depth->n * sizeof(u8); - mask = kmalloc(mask_size, GFP_KERNEL); - if (mask == NULL) { - kfree(x); - kfree(y); - kfree(buffer); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { - kfree(x); - kfree(y); - kfree(buffer); - kfree(mask); - return -EFAULT; - } - - for (i = 0; i < count; i++) { - if (mask[i]) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x[i] << 16) | y[i]); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - kfree(mask); - } else { - for (i = 0; i < count; i++) { - BEGIN_RING(6); - - OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4)); - OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_P | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(buffer[i]); - - OUT_RING((x[i] << 16) | y[i]); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - } - - kfree(x); - kfree(y); - kfree(buffer); - - return 0; -} - -static int r128_cce_dispatch_read_span(struct drm_device *dev, - drm_r128_depth_t *depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, x, y; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) - return -EFAULT; - if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) - return -EFAULT; - - BEGIN_RING(7); - - OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); - OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(dev_priv->span_pitch_offset_c); - - OUT_RING((x << 16) | y); - OUT_RING((0 << 16) | 0); - OUT_RING((count << 16) | 1); - - ADVANCE_RING(); - - return 0; -} - -static int r128_cce_dispatch_read_pixels(struct drm_device *dev, - drm_r128_depth_t *depth) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int count, *x, *y; - int i, xbuf_size, ybuf_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - count = depth->n; - if (count > 4096 || count <= 0) - return -EMSGSIZE; - - if (count > dev_priv->depth_pitch) - count = dev_priv->depth_pitch; - - xbuf_size = count * sizeof(*x); - ybuf_size = count * sizeof(*y); - x = kmalloc(xbuf_size, GFP_KERNEL); - if (x == NULL) - return -ENOMEM; - y = kmalloc(ybuf_size, GFP_KERNEL); - if (y == NULL) { - kfree(x); - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { - kfree(x); - kfree(y); - return -EFAULT; - } - if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { - kfree(x); - kfree(y); - return -EFAULT; - } - - for (i = 0; i < count; i++) { - BEGIN_RING(7); - - OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5)); - OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL | - R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_NONE | - (dev_priv->depth_fmt << 8) | - R128_GMC_SRC_DATATYPE_COLOR | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS); - - OUT_RING(dev_priv->depth_pitch_offset_c); - OUT_RING(dev_priv->span_pitch_offset_c); - - OUT_RING((x[i] << 16) | y[i]); - OUT_RING((i << 16) | 0); - OUT_RING((1 << 16) | 1); - - ADVANCE_RING(); - } - - kfree(x); - kfree(y); - - return 0; -} - -/* ================================================================ - * Polygon stipple - */ - -static void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(33); - - OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31)); - for (i = 0; i < 32; i++) - OUT_RING(stipple[i]); - - ADVANCE_RING(); -} - -/* ================================================================ - * IOCTL functions - */ - -static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv; - drm_r128_clear_t *clear = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - sarea_priv = dev_priv->sarea_priv; - - if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - - r128_cce_dispatch_clear(dev, clear); - COMMIT_RING(); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; - - return 0; -} - -static int r128_do_init_pageflip(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET); - dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL); - - R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset); - R128_WRITE(R128_CRTC_OFFSET_CNTL, - dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL); - - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; - - return 0; -} - -static int r128_do_cleanup_pageflip(struct drm_device *dev) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset); - R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl); - - if (dev_priv->current_page != 0) { - r128_cce_dispatch_flip(dev); - COMMIT_RING(); - } - - dev_priv->page_flipping = 0; - return 0; -} - -/* Swapping and flipping are different operations, need different ioctls. - * They can & should be intermixed to support multiple 3d windows. - */ - -static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (!dev_priv->page_flipping) - r128_do_init_pageflip(dev); - - r128_cce_dispatch_flip(dev); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - - r128_cce_dispatch_swap(dev); - dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_MASKS); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_vertex_t *vertex = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); - - if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - vertex->idx, dma->buf_count - 1); - return -EINVAL; - } - if (vertex->prim < 0 || - vertex->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { - DRM_ERROR("buffer prim %d\n", vertex->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[vertex->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex->idx); - return -EINVAL; - } - - buf->used = vertex->count; - buf_priv->prim = vertex->prim; - buf_priv->discard = vertex->discard; - - r128_cce_dispatch_vertex(dev, buf); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_indices_t *elts = data; - int count; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, - elts->idx, elts->start, elts->end, elts->discard); - - if (elts->idx < 0 || elts->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - elts->idx, dma->buf_count - 1); - return -EINVAL; - } - if (elts->prim < 0 || - elts->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) { - DRM_ERROR("buffer prim %d\n", elts->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[elts->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", elts->idx); - return -EINVAL; - } - - count = (elts->end - elts->start) / sizeof(u16); - elts->start -= R128_INDEX_PRIM_OFFSET; - - if (elts->start & 0x7) { - DRM_ERROR("misaligned buffer 0x%x\n", elts->start); - return -EINVAL; - } - if (elts->start < buf->used) { - DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); - return -EINVAL; - } - - buf->used = elts->end; - buf_priv->prim = elts->prim; - buf_priv->discard = elts->discard; - - r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_blit_t *blit = data; - int ret; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx); - - if (blit->idx < 0 || blit->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - blit->idx, dma->buf_count - 1); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - ret = r128_cce_dispatch_blit(dev, file_priv, blit); - - COMMIT_RING(); - return ret; -} - -static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_depth_t *depth = data; - int ret; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - ret = -EINVAL; - switch (depth->func) { - case R128_WRITE_SPAN: - ret = r128_cce_dispatch_write_span(dev, depth); - break; - case R128_WRITE_PIXELS: - ret = r128_cce_dispatch_write_pixels(dev, depth); - break; - case R128_READ_SPAN: - ret = r128_cce_dispatch_read_span(dev, depth); - break; - case R128_READ_PIXELS: - ret = r128_cce_dispatch_read_pixels(dev, depth); - break; - } - - COMMIT_RING(); - return ret; -} - -static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_stipple_t *stipple = data; - u32 mask[32]; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) - return -EFAULT; - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - r128_cce_dispatch_stipple(dev, mask); - - COMMIT_RING(); - return 0; -} - -static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_r128_buf_priv_t *buf_priv; - drm_r128_indirect_t *indirect = data; -#if 0 - RING_LOCALS; -#endif - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", - indirect->idx, indirect->start, indirect->end, - indirect->discard); - - if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - indirect->idx, dma->buf_count - 1); - return -EINVAL; - } - - buf = dma->buflist[indirect->idx]; - buf_priv = buf->dev_private; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", indirect->idx); - return -EINVAL; - } - - if (indirect->start < buf->used) { - DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", - indirect->start, buf->used); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf->used = indirect->end; - buf_priv->discard = indirect->discard; - -#if 0 - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); -#endif - - /* Dispatch the indirect buffer full of commands from the - * X server. This is insecure and is thus only available to - * privileged clients. - */ - r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end); - - COMMIT_RING(); - return 0; -} - -static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_getparam_t *param = data; - int value; - - DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - switch (param->param) { - case R128_PARAM_IRQ_NR: - value = drm_dev_to_irq(dev); - break; - default: - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_r128_private_t *dev_priv = dev->dev_private; - if (dev_priv->page_flipping) - r128_do_cleanup_pageflip(dev); - } -} -void r128_driver_lastclose(struct drm_device *dev) -{ - r128_do_cleanup_cce(dev); -} - -struct drm_ioctl_desc r128_ioctls[] = { - DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH), - DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), -}; - -int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/Kconfig b/ANDROID_3.4.5/drivers/gpu/drm/radeon/Kconfig deleted file mode 100644 index ea92bbe3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/Kconfig +++ /dev/null @@ -1,31 +0,0 @@ -config DRM_RADEON_KMS - bool "Enable modesetting on radeon by default - NEW DRIVER" - depends on DRM_RADEON - select BACKLIGHT_CLASS_DEVICE - help - Choose this option if you want kernel modesetting enabled by default. - - This is a completely new driver. It's only part of the existing drm - for compatibility reasons. It requires an entirely different graphics - stack above it and works very differently from the old drm stack. - i.e. don't enable this unless you know what you are doing it may - cause issues or bugs compared to the previous userspace driver stack. - - When kernel modesetting is enabled the IOCTL of radeon/drm - driver are considered as invalid and an error message is printed - in the log and they return failure. - - KMS enabled userspace will use new API to talk with the radeon/drm - driver. The new API provide functions to create/destroy/share/mmap - buffer object which are then managed by the kernel memory manager - (here TTM). In order to submit command to the GPU the userspace - provide a buffer holding the command stream, along this buffer - userspace have to provide a list of buffer object used by the - command stream. The kernel radeon driver will then place buffer - in GPU accessible memory and will update command stream to reflect - the position of the different buffers. - - The kernel will also perform security check on command stream - provided by the user, we want to catch and forbid any illegal use - of the GPU such as DMA into random system memory or into memory - not owned by the process supplying the command stream. diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/radeon/Makefile deleted file mode 100644 index 9d837299..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y := -Iinclude/drm - -hostprogs-y := mkregtable -clean-files := rn50_reg_safe.h r100_reg_safe.h r200_reg_safe.h rv515_reg_safe.h r300_reg_safe.h r420_reg_safe.h rs600_reg_safe.h r600_reg_safe.h evergreen_reg_safe.h cayman_reg_safe.h - -quiet_cmd_mkregtable = MKREGTABLE $@ - cmd_mkregtable = $(obj)/mkregtable $< > $@ - -$(obj)/rn50_reg_safe.h: $(src)/reg_srcs/rn50 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/r100_reg_safe.h: $(src)/reg_srcs/r100 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/r200_reg_safe.h: $(src)/reg_srcs/r200 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/r420_reg_safe.h: $(src)/reg_srcs/r420 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/cayman_reg_safe.h: $(src)/reg_srcs/cayman $(obj)/mkregtable - $(call if_changed,mkregtable) - -$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h - -$(obj)/r200.o: $(obj)/r200_reg_safe.h - -$(obj)/rv515.o: $(obj)/rv515_reg_safe.h - -$(obj)/r300.o: $(obj)/r300_reg_safe.h - -$(obj)/r420.o: $(obj)/r420_reg_safe.h - -$(obj)/rs600.o: $(obj)/rs600_reg_safe.h - -$(obj)/r600_cs.o: $(obj)/r600_reg_safe.h - -$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h $(obj)/cayman_reg_safe.h - -radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ - radeon_irq.o r300_cmdbuf.o r600_cp.o -# add KMS driver -radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ - radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \ - atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \ - radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \ - radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \ - radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ - radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ - rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ - r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ - r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ - evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ - radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \ - radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o si_blit_shaders.o - -radeon-$(CONFIG_COMPAT) += radeon_ioc32.o -radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o -radeon-$(CONFIG_ACPI) += radeon_acpi.o - -obj-$(CONFIG_DRM_RADEON)+= radeon.o - -CFLAGS_radeon_trace_points.o := -I$(src) diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/ObjectID.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/ObjectID.h deleted file mode 100644 index ca4b0380..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/ObjectID.h +++ /dev/null @@ -1,696 +0,0 @@ -/* -* Copyright 2006-2007 Advanced Micro Devices, Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining a -* copy of this software and associated documentation files (the "Software"), -* to deal in the Software without restriction, including without limitation -* the rights to use, copy, modify, merge, publish, distribute, sublicense, -* and/or sell copies of the Software, and to permit persons to whom the -* Software is furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -* OTHER DEALINGS IN THE SOFTWARE. -*/ -/* based on stg/asic_reg/drivers/inc/asic_reg/ObjectID.h ver 23 */ - -#ifndef _OBJECTID_H -#define _OBJECTID_H - -#if defined(_X86_) -#pragma pack(1) -#endif - -/****************************************************/ -/* Graphics Object Type Definition */ -/****************************************************/ -#define GRAPH_OBJECT_TYPE_NONE 0x0 -#define GRAPH_OBJECT_TYPE_GPU 0x1 -#define GRAPH_OBJECT_TYPE_ENCODER 0x2 -#define GRAPH_OBJECT_TYPE_CONNECTOR 0x3 -#define GRAPH_OBJECT_TYPE_ROUTER 0x4 -/* deleted */ -#define GRAPH_OBJECT_TYPE_DISPLAY_PATH 0x6 -#define GRAPH_OBJECT_TYPE_GENERIC 0x7 - -/****************************************************/ -/* Encoder Object ID Definition */ -/****************************************************/ -#define ENCODER_OBJECT_ID_NONE 0x00 - -/* Radeon Class Display Hardware */ -#define ENCODER_OBJECT_ID_INTERNAL_LVDS 0x01 -#define ENCODER_OBJECT_ID_INTERNAL_TMDS1 0x02 -#define ENCODER_OBJECT_ID_INTERNAL_TMDS2 0x03 -#define ENCODER_OBJECT_ID_INTERNAL_DAC1 0x04 -#define ENCODER_OBJECT_ID_INTERNAL_DAC2 0x05 /* TV/CV DAC */ -#define ENCODER_OBJECT_ID_INTERNAL_SDVOA 0x06 -#define ENCODER_OBJECT_ID_INTERNAL_SDVOB 0x07 - -/* External Third Party Encoders */ -#define ENCODER_OBJECT_ID_SI170B 0x08 -#define ENCODER_OBJECT_ID_CH7303 0x09 -#define ENCODER_OBJECT_ID_CH7301 0x0A -#define ENCODER_OBJECT_ID_INTERNAL_DVO1 0x0B /* This belongs to Radeon Class Display Hardware */ -#define ENCODER_OBJECT_ID_EXTERNAL_SDVOA 0x0C -#define ENCODER_OBJECT_ID_EXTERNAL_SDVOB 0x0D -#define ENCODER_OBJECT_ID_TITFP513 0x0E -#define ENCODER_OBJECT_ID_INTERNAL_LVTM1 0x0F /* not used for Radeon */ -#define ENCODER_OBJECT_ID_VT1623 0x10 -#define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 -#define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 -#define ENCODER_OBJECT_ID_ALMOND 0x22 -#define ENCODER_OBJECT_ID_TRAVIS 0x23 -#define ENCODER_OBJECT_ID_NUTMEG 0x22 -/* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */ -#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 -#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 -#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 0x15 -#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 0x16 /* Shared with CV/TV and CRT */ -#define ENCODER_OBJECT_ID_SI178 0X17 /* External TMDS (dual link, no HDCP.) */ -#define ENCODER_OBJECT_ID_MVPU_FPGA 0x18 /* MVPU FPGA chip */ -#define ENCODER_OBJECT_ID_INTERNAL_DDI 0x19 -#define ENCODER_OBJECT_ID_VT1625 0x1A -#define ENCODER_OBJECT_ID_HDMI_SI1932 0x1B -#define ENCODER_OBJECT_ID_DP_AN9801 0x1C -#define ENCODER_OBJECT_ID_DP_DP501 0x1D -#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY 0x1E -#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA 0x1F -#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 0x20 -#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 0x21 -#define ENCODER_OBJECT_ID_INTERNAL_VCE 0x24 - -#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO 0xFF - -/****************************************************/ -/* Connector Object ID Definition */ -/****************************************************/ -#define CONNECTOR_OBJECT_ID_NONE 0x00 -#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I 0x01 -#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I 0x02 -#define CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D 0x03 -#define CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D 0x04 -#define CONNECTOR_OBJECT_ID_VGA 0x05 -#define CONNECTOR_OBJECT_ID_COMPOSITE 0x06 -#define CONNECTOR_OBJECT_ID_SVIDEO 0x07 -#define CONNECTOR_OBJECT_ID_YPbPr 0x08 -#define CONNECTOR_OBJECT_ID_D_CONNECTOR 0x09 -#define CONNECTOR_OBJECT_ID_9PIN_DIN 0x0A /* Supports both CV & TV */ -#define CONNECTOR_OBJECT_ID_SCART 0x0B -#define CONNECTOR_OBJECT_ID_HDMI_TYPE_A 0x0C -#define CONNECTOR_OBJECT_ID_HDMI_TYPE_B 0x0D -#define CONNECTOR_OBJECT_ID_LVDS 0x0E -#define CONNECTOR_OBJECT_ID_7PIN_DIN 0x0F -#define CONNECTOR_OBJECT_ID_PCIE_CONNECTOR 0x10 -#define CONNECTOR_OBJECT_ID_CROSSFIRE 0x11 -#define CONNECTOR_OBJECT_ID_HARDCODE_DVI 0x12 -#define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 -#define CONNECTOR_OBJECT_ID_eDP 0x14 -#define CONNECTOR_OBJECT_ID_MXM 0x15 -#define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16 - -/* deleted */ - -/****************************************************/ -/* Router Object ID Definition */ -/****************************************************/ -#define ROUTER_OBJECT_ID_NONE 0x00 -#define ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL 0x01 - -/****************************************************/ -/* Generic Object ID Definition */ -/****************************************************/ -#define GENERIC_OBJECT_ID_NONE 0x00 -#define GENERIC_OBJECT_ID_GLSYNC 0x01 -#define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 -#define GENERIC_OBJECT_ID_MXM_OPM 0x03 -#define GENERIC_OBJECT_ID_STEREO_PIN 0x04 //This object could show up from Misc Object table, it follows ATOM_OBJECT format, and contains one ATOM_OBJECT_GPIO_CNTL_RECORD for the stereo pin - -/****************************************************/ -/* Graphics Object ENUM ID Definition */ -/****************************************************/ -#define GRAPH_OBJECT_ENUM_ID1 0x01 -#define GRAPH_OBJECT_ENUM_ID2 0x02 -#define GRAPH_OBJECT_ENUM_ID3 0x03 -#define GRAPH_OBJECT_ENUM_ID4 0x04 -#define GRAPH_OBJECT_ENUM_ID5 0x05 -#define GRAPH_OBJECT_ENUM_ID6 0x06 -#define GRAPH_OBJECT_ENUM_ID7 0x07 - -/****************************************************/ -/* Graphics Object ID Bit definition */ -/****************************************************/ -#define OBJECT_ID_MASK 0x00FF -#define ENUM_ID_MASK 0x0700 -#define RESERVED1_ID_MASK 0x0800 -#define OBJECT_TYPE_MASK 0x7000 -#define RESERVED2_ID_MASK 0x8000 - -#define OBJECT_ID_SHIFT 0x00 -#define ENUM_ID_SHIFT 0x08 -#define OBJECT_TYPE_SHIFT 0x0C - - -/****************************************************/ -/* Graphics Object family definition */ -/****************************************************/ -#define CONSTRUCTOBJECTFAMILYID(GRAPHICS_OBJECT_TYPE, GRAPHICS_OBJECT_ID) (GRAPHICS_OBJECT_TYPE << OBJECT_TYPE_SHIFT | \ - GRAPHICS_OBJECT_ID << OBJECT_ID_SHIFT) -/****************************************************/ -/* GPU Object ID definition - Shared with BIOS */ -/****************************************************/ -#define GPU_ENUM_ID1 ( GRAPH_OBJECT_TYPE_GPU << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT) - -/****************************************************/ -/* Encoder Object ID definition - Shared with BIOS */ -/****************************************************/ -/* -#define ENCODER_INTERNAL_LVDS_ENUM_ID1 0x2101 -#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 0x2102 -#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 0x2103 -#define ENCODER_INTERNAL_DAC1_ENUM_ID1 0x2104 -#define ENCODER_INTERNAL_DAC2_ENUM_ID1 0x2105 -#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 0x2106 -#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 0x2107 -#define ENCODER_SIL170B_ENUM_ID1 0x2108 -#define ENCODER_CH7303_ENUM_ID1 0x2109 -#define ENCODER_CH7301_ENUM_ID1 0x210A -#define ENCODER_INTERNAL_DVO1_ENUM_ID1 0x210B -#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 0x210C -#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 0x210D -#define ENCODER_TITFP513_ENUM_ID1 0x210E -#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 0x210F -#define ENCODER_VT1623_ENUM_ID1 0x2110 -#define ENCODER_HDMI_SI1930_ENUM_ID1 0x2111 -#define ENCODER_HDMI_INTERNAL_ENUM_ID1 0x2112 -#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 0x2113 -#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 0x2114 -#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 0x2115 -#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 0x2116 -#define ENCODER_SI178_ENUM_ID1 0x2117 -#define ENCODER_MVPU_FPGA_ENUM_ID1 0x2118 -#define ENCODER_INTERNAL_DDI_ENUM_ID1 0x2119 -#define ENCODER_VT1625_ENUM_ID1 0x211A -#define ENCODER_HDMI_SI1932_ENUM_ID1 0x211B -#define ENCODER_ENCODER_DP_AN9801_ENUM_ID1 0x211C -#define ENCODER_DP_DP501_ENUM_ID1 0x211D -#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 0x211E -*/ -#define ENCODER_INTERNAL_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_LVDS << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_TMDS1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_TMDS2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_TMDS2 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DAC1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DAC2 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_SDVOB << OBJECT_ID_SHIFT) - -#define ENCODER_SIL170B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_SI170B << OBJECT_ID_SHIFT) - -#define ENCODER_CH7303_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_CH7303 << OBJECT_ID_SHIFT) - -#define ENCODER_CH7301_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_CH7301 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DVO1 << OBJECT_ID_SHIFT) - -#define ENCODER_EXTERNAL_SDVOA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) - -#define ENCODER_EXTERNAL_SDVOA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_EXTERNAL_SDVOA << OBJECT_ID_SHIFT) - - -#define ENCODER_EXTERNAL_SDVOB_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_EXTERNAL_SDVOB << OBJECT_ID_SHIFT) - - -#define ENCODER_TITFP513_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_TITFP513 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_LVTM1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_LVTM1 << OBJECT_ID_SHIFT) - -#define ENCODER_VT1623_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_VT1623 << OBJECT_ID_SHIFT) - -#define ENCODER_HDMI_SI1930_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_HDMI_SI1930 << OBJECT_ID_SHIFT) - -#define ENCODER_HDMI_INTERNAL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_HDMI_INTERNAL << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) - - -#define ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 << OBJECT_ID_SHIFT) - - -#define ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2 << OBJECT_ID_SHIFT) // Shared with CV/TV and CRT - -#define ENCODER_SI178_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_SI178 << OBJECT_ID_SHIFT) - -#define ENCODER_MVPU_FPGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_MVPU_FPGA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_DDI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_DDI << OBJECT_ID_SHIFT) - -#define ENCODER_VT1625_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_VT1625 << OBJECT_ID_SHIFT) - -#define ENCODER_HDMI_SI1932_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_HDMI_SI1932 << OBJECT_ID_SHIFT) - -#define ENCODER_DP_DP501_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_DP_DP501 << OBJECT_ID_SHIFT) - -#define ENCODER_DP_AN9801_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_DP_AN9801 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_KLDSCP_LVTMA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY1_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY1 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) - -#define ENCODER_INTERNAL_UNIPHY2_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT) - -#define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) - -#define ENCODER_ALMOND_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT) - -#define ENCODER_ALMOND_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT) - -#define ENCODER_TRAVIS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT) - -#define ENCODER_TRAVIS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT) - -#define ENCODER_NUTMEG_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT) - -#define ENCODER_VCE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT) - -/****************************************************/ -/* Connector Object ID definition - Shared with BIOS */ -/****************************************************/ -/* -#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 0x3101 -#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 0x3102 -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 0x3103 -#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 0x3104 -#define CONNECTOR_VGA_ENUM_ID1 0x3105 -#define CONNECTOR_COMPOSITE_ENUM_ID1 0x3106 -#define CONNECTOR_SVIDEO_ENUM_ID1 0x3107 -#define CONNECTOR_YPbPr_ENUM_ID1 0x3108 -#define CONNECTOR_D_CONNECTORE_ENUM_ID1 0x3109 -#define CONNECTOR_9PIN_DIN_ENUM_ID1 0x310A -#define CONNECTOR_SCART_ENUM_ID1 0x310B -#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 0x310C -#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 0x310D -#define CONNECTOR_LVDS_ENUM_ID1 0x310E -#define CONNECTOR_7PIN_DIN_ENUM_ID1 0x310F -#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 0x3110 -*/ -#define CONNECTOR_LVDS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) - -#define CONNECTOR_LVDS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_LVDS << OBJECT_ID_SHIFT) - -#define CONNECTOR_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT) - -#define CONNECTOR_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_eDP << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_I_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) - -#define CONNECTOR_VGA_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) - -#define CONNECTOR_VGA_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT) - -#define CONNECTOR_COMPOSITE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) - -#define CONNECTOR_COMPOSITE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_COMPOSITE << OBJECT_ID_SHIFT) - -#define CONNECTOR_SVIDEO_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) - -#define CONNECTOR_SVIDEO_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SVIDEO << OBJECT_ID_SHIFT) - -#define CONNECTOR_YPbPr_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) - -#define CONNECTOR_YPbPr_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_YPbPr << OBJECT_ID_SHIFT) - -#define CONNECTOR_D_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_D_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_D_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_9PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) - -#define CONNECTOR_9PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_9PIN_DIN << OBJECT_ID_SHIFT) - -#define CONNECTOR_SCART_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) - -#define CONNECTOR_SCART_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_SCART << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_A_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_A_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_A_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_B_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) - -#define CONNECTOR_HDMI_TYPE_B_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT) - -#define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) - -#define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) - -#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_PCIE_CONNECTOR_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_PCIE_CONNECTOR << OBJECT_ID_SHIFT) - -#define CONNECTOR_CROSSFIRE_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) - -#define CONNECTOR_CROSSFIRE_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_CROSSFIRE << OBJECT_ID_SHIFT) - - -#define CONNECTOR_HARDCODE_DVI_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) - -#define CONNECTOR_HARDCODE_DVI_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_HARDCODE_DVI << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_DISPLAYPORT_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_DISPLAYPORT << OBJECT_ID_SHIFT) - -#define CONNECTOR_MXM_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_A - -#define CONNECTOR_MXM_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_B - -#define CONNECTOR_MXM_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_C - -#define CONNECTOR_MXM_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DP_D - -#define CONNECTOR_MXM_ENUM_ID5 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_TXxx - -#define CONNECTOR_MXM_ENUM_ID6 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_LVDS_UXxx - -#define CONNECTOR_MXM_ENUM_ID7 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC - -#define CONNECTOR_LVDS_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT) - -#define CONNECTOR_LVDS_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT) - -/****************************************************/ -/* Router Object ID definition - Shared with BIOS */ -/****************************************************/ -#define ROUTER_I2C_EXTENDER_CNTL_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ROUTER << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - ROUTER_OBJECT_ID_I2C_EXTENDER_CNTL << OBJECT_ID_SHIFT) - -/* deleted */ - -/****************************************************/ -/* Generic Object ID definition - Shared with BIOS */ -/****************************************************/ -#define GENERICOBJECT_GLSYNC_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_GLSYNC << OBJECT_ID_SHIFT) - -#define GENERICOBJECT_PX2_NON_DRIVABLE_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT) - -#define GENERICOBJECT_PX2_NON_DRIVABLE_ID2 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_PX2_NON_DRIVABLE<< OBJECT_ID_SHIFT) - -#define GENERICOBJECT_MXM_OPM_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT) - -#define GENERICOBJECT_STEREO_PIN_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ - GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ - GENERIC_OBJECT_ID_STEREO_PIN << OBJECT_ID_SHIFT) - -/****************************************************/ -/* Object Cap definition - Shared with BIOS */ -/****************************************************/ -#define GRAPHICS_OBJECT_CAP_I2C 0x00000001L -#define GRAPHICS_OBJECT_CAP_TABLE_ID 0x00000002L - - -#define GRAPHICS_OBJECT_I2CCOMMAND_TABLE_ID 0x01 -#define GRAPHICS_OBJECT_HOTPLUGDETECTIONINTERUPT_TABLE_ID 0x02 -#define GRAPHICS_OBJECT_ENCODER_OUTPUT_PROTECTION_TABLE_ID 0x03 - -#if defined(_X86_) -#pragma pack() -#endif - -#endif /*GRAPHICTYPE */ - - - - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-bits.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-bits.h deleted file mode 100644 index e8fae5c7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-bits.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Author: Stanislaw Skowronek - */ - -#ifndef ATOM_BITS_H -#define ATOM_BITS_H - -static inline uint8_t get_u8(void *bios, int ptr) -{ - return ((unsigned char *)bios)[ptr]; -} -#define U8(ptr) get_u8(ctx->ctx->bios, (ptr)) -#define CU8(ptr) get_u8(ctx->bios, (ptr)) -static inline uint16_t get_u16(void *bios, int ptr) -{ - return get_u8(bios ,ptr)|(((uint16_t)get_u8(bios, ptr+1))<<8); -} -#define U16(ptr) get_u16(ctx->ctx->bios, (ptr)) -#define CU16(ptr) get_u16(ctx->bios, (ptr)) -static inline uint32_t get_u32(void *bios, int ptr) -{ - return get_u16(bios, ptr)|(((uint32_t)get_u16(bios, ptr+2))<<16); -} -#define U32(ptr) get_u32(ctx->ctx->bios, (ptr)) -#define CU32(ptr) get_u32(ctx->bios, (ptr)) -#define CSTR(ptr) (((char *)(ctx->bios))+(ptr)) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-names.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-names.h deleted file mode 100644 index 6f907a5f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-names.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Author: Stanislaw Skowronek - */ - -#ifndef ATOM_NAMES_H -#define ATOM_NAMES_H - -#include "atom.h" - -#ifdef ATOM_DEBUG - -#define ATOM_OP_NAMES_CNT 123 -static char *atom_op_names[ATOM_OP_NAMES_CNT] = { -"RESERVED", "MOVE_REG", "MOVE_PS", "MOVE_WS", "MOVE_FB", "MOVE_PLL", -"MOVE_MC", "AND_REG", "AND_PS", "AND_WS", "AND_FB", "AND_PLL", "AND_MC", -"OR_REG", "OR_PS", "OR_WS", "OR_FB", "OR_PLL", "OR_MC", "SHIFT_LEFT_REG", -"SHIFT_LEFT_PS", "SHIFT_LEFT_WS", "SHIFT_LEFT_FB", "SHIFT_LEFT_PLL", -"SHIFT_LEFT_MC", "SHIFT_RIGHT_REG", "SHIFT_RIGHT_PS", "SHIFT_RIGHT_WS", -"SHIFT_RIGHT_FB", "SHIFT_RIGHT_PLL", "SHIFT_RIGHT_MC", "MUL_REG", -"MUL_PS", "MUL_WS", "MUL_FB", "MUL_PLL", "MUL_MC", "DIV_REG", "DIV_PS", -"DIV_WS", "DIV_FB", "DIV_PLL", "DIV_MC", "ADD_REG", "ADD_PS", "ADD_WS", -"ADD_FB", "ADD_PLL", "ADD_MC", "SUB_REG", "SUB_PS", "SUB_WS", "SUB_FB", -"SUB_PLL", "SUB_MC", "SET_ATI_PORT", "SET_PCI_PORT", "SET_SYS_IO_PORT", -"SET_REG_BLOCK", "SET_FB_BASE", "COMPARE_REG", "COMPARE_PS", -"COMPARE_WS", "COMPARE_FB", "COMPARE_PLL", "COMPARE_MC", "SWITCH", -"JUMP", "JUMP_EQUAL", "JUMP_BELOW", "JUMP_ABOVE", "JUMP_BELOW_OR_EQUAL", -"JUMP_ABOVE_OR_EQUAL", "JUMP_NOT_EQUAL", "TEST_REG", "TEST_PS", "TEST_WS", -"TEST_FB", "TEST_PLL", "TEST_MC", "DELAY_MILLISEC", "DELAY_MICROSEC", -"CALL_TABLE", "REPEAT", "CLEAR_REG", "CLEAR_PS", "CLEAR_WS", "CLEAR_FB", -"CLEAR_PLL", "CLEAR_MC", "NOP", "EOT", "MASK_REG", "MASK_PS", "MASK_WS", -"MASK_FB", "MASK_PLL", "MASK_MC", "POST_CARD", "BEEP", "SAVE_REG", -"RESTORE_REG", "SET_DATA_BLOCK", "XOR_REG", "XOR_PS", "XOR_WS", "XOR_FB", -"XOR_PLL", "XOR_MC", "SHL_REG", "SHL_PS", "SHL_WS", "SHL_FB", "SHL_PLL", -"SHL_MC", "SHR_REG", "SHR_PS", "SHR_WS", "SHR_FB", "SHR_PLL", "SHR_MC", -"DEBUG", "CTB_DS", -}; - -#define ATOM_TABLE_NAMES_CNT 74 -static char *atom_table_names[ATOM_TABLE_NAMES_CNT] = { -"ASIC_Init", "GetDisplaySurfaceSize", "ASIC_RegistersInit", -"VRAM_BlockVenderDetection", "SetClocksRatio", "MemoryControllerInit", -"GPIO_PinInit", "MemoryParamAdjust", "DVOEncoderControl", -"GPIOPinControl", "SetEngineClock", "SetMemoryClock", "SetPixelClock", -"DynamicClockGating", "ResetMemoryDLL", "ResetMemoryDevice", -"MemoryPLLInit", "EnableMemorySelfRefresh", "AdjustMemoryController", -"EnableASIC_StaticPwrMgt", "ASIC_StaticPwrMgtStatusChange", -"DAC_LoadDetection", "TMDS2EncoderControl", "LCD1OutputControl", -"DAC1EncoderControl", "DAC2EncoderControl", "DVOOutputControl", -"CV1OutputControl", "SetCRTC_DPM_State", "TVEncoderControl", -"TMDS1EncoderControl", "LVDSEncoderControl", "TV1OutputControl", -"EnableScaler", "BlankCRTC", "EnableCRTC", "GetPixelClock", -"EnableVGA_Render", "EnableVGA_Access", "SetCRTC_Timing", -"SetCRTC_OverScan", "SetCRTC_Replication", "SelectCRTC_Source", -"EnableGraphSurfaces", "UpdateCRTC_DoubleBufferRegisters", -"LUT_AutoFill", "EnableHW_IconCursor", "GetMemoryClock", -"GetEngineClock", "SetCRTC_UsingDTDTiming", "TVBootUpStdPinDetection", -"DFP2OutputControl", "VRAM_BlockDetectionByStrap", "MemoryCleanUp", -"ReadEDIDFromHWAssistedI2C", "WriteOneByteToHWAssistedI2C", -"ReadHWAssistedI2CStatus", "SpeedFanControl", "PowerConnectorDetection", -"MC_Synchronization", "ComputeMemoryEnginePLL", "MemoryRefreshConversion", -"VRAM_GetCurrentInfoBlock", "DynamicMemorySettings", "MemoryTraining", -"EnableLVDS_SS", "DFP1OutputControl", "SetVoltage", "CRT1OutputControl", -"CRT2OutputControl", "SetupHWAssistedI2CStatus", "ClockSource", -"MemoryDeviceInit", "EnableYUV", -}; - -#define ATOM_IO_NAMES_CNT 5 -static char *atom_io_names[ATOM_IO_NAMES_CNT] = { -"MM", "PLL", "MC", "PCIE", "PCIE PORT", -}; - -#else - -#define ATOM_OP_NAMES_CNT 0 -#define ATOM_TABLE_NAMES_CNT 0 -#define ATOM_IO_NAMES_CNT 0 - -#endif - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-types.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-types.h deleted file mode 100644 index 1125b866..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom-types.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Author: Dave Airlie - */ - -#ifndef ATOM_TYPES_H -#define ATOM_TYPES_H - -/* sync atom types to kernel types */ - -typedef uint16_t USHORT; -typedef uint32_t ULONG; -typedef uint8_t UCHAR; - - -#ifndef ATOM_BIG_ENDIAN -#if defined(__BIG_ENDIAN) -#define ATOM_BIG_ENDIAN 1 -#else -#define ATOM_BIG_ENDIAN 0 -#endif -#endif -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.c deleted file mode 100644 index 5ce9bf51..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.c +++ /dev/null @@ -1,1406 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Author: Stanislaw Skowronek - */ - -#include -#include -#include -#include - -#define ATOM_DEBUG - -#include "atom.h" -#include "atom-names.h" -#include "atom-bits.h" -#include "radeon.h" - -#define ATOM_COND_ABOVE 0 -#define ATOM_COND_ABOVEOREQUAL 1 -#define ATOM_COND_ALWAYS 2 -#define ATOM_COND_BELOW 3 -#define ATOM_COND_BELOWOREQUAL 4 -#define ATOM_COND_EQUAL 5 -#define ATOM_COND_NOTEQUAL 6 - -#define ATOM_PORT_ATI 0 -#define ATOM_PORT_PCI 1 -#define ATOM_PORT_SYSIO 2 - -#define ATOM_UNIT_MICROSEC 0 -#define ATOM_UNIT_MILLISEC 1 - -#define PLL_INDEX 2 -#define PLL_DATA 3 - -typedef struct { - struct atom_context *ctx; - uint32_t *ps, *ws; - int ps_shift; - uint16_t start; - unsigned last_jump; - unsigned long last_jump_jiffies; - bool abort; -} atom_exec_context; - -int atom_debug = 0; -static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); -int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); - -static uint32_t atom_arg_mask[8] = - { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, -0xFF000000 }; -static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 }; - -static int atom_dst_to_src[8][4] = { - /* translate destination alignment field to the source alignment encoding */ - {0, 0, 0, 0}, - {1, 2, 3, 0}, - {1, 2, 3, 0}, - {1, 2, 3, 0}, - {4, 5, 6, 7}, - {4, 5, 6, 7}, - {4, 5, 6, 7}, - {4, 5, 6, 7}, -}; -static int atom_def_dst[8] = { 0, 0, 1, 2, 0, 1, 2, 3 }; - -static int debug_depth = 0; -#ifdef ATOM_DEBUG -static void debug_print_spaces(int n) -{ - while (n--) - printk(" "); -} - -#define DEBUG(...) do if (atom_debug) { printk(KERN_DEBUG __VA_ARGS__); } while (0) -#define SDEBUG(...) do if (atom_debug) { printk(KERN_DEBUG); debug_print_spaces(debug_depth); printk(__VA_ARGS__); } while (0) -#else -#define DEBUG(...) do { } while (0) -#define SDEBUG(...) do { } while (0) -#endif - -static uint32_t atom_iio_execute(struct atom_context *ctx, int base, - uint32_t index, uint32_t data) -{ - struct radeon_device *rdev = ctx->card->dev->dev_private; - uint32_t temp = 0xCDCDCDCD; - - while (1) - switch (CU8(base)) { - case ATOM_IIO_NOP: - base++; - break; - case ATOM_IIO_READ: - temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1)); - base += 3; - break; - case ATOM_IIO_WRITE: - if (rdev->family == CHIP_RV515) - (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1)); - ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); - base += 3; - break; - case ATOM_IIO_CLEAR: - temp &= - ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << - CU8(base + 2)); - base += 3; - break; - case ATOM_IIO_SET: - temp |= - (0xFFFFFFFF >> (32 - CU8(base + 1))) << CU8(base + - 2); - base += 3; - break; - case ATOM_IIO_MOVE_INDEX: - temp &= - ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << - CU8(base + 3)); - temp |= - ((index >> CU8(base + 2)) & - (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + - 3); - base += 4; - break; - case ATOM_IIO_MOVE_DATA: - temp &= - ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << - CU8(base + 3)); - temp |= - ((data >> CU8(base + 2)) & - (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + - 3); - base += 4; - break; - case ATOM_IIO_MOVE_ATTR: - temp &= - ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << - CU8(base + 3)); - temp |= - ((ctx-> - io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - - CU8 - (base - + - 1)))) - << CU8(base + 3); - base += 4; - break; - case ATOM_IIO_END: - return temp; - default: - printk(KERN_INFO "Unknown IIO opcode.\n"); - return 0; - } -} - -static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, - int *ptr, uint32_t *saved, int print) -{ - uint32_t idx, val = 0xCDCDCDCD, align, arg; - struct atom_context *gctx = ctx->ctx; - arg = attr & 7; - align = (attr >> 3) & 7; - switch (arg) { - case ATOM_ARG_REG: - idx = U16(*ptr); - (*ptr) += 2; - if (print) - DEBUG("REG[0x%04X]", idx); - idx += gctx->reg_block; - switch (gctx->io_mode) { - case ATOM_IO_MM: - val = gctx->card->reg_read(gctx->card, idx); - break; - case ATOM_IO_PCI: - printk(KERN_INFO - "PCI registers are not implemented.\n"); - return 0; - case ATOM_IO_SYSIO: - printk(KERN_INFO - "SYSIO registers are not implemented.\n"); - return 0; - default: - if (!(gctx->io_mode & 0x80)) { - printk(KERN_INFO "Bad IO mode.\n"); - return 0; - } - if (!gctx->iio[gctx->io_mode & 0x7F]) { - printk(KERN_INFO - "Undefined indirect IO read method %d.\n", - gctx->io_mode & 0x7F); - return 0; - } - val = - atom_iio_execute(gctx, - gctx->iio[gctx->io_mode & 0x7F], - idx, 0); - } - break; - case ATOM_ARG_PS: - idx = U8(*ptr); - (*ptr)++; - /* get_unaligned_le32 avoids unaligned accesses from atombios - * tables, noticed on a DEC Alpha. */ - val = get_unaligned_le32((u32 *)&ctx->ps[idx]); - if (print) - DEBUG("PS[0x%02X,0x%04X]", idx, val); - break; - case ATOM_ARG_WS: - idx = U8(*ptr); - (*ptr)++; - if (print) - DEBUG("WS[0x%02X]", idx); - switch (idx) { - case ATOM_WS_QUOTIENT: - val = gctx->divmul[0]; - break; - case ATOM_WS_REMAINDER: - val = gctx->divmul[1]; - break; - case ATOM_WS_DATAPTR: - val = gctx->data_block; - break; - case ATOM_WS_SHIFT: - val = gctx->shift; - break; - case ATOM_WS_OR_MASK: - val = 1 << gctx->shift; - break; - case ATOM_WS_AND_MASK: - val = ~(1 << gctx->shift); - break; - case ATOM_WS_FB_WINDOW: - val = gctx->fb_base; - break; - case ATOM_WS_ATTRIBUTES: - val = gctx->io_attr; - break; - case ATOM_WS_REGPTR: - val = gctx->reg_block; - break; - default: - val = ctx->ws[idx]; - } - break; - case ATOM_ARG_ID: - idx = U16(*ptr); - (*ptr) += 2; - if (print) { - if (gctx->data_block) - DEBUG("ID[0x%04X+%04X]", idx, gctx->data_block); - else - DEBUG("ID[0x%04X]", idx); - } - val = U32(idx + gctx->data_block); - break; - case ATOM_ARG_FB: - idx = U8(*ptr); - (*ptr)++; - if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { - DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n", - gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); - val = 0; - } else - val = gctx->scratch[(gctx->fb_base / 4) + idx]; - if (print) - DEBUG("FB[0x%02X]", idx); - break; - case ATOM_ARG_IMM: - switch (align) { - case ATOM_SRC_DWORD: - val = U32(*ptr); - (*ptr) += 4; - if (print) - DEBUG("IMM 0x%08X\n", val); - return val; - case ATOM_SRC_WORD0: - case ATOM_SRC_WORD8: - case ATOM_SRC_WORD16: - val = U16(*ptr); - (*ptr) += 2; - if (print) - DEBUG("IMM 0x%04X\n", val); - return val; - case ATOM_SRC_BYTE0: - case ATOM_SRC_BYTE8: - case ATOM_SRC_BYTE16: - case ATOM_SRC_BYTE24: - val = U8(*ptr); - (*ptr)++; - if (print) - DEBUG("IMM 0x%02X\n", val); - return val; - } - return 0; - case ATOM_ARG_PLL: - idx = U8(*ptr); - (*ptr)++; - if (print) - DEBUG("PLL[0x%02X]", idx); - val = gctx->card->pll_read(gctx->card, idx); - break; - case ATOM_ARG_MC: - idx = U8(*ptr); - (*ptr)++; - if (print) - DEBUG("MC[0x%02X]", idx); - val = gctx->card->mc_read(gctx->card, idx); - break; - } - if (saved) - *saved = val; - val &= atom_arg_mask[align]; - val >>= atom_arg_shift[align]; - if (print) - switch (align) { - case ATOM_SRC_DWORD: - DEBUG(".[31:0] -> 0x%08X\n", val); - break; - case ATOM_SRC_WORD0: - DEBUG(".[15:0] -> 0x%04X\n", val); - break; - case ATOM_SRC_WORD8: - DEBUG(".[23:8] -> 0x%04X\n", val); - break; - case ATOM_SRC_WORD16: - DEBUG(".[31:16] -> 0x%04X\n", val); - break; - case ATOM_SRC_BYTE0: - DEBUG(".[7:0] -> 0x%02X\n", val); - break; - case ATOM_SRC_BYTE8: - DEBUG(".[15:8] -> 0x%02X\n", val); - break; - case ATOM_SRC_BYTE16: - DEBUG(".[23:16] -> 0x%02X\n", val); - break; - case ATOM_SRC_BYTE24: - DEBUG(".[31:24] -> 0x%02X\n", val); - break; - } - return val; -} - -static void atom_skip_src_int(atom_exec_context *ctx, uint8_t attr, int *ptr) -{ - uint32_t align = (attr >> 3) & 7, arg = attr & 7; - switch (arg) { - case ATOM_ARG_REG: - case ATOM_ARG_ID: - (*ptr) += 2; - break; - case ATOM_ARG_PLL: - case ATOM_ARG_MC: - case ATOM_ARG_PS: - case ATOM_ARG_WS: - case ATOM_ARG_FB: - (*ptr)++; - break; - case ATOM_ARG_IMM: - switch (align) { - case ATOM_SRC_DWORD: - (*ptr) += 4; - return; - case ATOM_SRC_WORD0: - case ATOM_SRC_WORD8: - case ATOM_SRC_WORD16: - (*ptr) += 2; - return; - case ATOM_SRC_BYTE0: - case ATOM_SRC_BYTE8: - case ATOM_SRC_BYTE16: - case ATOM_SRC_BYTE24: - (*ptr)++; - return; - } - return; - } -} - -static uint32_t atom_get_src(atom_exec_context *ctx, uint8_t attr, int *ptr) -{ - return atom_get_src_int(ctx, attr, ptr, NULL, 1); -} - -static uint32_t atom_get_src_direct(atom_exec_context *ctx, uint8_t align, int *ptr) -{ - uint32_t val = 0xCDCDCDCD; - - switch (align) { - case ATOM_SRC_DWORD: - val = U32(*ptr); - (*ptr) += 4; - break; - case ATOM_SRC_WORD0: - case ATOM_SRC_WORD8: - case ATOM_SRC_WORD16: - val = U16(*ptr); - (*ptr) += 2; - break; - case ATOM_SRC_BYTE0: - case ATOM_SRC_BYTE8: - case ATOM_SRC_BYTE16: - case ATOM_SRC_BYTE24: - val = U8(*ptr); - (*ptr)++; - break; - } - return val; -} - -static uint32_t atom_get_dst(atom_exec_context *ctx, int arg, uint8_t attr, - int *ptr, uint32_t *saved, int print) -{ - return atom_get_src_int(ctx, - arg | atom_dst_to_src[(attr >> 3) & - 7][(attr >> 6) & 3] << 3, - ptr, saved, print); -} - -static void atom_skip_dst(atom_exec_context *ctx, int arg, uint8_t attr, int *ptr) -{ - atom_skip_src_int(ctx, - arg | atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & - 3] << 3, ptr); -} - -static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, - int *ptr, uint32_t val, uint32_t saved) -{ - uint32_t align = - atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3], old_val = - val, idx; - struct atom_context *gctx = ctx->ctx; - old_val &= atom_arg_mask[align] >> atom_arg_shift[align]; - val <<= atom_arg_shift[align]; - val &= atom_arg_mask[align]; - saved &= ~atom_arg_mask[align]; - val |= saved; - switch (arg) { - case ATOM_ARG_REG: - idx = U16(*ptr); - (*ptr) += 2; - DEBUG("REG[0x%04X]", idx); - idx += gctx->reg_block; - switch (gctx->io_mode) { - case ATOM_IO_MM: - if (idx == 0) - gctx->card->reg_write(gctx->card, idx, - val << 2); - else - gctx->card->reg_write(gctx->card, idx, val); - break; - case ATOM_IO_PCI: - printk(KERN_INFO - "PCI registers are not implemented.\n"); - return; - case ATOM_IO_SYSIO: - printk(KERN_INFO - "SYSIO registers are not implemented.\n"); - return; - default: - if (!(gctx->io_mode & 0x80)) { - printk(KERN_INFO "Bad IO mode.\n"); - return; - } - if (!gctx->iio[gctx->io_mode & 0xFF]) { - printk(KERN_INFO - "Undefined indirect IO write method %d.\n", - gctx->io_mode & 0x7F); - return; - } - atom_iio_execute(gctx, gctx->iio[gctx->io_mode & 0xFF], - idx, val); - } - break; - case ATOM_ARG_PS: - idx = U8(*ptr); - (*ptr)++; - DEBUG("PS[0x%02X]", idx); - ctx->ps[idx] = cpu_to_le32(val); - break; - case ATOM_ARG_WS: - idx = U8(*ptr); - (*ptr)++; - DEBUG("WS[0x%02X]", idx); - switch (idx) { - case ATOM_WS_QUOTIENT: - gctx->divmul[0] = val; - break; - case ATOM_WS_REMAINDER: - gctx->divmul[1] = val; - break; - case ATOM_WS_DATAPTR: - gctx->data_block = val; - break; - case ATOM_WS_SHIFT: - gctx->shift = val; - break; - case ATOM_WS_OR_MASK: - case ATOM_WS_AND_MASK: - break; - case ATOM_WS_FB_WINDOW: - gctx->fb_base = val; - break; - case ATOM_WS_ATTRIBUTES: - gctx->io_attr = val; - break; - case ATOM_WS_REGPTR: - gctx->reg_block = val; - break; - default: - ctx->ws[idx] = val; - } - break; - case ATOM_ARG_FB: - idx = U8(*ptr); - (*ptr)++; - if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { - DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n", - gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); - } else - gctx->scratch[(gctx->fb_base / 4) + idx] = val; - DEBUG("FB[0x%02X]", idx); - break; - case ATOM_ARG_PLL: - idx = U8(*ptr); - (*ptr)++; - DEBUG("PLL[0x%02X]", idx); - gctx->card->pll_write(gctx->card, idx, val); - break; - case ATOM_ARG_MC: - idx = U8(*ptr); - (*ptr)++; - DEBUG("MC[0x%02X]", idx); - gctx->card->mc_write(gctx->card, idx, val); - return; - } - switch (align) { - case ATOM_SRC_DWORD: - DEBUG(".[31:0] <- 0x%08X\n", old_val); - break; - case ATOM_SRC_WORD0: - DEBUG(".[15:0] <- 0x%04X\n", old_val); - break; - case ATOM_SRC_WORD8: - DEBUG(".[23:8] <- 0x%04X\n", old_val); - break; - case ATOM_SRC_WORD16: - DEBUG(".[31:16] <- 0x%04X\n", old_val); - break; - case ATOM_SRC_BYTE0: - DEBUG(".[7:0] <- 0x%02X\n", old_val); - break; - case ATOM_SRC_BYTE8: - DEBUG(".[15:8] <- 0x%02X\n", old_val); - break; - case ATOM_SRC_BYTE16: - DEBUG(".[23:16] <- 0x%02X\n", old_val); - break; - case ATOM_SRC_BYTE24: - DEBUG(".[31:24] <- 0x%02X\n", old_val); - break; - } -} - -static void atom_op_add(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src, saved; - int dptr = *ptr; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - dst += src; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_and(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src, saved; - int dptr = *ptr; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - dst &= src; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg) -{ - printk("ATOM BIOS beeped!\n"); -} - -static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) -{ - int idx = U8((*ptr)++); - int r = 0; - - if (idx < ATOM_TABLE_NAMES_CNT) - SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]); - else - SDEBUG(" table: %d\n", idx); - if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) - r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); - if (r) { - ctx->abort = true; - } -} - -static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t saved; - int dptr = *ptr; - attr &= 0x38; - attr |= atom_def_dst[attr >> 3] << 6; - atom_get_dst(ctx, arg, attr, ptr, &saved, 0); - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, 0, saved); -} - -static void atom_op_compare(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src; - SDEBUG(" src1: "); - dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); - SDEBUG(" src2: "); - src = atom_get_src(ctx, attr, ptr); - ctx->ctx->cs_equal = (dst == src); - ctx->ctx->cs_above = (dst > src); - SDEBUG(" result: %s %s\n", ctx->ctx->cs_equal ? "EQ" : "NE", - ctx->ctx->cs_above ? "GT" : "LE"); -} - -static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg) -{ - unsigned count = U8((*ptr)++); - SDEBUG(" count: %d\n", count); - if (arg == ATOM_UNIT_MICROSEC) - udelay(count); - else if (!drm_can_sleep()) - mdelay(count); - else - msleep(count); -} - -static void atom_op_div(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src; - SDEBUG(" src1: "); - dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); - SDEBUG(" src2: "); - src = atom_get_src(ctx, attr, ptr); - if (src != 0) { - ctx->ctx->divmul[0] = dst / src; - ctx->ctx->divmul[1] = dst % src; - } else { - ctx->ctx->divmul[0] = 0; - ctx->ctx->divmul[1] = 0; - } -} - -static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg) -{ - /* functionally, a nop */ -} - -static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) -{ - int execute = 0, target = U16(*ptr); - unsigned long cjiffies; - - (*ptr) += 2; - switch (arg) { - case ATOM_COND_ABOVE: - execute = ctx->ctx->cs_above; - break; - case ATOM_COND_ABOVEOREQUAL: - execute = ctx->ctx->cs_above || ctx->ctx->cs_equal; - break; - case ATOM_COND_ALWAYS: - execute = 1; - break; - case ATOM_COND_BELOW: - execute = !(ctx->ctx->cs_above || ctx->ctx->cs_equal); - break; - case ATOM_COND_BELOWOREQUAL: - execute = !ctx->ctx->cs_above; - break; - case ATOM_COND_EQUAL: - execute = ctx->ctx->cs_equal; - break; - case ATOM_COND_NOTEQUAL: - execute = !ctx->ctx->cs_equal; - break; - } - if (arg != ATOM_COND_ALWAYS) - SDEBUG(" taken: %s\n", execute ? "yes" : "no"); - SDEBUG(" target: 0x%04X\n", target); - if (execute) { - if (ctx->last_jump == (ctx->start + target)) { - cjiffies = jiffies; - if (time_after(cjiffies, ctx->last_jump_jiffies)) { - cjiffies -= ctx->last_jump_jiffies; - if ((jiffies_to_msecs(cjiffies) > 5000)) { - DRM_ERROR("atombios stuck in loop for more than 5secs aborting\n"); - ctx->abort = true; - } - } else { - /* jiffies wrap around we will just wait a little longer */ - ctx->last_jump_jiffies = jiffies; - } - } else { - ctx->last_jump = ctx->start + target; - ctx->last_jump_jiffies = jiffies; - } - *ptr = ctx->start + target; - } -} - -static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, mask, src, saved; - int dptr = *ptr; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); - SDEBUG(" mask: 0x%08x", mask); - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - dst &= mask; - dst |= src; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_move(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t src, saved; - int dptr = *ptr; - if (((attr >> 3) & 7) != ATOM_SRC_DWORD) - atom_get_dst(ctx, arg, attr, ptr, &saved, 0); - else { - atom_skip_dst(ctx, arg, attr, ptr); - saved = 0xCDCDCDCD; - } - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, src, saved); -} - -static void atom_op_mul(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src; - SDEBUG(" src1: "); - dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); - SDEBUG(" src2: "); - src = atom_get_src(ctx, attr, ptr); - ctx->ctx->divmul[0] = dst * src; -} - -static void atom_op_nop(atom_exec_context *ctx, int *ptr, int arg) -{ - /* nothing */ -} - -static void atom_op_or(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src, saved; - int dptr = *ptr; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - dst |= src; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_postcard(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t val = U8((*ptr)++); - SDEBUG("POST card output: 0x%02X\n", val); -} - -static void atom_op_repeat(atom_exec_context *ctx, int *ptr, int arg) -{ - printk(KERN_INFO "unimplemented!\n"); -} - -static void atom_op_restorereg(atom_exec_context *ctx, int *ptr, int arg) -{ - printk(KERN_INFO "unimplemented!\n"); -} - -static void atom_op_savereg(atom_exec_context *ctx, int *ptr, int arg) -{ - printk(KERN_INFO "unimplemented!\n"); -} - -static void atom_op_setdatablock(atom_exec_context *ctx, int *ptr, int arg) -{ - int idx = U8(*ptr); - (*ptr)++; - SDEBUG(" block: %d\n", idx); - if (!idx) - ctx->ctx->data_block = 0; - else if (idx == 255) - ctx->ctx->data_block = ctx->start; - else - ctx->ctx->data_block = U16(ctx->ctx->data_table + 4 + 2 * idx); - SDEBUG(" base: 0x%04X\n", ctx->ctx->data_block); -} - -static void atom_op_setfbbase(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - SDEBUG(" fb_base: "); - ctx->ctx->fb_base = atom_get_src(ctx, attr, ptr); -} - -static void atom_op_setport(atom_exec_context *ctx, int *ptr, int arg) -{ - int port; - switch (arg) { - case ATOM_PORT_ATI: - port = U16(*ptr); - if (port < ATOM_IO_NAMES_CNT) - SDEBUG(" port: %d (%s)\n", port, atom_io_names[port]); - else - SDEBUG(" port: %d\n", port); - if (!port) - ctx->ctx->io_mode = ATOM_IO_MM; - else - ctx->ctx->io_mode = ATOM_IO_IIO | port; - (*ptr) += 2; - break; - case ATOM_PORT_PCI: - ctx->ctx->io_mode = ATOM_IO_PCI; - (*ptr)++; - break; - case ATOM_PORT_SYSIO: - ctx->ctx->io_mode = ATOM_IO_SYSIO; - (*ptr)++; - break; - } -} - -static void atom_op_setregblock(atom_exec_context *ctx, int *ptr, int arg) -{ - ctx->ctx->reg_block = U16(*ptr); - (*ptr) += 2; - SDEBUG(" base: 0x%04X\n", ctx->ctx->reg_block); -} - -static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++), shift; - uint32_t saved, dst; - int dptr = *ptr; - attr &= 0x38; - attr |= atom_def_dst[attr >> 3] << 6; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr); - SDEBUG(" shift: %d\n", shift); - dst <<= shift; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++), shift; - uint32_t saved, dst; - int dptr = *ptr; - attr &= 0x38; - attr |= atom_def_dst[attr >> 3] << 6; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr); - SDEBUG(" shift: %d\n", shift); - dst >>= shift; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++), shift; - uint32_t saved, dst; - int dptr = *ptr; - uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - /* op needs to full dst value */ - dst = saved; - shift = atom_get_src(ctx, attr, ptr); - SDEBUG(" shift: %d\n", shift); - dst <<= shift; - dst &= atom_arg_mask[dst_align]; - dst >>= atom_arg_shift[dst_align]; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++), shift; - uint32_t saved, dst; - int dptr = *ptr; - uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - /* op needs to full dst value */ - dst = saved; - shift = atom_get_src(ctx, attr, ptr); - SDEBUG(" shift: %d\n", shift); - dst >>= shift; - dst &= atom_arg_mask[dst_align]; - dst >>= atom_arg_shift[dst_align]; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_sub(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src, saved; - int dptr = *ptr; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - dst -= src; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_switch(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t src, val, target; - SDEBUG(" switch: "); - src = atom_get_src(ctx, attr, ptr); - while (U16(*ptr) != ATOM_CASE_END) - if (U8(*ptr) == ATOM_CASE_MAGIC) { - (*ptr)++; - SDEBUG(" case: "); - val = - atom_get_src(ctx, (attr & 0x38) | ATOM_ARG_IMM, - ptr); - target = U16(*ptr); - if (val == src) { - SDEBUG(" target: %04X\n", target); - *ptr = ctx->start + target; - return; - } - (*ptr) += 2; - } else { - printk(KERN_INFO "Bad case.\n"); - return; - } - (*ptr) += 2; -} - -static void atom_op_test(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src; - SDEBUG(" src1: "); - dst = atom_get_dst(ctx, arg, attr, ptr, NULL, 1); - SDEBUG(" src2: "); - src = atom_get_src(ctx, attr, ptr); - ctx->ctx->cs_equal = ((dst & src) == 0); - SDEBUG(" result: %s\n", ctx->ctx->cs_equal ? "EQ" : "NE"); -} - -static void atom_op_xor(atom_exec_context *ctx, int *ptr, int arg) -{ - uint8_t attr = U8((*ptr)++); - uint32_t dst, src, saved; - int dptr = *ptr; - SDEBUG(" dst: "); - dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - SDEBUG(" src: "); - src = atom_get_src(ctx, attr, ptr); - dst ^= src; - SDEBUG(" dst: "); - atom_put_dst(ctx, arg, attr, &dptr, dst, saved); -} - -static void atom_op_debug(atom_exec_context *ctx, int *ptr, int arg) -{ - printk(KERN_INFO "unimplemented!\n"); -} - -static struct { - void (*func) (atom_exec_context *, int *, int); - int arg; -} opcode_table[ATOM_OP_CNT] = { - { - NULL, 0}, { - atom_op_move, ATOM_ARG_REG}, { - atom_op_move, ATOM_ARG_PS}, { - atom_op_move, ATOM_ARG_WS}, { - atom_op_move, ATOM_ARG_FB}, { - atom_op_move, ATOM_ARG_PLL}, { - atom_op_move, ATOM_ARG_MC}, { - atom_op_and, ATOM_ARG_REG}, { - atom_op_and, ATOM_ARG_PS}, { - atom_op_and, ATOM_ARG_WS}, { - atom_op_and, ATOM_ARG_FB}, { - atom_op_and, ATOM_ARG_PLL}, { - atom_op_and, ATOM_ARG_MC}, { - atom_op_or, ATOM_ARG_REG}, { - atom_op_or, ATOM_ARG_PS}, { - atom_op_or, ATOM_ARG_WS}, { - atom_op_or, ATOM_ARG_FB}, { - atom_op_or, ATOM_ARG_PLL}, { - atom_op_or, ATOM_ARG_MC}, { - atom_op_shift_left, ATOM_ARG_REG}, { - atom_op_shift_left, ATOM_ARG_PS}, { - atom_op_shift_left, ATOM_ARG_WS}, { - atom_op_shift_left, ATOM_ARG_FB}, { - atom_op_shift_left, ATOM_ARG_PLL}, { - atom_op_shift_left, ATOM_ARG_MC}, { - atom_op_shift_right, ATOM_ARG_REG}, { - atom_op_shift_right, ATOM_ARG_PS}, { - atom_op_shift_right, ATOM_ARG_WS}, { - atom_op_shift_right, ATOM_ARG_FB}, { - atom_op_shift_right, ATOM_ARG_PLL}, { - atom_op_shift_right, ATOM_ARG_MC}, { - atom_op_mul, ATOM_ARG_REG}, { - atom_op_mul, ATOM_ARG_PS}, { - atom_op_mul, ATOM_ARG_WS}, { - atom_op_mul, ATOM_ARG_FB}, { - atom_op_mul, ATOM_ARG_PLL}, { - atom_op_mul, ATOM_ARG_MC}, { - atom_op_div, ATOM_ARG_REG}, { - atom_op_div, ATOM_ARG_PS}, { - atom_op_div, ATOM_ARG_WS}, { - atom_op_div, ATOM_ARG_FB}, { - atom_op_div, ATOM_ARG_PLL}, { - atom_op_div, ATOM_ARG_MC}, { - atom_op_add, ATOM_ARG_REG}, { - atom_op_add, ATOM_ARG_PS}, { - atom_op_add, ATOM_ARG_WS}, { - atom_op_add, ATOM_ARG_FB}, { - atom_op_add, ATOM_ARG_PLL}, { - atom_op_add, ATOM_ARG_MC}, { - atom_op_sub, ATOM_ARG_REG}, { - atom_op_sub, ATOM_ARG_PS}, { - atom_op_sub, ATOM_ARG_WS}, { - atom_op_sub, ATOM_ARG_FB}, { - atom_op_sub, ATOM_ARG_PLL}, { - atom_op_sub, ATOM_ARG_MC}, { - atom_op_setport, ATOM_PORT_ATI}, { - atom_op_setport, ATOM_PORT_PCI}, { - atom_op_setport, ATOM_PORT_SYSIO}, { - atom_op_setregblock, 0}, { - atom_op_setfbbase, 0}, { - atom_op_compare, ATOM_ARG_REG}, { - atom_op_compare, ATOM_ARG_PS}, { - atom_op_compare, ATOM_ARG_WS}, { - atom_op_compare, ATOM_ARG_FB}, { - atom_op_compare, ATOM_ARG_PLL}, { - atom_op_compare, ATOM_ARG_MC}, { - atom_op_switch, 0}, { - atom_op_jump, ATOM_COND_ALWAYS}, { - atom_op_jump, ATOM_COND_EQUAL}, { - atom_op_jump, ATOM_COND_BELOW}, { - atom_op_jump, ATOM_COND_ABOVE}, { - atom_op_jump, ATOM_COND_BELOWOREQUAL}, { - atom_op_jump, ATOM_COND_ABOVEOREQUAL}, { - atom_op_jump, ATOM_COND_NOTEQUAL}, { - atom_op_test, ATOM_ARG_REG}, { - atom_op_test, ATOM_ARG_PS}, { - atom_op_test, ATOM_ARG_WS}, { - atom_op_test, ATOM_ARG_FB}, { - atom_op_test, ATOM_ARG_PLL}, { - atom_op_test, ATOM_ARG_MC}, { - atom_op_delay, ATOM_UNIT_MILLISEC}, { - atom_op_delay, ATOM_UNIT_MICROSEC}, { - atom_op_calltable, 0}, { - atom_op_repeat, 0}, { - atom_op_clear, ATOM_ARG_REG}, { - atom_op_clear, ATOM_ARG_PS}, { - atom_op_clear, ATOM_ARG_WS}, { - atom_op_clear, ATOM_ARG_FB}, { - atom_op_clear, ATOM_ARG_PLL}, { - atom_op_clear, ATOM_ARG_MC}, { - atom_op_nop, 0}, { - atom_op_eot, 0}, { - atom_op_mask, ATOM_ARG_REG}, { - atom_op_mask, ATOM_ARG_PS}, { - atom_op_mask, ATOM_ARG_WS}, { - atom_op_mask, ATOM_ARG_FB}, { - atom_op_mask, ATOM_ARG_PLL}, { - atom_op_mask, ATOM_ARG_MC}, { - atom_op_postcard, 0}, { - atom_op_beep, 0}, { - atom_op_savereg, 0}, { - atom_op_restorereg, 0}, { - atom_op_setdatablock, 0}, { - atom_op_xor, ATOM_ARG_REG}, { - atom_op_xor, ATOM_ARG_PS}, { - atom_op_xor, ATOM_ARG_WS}, { - atom_op_xor, ATOM_ARG_FB}, { - atom_op_xor, ATOM_ARG_PLL}, { - atom_op_xor, ATOM_ARG_MC}, { - atom_op_shl, ATOM_ARG_REG}, { - atom_op_shl, ATOM_ARG_PS}, { - atom_op_shl, ATOM_ARG_WS}, { - atom_op_shl, ATOM_ARG_FB}, { - atom_op_shl, ATOM_ARG_PLL}, { - atom_op_shl, ATOM_ARG_MC}, { - atom_op_shr, ATOM_ARG_REG}, { - atom_op_shr, ATOM_ARG_PS}, { - atom_op_shr, ATOM_ARG_WS}, { - atom_op_shr, ATOM_ARG_FB}, { - atom_op_shr, ATOM_ARG_PLL}, { - atom_op_shr, ATOM_ARG_MC}, { -atom_op_debug, 0},}; - -static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) -{ - int base = CU16(ctx->cmd_table + 4 + 2 * index); - int len, ws, ps, ptr; - unsigned char op; - atom_exec_context ectx; - int ret = 0; - - if (!base) - return -EINVAL; - - len = CU16(base + ATOM_CT_SIZE_PTR); - ws = CU8(base + ATOM_CT_WS_PTR); - ps = CU8(base + ATOM_CT_PS_PTR) & ATOM_CT_PS_MASK; - ptr = base + ATOM_CT_CODE_PTR; - - SDEBUG(">> execute %04X (len %d, WS %d, PS %d)\n", base, len, ws, ps); - - ectx.ctx = ctx; - ectx.ps_shift = ps / 4; - ectx.start = base; - ectx.ps = params; - ectx.abort = false; - ectx.last_jump = 0; - if (ws) - ectx.ws = kzalloc(4 * ws, GFP_KERNEL); - else - ectx.ws = NULL; - - debug_depth++; - while (1) { - op = CU8(ptr++); - if (op < ATOM_OP_NAMES_CNT) - SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1); - else - SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1); - if (ectx.abort) { - DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n", - base, len, ws, ps, ptr - 1); - ret = -EINVAL; - goto free; - } - - if (op < ATOM_OP_CNT && op > 0) - opcode_table[op].func(&ectx, &ptr, - opcode_table[op].arg); - else - break; - - if (op == ATOM_OP_EOT) - break; - } - debug_depth--; - SDEBUG("<<\n"); - -free: - if (ws) - kfree(ectx.ws); - return ret; -} - -int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) -{ - int r; - - mutex_lock(&ctx->mutex); - /* reset reg block */ - ctx->reg_block = 0; - /* reset fb window */ - ctx->fb_base = 0; - /* reset io mode */ - ctx->io_mode = ATOM_IO_MM; - r = atom_execute_table_locked(ctx, index, params); - mutex_unlock(&ctx->mutex); - return r; -} - -static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; - -static void atom_index_iio(struct atom_context *ctx, int base) -{ - ctx->iio = kzalloc(2 * 256, GFP_KERNEL); - while (CU8(base) == ATOM_IIO_START) { - ctx->iio[CU8(base + 1)] = base + 2; - base += 2; - while (CU8(base) != ATOM_IIO_END) - base += atom_iio_len[CU8(base)]; - base += 3; - } -} - -struct atom_context *atom_parse(struct card_info *card, void *bios) -{ - int base; - struct atom_context *ctx = - kzalloc(sizeof(struct atom_context), GFP_KERNEL); - char *str; - char name[512]; - int i; - - if (!ctx) - return NULL; - - ctx->card = card; - ctx->bios = bios; - - if (CU16(0) != ATOM_BIOS_MAGIC) { - printk(KERN_INFO "Invalid BIOS magic.\n"); - kfree(ctx); - return NULL; - } - if (strncmp - (CSTR(ATOM_ATI_MAGIC_PTR), ATOM_ATI_MAGIC, - strlen(ATOM_ATI_MAGIC))) { - printk(KERN_INFO "Invalid ATI magic.\n"); - kfree(ctx); - return NULL; - } - - base = CU16(ATOM_ROM_TABLE_PTR); - if (strncmp - (CSTR(base + ATOM_ROM_MAGIC_PTR), ATOM_ROM_MAGIC, - strlen(ATOM_ROM_MAGIC))) { - printk(KERN_INFO "Invalid ATOM magic.\n"); - kfree(ctx); - return NULL; - } - - ctx->cmd_table = CU16(base + ATOM_ROM_CMD_PTR); - ctx->data_table = CU16(base + ATOM_ROM_DATA_PTR); - atom_index_iio(ctx, CU16(ctx->data_table + ATOM_DATA_IIO_PTR) + 4); - - str = CSTR(CU16(base + ATOM_ROM_MSG_PTR)); - while (*str && ((*str == '\n') || (*str == '\r'))) - str++; - /* name string isn't always 0 terminated */ - for (i = 0; i < 511; i++) { - name[i] = str[i]; - if (name[i] < '.' || name[i] > 'z') { - name[i] = 0; - break; - } - } - printk(KERN_INFO "ATOM BIOS: %s\n", name); - - return ctx; -} - -int atom_asic_init(struct atom_context *ctx) -{ - struct radeon_device *rdev = ctx->card->dev->dev_private; - int hwi = CU16(ctx->data_table + ATOM_DATA_FWI_PTR); - uint32_t ps[16]; - int ret; - - memset(ps, 0, 64); - - ps[0] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFSCLK_PTR)); - ps[1] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFMCLK_PTR)); - if (!ps[0] || !ps[1]) - return 1; - - if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT)) - return 1; - ret = atom_execute_table(ctx, ATOM_CMD_INIT, ps); - if (ret) - return ret; - - memset(ps, 0, 64); - - if (rdev->family < CHIP_R600) { - if (CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_SPDFANCNTL)) - atom_execute_table(ctx, ATOM_CMD_SPDFANCNTL, ps); - } - return ret; -} - -void atom_destroy(struct atom_context *ctx) -{ - if (ctx->iio) - kfree(ctx->iio); - kfree(ctx); -} - -bool atom_parse_data_header(struct atom_context *ctx, int index, - uint16_t * size, uint8_t * frev, uint8_t * crev, - uint16_t * data_start) -{ - int offset = index * 2 + 4; - int idx = CU16(ctx->data_table + offset); - u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4); - - if (!mdt[index]) - return false; - - if (size) - *size = CU16(idx); - if (frev) - *frev = CU8(idx + 2); - if (crev) - *crev = CU8(idx + 3); - *data_start = idx; - return true; -} - -bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, - uint8_t * crev) -{ - int offset = index * 2 + 4; - int idx = CU16(ctx->cmd_table + offset); - u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4); - - if (!mct[index]) - return false; - - if (frev) - *frev = CU8(idx + 2); - if (crev) - *crev = CU8(idx + 3); - return true; -} - -int atom_allocate_fb_scratch(struct atom_context *ctx) -{ - int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); - uint16_t data_offset; - int usage_bytes = 0; - struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; - - if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { - firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); - - DRM_DEBUG("atom firmware requested %08x %dkb\n", - firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, - firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); - - usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; - } - ctx->scratch_size_bytes = 0; - if (usage_bytes == 0) - usage_bytes = 20 * 1024; - /* allocate some scratch memory */ - ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); - if (!ctx->scratch) - return -ENOMEM; - ctx->scratch_size_bytes = usage_bytes; - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.h deleted file mode 100644 index 25fea631..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atom.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Author: Stanislaw Skowronek - */ - -#ifndef ATOM_H -#define ATOM_H - -#include -#include "drmP.h" - -#define ATOM_BIOS_MAGIC 0xAA55 -#define ATOM_ATI_MAGIC_PTR 0x30 -#define ATOM_ATI_MAGIC " 761295520" -#define ATOM_ROM_TABLE_PTR 0x48 - -#define ATOM_ROM_MAGIC "ATOM" -#define ATOM_ROM_MAGIC_PTR 4 - -#define ATOM_ROM_MSG_PTR 0x10 -#define ATOM_ROM_CMD_PTR 0x1E -#define ATOM_ROM_DATA_PTR 0x20 - -#define ATOM_CMD_INIT 0 -#define ATOM_CMD_SETSCLK 0x0A -#define ATOM_CMD_SETMCLK 0x0B -#define ATOM_CMD_SETPCLK 0x0C -#define ATOM_CMD_SPDFANCNTL 0x39 - -#define ATOM_DATA_FWI_PTR 0xC -#define ATOM_DATA_IIO_PTR 0x32 - -#define ATOM_FWI_DEFSCLK_PTR 8 -#define ATOM_FWI_DEFMCLK_PTR 0xC -#define ATOM_FWI_MAXSCLK_PTR 0x24 -#define ATOM_FWI_MAXMCLK_PTR 0x28 - -#define ATOM_CT_SIZE_PTR 0 -#define ATOM_CT_WS_PTR 4 -#define ATOM_CT_PS_PTR 5 -#define ATOM_CT_PS_MASK 0x7F -#define ATOM_CT_CODE_PTR 6 - -#define ATOM_OP_CNT 123 -#define ATOM_OP_EOT 91 - -#define ATOM_CASE_MAGIC 0x63 -#define ATOM_CASE_END 0x5A5A - -#define ATOM_ARG_REG 0 -#define ATOM_ARG_PS 1 -#define ATOM_ARG_WS 2 -#define ATOM_ARG_FB 3 -#define ATOM_ARG_ID 4 -#define ATOM_ARG_IMM 5 -#define ATOM_ARG_PLL 6 -#define ATOM_ARG_MC 7 - -#define ATOM_SRC_DWORD 0 -#define ATOM_SRC_WORD0 1 -#define ATOM_SRC_WORD8 2 -#define ATOM_SRC_WORD16 3 -#define ATOM_SRC_BYTE0 4 -#define ATOM_SRC_BYTE8 5 -#define ATOM_SRC_BYTE16 6 -#define ATOM_SRC_BYTE24 7 - -#define ATOM_WS_QUOTIENT 0x40 -#define ATOM_WS_REMAINDER 0x41 -#define ATOM_WS_DATAPTR 0x42 -#define ATOM_WS_SHIFT 0x43 -#define ATOM_WS_OR_MASK 0x44 -#define ATOM_WS_AND_MASK 0x45 -#define ATOM_WS_FB_WINDOW 0x46 -#define ATOM_WS_ATTRIBUTES 0x47 -#define ATOM_WS_REGPTR 0x48 - -#define ATOM_IIO_NOP 0 -#define ATOM_IIO_START 1 -#define ATOM_IIO_READ 2 -#define ATOM_IIO_WRITE 3 -#define ATOM_IIO_CLEAR 4 -#define ATOM_IIO_SET 5 -#define ATOM_IIO_MOVE_INDEX 6 -#define ATOM_IIO_MOVE_ATTR 7 -#define ATOM_IIO_MOVE_DATA 8 -#define ATOM_IIO_END 9 - -#define ATOM_IO_MM 0 -#define ATOM_IO_PCI 1 -#define ATOM_IO_SYSIO 2 -#define ATOM_IO_IIO 0x80 - -struct card_info { - struct drm_device *dev; - void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ - void (* ioreg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* ioreg_read)(struct card_info *, uint32_t); /* filled by driver */ - void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ - void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ - uint32_t (* pll_read)(struct card_info *, uint32_t); /* filled by driver */ -}; - -struct atom_context { - struct card_info *card; - struct mutex mutex; - void *bios; - uint32_t cmd_table, data_table; - uint16_t *iio; - - uint16_t data_block; - uint32_t fb_base; - uint32_t divmul[2]; - uint16_t io_attr; - uint16_t reg_block; - uint8_t shift; - int cs_equal, cs_above; - int io_mode; - uint32_t *scratch; - int scratch_size_bytes; -}; - -extern int atom_debug; - -struct atom_context *atom_parse(struct card_info *, void *); -int atom_execute_table(struct atom_context *, int, uint32_t *); -int atom_asic_init(struct atom_context *); -void atom_destroy(struct atom_context *); -bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, - uint8_t *frev, uint8_t *crev, uint16_t *data_start); -bool atom_parse_cmd_header(struct atom_context *ctx, int index, - uint8_t *frev, uint8_t *crev); -int atom_allocate_fb_scratch(struct atom_context *ctx); -#include "atom-types.h" -#include "atombios.h" -#include "ObjectID.h" - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios.h deleted file mode 100644 index 4b04ba38..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios.h +++ /dev/null @@ -1,8010 +0,0 @@ -/* - * Copyright 2006-2007 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/****************************************************************************/ -/*Portion I: Definitions shared between VBIOS and Driver */ -/****************************************************************************/ - - -#ifndef _ATOMBIOS_H -#define _ATOMBIOS_H - -#define ATOM_VERSION_MAJOR 0x00020000 -#define ATOM_VERSION_MINOR 0x00000002 - -#define ATOM_HEADER_VERSION (ATOM_VERSION_MAJOR | ATOM_VERSION_MINOR) - -/* Endianness should be specified before inclusion, - * default to little endian - */ -#ifndef ATOM_BIG_ENDIAN -#error Endian not specified -#endif - -#ifdef _H2INC - #ifndef ULONG - typedef unsigned long ULONG; - #endif - - #ifndef UCHAR - typedef unsigned char UCHAR; - #endif - - #ifndef USHORT - typedef unsigned short USHORT; - #endif -#endif - -#define ATOM_DAC_A 0 -#define ATOM_DAC_B 1 -#define ATOM_EXT_DAC 2 - -#define ATOM_CRTC1 0 -#define ATOM_CRTC2 1 -#define ATOM_CRTC3 2 -#define ATOM_CRTC4 3 -#define ATOM_CRTC5 4 -#define ATOM_CRTC6 5 -#define ATOM_CRTC_INVALID 0xFF - -#define ATOM_DIGA 0 -#define ATOM_DIGB 1 - -#define ATOM_PPLL1 0 -#define ATOM_PPLL2 1 -#define ATOM_DCPLL 2 -#define ATOM_PPLL0 2 -#define ATOM_EXT_PLL1 8 -#define ATOM_EXT_PLL2 9 -#define ATOM_EXT_CLOCK 10 -#define ATOM_PPLL_INVALID 0xFF - -#define ENCODER_REFCLK_SRC_P1PLL 0 -#define ENCODER_REFCLK_SRC_P2PLL 1 -#define ENCODER_REFCLK_SRC_DCPLL 2 -#define ENCODER_REFCLK_SRC_EXTCLK 3 -#define ENCODER_REFCLK_SRC_INVALID 0xFF - -#define ATOM_SCALER1 0 -#define ATOM_SCALER2 1 - -#define ATOM_SCALER_DISABLE 0 -#define ATOM_SCALER_CENTER 1 -#define ATOM_SCALER_EXPANSION 2 -#define ATOM_SCALER_MULTI_EX 3 - -#define ATOM_DISABLE 0 -#define ATOM_ENABLE 1 -#define ATOM_LCD_BLOFF (ATOM_DISABLE+2) -#define ATOM_LCD_BLON (ATOM_ENABLE+2) -#define ATOM_LCD_BL_BRIGHTNESS_CONTROL (ATOM_ENABLE+3) -#define ATOM_LCD_SELFTEST_START (ATOM_DISABLE+5) -#define ATOM_LCD_SELFTEST_STOP (ATOM_ENABLE+5) -#define ATOM_ENCODER_INIT (ATOM_DISABLE+7) -#define ATOM_INIT (ATOM_DISABLE+7) -#define ATOM_GET_STATUS (ATOM_DISABLE+8) - -#define ATOM_BLANKING 1 -#define ATOM_BLANKING_OFF 0 - -#define ATOM_CURSOR1 0 -#define ATOM_CURSOR2 1 - -#define ATOM_ICON1 0 -#define ATOM_ICON2 1 - -#define ATOM_CRT1 0 -#define ATOM_CRT2 1 - -#define ATOM_TV_NTSC 1 -#define ATOM_TV_NTSCJ 2 -#define ATOM_TV_PAL 3 -#define ATOM_TV_PALM 4 -#define ATOM_TV_PALCN 5 -#define ATOM_TV_PALN 6 -#define ATOM_TV_PAL60 7 -#define ATOM_TV_SECAM 8 -#define ATOM_TV_CV 16 - -#define ATOM_DAC1_PS2 1 -#define ATOM_DAC1_CV 2 -#define ATOM_DAC1_NTSC 3 -#define ATOM_DAC1_PAL 4 - -#define ATOM_DAC2_PS2 ATOM_DAC1_PS2 -#define ATOM_DAC2_CV ATOM_DAC1_CV -#define ATOM_DAC2_NTSC ATOM_DAC1_NTSC -#define ATOM_DAC2_PAL ATOM_DAC1_PAL - -#define ATOM_PM_ON 0 -#define ATOM_PM_STANDBY 1 -#define ATOM_PM_SUSPEND 2 -#define ATOM_PM_OFF 3 - -/* Bit0:{=0:single, =1:dual}, - Bit1 {=0:666RGB, =1:888RGB}, - Bit2:3:{Grey level} - Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}*/ - -#define ATOM_PANEL_MISC_DUAL 0x00000001 -#define ATOM_PANEL_MISC_888RGB 0x00000002 -#define ATOM_PANEL_MISC_GREY_LEVEL 0x0000000C -#define ATOM_PANEL_MISC_FPDI 0x00000010 -#define ATOM_PANEL_MISC_GREY_LEVEL_SHIFT 2 -#define ATOM_PANEL_MISC_SPATIAL 0x00000020 -#define ATOM_PANEL_MISC_TEMPORAL 0x00000040 -#define ATOM_PANEL_MISC_API_ENABLED 0x00000080 - - -#define MEMTYPE_DDR1 "DDR1" -#define MEMTYPE_DDR2 "DDR2" -#define MEMTYPE_DDR3 "DDR3" -#define MEMTYPE_DDR4 "DDR4" - -#define ASIC_BUS_TYPE_PCI "PCI" -#define ASIC_BUS_TYPE_AGP "AGP" -#define ASIC_BUS_TYPE_PCIE "PCI_EXPRESS" - -/* Maximum size of that FireGL flag string */ - -#define ATOM_FIREGL_FLAG_STRING "FGL" //Flag used to enable FireGL Support -#define ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING 3 //sizeof( ATOM_FIREGL_FLAG_STRING ) - -#define ATOM_FAKE_DESKTOP_STRING "DSK" //Flag used to enable mobile ASIC on Desktop -#define ATOM_MAX_SIZE_OF_FAKE_DESKTOP_STRING ATOM_MAX_SIZE_OF_FIREGL_FLAG_STRING - -#define ATOM_M54T_FLAG_STRING "M54T" //Flag used to enable M54T Support -#define ATOM_MAX_SIZE_OF_M54T_FLAG_STRING 4 //sizeof( ATOM_M54T_FLAG_STRING ) - -#define HW_ASSISTED_I2C_STATUS_FAILURE 2 -#define HW_ASSISTED_I2C_STATUS_SUCCESS 1 - -#pragma pack(1) /* BIOS data must use byte aligment */ - -/* Define offset to location of ROM header. */ - -#define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER 0x00000048L -#define OFFSET_TO_ATOM_ROM_IMAGE_SIZE 0x00000002L - -#define OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE 0x94 -#define MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE 20 /* including the terminator 0x0! */ -#define OFFSET_TO_GET_ATOMBIOS_STRINGS_NUMBER 0x002f -#define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x006e - -/* Common header for all ROM Data tables. - Every table pointed _ATOM_MASTER_DATA_TABLE has this common header. - And the pointer actually points to this header. */ - -typedef struct _ATOM_COMMON_TABLE_HEADER -{ - USHORT usStructureSize; - UCHAR ucTableFormatRevision; /*Change it when the Parser is not backward compatible */ - UCHAR ucTableContentRevision; /*Change it only when the table needs to change but the firmware */ - /*Image can't be updated, while Driver needs to carry the new table! */ -}ATOM_COMMON_TABLE_HEADER; - -/****************************************************************************/ -// Structure stores the ROM header. -/****************************************************************************/ -typedef struct _ATOM_ROM_HEADER -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR uaFirmWareSignature[4]; /*Signature to distinguish between Atombios and non-atombios, - atombios should init it as "ATOM", don't change the position */ - USHORT usBiosRuntimeSegmentAddress; - USHORT usProtectedModeInfoOffset; - USHORT usConfigFilenameOffset; - USHORT usCRC_BlockOffset; - USHORT usBIOS_BootupMessageOffset; - USHORT usInt10Offset; - USHORT usPciBusDevInitCode; - USHORT usIoBaseAddress; - USHORT usSubsystemVendorID; - USHORT usSubsystemID; - USHORT usPCI_InfoOffset; - USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */ - USHORT usMasterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */ - UCHAR ucExtendedFunctionCode; - UCHAR ucReserved; -}ATOM_ROM_HEADER; - -/*==============================Command Table Portion==================================== */ - -#ifdef UEFI_BUILD - #define UTEMP USHORT - #define USHORT void* -#endif - -/****************************************************************************/ -// Structures used in Command.mtb -/****************************************************************************/ -typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ - USHORT ASIC_Init; //Function Table, used by various SW components,latest version 1.1 - USHORT GetDisplaySurfaceSize; //Atomic Table, Used by Bios when enabling HW ICON - USHORT ASIC_RegistersInit; //Atomic Table, indirectly used by various SW components,called from ASIC_Init - USHORT VRAM_BlockVenderDetection; //Atomic Table, used only by Bios - USHORT DIGxEncoderControl; //Only used by Bios - USHORT MemoryControllerInit; //Atomic Table, indirectly used by various SW components,called from ASIC_Init - USHORT EnableCRTCMemReq; //Function Table,directly used by various SW components,latest version 2.1 - USHORT MemoryParamAdjust; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock if needed - USHORT DVOEncoderControl; //Function Table,directly used by various SW components,latest version 1.2 - USHORT GPIOPinControl; //Atomic Table, only used by Bios - USHORT SetEngineClock; //Function Table,directly used by various SW components,latest version 1.1 - USHORT SetMemoryClock; //Function Table,directly used by various SW components,latest version 1.1 - USHORT SetPixelClock; //Function Table,directly used by various SW components,latest version 1.2 - USHORT EnableDispPowerGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init - USHORT ResetMemoryDLL; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock - USHORT ResetMemoryDevice; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock - USHORT MemoryPLLInit; //Atomic Table, used only by Bios - USHORT AdjustDisplayPll; //Atomic Table, used by various SW componentes. - USHORT AdjustMemoryController; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock - USHORT EnableASIC_StaticPwrMgt; //Atomic Table, only used by Bios - USHORT ASIC_StaticPwrMgtStatusChange; //Obsolete , only used by Bios - USHORT DAC_LoadDetection; //Atomic Table, directly used by various SW components,latest version 1.2 - USHORT LVTMAEncoderControl; //Atomic Table,directly used by various SW components,latest version 1.3 - USHORT HW_Misc_Operation; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT DAC1EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT DAC2EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT DVOOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT CV1OutputControl; //Atomic Table, Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead - USHORT GetConditionalGoldenSetting; //Only used by Bios - USHORT TVEncoderControl; //Function Table,directly used by various SW components,latest version 1.1 - USHORT PatchMCSetting; //only used by BIOS - USHORT MC_SEQ_Control; //only used by BIOS - USHORT TV1OutputControl; //Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead - USHORT EnableScaler; //Atomic Table, used only by Bios - USHORT BlankCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT EnableCRTC; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT GetPixelClock; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT EnableVGA_Render; //Function Table,directly used by various SW components,latest version 1.1 - USHORT GetSCLKOverMCLKRatio; //Atomic Table, only used by Bios - USHORT SetCRTC_Timing; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT SetCRTC_OverScan; //Atomic Table, used by various SW components,latest version 1.1 - USHORT SetCRTC_Replication; //Atomic Table, used only by Bios - USHORT SelectCRTC_Source; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT EnableGraphSurfaces; //Atomic Table, used only by Bios - USHORT UpdateCRTC_DoubleBufferRegisters; //Atomic Table, used only by Bios - USHORT LUT_AutoFill; //Atomic Table, only used by Bios - USHORT EnableHW_IconCursor; //Atomic Table, only used by Bios - USHORT GetMemoryClock; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT GetEngineClock; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT SetCRTC_UsingDTDTiming; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT ExternalEncoderControl; //Atomic Table, directly used by various SW components,latest version 2.1 - USHORT LVTMAOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT VRAM_BlockDetectionByStrap; //Atomic Table, used only by Bios - USHORT MemoryCleanUp; //Atomic Table, only used by Bios - USHORT ProcessI2cChannelTransaction; //Function Table,only used by Bios - USHORT WriteOneByteToHWAssistedI2C; //Function Table,indirectly used by various SW components - USHORT ReadHWAssistedI2CStatus; //Atomic Table, indirectly used by various SW components - USHORT SpeedFanControl; //Function Table,indirectly used by various SW components,called from ASIC_Init - USHORT PowerConnectorDetection; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT MC_Synchronization; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock - USHORT ComputeMemoryEnginePLL; //Atomic Table, indirectly used by various SW components,called from SetMemory/EngineClock - USHORT MemoryRefreshConversion; //Atomic Table, indirectly used by various SW components,called from SetMemory or SetEngineClock - USHORT VRAM_GetCurrentInfoBlock; //Atomic Table, used only by Bios - USHORT DynamicMemorySettings; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock - USHORT MemoryTraining; //Atomic Table, used only by Bios - USHORT EnableSpreadSpectrumOnPPLL; //Atomic Table, directly used by various SW components,latest version 1.2 - USHORT TMDSAOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT SetVoltage; //Function Table,directly and/or indirectly used by various SW components,latest version 1.1 - USHORT DAC1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT DAC2OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1 - USHORT ComputeMemoryClockParam; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C" - USHORT ClockSource; //Atomic Table, indirectly used by various SW components,called from ASIC_Init - USHORT MemoryDeviceInit; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock - USHORT GetDispObjectInfo; //Atomic Table, indirectly used by various SW components,called from EnableVGARender - USHORT DIG1EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 - USHORT DIG2EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1 - USHORT DIG1TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 - USHORT DIG2TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1 - USHORT ProcessAuxChannelTransaction; //Function Table,only used by Bios - USHORT DPEncoderService; //Function Table,only used by Bios - USHORT GetVoltageInfo; //Function Table,only used by Bios since SI -}ATOM_MASTER_LIST_OF_COMMAND_TABLES; - -// For backward compatible -#define ReadEDIDFromHWAssistedI2C ProcessI2cChannelTransaction -#define DPTranslatorControl DIG2EncoderControl -#define UNIPHYTransmitterControl DIG1TransmitterControl -#define LVTMATransmitterControl DIG2TransmitterControl -#define SetCRTC_DPM_State GetConditionalGoldenSetting -#define SetUniphyInstance ASIC_StaticPwrMgtStatusChange -#define HPDInterruptService ReadHWAssistedI2CStatus -#define EnableVGA_Access GetSCLKOverMCLKRatio -#define EnableYUV GetDispObjectInfo -#define DynamicClockGating EnableDispPowerGating -#define SetupHWAssistedI2CStatus ComputeMemoryClockParam - -#define TMDSAEncoderControl PatchMCSetting -#define LVDSEncoderControl MC_SEQ_Control -#define LCD1OutputControl HW_Misc_Operation - - -typedef struct _ATOM_MASTER_COMMAND_TABLE -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_MASTER_LIST_OF_COMMAND_TABLES ListOfCommandTables; -}ATOM_MASTER_COMMAND_TABLE; - -/****************************************************************************/ -// Structures used in every command table -/****************************************************************************/ -typedef struct _ATOM_TABLE_ATTRIBUTE -{ -#if ATOM_BIG_ENDIAN - USHORT UpdatedByUtility:1; //[15]=Table updated by utility flag - USHORT PS_SizeInBytes:7; //[14:8]=Size of parameter space in Bytes (multiple of a dword), - USHORT WS_SizeInBytes:8; //[7:0]=Size of workspace in Bytes (in multiple of a dword), -#else - USHORT WS_SizeInBytes:8; //[7:0]=Size of workspace in Bytes (in multiple of a dword), - USHORT PS_SizeInBytes:7; //[14:8]=Size of parameter space in Bytes (multiple of a dword), - USHORT UpdatedByUtility:1; //[15]=Table updated by utility flag -#endif -}ATOM_TABLE_ATTRIBUTE; - -typedef union _ATOM_TABLE_ATTRIBUTE_ACCESS -{ - ATOM_TABLE_ATTRIBUTE sbfAccess; - USHORT susAccess; -}ATOM_TABLE_ATTRIBUTE_ACCESS; - -/****************************************************************************/ -// Common header for all command tables. -// Every table pointed by _ATOM_MASTER_COMMAND_TABLE has this common header. -// And the pointer actually points to this header. -/****************************************************************************/ -typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER -{ - ATOM_COMMON_TABLE_HEADER CommonHeader; - ATOM_TABLE_ATTRIBUTE TableAttribute; -}ATOM_COMMON_ROM_COMMAND_TABLE_HEADER; - -/****************************************************************************/ -// Structures used by ComputeMemoryEnginePLLTable -/****************************************************************************/ -#define COMPUTE_MEMORY_PLL_PARAM 1 -#define COMPUTE_ENGINE_PLL_PARAM 2 -#define ADJUST_MC_SETTING_PARAM 3 - -/****************************************************************************/ -// Structures used by AdjustMemoryControllerTable -/****************************************************************************/ -typedef struct _ATOM_ADJUST_MEMORY_CLOCK_FREQ -{ -#if ATOM_BIG_ENDIAN - ULONG ulPointerReturnFlag:1; // BYTE_3[7]=1 - Return the pointer to the right Data Block; BYTE_3[7]=0 - Program the right Data Block - ULONG ulMemoryModuleNumber:7; // BYTE_3[6:0] - ULONG ulClockFreq:24; -#else - ULONG ulClockFreq:24; - ULONG ulMemoryModuleNumber:7; // BYTE_3[6:0] - ULONG ulPointerReturnFlag:1; // BYTE_3[7]=1 - Return the pointer to the right Data Block; BYTE_3[7]=0 - Program the right Data Block -#endif -}ATOM_ADJUST_MEMORY_CLOCK_FREQ; -#define POINTER_RETURN_FLAG 0x80 - -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS -{ - ULONG ulClock; //When returen, it's the re-calculated clock based on given Fb_div Post_Div and ref_div - UCHAR ucAction; //0:reserved //1:Memory //2:Engine - UCHAR ucReserved; //may expand to return larger Fbdiv later - UCHAR ucFbDiv; //return value - UCHAR ucPostDiv; //return value -}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS; - -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2 -{ - ULONG ulClock; //When return, [23:0] return real clock - UCHAR ucAction; //0:reserved;COMPUTE_MEMORY_PLL_PARAM:Memory;COMPUTE_ENGINE_PLL_PARAM:Engine. it return ref_div to be written to register - USHORT usFbDiv; //return Feedback value to be written to register - UCHAR ucPostDiv; //return post div to be written to register -}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V2; -#define COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS - - -#define SET_CLOCK_FREQ_MASK 0x00FFFFFF //Clock change tables only take bit [23:0] as the requested clock value -#define USE_NON_BUS_CLOCK_MASK 0x01000000 //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) -#define USE_MEMORY_SELF_REFRESH_MASK 0x02000000 //Only applicable to memory clock change, when set, using memory self refresh during clock transition -#define SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04000000 //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change -#define FIRST_TIME_CHANGE_CLOCK 0x08000000 //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup -#define SKIP_SW_PROGRAM_PLL 0x10000000 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL -#define USE_SS_ENABLED_PIXEL_CLOCK USE_NON_BUS_CLOCK_MASK - -#define b3USE_NON_BUS_CLOCK_MASK 0x01 //Applicable to both memory and engine clock change, when set, it uses another clock as the temporary clock (engine uses memory and vice versa) -#define b3USE_MEMORY_SELF_REFRESH 0x02 //Only applicable to memory clock change, when set, using memory self refresh during clock transition -#define b3SKIP_INTERNAL_MEMORY_PARAMETER_CHANGE 0x04 //Only applicable to memory clock change, when set, the table will skip predefined internal memory parameter change -#define b3FIRST_TIME_CHANGE_CLOCK 0x08 //Applicable to both memory and engine clock change,when set, it means this is 1st time to change clock after ASIC bootup -#define b3SKIP_SW_PROGRAM_PLL 0x10 //Applicable to both memory and engine clock change, when set, it means the table will not program SPLL/MPLL - -typedef struct _ATOM_COMPUTE_CLOCK_FREQ -{ -#if ATOM_BIG_ENDIAN - ULONG ulComputeClockFlag:8; // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM - ULONG ulClockFreq:24; // in unit of 10kHz -#else - ULONG ulClockFreq:24; // in unit of 10kHz - ULONG ulComputeClockFlag:8; // =1: COMPUTE_MEMORY_PLL_PARAM, =2: COMPUTE_ENGINE_PLL_PARAM -#endif -}ATOM_COMPUTE_CLOCK_FREQ; - -typedef struct _ATOM_S_MPLL_FB_DIVIDER -{ - USHORT usFbDivFrac; - USHORT usFbDiv; -}ATOM_S_MPLL_FB_DIVIDER; - -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 -{ - union - { - ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter - ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter - }; - UCHAR ucRefDiv; //Output Parameter - UCHAR ucPostDiv; //Output Parameter - UCHAR ucCntlFlag; //Output Parameter - UCHAR ucReserved; -}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3; - -// ucCntlFlag -#define ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN 1 -#define ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE 2 -#define ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE 4 -#define ATOM_PLL_CNTL_FLAG_SPLL_ISPARE_9 8 - - -// V4 are only used for APU which PLL outside GPU -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 -{ -#if ATOM_BIG_ENDIAN - ULONG ucPostDiv; //return parameter: post divider which is used to program to register directly - ULONG ulClock:24; //Input= target clock, output = actual clock -#else - ULONG ulClock:24; //Input= target clock, output = actual clock - ULONG ucPostDiv; //return parameter: post divider which is used to program to register directly -#endif -}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4; - -typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 -{ - union - { - ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter - ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter - }; - UCHAR ucRefDiv; //Output Parameter - UCHAR ucPostDiv; //Output Parameter - union - { - UCHAR ucCntlFlag; //Output Flags - UCHAR ucInputFlag; //Input Flags. ucInputFlag[0] - Strobe(1)/Performance(0) mode - }; - UCHAR ucReserved; -}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5; - -// ucInputFlag -#define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN 1 // 1-StrobeMode, 0-PerformanceMode - -// use for ComputeMemoryClockParamTable -typedef struct _COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 -{ - union - { - ULONG ulClock; - ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output:UPPER_WORD=FB_DIV_INTEGER, LOWER_WORD=FB_DIV_FRAC shl (16-FB_FRACTION_BITS) - }; - UCHAR ucDllSpeed; //Output - UCHAR ucPostDiv; //Output - union{ - UCHAR ucInputFlag; //Input : ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN: 1-StrobeMode, 0-PerformanceMode - UCHAR ucPllCntlFlag; //Output: - }; - UCHAR ucBWCntl; -}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1; - -// definition of ucInputFlag -#define MPLL_INPUT_FLAG_STROBE_MODE_EN 0x01 -// definition of ucPllCntlFlag -#define MPLL_CNTL_FLAG_VCO_MODE_MASK 0x03 -#define MPLL_CNTL_FLAG_BYPASS_DQ_PLL 0x04 -#define MPLL_CNTL_FLAG_QDR_ENABLE 0x08 -#define MPLL_CNTL_FLAG_AD_HALF_RATE 0x10 - -//MPLL_CNTL_FLAG_BYPASS_AD_PLL has a wrong name, should be BYPASS_DQ_PLL -#define MPLL_CNTL_FLAG_BYPASS_AD_PLL 0x04 - -typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER -{ - ATOM_COMPUTE_CLOCK_FREQ ulClock; - ULONG ulReserved[2]; -}DYNAMICE_MEMORY_SETTINGS_PARAMETER; - -typedef struct _DYNAMICE_ENGINE_SETTINGS_PARAMETER -{ - ATOM_COMPUTE_CLOCK_FREQ ulClock; - ULONG ulMemoryClock; - ULONG ulReserved; -}DYNAMICE_ENGINE_SETTINGS_PARAMETER; - -/****************************************************************************/ -// Structures used by SetEngineClockTable -/****************************************************************************/ -typedef struct _SET_ENGINE_CLOCK_PARAMETERS -{ - ULONG ulTargetEngineClock; //In 10Khz unit -}SET_ENGINE_CLOCK_PARAMETERS; - -typedef struct _SET_ENGINE_CLOCK_PS_ALLOCATION -{ - ULONG ulTargetEngineClock; //In 10Khz unit - COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; -}SET_ENGINE_CLOCK_PS_ALLOCATION; - -/****************************************************************************/ -// Structures used by SetMemoryClockTable -/****************************************************************************/ -typedef struct _SET_MEMORY_CLOCK_PARAMETERS -{ - ULONG ulTargetMemoryClock; //In 10Khz unit -}SET_MEMORY_CLOCK_PARAMETERS; - -typedef struct _SET_MEMORY_CLOCK_PS_ALLOCATION -{ - ULONG ulTargetMemoryClock; //In 10Khz unit - COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_PS_ALLOCATION sReserved; -}SET_MEMORY_CLOCK_PS_ALLOCATION; - -/****************************************************************************/ -// Structures used by ASIC_Init.ctb -/****************************************************************************/ -typedef struct _ASIC_INIT_PARAMETERS -{ - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit -}ASIC_INIT_PARAMETERS; - -typedef struct _ASIC_INIT_PS_ALLOCATION -{ - ASIC_INIT_PARAMETERS sASICInitClocks; - SET_ENGINE_CLOCK_PS_ALLOCATION sReserved; //Caller doesn't need to init this structure -}ASIC_INIT_PS_ALLOCATION; - -/****************************************************************************/ -// Structure used by DynamicClockGatingTable.ctb -/****************************************************************************/ -typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS -{ - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucPadding[3]; -}DYNAMIC_CLOCK_GATING_PARAMETERS; -#define DYNAMIC_CLOCK_GATING_PS_ALLOCATION DYNAMIC_CLOCK_GATING_PARAMETERS - -/****************************************************************************/ -// Structure used by EnableDispPowerGatingTable.ctb -/****************************************************************************/ -typedef struct _ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 -{ - UCHAR ucDispPipeId; // ATOM_CRTC1, ATOM_CRTC2, ... - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucPadding[2]; -}ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1; - -/****************************************************************************/ -// Structure used by EnableASIC_StaticPwrMgtTable.ctb -/****************************************************************************/ -typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS -{ - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucPadding[3]; -}ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS; -#define ENABLE_ASIC_STATIC_PWR_MGT_PS_ALLOCATION ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS - -/****************************************************************************/ -// Structures used by DAC_LoadDetectionTable.ctb -/****************************************************************************/ -typedef struct _DAC_LOAD_DETECTION_PARAMETERS -{ - USHORT usDeviceID; //{ATOM_DEVICE_CRTx_SUPPORT,ATOM_DEVICE_TVx_SUPPORT,ATOM_DEVICE_CVx_SUPPORT} - UCHAR ucDacType; //{ATOM_DAC_A,ATOM_DAC_B, ATOM_EXT_DAC} - UCHAR ucMisc; //Valid only when table revision =1.3 and above -}DAC_LOAD_DETECTION_PARAMETERS; - -// DAC_LOAD_DETECTION_PARAMETERS.ucMisc -#define DAC_LOAD_MISC_YPrPb 0x01 - -typedef struct _DAC_LOAD_DETECTION_PS_ALLOCATION -{ - DAC_LOAD_DETECTION_PARAMETERS sDacload; - ULONG Reserved[2];// Don't set this one, allocation for EXT DAC -}DAC_LOAD_DETECTION_PS_ALLOCATION; - -/****************************************************************************/ -// Structures used by DAC1EncoderControlTable.ctb and DAC2EncoderControlTable.ctb -/****************************************************************************/ -typedef struct _DAC_ENCODER_CONTROL_PARAMETERS -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - UCHAR ucDacStandard; // See definition of ATOM_DACx_xxx, For DEC3.0, bit 7 used as internal flag to indicate DAC2 (==1) or DAC1 (==0) - UCHAR ucAction; // 0: turn off encoder - // 1: setup and turn on encoder - // 7: ATOM_ENCODER_INIT Initialize DAC -}DAC_ENCODER_CONTROL_PARAMETERS; - -#define DAC_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PARAMETERS - -/****************************************************************************/ -// Structures used by DIG1EncoderControlTable -// DIG2EncoderControlTable -// ExternalEncoderControlTable -/****************************************************************************/ -typedef struct _DIG_ENCODER_CONTROL_PARAMETERS -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - UCHAR ucConfig; - // [2] Link Select: - // =0: PHY linkA if bfLane<3 - // =1: PHY linkB if bfLanes<3 - // =0: PHY linkA+B if bfLanes=3 - // [3] Transmitter Sel - // =0: UNIPHY or PCIEPHY - // =1: LVTMA - UCHAR ucAction; // =0: turn off encoder - // =1: turn on encoder - UCHAR ucEncoderMode; - // =0: DP encoder - // =1: LVDS encoder - // =2: DVI encoder - // =3: HDMI encoder - // =4: SDVO encoder - UCHAR ucLaneNum; // how many lanes to enable - UCHAR ucReserved[2]; -}DIG_ENCODER_CONTROL_PARAMETERS; -#define DIG_ENCODER_CONTROL_PS_ALLOCATION DIG_ENCODER_CONTROL_PARAMETERS -#define EXTERNAL_ENCODER_CONTROL_PARAMETER DIG_ENCODER_CONTROL_PARAMETERS - -//ucConfig -#define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK 0x01 -#define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ 0x00 -#define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ 0x01 -#define ATOM_ENCODER_CONFIG_DPLINKRATE_5_40GHZ 0x02 -#define ATOM_ENCODER_CONFIG_LINK_SEL_MASK 0x04 -#define ATOM_ENCODER_CONFIG_LINKA 0x00 -#define ATOM_ENCODER_CONFIG_LINKB 0x04 -#define ATOM_ENCODER_CONFIG_LINKA_B ATOM_TRANSMITTER_CONFIG_LINKA -#define ATOM_ENCODER_CONFIG_LINKB_A ATOM_ENCODER_CONFIG_LINKB -#define ATOM_ENCODER_CONFIG_TRANSMITTER_SEL_MASK 0x08 -#define ATOM_ENCODER_CONFIG_UNIPHY 0x00 -#define ATOM_ENCODER_CONFIG_LVTMA 0x08 -#define ATOM_ENCODER_CONFIG_TRANSMITTER1 0x00 -#define ATOM_ENCODER_CONFIG_TRANSMITTER2 0x08 -#define ATOM_ENCODER_CONFIG_DIGB 0x80 // VBIOS Internal use, outside SW should set this bit=0 -// ucAction -// ATOM_ENABLE: Enable Encoder -// ATOM_DISABLE: Disable Encoder - -//ucEncoderMode -#define ATOM_ENCODER_MODE_DP 0 -#define ATOM_ENCODER_MODE_LVDS 1 -#define ATOM_ENCODER_MODE_DVI 2 -#define ATOM_ENCODER_MODE_HDMI 3 -#define ATOM_ENCODER_MODE_SDVO 4 -#define ATOM_ENCODER_MODE_DP_AUDIO 5 -#define ATOM_ENCODER_MODE_TV 13 -#define ATOM_ENCODER_MODE_CV 14 -#define ATOM_ENCODER_MODE_CRT 15 -#define ATOM_ENCODER_MODE_DVO 16 -#define ATOM_ENCODER_MODE_DP_SST ATOM_ENCODER_MODE_DP // For DP1.2 -#define ATOM_ENCODER_MODE_DP_MST 5 // For DP1.2 - -typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucReserved1:2; - UCHAR ucTransmitterSel:2; // =0: UniphyAB, =1: UniphyCD =2: UniphyEF - UCHAR ucLinkSel:1; // =0: linkA/C/E =1: linkB/D/F - UCHAR ucReserved:1; - UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz -#else - UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz - UCHAR ucReserved:1; - UCHAR ucLinkSel:1; // =0: linkA/C/E =1: linkB/D/F - UCHAR ucTransmitterSel:2; // =0: UniphyAB, =1: UniphyCD =2: UniphyEF - UCHAR ucReserved1:2; -#endif -}ATOM_DIG_ENCODER_CONFIG_V2; - - -typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - ATOM_DIG_ENCODER_CONFIG_V2 acConfig; - UCHAR ucAction; - UCHAR ucEncoderMode; - // =0: DP encoder - // =1: LVDS encoder - // =2: DVI encoder - // =3: HDMI encoder - // =4: SDVO encoder - UCHAR ucLaneNum; // how many lanes to enable - UCHAR ucStatus; // = DP_LINK_TRAINING_COMPLETE or DP_LINK_TRAINING_INCOMPLETE, only used by VBIOS with command ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS - UCHAR ucReserved; -}DIG_ENCODER_CONTROL_PARAMETERS_V2; - -//ucConfig -#define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_MASK 0x01 -#define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_1_62GHZ 0x00 -#define ATOM_ENCODER_CONFIG_V2_DPLINKRATE_2_70GHZ 0x01 -#define ATOM_ENCODER_CONFIG_V2_LINK_SEL_MASK 0x04 -#define ATOM_ENCODER_CONFIG_V2_LINKA 0x00 -#define ATOM_ENCODER_CONFIG_V2_LINKB 0x04 -#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER_SEL_MASK 0x18 -#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER1 0x00 -#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER2 0x08 -#define ATOM_ENCODER_CONFIG_V2_TRANSMITTER3 0x10 - -// ucAction: -// ATOM_DISABLE -// ATOM_ENABLE -#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_START 0x08 -#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1 0x09 -#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2 0x0a -#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3 0x13 -#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE 0x0b -#define ATOM_ENCODER_CMD_DP_VIDEO_OFF 0x0c -#define ATOM_ENCODER_CMD_DP_VIDEO_ON 0x0d -#define ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS 0x0e -#define ATOM_ENCODER_CMD_SETUP 0x0f -#define ATOM_ENCODER_CMD_SETUP_PANEL_MODE 0x10 - -// ucStatus -#define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE 0x10 -#define ATOM_ENCODER_STATUS_LINK_TRAINING_INCOMPLETE 0x00 - -//ucTableFormatRevision=1 -//ucTableContentRevision=3 -// Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver -typedef struct _ATOM_DIG_ENCODER_CONFIG_V3 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucReserved1:1; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) - UCHAR ucReserved:3; - UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz -#else - UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz - UCHAR ucReserved:3; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) - UCHAR ucReserved1:1; -#endif -}ATOM_DIG_ENCODER_CONFIG_V3; - -#define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 -#define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ 0x00 -#define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ 0x01 -#define ATOM_ENCODER_CONFIG_V3_ENCODER_SEL 0x70 -#define ATOM_ENCODER_CONFIG_V3_DIG0_ENCODER 0x00 -#define ATOM_ENCODER_CONFIG_V3_DIG1_ENCODER 0x10 -#define ATOM_ENCODER_CONFIG_V3_DIG2_ENCODER 0x20 -#define ATOM_ENCODER_CONFIG_V3_DIG3_ENCODER 0x30 -#define ATOM_ENCODER_CONFIG_V3_DIG4_ENCODER 0x40 -#define ATOM_ENCODER_CONFIG_V3_DIG5_ENCODER 0x50 - -typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - ATOM_DIG_ENCODER_CONFIG_V3 acConfig; - UCHAR ucAction; - union { - UCHAR ucEncoderMode; - // =0: DP encoder - // =1: LVDS encoder - // =2: DVI encoder - // =3: HDMI encoder - // =4: SDVO encoder - // =5: DP audio - UCHAR ucPanelMode; // only valid when ucAction == ATOM_ENCODER_CMD_SETUP_PANEL_MODE - // =0: external DP - // =1: internal DP2 - // =0x11: internal DP1 for NutMeg/Travis DP translator - }; - UCHAR ucLaneNum; // how many lanes to enable - UCHAR ucBitPerColor; // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP - UCHAR ucReserved; -}DIG_ENCODER_CONTROL_PARAMETERS_V3; - -//ucTableFormatRevision=1 -//ucTableContentRevision=4 -// start from NI -// Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver -typedef struct _ATOM_DIG_ENCODER_CONFIG_V4 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucReserved1:1; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) - UCHAR ucReserved:2; - UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version -#else - UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version - UCHAR ucReserved:2; - UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also referred as DIGA/B/C/D/E/F) - UCHAR ucReserved1:1; -#endif -}ATOM_DIG_ENCODER_CONFIG_V4; - -#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_MASK 0x03 -#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ 0x00 -#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ 0x01 -#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ 0x02 -#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ 0x03 -#define ATOM_ENCODER_CONFIG_V4_ENCODER_SEL 0x70 -#define ATOM_ENCODER_CONFIG_V4_DIG0_ENCODER 0x00 -#define ATOM_ENCODER_CONFIG_V4_DIG1_ENCODER 0x10 -#define ATOM_ENCODER_CONFIG_V4_DIG2_ENCODER 0x20 -#define ATOM_ENCODER_CONFIG_V4_DIG3_ENCODER 0x30 -#define ATOM_ENCODER_CONFIG_V4_DIG4_ENCODER 0x40 -#define ATOM_ENCODER_CONFIG_V4_DIG5_ENCODER 0x50 -#define ATOM_ENCODER_CONFIG_V4_DIG6_ENCODER 0x60 - -typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V4 -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - union{ - ATOM_DIG_ENCODER_CONFIG_V4 acConfig; - UCHAR ucConfig; - }; - UCHAR ucAction; - union { - UCHAR ucEncoderMode; - // =0: DP encoder - // =1: LVDS encoder - // =2: DVI encoder - // =3: HDMI encoder - // =4: SDVO encoder - // =5: DP audio - UCHAR ucPanelMode; // only valid when ucAction == ATOM_ENCODER_CMD_SETUP_PANEL_MODE - // =0: external DP - // =1: internal DP2 - // =0x11: internal DP1 for NutMeg/Travis DP translator - }; - UCHAR ucLaneNum; // how many lanes to enable - UCHAR ucBitPerColor; // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP - UCHAR ucHPD_ID; // HPD ID (1-6). =0 means to skip HDP programming. New comparing to previous version -}DIG_ENCODER_CONTROL_PARAMETERS_V4; - -// define ucBitPerColor: -#define PANEL_BPC_UNDEFINE 0x00 -#define PANEL_6BIT_PER_COLOR 0x01 -#define PANEL_8BIT_PER_COLOR 0x02 -#define PANEL_10BIT_PER_COLOR 0x03 -#define PANEL_12BIT_PER_COLOR 0x04 -#define PANEL_16BIT_PER_COLOR 0x05 - -//define ucPanelMode -#define DP_PANEL_MODE_EXTERNAL_DP_MODE 0x00 -#define DP_PANEL_MODE_INTERNAL_DP2_MODE 0x01 -#define DP_PANEL_MODE_INTERNAL_DP1_MODE 0x11 - -/****************************************************************************/ -// Structures used by UNIPHYTransmitterControlTable -// LVTMATransmitterControlTable -// DVOOutputControlTable -/****************************************************************************/ -typedef struct _ATOM_DP_VS_MODE -{ - UCHAR ucLaneSel; - UCHAR ucLaneSet; -}ATOM_DP_VS_MODE; - -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS -{ - union - { - USHORT usPixelClock; // in 10KHz; for bios convenient - USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h - ATOM_DP_VS_MODE asMode; // DP Voltage swing mode - }; - UCHAR ucConfig; - // [0]=0: 4 lane Link, - // =1: 8 lane Link ( Dual Links TMDS ) - // [1]=0: InCoherent mode - // =1: Coherent Mode - // [2] Link Select: - // =0: PHY linkA if bfLane<3 - // =1: PHY linkB if bfLanes<3 - // =0: PHY linkA+B if bfLanes=3 - // [5:4]PCIE lane Sel - // =0: lane 0~3 or 0~7 - // =1: lane 4~7 - // =2: lane 8~11 or 8~15 - // =3: lane 12~15 - UCHAR ucAction; // =0: turn off encoder - // =1: turn on encoder - UCHAR ucReserved[4]; -}DIG_TRANSMITTER_CONTROL_PARAMETERS; - -#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION DIG_TRANSMITTER_CONTROL_PARAMETERS - -//ucInitInfo -#define ATOM_TRAMITTER_INITINFO_CONNECTOR_MASK 0x00ff - -//ucConfig -#define ATOM_TRANSMITTER_CONFIG_8LANE_LINK 0x01 -#define ATOM_TRANSMITTER_CONFIG_COHERENT 0x02 -#define ATOM_TRANSMITTER_CONFIG_LINK_SEL_MASK 0x04 -#define ATOM_TRANSMITTER_CONFIG_LINKA 0x00 -#define ATOM_TRANSMITTER_CONFIG_LINKB 0x04 -#define ATOM_TRANSMITTER_CONFIG_LINKA_B 0x00 -#define ATOM_TRANSMITTER_CONFIG_LINKB_A 0x04 - -#define ATOM_TRANSMITTER_CONFIG_ENCODER_SEL_MASK 0x08 // only used when ATOM_TRANSMITTER_ACTION_ENABLE -#define ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER 0x00 // only used when ATOM_TRANSMITTER_ACTION_ENABLE -#define ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER 0x08 // only used when ATOM_TRANSMITTER_ACTION_ENABLE - -#define ATOM_TRANSMITTER_CONFIG_CLKSRC_MASK 0x30 -#define ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL 0x00 -#define ATOM_TRANSMITTER_CONFIG_CLKSRC_PCIE 0x20 -#define ATOM_TRANSMITTER_CONFIG_CLKSRC_XTALIN 0x30 -#define ATOM_TRANSMITTER_CONFIG_LANE_SEL_MASK 0xc0 -#define ATOM_TRANSMITTER_CONFIG_LANE_0_3 0x00 -#define ATOM_TRANSMITTER_CONFIG_LANE_0_7 0x00 -#define ATOM_TRANSMITTER_CONFIG_LANE_4_7 0x40 -#define ATOM_TRANSMITTER_CONFIG_LANE_8_11 0x80 -#define ATOM_TRANSMITTER_CONFIG_LANE_8_15 0x80 -#define ATOM_TRANSMITTER_CONFIG_LANE_12_15 0xc0 - -//ucAction -#define ATOM_TRANSMITTER_ACTION_DISABLE 0 -#define ATOM_TRANSMITTER_ACTION_ENABLE 1 -#define ATOM_TRANSMITTER_ACTION_LCD_BLOFF 2 -#define ATOM_TRANSMITTER_ACTION_LCD_BLON 3 -#define ATOM_TRANSMITTER_ACTION_BL_BRIGHTNESS_CONTROL 4 -#define ATOM_TRANSMITTER_ACTION_LCD_SELFTEST_START 5 -#define ATOM_TRANSMITTER_ACTION_LCD_SELFTEST_STOP 6 -#define ATOM_TRANSMITTER_ACTION_INIT 7 -#define ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT 8 -#define ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT 9 -#define ATOM_TRANSMITTER_ACTION_SETUP 10 -#define ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH 11 -#define ATOM_TRANSMITTER_ACTION_POWER_ON 12 -#define ATOM_TRANSMITTER_ACTION_POWER_OFF 13 - -// Following are used for DigTransmitterControlTable ver1.2 -typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V2 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) - // =1 Dig Transmitter 2 ( Uniphy CD ) - // =2 Dig Transmitter 3 ( Uniphy EF ) - UCHAR ucReserved:1; - UCHAR fDPConnector:1; //bit4=0: DP connector =1: None DP connector - UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) - UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E - // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - - UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) - UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector -#else - UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector - UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) - UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E - // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA( DIG inst0 ). =1: Data/clk path source from DIGB ( DIG inst1 ) - UCHAR fDPConnector:1; //bit4=0: DP connector =1: None DP connector - UCHAR ucReserved:1; - UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) - // =1 Dig Transmitter 2 ( Uniphy CD ) - // =2 Dig Transmitter 3 ( Uniphy EF ) -#endif -}ATOM_DIG_TRANSMITTER_CONFIG_V2; - -//ucConfig -//Bit0 -#define ATOM_TRANSMITTER_CONFIG_V2_DUAL_LINK_CONNECTOR 0x01 - -//Bit1 -#define ATOM_TRANSMITTER_CONFIG_V2_COHERENT 0x02 - -//Bit2 -#define ATOM_TRANSMITTER_CONFIG_V2_LINK_SEL_MASK 0x04 -#define ATOM_TRANSMITTER_CONFIG_V2_LINKA 0x00 -#define ATOM_TRANSMITTER_CONFIG_V2_LINKB 0x04 - -// Bit3 -#define ATOM_TRANSMITTER_CONFIG_V2_ENCODER_SEL_MASK 0x08 -#define ATOM_TRANSMITTER_CONFIG_V2_DIG1_ENCODER 0x00 // only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP -#define ATOM_TRANSMITTER_CONFIG_V2_DIG2_ENCODER 0x08 // only used when ucAction == ATOM_TRANSMITTER_ACTION_ENABLE or ATOM_TRANSMITTER_ACTION_SETUP - -// Bit4 -#define ATOM_TRASMITTER_CONFIG_V2_DP_CONNECTOR 0x10 - -// Bit7:6 -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER_SEL_MASK 0xC0 -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER1 0x00 //AB -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER2 0x40 //CD -#define ATOM_TRANSMITTER_CONFIG_V2_TRANSMITTER3 0x80 //EF - -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 -{ - union - { - USHORT usPixelClock; // in 10KHz; for bios convenient - USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h - ATOM_DP_VS_MODE asMode; // DP Voltage swing mode - }; - ATOM_DIG_TRANSMITTER_CONFIG_V2 acConfig; - UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX - UCHAR ucReserved[4]; -}DIG_TRANSMITTER_CONTROL_PARAMETERS_V2; - -typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V3 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) - // =1 Dig Transmitter 2 ( Uniphy CD ) - // =2 Dig Transmitter 3 ( Uniphy EF ) - UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, EXT_CLK=2 - UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F - UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E - // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) - UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector -#else - UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector - UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) - UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E - // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F - UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, EXT_CLK=2 - UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) - // =1 Dig Transmitter 2 ( Uniphy CD ) - // =2 Dig Transmitter 3 ( Uniphy EF ) -#endif -}ATOM_DIG_TRANSMITTER_CONFIG_V3; - - -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 -{ - union - { - USHORT usPixelClock; // in 10KHz; for bios convenient - USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h - ATOM_DP_VS_MODE asMode; // DP Voltage swing mode - }; - ATOM_DIG_TRANSMITTER_CONFIG_V3 acConfig; - UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX - UCHAR ucLaneNum; - UCHAR ucReserved[3]; -}DIG_TRANSMITTER_CONTROL_PARAMETERS_V3; - -//ucConfig -//Bit0 -#define ATOM_TRANSMITTER_CONFIG_V3_DUAL_LINK_CONNECTOR 0x01 - -//Bit1 -#define ATOM_TRANSMITTER_CONFIG_V3_COHERENT 0x02 - -//Bit2 -#define ATOM_TRANSMITTER_CONFIG_V3_LINK_SEL_MASK 0x04 -#define ATOM_TRANSMITTER_CONFIG_V3_LINKA 0x00 -#define ATOM_TRANSMITTER_CONFIG_V3_LINKB 0x04 - -// Bit3 -#define ATOM_TRANSMITTER_CONFIG_V3_ENCODER_SEL_MASK 0x08 -#define ATOM_TRANSMITTER_CONFIG_V3_DIG1_ENCODER 0x00 -#define ATOM_TRANSMITTER_CONFIG_V3_DIG2_ENCODER 0x08 - -// Bit5:4 -#define ATOM_TRASMITTER_CONFIG_V3_REFCLK_SEL_MASK 0x30 -#define ATOM_TRASMITTER_CONFIG_V3_P1PLL 0x00 -#define ATOM_TRASMITTER_CONFIG_V3_P2PLL 0x10 -#define ATOM_TRASMITTER_CONFIG_V3_REFCLK_SRC_EXT 0x20 - -// Bit7:6 -#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER_SEL_MASK 0xC0 -#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER1 0x00 //AB -#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER2 0x40 //CD -#define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER3 0x80 //EF - - -/****************************************************************************/ -// Structures used by UNIPHYTransmitterControlTable V1.4 -// ASIC Families: NI -// ucTableFormatRevision=1 -// ucTableContentRevision=4 -/****************************************************************************/ -typedef struct _ATOM_DP_VS_MODE_V4 -{ - UCHAR ucLaneSel; - union - { - UCHAR ucLaneSet; - struct { -#if ATOM_BIG_ENDIAN - UCHAR ucPOST_CURSOR2:2; //Bit[7:6] Post Cursor2 Level <= New in V4 - UCHAR ucPRE_EMPHASIS:3; //Bit[5:3] Pre-emphasis Level - UCHAR ucVOLTAGE_SWING:3; //Bit[2:0] Voltage Swing Level -#else - UCHAR ucVOLTAGE_SWING:3; //Bit[2:0] Voltage Swing Level - UCHAR ucPRE_EMPHASIS:3; //Bit[5:3] Pre-emphasis Level - UCHAR ucPOST_CURSOR2:2; //Bit[7:6] Post Cursor2 Level <= New in V4 -#endif - }; - }; -}ATOM_DP_VS_MODE_V4; - -typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V4 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) - // =1 Dig Transmitter 2 ( Uniphy CD ) - // =2 Dig Transmitter 3 ( Uniphy EF ) - UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, DCPLL=2, EXT_CLK=3 <= New - UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F - UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E - // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) - UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector -#else - UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector - UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) - UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E - // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F - UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F - UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, DCPLL=2, EXT_CLK=3 <= New - UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) - // =1 Dig Transmitter 2 ( Uniphy CD ) - // =2 Dig Transmitter 3 ( Uniphy EF ) -#endif -}ATOM_DIG_TRANSMITTER_CONFIG_V4; - -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 -{ - union - { - USHORT usPixelClock; // in 10KHz; for bios convenient - USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h - ATOM_DP_VS_MODE_V4 asMode; // DP Voltage swing mode Redefined comparing to previous version - }; - union - { - ATOM_DIG_TRANSMITTER_CONFIG_V4 acConfig; - UCHAR ucConfig; - }; - UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX - UCHAR ucLaneNum; - UCHAR ucReserved[3]; -}DIG_TRANSMITTER_CONTROL_PARAMETERS_V4; - -//ucConfig -//Bit0 -#define ATOM_TRANSMITTER_CONFIG_V4_DUAL_LINK_CONNECTOR 0x01 -//Bit1 -#define ATOM_TRANSMITTER_CONFIG_V4_COHERENT 0x02 -//Bit2 -#define ATOM_TRANSMITTER_CONFIG_V4_LINK_SEL_MASK 0x04 -#define ATOM_TRANSMITTER_CONFIG_V4_LINKA 0x00 -#define ATOM_TRANSMITTER_CONFIG_V4_LINKB 0x04 -// Bit3 -#define ATOM_TRANSMITTER_CONFIG_V4_ENCODER_SEL_MASK 0x08 -#define ATOM_TRANSMITTER_CONFIG_V4_DIG1_ENCODER 0x00 -#define ATOM_TRANSMITTER_CONFIG_V4_DIG2_ENCODER 0x08 -// Bit5:4 -#define ATOM_TRANSMITTER_CONFIG_V4_REFCLK_SEL_MASK 0x30 -#define ATOM_TRANSMITTER_CONFIG_V4_P1PLL 0x00 -#define ATOM_TRANSMITTER_CONFIG_V4_P2PLL 0x10 -#define ATOM_TRANSMITTER_CONFIG_V4_DCPLL 0x20 // New in _V4 -#define ATOM_TRANSMITTER_CONFIG_V4_REFCLK_SRC_EXT 0x30 // Changed comparing to V3 -// Bit7:6 -#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER_SEL_MASK 0xC0 -#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER1 0x00 //AB -#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER2 0x40 //CD -#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER3 0x80 //EF - - -typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V5 -{ -#if ATOM_BIG_ENDIAN - UCHAR ucReservd1:1; - UCHAR ucHPDSel:3; - UCHAR ucPhyClkSrcId:2; - UCHAR ucCoherentMode:1; - UCHAR ucReserved:1; -#else - UCHAR ucReserved:1; - UCHAR ucCoherentMode:1; - UCHAR ucPhyClkSrcId:2; - UCHAR ucHPDSel:3; - UCHAR ucReservd1:1; -#endif -}ATOM_DIG_TRANSMITTER_CONFIG_V5; - -typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 -{ - USHORT usSymClock; // Encoder Clock in 10kHz,(DP mode)= linkclock/10, (TMDS/LVDS/HDMI)= pixel clock, (HDMI deep color), =pixel clock * deep_color_ratio - UCHAR ucPhyId; // 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4= UNIPHYE 5=UNIPHYF - UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_xxx - UCHAR ucLaneNum; // indicate lane number 1-8 - UCHAR ucConnObjId; // Connector Object Id defined in ObjectId.h - UCHAR ucDigMode; // indicate DIG mode - union{ - ATOM_DIG_TRANSMITTER_CONFIG_V5 asConfig; - UCHAR ucConfig; - }; - UCHAR ucDigEncoderSel; // indicate DIG front end encoder - UCHAR ucDPLaneSet; - UCHAR ucReserved; - UCHAR ucReserved1; -}DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5; - -//ucPhyId -#define ATOM_PHY_ID_UNIPHYA 0 -#define ATOM_PHY_ID_UNIPHYB 1 -#define ATOM_PHY_ID_UNIPHYC 2 -#define ATOM_PHY_ID_UNIPHYD 3 -#define ATOM_PHY_ID_UNIPHYE 4 -#define ATOM_PHY_ID_UNIPHYF 5 -#define ATOM_PHY_ID_UNIPHYG 6 - -// ucDigEncoderSel -#define ATOM_TRANMSITTER_V5__DIGA_SEL 0x01 -#define ATOM_TRANMSITTER_V5__DIGB_SEL 0x02 -#define ATOM_TRANMSITTER_V5__DIGC_SEL 0x04 -#define ATOM_TRANMSITTER_V5__DIGD_SEL 0x08 -#define ATOM_TRANMSITTER_V5__DIGE_SEL 0x10 -#define ATOM_TRANMSITTER_V5__DIGF_SEL 0x20 -#define ATOM_TRANMSITTER_V5__DIGG_SEL 0x40 - -// ucDigMode -#define ATOM_TRANSMITTER_DIGMODE_V5_DP 0 -#define ATOM_TRANSMITTER_DIGMODE_V5_LVDS 1 -#define ATOM_TRANSMITTER_DIGMODE_V5_DVI 2 -#define ATOM_TRANSMITTER_DIGMODE_V5_HDMI 3 -#define ATOM_TRANSMITTER_DIGMODE_V5_SDVO 4 -#define ATOM_TRANSMITTER_DIGMODE_V5_DP_MST 5 - -// ucDPLaneSet -#define DP_LANE_SET__0DB_0_4V 0x00 -#define DP_LANE_SET__0DB_0_6V 0x01 -#define DP_LANE_SET__0DB_0_8V 0x02 -#define DP_LANE_SET__0DB_1_2V 0x03 -#define DP_LANE_SET__3_5DB_0_4V 0x08 -#define DP_LANE_SET__3_5DB_0_6V 0x09 -#define DP_LANE_SET__3_5DB_0_8V 0x0a -#define DP_LANE_SET__6DB_0_4V 0x10 -#define DP_LANE_SET__6DB_0_6V 0x11 -#define DP_LANE_SET__9_5DB_0_4V 0x18 - -// ATOM_DIG_TRANSMITTER_CONFIG_V5 asConfig; -// Bit1 -#define ATOM_TRANSMITTER_CONFIG_V5_COHERENT 0x02 - -// Bit3:2 -#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SEL_MASK 0x0c -#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SEL_SHIFT 0x02 - -#define ATOM_TRANSMITTER_CONFIG_V5_P1PLL 0x00 -#define ATOM_TRANSMITTER_CONFIG_V5_P2PLL 0x04 -#define ATOM_TRANSMITTER_CONFIG_V5_P0PLL 0x08 -#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT 0x0c -// Bit6:4 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD_SEL_MASK 0x70 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD_SEL_SHIFT 0x04 - -#define ATOM_TRANSMITTER_CONFIG_V5_NO_HPD_SEL 0x00 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL 0x10 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL 0x20 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL 0x30 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL 0x40 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL 0x50 -#define ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL 0x60 - -#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION_V1_5 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 - - -/****************************************************************************/ -// Structures used by ExternalEncoderControlTable V1.3 -// ASIC Families: Evergreen, Llano, NI -// ucTableFormatRevision=1 -// ucTableContentRevision=3 -/****************************************************************************/ - -typedef struct _EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 -{ - union{ - USHORT usPixelClock; // pixel clock in 10Khz, valid when ucAction=SETUP/ENABLE_OUTPUT - USHORT usConnectorId; // connector id, valid when ucAction = INIT - }; - UCHAR ucConfig; // indicate which encoder, and DP link rate when ucAction = SETUP/ENABLE_OUTPUT - UCHAR ucAction; // - UCHAR ucEncoderMode; // encoder mode, only used when ucAction = SETUP/ENABLE_OUTPUT - UCHAR ucLaneNum; // lane number, only used when ucAction = SETUP/ENABLE_OUTPUT - UCHAR ucBitPerColor; // output bit per color, only valid when ucAction = SETUP/ENABLE_OUTPUT and ucEncodeMode= DP - UCHAR ucReserved; -}EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3; - -// ucAction -#define EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT 0x00 -#define EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT 0x01 -#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT 0x07 -#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP 0x0f -#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF 0x10 -#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING 0x11 -#define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12 -#define EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP 0x14 - -// ucConfig -#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 -#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ 0x00 -#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ 0x01 -#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ 0x02 -#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER_SEL_MASK 0x70 -#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER1 0x00 -#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER2 0x10 -#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER3 0x20 - -typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 -{ - EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 sExtEncoder; - ULONG ulReserved[2]; -}EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3; - - -/****************************************************************************/ -// Structures used by DAC1OuputControlTable -// DAC2OuputControlTable -// LVTMAOutputControlTable (Before DEC30) -// TMDSAOutputControlTable (Before DEC30) -/****************************************************************************/ -typedef struct _DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -{ - UCHAR ucAction; // Possible input:ATOM_ENABLE||ATOMDISABLE - // When the display is LCD, in addition to above: - // ATOM_LCD_BLOFF|| ATOM_LCD_BLON ||ATOM_LCD_BL_BRIGHTNESS_CONTROL||ATOM_LCD_SELFTEST_START|| - // ATOM_LCD_SELFTEST_STOP - - UCHAR aucPadding[3]; // padding to DWORD aligned -}DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS; - -#define DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS - - -#define CRT1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define CRT1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define CRT2_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define CRT2_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define CV1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define CV1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define TV1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define TV1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define DFP1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define DFP1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define DFP2_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define DFP2_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define LCD1_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define LCD1_OUTPUT_CONTROL_PS_ALLOCATION DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION - -#define DVO_OUTPUT_CONTROL_PARAMETERS DISPLAY_DEVICE_OUTPUT_CONTROL_PARAMETERS -#define DVO_OUTPUT_CONTROL_PS_ALLOCATION DIG_TRANSMITTER_CONTROL_PS_ALLOCATION -#define DVO_OUTPUT_CONTROL_PARAMETERS_V3 DIG_TRANSMITTER_CONTROL_PARAMETERS - -/****************************************************************************/ -// Structures used by BlankCRTCTable -/****************************************************************************/ -typedef struct _BLANK_CRTC_PARAMETERS -{ - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucBlanking; // ATOM_BLANKING or ATOM_BLANKINGOFF - USHORT usBlackColorRCr; - USHORT usBlackColorGY; - USHORT usBlackColorBCb; -}BLANK_CRTC_PARAMETERS; -#define BLANK_CRTC_PS_ALLOCATION BLANK_CRTC_PARAMETERS - -/****************************************************************************/ -// Structures used by EnableCRTCTable -// EnableCRTCMemReqTable -// UpdateCRTC_DoubleBufferRegistersTable -/****************************************************************************/ -typedef struct _ENABLE_CRTC_PARAMETERS -{ - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucPadding[2]; -}ENABLE_CRTC_PARAMETERS; -#define ENABLE_CRTC_PS_ALLOCATION ENABLE_CRTC_PARAMETERS - -/****************************************************************************/ -// Structures used by SetCRTC_OverScanTable -/****************************************************************************/ -typedef struct _SET_CRTC_OVERSCAN_PARAMETERS -{ - USHORT usOverscanRight; // right - USHORT usOverscanLeft; // left - USHORT usOverscanBottom; // bottom - USHORT usOverscanTop; // top - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucPadding[3]; -}SET_CRTC_OVERSCAN_PARAMETERS; -#define SET_CRTC_OVERSCAN_PS_ALLOCATION SET_CRTC_OVERSCAN_PARAMETERS - -/****************************************************************************/ -// Structures used by SetCRTC_ReplicationTable -/****************************************************************************/ -typedef struct _SET_CRTC_REPLICATION_PARAMETERS -{ - UCHAR ucH_Replication; // horizontal replication - UCHAR ucV_Replication; // vertical replication - UCHAR usCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucPadding; -}SET_CRTC_REPLICATION_PARAMETERS; -#define SET_CRTC_REPLICATION_PS_ALLOCATION SET_CRTC_REPLICATION_PARAMETERS - -/****************************************************************************/ -// Structures used by SelectCRTC_SourceTable -/****************************************************************************/ -typedef struct _SELECT_CRTC_SOURCE_PARAMETERS -{ - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucDevice; // ATOM_DEVICE_CRT1|ATOM_DEVICE_CRT2|.... - UCHAR ucPadding[2]; -}SELECT_CRTC_SOURCE_PARAMETERS; -#define SELECT_CRTC_SOURCE_PS_ALLOCATION SELECT_CRTC_SOURCE_PARAMETERS - -typedef struct _SELECT_CRTC_SOURCE_PARAMETERS_V2 -{ - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucEncoderID; // DAC1/DAC2/TVOUT/DIG1/DIG2/DVO - UCHAR ucEncodeMode; // Encoding mode, only valid when using DIG1/DIG2/DVO - UCHAR ucPadding; -}SELECT_CRTC_SOURCE_PARAMETERS_V2; - -//ucEncoderID -//#define ASIC_INT_DAC1_ENCODER_ID 0x00 -//#define ASIC_INT_TV_ENCODER_ID 0x02 -//#define ASIC_INT_DIG1_ENCODER_ID 0x03 -//#define ASIC_INT_DAC2_ENCODER_ID 0x04 -//#define ASIC_EXT_TV_ENCODER_ID 0x06 -//#define ASIC_INT_DVO_ENCODER_ID 0x07 -//#define ASIC_INT_DIG2_ENCODER_ID 0x09 -//#define ASIC_EXT_DIG_ENCODER_ID 0x05 - -//ucEncodeMode -//#define ATOM_ENCODER_MODE_DP 0 -//#define ATOM_ENCODER_MODE_LVDS 1 -//#define ATOM_ENCODER_MODE_DVI 2 -//#define ATOM_ENCODER_MODE_HDMI 3 -//#define ATOM_ENCODER_MODE_SDVO 4 -//#define ATOM_ENCODER_MODE_TV 13 -//#define ATOM_ENCODER_MODE_CV 14 -//#define ATOM_ENCODER_MODE_CRT 15 - -/****************************************************************************/ -// Structures used by SetPixelClockTable -// GetPixelClockTable -/****************************************************************************/ -//Major revision=1., Minor revision=1 -typedef struct _PIXEL_CLOCK_PARAMETERS -{ - USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) - // 0 means disable PPLL - USHORT usRefDiv; // Reference divider - USHORT usFbDiv; // feedback divider - UCHAR ucPostDiv; // post divider - UCHAR ucFracFbDiv; // fractional feedback divider - UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 - UCHAR ucRefDivSrc; // ATOM_PJITTER or ATO_NONPJITTER - UCHAR ucCRTC; // Which CRTC uses this Ppll - UCHAR ucPadding; -}PIXEL_CLOCK_PARAMETERS; - -//Major revision=1., Minor revision=2, add ucMiscIfno -//ucMiscInfo: -#define MISC_FORCE_REPROG_PIXEL_CLOCK 0x1 -#define MISC_DEVICE_INDEX_MASK 0xF0 -#define MISC_DEVICE_INDEX_SHIFT 4 - -typedef struct _PIXEL_CLOCK_PARAMETERS_V2 -{ - USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) - // 0 means disable PPLL - USHORT usRefDiv; // Reference divider - USHORT usFbDiv; // feedback divider - UCHAR ucPostDiv; // post divider - UCHAR ucFracFbDiv; // fractional feedback divider - UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 - UCHAR ucRefDivSrc; // ATOM_PJITTER or ATO_NONPJITTER - UCHAR ucCRTC; // Which CRTC uses this Ppll - UCHAR ucMiscInfo; // Different bits for different purpose, bit [7:4] as device index, bit[0]=Force prog -}PIXEL_CLOCK_PARAMETERS_V2; - -//Major revision=1., Minor revision=3, structure/definition change -//ucEncoderMode: -//ATOM_ENCODER_MODE_DP -//ATOM_ENOCDER_MODE_LVDS -//ATOM_ENOCDER_MODE_DVI -//ATOM_ENOCDER_MODE_HDMI -//ATOM_ENOCDER_MODE_SDVO -//ATOM_ENCODER_MODE_TV 13 -//ATOM_ENCODER_MODE_CV 14 -//ATOM_ENCODER_MODE_CRT 15 - -//ucDVOConfig -//#define DVO_ENCODER_CONFIG_RATE_SEL 0x01 -//#define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 -//#define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 -//#define DVO_ENCODER_CONFIG_OUTPUT_SEL 0x0c -//#define DVO_ENCODER_CONFIG_LOW12BIT 0x00 -//#define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 -//#define DVO_ENCODER_CONFIG_24BIT 0x08 - -//ucMiscInfo: also changed, see below -#define PIXEL_CLOCK_MISC_FORCE_PROG_PPLL 0x01 -#define PIXEL_CLOCK_MISC_VGA_MODE 0x02 -#define PIXEL_CLOCK_MISC_CRTC_SEL_MASK 0x04 -#define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC1 0x00 -#define PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2 0x04 -#define PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK 0x08 -#define PIXEL_CLOCK_MISC_REF_DIV_SRC 0x10 -// V1.4 for RoadRunner -#define PIXEL_CLOCK_V4_MISC_SS_ENABLE 0x10 -#define PIXEL_CLOCK_V4_MISC_COHERENT_MODE 0x20 - - -typedef struct _PIXEL_CLOCK_PARAMETERS_V3 -{ - USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) - // 0 means disable PPLL. For VGA PPLL,make sure this value is not 0. - USHORT usRefDiv; // Reference divider - USHORT usFbDiv; // feedback divider - UCHAR ucPostDiv; // post divider - UCHAR ucFracFbDiv; // fractional feedback divider - UCHAR ucPpll; // ATOM_PPLL1 or ATOM_PPL2 - UCHAR ucTransmitterId; // graphic encoder id defined in objectId.h - union - { - UCHAR ucEncoderMode; // encoder type defined as ATOM_ENCODER_MODE_DP/DVI/HDMI/ - UCHAR ucDVOConfig; // when use DVO, need to know SDR/DDR, 12bit or 24bit - }; - UCHAR ucMiscInfo; // bit[0]=Force program, bit[1]= set pclk for VGA, b[2]= CRTC sel - // bit[3]=0:use PPLL for dispclk source, =1: use engine clock for dispclock source - // bit[4]=0:use XTALIN as the source of reference divider,=1 use the pre-defined clock as the source of reference divider -}PIXEL_CLOCK_PARAMETERS_V3; - -#define PIXEL_CLOCK_PARAMETERS_LAST PIXEL_CLOCK_PARAMETERS_V2 -#define GET_PIXEL_CLOCK_PS_ALLOCATION PIXEL_CLOCK_PARAMETERS_LAST - -typedef struct _PIXEL_CLOCK_PARAMETERS_V5 -{ - UCHAR ucCRTC; // ATOM_CRTC1~6, indicate the CRTC controller to - // drive the pixel clock. not used for DCPLL case. - union{ - UCHAR ucReserved; - UCHAR ucFracFbDiv; // [gphan] temporary to prevent build problem. remove it after driver code is changed. - }; - USHORT usPixelClock; // target the pixel clock to drive the CRTC timing - // 0 means disable PPLL/DCPLL. - USHORT usFbDiv; // feedback divider integer part. - UCHAR ucPostDiv; // post divider. - UCHAR ucRefDiv; // Reference divider - UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2/ATOM_DCPLL - UCHAR ucTransmitterID; // ASIC encoder id defined in objectId.h, - // indicate which graphic encoder will be used. - UCHAR ucEncoderMode; // Encoder mode: - UCHAR ucMiscInfo; // bit[0]= Force program PPLL - // bit[1]= when VGA timing is used. - // bit[3:2]= HDMI panel bit depth: =0: 24bpp =1:30bpp, =2:32bpp - // bit[4]= RefClock source for PPLL. - // =0: XTLAIN( default mode ) - // =1: other external clock source, which is pre-defined - // by VBIOS depend on the feature required. - // bit[7:5]: reserved. - ULONG ulFbDivDecFrac; // 20 bit feedback divider decimal fraction part, range from 1~999999 ( 0.000001 to 0.999999 ) - -}PIXEL_CLOCK_PARAMETERS_V5; - -#define PIXEL_CLOCK_V5_MISC_FORCE_PROG_PPLL 0x01 -#define PIXEL_CLOCK_V5_MISC_VGA_MODE 0x02 -#define PIXEL_CLOCK_V5_MISC_HDMI_BPP_MASK 0x0c -#define PIXEL_CLOCK_V5_MISC_HDMI_24BPP 0x00 -#define PIXEL_CLOCK_V5_MISC_HDMI_30BPP 0x04 -#define PIXEL_CLOCK_V5_MISC_HDMI_32BPP 0x08 -#define PIXEL_CLOCK_V5_MISC_REF_DIV_SRC 0x10 - -typedef struct _CRTC_PIXEL_CLOCK_FREQ -{ -#if ATOM_BIG_ENDIAN - ULONG ucCRTC:8; // ATOM_CRTC1~6, indicate the CRTC controller to - // drive the pixel clock. not used for DCPLL case. - ULONG ulPixelClock:24; // target the pixel clock to drive the CRTC timing. - // 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to previous version. -#else - ULONG ulPixelClock:24; // target the pixel clock to drive the CRTC timing. - // 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to previous version. - ULONG ucCRTC:8; // ATOM_CRTC1~6, indicate the CRTC controller to - // drive the pixel clock. not used for DCPLL case. -#endif -}CRTC_PIXEL_CLOCK_FREQ; - -typedef struct _PIXEL_CLOCK_PARAMETERS_V6 -{ - union{ - CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; // pixel clock and CRTC id frequency - ULONG ulDispEngClkFreq; // dispclk frequency - }; - USHORT usFbDiv; // feedback divider integer part. - UCHAR ucPostDiv; // post divider. - UCHAR ucRefDiv; // Reference divider - UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2/ATOM_DCPLL - UCHAR ucTransmitterID; // ASIC encoder id defined in objectId.h, - // indicate which graphic encoder will be used. - UCHAR ucEncoderMode; // Encoder mode: - UCHAR ucMiscInfo; // bit[0]= Force program PPLL - // bit[1]= when VGA timing is used. - // bit[3:2]= HDMI panel bit depth: =0: 24bpp =1:30bpp, =2:32bpp - // bit[4]= RefClock source for PPLL. - // =0: XTLAIN( default mode ) - // =1: other external clock source, which is pre-defined - // by VBIOS depend on the feature required. - // bit[7:5]: reserved. - ULONG ulFbDivDecFrac; // 20 bit feedback divider decimal fraction part, range from 1~999999 ( 0.000001 to 0.999999 ) - -}PIXEL_CLOCK_PARAMETERS_V6; - -#define PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL 0x01 -#define PIXEL_CLOCK_V6_MISC_VGA_MODE 0x02 -#define PIXEL_CLOCK_V6_MISC_HDMI_BPP_MASK 0x0c -#define PIXEL_CLOCK_V6_MISC_HDMI_24BPP 0x00 -#define PIXEL_CLOCK_V6_MISC_HDMI_36BPP 0x04 -#define PIXEL_CLOCK_V6_MISC_HDMI_30BPP 0x08 -#define PIXEL_CLOCK_V6_MISC_HDMI_48BPP 0x0c -#define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC 0x10 - -typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2 -{ - PIXEL_CLOCK_PARAMETERS_V3 sDispClkInput; -}GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2; - -typedef struct _GET_DISP_PLL_STATUS_OUTPUT_PARAMETERS_V2 -{ - UCHAR ucStatus; - UCHAR ucRefDivSrc; // =1: reference clock source from XTALIN, =0: source from PCIE ref clock - UCHAR ucReserved[2]; -}GET_DISP_PLL_STATUS_OUTPUT_PARAMETERS_V2; - -typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V3 -{ - PIXEL_CLOCK_PARAMETERS_V5 sDispClkInput; -}GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V3; - -/****************************************************************************/ -// Structures used by AdjustDisplayPllTable -/****************************************************************************/ -typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS -{ - USHORT usPixelClock; - UCHAR ucTransmitterID; - UCHAR ucEncodeMode; - union - { - UCHAR ucDVOConfig; //if DVO, need passing link rate and output 12bitlow or 24bit - UCHAR ucConfig; //if none DVO, not defined yet - }; - UCHAR ucReserved[3]; -}ADJUST_DISPLAY_PLL_PARAMETERS; - -#define ADJUST_DISPLAY_CONFIG_SS_ENABLE 0x10 -#define ADJUST_DISPLAY_PLL_PS_ALLOCATION ADJUST_DISPLAY_PLL_PARAMETERS - -typedef struct _ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 -{ - USHORT usPixelClock; // target pixel clock - UCHAR ucTransmitterID; // GPU transmitter id defined in objectid.h - UCHAR ucEncodeMode; // encoder mode: CRT, LVDS, DP, TMDS or HDMI - UCHAR ucDispPllConfig; // display pll configure parameter defined as following DISPPLL_CONFIG_XXXX - UCHAR ucExtTransmitterID; // external encoder id. - UCHAR ucReserved[2]; -}ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3; - -// usDispPllConfig v1.2 for RoadRunner -#define DISPPLL_CONFIG_DVO_RATE_SEL 0x0001 // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_DVO_DDR_SPEED 0x0000 // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_DVO_SDR_SPEED 0x0001 // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_DVO_OUTPUT_SEL 0x000c // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_DVO_LOW12BIT 0x0000 // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_DVO_UPPER12BIT 0x0004 // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_DVO_24BIT 0x0008 // need only when ucTransmitterID = DVO -#define DISPPLL_CONFIG_SS_ENABLE 0x0010 // Only used when ucEncoderMode = DP or LVDS -#define DISPPLL_CONFIG_COHERENT_MODE 0x0020 // Only used when ucEncoderMode = TMDS or HDMI -#define DISPPLL_CONFIG_DUAL_LINK 0x0040 // Only used when ucEncoderMode = TMDS or LVDS - - -typedef struct _ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3 -{ - ULONG ulDispPllFreq; // return display PPLL freq which is used to generate the pixclock, and related idclk, symclk etc - UCHAR ucRefDiv; // if it is none-zero, it is used to be calculated the other ppll parameter fb_divider and post_div ( if it is not given ) - UCHAR ucPostDiv; // if it is none-zero, it is used to be calculated the other ppll parameter fb_divider - UCHAR ucReserved[2]; -}ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3; - -typedef struct _ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 -{ - union - { - ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 sInput; - ADJUST_DISPLAY_PLL_OUTPUT_PARAMETERS_V3 sOutput; - }; -} ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3; - -/****************************************************************************/ -// Structures used by EnableYUVTable -/****************************************************************************/ -typedef struct _ENABLE_YUV_PARAMETERS -{ - UCHAR ucEnable; // ATOM_ENABLE:Enable YUV or ATOM_DISABLE:Disable YUV (RGB) - UCHAR ucCRTC; // Which CRTC needs this YUV or RGB format - UCHAR ucPadding[2]; -}ENABLE_YUV_PARAMETERS; -#define ENABLE_YUV_PS_ALLOCATION ENABLE_YUV_PARAMETERS - -/****************************************************************************/ -// Structures used by GetMemoryClockTable -/****************************************************************************/ -typedef struct _GET_MEMORY_CLOCK_PARAMETERS -{ - ULONG ulReturnMemoryClock; // current memory speed in 10KHz unit -} GET_MEMORY_CLOCK_PARAMETERS; -#define GET_MEMORY_CLOCK_PS_ALLOCATION GET_MEMORY_CLOCK_PARAMETERS - -/****************************************************************************/ -// Structures used by GetEngineClockTable -/****************************************************************************/ -typedef struct _GET_ENGINE_CLOCK_PARAMETERS -{ - ULONG ulReturnEngineClock; // current engine speed in 10KHz unit -} GET_ENGINE_CLOCK_PARAMETERS; -#define GET_ENGINE_CLOCK_PS_ALLOCATION GET_ENGINE_CLOCK_PARAMETERS - -/****************************************************************************/ -// Following Structures and constant may be obsolete -/****************************************************************************/ -//Maxium 8 bytes,the data read in will be placed in the parameter space. -//Read operaion successeful when the paramter space is non-zero, otherwise read operation failed -typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS -{ - USHORT usPrescale; //Ratio between Engine clock and I2C clock - USHORT usVRAMAddress; //Address in Frame Buffer where to pace raw EDID - USHORT usStatus; //When use output: lower byte EDID checksum, high byte hardware status - //WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte - UCHAR ucSlaveAddr; //Read from which slave - UCHAR ucLineNumber; //Read from which HW assisted line -}READ_EDID_FROM_HW_I2C_DATA_PARAMETERS; -#define READ_EDID_FROM_HW_I2C_DATA_PS_ALLOCATION READ_EDID_FROM_HW_I2C_DATA_PARAMETERS - - -#define ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSDATABYTE 0 -#define ATOM_WRITE_I2C_FORMAT_PSOFFSET_PSTWODATABYTES 1 -#define ATOM_WRITE_I2C_FORMAT_PSCOUNTER_PSOFFSET_IDDATABLOCK 2 -#define ATOM_WRITE_I2C_FORMAT_PSCOUNTER_IDOFFSET_PLUS_IDDATABLOCK 3 -#define ATOM_WRITE_I2C_FORMAT_IDCOUNTER_IDOFFSET_IDDATABLOCK 4 - -typedef struct _WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS -{ - USHORT usPrescale; //Ratio between Engine clock and I2C clock - USHORT usByteOffset; //Write to which byte - //Upper portion of usByteOffset is Format of data - //1bytePS+offsetPS - //2bytesPS+offsetPS - //blockID+offsetPS - //blockID+offsetID - //blockID+counterID+offsetID - UCHAR ucData; //PS data1 - UCHAR ucStatus; //Status byte 1=success, 2=failure, Also is used as PS data2 - UCHAR ucSlaveAddr; //Write to which slave - UCHAR ucLineNumber; //Write from which HW assisted line -}WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS; - -#define WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS - -typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS -{ - USHORT usPrescale; //Ratio between Engine clock and I2C clock - UCHAR ucSlaveAddr; //Write to which slave - UCHAR ucLineNumber; //Write from which HW assisted line -}SET_UP_HW_I2C_DATA_PARAMETERS; - - -/**************************************************************************/ -#define SPEED_FAN_CONTROL_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS - - -/****************************************************************************/ -// Structures used by PowerConnectorDetectionTable -/****************************************************************************/ -typedef struct _POWER_CONNECTOR_DETECTION_PARAMETERS -{ - UCHAR ucPowerConnectorStatus; //Used for return value 0: detected, 1:not detected - UCHAR ucPwrBehaviorId; - USHORT usPwrBudget; //how much power currently boot to in unit of watt -}POWER_CONNECTOR_DETECTION_PARAMETERS; - -typedef struct POWER_CONNECTOR_DETECTION_PS_ALLOCATION -{ - UCHAR ucPowerConnectorStatus; //Used for return value 0: detected, 1:not detected - UCHAR ucReserved; - USHORT usPwrBudget; //how much power currently boot to in unit of watt - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; -}POWER_CONNECTOR_DETECTION_PS_ALLOCATION; - -/****************************LVDS SS Command Table Definitions**********************/ - -/****************************************************************************/ -// Structures used by EnableSpreadSpectrumOnPPLLTable -/****************************************************************************/ -typedef struct _ENABLE_LVDS_SS_PARAMETERS -{ - USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD - UCHAR ucSpreadSpectrumStepSize_Delay; //bits3:2 SS_STEP_SIZE; bit 6:4 SS_DELAY - UCHAR ucEnable; //ATOM_ENABLE or ATOM_DISABLE - UCHAR ucPadding[3]; -}ENABLE_LVDS_SS_PARAMETERS; - -//ucTableFormatRevision=1,ucTableContentRevision=2 -typedef struct _ENABLE_LVDS_SS_PARAMETERS_V2 -{ - USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD - UCHAR ucSpreadSpectrumStep; // - UCHAR ucEnable; //ATOM_ENABLE or ATOM_DISABLE - UCHAR ucSpreadSpectrumDelay; - UCHAR ucSpreadSpectrumRange; - UCHAR ucPadding; -}ENABLE_LVDS_SS_PARAMETERS_V2; - -//This new structure is based on ENABLE_LVDS_SS_PARAMETERS but expands to SS on PPLL, so other devices can use SS. -typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL -{ - USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; // Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Others:TBD - UCHAR ucSpreadSpectrumStep; // - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucSpreadSpectrumDelay; - UCHAR ucSpreadSpectrumRange; - UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2 -}ENABLE_SPREAD_SPECTRUM_ON_PPLL; - -typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 -{ - USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; // Bit[0]: 0-Down Spread,1-Center Spread. - // Bit[1]: 1-Ext. 0-Int. - // Bit[3:2]: =0 P1PLL =1 P2PLL =2 DCPLL - // Bits[7:4] reserved - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - USHORT usSpreadSpectrumAmount; // Includes SS_AMOUNT_FBDIV[7:0] and SS_AMOUNT_NFRAC_SLIP[11:8] - USHORT usSpreadSpectrumStep; // SS_STEP_SIZE_DSFRAC -}ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2; - -#define ATOM_PPLL_SS_TYPE_V2_DOWN_SPREAD 0x00 -#define ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD 0x01 -#define ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD 0x02 -#define ATOM_PPLL_SS_TYPE_V2_PPLL_SEL_MASK 0x0c -#define ATOM_PPLL_SS_TYPE_V2_P1PLL 0x00 -#define ATOM_PPLL_SS_TYPE_V2_P2PLL 0x04 -#define ATOM_PPLL_SS_TYPE_V2_DCPLL 0x08 -#define ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK 0x00FF -#define ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT 0 -#define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK 0x0F00 -#define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT 8 - -// Used by DCE5.0 - typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 -{ - USHORT usSpreadSpectrumAmountFrac; // SS_AMOUNT_DSFRAC New in DCE5.0 - UCHAR ucSpreadSpectrumType; // Bit[0]: 0-Down Spread,1-Center Spread. - // Bit[1]: 1-Ext. 0-Int. - // Bit[3:2]: =0 P1PLL =1 P2PLL =2 DCPLL - // Bits[7:4] reserved - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - USHORT usSpreadSpectrumAmount; // Includes SS_AMOUNT_FBDIV[7:0] and SS_AMOUNT_NFRAC_SLIP[11:8] - USHORT usSpreadSpectrumStep; // SS_STEP_SIZE_DSFRAC -}ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3; - -#define ATOM_PPLL_SS_TYPE_V3_DOWN_SPREAD 0x00 -#define ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD 0x01 -#define ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD 0x02 -#define ATOM_PPLL_SS_TYPE_V3_PPLL_SEL_MASK 0x0c -#define ATOM_PPLL_SS_TYPE_V3_P1PLL 0x00 -#define ATOM_PPLL_SS_TYPE_V3_P2PLL 0x04 -#define ATOM_PPLL_SS_TYPE_V3_DCPLL 0x08 -#define ATOM_PPLL_SS_TYPE_V3_P0PLL ATOM_PPLL_SS_TYPE_V3_DCPLL -#define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK 0x00FF -#define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT 0 -#define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK 0x0F00 -#define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT 8 - -#define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION ENABLE_SPREAD_SPECTRUM_ON_PPLL - -/**************************************************************************/ - -typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION -{ - PIXEL_CLOCK_PARAMETERS sPCLKInput; - ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;//Caller doesn't need to init this portion -}SET_PIXEL_CLOCK_PS_ALLOCATION; - -#define ENABLE_VGA_RENDER_PS_ALLOCATION SET_PIXEL_CLOCK_PS_ALLOCATION - -/****************************************************************************/ -// Structures used by ### -/****************************************************************************/ -typedef struct _MEMORY_TRAINING_PARAMETERS -{ - ULONG ulTargetMemoryClock; //In 10Khz unit -}MEMORY_TRAINING_PARAMETERS; -#define MEMORY_TRAINING_PS_ALLOCATION MEMORY_TRAINING_PARAMETERS - - -/****************************LVDS and other encoder command table definitions **********************/ - - -/****************************************************************************/ -// Structures used by LVDSEncoderControlTable (Before DCE30) -// LVTMAEncoderControlTable (Before DCE30) -// TMDSAEncoderControlTable (Before DCE30) -/****************************************************************************/ -typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - UCHAR ucMisc; // bit0=0: Enable single link - // =1: Enable dual link - // Bit1=0: 666RGB - // =1: 888RGB - UCHAR ucAction; // 0: turn off encoder - // 1: setup and turn on encoder -}LVDS_ENCODER_CONTROL_PARAMETERS; - -#define LVDS_ENCODER_CONTROL_PS_ALLOCATION LVDS_ENCODER_CONTROL_PARAMETERS - -#define TMDS1_ENCODER_CONTROL_PARAMETERS LVDS_ENCODER_CONTROL_PARAMETERS -#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION TMDS1_ENCODER_CONTROL_PARAMETERS - -#define TMDS2_ENCODER_CONTROL_PARAMETERS TMDS1_ENCODER_CONTROL_PARAMETERS -#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION TMDS2_ENCODER_CONTROL_PARAMETERS - - -//ucTableFormatRevision=1,ucTableContentRevision=2 -typedef struct _LVDS_ENCODER_CONTROL_PARAMETERS_V2 -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - UCHAR ucMisc; // see PANEL_ENCODER_MISC_xx defintions below - UCHAR ucAction; // 0: turn off encoder - // 1: setup and turn on encoder - UCHAR ucTruncate; // bit0=0: Disable truncate - // =1: Enable truncate - // bit4=0: 666RGB - // =1: 888RGB - UCHAR ucSpatial; // bit0=0: Disable spatial dithering - // =1: Enable spatial dithering - // bit4=0: 666RGB - // =1: 888RGB - UCHAR ucTemporal; // bit0=0: Disable temporal dithering - // =1: Enable temporal dithering - // bit4=0: 666RGB - // =1: 888RGB - // bit5=0: Gray level 2 - // =1: Gray level 4 - UCHAR ucFRC; // bit4=0: 25FRC_SEL pattern E - // =1: 25FRC_SEL pattern F - // bit6:5=0: 50FRC_SEL pattern A - // =1: 50FRC_SEL pattern B - // =2: 50FRC_SEL pattern C - // =3: 50FRC_SEL pattern D - // bit7=0: 75FRC_SEL pattern E - // =1: 75FRC_SEL pattern F -}LVDS_ENCODER_CONTROL_PARAMETERS_V2; - -#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 - -#define TMDS1_ENCODER_CONTROL_PARAMETERS_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 -#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS1_ENCODER_CONTROL_PARAMETERS_V2 - -#define TMDS2_ENCODER_CONTROL_PARAMETERS_V2 TMDS1_ENCODER_CONTROL_PARAMETERS_V2 -#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V2 TMDS2_ENCODER_CONTROL_PARAMETERS_V2 - -#define LVDS_ENCODER_CONTROL_PARAMETERS_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V2 -#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V3 - -#define TMDS1_ENCODER_CONTROL_PARAMETERS_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V3 -#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS1_ENCODER_CONTROL_PARAMETERS_V3 - -#define TMDS2_ENCODER_CONTROL_PARAMETERS_V3 LVDS_ENCODER_CONTROL_PARAMETERS_V3 -#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_V3 TMDS2_ENCODER_CONTROL_PARAMETERS_V3 - -/****************************************************************************/ -// Structures used by ### -/****************************************************************************/ -typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS -{ - UCHAR ucEnable; // Enable or Disable External TMDS encoder - UCHAR ucMisc; // Bit0=0:Enable Single link;=1:Enable Dual link;Bit1 {=0:666RGB, =1:888RGB} - UCHAR ucPadding[2]; -}ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS; - -typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION -{ - ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS sXTmdsEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion -}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION; - -#define ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 LVDS_ENCODER_CONTROL_PARAMETERS_V2 - -typedef struct _ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2 -{ - ENABLE_EXTERNAL_TMDS_ENCODER_PARAMETERS_V2 sXTmdsEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion -}ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION_V2; - -typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION -{ - DIG_ENCODER_CONTROL_PARAMETERS sDigEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; -}EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION; - -/****************************************************************************/ -// Structures used by DVOEncoderControlTable -/****************************************************************************/ -//ucTableFormatRevision=1,ucTableContentRevision=3 - -//ucDVOConfig: -#define DVO_ENCODER_CONFIG_RATE_SEL 0x01 -#define DVO_ENCODER_CONFIG_DDR_SPEED 0x00 -#define DVO_ENCODER_CONFIG_SDR_SPEED 0x01 -#define DVO_ENCODER_CONFIG_OUTPUT_SEL 0x0c -#define DVO_ENCODER_CONFIG_LOW12BIT 0x00 -#define DVO_ENCODER_CONFIG_UPPER12BIT 0x04 -#define DVO_ENCODER_CONFIG_24BIT 0x08 - -typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3 -{ - USHORT usPixelClock; - UCHAR ucDVOConfig; - UCHAR ucAction; //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT - UCHAR ucReseved[4]; -}DVO_ENCODER_CONTROL_PARAMETERS_V3; -#define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 DVO_ENCODER_CONTROL_PARAMETERS_V3 - -//ucTableFormatRevision=1 -//ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for -// bit1=0: non-coherent mode -// =1: coherent mode - -//========================================================================================== -//Only change is here next time when changing encoder parameter definitions again! -#define LVDS_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 -#define LVDS_ENCODER_CONTROL_PS_ALLOCATION_LAST LVDS_ENCODER_CONTROL_PARAMETERS_LAST - -#define TMDS1_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 -#define TMDS1_ENCODER_CONTROL_PS_ALLOCATION_LAST TMDS1_ENCODER_CONTROL_PARAMETERS_LAST - -#define TMDS2_ENCODER_CONTROL_PARAMETERS_LAST LVDS_ENCODER_CONTROL_PARAMETERS_V3 -#define TMDS2_ENCODER_CONTROL_PS_ALLOCATION_LAST TMDS2_ENCODER_CONTROL_PARAMETERS_LAST - -#define DVO_ENCODER_CONTROL_PARAMETERS_LAST DVO_ENCODER_CONTROL_PARAMETERS -#define DVO_ENCODER_CONTROL_PS_ALLOCATION_LAST DVO_ENCODER_CONTROL_PS_ALLOCATION - -//========================================================================================== -#define PANEL_ENCODER_MISC_DUAL 0x01 -#define PANEL_ENCODER_MISC_COHERENT 0x02 -#define PANEL_ENCODER_MISC_TMDS_LINKB 0x04 -#define PANEL_ENCODER_MISC_HDMI_TYPE 0x08 - -#define PANEL_ENCODER_ACTION_DISABLE ATOM_DISABLE -#define PANEL_ENCODER_ACTION_ENABLE ATOM_ENABLE -#define PANEL_ENCODER_ACTION_COHERENTSEQ (ATOM_ENABLE+1) - -#define PANEL_ENCODER_TRUNCATE_EN 0x01 -#define PANEL_ENCODER_TRUNCATE_DEPTH 0x10 -#define PANEL_ENCODER_SPATIAL_DITHER_EN 0x01 -#define PANEL_ENCODER_SPATIAL_DITHER_DEPTH 0x10 -#define PANEL_ENCODER_TEMPORAL_DITHER_EN 0x01 -#define PANEL_ENCODER_TEMPORAL_DITHER_DEPTH 0x10 -#define PANEL_ENCODER_TEMPORAL_LEVEL_4 0x20 -#define PANEL_ENCODER_25FRC_MASK 0x10 -#define PANEL_ENCODER_25FRC_E 0x00 -#define PANEL_ENCODER_25FRC_F 0x10 -#define PANEL_ENCODER_50FRC_MASK 0x60 -#define PANEL_ENCODER_50FRC_A 0x00 -#define PANEL_ENCODER_50FRC_B 0x20 -#define PANEL_ENCODER_50FRC_C 0x40 -#define PANEL_ENCODER_50FRC_D 0x60 -#define PANEL_ENCODER_75FRC_MASK 0x80 -#define PANEL_ENCODER_75FRC_E 0x00 -#define PANEL_ENCODER_75FRC_F 0x80 - -/****************************************************************************/ -// Structures used by SetVoltageTable -/****************************************************************************/ -#define SET_VOLTAGE_TYPE_ASIC_VDDC 1 -#define SET_VOLTAGE_TYPE_ASIC_MVDDC 2 -#define SET_VOLTAGE_TYPE_ASIC_MVDDQ 3 -#define SET_VOLTAGE_TYPE_ASIC_VDDCI 4 -#define SET_VOLTAGE_INIT_MODE 5 -#define SET_VOLTAGE_GET_MAX_VOLTAGE 6 //Gets the Max. voltage for the soldered Asic - -#define SET_ASIC_VOLTAGE_MODE_ALL_SOURCE 0x1 -#define SET_ASIC_VOLTAGE_MODE_SOURCE_A 0x2 -#define SET_ASIC_VOLTAGE_MODE_SOURCE_B 0x4 - -#define SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE 0x0 -#define SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL 0x1 -#define SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK 0x2 - -typedef struct _SET_VOLTAGE_PARAMETERS -{ - UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ - UCHAR ucVoltageMode; // To set all, to set source A or source B or ... - UCHAR ucVoltageIndex; // An index to tell which voltage level - UCHAR ucReserved; -}SET_VOLTAGE_PARAMETERS; - -typedef struct _SET_VOLTAGE_PARAMETERS_V2 -{ - UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ - UCHAR ucVoltageMode; // Not used, maybe use for state machine for differen power mode - USHORT usVoltageLevel; // real voltage level -}SET_VOLTAGE_PARAMETERS_V2; - - -typedef struct _SET_VOLTAGE_PARAMETERS_V1_3 -{ - UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI - UCHAR ucVoltageMode; // Indicate action: Set voltage level - USHORT usVoltageLevel; // real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) -}SET_VOLTAGE_PARAMETERS_V1_3; - -//ucVoltageType -#define VOLTAGE_TYPE_VDDC 1 -#define VOLTAGE_TYPE_MVDDC 2 -#define VOLTAGE_TYPE_MVDDQ 3 -#define VOLTAGE_TYPE_VDDCI 4 - -//SET_VOLTAGE_PARAMETERS_V3.ucVoltageMode -#define ATOM_SET_VOLTAGE 0 //Set voltage Level -#define ATOM_INIT_VOLTAGE_REGULATOR 3 //Init Regulator -#define ATOM_SET_VOLTAGE_PHASE 4 //Set Vregulator Phase -#define ATOM_GET_MAX_VOLTAGE 6 //Get Max Voltage, not used in SetVoltageTable v1.3 -#define ATOM_GET_VOLTAGE_LEVEL 6 //Get Voltage level from vitual voltage ID - -// define vitual voltage id in usVoltageLevel -#define ATOM_VIRTUAL_VOLTAGE_ID0 0xff01 -#define ATOM_VIRTUAL_VOLTAGE_ID1 0xff02 -#define ATOM_VIRTUAL_VOLTAGE_ID2 0xff03 -#define ATOM_VIRTUAL_VOLTAGE_ID3 0xff04 - -typedef struct _SET_VOLTAGE_PS_ALLOCATION -{ - SET_VOLTAGE_PARAMETERS sASICSetVoltage; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; -}SET_VOLTAGE_PS_ALLOCATION; - -// New Added from SI for GetVoltageInfoTable, input parameter structure -typedef struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_1 -{ - UCHAR ucVoltageType; // Input: To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI - UCHAR ucVoltageMode; // Input: Indicate action: Get voltage info - USHORT usVoltageLevel; // Input: real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) or Leakage Id - ULONG ulReserved; -}GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_1; - -// New Added from SI for GetVoltageInfoTable, output parameter structure when ucVotlageMode == ATOM_GET_VOLTAGE_VID -typedef struct _GET_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1 -{ - ULONG ulVotlageGpioState; - ULONG ulVoltageGPioMask; -}GET_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1; - -// New Added from SI for GetVoltageInfoTable, output parameter structure when ucVotlageMode == ATOM_GET_VOLTAGE_STATEx_LEAKAGE_VID -typedef struct _GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1 -{ - USHORT usVoltageLevel; - USHORT usVoltageId; // Voltage Id programmed in Voltage Regulator - ULONG ulReseved; -}GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1; - - -// GetVoltageInfo v1.1 ucVoltageMode -#define ATOM_GET_VOLTAGE_VID 0x00 -#define ATOM_GET_VOTLAGE_INIT_SEQ 0x03 -#define ATOM_GET_VOLTTAGE_PHASE_PHASE_VID 0x04 -// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state -#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10 - -// for SI, this state map to 0xff01 voltage state in Power Play table, which is performance state -#define ATOM_GET_VOLTAGE_STATE1_LEAKAGE_VID 0x11 -// undefined power state -#define ATOM_GET_VOLTAGE_STATE2_LEAKAGE_VID 0x12 -#define ATOM_GET_VOLTAGE_STATE3_LEAKAGE_VID 0x13 - -/****************************************************************************/ -// Structures used by TVEncoderControlTable -/****************************************************************************/ -typedef struct _TV_ENCODER_CONTROL_PARAMETERS -{ - USHORT usPixelClock; // in 10KHz; for bios convenient - UCHAR ucTvStandard; // See definition "ATOM_TV_NTSC ..." - UCHAR ucAction; // 0: turn off encoder - // 1: setup and turn on encoder -}TV_ENCODER_CONTROL_PARAMETERS; - -typedef struct _TV_ENCODER_CONTROL_PS_ALLOCATION -{ - TV_ENCODER_CONTROL_PARAMETERS sTVEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; // Don't set this one -}TV_ENCODER_CONTROL_PS_ALLOCATION; - -//==============================Data Table Portion==================================== - -/****************************************************************************/ -// Structure used in Data.mtb -/****************************************************************************/ -typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES -{ - USHORT UtilityPipeLine; // Offest for the utility to get parser info,Don't change this position! - USHORT MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios - USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios - USHORT StandardVESA_Timing; // Only used by Bios - USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 - USHORT PaletteData; // Only used by BIOS - USHORT LCD_Info; // Shared by various SW components,latest version 1.3, was called LVDS_Info - USHORT DIGTransmitterInfo; // Internal used by VBIOS only version 3.1 - USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 - USHORT SupportedDevicesInfo; // Will be obsolete from R600 - USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600 - USHORT VRAM_UsageByFirmware; // Shared by various SW components,latest version 1.3 will be used from R600 - USHORT GPIO_Pin_LUT; // Shared by various SW components,latest version 1.1 - USHORT VESA_ToInternalModeLUT; // Only used by Bios - USHORT ComponentVideoInfo; // Shared by various SW components,latest version 2.1 will be used from R600 - USHORT PowerPlayInfo; // Shared by various SW components,latest version 2.1,new design from R600 - USHORT CompassionateData; // Will be obsolete from R600 - USHORT SaveRestoreInfo; // Only used by Bios - USHORT PPLL_SS_Info; // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info - USHORT OemInfo; // Defined and used by external SW, should be obsolete soon - USHORT XTMDS_Info; // Will be obsolete from R600 - USHORT MclkSS_Info; // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used - USHORT Object_Header; // Shared by various SW components,latest version 1.1 - USHORT IndirectIOAccess; // Only used by Bios,this table position can't change at all!! - USHORT MC_InitParameter; // Only used by command table - USHORT ASIC_VDDC_Info; // Will be obsolete from R600 - USHORT ASIC_InternalSS_Info; // New tabel name from R600, used to be called "ASIC_MVDDC_Info" - USHORT TV_VideoMode; // Only used by command table - USHORT VRAM_Info; // Only used by command table, latest version 1.3 - USHORT MemoryTrainingInfo; // Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1 - USHORT IntegratedSystemInfo; // Shared by various SW components - USHORT ASIC_ProfilingInfo; // New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600 - USHORT VoltageObjectInfo; // Shared by various SW components, latest version 1.1 - USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 -}ATOM_MASTER_LIST_OF_DATA_TABLES; - -typedef struct _ATOM_MASTER_DATA_TABLE -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; -}ATOM_MASTER_DATA_TABLE; - -// For backward compatible -#define LVDS_Info LCD_Info -#define DAC_Info PaletteData -#define TMDS_Info DIGTransmitterInfo - -/****************************************************************************/ -// Structure used in MultimediaCapabilityInfoTable -/****************************************************************************/ -typedef struct _ATOM_MULTIMEDIA_CAPABILITY_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulSignature; // HW info table signature string "$ATI" - UCHAR ucI2C_Type; // I2C type (normal GP_IO, ImpactTV GP_IO, Dedicated I2C pin, etc) - UCHAR ucTV_OutInfo; // Type of TV out supported (3:0) and video out crystal frequency (6:4) and TV data port (7) - UCHAR ucVideoPortInfo; // Provides the video port capabilities - UCHAR ucHostPortInfo; // Provides host port configuration information -}ATOM_MULTIMEDIA_CAPABILITY_INFO; - -/****************************************************************************/ -// Structure used in MultimediaConfigInfoTable -/****************************************************************************/ -typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulSignature; // MM info table signature sting "$MMT" - UCHAR ucTunerInfo; // Type of tuner installed on the adapter (4:0) and video input for tuner (7:5) - UCHAR ucAudioChipInfo; // List the audio chip type (3:0) product type (4) and OEM revision (7:5) - UCHAR ucProductID; // Defines as OEM ID or ATI board ID dependent on product type setting - UCHAR ucMiscInfo1; // Tuner voltage (1:0) HW teletext support (3:2) FM audio decoder (5:4) reserved (6) audio scrambling (7) - UCHAR ucMiscInfo2; // I2S input config (0) I2S output config (1) I2S Audio Chip (4:2) SPDIF Output Config (5) reserved (7:6) - UCHAR ucMiscInfo3; // Video Decoder Type (3:0) Video In Standard/Crystal (7:4) - UCHAR ucMiscInfo4; // Video Decoder Host Config (2:0) reserved (7:3) - UCHAR ucVideoInput0Info;// Video Input 0 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) - UCHAR ucVideoInput1Info;// Video Input 1 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) - UCHAR ucVideoInput2Info;// Video Input 2 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) - UCHAR ucVideoInput3Info;// Video Input 3 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) - UCHAR ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) -}ATOM_MULTIMEDIA_CONFIG_INFO; - - -/****************************************************************************/ -// Structures used in FirmwareInfoTable -/****************************************************************************/ - -// usBIOSCapability Definition: -// Bit 0 = 0: Bios image is not Posted, =1:Bios image is Posted; -// Bit 1 = 0: Dual CRTC is not supported, =1: Dual CRTC is supported; -// Bit 2 = 0: Extended Desktop is not supported, =1: Extended Desktop is supported; -// Others: Reserved -#define ATOM_BIOS_INFO_ATOM_FIRMWARE_POSTED 0x0001 -#define ATOM_BIOS_INFO_DUAL_CRTC_SUPPORT 0x0002 -#define ATOM_BIOS_INFO_EXTENDED_DESKTOP_SUPPORT 0x0004 -#define ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT 0x0008 // (valid from v1.1 ~v1.4):=1: memclk SS enable, =0 memclk SS disable. -#define ATOM_BIOS_INFO_ENGINE_CLOCK_SS_SUPPORT 0x0010 // (valid from v1.1 ~v1.4):=1: engclk SS enable, =0 engclk SS disable. -#define ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU 0x0020 -#define ATOM_BIOS_INFO_WMI_SUPPORT 0x0040 -#define ATOM_BIOS_INFO_PPMODE_ASSIGNGED_BY_SYSTEM 0x0080 -#define ATOM_BIOS_INFO_HYPERMEMORY_SUPPORT 0x0100 -#define ATOM_BIOS_INFO_HYPERMEMORY_SIZE_MASK 0x1E00 -#define ATOM_BIOS_INFO_VPOST_WITHOUT_FIRST_MODE_SET 0x2000 -#define ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE 0x4000 -#define ATOM_BIOS_INFO_MEMORY_CLOCK_EXT_SS_SUPPORT 0x0008 // (valid from v2.1 ): =1: memclk ss enable with external ss chip -#define ATOM_BIOS_INFO_ENGINE_CLOCK_EXT_SS_SUPPORT 0x0010 // (valid from v2.1 ): =1: engclk ss enable with external ss chip - -#ifndef _H2INC - -//Please don't add or expand this bitfield structure below, this one will retire soon.! -typedef struct _ATOM_FIRMWARE_CAPABILITY -{ -#if ATOM_BIG_ENDIAN - USHORT Reserved:1; - USHORT SCL2Redefined:1; - USHORT PostWithoutModeSet:1; - USHORT HyperMemory_Size:4; - USHORT HyperMemory_Support:1; - USHORT PPMode_Assigned:1; - USHORT WMI_SUPPORT:1; - USHORT GPUControlsBL:1; - USHORT EngineClockSS_Support:1; - USHORT MemoryClockSS_Support:1; - USHORT ExtendedDesktopSupport:1; - USHORT DualCRTC_Support:1; - USHORT FirmwarePosted:1; -#else - USHORT FirmwarePosted:1; - USHORT DualCRTC_Support:1; - USHORT ExtendedDesktopSupport:1; - USHORT MemoryClockSS_Support:1; - USHORT EngineClockSS_Support:1; - USHORT GPUControlsBL:1; - USHORT WMI_SUPPORT:1; - USHORT PPMode_Assigned:1; - USHORT HyperMemory_Support:1; - USHORT HyperMemory_Size:4; - USHORT PostWithoutModeSet:1; - USHORT SCL2Redefined:1; - USHORT Reserved:1; -#endif -}ATOM_FIRMWARE_CAPABILITY; - -typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS -{ - ATOM_FIRMWARE_CAPABILITY sbfAccess; - USHORT susAccess; -}ATOM_FIRMWARE_CAPABILITY_ACCESS; - -#else - -typedef union _ATOM_FIRMWARE_CAPABILITY_ACCESS -{ - USHORT susAccess; -}ATOM_FIRMWARE_CAPABILITY_ACCESS; - -#endif - -typedef struct _ATOM_FIRMWARE_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit - ULONG ulDriverTargetEngineClock; //In 10Khz unit - ULONG ulDriverTargetMemoryClock; //In 10Khz unit - ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit - ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit - ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit - ULONG ulASICMaxEngineClock; //In 10Khz unit - ULONG ulASICMaxMemoryClock; //In 10Khz unit - UCHAR ucASICMaxTemperature; - UCHAR ucPadding[3]; //Don't use them - ULONG aulReservedForBIOS[3]; //Don't use them - USHORT usMinEngineClockPLL_Input; //In 10Khz unit - USHORT usMaxEngineClockPLL_Input; //In 10Khz unit - USHORT usMinEngineClockPLL_Output; //In 10Khz unit - USHORT usMinMemoryClockPLL_Input; //In 10Khz unit - USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit - USHORT usMinMemoryClockPLL_Output; //In 10Khz unit - USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk - USHORT usMinPixelClockPLL_Input; //In 10Khz unit - USHORT usMaxPixelClockPLL_Input; //In 10Khz unit - USHORT usMinPixelClockPLL_Output; //In 10Khz unit, the definitions above can't change!!! - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; //In 10Khz unit - USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit - UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit - UCHAR ucDesign_ID; //Indicate what is the board design - UCHAR ucMemoryModule_ID; //Indicate what is the board design -}ATOM_FIRMWARE_INFO; - -typedef struct _ATOM_FIRMWARE_INFO_V1_2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit - ULONG ulDriverTargetEngineClock; //In 10Khz unit - ULONG ulDriverTargetMemoryClock; //In 10Khz unit - ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit - ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit - ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit - ULONG ulASICMaxEngineClock; //In 10Khz unit - ULONG ulASICMaxMemoryClock; //In 10Khz unit - UCHAR ucASICMaxTemperature; - UCHAR ucMinAllowedBL_Level; - UCHAR ucPadding[2]; //Don't use them - ULONG aulReservedForBIOS[2]; //Don't use them - ULONG ulMinPixelClockPLL_Output; //In 10Khz unit - USHORT usMinEngineClockPLL_Input; //In 10Khz unit - USHORT usMaxEngineClockPLL_Input; //In 10Khz unit - USHORT usMinEngineClockPLL_Output; //In 10Khz unit - USHORT usMinMemoryClockPLL_Input; //In 10Khz unit - USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit - USHORT usMinMemoryClockPLL_Output; //In 10Khz unit - USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk - USHORT usMinPixelClockPLL_Input; //In 10Khz unit - USHORT usMaxPixelClockPLL_Input; //In 10Khz unit - USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; //In 10Khz unit - USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit - UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit - UCHAR ucDesign_ID; //Indicate what is the board design - UCHAR ucMemoryModule_ID; //Indicate what is the board design -}ATOM_FIRMWARE_INFO_V1_2; - -typedef struct _ATOM_FIRMWARE_INFO_V1_3 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit - ULONG ulDriverTargetEngineClock; //In 10Khz unit - ULONG ulDriverTargetMemoryClock; //In 10Khz unit - ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit - ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit - ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit - ULONG ulASICMaxEngineClock; //In 10Khz unit - ULONG ulASICMaxMemoryClock; //In 10Khz unit - UCHAR ucASICMaxTemperature; - UCHAR ucMinAllowedBL_Level; - UCHAR ucPadding[2]; //Don't use them - ULONG aulReservedForBIOS; //Don't use them - ULONG ul3DAccelerationEngineClock;//In 10Khz unit - ULONG ulMinPixelClockPLL_Output; //In 10Khz unit - USHORT usMinEngineClockPLL_Input; //In 10Khz unit - USHORT usMaxEngineClockPLL_Input; //In 10Khz unit - USHORT usMinEngineClockPLL_Output; //In 10Khz unit - USHORT usMinMemoryClockPLL_Input; //In 10Khz unit - USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit - USHORT usMinMemoryClockPLL_Output; //In 10Khz unit - USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk - USHORT usMinPixelClockPLL_Input; //In 10Khz unit - USHORT usMaxPixelClockPLL_Input; //In 10Khz unit - USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; //In 10Khz unit - USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit - UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit - UCHAR ucDesign_ID; //Indicate what is the board design - UCHAR ucMemoryModule_ID; //Indicate what is the board design -}ATOM_FIRMWARE_INFO_V1_3; - -typedef struct _ATOM_FIRMWARE_INFO_V1_4 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit - ULONG ulDriverTargetEngineClock; //In 10Khz unit - ULONG ulDriverTargetMemoryClock; //In 10Khz unit - ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit - ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit - ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit - ULONG ulASICMaxEngineClock; //In 10Khz unit - ULONG ulASICMaxMemoryClock; //In 10Khz unit - UCHAR ucASICMaxTemperature; - UCHAR ucMinAllowedBL_Level; - USHORT usBootUpVDDCVoltage; //In MV unit - USHORT usLcdMinPixelClockPLL_Output; // In MHz unit - USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit - ULONG ul3DAccelerationEngineClock;//In 10Khz unit - ULONG ulMinPixelClockPLL_Output; //In 10Khz unit - USHORT usMinEngineClockPLL_Input; //In 10Khz unit - USHORT usMaxEngineClockPLL_Input; //In 10Khz unit - USHORT usMinEngineClockPLL_Output; //In 10Khz unit - USHORT usMinMemoryClockPLL_Input; //In 10Khz unit - USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit - USHORT usMinMemoryClockPLL_Output; //In 10Khz unit - USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk - USHORT usMinPixelClockPLL_Input; //In 10Khz unit - USHORT usMaxPixelClockPLL_Input; //In 10Khz unit - USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usReferenceClock; //In 10Khz unit - USHORT usPM_RTS_Location; //RTS PM4 starting location in ROM in 1Kb unit - UCHAR ucPM_RTS_StreamSize; //RTS PM4 packets in Kb unit - UCHAR ucDesign_ID; //Indicate what is the board design - UCHAR ucMemoryModule_ID; //Indicate what is the board design -}ATOM_FIRMWARE_INFO_V1_4; - -//the structure below to be used from Cypress -typedef struct _ATOM_FIRMWARE_INFO_V2_1 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit - ULONG ulReserved1; - ULONG ulReserved2; - ULONG ulMaxEngineClockPLL_Output; //In 10Khz unit - ULONG ulMaxMemoryClockPLL_Output; //In 10Khz unit - ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit - ULONG ulBinaryAlteredInfo; //Was ulASICMaxEngineClock - ULONG ulDefaultDispEngineClkFreq; //In 10Khz unit - UCHAR ucReserved1; //Was ucASICMaxTemperature; - UCHAR ucMinAllowedBL_Level; - USHORT usBootUpVDDCVoltage; //In MV unit - USHORT usLcdMinPixelClockPLL_Output; // In MHz unit - USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit - ULONG ulReserved4; //Was ulAsicMaximumVoltage - ULONG ulMinPixelClockPLL_Output; //In 10Khz unit - USHORT usMinEngineClockPLL_Input; //In 10Khz unit - USHORT usMaxEngineClockPLL_Input; //In 10Khz unit - USHORT usMinEngineClockPLL_Output; //In 10Khz unit - USHORT usMinMemoryClockPLL_Input; //In 10Khz unit - USHORT usMaxMemoryClockPLL_Input; //In 10Khz unit - USHORT usMinMemoryClockPLL_Output; //In 10Khz unit - USHORT usMaxPixelClock; //In 10Khz unit, Max. Pclk - USHORT usMinPixelClockPLL_Input; //In 10Khz unit - USHORT usMaxPixelClockPLL_Input; //In 10Khz unit - USHORT usMinPixelClockPLL_Output; //In 10Khz unit - lower 16bit of ulMinPixelClockPLL_Output - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usCoreReferenceClock; //In 10Khz unit - USHORT usMemoryReferenceClock; //In 10Khz unit - USHORT usUniphyDPModeExtClkFreq; //In 10Khz unit, if it is 0, In DP Mode Uniphy Input clock from internal PPLL, otherwise Input clock from external Spread clock - UCHAR ucMemoryModule_ID; //Indicate what is the board design - UCHAR ucReserved4[3]; -}ATOM_FIRMWARE_INFO_V2_1; - -//the structure below to be used from NI -//ucTableFormatRevision=2 -//ucTableContentRevision=2 -typedef struct _ATOM_FIRMWARE_INFO_V2_2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulFirmwareRevision; - ULONG ulDefaultEngineClock; //In 10Khz unit - ULONG ulDefaultMemoryClock; //In 10Khz unit - ULONG ulReserved[2]; - ULONG ulReserved1; //Was ulMaxEngineClockPLL_Output; //In 10Khz unit* - ULONG ulReserved2; //Was ulMaxMemoryClockPLL_Output; //In 10Khz unit* - ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit - ULONG ulBinaryAlteredInfo; //Was ulASICMaxEngineClock ? - ULONG ulDefaultDispEngineClkFreq; //In 10Khz unit. This is the frequency before DCDTO, corresponding to usBootUpVDDCVoltage. - UCHAR ucReserved3; //Was ucASICMaxTemperature; - UCHAR ucMinAllowedBL_Level; - USHORT usBootUpVDDCVoltage; //In MV unit - USHORT usLcdMinPixelClockPLL_Output; // In MHz unit - USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit - ULONG ulReserved4; //Was ulAsicMaximumVoltage - ULONG ulMinPixelClockPLL_Output; //In 10Khz unit - UCHAR ucRemoteDisplayConfig; - UCHAR ucReserved5[3]; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input - ULONG ulReserved6; //Was usMinEngineClockPLL_Output and usMinMemoryClockPLL_Input - ULONG ulReserved7; //Was usMaxMemoryClockPLL_Input and usMinMemoryClockPLL_Output - USHORT usReserved11; //Was usMaxPixelClock; //In 10Khz unit, Max. Pclk used only for DAC - USHORT usMinPixelClockPLL_Input; //In 10Khz unit - USHORT usMaxPixelClockPLL_Input; //In 10Khz unit - USHORT usBootUpVDDCIVoltage; //In unit of mv; Was usMinPixelClockPLL_Output; - ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; - USHORT usCoreReferenceClock; //In 10Khz unit - USHORT usMemoryReferenceClock; //In 10Khz unit - USHORT usUniphyDPModeExtClkFreq; //In 10Khz unit, if it is 0, In DP Mode Uniphy Input clock from internal PPLL, otherwise Input clock from external Spread clock - UCHAR ucMemoryModule_ID; //Indicate what is the board design - UCHAR ucReserved9[3]; - USHORT usBootUpMVDDCVoltage; //In unit of mv; Was usMinPixelClockPLL_Output; - USHORT usReserved12; - ULONG ulReserved10[3]; // New added comparing to previous version -}ATOM_FIRMWARE_INFO_V2_2; - -#define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_2 - - -// definition of ucRemoteDisplayConfig -#define REMOTE_DISPLAY_DISABLE 0x00 -#define REMOTE_DISPLAY_ENABLE 0x01 - -/****************************************************************************/ -// Structures used in IntegratedSystemInfoTable -/****************************************************************************/ -#define IGP_CAP_FLAG_DYNAMIC_CLOCK_EN 0x2 -#define IGP_CAP_FLAG_AC_CARD 0x4 -#define IGP_CAP_FLAG_SDVO_CARD 0x8 -#define IGP_CAP_FLAG_POSTDIV_BY_2_MODE 0x10 - -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; //in 10kHz unit - ULONG ulBootUpMemoryClock; //in 10kHz unit - ULONG ulMaxSystemMemoryClock; //in 10kHz unit - ULONG ulMinSystemMemoryClock; //in 10kHz unit - UCHAR ucNumberOfCyclesInPeriodHi; - UCHAR ucLCDTimingSel; //=0:not valid.!=0 sel this timing descriptor from LCD EDID. - USHORT usReserved1; - USHORT usInterNBVoltageLow; //An intermidiate PMW value to set the voltage - USHORT usInterNBVoltageHigh; //Another intermidiate PMW value to set the voltage - ULONG ulReserved[2]; - - USHORT usFSBClock; //In MHz unit - USHORT usCapabilityFlag; //Bit0=1 indicates the fake HDMI support,Bit1=0/1 for Dynamic clocking dis/enable - //Bit[3:2]== 0:No PCIE card, 1:AC card, 2:SDVO card - //Bit[4]==1: P/2 mode, ==0: P/1 mode - USHORT usPCIENBCfgReg7; //bit[7:0]=MUX_Sel, bit[9:8]=MUX_SEL_LEVEL2, bit[10]=Lane_Reversal - USHORT usK8MemoryClock; //in MHz unit - USHORT usK8SyncStartDelay; //in 0.01 us unit - USHORT usK8DataReturnTime; //in 0.01 us unit - UCHAR ucMaxNBVoltage; - UCHAR ucMinNBVoltage; - UCHAR ucMemoryType; //[7:4]=1:DDR1;=2:DDR2;=3:DDR3.[3:0] is reserved - UCHAR ucNumberOfCyclesInPeriod; //CG.FVTHROT_PWM_CTRL_REG0.NumberOfCyclesInPeriod - UCHAR ucStartingPWM_HighTime; //CG.FVTHROT_PWM_CTRL_REG0.StartingPWM_HighTime - UCHAR ucHTLinkWidth; //16 bit vs. 8 bit - UCHAR ucMaxNBVoltageHigh; - UCHAR ucMinNBVoltageHigh; -}ATOM_INTEGRATED_SYSTEM_INFO; - -/* Explanation on entries in ATOM_INTEGRATED_SYSTEM_INFO -ulBootUpMemoryClock: For Intel IGP,it's the UMA system memory clock - For AMD IGP,it's 0 if no SidePort memory installed or it's the boot-up SidePort memory clock -ulMaxSystemMemoryClock: For Intel IGP,it's the Max freq from memory SPD if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0 - For AMD IGP,for now this can be 0 -ulMinSystemMemoryClock: For Intel IGP,it's 133MHz if memory runs in ASYNC mode or otherwise (SYNC mode) it's 0 - For AMD IGP,for now this can be 0 - -usFSBClock: For Intel IGP,it's FSB Freq - For AMD IGP,it's HT Link Speed - -usK8MemoryClock: For AMD IGP only. For RevF CPU, set it to 200 -usK8SyncStartDelay: For AMD IGP only. Memory access latency in K8, required for watermark calculation -usK8DataReturnTime: For AMD IGP only. Memory access latency in K8, required for watermark calculation - -VC:Voltage Control -ucMaxNBVoltage: Voltage regulator dependent PWM value. Low 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all. -ucMinNBVoltage: Voltage regulator dependent PWM value. Low 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all. - -ucNumberOfCyclesInPeriod: Indicate how many cycles when PWM duty is 100%. low 8 bits of the value. -ucNumberOfCyclesInPeriodHi: Indicate how many cycles when PWM duty is 100%. high 8 bits of the value.If the PWM has an inverter,set bit [7]==1,otherwise set it 0 - -ucMaxNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the max voltage.Set this one to 0xFF if VC without PWM. Set this to 0x0 if no VC at all. -ucMinNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all. - - -usInterNBVoltageLow: Voltage regulator dependent PWM value. The value makes the the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all. -usInterNBVoltageHigh: Voltage regulator dependent PWM value. The value makes the the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all. -*/ - - -/* -The following IGP table is introduced from RS780, which is supposed to be put by SBIOS in FB before IGP VBIOS starts VPOST; -Then VBIOS will copy the whole structure to its image so all GPU SW components can access this data structure to get whatever they need. -The enough reservation should allow us to never change table revisions. Whenever needed, a GPU SW component can use reserved portion for new data entries. - -SW components can access the IGP system infor structure in the same way as before -*/ - - -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; //in 10kHz unit - ULONG ulReserved1[2]; //must be 0x0 for the reserved - ULONG ulBootUpUMAClock; //in 10kHz unit - ULONG ulBootUpSidePortClock; //in 10kHz unit - ULONG ulMinSidePortClock; //in 10kHz unit - ULONG ulReserved2[6]; //must be 0x0 for the reserved - ULONG ulSystemConfig; //see explanation below - ULONG ulBootUpReqDisplayVector; - ULONG ulOtherDisplayMisc; - ULONG ulDDISlot1Config; - ULONG ulDDISlot2Config; - UCHAR ucMemoryType; //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved - UCHAR ucUMAChannelNumber; - UCHAR ucDockingPinBit; - UCHAR ucDockingPinPolarity; - ULONG ulDockingPinCFGInfo; - ULONG ulCPUCapInfo; - USHORT usNumberOfCyclesInPeriod; - USHORT usMaxNBVoltage; - USHORT usMinNBVoltage; - USHORT usBootUpNBVoltage; - ULONG ulHTLinkFreq; //in 10Khz - USHORT usMinHTLinkWidth; - USHORT usMaxHTLinkWidth; - USHORT usUMASyncStartDelay; - USHORT usUMADataReturnTime; - USHORT usLinkStatusZeroTime; - USHORT usDACEfuse; //for storing badgap value (for RS880 only) - ULONG ulHighVoltageHTLinkFreq; // in 10Khz - ULONG ulLowVoltageHTLinkFreq; // in 10Khz - USHORT usMaxUpStreamHTLinkWidth; - USHORT usMaxDownStreamHTLinkWidth; - USHORT usMinUpStreamHTLinkWidth; - USHORT usMinDownStreamHTLinkWidth; - USHORT usFirmwareVersion; //0 means FW is not supported. Otherwise it's the FW version loaded by SBIOS and driver should enable FW. - USHORT usFullT0Time; // Input to calculate minimum HT link change time required by NB P-State. Unit is 0.01us. - ULONG ulReserved3[96]; //must be 0x0 -}ATOM_INTEGRATED_SYSTEM_INFO_V2; - -/* -ulBootUpEngineClock: Boot-up Engine Clock in 10Khz; -ulBootUpUMAClock: Boot-up UMA Clock in 10Khz; it must be 0x0 when UMA is not present -ulBootUpSidePortClock: Boot-up SidePort Clock in 10Khz; it must be 0x0 when SidePort Memory is not present,this could be equal to or less than maximum supported Sideport memory clock - -ulSystemConfig: -Bit[0]=1: PowerExpress mode =0 Non-PowerExpress mode; -Bit[1]=1: system boots up at AMD overdrived state or user customized mode. In this case, driver will just stick to this boot-up mode. No other PowerPlay state - =0: system boots up at driver control state. Power state depends on PowerPlay table. -Bit[2]=1: PWM method is used on NB voltage control. =0: GPIO method is used. -Bit[3]=1: Only one power state(Performance) will be supported. - =0: Multiple power states supported from PowerPlay table. -Bit[4]=1: CLMC is supported and enabled on current system. - =0: CLMC is not supported or enabled on current system. SBIOS need to support HT link/freq change through ATIF interface. -Bit[5]=1: Enable CDLW for all driver control power states. Max HT width is from SBIOS, while Min HT width is determined by display requirement. - =0: CDLW is disabled. If CLMC is enabled case, Min HT width will be set equal to Max HT width. If CLMC disabled case, Max HT width will be applied. -Bit[6]=1: High Voltage requested for all power states. In this case, voltage will be forced at 1.1v and powerplay table voltage drop/throttling request will be ignored. - =0: Voltage settings is determined by powerplay table. -Bit[7]=1: Enable CLMC as hybrid Mode. CDLD and CILR will be disabled in this case and we're using legacy C1E. This is workaround for CPU(Griffin) performance issue. - =0: Enable CLMC as regular mode, CDLD and CILR will be enabled. -Bit[8]=1: CDLF is supported and enabled on current system. - =0: CDLF is not supported or enabled on current system. -Bit[9]=1: DLL Shut Down feature is enabled on current system. - =0: DLL Shut Down feature is not enabled or supported on current system. - -ulBootUpReqDisplayVector: This dword is a bit vector indicates what display devices are requested during boot-up. Refer to ATOM_DEVICE_xxx_SUPPORT for the bit vector definitions. - -ulOtherDisplayMisc: [15:8]- Bootup LCD Expansion selection; 0-center, 1-full panel size expansion; - [7:0] - BootupTV standard selection; This is a bit vector to indicate what TV standards are supported by the system. Refer to ucTVSupportedStd definition; - -ulDDISlot1Config: Describes the PCIE lane configuration on this DDI PCIE slot (ADD2 card) or connector (Mobile design). - [3:0] - Bit vector to indicate PCIE lane config of the DDI slot/connector on chassis (bit 0=1 lane 3:0; bit 1=1 lane 7:4; bit 2=1 lane 11:8; bit 3=1 lane 15:12) - [7:4] - Bit vector to indicate PCIE lane config of the same DDI slot/connector on docking station (bit 4=1 lane 3:0; bit 5=1 lane 7:4; bit 6=1 lane 11:8; bit 7=1 lane 15:12) - When a DDI connector is not "paired" (meaming two connections mutualexclusive on chassis or docking, only one of them can be connected at one time. - in both chassis and docking, SBIOS has to duplicate the same PCIE lane info from chassis to docking or vice versa. For example: - one DDI connector is only populated in docking with PCIE lane 8-11, but there is no paired connection on chassis, SBIOS has to copy bit 6 to bit 2. - - [15:8] - Lane configuration attribute; - [23:16]- Connector type, possible value: - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D - CONNECTOR_OBJECT_ID_HDMI_TYPE_A - CONNECTOR_OBJECT_ID_DISPLAYPORT - CONNECTOR_OBJECT_ID_eDP - [31:24]- Reserved - -ulDDISlot2Config: Same as Slot1. -ucMemoryType: SidePort memory type, set it to 0x0 when Sideport memory is not installed. Driver needs this info to change sideport memory clock. Not for display in CCC. -For IGP, Hypermemory is the only memory type showed in CCC. - -ucUMAChannelNumber: how many channels for the UMA; - -ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pin; [31:16]-reg offset in CFG to read this pin -ucDockingPinBit: which bit in this register to read the pin status; -ucDockingPinPolarity:Polarity of the pin when docked; - -ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, [7:0]=4:Pharaoh, other bits reserved for now and must be 0x0 - -usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%. - -usMaxNBVoltage:Max. voltage control value in either PWM or GPIO mode. -usMinNBVoltage:Min. voltage control value in either PWM or GPIO mode. - GPIO mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=0 - PWM mode: both usMaxNBVoltage & usMinNBVoltage have a valid value ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE=1 - GPU SW don't control mode: usMaxNBVoltage & usMinNBVoltage=0 and no care about ulSystemConfig.SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE - -usBootUpNBVoltage:Boot-up voltage regulator dependent PWM value. - -ulHTLinkFreq: Bootup HT link Frequency in 10Khz. -usMinHTLinkWidth: Bootup minimum HT link width. If CDLW disabled, this is equal to usMaxHTLinkWidth. - If CDLW enabled, both upstream and downstream width should be the same during bootup. -usMaxHTLinkWidth: Bootup maximum HT link width. If CDLW disabled, this is equal to usMinHTLinkWidth. - If CDLW enabled, both upstream and downstream width should be the same during bootup. - -usUMASyncStartDelay: Memory access latency, required for watermark calculation -usUMADataReturnTime: Memory access latency, required for watermark calculation -usLinkStatusZeroTime:Memory access latency required for watermark calculation, set this to 0x0 for K8 CPU, set a proper value in 0.01 the unit of us -for Griffin or Greyhound. SBIOS needs to convert to actual time by: - if T0Ttime [5:4]=00b, then usLinkStatusZeroTime=T0Ttime [3:0]*0.1us (0.0 to 1.5us) - if T0Ttime [5:4]=01b, then usLinkStatusZeroTime=T0Ttime [3:0]*0.5us (0.0 to 7.5us) - if T0Ttime [5:4]=10b, then usLinkStatusZeroTime=T0Ttime [3:0]*2.0us (0.0 to 30us) - if T0Ttime [5:4]=11b, and T0Ttime [3:0]=0x0 to 0xa, then usLinkStatusZeroTime=T0Ttime [3:0]*20us (0.0 to 200us) - -ulHighVoltageHTLinkFreq: HT link frequency for power state with low voltage. If boot up runs in HT1, this must be 0. - This must be less than or equal to ulHTLinkFreq(bootup frequency). -ulLowVoltageHTLinkFreq: HT link frequency for power state with low voltage or voltage scaling 1.0v~1.1v. If boot up runs in HT1, this must be 0. - This must be less than or equal to ulHighVoltageHTLinkFreq. - -usMaxUpStreamHTLinkWidth: Asymmetric link width support in the future, to replace usMaxHTLinkWidth. Not used for now. -usMaxDownStreamHTLinkWidth: same as above. -usMinUpStreamHTLinkWidth: Asymmetric link width support in the future, to replace usMinHTLinkWidth. Not used for now. -usMinDownStreamHTLinkWidth: same as above. -*/ - -// ATOM_INTEGRATED_SYSTEM_INFO::ulCPUCapInfo - CPU type definition -#define INTEGRATED_SYSTEM_INFO__UNKNOWN_CPU 0 -#define INTEGRATED_SYSTEM_INFO__AMD_CPU__GRIFFIN 1 -#define INTEGRATED_SYSTEM_INFO__AMD_CPU__GREYHOUND 2 -#define INTEGRATED_SYSTEM_INFO__AMD_CPU__K8 3 -#define INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH 4 -#define INTEGRATED_SYSTEM_INFO__AMD_CPU__OROCHI 5 - -#define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__OROCHI // this deff reflects max defined CPU code - -#define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 -#define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 -#define SYSTEM_CONFIG_USE_PWM_ON_VOLTAGE 0x00000004 -#define SYSTEM_CONFIG_PERFORMANCE_POWERSTATE_ONLY 0x00000008 -#define SYSTEM_CONFIG_CLMC_ENABLED 0x00000010 -#define SYSTEM_CONFIG_CDLW_ENABLED 0x00000020 -#define SYSTEM_CONFIG_HIGH_VOLTAGE_REQUESTED 0x00000040 -#define SYSTEM_CONFIG_CLMC_HYBRID_MODE_ENABLED 0x00000080 -#define SYSTEM_CONFIG_CDLF_ENABLED 0x00000100 -#define SYSTEM_CONFIG_DLL_SHUTDOWN_ENABLED 0x00000200 - -#define IGP_DDI_SLOT_LANE_CONFIG_MASK 0x000000FF - -#define b0IGP_DDI_SLOT_LANE_MAP_MASK 0x0F -#define b0IGP_DDI_SLOT_DOCKING_LANE_MAP_MASK 0xF0 -#define b0IGP_DDI_SLOT_CONFIG_LANE_0_3 0x01 -#define b0IGP_DDI_SLOT_CONFIG_LANE_4_7 0x02 -#define b0IGP_DDI_SLOT_CONFIG_LANE_8_11 0x04 -#define b0IGP_DDI_SLOT_CONFIG_LANE_12_15 0x08 - -#define IGP_DDI_SLOT_ATTRIBUTE_MASK 0x0000FF00 -#define IGP_DDI_SLOT_CONFIG_REVERSED 0x00000100 -#define b1IGP_DDI_SLOT_CONFIG_REVERSED 0x01 - -#define IGP_DDI_SLOT_CONNECTOR_TYPE_MASK 0x00FF0000 - -// IntegratedSystemInfoTable new Rev is V5 after V2, because of the real rev of V2 is v1.4. This rev is used for RR -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; //in 10kHz unit - ULONG ulDentistVCOFreq; //Dentist VCO clock in 10kHz unit, the source of GPU SCLK, LCLK, UCLK and VCLK. - ULONG ulLClockFreq; //GPU Lclk freq in 10kHz unit, have relationship with NCLK in NorthBridge - ULONG ulBootUpUMAClock; //in 10kHz unit - ULONG ulReserved1[8]; //must be 0x0 for the reserved - ULONG ulBootUpReqDisplayVector; - ULONG ulOtherDisplayMisc; - ULONG ulReserved2[4]; //must be 0x0 for the reserved - ULONG ulSystemConfig; //TBD - ULONG ulCPUCapInfo; //TBD - USHORT usMaxNBVoltage; //high NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse; - USHORT usMinNBVoltage; //low NB voltage, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse; - USHORT usBootUpNBVoltage; //boot up NB voltage - UCHAR ucHtcTmpLmt; //bit [22:16] of D24F3x64 Hardware Thermal Control (HTC) Register, may not be needed, TBD - UCHAR ucTjOffset; //bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed, TBD - ULONG ulReserved3[4]; //must be 0x0 for the reserved - ULONG ulDDISlot1Config; //see above ulDDISlot1Config definition - ULONG ulDDISlot2Config; - ULONG ulDDISlot3Config; - ULONG ulDDISlot4Config; - ULONG ulReserved4[4]; //must be 0x0 for the reserved - UCHAR ucMemoryType; //[3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved - UCHAR ucUMAChannelNumber; - USHORT usReserved; - ULONG ulReserved5[4]; //must be 0x0 for the reserved - ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10];//arrays with values for CSR M3 arbiter for default - ULONG ulCSR_M3_ARB_CNTL_UVD[10]; //arrays with values for CSR M3 arbiter for UVD playback - ULONG ulCSR_M3_ARB_CNTL_FS3D[10];//arrays with values for CSR M3 arbiter for Full Screen 3D applications - ULONG ulReserved6[61]; //must be 0x0 -}ATOM_INTEGRATED_SYSTEM_INFO_V5; - -#define ATOM_CRT_INT_ENCODER1_INDEX 0x00000000 -#define ATOM_LCD_INT_ENCODER1_INDEX 0x00000001 -#define ATOM_TV_INT_ENCODER1_INDEX 0x00000002 -#define ATOM_DFP_INT_ENCODER1_INDEX 0x00000003 -#define ATOM_CRT_INT_ENCODER2_INDEX 0x00000004 -#define ATOM_LCD_EXT_ENCODER1_INDEX 0x00000005 -#define ATOM_TV_EXT_ENCODER1_INDEX 0x00000006 -#define ATOM_DFP_EXT_ENCODER1_INDEX 0x00000007 -#define ATOM_CV_INT_ENCODER1_INDEX 0x00000008 -#define ATOM_DFP_INT_ENCODER2_INDEX 0x00000009 -#define ATOM_CRT_EXT_ENCODER1_INDEX 0x0000000A -#define ATOM_CV_EXT_ENCODER1_INDEX 0x0000000B -#define ATOM_DFP_INT_ENCODER3_INDEX 0x0000000C -#define ATOM_DFP_INT_ENCODER4_INDEX 0x0000000D - -// define ASIC internal encoder id ( bit vector ), used for CRTC_SourceSelTable -#define ASIC_INT_DAC1_ENCODER_ID 0x00 -#define ASIC_INT_TV_ENCODER_ID 0x02 -#define ASIC_INT_DIG1_ENCODER_ID 0x03 -#define ASIC_INT_DAC2_ENCODER_ID 0x04 -#define ASIC_EXT_TV_ENCODER_ID 0x06 -#define ASIC_INT_DVO_ENCODER_ID 0x07 -#define ASIC_INT_DIG2_ENCODER_ID 0x09 -#define ASIC_EXT_DIG_ENCODER_ID 0x05 -#define ASIC_EXT_DIG2_ENCODER_ID 0x08 -#define ASIC_INT_DIG3_ENCODER_ID 0x0a -#define ASIC_INT_DIG4_ENCODER_ID 0x0b -#define ASIC_INT_DIG5_ENCODER_ID 0x0c -#define ASIC_INT_DIG6_ENCODER_ID 0x0d -#define ASIC_INT_DIG7_ENCODER_ID 0x0e - -//define Encoder attribute -#define ATOM_ANALOG_ENCODER 0 -#define ATOM_DIGITAL_ENCODER 1 -#define ATOM_DP_ENCODER 2 - -#define ATOM_ENCODER_ENUM_MASK 0x70 -#define ATOM_ENCODER_ENUM_ID1 0x00 -#define ATOM_ENCODER_ENUM_ID2 0x10 -#define ATOM_ENCODER_ENUM_ID3 0x20 -#define ATOM_ENCODER_ENUM_ID4 0x30 -#define ATOM_ENCODER_ENUM_ID5 0x40 -#define ATOM_ENCODER_ENUM_ID6 0x50 - -#define ATOM_DEVICE_CRT1_INDEX 0x00000000 -#define ATOM_DEVICE_LCD1_INDEX 0x00000001 -#define ATOM_DEVICE_TV1_INDEX 0x00000002 -#define ATOM_DEVICE_DFP1_INDEX 0x00000003 -#define ATOM_DEVICE_CRT2_INDEX 0x00000004 -#define ATOM_DEVICE_LCD2_INDEX 0x00000005 -#define ATOM_DEVICE_DFP6_INDEX 0x00000006 -#define ATOM_DEVICE_DFP2_INDEX 0x00000007 -#define ATOM_DEVICE_CV_INDEX 0x00000008 -#define ATOM_DEVICE_DFP3_INDEX 0x00000009 -#define ATOM_DEVICE_DFP4_INDEX 0x0000000A -#define ATOM_DEVICE_DFP5_INDEX 0x0000000B - -#define ATOM_DEVICE_RESERVEDC_INDEX 0x0000000C -#define ATOM_DEVICE_RESERVEDD_INDEX 0x0000000D -#define ATOM_DEVICE_RESERVEDE_INDEX 0x0000000E -#define ATOM_DEVICE_RESERVEDF_INDEX 0x0000000F -#define ATOM_MAX_SUPPORTED_DEVICE_INFO (ATOM_DEVICE_DFP3_INDEX+1) -#define ATOM_MAX_SUPPORTED_DEVICE_INFO_2 ATOM_MAX_SUPPORTED_DEVICE_INFO -#define ATOM_MAX_SUPPORTED_DEVICE_INFO_3 (ATOM_DEVICE_DFP5_INDEX + 1 ) - -#define ATOM_MAX_SUPPORTED_DEVICE (ATOM_DEVICE_RESERVEDF_INDEX+1) - -#define ATOM_DEVICE_CRT1_SUPPORT (0x1L << ATOM_DEVICE_CRT1_INDEX ) -#define ATOM_DEVICE_LCD1_SUPPORT (0x1L << ATOM_DEVICE_LCD1_INDEX ) -#define ATOM_DEVICE_TV1_SUPPORT (0x1L << ATOM_DEVICE_TV1_INDEX ) -#define ATOM_DEVICE_DFP1_SUPPORT (0x1L << ATOM_DEVICE_DFP1_INDEX ) -#define ATOM_DEVICE_CRT2_SUPPORT (0x1L << ATOM_DEVICE_CRT2_INDEX ) -#define ATOM_DEVICE_LCD2_SUPPORT (0x1L << ATOM_DEVICE_LCD2_INDEX ) -#define ATOM_DEVICE_DFP6_SUPPORT (0x1L << ATOM_DEVICE_DFP6_INDEX ) -#define ATOM_DEVICE_DFP2_SUPPORT (0x1L << ATOM_DEVICE_DFP2_INDEX ) -#define ATOM_DEVICE_CV_SUPPORT (0x1L << ATOM_DEVICE_CV_INDEX ) -#define ATOM_DEVICE_DFP3_SUPPORT (0x1L << ATOM_DEVICE_DFP3_INDEX ) -#define ATOM_DEVICE_DFP4_SUPPORT (0x1L << ATOM_DEVICE_DFP4_INDEX ) -#define ATOM_DEVICE_DFP5_SUPPORT (0x1L << ATOM_DEVICE_DFP5_INDEX ) - -#define ATOM_DEVICE_CRT_SUPPORT (ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_CRT2_SUPPORT) -#define ATOM_DEVICE_DFP_SUPPORT (ATOM_DEVICE_DFP1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT | ATOM_DEVICE_DFP3_SUPPORT | ATOM_DEVICE_DFP4_SUPPORT | ATOM_DEVICE_DFP5_SUPPORT | ATOM_DEVICE_DFP6_SUPPORT) -#define ATOM_DEVICE_TV_SUPPORT (ATOM_DEVICE_TV1_SUPPORT) -#define ATOM_DEVICE_LCD_SUPPORT (ATOM_DEVICE_LCD1_SUPPORT | ATOM_DEVICE_LCD2_SUPPORT) - -#define ATOM_DEVICE_CONNECTOR_TYPE_MASK 0x000000F0 -#define ATOM_DEVICE_CONNECTOR_TYPE_SHIFT 0x00000004 -#define ATOM_DEVICE_CONNECTOR_VGA 0x00000001 -#define ATOM_DEVICE_CONNECTOR_DVI_I 0x00000002 -#define ATOM_DEVICE_CONNECTOR_DVI_D 0x00000003 -#define ATOM_DEVICE_CONNECTOR_DVI_A 0x00000004 -#define ATOM_DEVICE_CONNECTOR_SVIDEO 0x00000005 -#define ATOM_DEVICE_CONNECTOR_COMPOSITE 0x00000006 -#define ATOM_DEVICE_CONNECTOR_LVDS 0x00000007 -#define ATOM_DEVICE_CONNECTOR_DIGI_LINK 0x00000008 -#define ATOM_DEVICE_CONNECTOR_SCART 0x00000009 -#define ATOM_DEVICE_CONNECTOR_HDMI_TYPE_A 0x0000000A -#define ATOM_DEVICE_CONNECTOR_HDMI_TYPE_B 0x0000000B -#define ATOM_DEVICE_CONNECTOR_CASE_1 0x0000000E -#define ATOM_DEVICE_CONNECTOR_DISPLAYPORT 0x0000000F - - -#define ATOM_DEVICE_DAC_INFO_MASK 0x0000000F -#define ATOM_DEVICE_DAC_INFO_SHIFT 0x00000000 -#define ATOM_DEVICE_DAC_INFO_NODAC 0x00000000 -#define ATOM_DEVICE_DAC_INFO_DACA 0x00000001 -#define ATOM_DEVICE_DAC_INFO_DACB 0x00000002 -#define ATOM_DEVICE_DAC_INFO_EXDAC 0x00000003 - -#define ATOM_DEVICE_I2C_ID_NOI2C 0x00000000 - -#define ATOM_DEVICE_I2C_LINEMUX_MASK 0x0000000F -#define ATOM_DEVICE_I2C_LINEMUX_SHIFT 0x00000000 - -#define ATOM_DEVICE_I2C_ID_MASK 0x00000070 -#define ATOM_DEVICE_I2C_ID_SHIFT 0x00000004 -#define ATOM_DEVICE_I2C_ID_IS_FOR_NON_MM_USE 0x00000001 -#define ATOM_DEVICE_I2C_ID_IS_FOR_MM_USE 0x00000002 -#define ATOM_DEVICE_I2C_ID_IS_FOR_SDVO_USE 0x00000003 //For IGP RS600 -#define ATOM_DEVICE_I2C_ID_IS_FOR_DAC_SCL 0x00000004 //For IGP RS690 - -#define ATOM_DEVICE_I2C_HARDWARE_CAP_MASK 0x00000080 -#define ATOM_DEVICE_I2C_HARDWARE_CAP_SHIFT 0x00000007 -#define ATOM_DEVICE_USES_SOFTWARE_ASSISTED_I2C 0x00000000 -#define ATOM_DEVICE_USES_HARDWARE_ASSISTED_I2C 0x00000001 - -// usDeviceSupport: -// Bits0 = 0 - no CRT1 support= 1- CRT1 is supported -// Bit 1 = 0 - no LCD1 support= 1- LCD1 is supported -// Bit 2 = 0 - no TV1 support= 1- TV1 is supported -// Bit 3 = 0 - no DFP1 support= 1- DFP1 is supported -// Bit 4 = 0 - no CRT2 support= 1- CRT2 is supported -// Bit 5 = 0 - no LCD2 support= 1- LCD2 is supported -// Bit 6 = 0 - no DFP6 support= 1- DFP6 is supported -// Bit 7 = 0 - no DFP2 support= 1- DFP2 is supported -// Bit 8 = 0 - no CV support= 1- CV is supported -// Bit 9 = 0 - no DFP3 support= 1- DFP3 is supported -// Bit 10 = 0 - no DFP4 support= 1- DFP4 is supported -// Bit 11 = 0 - no DFP5 support= 1- DFP5 is supported -// -// - -/****************************************************************************/ -/* Structure used in MclkSS_InfoTable */ -/****************************************************************************/ -// ucI2C_ConfigID -// [7:0] - I2C LINE Associate ID -// = 0 - no I2C -// [7] - HW_Cap = 1, [6:0]=HW assisted I2C ID(HW line selection) -// = 0, [6:0]=SW assisted I2C ID -// [6-4] - HW_ENGINE_ID = 1, HW engine for NON multimedia use -// = 2, HW engine for Multimedia use -// = 3-7 Reserved for future I2C engines -// [3-0] - I2C_LINE_MUX = A Mux number when it's HW assisted I2C or GPIO ID when it's SW I2C - -typedef struct _ATOM_I2C_ID_CONFIG -{ -#if ATOM_BIG_ENDIAN - UCHAR bfHW_Capable:1; - UCHAR bfHW_EngineID:3; - UCHAR bfI2C_LineMux:4; -#else - UCHAR bfI2C_LineMux:4; - UCHAR bfHW_EngineID:3; - UCHAR bfHW_Capable:1; -#endif -}ATOM_I2C_ID_CONFIG; - -typedef union _ATOM_I2C_ID_CONFIG_ACCESS -{ - ATOM_I2C_ID_CONFIG sbfAccess; - UCHAR ucAccess; -}ATOM_I2C_ID_CONFIG_ACCESS; - - -/****************************************************************************/ -// Structure used in GPIO_I2C_InfoTable -/****************************************************************************/ -typedef struct _ATOM_GPIO_I2C_ASSIGMENT -{ - USHORT usClkMaskRegisterIndex; - USHORT usClkEnRegisterIndex; - USHORT usClkY_RegisterIndex; - USHORT usClkA_RegisterIndex; - USHORT usDataMaskRegisterIndex; - USHORT usDataEnRegisterIndex; - USHORT usDataY_RegisterIndex; - USHORT usDataA_RegisterIndex; - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; - UCHAR ucClkMaskShift; - UCHAR ucClkEnShift; - UCHAR ucClkY_Shift; - UCHAR ucClkA_Shift; - UCHAR ucDataMaskShift; - UCHAR ucDataEnShift; - UCHAR ucDataY_Shift; - UCHAR ucDataA_Shift; - UCHAR ucReserved1; - UCHAR ucReserved2; -}ATOM_GPIO_I2C_ASSIGMENT; - -typedef struct _ATOM_GPIO_I2C_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_GPIO_I2C_ASSIGMENT asGPIO_Info[ATOM_MAX_SUPPORTED_DEVICE]; -}ATOM_GPIO_I2C_INFO; - -/****************************************************************************/ -// Common Structure used in other structures -/****************************************************************************/ - -#ifndef _H2INC - -//Please don't add or expand this bitfield structure below, this one will retire soon.! -typedef struct _ATOM_MODE_MISC_INFO -{ -#if ATOM_BIG_ENDIAN - USHORT Reserved:6; - USHORT RGB888:1; - USHORT DoubleClock:1; - USHORT Interlace:1; - USHORT CompositeSync:1; - USHORT V_ReplicationBy2:1; - USHORT H_ReplicationBy2:1; - USHORT VerticalCutOff:1; - USHORT VSyncPolarity:1; //0=Active High, 1=Active Low - USHORT HSyncPolarity:1; //0=Active High, 1=Active Low - USHORT HorizontalCutOff:1; -#else - USHORT HorizontalCutOff:1; - USHORT HSyncPolarity:1; //0=Active High, 1=Active Low - USHORT VSyncPolarity:1; //0=Active High, 1=Active Low - USHORT VerticalCutOff:1; - USHORT H_ReplicationBy2:1; - USHORT V_ReplicationBy2:1; - USHORT CompositeSync:1; - USHORT Interlace:1; - USHORT DoubleClock:1; - USHORT RGB888:1; - USHORT Reserved:6; -#endif -}ATOM_MODE_MISC_INFO; - -typedef union _ATOM_MODE_MISC_INFO_ACCESS -{ - ATOM_MODE_MISC_INFO sbfAccess; - USHORT usAccess; -}ATOM_MODE_MISC_INFO_ACCESS; - -#else - -typedef union _ATOM_MODE_MISC_INFO_ACCESS -{ - USHORT usAccess; -}ATOM_MODE_MISC_INFO_ACCESS; - -#endif - -// usModeMiscInfo- -#define ATOM_H_CUTOFF 0x01 -#define ATOM_HSYNC_POLARITY 0x02 //0=Active High, 1=Active Low -#define ATOM_VSYNC_POLARITY 0x04 //0=Active High, 1=Active Low -#define ATOM_V_CUTOFF 0x08 -#define ATOM_H_REPLICATIONBY2 0x10 -#define ATOM_V_REPLICATIONBY2 0x20 -#define ATOM_COMPOSITESYNC 0x40 -#define ATOM_INTERLACE 0x80 -#define ATOM_DOUBLE_CLOCK_MODE 0x100 -#define ATOM_RGB888_MODE 0x200 - -//usRefreshRate- -#define ATOM_REFRESH_43 43 -#define ATOM_REFRESH_47 47 -#define ATOM_REFRESH_56 56 -#define ATOM_REFRESH_60 60 -#define ATOM_REFRESH_65 65 -#define ATOM_REFRESH_70 70 -#define ATOM_REFRESH_72 72 -#define ATOM_REFRESH_75 75 -#define ATOM_REFRESH_85 85 - -// ATOM_MODE_TIMING data are exactly the same as VESA timing data. -// Translation from EDID to ATOM_MODE_TIMING, use the following formula. -// -// VESA_HTOTAL = VESA_ACTIVE + 2* VESA_BORDER + VESA_BLANK -// = EDID_HA + EDID_HBL -// VESA_HDISP = VESA_ACTIVE = EDID_HA -// VESA_HSYNC_START = VESA_ACTIVE + VESA_BORDER + VESA_FRONT_PORCH -// = EDID_HA + EDID_HSO -// VESA_HSYNC_WIDTH = VESA_HSYNC_TIME = EDID_HSPW -// VESA_BORDER = EDID_BORDER - -/****************************************************************************/ -// Structure used in SetCRTC_UsingDTDTimingTable -/****************************************************************************/ -typedef struct _SET_CRTC_USING_DTD_TIMING_PARAMETERS -{ - USHORT usH_Size; - USHORT usH_Blanking_Time; - USHORT usV_Size; - USHORT usV_Blanking_Time; - USHORT usH_SyncOffset; - USHORT usH_SyncWidth; - USHORT usV_SyncOffset; - USHORT usV_SyncWidth; - ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; - UCHAR ucH_Border; // From DFP EDID - UCHAR ucV_Border; - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucPadding[3]; -}SET_CRTC_USING_DTD_TIMING_PARAMETERS; - -/****************************************************************************/ -// Structure used in SetCRTC_TimingTable -/****************************************************************************/ -typedef struct _SET_CRTC_TIMING_PARAMETERS -{ - USHORT usH_Total; // horizontal total - USHORT usH_Disp; // horizontal display - USHORT usH_SyncStart; // horozontal Sync start - USHORT usH_SyncWidth; // horizontal Sync width - USHORT usV_Total; // vertical total - USHORT usV_Disp; // vertical display - USHORT usV_SyncStart; // vertical Sync start - USHORT usV_SyncWidth; // vertical Sync width - ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; - UCHAR ucCRTC; // ATOM_CRTC1 or ATOM_CRTC2 - UCHAR ucOverscanRight; // right - UCHAR ucOverscanLeft; // left - UCHAR ucOverscanBottom; // bottom - UCHAR ucOverscanTop; // top - UCHAR ucReserved; -}SET_CRTC_TIMING_PARAMETERS; -#define SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION SET_CRTC_TIMING_PARAMETERS - -/****************************************************************************/ -// Structure used in StandardVESA_TimingTable -// AnalogTV_InfoTable -// ComponentVideoInfoTable -/****************************************************************************/ -typedef struct _ATOM_MODE_TIMING -{ - USHORT usCRTC_H_Total; - USHORT usCRTC_H_Disp; - USHORT usCRTC_H_SyncStart; - USHORT usCRTC_H_SyncWidth; - USHORT usCRTC_V_Total; - USHORT usCRTC_V_Disp; - USHORT usCRTC_V_SyncStart; - USHORT usCRTC_V_SyncWidth; - USHORT usPixelClock; //in 10Khz unit - ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; - USHORT usCRTC_OverscanRight; - USHORT usCRTC_OverscanLeft; - USHORT usCRTC_OverscanBottom; - USHORT usCRTC_OverscanTop; - USHORT usReserve; - UCHAR ucInternalModeNumber; - UCHAR ucRefreshRate; -}ATOM_MODE_TIMING; - -typedef struct _ATOM_DTD_FORMAT -{ - USHORT usPixClk; - USHORT usHActive; - USHORT usHBlanking_Time; - USHORT usVActive; - USHORT usVBlanking_Time; - USHORT usHSyncOffset; - USHORT usHSyncWidth; - USHORT usVSyncOffset; - USHORT usVSyncWidth; - USHORT usImageHSize; - USHORT usImageVSize; - UCHAR ucHBorder; - UCHAR ucVBorder; - ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo; - UCHAR ucInternalModeNumber; - UCHAR ucRefreshRate; -}ATOM_DTD_FORMAT; - -/****************************************************************************/ -// Structure used in LVDS_InfoTable -// * Need a document to describe this table -/****************************************************************************/ -#define SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 -#define SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 -#define SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 -#define SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 - -//ucTableFormatRevision=1 -//ucTableContentRevision=1 -typedef struct _ATOM_LVDS_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_DTD_FORMAT sLCDTiming; - USHORT usModePatchTableOffset; - USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. - USHORT usOffDelayInMs; - UCHAR ucPowerSequenceDigOntoDEin10Ms; - UCHAR ucPowerSequenceDEtoBLOnin10Ms; - UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} - // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} - // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} - // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} - UCHAR ucPanelDefaultRefreshRate; - UCHAR ucPanelIdentification; - UCHAR ucSS_Id; -}ATOM_LVDS_INFO; - -//ucTableFormatRevision=1 -//ucTableContentRevision=2 -typedef struct _ATOM_LVDS_INFO_V12 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_DTD_FORMAT sLCDTiming; - USHORT usExtInfoTableOffset; - USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. - USHORT usOffDelayInMs; - UCHAR ucPowerSequenceDigOntoDEin10Ms; - UCHAR ucPowerSequenceDEtoBLOnin10Ms; - UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level} - // Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888} - // Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled} - // Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled} - UCHAR ucPanelDefaultRefreshRate; - UCHAR ucPanelIdentification; - UCHAR ucSS_Id; - USHORT usLCDVenderID; - USHORT usLCDProductID; - UCHAR ucLCDPanel_SpecialHandlingCap; - UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable - UCHAR ucReserved[2]; -}ATOM_LVDS_INFO_V12; - -//Definitions for ucLCDPanel_SpecialHandlingCap: - -//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. -//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL -#define LCDPANEL_CAP_READ_EDID 0x1 - -//If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together -//with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static -//refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12 -#define LCDPANEL_CAP_DRR_SUPPORTED 0x2 - -//Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP. -#define LCDPANEL_CAP_eDP 0x4 - - -//Color Bit Depth definition in EDID V1.4 @BYTE 14h -//Bit 6 5 4 - // 0 0 0 - Color bit depth is undefined - // 0 0 1 - 6 Bits per Primary Color - // 0 1 0 - 8 Bits per Primary Color - // 0 1 1 - 10 Bits per Primary Color - // 1 0 0 - 12 Bits per Primary Color - // 1 0 1 - 14 Bits per Primary Color - // 1 1 0 - 16 Bits per Primary Color - // 1 1 1 - Reserved - -#define PANEL_COLOR_BIT_DEPTH_MASK 0x70 - -// Bit7:{=0:Random Dithering disabled;1 Random Dithering enabled} -#define PANEL_RANDOM_DITHER 0x80 -#define PANEL_RANDOM_DITHER_MASK 0x80 - -#define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 // no need to change this - -/****************************************************************************/ -// Structures used by LCD_InfoTable V1.3 Note: previous version was called ATOM_LVDS_INFO_V12 -// ASIC Families: NI -// ucTableFormatRevision=1 -// ucTableContentRevision=3 -/****************************************************************************/ -typedef struct _ATOM_LCD_INFO_V13 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_DTD_FORMAT sLCDTiming; - USHORT usExtInfoTableOffset; - USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. - ULONG ulReserved0; - UCHAR ucLCD_Misc; // Reorganized in V13 - // Bit0: {=0:single, =1:dual}, - // Bit1: {=0:LDI format for RGB888, =1 FPDI format for RGB888} // was {=0:666RGB, =1:888RGB}, - // Bit3:2: {Grey level} - // Bit6:4 Color Bit Depth definition (see below definition in EDID V1.4 @BYTE 14h) - // Bit7 Reserved. was for ATOM_PANEL_MISC_API_ENABLED, still need it? - UCHAR ucPanelDefaultRefreshRate; - UCHAR ucPanelIdentification; - UCHAR ucSS_Id; - USHORT usLCDVenderID; - USHORT usLCDProductID; - UCHAR ucLCDPanel_SpecialHandlingCap; // Reorganized in V13 - // Bit0: Once DAL sees this CAP is set, it will read EDID from LCD on its own - // Bit1: See LCDPANEL_CAP_DRR_SUPPORTED - // Bit2: a quick reference whether an embadded panel (LCD1 ) is LVDS (0) or eDP (1) - // Bit7-3: Reserved - UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable - USHORT usBacklightPWM; // Backlight PWM in Hz. New in _V13 - - UCHAR ucPowerSequenceDIGONtoDE_in4Ms; - UCHAR ucPowerSequenceDEtoVARY_BL_in4Ms; - UCHAR ucPowerSequenceVARY_BLtoDE_in4Ms; - UCHAR ucPowerSequenceDEtoDIGON_in4Ms; - - UCHAR ucOffDelay_in4Ms; - UCHAR ucPowerSequenceVARY_BLtoBLON_in4Ms; - UCHAR ucPowerSequenceBLONtoVARY_BL_in4Ms; - UCHAR ucReserved1; - - UCHAR ucDPCD_eDP_CONFIGURATION_CAP; // dpcd 0dh - UCHAR ucDPCD_MAX_LINK_RATE; // dpcd 01h - UCHAR ucDPCD_MAX_LANE_COUNT; // dpcd 02h - UCHAR ucDPCD_MAX_DOWNSPREAD; // dpcd 03h - - USHORT usMaxPclkFreqInSingleLink; // Max PixelClock frequency in single link mode. - UCHAR uceDPToLVDSRxId; - UCHAR ucLcdReservd; - ULONG ulReserved[2]; -}ATOM_LCD_INFO_V13; - -#define ATOM_LCD_INFO_LAST ATOM_LCD_INFO_V13 - -//Definitions for ucLCD_Misc -#define ATOM_PANEL_MISC_V13_DUAL 0x00000001 -#define ATOM_PANEL_MISC_V13_FPDI 0x00000002 -#define ATOM_PANEL_MISC_V13_GREY_LEVEL 0x0000000C -#define ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT 2 -#define ATOM_PANEL_MISC_V13_COLOR_BIT_DEPTH_MASK 0x70 -#define ATOM_PANEL_MISC_V13_6BIT_PER_COLOR 0x10 -#define ATOM_PANEL_MISC_V13_8BIT_PER_COLOR 0x20 - -//Color Bit Depth definition in EDID V1.4 @BYTE 14h -//Bit 6 5 4 - // 0 0 0 - Color bit depth is undefined - // 0 0 1 - 6 Bits per Primary Color - // 0 1 0 - 8 Bits per Primary Color - // 0 1 1 - 10 Bits per Primary Color - // 1 0 0 - 12 Bits per Primary Color - // 1 0 1 - 14 Bits per Primary Color - // 1 1 0 - 16 Bits per Primary Color - // 1 1 1 - Reserved - -//Definitions for ucLCDPanel_SpecialHandlingCap: - -//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. -//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL -#define LCDPANEL_CAP_V13_READ_EDID 0x1 // = LCDPANEL_CAP_READ_EDID no change comparing to previous version - -//If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together -//with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static -//refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12 -#define LCDPANEL_CAP_V13_DRR_SUPPORTED 0x2 // = LCDPANEL_CAP_DRR_SUPPORTED no change comparing to previous version - -//Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP. -#define LCDPANEL_CAP_V13_eDP 0x4 // = LCDPANEL_CAP_eDP no change comparing to previous version - -//uceDPToLVDSRxId -#define eDP_TO_LVDS_RX_DISABLE 0x00 // no eDP->LVDS translator chip -#define eDP_TO_LVDS_COMMON_ID 0x01 // common eDP->LVDS translator chip without AMD SW init -#define eDP_TO_LVDS_RT_ID 0x02 // RT tanslator which require AMD SW init - -typedef struct _ATOM_PATCH_RECORD_MODE -{ - UCHAR ucRecordType; - USHORT usHDisp; - USHORT usVDisp; -}ATOM_PATCH_RECORD_MODE; - -typedef struct _ATOM_LCD_RTS_RECORD -{ - UCHAR ucRecordType; - UCHAR ucRTSValue; -}ATOM_LCD_RTS_RECORD; - -//!! If the record below exits, it shoud always be the first record for easy use in command table!!! -// The record below is only used when LVDS_Info is present. From ATOM_LVDS_INFO_V12, use ucLCDPanel_SpecialHandlingCap instead. -typedef struct _ATOM_LCD_MODE_CONTROL_CAP -{ - UCHAR ucRecordType; - USHORT usLCDCap; -}ATOM_LCD_MODE_CONTROL_CAP; - -#define LCD_MODE_CAP_BL_OFF 1 -#define LCD_MODE_CAP_CRTC_OFF 2 -#define LCD_MODE_CAP_PANEL_OFF 4 - -typedef struct _ATOM_FAKE_EDID_PATCH_RECORD -{ - UCHAR ucRecordType; - UCHAR ucFakeEDIDLength; - UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. -} ATOM_FAKE_EDID_PATCH_RECORD; - -typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD -{ - UCHAR ucRecordType; - USHORT usHSize; - USHORT usVSize; -}ATOM_PANEL_RESOLUTION_PATCH_RECORD; - -#define LCD_MODE_PATCH_RECORD_MODE_TYPE 1 -#define LCD_RTS_RECORD_TYPE 2 -#define LCD_CAP_RECORD_TYPE 3 -#define LCD_FAKE_EDID_PATCH_RECORD_TYPE 4 -#define LCD_PANEL_RESOLUTION_RECORD_TYPE 5 -#define LCD_EDID_OFFSET_PATCH_RECORD_TYPE 6 -#define ATOM_RECORD_END_TYPE 0xFF - -/****************************Spread Spectrum Info Table Definitions **********************/ - -//ucTableFormatRevision=1 -//ucTableContentRevision=2 -typedef struct _ATOM_SPREAD_SPECTRUM_ASSIGNMENT -{ - USHORT usSpreadSpectrumPercentage; - UCHAR ucSpreadSpectrumType; //Bit1=0 Down Spread,=1 Center Spread. Bit1=1 Ext. =0 Int. Bit2=1: PCIE REFCLK SS =0 iternal PPLL SS Others:TBD - UCHAR ucSS_Step; - UCHAR ucSS_Delay; - UCHAR ucSS_Id; - UCHAR ucRecommendedRef_Div; - UCHAR ucSS_Range; //it was reserved for V11 -}ATOM_SPREAD_SPECTRUM_ASSIGNMENT; - -#define ATOM_MAX_SS_ENTRY 16 -#define ATOM_DP_SS_ID1 0x0f1 // SS ID for internal DP stream at 2.7Ghz. if ATOM_DP_SS_ID2 does not exist in SS_InfoTable, it is used for internal DP stream at 1.62Ghz as well. -#define ATOM_DP_SS_ID2 0x0f2 // SS ID for internal DP stream at 1.62Ghz, if it exists in SS_InfoTable. -#define ATOM_LVLINK_2700MHz_SS_ID 0x0f3 // SS ID for LV link translator chip at 2.7Ghz -#define ATOM_LVLINK_1620MHz_SS_ID 0x0f4 // SS ID for LV link translator chip at 1.62Ghz - - -#define ATOM_SS_DOWN_SPREAD_MODE_MASK 0x00000000 -#define ATOM_SS_DOWN_SPREAD_MODE 0x00000000 -#define ATOM_SS_CENTRE_SPREAD_MODE_MASK 0x00000001 -#define ATOM_SS_CENTRE_SPREAD_MODE 0x00000001 -#define ATOM_INTERNAL_SS_MASK 0x00000000 -#define ATOM_EXTERNAL_SS_MASK 0x00000002 -#define EXEC_SS_STEP_SIZE_SHIFT 2 -#define EXEC_SS_DELAY_SHIFT 4 -#define ACTIVEDATA_TO_BLON_DELAY_SHIFT 4 - -typedef struct _ATOM_SPREAD_SPECTRUM_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_SPREAD_SPECTRUM_ASSIGNMENT asSS_Info[ATOM_MAX_SS_ENTRY]; -}ATOM_SPREAD_SPECTRUM_INFO; - -/****************************************************************************/ -// Structure used in AnalogTV_InfoTable (Top level) -/****************************************************************************/ -//ucTVBootUpDefaultStd definition: - -//ATOM_TV_NTSC 1 -//ATOM_TV_NTSCJ 2 -//ATOM_TV_PAL 3 -//ATOM_TV_PALM 4 -//ATOM_TV_PALCN 5 -//ATOM_TV_PALN 6 -//ATOM_TV_PAL60 7 -//ATOM_TV_SECAM 8 - -//ucTVSupportedStd definition: -#define NTSC_SUPPORT 0x1 -#define NTSCJ_SUPPORT 0x2 - -#define PAL_SUPPORT 0x4 -#define PALM_SUPPORT 0x8 -#define PALCN_SUPPORT 0x10 -#define PALN_SUPPORT 0x20 -#define PAL60_SUPPORT 0x40 -#define SECAM_SUPPORT 0x80 - -#define MAX_SUPPORTED_TV_TIMING 2 - -typedef struct _ATOM_ANALOG_TV_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucTV_SupportedStandard; - UCHAR ucTV_BootUpDefaultStandard; - UCHAR ucExt_TV_ASIC_ID; - UCHAR ucExt_TV_ASIC_SlaveAddr; - /*ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING];*/ - ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; -}ATOM_ANALOG_TV_INFO; - -#define MAX_SUPPORTED_TV_TIMING_V1_2 3 - -typedef struct _ATOM_ANALOG_TV_INFO_V1_2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucTV_SupportedStandard; - UCHAR ucTV_BootUpDefaultStandard; - UCHAR ucExt_TV_ASIC_ID; - UCHAR ucExt_TV_ASIC_SlaveAddr; - ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING_V1_2]; -}ATOM_ANALOG_TV_INFO_V1_2; - -typedef struct _ATOM_DPCD_INFO -{ - UCHAR ucRevisionNumber; //10h : Revision 1.0; 11h : Revision 1.1 - UCHAR ucMaxLinkRate; //06h : 1.62Gbps per lane; 0Ah = 2.7Gbps per lane - UCHAR ucMaxLane; //Bits 4:0 = MAX_LANE_COUNT (1/2/4). Bit 7 = ENHANCED_FRAME_CAP - UCHAR ucMaxDownSpread; //Bit0 = 0: No Down spread; Bit0 = 1: 0.5% (Subject to change according to DP spec) -}ATOM_DPCD_INFO; - -#define ATOM_DPCD_MAX_LANE_MASK 0x1F - -/**************************************************************************/ -// VRAM usage and their defintions - -// One chunk of VRAM used by Bios are for HWICON surfaces,EDID data. -// Current Mode timing and Dail Timing and/or STD timing data EACH device. They can be broken down as below. -// All the addresses below are the offsets from the frame buffer start.They all MUST be Dword aligned! -// To driver: The physical address of this memory portion=mmFB_START(4K aligned)+ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR -// To Bios: ATOMBIOS_VRAM_USAGE_START_ADDR+ATOM_x_ADDR->MM_INDEX - -#ifndef VESA_MEMORY_IN_64K_BLOCK -#define VESA_MEMORY_IN_64K_BLOCK 0x100 //256*64K=16Mb (Max. VESA memory is 16Mb!) -#endif - -#define ATOM_EDID_RAW_DATASIZE 256 //In Bytes -#define ATOM_HWICON_SURFACE_SIZE 4096 //In Bytes -#define ATOM_HWICON_INFOTABLE_SIZE 32 -#define MAX_DTD_MODE_IN_VRAM 6 -#define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) //28= (SIZEOF ATOM_DTD_FORMAT) -#define ATOM_STD_MODE_SUPPORT_TBL_SIZE 32*8 //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) -//20 bytes for Encoder Type and DPCD in STD EDID area -#define DFP_ENCODER_TYPE_OFFSET (ATOM_EDID_RAW_DATASIZE + ATOM_DTD_MODE_SUPPORT_TBL_SIZE + ATOM_STD_MODE_SUPPORT_TBL_SIZE - 20) -#define ATOM_DP_DPCD_OFFSET (DFP_ENCODER_TYPE_OFFSET + 4 ) - -#define ATOM_HWICON1_SURFACE_ADDR 0 -#define ATOM_HWICON2_SURFACE_ADDR (ATOM_HWICON1_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) -#define ATOM_HWICON_INFOTABLE_ADDR (ATOM_HWICON2_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) -#define ATOM_CRT1_EDID_ADDR (ATOM_HWICON_INFOTABLE_ADDR + ATOM_HWICON_INFOTABLE_SIZE) -#define ATOM_CRT1_DTD_MODE_TBL_ADDR (ATOM_CRT1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_CRT1_STD_MODE_TBL_ADDR (ATOM_CRT1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_LCD1_EDID_ADDR (ATOM_CRT1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_LCD1_DTD_MODE_TBL_ADDR (ATOM_LCD1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_LCD1_STD_MODE_TBL_ADDR (ATOM_LCD1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_TV1_DTD_MODE_TBL_ADDR (ATOM_LCD1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DFP1_EDID_ADDR (ATOM_TV1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP1_DTD_MODE_TBL_ADDR (ATOM_DFP1_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_DFP1_STD_MODE_TBL_ADDR (ATOM_DFP1_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_CRT2_EDID_ADDR (ATOM_DFP1_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_CRT2_DTD_MODE_TBL_ADDR (ATOM_CRT2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_CRT2_STD_MODE_TBL_ADDR (ATOM_CRT2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_LCD2_EDID_ADDR (ATOM_CRT2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_LCD2_DTD_MODE_TBL_ADDR (ATOM_LCD2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_LCD2_STD_MODE_TBL_ADDR (ATOM_LCD2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DFP6_EDID_ADDR (ATOM_LCD2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP6_DTD_MODE_TBL_ADDR (ATOM_DFP6_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_DFP6_STD_MODE_TBL_ADDR (ATOM_DFP6_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DFP2_EDID_ADDR (ATOM_DFP6_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP2_DTD_MODE_TBL_ADDR (ATOM_DFP2_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_DFP2_STD_MODE_TBL_ADDR (ATOM_DFP2_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_CV_EDID_ADDR (ATOM_DFP2_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_CV_DTD_MODE_TBL_ADDR (ATOM_CV_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_CV_STD_MODE_TBL_ADDR (ATOM_CV_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DFP3_EDID_ADDR (ATOM_CV_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP3_DTD_MODE_TBL_ADDR (ATOM_DFP3_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_DFP3_STD_MODE_TBL_ADDR (ATOM_DFP3_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DFP4_EDID_ADDR (ATOM_DFP3_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP4_DTD_MODE_TBL_ADDR (ATOM_DFP4_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_DFP4_STD_MODE_TBL_ADDR (ATOM_DFP4_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DFP5_EDID_ADDR (ATOM_DFP4_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DFP5_DTD_MODE_TBL_ADDR (ATOM_DFP5_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) -#define ATOM_DFP5_STD_MODE_TBL_ADDR (ATOM_DFP5_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) - -#define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR + 1024) -#define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START + 512 - -//The size below is in Kb! -#define ATOM_VRAM_RESERVE_SIZE ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC) - -#define ATOM_VRAM_RESERVE_V2_SIZE 32 - -#define ATOM_VRAM_OPERATION_FLAGS_MASK 0xC0000000L -#define ATOM_VRAM_OPERATION_FLAGS_SHIFT 30 -#define ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION 0x1 -#define ATOM_VRAM_BLOCK_NEEDS_RESERVATION 0x0 - -/***********************************************************************************/ -// Structure used in VRAM_UsageByFirmwareTable -// Note1: This table is filled by SetBiosReservationStartInFB in CoreCommSubs.asm -// at running time. -// note2: From RV770, the memory is more than 32bit addressable, so we will change -// ucTableFormatRevision=1,ucTableContentRevision=4, the strcuture remains -// exactly same as 1.1 and 1.2 (1.3 is never in use), but ulStartAddrUsedByFirmware -// (in offset to start of memory address) is KB aligned instead of byte aligend. -/***********************************************************************************/ -// Note3: -/* If we change usReserved to "usFBUsedbyDrvInKB", then to VBIOS this usFBUsedbyDrvInKB is a predefined, unchanged constant across VGA or non VGA adapter, -for CAIL, The size of FB access area is known, only thing missing is the Offset of FB Access area, so we can have: - -If (ulStartAddrUsedByFirmware!=0) -FBAccessAreaOffset= ulStartAddrUsedByFirmware - usFBUsedbyDrvInKB; -Reserved area has been claimed by VBIOS including this FB access area; CAIL doesn't need to reserve any extra area for this purpose -else //Non VGA case - if (FB_Size<=2Gb) - FBAccessAreaOffset= FB_Size - usFBUsedbyDrvInKB; - else - FBAccessAreaOffset= Aper_Size - usFBUsedbyDrvInKB - -CAIL needs to claim an reserved area defined by FBAccessAreaOffset and usFBUsedbyDrvInKB in non VGA case.*/ - -/***********************************************************************************/ -#define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO 1 - -typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO -{ - ULONG ulStartAddrUsedByFirmware; - USHORT usFirmwareUseInKb; - USHORT usReserved; -}ATOM_FIRMWARE_VRAM_RESERVE_INFO; - -typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_FIRMWARE_VRAM_RESERVE_INFO asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO]; -}ATOM_VRAM_USAGE_BY_FIRMWARE; - -// change verion to 1.5, when allow driver to allocate the vram area for command table access. -typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5 -{ - ULONG ulStartAddrUsedByFirmware; - USHORT usFirmwareUseInKb; - USHORT usFBUsedByDrvInKb; -}ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5; - -typedef struct _ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_FIRMWARE_VRAM_RESERVE_INFO_V1_5 asFirmwareVramReserveInfo[ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO]; -}ATOM_VRAM_USAGE_BY_FIRMWARE_V1_5; - -/****************************************************************************/ -// Structure used in GPIO_Pin_LUTTable -/****************************************************************************/ -typedef struct _ATOM_GPIO_PIN_ASSIGNMENT -{ - USHORT usGpioPin_AIndex; - UCHAR ucGpioPinBitShift; - UCHAR ucGPIO_ID; -}ATOM_GPIO_PIN_ASSIGNMENT; - -typedef struct _ATOM_GPIO_PIN_LUT -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[1]; -}ATOM_GPIO_PIN_LUT; - -/****************************************************************************/ -// Structure used in ComponentVideoInfoTable -/****************************************************************************/ -#define GPIO_PIN_ACTIVE_HIGH 0x1 - -#define MAX_SUPPORTED_CV_STANDARDS 5 - -// definitions for ATOM_D_INFO.ucSettings -#define ATOM_GPIO_SETTINGS_BITSHIFT_MASK 0x1F // [4:0] -#define ATOM_GPIO_SETTINGS_RESERVED_MASK 0x60 // [6:5] = must be zeroed out -#define ATOM_GPIO_SETTINGS_ACTIVE_MASK 0x80 // [7] - -typedef struct _ATOM_GPIO_INFO -{ - USHORT usAOffset; - UCHAR ucSettings; - UCHAR ucReserved; -}ATOM_GPIO_INFO; - -// definitions for ATOM_COMPONENT_VIDEO_INFO.ucMiscInfo (bit vector) -#define ATOM_CV_RESTRICT_FORMAT_SELECTION 0x2 - -// definitions for ATOM_COMPONENT_VIDEO_INFO.uc480i/uc480p/uc720p/uc1080i -#define ATOM_GPIO_DEFAULT_MODE_EN 0x80 //[7]; -#define ATOM_GPIO_SETTING_PERMODE_MASK 0x7F //[6:0] - -// definitions for ATOM_COMPONENT_VIDEO_INFO.ucLetterBoxMode -//Line 3 out put 5V. -#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_A 0x01 //represent gpio 3 state for 16:9 -#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_B 0x02 //represent gpio 4 state for 16:9 -#define ATOM_CV_LINE3_ASPECTRATIO_16_9_GPIO_SHIFT 0x0 - -//Line 3 out put 2.2V -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_A 0x04 //represent gpio 3 state for 4:3 Letter box -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_B 0x08 //represent gpio 4 state for 4:3 Letter box -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_LETBOX_GPIO_SHIFT 0x2 - -//Line 3 out put 0V -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_A 0x10 //represent gpio 3 state for 4:3 -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_B 0x20 //represent gpio 4 state for 4:3 -#define ATOM_CV_LINE3_ASPECTRATIO_4_3_GPIO_SHIFT 0x4 - -#define ATOM_CV_LINE3_ASPECTRATIO_MASK 0x3F // bit [5:0] - -#define ATOM_CV_LINE3_ASPECTRATIO_EXIST 0x80 //bit 7 - -//GPIO bit index in gpio setting per mode value, also represend the block no. in gpio blocks. -#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_A 3 //bit 3 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. -#define ATOM_GPIO_INDEX_LINE3_ASPECRATIO_GPIO_B 4 //bit 4 in uc480i/uc480p/uc720p/uc1080i, which represend the default gpio bit setting for the mode. - - -typedef struct _ATOM_COMPONENT_VIDEO_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMask_PinRegisterIndex; - USHORT usEN_PinRegisterIndex; - USHORT usY_PinRegisterIndex; - USHORT usA_PinRegisterIndex; - UCHAR ucBitShift; - UCHAR ucPinActiveState; //ucPinActiveState: Bit0=1 active high, =0 active low - ATOM_DTD_FORMAT sReserved; // must be zeroed out - UCHAR ucMiscInfo; - UCHAR uc480i; - UCHAR uc480p; - UCHAR uc720p; - UCHAR uc1080i; - UCHAR ucLetterBoxMode; - UCHAR ucReserved[3]; - UCHAR ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector - ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS]; - ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS]; -}ATOM_COMPONENT_VIDEO_INFO; - -//ucTableFormatRevision=2 -//ucTableContentRevision=1 -typedef struct _ATOM_COMPONENT_VIDEO_INFO_V21 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucMiscInfo; - UCHAR uc480i; - UCHAR uc480p; - UCHAR uc720p; - UCHAR uc1080i; - UCHAR ucReserved; - UCHAR ucLetterBoxMode; - UCHAR ucNumOfWbGpioBlocks; //For Component video D-Connector support. If zere, NTSC type connector - ATOM_GPIO_INFO aWbGpioStateBlock[MAX_SUPPORTED_CV_STANDARDS]; - ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_CV_STANDARDS]; -}ATOM_COMPONENT_VIDEO_INFO_V21; - -#define ATOM_COMPONENT_VIDEO_INFO_LAST ATOM_COMPONENT_VIDEO_INFO_V21 - -/****************************************************************************/ -// Structure used in object_InfoTable -/****************************************************************************/ -typedef struct _ATOM_OBJECT_HEADER -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usDeviceSupport; - USHORT usConnectorObjectTableOffset; - USHORT usRouterObjectTableOffset; - USHORT usEncoderObjectTableOffset; - USHORT usProtectionObjectTableOffset; //only available when Protection block is independent. - USHORT usDisplayPathTableOffset; -}ATOM_OBJECT_HEADER; - -typedef struct _ATOM_OBJECT_HEADER_V3 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usDeviceSupport; - USHORT usConnectorObjectTableOffset; - USHORT usRouterObjectTableOffset; - USHORT usEncoderObjectTableOffset; - USHORT usProtectionObjectTableOffset; //only available when Protection block is independent. - USHORT usDisplayPathTableOffset; - USHORT usMiscObjectTableOffset; -}ATOM_OBJECT_HEADER_V3; - -typedef struct _ATOM_DISPLAY_OBJECT_PATH -{ - USHORT usDeviceTag; //supported device - USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH - USHORT usConnObjectId; //Connector Object ID - USHORT usGPUObjectId; //GPU ID - USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. -}ATOM_DISPLAY_OBJECT_PATH; - -typedef struct _ATOM_DISPLAY_EXTERNAL_OBJECT_PATH -{ - USHORT usDeviceTag; //supported device - USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH - USHORT usConnObjectId; //Connector Object ID - USHORT usGPUObjectId; //GPU ID - USHORT usGraphicObjIds[2]; //usGraphicObjIds[0]= GPU internal encoder, usGraphicObjIds[1]= external encoder -}ATOM_DISPLAY_EXTERNAL_OBJECT_PATH; - -typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE -{ - UCHAR ucNumOfDispPath; - UCHAR ucVersion; - UCHAR ucPadding[2]; - ATOM_DISPLAY_OBJECT_PATH asDispPath[1]; -}ATOM_DISPLAY_OBJECT_PATH_TABLE; - - -typedef struct _ATOM_OBJECT //each object has this structure -{ - USHORT usObjectID; - USHORT usSrcDstTableOffset; - USHORT usRecordOffset; //this pointing to a bunch of records defined below - USHORT usReserved; -}ATOM_OBJECT; - -typedef struct _ATOM_OBJECT_TABLE //Above 4 object table offset pointing to a bunch of objects all have this structure -{ - UCHAR ucNumberOfObjects; - UCHAR ucPadding[3]; - ATOM_OBJECT asObjects[1]; -}ATOM_OBJECT_TABLE; - -typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure -{ - UCHAR ucNumberOfSrc; - USHORT usSrcObjectID[1]; - UCHAR ucNumberOfDst; - USHORT usDstObjectID[1]; -}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT; - - -//Two definitions below are for OPM on MXM module designs - -#define EXT_HPDPIN_LUTINDEX_0 0 -#define EXT_HPDPIN_LUTINDEX_1 1 -#define EXT_HPDPIN_LUTINDEX_2 2 -#define EXT_HPDPIN_LUTINDEX_3 3 -#define EXT_HPDPIN_LUTINDEX_4 4 -#define EXT_HPDPIN_LUTINDEX_5 5 -#define EXT_HPDPIN_LUTINDEX_6 6 -#define EXT_HPDPIN_LUTINDEX_7 7 -#define MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES (EXT_HPDPIN_LUTINDEX_7+1) - -#define EXT_AUXDDC_LUTINDEX_0 0 -#define EXT_AUXDDC_LUTINDEX_1 1 -#define EXT_AUXDDC_LUTINDEX_2 2 -#define EXT_AUXDDC_LUTINDEX_3 3 -#define EXT_AUXDDC_LUTINDEX_4 4 -#define EXT_AUXDDC_LUTINDEX_5 5 -#define EXT_AUXDDC_LUTINDEX_6 6 -#define EXT_AUXDDC_LUTINDEX_7 7 -#define MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES (EXT_AUXDDC_LUTINDEX_7+1) - -//ucChannelMapping are defined as following -//for DP connector, eDP, DP to VGA/LVDS -//Bit[1:0]: Define which pin connect to DP connector DP_Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -//Bit[3:2]: Define which pin connect to DP connector DP_Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -//Bit[5:4]: Define which pin connect to DP connector DP_Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -//Bit[7:6]: Define which pin connect to DP connector DP_Lane3, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -typedef struct _ATOM_DP_CONN_CHANNEL_MAPPING -{ -#if ATOM_BIG_ENDIAN - UCHAR ucDP_Lane3_Source:2; - UCHAR ucDP_Lane2_Source:2; - UCHAR ucDP_Lane1_Source:2; - UCHAR ucDP_Lane0_Source:2; -#else - UCHAR ucDP_Lane0_Source:2; - UCHAR ucDP_Lane1_Source:2; - UCHAR ucDP_Lane2_Source:2; - UCHAR ucDP_Lane3_Source:2; -#endif -}ATOM_DP_CONN_CHANNEL_MAPPING; - -//for DVI/HDMI, in dual link case, both links have to have same mapping. -//Bit[1:0]: Define which pin connect to DVI connector data Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -//Bit[3:2]: Define which pin connect to DVI connector data Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -//Bit[5:4]: Define which pin connect to DVI connector data Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -//Bit[7:6]: Define which pin connect to DVI connector clock lane, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 -typedef struct _ATOM_DVI_CONN_CHANNEL_MAPPING -{ -#if ATOM_BIG_ENDIAN - UCHAR ucDVI_CLK_Source:2; - UCHAR ucDVI_DATA0_Source:2; - UCHAR ucDVI_DATA1_Source:2; - UCHAR ucDVI_DATA2_Source:2; -#else - UCHAR ucDVI_DATA2_Source:2; - UCHAR ucDVI_DATA1_Source:2; - UCHAR ucDVI_DATA0_Source:2; - UCHAR ucDVI_CLK_Source:2; -#endif -}ATOM_DVI_CONN_CHANNEL_MAPPING; - -typedef struct _EXT_DISPLAY_PATH -{ - USHORT usDeviceTag; //A bit vector to show what devices are supported - USHORT usDeviceACPIEnum; //16bit device ACPI id. - USHORT usDeviceConnector; //A physical connector for displays to plug in, using object connector definitions - UCHAR ucExtAUXDDCLutIndex; //An index into external AUX/DDC channel LUT - UCHAR ucExtHPDPINLutIndex; //An index into external HPD pin LUT - USHORT usExtEncoderObjId; //external encoder object id - union{ - UCHAR ucChannelMapping; // if ucChannelMapping=0, using default one to one mapping - ATOM_DP_CONN_CHANNEL_MAPPING asDPMapping; - ATOM_DVI_CONN_CHANNEL_MAPPING asDVIMapping; - }; - UCHAR ucChPNInvert; // bit vector for up to 8 lanes, =0: P and N is not invert, =1 P and N is inverted - USHORT usCaps; - USHORT usReserved; -}EXT_DISPLAY_PATH; - -#define NUMBER_OF_UCHAR_FOR_GUID 16 -#define MAX_NUMBER_OF_EXT_DISPLAY_PATH 7 - -//usCaps -#define EXT_DISPLAY_PATH_CAPS__HBR2_DISABLE 0x01 - -typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucGuid [NUMBER_OF_UCHAR_FOR_GUID]; // a GUID is a 16 byte long string - EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries. - UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0. - UCHAR uc3DStereoPinId; // use for eDP panel - UCHAR ucRemoteDisplayConfig; - UCHAR uceDPToLVDSRxId; - UCHAR Reserved[4]; // for potential expansion -}ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; - -//Related definitions, all records are different but they have a commond header -typedef struct _ATOM_COMMON_RECORD_HEADER -{ - UCHAR ucRecordType; //An emun to indicate the record type - UCHAR ucRecordSize; //The size of the whole record in byte -}ATOM_COMMON_RECORD_HEADER; - - -#define ATOM_I2C_RECORD_TYPE 1 -#define ATOM_HPD_INT_RECORD_TYPE 2 -#define ATOM_OUTPUT_PROTECTION_RECORD_TYPE 3 -#define ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE 4 -#define ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD_TYPE 5 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE -#define ATOM_ENCODER_FPGA_CONTROL_RECORD_TYPE 6 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE -#define ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE 7 -#define ATOM_JTAG_RECORD_TYPE 8 //Obsolete, switch to use GPIO_CNTL_RECORD_TYPE -#define ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE 9 -#define ATOM_ENCODER_DVO_CF_RECORD_TYPE 10 -#define ATOM_CONNECTOR_CF_RECORD_TYPE 11 -#define ATOM_CONNECTOR_HARDCODE_DTD_RECORD_TYPE 12 -#define ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE 13 -#define ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE 14 -#define ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE 15 -#define ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE 16 //This is for the case when connectors are not known to object table -#define ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE 17 //This is for the case when connectors are not known to object table -#define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record -#define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 -#define ATOM_ENCODER_CAP_RECORD_TYPE 20 - - -//Must be updated when new record type is added,equal to that record definition! -#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ENCODER_CAP_RECORD_TYPE - -typedef struct _ATOM_I2C_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - ATOM_I2C_ID_CONFIG sucI2cId; - UCHAR ucI2CAddr; //The slave address, it's 0 when the record is attached to connector for DDC -}ATOM_I2C_RECORD; - -typedef struct _ATOM_HPD_INT_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucHPDIntGPIOID; //Corresponding block in GPIO_PIN_INFO table gives the pin info - UCHAR ucPlugged_PinState; -}ATOM_HPD_INT_RECORD; - - -typedef struct _ATOM_OUTPUT_PROTECTION_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucProtectionFlag; - UCHAR ucReserved; -}ATOM_OUTPUT_PROTECTION_RECORD; - -typedef struct _ATOM_CONNECTOR_DEVICE_TAG -{ - ULONG ulACPIDeviceEnum; //Reserved for now - USHORT usDeviceID; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT" - USHORT usPadding; -}ATOM_CONNECTOR_DEVICE_TAG; - -typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucNumberOfDevice; - UCHAR ucReserved; - ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation -}ATOM_CONNECTOR_DEVICE_TAG_RECORD; - - -typedef struct _ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucConfigGPIOID; - UCHAR ucConfigGPIOState; //Set to 1 when it's active high to enable external flow in - UCHAR ucFlowinGPIPID; - UCHAR ucExtInGPIPID; -}ATOM_CONNECTOR_DVI_EXT_INPUT_RECORD; - -typedef struct _ATOM_ENCODER_FPGA_CONTROL_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucCTL1GPIO_ID; - UCHAR ucCTL1GPIOState; //Set to 1 when it's active high - UCHAR ucCTL2GPIO_ID; - UCHAR ucCTL2GPIOState; //Set to 1 when it's active high - UCHAR ucCTL3GPIO_ID; - UCHAR ucCTL3GPIOState; //Set to 1 when it's active high - UCHAR ucCTLFPGA_IN_ID; - UCHAR ucPadding[3]; -}ATOM_ENCODER_FPGA_CONTROL_RECORD; - -typedef struct _ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucGPIOID; //Corresponding block in GPIO_PIN_INFO table gives the pin info - UCHAR ucTVActiveState; //Indicating when the pin==0 or 1 when TV is connected -}ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD; - -typedef struct _ATOM_JTAG_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucTMSGPIO_ID; - UCHAR ucTMSGPIOState; //Set to 1 when it's active high - UCHAR ucTCKGPIO_ID; - UCHAR ucTCKGPIOState; //Set to 1 when it's active high - UCHAR ucTDOGPIO_ID; - UCHAR ucTDOGPIOState; //Set to 1 when it's active high - UCHAR ucTDIGPIO_ID; - UCHAR ucTDIGPIOState; //Set to 1 when it's active high - UCHAR ucPadding[2]; -}ATOM_JTAG_RECORD; - - -//The following generic object gpio pin control record type will replace JTAG_RECORD/FPGA_CONTROL_RECORD/DVI_EXT_INPUT_RECORD above gradually -typedef struct _ATOM_GPIO_PIN_CONTROL_PAIR -{ - UCHAR ucGPIOID; // GPIO_ID, find the corresponding ID in GPIO_LUT table - UCHAR ucGPIO_PinState; // Pin state showing how to set-up the pin -}ATOM_GPIO_PIN_CONTROL_PAIR; - -typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucFlags; // Future expnadibility - UCHAR ucNumberOfPins; // Number of GPIO pins used to control the object - ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1]; // the real gpio pin pair determined by number of pins ucNumberOfPins -}ATOM_OBJECT_GPIO_CNTL_RECORD; - -//Definitions for GPIO pin state -#define GPIO_PIN_TYPE_INPUT 0x00 -#define GPIO_PIN_TYPE_OUTPUT 0x10 -#define GPIO_PIN_TYPE_HW_CONTROL 0x20 - -//For GPIO_PIN_TYPE_OUTPUT the following is defined -#define GPIO_PIN_OUTPUT_STATE_MASK 0x01 -#define GPIO_PIN_OUTPUT_STATE_SHIFT 0 -#define GPIO_PIN_STATE_ACTIVE_LOW 0x0 -#define GPIO_PIN_STATE_ACTIVE_HIGH 0x1 - -// Indexes to GPIO array in GLSync record -// GLSync record is for Frame Lock/Gen Lock feature. -#define ATOM_GPIO_INDEX_GLSYNC_REFCLK 0 -#define ATOM_GPIO_INDEX_GLSYNC_HSYNC 1 -#define ATOM_GPIO_INDEX_GLSYNC_VSYNC 2 -#define ATOM_GPIO_INDEX_GLSYNC_SWAP_REQ 3 -#define ATOM_GPIO_INDEX_GLSYNC_SWAP_GNT 4 -#define ATOM_GPIO_INDEX_GLSYNC_INTERRUPT 5 -#define ATOM_GPIO_INDEX_GLSYNC_V_RESET 6 -#define ATOM_GPIO_INDEX_GLSYNC_SWAP_CNTL 7 -#define ATOM_GPIO_INDEX_GLSYNC_SWAP_SEL 8 -#define ATOM_GPIO_INDEX_GLSYNC_MAX 9 - -typedef struct _ATOM_ENCODER_DVO_CF_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - ULONG ulStrengthControl; // DVOA strength control for CF - UCHAR ucPadding[2]; -}ATOM_ENCODER_DVO_CF_RECORD; - -// Bit maps for ATOM_ENCODER_CAP_RECORD.ucEncoderCap -#define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by HW encoder -#define ATOM_ENCODER_CAP_RECORD_HBR2_EN 0x02 // DP1.2 HBR2 setting is qualified and HBR2 can be enabled - -typedef struct _ATOM_ENCODER_CAP_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - union { - USHORT usEncoderCap; - struct { -#if ATOM_BIG_ENDIAN - USHORT usReserved:14; // Bit1-15 may be defined for other capability in future - USHORT usHBR2En:1; // Bit1 is for DP1.2 HBR2 enable - USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. -#else - USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. - USHORT usHBR2En:1; // Bit1 is for DP1.2 HBR2 enable - USHORT usReserved:14; // Bit1-15 may be defined for other capability in future -#endif - }; - }; -}ATOM_ENCODER_CAP_RECORD; - -// value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle -#define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA 1 -#define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB 2 - -typedef struct _ATOM_CONNECTOR_CF_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - USHORT usMaxPixClk; - UCHAR ucFlowCntlGpioId; - UCHAR ucSwapCntlGpioId; - UCHAR ucConnectedDvoBundle; - UCHAR ucPadding; -}ATOM_CONNECTOR_CF_RECORD; - -typedef struct _ATOM_CONNECTOR_HARDCODE_DTD_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - ATOM_DTD_FORMAT asTiming; -}ATOM_CONNECTOR_HARDCODE_DTD_RECORD; - -typedef struct _ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; //ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD_TYPE - UCHAR ucSubConnectorType; //CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D|X_ID_DUAL_LINK_DVI_D|HDMI_TYPE_A - UCHAR ucReserved; -}ATOM_CONNECTOR_PCIE_SUBCONNECTOR_RECORD; - - -typedef struct _ATOM_ROUTER_DDC_PATH_SELECT_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucMuxType; //decide the number of ucMuxState, =0, no pin state, =1: single state with complement, >1: multiple state - UCHAR ucMuxControlPin; - UCHAR ucMuxState[2]; //for alligment purpose -}ATOM_ROUTER_DDC_PATH_SELECT_RECORD; - -typedef struct _ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucMuxType; - UCHAR ucMuxControlPin; - UCHAR ucMuxState[2]; //for alligment purpose -}ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD; - -// define ucMuxType -#define ATOM_ROUTER_MUX_PIN_STATE_MASK 0x0f -#define ATOM_ROUTER_MUX_PIN_SINGLE_STATE_COMPLEMENT 0x01 - -typedef struct _ATOM_CONNECTOR_HPDPIN_LUT_RECORD //record for ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE -{ - ATOM_COMMON_RECORD_HEADER sheader; - UCHAR ucHPDPINMap[MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES]; //An fixed size array which maps external pins to internal GPIO_PIN_INFO table -}ATOM_CONNECTOR_HPDPIN_LUT_RECORD; - -typedef struct _ATOM_CONNECTOR_AUXDDC_LUT_RECORD //record for ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE -{ - ATOM_COMMON_RECORD_HEADER sheader; - ATOM_I2C_ID_CONFIG ucAUXDDCMap[MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES]; //An fixed size array which maps external pins to internal DDC ID -}ATOM_CONNECTOR_AUXDDC_LUT_RECORD; - -typedef struct _ATOM_OBJECT_LINK_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - USHORT usObjectID; //could be connector, encorder or other object in object.h -}ATOM_OBJECT_LINK_RECORD; - -typedef struct _ATOM_CONNECTOR_REMOTE_CAP_RECORD -{ - ATOM_COMMON_RECORD_HEADER sheader; - USHORT usReserved; -}ATOM_CONNECTOR_REMOTE_CAP_RECORD; - -/****************************************************************************/ -// ASIC voltage data table -/****************************************************************************/ -typedef struct _ATOM_VOLTAGE_INFO_HEADER -{ - USHORT usVDDCBaseLevel; //In number of 50mv unit - USHORT usReserved; //For possible extension table offset - UCHAR ucNumOfVoltageEntries; - UCHAR ucBytesPerVoltageEntry; - UCHAR ucVoltageStep; //Indicating in how many mv increament is one step, 0.5mv unit - UCHAR ucDefaultVoltageEntry; - UCHAR ucVoltageControlI2cLine; - UCHAR ucVoltageControlAddress; - UCHAR ucVoltageControlOffset; -}ATOM_VOLTAGE_INFO_HEADER; - -typedef struct _ATOM_VOLTAGE_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_VOLTAGE_INFO_HEADER viHeader; - UCHAR ucVoltageEntries[64]; //64 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries*ucBytesPerVoltageEntry -}ATOM_VOLTAGE_INFO; - - -typedef struct _ATOM_VOLTAGE_FORMULA -{ - USHORT usVoltageBaseLevel; // In number of 1mv unit - USHORT usVoltageStep; // Indicating in how many mv increament is one step, 1mv unit - UCHAR ucNumOfVoltageEntries; // Number of Voltage Entry, which indicate max Voltage - UCHAR ucFlag; // bit0=0 :step is 1mv =1 0.5mv - UCHAR ucBaseVID; // if there is no lookup table, VID= BaseVID + ( Vol - BaseLevle ) /VoltageStep - UCHAR ucReserved; - UCHAR ucVIDAdjustEntries[32]; // 32 is for allocation, the actual number of entry is present at ucNumOfVoltageEntries -}ATOM_VOLTAGE_FORMULA; - -typedef struct _VOLTAGE_LUT_ENTRY -{ - USHORT usVoltageCode; // The Voltage ID, either GPIO or I2C code - USHORT usVoltageValue; // The corresponding Voltage Value, in mV -}VOLTAGE_LUT_ENTRY; - -typedef struct _ATOM_VOLTAGE_FORMULA_V2 -{ - UCHAR ucNumOfVoltageEntries; // Number of Voltage Entry, which indicate max Voltage - UCHAR ucReserved[3]; - VOLTAGE_LUT_ENTRY asVIDAdjustEntries[32];// 32 is for allocation, the actual number of entries is in ucNumOfVoltageEntries -}ATOM_VOLTAGE_FORMULA_V2; - -typedef struct _ATOM_VOLTAGE_CONTROL -{ - UCHAR ucVoltageControlId; //Indicate it is controlled by I2C or GPIO or HW state machine - UCHAR ucVoltageControlI2cLine; - UCHAR ucVoltageControlAddress; - UCHAR ucVoltageControlOffset; - USHORT usGpioPin_AIndex; //GPIO_PAD register index - UCHAR ucGpioPinBitShift[9]; //at most 8 pin support 255 VIDs, termintate with 0xff - UCHAR ucReserved; -}ATOM_VOLTAGE_CONTROL; - -// Define ucVoltageControlId -#define VOLTAGE_CONTROLLED_BY_HW 0x00 -#define VOLTAGE_CONTROLLED_BY_I2C_MASK 0x7F -#define VOLTAGE_CONTROLLED_BY_GPIO 0x80 -#define VOLTAGE_CONTROL_ID_LM64 0x01 //I2C control, used for R5xx Core Voltage -#define VOLTAGE_CONTROL_ID_DAC 0x02 //I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI -#define VOLTAGE_CONTROL_ID_VT116xM 0x03 //I2C control, used for R6xx Core Voltage -#define VOLTAGE_CONTROL_ID_DS4402 0x04 -#define VOLTAGE_CONTROL_ID_UP6266 0x05 -#define VOLTAGE_CONTROL_ID_SCORPIO 0x06 -#define VOLTAGE_CONTROL_ID_VT1556M 0x07 -#define VOLTAGE_CONTROL_ID_CHL822x 0x08 -#define VOLTAGE_CONTROL_ID_VT1586M 0x09 -#define VOLTAGE_CONTROL_ID_UP1637 0x0A - -typedef struct _ATOM_VOLTAGE_OBJECT -{ - UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI - UCHAR ucSize; //Size of Object - ATOM_VOLTAGE_CONTROL asControl; //describ how to control - ATOM_VOLTAGE_FORMULA asFormula; //Indicate How to convert real Voltage to VID -}ATOM_VOLTAGE_OBJECT; - -typedef struct _ATOM_VOLTAGE_OBJECT_V2 -{ - UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI - UCHAR ucSize; //Size of Object - ATOM_VOLTAGE_CONTROL asControl; //describ how to control - ATOM_VOLTAGE_FORMULA_V2 asFormula; //Indicate How to convert real Voltage to VID -}ATOM_VOLTAGE_OBJECT_V2; - -typedef struct _ATOM_VOLTAGE_OBJECT_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_VOLTAGE_OBJECT asVoltageObj[3]; //Info for Voltage control -}ATOM_VOLTAGE_OBJECT_INFO; - -typedef struct _ATOM_VOLTAGE_OBJECT_INFO_V2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_VOLTAGE_OBJECT_V2 asVoltageObj[3]; //Info for Voltage control -}ATOM_VOLTAGE_OBJECT_INFO_V2; - -typedef struct _ATOM_LEAKID_VOLTAGE -{ - UCHAR ucLeakageId; - UCHAR ucReserved; - USHORT usVoltage; -}ATOM_LEAKID_VOLTAGE; - -typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{ - UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI - UCHAR ucVoltageMode; //Indicate voltage control mode: Init/Set/Leakage/Set phase - USHORT usSize; //Size of Object -}ATOM_VOLTAGE_OBJECT_HEADER_V3; - -typedef struct _VOLTAGE_LUT_ENTRY_V2 -{ - ULONG ulVoltageId; // The Voltage ID which is used to program GPIO register - USHORT usVoltageValue; // The corresponding Voltage Value, in mV -}VOLTAGE_LUT_ENTRY_V2; - -typedef struct _LEAKAGE_VOLTAGE_LUT_ENTRY_V2 -{ - USHORT usVoltageLevel; // The Voltage ID which is used to program GPIO register - USHORT usVoltageId; - USHORT usLeakageId; // The corresponding Voltage Value, in mV -}LEAKAGE_VOLTAGE_LUT_ENTRY_V2; - -typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3 -{ - ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; - UCHAR ucVoltageRegulatorId; //Indicate Voltage Regulator Id - UCHAR ucVoltageControlI2cLine; - UCHAR ucVoltageControlAddress; - UCHAR ucVoltageControlOffset; - ULONG ulReserved; - VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff -}ATOM_I2C_VOLTAGE_OBJECT_V3; - -typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 -{ - ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; - UCHAR ucVoltageGpioCntlId; // default is 0 which indicate control through CG VID mode - UCHAR ucGpioEntryNum; // indiate the entry numbers of Votlage/Gpio value Look up table - UCHAR ucPhaseDelay; // phase delay in unit of micro second - UCHAR ucReserved; - ULONG ulGpioMaskVal; // GPIO Mask value - VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[1]; -}ATOM_GPIO_VOLTAGE_OBJECT_V3; - -typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 -{ - ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; - UCHAR ucLeakageCntlId; // default is 0 - UCHAR ucLeakageEntryNum; // indicate the entry number of LeakageId/Voltage Lut table - UCHAR ucReserved[2]; - ULONG ulMaxVoltageLevel; - LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1]; -}ATOM_LEAKAGE_VOLTAGE_OBJECT_V3; - -typedef union _ATOM_VOLTAGE_OBJECT_V3{ - ATOM_GPIO_VOLTAGE_OBJECT_V3 asGpioVoltageObj; - ATOM_I2C_VOLTAGE_OBJECT_V3 asI2cVoltageObj; - ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 asLeakageObj; -}ATOM_VOLTAGE_OBJECT_V3; - -typedef struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_VOLTAGE_OBJECT_V3 asVoltageObj[3]; //Info for Voltage control -}ATOM_VOLTAGE_OBJECT_INFO_V3_1; - -typedef struct _ATOM_ASIC_PROFILE_VOLTAGE -{ - UCHAR ucProfileId; - UCHAR ucReserved; - USHORT usSize; - USHORT usEfuseSpareStartAddr; - USHORT usFuseIndex[8]; //from LSB to MSB, Max 8bit,end of 0xffff if less than 8 efuse id, - ATOM_LEAKID_VOLTAGE asLeakVol[2]; //Leakid and relatd voltage -}ATOM_ASIC_PROFILE_VOLTAGE; - -//ucProfileId -#define ATOM_ASIC_PROFILE_ID_EFUSE_VOLTAGE 1 -#define ATOM_ASIC_PROFILE_ID_EFUSE_PERFORMANCE_VOLTAGE 1 -#define ATOM_ASIC_PROFILE_ID_EFUSE_THERMAL_VOLTAGE 2 - -typedef struct _ATOM_ASIC_PROFILING_INFO -{ - ATOM_COMMON_TABLE_HEADER asHeader; - ATOM_ASIC_PROFILE_VOLTAGE asVoltage; -}ATOM_ASIC_PROFILING_INFO; - -typedef struct _ATOM_POWER_SOURCE_OBJECT -{ - UCHAR ucPwrSrcId; // Power source - UCHAR ucPwrSensorType; // GPIO, I2C or none - UCHAR ucPwrSensId; // if GPIO detect, it is GPIO id, if I2C detect, it is I2C id - UCHAR ucPwrSensSlaveAddr; // Slave address if I2C detect - UCHAR ucPwrSensRegIndex; // I2C register Index if I2C detect - UCHAR ucPwrSensRegBitMask; // detect which bit is used if I2C detect - UCHAR ucPwrSensActiveState; // high active or low active - UCHAR ucReserve[3]; // reserve - USHORT usSensPwr; // in unit of watt -}ATOM_POWER_SOURCE_OBJECT; - -typedef struct _ATOM_POWER_SOURCE_INFO -{ - ATOM_COMMON_TABLE_HEADER asHeader; - UCHAR asPwrbehave[16]; - ATOM_POWER_SOURCE_OBJECT asPwrObj[1]; -}ATOM_POWER_SOURCE_INFO; - - -//Define ucPwrSrcId -#define POWERSOURCE_PCIE_ID1 0x00 -#define POWERSOURCE_6PIN_CONNECTOR_ID1 0x01 -#define POWERSOURCE_8PIN_CONNECTOR_ID1 0x02 -#define POWERSOURCE_6PIN_CONNECTOR_ID2 0x04 -#define POWERSOURCE_8PIN_CONNECTOR_ID2 0x08 - -//define ucPwrSensorId -#define POWER_SENSOR_ALWAYS 0x00 -#define POWER_SENSOR_GPIO 0x01 -#define POWER_SENSOR_I2C 0x02 - -typedef struct _ATOM_CLK_VOLT_CAPABILITY -{ - ULONG ulVoltageIndex; // The Voltage Index indicated by FUSE, same voltage index shared with SCLK DPM fuse table - ULONG ulMaximumSupportedCLK; // Maximum clock supported with specified voltage index, unit in 10kHz -}ATOM_CLK_VOLT_CAPABILITY; - -typedef struct _ATOM_AVAILABLE_SCLK_LIST -{ - ULONG ulSupportedSCLK; // Maximum clock supported with specified voltage index, unit in 10kHz - USHORT usVoltageIndex; // The Voltage Index indicated by FUSE for specified SCLK - USHORT usVoltageID; // The Voltage ID indicated by FUSE for specified SCLK -}ATOM_AVAILABLE_SCLK_LIST; - -// ATOM_INTEGRATED_SYSTEM_INFO_V6 ulSystemConfig cap definition -#define ATOM_IGP_INFO_V6_SYSTEM_CONFIG__PCIE_POWER_GATING_ENABLE 1 // refer to ulSystemConfig bit[0] - -// this IntegrateSystemInfoTable is used for Liano/Ontario APU -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; - ULONG ulDentistVCOFreq; - ULONG ulBootUpUMAClock; - ATOM_CLK_VOLT_CAPABILITY sDISPCLK_Voltage[4]; - ULONG ulBootUpReqDisplayVector; - ULONG ulOtherDisplayMisc; - ULONG ulGPUCapInfo; - ULONG ulSB_MMIO_Base_Addr; - USHORT usRequestedPWMFreqInHz; - UCHAR ucHtcTmpLmt; - UCHAR ucHtcHystLmt; - ULONG ulMinEngineClock; - ULONG ulSystemConfig; - ULONG ulCPUCapInfo; - USHORT usNBP0Voltage; - USHORT usNBP1Voltage; - USHORT usBootUpNBVoltage; - USHORT usExtDispConnInfoOffset; - USHORT usPanelRefreshRateRange; - UCHAR ucMemoryType; - UCHAR ucUMAChannelNumber; - ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10]; - ULONG ulCSR_M3_ARB_CNTL_UVD[10]; - ULONG ulCSR_M3_ARB_CNTL_FS3D[10]; - ATOM_AVAILABLE_SCLK_LIST sAvail_SCLK[5]; - ULONG ulGMCRestoreResetTime; - ULONG ulMinimumNClk; - ULONG ulIdleNClk; - ULONG ulDDR_DLL_PowerUpTime; - ULONG ulDDR_PLL_PowerUpTime; - USHORT usPCIEClkSSPercentage; - USHORT usPCIEClkSSType; - USHORT usLvdsSSPercentage; - USHORT usLvdsSSpreadRateIn10Hz; - USHORT usHDMISSPercentage; - USHORT usHDMISSpreadRateIn10Hz; - USHORT usDVISSPercentage; - USHORT usDVISSpreadRateIn10Hz; - ULONG SclkDpmBoostMargin; - ULONG SclkDpmThrottleMargin; - USHORT SclkDpmTdpLimitPG; - USHORT SclkDpmTdpLimitBoost; - ULONG ulBoostEngineCLock; - UCHAR ulBoostVid_2bit; - UCHAR EnableBoost; - USHORT GnbTdpLimit; - USHORT usMaxLVDSPclkFreqInSingleLink; - UCHAR ucLvdsMisc; - UCHAR ucLVDSReserved; - ULONG ulReserved3[15]; - ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; -}ATOM_INTEGRATED_SYSTEM_INFO_V6; - -// ulGPUCapInfo -#define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01 -#define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__DISABLE_AUX_HW_MODE_DETECTION 0x08 - -//ucLVDSMisc: -#define SYS_INFO_LVDSMISC__888_FPDI_MODE 0x01 -#define SYS_INFO_LVDSMISC__DL_CH_SWAP 0x02 -#define SYS_INFO_LVDSMISC__888_BPC 0x04 -#define SYS_INFO_LVDSMISC__OVERRIDE_EN 0x08 -#define SYS_INFO_LVDSMISC__BLON_ACTIVE_LOW 0x10 - -// not used any more -#define SYS_INFO_LVDSMISC__VSYNC_ACTIVE_LOW 0x04 -#define SYS_INFO_LVDSMISC__HSYNC_ACTIVE_LOW 0x08 - -/********************************************************************************************************************** - ATOM_INTEGRATED_SYSTEM_INFO_V6 Description -ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock -ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. -ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. -sDISPCLK_Voltage: Report Display clock voltage requirement. - -ulBootUpReqDisplayVector: VBIOS boot up display IDs, following are supported devices in Liano/Ontaio projects: - ATOM_DEVICE_CRT1_SUPPORT 0x0001 - ATOM_DEVICE_CRT2_SUPPORT 0x0010 - ATOM_DEVICE_DFP1_SUPPORT 0x0008 - ATOM_DEVICE_DFP6_SUPPORT 0x0040 - ATOM_DEVICE_DFP2_SUPPORT 0x0080 - ATOM_DEVICE_DFP3_SUPPORT 0x0200 - ATOM_DEVICE_DFP4_SUPPORT 0x0400 - ATOM_DEVICE_DFP5_SUPPORT 0x0800 - ATOM_DEVICE_LCD1_SUPPORT 0x0002 -ulOtherDisplayMisc: Other display related flags, not defined yet. -ulGPUCapInfo: bit[0]=0: TMDS/HDMI Coherent Mode use cascade PLL mode. - =1: TMDS/HDMI Coherent Mode use signel PLL mode. - bit[3]=0: Enable HW AUX mode detection logic - =1: Disable HW AUX mode dettion logic -ulSB_MMIO_Base_Addr: Physical Base address to SB MMIO space. Driver needs to initialize it for SMU usage. - -usRequestedPWMFreqInHz: When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW). - Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0; - - When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below: - 1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use; - VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result, - Changing BL using VBIOS function is functional in both driver and non-driver present environment; - and enabling VariBri under the driver environment from PP table is optional. - - 2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating - that BL control from GPU is expected. - VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1 - Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but - it's per platform - and enabling VariBri under the driver environment from PP table is optional. - -ucHtcTmpLmt: Refer to D18F3x64 bit[22:16], HtcTmpLmt. - Threshold on value to enter HTC_active state. -ucHtcHystLmt: Refer to D18F3x64 bit[27:24], HtcHystLmt. - To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt. -ulMinEngineClock: Minimum SCLK allowed in 10kHz unit. This is calculated based on WRCK Fuse settings. -ulSystemConfig: Bit[0]=0: PCIE Power Gating Disabled - =1: PCIE Power Gating Enabled - Bit[1]=0: DDR-DLL shut-down feature disabled. - 1: DDR-DLL shut-down feature enabled. - Bit[2]=0: DDR-PLL Power down feature disabled. - 1: DDR-PLL Power down feature enabled. -ulCPUCapInfo: TBD -usNBP0Voltage: VID for voltage on NB P0 State -usNBP1Voltage: VID for voltage on NB P1 State -usBootUpNBVoltage: Voltage Index of GNB voltage configured by SBIOS, which is suffcient to support VBIOS DISPCLK requirement. -usExtDispConnInfoOffset: Offset to sExtDispConnInfo inside the structure -usPanelRefreshRateRange: Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set - to indicate a range. - SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 - SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 - SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 - SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 -ucMemoryType: [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. -ucUMAChannelNumber: System memory channel numbers. -ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default -ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. -ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. -sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high -ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. -ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. -ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. -ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns. -ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns. -usPCIEClkSSPercentage: PCIE Clock Spred Spectrum Percentage in unit 0.01%; 100 mean 1%. -usPCIEClkSSType: PCIE Clock Spred Spectrum Type. 0 for Down spread(default); 1 for Center spread. -usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. -usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. -usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. -usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. -usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. -usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. -usMaxLVDSPclkFreqInSingleLink: Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz -ucLVDSMisc: [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode - [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped - [bit2] LVDS 888bit per color mode =0: 666 bit per color =1:888 bit per color - [bit3] LVDS parameter override enable =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used - [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low ) -**********************************************************************************************************************/ - -// this Table is used for Liano/Ontario APU -typedef struct _ATOM_FUSION_SYSTEM_INFO_V1 -{ - ATOM_INTEGRATED_SYSTEM_INFO_V6 sIntegratedSysInfo; - ULONG ulPowerplayTable[128]; -}ATOM_FUSION_SYSTEM_INFO_V1; -/********************************************************************************************************************** - ATOM_FUSION_SYSTEM_INFO_V1 Description -sIntegratedSysInfo: refer to ATOM_INTEGRATED_SYSTEM_INFO_V6 definition. -ulPowerplayTable[128]: This 512 bytes memory is used to save ATOM_PPLIB_POWERPLAYTABLE3, starting form ulPowerplayTable[0] -**********************************************************************************************************************/ - -// this IntegrateSystemInfoTable is used for Trinity APU -typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ULONG ulBootUpEngineClock; - ULONG ulDentistVCOFreq; - ULONG ulBootUpUMAClock; - ATOM_CLK_VOLT_CAPABILITY sDISPCLK_Voltage[4]; - ULONG ulBootUpReqDisplayVector; - ULONG ulOtherDisplayMisc; - ULONG ulGPUCapInfo; - ULONG ulSB_MMIO_Base_Addr; - USHORT usRequestedPWMFreqInHz; - UCHAR ucHtcTmpLmt; - UCHAR ucHtcHystLmt; - ULONG ulMinEngineClock; - ULONG ulSystemConfig; - ULONG ulCPUCapInfo; - USHORT usNBP0Voltage; - USHORT usNBP1Voltage; - USHORT usBootUpNBVoltage; - USHORT usExtDispConnInfoOffset; - USHORT usPanelRefreshRateRange; - UCHAR ucMemoryType; - UCHAR ucUMAChannelNumber; - UCHAR strVBIOSMsg[40]; - ULONG ulReserved[20]; - ATOM_AVAILABLE_SCLK_LIST sAvail_SCLK[5]; - ULONG ulGMCRestoreResetTime; - ULONG ulMinimumNClk; - ULONG ulIdleNClk; - ULONG ulDDR_DLL_PowerUpTime; - ULONG ulDDR_PLL_PowerUpTime; - USHORT usPCIEClkSSPercentage; - USHORT usPCIEClkSSType; - USHORT usLvdsSSPercentage; - USHORT usLvdsSSpreadRateIn10Hz; - USHORT usHDMISSPercentage; - USHORT usHDMISSpreadRateIn10Hz; - USHORT usDVISSPercentage; - USHORT usDVISSpreadRateIn10Hz; - ULONG SclkDpmBoostMargin; - ULONG SclkDpmThrottleMargin; - USHORT SclkDpmTdpLimitPG; - USHORT SclkDpmTdpLimitBoost; - ULONG ulBoostEngineCLock; - UCHAR ulBoostVid_2bit; - UCHAR EnableBoost; - USHORT GnbTdpLimit; - USHORT usMaxLVDSPclkFreqInSingleLink; - UCHAR ucLvdsMisc; - UCHAR ucLVDSReserved; - UCHAR ucLVDSPwrOnSeqDIGONtoDE_in4Ms; - UCHAR ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; - UCHAR ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; - UCHAR ucLVDSPwrOffSeqDEtoDIGON_in4Ms; - UCHAR ucLVDSOffToOnDelay_in4Ms; - UCHAR ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; - UCHAR ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; - UCHAR ucLVDSReserved1; - ULONG ulLCDBitDepthControlVal; - ULONG ulNbpStateMemclkFreq[4]; - USHORT usNBP2Voltage; - USHORT usNBP3Voltage; - ULONG ulNbpStateNClkFreq[4]; - UCHAR ucNBDPMEnable; - UCHAR ucReserved[3]; - UCHAR ucDPMState0VclkFid; - UCHAR ucDPMState0DclkFid; - UCHAR ucDPMState1VclkFid; - UCHAR ucDPMState1DclkFid; - UCHAR ucDPMState2VclkFid; - UCHAR ucDPMState2DclkFid; - UCHAR ucDPMState3VclkFid; - UCHAR ucDPMState3DclkFid; - ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; -}ATOM_INTEGRATED_SYSTEM_INFO_V1_7; - -// ulOtherDisplayMisc -#define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01 -#define INTEGRATED_SYSTEM_INFO__GET_BOOTUP_DISPLAY_CALLBACK_FUNC_SUPPORT 0x02 -#define INTEGRATED_SYSTEM_INFO__GET_EXPANSION_CALLBACK_FUNC_SUPPORT 0x04 -#define INTEGRATED_SYSTEM_INFO__FAST_BOOT_SUPPORT 0x08 - -// ulGPUCapInfo -#define SYS_INFO_GPUCAPS__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01 -#define SYS_INFO_GPUCAPS__DP_SINGLEPLL_MODE 0x02 -#define SYS_INFO_GPUCAPS__DISABLE_AUX_MODE_DETECT 0x08 - -/********************************************************************************************************************** - ATOM_INTEGRATED_SYSTEM_INFO_V1_7 Description -ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock -ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. -ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. -sDISPCLK_Voltage: Report Display clock voltage requirement. - -ulBootUpReqDisplayVector: VBIOS boot up display IDs, following are supported devices in Trinity projects: - ATOM_DEVICE_CRT1_SUPPORT 0x0001 - ATOM_DEVICE_DFP1_SUPPORT 0x0008 - ATOM_DEVICE_DFP6_SUPPORT 0x0040 - ATOM_DEVICE_DFP2_SUPPORT 0x0080 - ATOM_DEVICE_DFP3_SUPPORT 0x0200 - ATOM_DEVICE_DFP4_SUPPORT 0x0400 - ATOM_DEVICE_DFP5_SUPPORT 0x0800 - ATOM_DEVICE_LCD1_SUPPORT 0x0002 -ulOtherDisplayMisc: bit[0]=0: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is not supported by SBIOS. - =1: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is supported by SBIOS. - bit[1]=0: INT15 callback function Get boot display( ax=4e08, bl=01h) is not supported by SBIOS - =1: INT15 callback function Get boot display( ax=4e08, bl=01h) is supported by SBIOS - bit[2]=0: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is not supported by SBIOS - =1: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is supported by SBIOS - bit[3]=0: VBIOS fast boot is disable - =1: VBIOS fast boot is enable. ( VBIOS skip display device detection in every set mode if LCD panel is connect and LID is open) -ulGPUCapInfo: bit[0]=0: TMDS/HDMI Coherent Mode use cascade PLL mode. - =1: TMDS/HDMI Coherent Mode use signel PLL mode. - bit[1]=0: DP mode use cascade PLL mode ( New for Trinity ) - =1: DP mode use single PLL mode - bit[3]=0: Enable AUX HW mode detection logic - =1: Disable AUX HW mode detection logic - -ulSB_MMIO_Base_Addr: Physical Base address to SB MMIO space. Driver needs to initialize it for SMU usage. - -usRequestedPWMFreqInHz: When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW). - Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0; - - When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below: - 1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use; - VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result, - Changing BL using VBIOS function is functional in both driver and non-driver present environment; - and enabling VariBri under the driver environment from PP table is optional. - - 2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating - that BL control from GPU is expected. - VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1 - Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but - it's per platform - and enabling VariBri under the driver environment from PP table is optional. - -ucHtcTmpLmt: Refer to D18F3x64 bit[22:16], HtcTmpLmt. - Threshold on value to enter HTC_active state. -ucHtcHystLmt: Refer to D18F3x64 bit[27:24], HtcHystLmt. - To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt. -ulMinEngineClock: Minimum SCLK allowed in 10kHz unit. This is calculated based on WRCK Fuse settings. -ulSystemConfig: Bit[0]=0: PCIE Power Gating Disabled - =1: PCIE Power Gating Enabled - Bit[1]=0: DDR-DLL shut-down feature disabled. - 1: DDR-DLL shut-down feature enabled. - Bit[2]=0: DDR-PLL Power down feature disabled. - 1: DDR-PLL Power down feature enabled. -ulCPUCapInfo: TBD -usNBP0Voltage: VID for voltage on NB P0 State -usNBP1Voltage: VID for voltage on NB P1 State -usNBP2Voltage: VID for voltage on NB P2 State -usNBP3Voltage: VID for voltage on NB P3 State -usBootUpNBVoltage: Voltage Index of GNB voltage configured by SBIOS, which is suffcient to support VBIOS DISPCLK requirement. -usExtDispConnInfoOffset: Offset to sExtDispConnInfo inside the structure -usPanelRefreshRateRange: Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set - to indicate a range. - SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 - SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 - SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 - SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 -ucMemoryType: [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. -ucUMAChannelNumber: System memory channel numbers. -ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default -ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. -ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. -sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high -ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. -ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. -ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. -ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns. -ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns. -usPCIEClkSSPercentage: PCIE Clock Spread Spectrum Percentage in unit 0.01%; 100 mean 1%. -usPCIEClkSSType: PCIE Clock Spread Spectrum Type. 0 for Down spread(default); 1 for Center spread. -usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. -usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. -usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. -usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. -usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. -usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. -usMaxLVDSPclkFreqInSingleLink: Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz -ucLVDSMisc: [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode - [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped - [bit2] LVDS 888bit per color mode =0: 666 bit per color =1:888 bit per color - [bit3] LVDS parameter override enable =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used - [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low ) -ucLVDSPwrOnSeqDIGONtoDE_in4Ms: LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ). - =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. -ucLVDSPwrOnDEtoVARY_BL_in4Ms: LVDS power up sequence time in unit of 4ms., time delay from DE( data enable ) active to Vary Brightness enable signal active( VARY_BL ). - =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. - -ucLVDSPwrOffVARY_BLtoDE_in4Ms: LVDS power down sequence time in unit of 4ms, time delay from data enable ( DE ) signal off to LCDVCC (DIGON) off. - =0 mean use VBIOS default delay which is 8 ( 32ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. - -ucLVDSPwrOffDEtoDIGON_in4Ms: LVDS power down sequence time in unit of 4ms, time delay from vary brightness enable signal( VARY_BL) off to data enable ( DE ) signal off. - =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. - -ucLVDSOffToOnDelay_in4Ms: LVDS power down sequence time in unit of 4ms. Time delay from DIGON signal off to DIGON signal active. - =0 means to use VBIOS default delay which is 125 ( 500ms ). - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. - -ucLVDSPwrOnVARY_BLtoBLON_in4Ms: LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active. - =0 means to use VBIOS default delay which is 0 ( 0ms ). - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. - -ucLVDSPwrOffBLONtoVARY_BL_in4Ms: LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off. - =0 means to use VBIOS default delay which is 0 ( 0ms ). - This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable. - -ulNbpStateMemclkFreq[4]: system memory clock frequncey in unit of 10Khz in different NB pstate. - -**********************************************************************************************************************/ - -/**************************************************************************/ -// This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design -//Memory SS Info Table -//Define Memory Clock SS chip ID -#define ICS91719 1 -#define ICS91720 2 - -//Define one structure to inform SW a "block of data" writing to external SS chip via I2C protocol -typedef struct _ATOM_I2C_DATA_RECORD -{ - UCHAR ucNunberOfBytes; //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop" - UCHAR ucI2CData[1]; //I2C data in bytes, should be less than 16 bytes usually -}ATOM_I2C_DATA_RECORD; - - -//Define one structure to inform SW how many blocks of data writing to external SS chip via I2C protocol, in addition to other information -typedef struct _ATOM_I2C_DEVICE_SETUP_INFO -{ - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; //I2C line and HW/SW assisted cap. - UCHAR ucSSChipID; //SS chip being used - UCHAR ucSSChipSlaveAddr; //Slave Address to set up this SS chip - UCHAR ucNumOfI2CDataRecords; //number of data block - ATOM_I2C_DATA_RECORD asI2CData[1]; -}ATOM_I2C_DEVICE_SETUP_INFO; - -//========================================================================================== -typedef struct _ATOM_ASIC_MVDD_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[1]; -}ATOM_ASIC_MVDD_INFO; - -//========================================================================================== -#define ATOM_MCLK_SS_INFO ATOM_ASIC_MVDD_INFO - -//========================================================================================== -/**************************************************************************/ - -typedef struct _ATOM_ASIC_SS_ASSIGNMENT -{ - ULONG ulTargetClockRange; //Clock Out frequence (VCO ), in unit of 10Khz - USHORT usSpreadSpectrumPercentage; //in unit of 0.01% - USHORT usSpreadRateInKhz; //in unit of kHz, modulation freq - UCHAR ucClockIndication; //Indicate which clock source needs SS - UCHAR ucSpreadSpectrumMode; //Bit1=0 Down Spread,=1 Center Spread. - UCHAR ucReserved[2]; -}ATOM_ASIC_SS_ASSIGNMENT; - -//Define ucClockIndication, SW uses the IDs below to search if the SS is required/enabled on a clock branch/signal type. -//SS is not required or enabled if a match is not found. -#define ASIC_INTERNAL_MEMORY_SS 1 -#define ASIC_INTERNAL_ENGINE_SS 2 -#define ASIC_INTERNAL_UVD_SS 3 -#define ASIC_INTERNAL_SS_ON_TMDS 4 -#define ASIC_INTERNAL_SS_ON_HDMI 5 -#define ASIC_INTERNAL_SS_ON_LVDS 6 -#define ASIC_INTERNAL_SS_ON_DP 7 -#define ASIC_INTERNAL_SS_ON_DCPLL 8 -#define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9 -#define ASIC_INTERNAL_VCE_SS 10 - -typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2 -{ - ULONG ulTargetClockRange; //For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz - //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 ) - USHORT usSpreadSpectrumPercentage; //in unit of 0.01% - USHORT usSpreadRateIn10Hz; //in unit of 10Hz, modulation freq - UCHAR ucClockIndication; //Indicate which clock source needs SS - UCHAR ucSpreadSpectrumMode; //Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS - UCHAR ucReserved[2]; -}ATOM_ASIC_SS_ASSIGNMENT_V2; - -//ucSpreadSpectrumMode -//#define ATOM_SS_DOWN_SPREAD_MODE_MASK 0x00000000 -//#define ATOM_SS_DOWN_SPREAD_MODE 0x00000000 -//#define ATOM_SS_CENTRE_SPREAD_MODE_MASK 0x00000001 -//#define ATOM_SS_CENTRE_SPREAD_MODE 0x00000001 -//#define ATOM_INTERNAL_SS_MASK 0x00000000 -//#define ATOM_EXTERNAL_SS_MASK 0x00000002 - -typedef struct _ATOM_ASIC_INTERNAL_SS_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_ASIC_SS_ASSIGNMENT asSpreadSpectrum[4]; -}ATOM_ASIC_INTERNAL_SS_INFO; - -typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_ASIC_SS_ASSIGNMENT_V2 asSpreadSpectrum[1]; //this is point only. -}ATOM_ASIC_INTERNAL_SS_INFO_V2; - -typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3 -{ - ULONG ulTargetClockRange; //For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz - //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 ) - USHORT usSpreadSpectrumPercentage; //in unit of 0.01% - USHORT usSpreadRateIn10Hz; //in unit of 10Hz, modulation freq - UCHAR ucClockIndication; //Indicate which clock source needs SS - UCHAR ucSpreadSpectrumMode; //Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS - UCHAR ucReserved[2]; -}ATOM_ASIC_SS_ASSIGNMENT_V3; - -typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_ASIC_SS_ASSIGNMENT_V3 asSpreadSpectrum[1]; //this is pointer only. -}ATOM_ASIC_INTERNAL_SS_INFO_V3; - - -//==============================Scratch Pad Definition Portion=============================== -#define ATOM_DEVICE_CONNECT_INFO_DEF 0 -#define ATOM_ROM_LOCATION_DEF 1 -#define ATOM_TV_STANDARD_DEF 2 -#define ATOM_ACTIVE_INFO_DEF 3 -#define ATOM_LCD_INFO_DEF 4 -#define ATOM_DOS_REQ_INFO_DEF 5 -#define ATOM_ACC_CHANGE_INFO_DEF 6 -#define ATOM_DOS_MODE_INFO_DEF 7 -#define ATOM_I2C_CHANNEL_STATUS_DEF 8 -#define ATOM_I2C_CHANNEL_STATUS1_DEF 9 -#define ATOM_INTERNAL_TIMER_DEF 10 - -// BIOS_0_SCRATCH Definition -#define ATOM_S0_CRT1_MONO 0x00000001L -#define ATOM_S0_CRT1_COLOR 0x00000002L -#define ATOM_S0_CRT1_MASK (ATOM_S0_CRT1_MONO+ATOM_S0_CRT1_COLOR) - -#define ATOM_S0_TV1_COMPOSITE_A 0x00000004L -#define ATOM_S0_TV1_SVIDEO_A 0x00000008L -#define ATOM_S0_TV1_MASK_A (ATOM_S0_TV1_COMPOSITE_A+ATOM_S0_TV1_SVIDEO_A) - -#define ATOM_S0_CV_A 0x00000010L -#define ATOM_S0_CV_DIN_A 0x00000020L -#define ATOM_S0_CV_MASK_A (ATOM_S0_CV_A+ATOM_S0_CV_DIN_A) - - -#define ATOM_S0_CRT2_MONO 0x00000100L -#define ATOM_S0_CRT2_COLOR 0x00000200L -#define ATOM_S0_CRT2_MASK (ATOM_S0_CRT2_MONO+ATOM_S0_CRT2_COLOR) - -#define ATOM_S0_TV1_COMPOSITE 0x00000400L -#define ATOM_S0_TV1_SVIDEO 0x00000800L -#define ATOM_S0_TV1_SCART 0x00004000L -#define ATOM_S0_TV1_MASK (ATOM_S0_TV1_COMPOSITE+ATOM_S0_TV1_SVIDEO+ATOM_S0_TV1_SCART) - -#define ATOM_S0_CV 0x00001000L -#define ATOM_S0_CV_DIN 0x00002000L -#define ATOM_S0_CV_MASK (ATOM_S0_CV+ATOM_S0_CV_DIN) - -#define ATOM_S0_DFP1 0x00010000L -#define ATOM_S0_DFP2 0x00020000L -#define ATOM_S0_LCD1 0x00040000L -#define ATOM_S0_LCD2 0x00080000L -#define ATOM_S0_DFP6 0x00100000L -#define ATOM_S0_DFP3 0x00200000L -#define ATOM_S0_DFP4 0x00400000L -#define ATOM_S0_DFP5 0x00800000L - -#define ATOM_S0_DFP_MASK ATOM_S0_DFP1 | ATOM_S0_DFP2 | ATOM_S0_DFP3 | ATOM_S0_DFP4 | ATOM_S0_DFP5 | ATOM_S0_DFP6 - -#define ATOM_S0_FAD_REGISTER_BUG 0x02000000L // If set, indicates we are running a PCIE asic with - // the FAD/HDP reg access bug. Bit is read by DAL, this is obsolete from RV5xx - -#define ATOM_S0_THERMAL_STATE_MASK 0x1C000000L -#define ATOM_S0_THERMAL_STATE_SHIFT 26 - -#define ATOM_S0_SYSTEM_POWER_STATE_MASK 0xE0000000L -#define ATOM_S0_SYSTEM_POWER_STATE_SHIFT 29 - -#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC 1 -#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 -#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 -#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LIT2AC 4 - -//Byte aligned definition for BIOS usage -#define ATOM_S0_CRT1_MONOb0 0x01 -#define ATOM_S0_CRT1_COLORb0 0x02 -#define ATOM_S0_CRT1_MASKb0 (ATOM_S0_CRT1_MONOb0+ATOM_S0_CRT1_COLORb0) - -#define ATOM_S0_TV1_COMPOSITEb0 0x04 -#define ATOM_S0_TV1_SVIDEOb0 0x08 -#define ATOM_S0_TV1_MASKb0 (ATOM_S0_TV1_COMPOSITEb0+ATOM_S0_TV1_SVIDEOb0) - -#define ATOM_S0_CVb0 0x10 -#define ATOM_S0_CV_DINb0 0x20 -#define ATOM_S0_CV_MASKb0 (ATOM_S0_CVb0+ATOM_S0_CV_DINb0) - -#define ATOM_S0_CRT2_MONOb1 0x01 -#define ATOM_S0_CRT2_COLORb1 0x02 -#define ATOM_S0_CRT2_MASKb1 (ATOM_S0_CRT2_MONOb1+ATOM_S0_CRT2_COLORb1) - -#define ATOM_S0_TV1_COMPOSITEb1 0x04 -#define ATOM_S0_TV1_SVIDEOb1 0x08 -#define ATOM_S0_TV1_SCARTb1 0x40 -#define ATOM_S0_TV1_MASKb1 (ATOM_S0_TV1_COMPOSITEb1+ATOM_S0_TV1_SVIDEOb1+ATOM_S0_TV1_SCARTb1) - -#define ATOM_S0_CVb1 0x10 -#define ATOM_S0_CV_DINb1 0x20 -#define ATOM_S0_CV_MASKb1 (ATOM_S0_CVb1+ATOM_S0_CV_DINb1) - -#define ATOM_S0_DFP1b2 0x01 -#define ATOM_S0_DFP2b2 0x02 -#define ATOM_S0_LCD1b2 0x04 -#define ATOM_S0_LCD2b2 0x08 -#define ATOM_S0_DFP6b2 0x10 -#define ATOM_S0_DFP3b2 0x20 -#define ATOM_S0_DFP4b2 0x40 -#define ATOM_S0_DFP5b2 0x80 - - -#define ATOM_S0_THERMAL_STATE_MASKb3 0x1C -#define ATOM_S0_THERMAL_STATE_SHIFTb3 2 - -#define ATOM_S0_SYSTEM_POWER_STATE_MASKb3 0xE0 -#define ATOM_S0_LCD1_SHIFT 18 - -// BIOS_1_SCRATCH Definition -#define ATOM_S1_ROM_LOCATION_MASK 0x0000FFFFL -#define ATOM_S1_PCI_BUS_DEV_MASK 0xFFFF0000L - -// BIOS_2_SCRATCH Definition -#define ATOM_S2_TV1_STANDARD_MASK 0x0000000FL -#define ATOM_S2_CURRENT_BL_LEVEL_MASK 0x0000FF00L -#define ATOM_S2_CURRENT_BL_LEVEL_SHIFT 8 - -#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK 0x0C000000L -#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASK_SHIFT 26 -#define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGE 0x10000000L - -#define ATOM_S2_DEVICE_DPMS_STATE 0x00010000L -#define ATOM_S2_VRI_BRIGHT_ENABLE 0x20000000L - -#define ATOM_S2_DISPLAY_ROTATION_0_DEGREE 0x0 -#define ATOM_S2_DISPLAY_ROTATION_90_DEGREE 0x1 -#define ATOM_S2_DISPLAY_ROTATION_180_DEGREE 0x2 -#define ATOM_S2_DISPLAY_ROTATION_270_DEGREE 0x3 -#define ATOM_S2_DISPLAY_ROTATION_DEGREE_SHIFT 30 -#define ATOM_S2_DISPLAY_ROTATION_ANGLE_MASK 0xC0000000L - - -//Byte aligned definition for BIOS usage -#define ATOM_S2_TV1_STANDARD_MASKb0 0x0F -#define ATOM_S2_CURRENT_BL_LEVEL_MASKb1 0xFF -#define ATOM_S2_DEVICE_DPMS_STATEb2 0x01 - -#define ATOM_S2_DEVICE_DPMS_MASKw1 0x3FF -#define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3 0x0C -#define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGEb3 0x10 -#define ATOM_S2_TMDS_COHERENT_MODEb3 0x10 // used by VBIOS code only, use coherent mode for TMDS/HDMI mode -#define ATOM_S2_VRI_BRIGHT_ENABLEb3 0x20 -#define ATOM_S2_ROTATION_STATE_MASKb3 0xC0 - - -// BIOS_3_SCRATCH Definition -#define ATOM_S3_CRT1_ACTIVE 0x00000001L -#define ATOM_S3_LCD1_ACTIVE 0x00000002L -#define ATOM_S3_TV1_ACTIVE 0x00000004L -#define ATOM_S3_DFP1_ACTIVE 0x00000008L -#define ATOM_S3_CRT2_ACTIVE 0x00000010L -#define ATOM_S3_LCD2_ACTIVE 0x00000020L -#define ATOM_S3_DFP6_ACTIVE 0x00000040L -#define ATOM_S3_DFP2_ACTIVE 0x00000080L -#define ATOM_S3_CV_ACTIVE 0x00000100L -#define ATOM_S3_DFP3_ACTIVE 0x00000200L -#define ATOM_S3_DFP4_ACTIVE 0x00000400L -#define ATOM_S3_DFP5_ACTIVE 0x00000800L - -#define ATOM_S3_DEVICE_ACTIVE_MASK 0x00000FFFL - -#define ATOM_S3_LCD_FULLEXPANSION_ACTIVE 0x00001000L -#define ATOM_S3_LCD_EXPANSION_ASPEC_RATIO_ACTIVE 0x00002000L - -#define ATOM_S3_CRT1_CRTC_ACTIVE 0x00010000L -#define ATOM_S3_LCD1_CRTC_ACTIVE 0x00020000L -#define ATOM_S3_TV1_CRTC_ACTIVE 0x00040000L -#define ATOM_S3_DFP1_CRTC_ACTIVE 0x00080000L -#define ATOM_S3_CRT2_CRTC_ACTIVE 0x00100000L -#define ATOM_S3_LCD2_CRTC_ACTIVE 0x00200000L -#define ATOM_S3_DFP6_CRTC_ACTIVE 0x00400000L -#define ATOM_S3_DFP2_CRTC_ACTIVE 0x00800000L -#define ATOM_S3_CV_CRTC_ACTIVE 0x01000000L -#define ATOM_S3_DFP3_CRTC_ACTIVE 0x02000000L -#define ATOM_S3_DFP4_CRTC_ACTIVE 0x04000000L -#define ATOM_S3_DFP5_CRTC_ACTIVE 0x08000000L - -#define ATOM_S3_DEVICE_CRTC_ACTIVE_MASK 0x0FFF0000L -#define ATOM_S3_ASIC_GUI_ENGINE_HUNG 0x20000000L -//Below two definitions are not supported in pplib, but in the old powerplay in DAL -#define ATOM_S3_ALLOW_FAST_PWR_SWITCH 0x40000000L -#define ATOM_S3_RQST_GPU_USE_MIN_PWR 0x80000000L - -//Byte aligned definition for BIOS usage -#define ATOM_S3_CRT1_ACTIVEb0 0x01 -#define ATOM_S3_LCD1_ACTIVEb0 0x02 -#define ATOM_S3_TV1_ACTIVEb0 0x04 -#define ATOM_S3_DFP1_ACTIVEb0 0x08 -#define ATOM_S3_CRT2_ACTIVEb0 0x10 -#define ATOM_S3_LCD2_ACTIVEb0 0x20 -#define ATOM_S3_DFP6_ACTIVEb0 0x40 -#define ATOM_S3_DFP2_ACTIVEb0 0x80 -#define ATOM_S3_CV_ACTIVEb1 0x01 -#define ATOM_S3_DFP3_ACTIVEb1 0x02 -#define ATOM_S3_DFP4_ACTIVEb1 0x04 -#define ATOM_S3_DFP5_ACTIVEb1 0x08 - -#define ATOM_S3_ACTIVE_CRTC1w0 0xFFF - -#define ATOM_S3_CRT1_CRTC_ACTIVEb2 0x01 -#define ATOM_S3_LCD1_CRTC_ACTIVEb2 0x02 -#define ATOM_S3_TV1_CRTC_ACTIVEb2 0x04 -#define ATOM_S3_DFP1_CRTC_ACTIVEb2 0x08 -#define ATOM_S3_CRT2_CRTC_ACTIVEb2 0x10 -#define ATOM_S3_LCD2_CRTC_ACTIVEb2 0x20 -#define ATOM_S3_DFP6_CRTC_ACTIVEb2 0x40 -#define ATOM_S3_DFP2_CRTC_ACTIVEb2 0x80 -#define ATOM_S3_CV_CRTC_ACTIVEb3 0x01 -#define ATOM_S3_DFP3_CRTC_ACTIVEb3 0x02 -#define ATOM_S3_DFP4_CRTC_ACTIVEb3 0x04 -#define ATOM_S3_DFP5_CRTC_ACTIVEb3 0x08 - -#define ATOM_S3_ACTIVE_CRTC2w1 0xFFF - -// BIOS_4_SCRATCH Definition -#define ATOM_S4_LCD1_PANEL_ID_MASK 0x000000FFL -#define ATOM_S4_LCD1_REFRESH_MASK 0x0000FF00L -#define ATOM_S4_LCD1_REFRESH_SHIFT 8 - -//Byte aligned definition for BIOS usage -#define ATOM_S4_LCD1_PANEL_ID_MASKb0 0x0FF -#define ATOM_S4_LCD1_REFRESH_MASKb1 ATOM_S4_LCD1_PANEL_ID_MASKb0 -#define ATOM_S4_VRAM_INFO_MASKb2 ATOM_S4_LCD1_PANEL_ID_MASKb0 - -// BIOS_5_SCRATCH Definition, BIOS_5_SCRATCH is used by Firmware only !!!! -#define ATOM_S5_DOS_REQ_CRT1b0 0x01 -#define ATOM_S5_DOS_REQ_LCD1b0 0x02 -#define ATOM_S5_DOS_REQ_TV1b0 0x04 -#define ATOM_S5_DOS_REQ_DFP1b0 0x08 -#define ATOM_S5_DOS_REQ_CRT2b0 0x10 -#define ATOM_S5_DOS_REQ_LCD2b0 0x20 -#define ATOM_S5_DOS_REQ_DFP6b0 0x40 -#define ATOM_S5_DOS_REQ_DFP2b0 0x80 -#define ATOM_S5_DOS_REQ_CVb1 0x01 -#define ATOM_S5_DOS_REQ_DFP3b1 0x02 -#define ATOM_S5_DOS_REQ_DFP4b1 0x04 -#define ATOM_S5_DOS_REQ_DFP5b1 0x08 - -#define ATOM_S5_DOS_REQ_DEVICEw0 0x0FFF - -#define ATOM_S5_DOS_REQ_CRT1 0x0001 -#define ATOM_S5_DOS_REQ_LCD1 0x0002 -#define ATOM_S5_DOS_REQ_TV1 0x0004 -#define ATOM_S5_DOS_REQ_DFP1 0x0008 -#define ATOM_S5_DOS_REQ_CRT2 0x0010 -#define ATOM_S5_DOS_REQ_LCD2 0x0020 -#define ATOM_S5_DOS_REQ_DFP6 0x0040 -#define ATOM_S5_DOS_REQ_DFP2 0x0080 -#define ATOM_S5_DOS_REQ_CV 0x0100 -#define ATOM_S5_DOS_REQ_DFP3 0x0200 -#define ATOM_S5_DOS_REQ_DFP4 0x0400 -#define ATOM_S5_DOS_REQ_DFP5 0x0800 - -#define ATOM_S5_DOS_FORCE_CRT1b2 ATOM_S5_DOS_REQ_CRT1b0 -#define ATOM_S5_DOS_FORCE_TV1b2 ATOM_S5_DOS_REQ_TV1b0 -#define ATOM_S5_DOS_FORCE_CRT2b2 ATOM_S5_DOS_REQ_CRT2b0 -#define ATOM_S5_DOS_FORCE_CVb3 ATOM_S5_DOS_REQ_CVb1 -#define ATOM_S5_DOS_FORCE_DEVICEw1 (ATOM_S5_DOS_FORCE_CRT1b2+ATOM_S5_DOS_FORCE_TV1b2+ATOM_S5_DOS_FORCE_CRT2b2+\ - (ATOM_S5_DOS_FORCE_CVb3<<8)) - -// BIOS_6_SCRATCH Definition -#define ATOM_S6_DEVICE_CHANGE 0x00000001L -#define ATOM_S6_SCALER_CHANGE 0x00000002L -#define ATOM_S6_LID_CHANGE 0x00000004L -#define ATOM_S6_DOCKING_CHANGE 0x00000008L -#define ATOM_S6_ACC_MODE 0x00000010L -#define ATOM_S6_EXT_DESKTOP_MODE 0x00000020L -#define ATOM_S6_LID_STATE 0x00000040L -#define ATOM_S6_DOCK_STATE 0x00000080L -#define ATOM_S6_CRITICAL_STATE 0x00000100L -#define ATOM_S6_HW_I2C_BUSY_STATE 0x00000200L -#define ATOM_S6_THERMAL_STATE_CHANGE 0x00000400L -#define ATOM_S6_INTERRUPT_SET_BY_BIOS 0x00000800L -#define ATOM_S6_REQ_LCD_EXPANSION_FULL 0x00001000L //Normal expansion Request bit for LCD -#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO 0x00002000L //Aspect ratio expansion Request bit for LCD - -#define ATOM_S6_DISPLAY_STATE_CHANGE 0x00004000L //This bit is recycled when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_H_expansion -#define ATOM_S6_I2C_STATE_CHANGE 0x00008000L //This bit is recycled,when ATOM_BIOS_INFO_BIOS_SCRATCH6_SCL2_REDEFINE is set,previously it's SCL2_V_expansion - -#define ATOM_S6_ACC_REQ_CRT1 0x00010000L -#define ATOM_S6_ACC_REQ_LCD1 0x00020000L -#define ATOM_S6_ACC_REQ_TV1 0x00040000L -#define ATOM_S6_ACC_REQ_DFP1 0x00080000L -#define ATOM_S6_ACC_REQ_CRT2 0x00100000L -#define ATOM_S6_ACC_REQ_LCD2 0x00200000L -#define ATOM_S6_ACC_REQ_DFP6 0x00400000L -#define ATOM_S6_ACC_REQ_DFP2 0x00800000L -#define ATOM_S6_ACC_REQ_CV 0x01000000L -#define ATOM_S6_ACC_REQ_DFP3 0x02000000L -#define ATOM_S6_ACC_REQ_DFP4 0x04000000L -#define ATOM_S6_ACC_REQ_DFP5 0x08000000L - -#define ATOM_S6_ACC_REQ_MASK 0x0FFF0000L -#define ATOM_S6_SYSTEM_POWER_MODE_CHANGE 0x10000000L -#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH 0x20000000L -#define ATOM_S6_VRI_BRIGHTNESS_CHANGE 0x40000000L -#define ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK 0x80000000L - -//Byte aligned definition for BIOS usage -#define ATOM_S6_DEVICE_CHANGEb0 0x01 -#define ATOM_S6_SCALER_CHANGEb0 0x02 -#define ATOM_S6_LID_CHANGEb0 0x04 -#define ATOM_S6_DOCKING_CHANGEb0 0x08 -#define ATOM_S6_ACC_MODEb0 0x10 -#define ATOM_S6_EXT_DESKTOP_MODEb0 0x20 -#define ATOM_S6_LID_STATEb0 0x40 -#define ATOM_S6_DOCK_STATEb0 0x80 -#define ATOM_S6_CRITICAL_STATEb1 0x01 -#define ATOM_S6_HW_I2C_BUSY_STATEb1 0x02 -#define ATOM_S6_THERMAL_STATE_CHANGEb1 0x04 -#define ATOM_S6_INTERRUPT_SET_BY_BIOSb1 0x08 -#define ATOM_S6_REQ_LCD_EXPANSION_FULLb1 0x10 -#define ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIOb1 0x20 - -#define ATOM_S6_ACC_REQ_CRT1b2 0x01 -#define ATOM_S6_ACC_REQ_LCD1b2 0x02 -#define ATOM_S6_ACC_REQ_TV1b2 0x04 -#define ATOM_S6_ACC_REQ_DFP1b2 0x08 -#define ATOM_S6_ACC_REQ_CRT2b2 0x10 -#define ATOM_S6_ACC_REQ_LCD2b2 0x20 -#define ATOM_S6_ACC_REQ_DFP6b2 0x40 -#define ATOM_S6_ACC_REQ_DFP2b2 0x80 -#define ATOM_S6_ACC_REQ_CVb3 0x01 -#define ATOM_S6_ACC_REQ_DFP3b3 0x02 -#define ATOM_S6_ACC_REQ_DFP4b3 0x04 -#define ATOM_S6_ACC_REQ_DFP5b3 0x08 - -#define ATOM_S6_ACC_REQ_DEVICEw1 ATOM_S5_DOS_REQ_DEVICEw0 -#define ATOM_S6_SYSTEM_POWER_MODE_CHANGEb3 0x10 -#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCHb3 0x20 -#define ATOM_S6_VRI_BRIGHTNESS_CHANGEb3 0x40 -#define ATOM_S6_CONFIG_DISPLAY_CHANGEb3 0x80 - -#define ATOM_S6_DEVICE_CHANGE_SHIFT 0 -#define ATOM_S6_SCALER_CHANGE_SHIFT 1 -#define ATOM_S6_LID_CHANGE_SHIFT 2 -#define ATOM_S6_DOCKING_CHANGE_SHIFT 3 -#define ATOM_S6_ACC_MODE_SHIFT 4 -#define ATOM_S6_EXT_DESKTOP_MODE_SHIFT 5 -#define ATOM_S6_LID_STATE_SHIFT 6 -#define ATOM_S6_DOCK_STATE_SHIFT 7 -#define ATOM_S6_CRITICAL_STATE_SHIFT 8 -#define ATOM_S6_HW_I2C_BUSY_STATE_SHIFT 9 -#define ATOM_S6_THERMAL_STATE_CHANGE_SHIFT 10 -#define ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT 11 -#define ATOM_S6_REQ_SCALER_SHIFT 12 -#define ATOM_S6_REQ_SCALER_ARATIO_SHIFT 13 -#define ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT 14 -#define ATOM_S6_I2C_STATE_CHANGE_SHIFT 15 -#define ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT 28 -#define ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH_SHIFT 29 -#define ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT 30 -#define ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT 31 - -// BIOS_7_SCRATCH Definition, BIOS_7_SCRATCH is used by Firmware only !!!! -#define ATOM_S7_DOS_MODE_TYPEb0 0x03 -#define ATOM_S7_DOS_MODE_VGAb0 0x00 -#define ATOM_S7_DOS_MODE_VESAb0 0x01 -#define ATOM_S7_DOS_MODE_EXTb0 0x02 -#define ATOM_S7_DOS_MODE_PIXEL_DEPTHb0 0x0C -#define ATOM_S7_DOS_MODE_PIXEL_FORMATb0 0xF0 -#define ATOM_S7_DOS_8BIT_DAC_ENb1 0x01 -#define ATOM_S7_DOS_MODE_NUMBERw1 0x0FFFF - -#define ATOM_S7_DOS_8BIT_DAC_EN_SHIFT 8 - -// BIOS_8_SCRATCH Definition -#define ATOM_S8_I2C_CHANNEL_BUSY_MASK 0x00000FFFF -#define ATOM_S8_I2C_HW_ENGINE_BUSY_MASK 0x0FFFF0000 - -#define ATOM_S8_I2C_CHANNEL_BUSY_SHIFT 0 -#define ATOM_S8_I2C_ENGINE_BUSY_SHIFT 16 - -// BIOS_9_SCRATCH Definition -#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_MASK -#define ATOM_S9_I2C_CHANNEL_COMPLETED_MASK 0x0000FFFF -#endif -#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_MASK -#define ATOM_S9_I2C_CHANNEL_ABORTED_MASK 0xFFFF0000 -#endif -#ifndef ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT -#define ATOM_S9_I2C_CHANNEL_COMPLETED_SHIFT 0 -#endif -#ifndef ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT -#define ATOM_S9_I2C_CHANNEL_ABORTED_SHIFT 16 -#endif - - -#define ATOM_FLAG_SET 0x20 -#define ATOM_FLAG_CLEAR 0 -#define CLEAR_ATOM_S6_ACC_MODE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_ACC_MODE_SHIFT | ATOM_FLAG_CLEAR) -#define SET_ATOM_S6_DEVICE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DEVICE_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_VRI_BRIGHTNESS_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_VRI_BRIGHTNESS_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_SCALER_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SCALER_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_LID_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_CHANGE_SHIFT | ATOM_FLAG_SET) - -#define SET_ATOM_S6_LID_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_LID_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_LID_STATE_SHIFT | ATOM_FLAG_CLEAR) - -#define SET_ATOM_S6_DOCK_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCKING_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_DOCK_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_DOCK_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DOCK_STATE_SHIFT | ATOM_FLAG_CLEAR) - -#define SET_ATOM_S6_THERMAL_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_THERMAL_STATE_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_SYSTEM_POWER_MODE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_SYSTEM_POWER_MODE_CHANGE_SHIFT | ATOM_FLAG_SET) -#define SET_ATOM_S6_INTERRUPT_SET_BY_BIOS ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_INTERRUPT_SET_BY_BIOS_SHIFT | ATOM_FLAG_SET) - -#define SET_ATOM_S6_CRITICAL_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_CRITICAL_STATE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CRITICAL_STATE_SHIFT | ATOM_FLAG_CLEAR) - -#define SET_ATOM_S6_REQ_SCALER ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S6_REQ_SCALER ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_SHIFT | ATOM_FLAG_CLEAR ) - -#define SET_ATOM_S6_REQ_SCALER_ARATIO ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_SET ) -#define CLEAR_ATOM_S6_REQ_SCALER_ARATIO ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_REQ_SCALER_ARATIO_SHIFT | ATOM_FLAG_CLEAR ) - -#define SET_ATOM_S6_I2C_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_I2C_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) - -#define SET_ATOM_S6_DISPLAY_STATE_CHANGE ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_DISPLAY_STATE_CHANGE_SHIFT | ATOM_FLAG_SET ) - -#define SET_ATOM_S6_DEVICE_RECONFIG ((ATOM_ACC_CHANGE_INFO_DEF << 8 )|ATOM_S6_CONFIG_DISPLAY_CHANGE_SHIFT | ATOM_FLAG_SET) -#define CLEAR_ATOM_S0_LCD1 ((ATOM_DEVICE_CONNECT_INFO_DEF << 8 )| ATOM_S0_LCD1_SHIFT | ATOM_FLAG_CLEAR ) -#define SET_ATOM_S7_DOS_8BIT_DAC_EN ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_SET ) -#define CLEAR_ATOM_S7_DOS_8BIT_DAC_EN ((ATOM_DOS_MODE_INFO_DEF << 8 )|ATOM_S7_DOS_8BIT_DAC_EN_SHIFT | ATOM_FLAG_CLEAR ) - -/****************************************************************************/ -//Portion II: Definitinos only used in Driver -/****************************************************************************/ - -// Macros used by driver -#ifdef __cplusplus -#define GetIndexIntoMasterTable(MasterOrData, FieldName) ((reinterpret_cast(&(static_cast(0))->FieldName)-static_cast(0))/sizeof(USHORT)) - -#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) (((static_cast(TABLE_HEADER_OFFSET))->ucTableFormatRevision )&0x3F) -#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) (((static_cast(TABLE_HEADER_OFFSET))->ucTableContentRevision)&0x3F) -#else // not __cplusplus -#define GetIndexIntoMasterTable(MasterOrData, FieldName) (((char*)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*)0)->FieldName)-(char*)0)/sizeof(USHORT)) - -#define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableFormatRevision)&0x3F) -#define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableContentRevision)&0x3F) -#endif // __cplusplus - -#define GET_DATA_TABLE_MAJOR_REVISION GET_COMMAND_TABLE_COMMANDSET_REVISION -#define GET_DATA_TABLE_MINOR_REVISION GET_COMMAND_TABLE_PARAMETER_REVISION - -/****************************************************************************/ -//Portion III: Definitinos only used in VBIOS -/****************************************************************************/ -#define ATOM_DAC_SRC 0x80 -#define ATOM_SRC_DAC1 0 -#define ATOM_SRC_DAC2 0x80 - -typedef struct _MEMORY_PLLINIT_PARAMETERS -{ - ULONG ulTargetMemoryClock; //In 10Khz unit - UCHAR ucAction; //not define yet - UCHAR ucFbDiv_Hi; //Fbdiv Hi byte - UCHAR ucFbDiv; //FB value - UCHAR ucPostDiv; //Post div -}MEMORY_PLLINIT_PARAMETERS; - -#define MEMORY_PLLINIT_PS_ALLOCATION MEMORY_PLLINIT_PARAMETERS - - -#define GPIO_PIN_WRITE 0x01 -#define GPIO_PIN_READ 0x00 - -typedef struct _GPIO_PIN_CONTROL_PARAMETERS -{ - UCHAR ucGPIO_ID; //return value, read from GPIO pins - UCHAR ucGPIOBitShift; //define which bit in uGPIOBitVal need to be update - UCHAR ucGPIOBitVal; //Set/Reset corresponding bit defined in ucGPIOBitMask - UCHAR ucAction; //=GPIO_PIN_WRITE: Read; =GPIO_PIN_READ: Write -}GPIO_PIN_CONTROL_PARAMETERS; - -typedef struct _ENABLE_SCALER_PARAMETERS -{ - UCHAR ucScaler; // ATOM_SCALER1, ATOM_SCALER2 - UCHAR ucEnable; // ATOM_SCALER_DISABLE or ATOM_SCALER_CENTER or ATOM_SCALER_EXPANSION - UCHAR ucTVStandard; // - UCHAR ucPadding[1]; -}ENABLE_SCALER_PARAMETERS; -#define ENABLE_SCALER_PS_ALLOCATION ENABLE_SCALER_PARAMETERS - -//ucEnable: -#define SCALER_BYPASS_AUTO_CENTER_NO_REPLICATION 0 -#define SCALER_BYPASS_AUTO_CENTER_AUTO_REPLICATION 1 -#define SCALER_ENABLE_2TAP_ALPHA_MODE 2 -#define SCALER_ENABLE_MULTITAP_MODE 3 - -typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS -{ - ULONG usHWIconHorzVertPosn; // Hardware Icon Vertical position - UCHAR ucHWIconVertOffset; // Hardware Icon Vertical offset - UCHAR ucHWIconHorzOffset; // Hardware Icon Horizontal offset - UCHAR ucSelection; // ATOM_CURSOR1 or ATOM_ICON1 or ATOM_CURSOR2 or ATOM_ICON2 - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE -}ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS; - -typedef struct _ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION -{ - ENABLE_HARDWARE_ICON_CURSOR_PARAMETERS sEnableIcon; - ENABLE_CRTC_PARAMETERS sReserved; -}ENABLE_HARDWARE_ICON_CURSOR_PS_ALLOCATION; - -typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS -{ - USHORT usHight; // Image Hight - USHORT usWidth; // Image Width - UCHAR ucSurface; // Surface 1 or 2 - UCHAR ucPadding[3]; -}ENABLE_GRAPH_SURFACE_PARAMETERS; - -typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2 -{ - USHORT usHight; // Image Hight - USHORT usWidth; // Image Width - UCHAR ucSurface; // Surface 1 or 2 - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucPadding[2]; -}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_2; - -typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3 -{ - USHORT usHight; // Image Hight - USHORT usWidth; // Image Width - UCHAR ucSurface; // Surface 1 or 2 - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - USHORT usDeviceId; // Active Device Id for this surface. If no device, set to 0. -}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3; - -typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_4 -{ - USHORT usHight; // Image Hight - USHORT usWidth; // Image Width - USHORT usGraphPitch; - UCHAR ucColorDepth; - UCHAR ucPixelFormat; - UCHAR ucSurface; // Surface 1 or 2 - UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE - UCHAR ucModeType; - UCHAR ucReserved; -}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_4; - -// ucEnable -#define ATOM_GRAPH_CONTROL_SET_PITCH 0x0f -#define ATOM_GRAPH_CONTROL_SET_DISP_START 0x10 - -typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION -{ - ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface; - ENABLE_YUV_PS_ALLOCATION sReserved; // Don't set this one -}ENABLE_GRAPH_SURFACE_PS_ALLOCATION; - -typedef struct _MEMORY_CLEAN_UP_PARAMETERS -{ - USHORT usMemoryStart; //in 8Kb boundary, offset from memory base address - USHORT usMemorySize; //8Kb blocks aligned -}MEMORY_CLEAN_UP_PARAMETERS; -#define MEMORY_CLEAN_UP_PS_ALLOCATION MEMORY_CLEAN_UP_PARAMETERS - -typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS -{ - USHORT usX_Size; //When use as input parameter, usX_Size indicates which CRTC - USHORT usY_Size; -}GET_DISPLAY_SURFACE_SIZE_PARAMETERS; - -typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS_V2 -{ - union{ - USHORT usX_Size; //When use as input parameter, usX_Size indicates which CRTC - USHORT usSurface; - }; - USHORT usY_Size; - USHORT usDispXStart; - USHORT usDispYStart; -}GET_DISPLAY_SURFACE_SIZE_PARAMETERS_V2; - - -typedef struct _PALETTE_DATA_CONTROL_PARAMETERS_V3 -{ - UCHAR ucLutId; - UCHAR ucAction; - USHORT usLutStartIndex; - USHORT usLutLength; - USHORT usLutOffsetInVram; -}PALETTE_DATA_CONTROL_PARAMETERS_V3; - -// ucAction: -#define PALETTE_DATA_AUTO_FILL 1 -#define PALETTE_DATA_READ 2 -#define PALETTE_DATA_WRITE 3 - - -typedef struct _INTERRUPT_SERVICE_PARAMETERS_V2 -{ - UCHAR ucInterruptId; - UCHAR ucServiceId; - UCHAR ucStatus; - UCHAR ucReserved; -}INTERRUPT_SERVICE_PARAMETER_V2; - -// ucInterruptId -#define HDP1_INTERRUPT_ID 1 -#define HDP2_INTERRUPT_ID 2 -#define HDP3_INTERRUPT_ID 3 -#define HDP4_INTERRUPT_ID 4 -#define HDP5_INTERRUPT_ID 5 -#define HDP6_INTERRUPT_ID 6 -#define SW_INTERRUPT_ID 11 - -// ucAction -#define INTERRUPT_SERVICE_GEN_SW_INT 1 -#define INTERRUPT_SERVICE_GET_STATUS 2 - - // ucStatus -#define INTERRUPT_STATUS__INT_TRIGGER 1 -#define INTERRUPT_STATUS__HPD_HIGH 2 - -typedef struct _INDIRECT_IO_ACCESS -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR IOAccessSequence[256]; -} INDIRECT_IO_ACCESS; - -#define INDIRECT_READ 0x00 -#define INDIRECT_WRITE 0x80 - -#define INDIRECT_IO_MM 0 -#define INDIRECT_IO_PLL 1 -#define INDIRECT_IO_MC 2 -#define INDIRECT_IO_PCIE 3 -#define INDIRECT_IO_PCIEP 4 -#define INDIRECT_IO_NBMISC 5 - -#define INDIRECT_IO_PLL_READ INDIRECT_IO_PLL | INDIRECT_READ -#define INDIRECT_IO_PLL_WRITE INDIRECT_IO_PLL | INDIRECT_WRITE -#define INDIRECT_IO_MC_READ INDIRECT_IO_MC | INDIRECT_READ -#define INDIRECT_IO_MC_WRITE INDIRECT_IO_MC | INDIRECT_WRITE -#define INDIRECT_IO_PCIE_READ INDIRECT_IO_PCIE | INDIRECT_READ -#define INDIRECT_IO_PCIE_WRITE INDIRECT_IO_PCIE | INDIRECT_WRITE -#define INDIRECT_IO_PCIEP_READ INDIRECT_IO_PCIEP | INDIRECT_READ -#define INDIRECT_IO_PCIEP_WRITE INDIRECT_IO_PCIEP | INDIRECT_WRITE -#define INDIRECT_IO_NBMISC_READ INDIRECT_IO_NBMISC | INDIRECT_READ -#define INDIRECT_IO_NBMISC_WRITE INDIRECT_IO_NBMISC | INDIRECT_WRITE - -typedef struct _ATOM_OEM_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; -}ATOM_OEM_INFO; - -typedef struct _ATOM_TV_MODE -{ - UCHAR ucVMode_Num; //Video mode number - UCHAR ucTV_Mode_Num; //Internal TV mode number -}ATOM_TV_MODE; - -typedef struct _ATOM_BIOS_INT_TVSTD_MODE -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usTV_Mode_LUT_Offset; // Pointer to standard to internal number conversion table - USHORT usTV_FIFO_Offset; // Pointer to FIFO entry table - USHORT usNTSC_Tbl_Offset; // Pointer to SDTV_Mode_NTSC table - USHORT usPAL_Tbl_Offset; // Pointer to SDTV_Mode_PAL table - USHORT usCV_Tbl_Offset; // Pointer to SDTV_Mode_PAL table -}ATOM_BIOS_INT_TVSTD_MODE; - - -typedef struct _ATOM_TV_MODE_SCALER_PTR -{ - USHORT ucFilter0_Offset; //Pointer to filter format 0 coefficients - USHORT usFilter1_Offset; //Pointer to filter format 0 coefficients - UCHAR ucTV_Mode_Num; -}ATOM_TV_MODE_SCALER_PTR; - -typedef struct _ATOM_STANDARD_VESA_TIMING -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_DTD_FORMAT aModeTimings[16]; // 16 is not the real array number, just for initial allocation -}ATOM_STANDARD_VESA_TIMING; - - -typedef struct _ATOM_STD_FORMAT -{ - USHORT usSTD_HDisp; - USHORT usSTD_VDisp; - USHORT usSTD_RefreshRate; - USHORT usReserved; -}ATOM_STD_FORMAT; - -typedef struct _ATOM_VESA_TO_EXTENDED_MODE -{ - USHORT usVESA_ModeNumber; - USHORT usExtendedModeNumber; -}ATOM_VESA_TO_EXTENDED_MODE; - -typedef struct _ATOM_VESA_TO_INTENAL_MODE_LUT -{ - ATOM_COMMON_TABLE_HEADER sHeader; - ATOM_VESA_TO_EXTENDED_MODE asVESA_ToExtendedModeInfo[76]; -}ATOM_VESA_TO_INTENAL_MODE_LUT; - -/*************** ATOM Memory Related Data Structure ***********************/ -typedef struct _ATOM_MEMORY_VENDOR_BLOCK{ - UCHAR ucMemoryType; - UCHAR ucMemoryVendor; - UCHAR ucAdjMCId; - UCHAR ucDynClkId; - ULONG ulDllResetClkRange; -}ATOM_MEMORY_VENDOR_BLOCK; - - -typedef struct _ATOM_MEMORY_SETTING_ID_CONFIG{ -#if ATOM_BIG_ENDIAN - ULONG ucMemBlkId:8; - ULONG ulMemClockRange:24; -#else - ULONG ulMemClockRange:24; - ULONG ucMemBlkId:8; -#endif -}ATOM_MEMORY_SETTING_ID_CONFIG; - -typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS -{ - ATOM_MEMORY_SETTING_ID_CONFIG slAccess; - ULONG ulAccess; -}ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS; - - -typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{ - ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ulMemoryID; - ULONG aulMemData[1]; -}ATOM_MEMORY_SETTING_DATA_BLOCK; - - -typedef struct _ATOM_INIT_REG_INDEX_FORMAT{ - USHORT usRegIndex; // MC register index - UCHAR ucPreRegDataLength; // offset in ATOM_INIT_REG_DATA_BLOCK.saRegDataBuf -}ATOM_INIT_REG_INDEX_FORMAT; - - -typedef struct _ATOM_INIT_REG_BLOCK{ - USHORT usRegIndexTblSize; //size of asRegIndexBuf - USHORT usRegDataBlkSize; //size of ATOM_MEMORY_SETTING_DATA_BLOCK - ATOM_INIT_REG_INDEX_FORMAT asRegIndexBuf[1]; - ATOM_MEMORY_SETTING_DATA_BLOCK asRegDataBuf[1]; -}ATOM_INIT_REG_BLOCK; - -#define END_OF_REG_INDEX_BLOCK 0x0ffff -#define END_OF_REG_DATA_BLOCK 0x00000000 -#define ATOM_INIT_REG_MASK_FLAG 0x80 //Not used in BIOS -#define CLOCK_RANGE_HIGHEST 0x00ffffff - -#define VALUE_DWORD SIZEOF ULONG -#define VALUE_SAME_AS_ABOVE 0 -#define VALUE_MASK_DWORD 0x84 - -#define INDEX_ACCESS_RANGE_BEGIN (VALUE_DWORD + 1) -#define INDEX_ACCESS_RANGE_END (INDEX_ACCESS_RANGE_BEGIN + 1) -#define VALUE_INDEX_ACCESS_SINGLE (INDEX_ACCESS_RANGE_END + 1) -//#define ACCESS_MCIODEBUGIND 0x40 //defined in BIOS code -#define ACCESS_PLACEHOLDER 0x80 - -typedef struct _ATOM_MC_INIT_PARAM_TABLE -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usAdjustARB_SEQDataOffset; - USHORT usMCInitMemTypeTblOffset; - USHORT usMCInitCommonTblOffset; - USHORT usMCInitPowerDownTblOffset; - ULONG ulARB_SEQDataBuf[32]; - ATOM_INIT_REG_BLOCK asMCInitMemType; - ATOM_INIT_REG_BLOCK asMCInitCommon; -}ATOM_MC_INIT_PARAM_TABLE; - - -#define _4Mx16 0x2 -#define _4Mx32 0x3 -#define _8Mx16 0x12 -#define _8Mx32 0x13 -#define _16Mx16 0x22 -#define _16Mx32 0x23 -#define _32Mx16 0x32 -#define _32Mx32 0x33 -#define _64Mx8 0x41 -#define _64Mx16 0x42 -#define _64Mx32 0x43 -#define _128Mx8 0x51 -#define _128Mx16 0x52 -#define _256Mx8 0x61 -#define _256Mx16 0x62 - -#define SAMSUNG 0x1 -#define INFINEON 0x2 -#define ELPIDA 0x3 -#define ETRON 0x4 -#define NANYA 0x5 -#define HYNIX 0x6 -#define MOSEL 0x7 -#define WINBOND 0x8 -#define ESMT 0x9 -#define MICRON 0xF - -#define QIMONDA INFINEON -#define PROMOS MOSEL -#define KRETON INFINEON -#define ELIXIR NANYA - -/////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// - -#define UCODE_ROM_START_ADDRESS 0x1b800 -#define UCODE_SIGNATURE 0x4375434d // 'MCuC' - MC uCode - -//uCode block header for reference - -typedef struct _MCuCodeHeader -{ - ULONG ulSignature; - UCHAR ucRevision; - UCHAR ucChecksum; - UCHAR ucReserved1; - UCHAR ucReserved2; - USHORT usParametersLength; - USHORT usUCodeLength; - USHORT usReserved1; - USHORT usReserved2; -} MCuCodeHeader; - -////////////////////////////////////////////////////////////////////////////////// - -#define ATOM_MAX_NUMBER_OF_VRAM_MODULE 16 - -#define ATOM_VRAM_MODULE_MEMORY_VENDOR_ID_MASK 0xF -typedef struct _ATOM_VRAM_MODULE_V1 -{ - ULONG ulReserved; - USHORT usEMRSValue; - USHORT usMRSValue; - USHORT usReserved; - UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module - UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] reserved; - UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender - UCHAR ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... - UCHAR ucRow; // Number of Row,in power of 2; - UCHAR ucColumn; // Number of Column,in power of 2; - UCHAR ucBank; // Nunber of Bank; - UCHAR ucRank; // Number of Rank, in power of 2 - UCHAR ucChannelNum; // Number of channel; - UCHAR ucChannelConfig; // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 - UCHAR ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; - UCHAR ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; - UCHAR ucReserved[2]; -}ATOM_VRAM_MODULE_V1; - - -typedef struct _ATOM_VRAM_MODULE_V2 -{ - ULONG ulReserved; - ULONG ulFlags; // To enable/disable functionalities based on memory type - ULONG ulEngineClock; // Override of default engine clock for particular memory type - ULONG ulMemoryClock; // Override of default memory clock for particular memory type - USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type - USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type - USHORT usEMRSValue; - USHORT usMRSValue; - USHORT usReserved; - UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module - UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; - UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed - UCHAR ucMemoryDeviceCfg; // [7:4]=0x0:4M;=0x1:8M;=0x2:16M;0x3:32M....[3:0]=0x0:x4;=0x1:x8;=0x2:x16;=0x3:x32... - UCHAR ucRow; // Number of Row,in power of 2; - UCHAR ucColumn; // Number of Column,in power of 2; - UCHAR ucBank; // Nunber of Bank; - UCHAR ucRank; // Number of Rank, in power of 2 - UCHAR ucChannelNum; // Number of channel; - UCHAR ucChannelConfig; // [3:0]=Indication of what channel combination;[4:7]=Channel bit width, in number of 2 - UCHAR ucDefaultMVDDQ_ID; // Default MVDDQ setting for this memory block, ID linking to MVDDQ info table to find real set-up data; - UCHAR ucDefaultMVDDC_ID; // Default MVDDC setting for this memory block, ID linking to MVDDC info table to find real set-up data; - UCHAR ucRefreshRateFactor; - UCHAR ucReserved[3]; -}ATOM_VRAM_MODULE_V2; - - -typedef struct _ATOM_MEMORY_TIMING_FORMAT -{ - ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing - union{ - USHORT usMRS; // mode register - USHORT usDDR3_MR0; - }; - union{ - USHORT usEMRS; // extended mode register - USHORT usDDR3_MR1; - }; - UCHAR ucCL; // CAS latency - UCHAR ucWL; // WRITE Latency - UCHAR uctRAS; // tRAS - UCHAR uctRC; // tRC - UCHAR uctRFC; // tRFC - UCHAR uctRCDR; // tRCDR - UCHAR uctRCDW; // tRCDW - UCHAR uctRP; // tRP - UCHAR uctRRD; // tRRD - UCHAR uctWR; // tWR - UCHAR uctWTR; // tWTR - UCHAR uctPDIX; // tPDIX - UCHAR uctFAW; // tFAW - UCHAR uctAOND; // tAOND - union - { - struct { - UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon - UCHAR ucReserved; - }; - USHORT usDDR3_MR2; - }; -}ATOM_MEMORY_TIMING_FORMAT; - - -typedef struct _ATOM_MEMORY_TIMING_FORMAT_V1 -{ - ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing - USHORT usMRS; // mode register - USHORT usEMRS; // extended mode register - UCHAR ucCL; // CAS latency - UCHAR ucWL; // WRITE Latency - UCHAR uctRAS; // tRAS - UCHAR uctRC; // tRC - UCHAR uctRFC; // tRFC - UCHAR uctRCDR; // tRCDR - UCHAR uctRCDW; // tRCDW - UCHAR uctRP; // tRP - UCHAR uctRRD; // tRRD - UCHAR uctWR; // tWR - UCHAR uctWTR; // tWTR - UCHAR uctPDIX; // tPDIX - UCHAR uctFAW; // tFAW - UCHAR uctAOND; // tAOND - UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon -////////////////////////////////////GDDR parameters/////////////////////////////////// - UCHAR uctCCDL; // - UCHAR uctCRCRL; // - UCHAR uctCRCWL; // - UCHAR uctCKE; // - UCHAR uctCKRSE; // - UCHAR uctCKRSX; // - UCHAR uctFAW32; // - UCHAR ucMR5lo; // - UCHAR ucMR5hi; // - UCHAR ucTerminator; -}ATOM_MEMORY_TIMING_FORMAT_V1; - -typedef struct _ATOM_MEMORY_TIMING_FORMAT_V2 -{ - ULONG ulClkRange; // memory clock in 10kHz unit, when target memory clock is below this clock, use this memory timing - USHORT usMRS; // mode register - USHORT usEMRS; // extended mode register - UCHAR ucCL; // CAS latency - UCHAR ucWL; // WRITE Latency - UCHAR uctRAS; // tRAS - UCHAR uctRC; // tRC - UCHAR uctRFC; // tRFC - UCHAR uctRCDR; // tRCDR - UCHAR uctRCDW; // tRCDW - UCHAR uctRP; // tRP - UCHAR uctRRD; // tRRD - UCHAR uctWR; // tWR - UCHAR uctWTR; // tWTR - UCHAR uctPDIX; // tPDIX - UCHAR uctFAW; // tFAW - UCHAR uctAOND; // tAOND - UCHAR ucflag; // flag to control memory timing calculation. bit0= control EMRS2 Infineon -////////////////////////////////////GDDR parameters/////////////////////////////////// - UCHAR uctCCDL; // - UCHAR uctCRCRL; // - UCHAR uctCRCWL; // - UCHAR uctCKE; // - UCHAR uctCKRSE; // - UCHAR uctCKRSX; // - UCHAR uctFAW32; // - UCHAR ucMR4lo; // - UCHAR ucMR4hi; // - UCHAR ucMR5lo; // - UCHAR ucMR5hi; // - UCHAR ucTerminator; - UCHAR ucReserved; -}ATOM_MEMORY_TIMING_FORMAT_V2; - -typedef struct _ATOM_MEMORY_FORMAT -{ - ULONG ulDllDisClock; // memory DLL will be disable when target memory clock is below this clock - union{ - USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type - USHORT usDDR3_Reserved; // Not used for DDR3 memory - }; - union{ - USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type - USHORT usDDR3_MR3; // Used for DDR3 memory - }; - UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4;[3:0] - must not be used for now; - UCHAR ucMemoryVenderID; // Predefined,never change across designs or memory type/vender. If not predefined, vendor detection table gets executed - UCHAR ucRow; // Number of Row,in power of 2; - UCHAR ucColumn; // Number of Column,in power of 2; - UCHAR ucBank; // Nunber of Bank; - UCHAR ucRank; // Number of Rank, in power of 2 - UCHAR ucBurstSize; // burst size, 0= burst size=4 1= burst size=8 - UCHAR ucDllDisBit; // position of DLL Enable/Disable bit in EMRS ( Extended Mode Register ) - UCHAR ucRefreshRateFactor; // memory refresh rate in unit of ms - UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 - UCHAR ucPreamble; //[7:4] Write Preamble, [3:0] Read Preamble - UCHAR ucMemAttrib; // Memory Device Addribute, like RDBI/WDBI etc - ATOM_MEMORY_TIMING_FORMAT asMemTiming[5]; //Memory Timing block sort from lower clock to higher clock -}ATOM_MEMORY_FORMAT; - - -typedef struct _ATOM_VRAM_MODULE_V3 -{ - ULONG ulChannelMapCfg; // board dependent paramenter:Channel combination - USHORT usSize; // size of ATOM_VRAM_MODULE_V3 - USHORT usDefaultMVDDQ; // board dependent parameter:Default Memory Core Voltage - USHORT usDefaultMVDDC; // board dependent parameter:Default Memory IO Voltage - UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module - UCHAR ucChannelNum; // board dependent parameter:Number of channel; - UCHAR ucChannelSize; // board dependent parameter:32bit or 64bit - UCHAR ucVREFI; // board dependnt parameter: EXT or INT +160mv to -140mv - UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters - UCHAR ucFlag; // To enable/disable functionalities based on memory type - ATOM_MEMORY_FORMAT asMemory; // describ all of video memory parameters from memory spec -}ATOM_VRAM_MODULE_V3; - - -//ATOM_VRAM_MODULE_V3.ucNPL_RT -#define NPL_RT_MASK 0x0f -#define BATTERY_ODT_MASK 0xc0 - -#define ATOM_VRAM_MODULE ATOM_VRAM_MODULE_V3 - -typedef struct _ATOM_VRAM_MODULE_V4 -{ - ULONG ulChannelMapCfg; // board dependent parameter: Channel combination - USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE - USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! - // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) - USHORT usReserved; - UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module - UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; - UCHAR ucChannelNum; // Number of channels present in this module config - UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits - UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 - UCHAR ucFlag; // To enable/disable functionalities based on memory type - UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 - UCHAR ucVREFI; // board dependent parameter - UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters - UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble - UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! - // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros - UCHAR ucReserved[3]; - -//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level - union{ - USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type - USHORT usDDR3_Reserved; - }; - union{ - USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type - USHORT usDDR3_MR3; // Used for DDR3 memory - }; - UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed - UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) - UCHAR ucReserved2[2]; - ATOM_MEMORY_TIMING_FORMAT asMemTiming[5];//Memory Timing block sort from lower clock to higher clock -}ATOM_VRAM_MODULE_V4; - -#define VRAM_MODULE_V4_MISC_RANK_MASK 0x3 -#define VRAM_MODULE_V4_MISC_DUAL_RANK 0x1 -#define VRAM_MODULE_V4_MISC_BL_MASK 0x4 -#define VRAM_MODULE_V4_MISC_BL8 0x4 -#define VRAM_MODULE_V4_MISC_DUAL_CS 0x10 - -typedef struct _ATOM_VRAM_MODULE_V5 -{ - ULONG ulChannelMapCfg; // board dependent parameter: Channel combination - USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE - USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! - // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) - USHORT usReserved; - UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module - UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; - UCHAR ucChannelNum; // Number of channels present in this module config - UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits - UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 - UCHAR ucFlag; // To enable/disable functionalities based on memory type - UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 - UCHAR ucVREFI; // board dependent parameter - UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters - UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble - UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! - // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros - UCHAR ucReserved[3]; - -//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level - USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type - USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type - UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed - UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) - UCHAR ucFIFODepth; // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth - UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth - ATOM_MEMORY_TIMING_FORMAT_V1 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock -}ATOM_VRAM_MODULE_V5; - -typedef struct _ATOM_VRAM_MODULE_V6 -{ - ULONG ulChannelMapCfg; // board dependent parameter: Channel combination - USHORT usModuleSize; // size of ATOM_VRAM_MODULE_V4, make it easy for VBIOS to look for next entry of VRAM_MODULE - USHORT usPrivateReserved; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! - // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) - USHORT usReserved; - UCHAR ucExtMemoryID; // An external indicator (by hardcode, callback or pin) to tell what is the current memory module - UCHAR ucMemoryType; // [7:4]=0x1:DDR1;=0x2:DDR2;=0x3:DDR3;=0x4:DDR4; 0x5:DDR5 [3:0] - Must be 0x0 for now; - UCHAR ucChannelNum; // Number of channels present in this module config - UCHAR ucChannelWidth; // 0 - 32 bits; 1 - 64 bits - UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 - UCHAR ucFlag; // To enable/disable functionalities based on memory type - UCHAR ucMisc; // bit0: 0 - single rank; 1 - dual rank; bit2: 0 - burstlength 4, 1 - burstlength 8 - UCHAR ucVREFI; // board dependent parameter - UCHAR ucNPL_RT; // board dependent parameter:NPL round trip delay, used for calculate memory timing parameters - UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble - UCHAR ucMemorySize; // BIOS internal reserved space to optimize code size, updated by the compiler, shouldn't be modified manually!! - // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros - UCHAR ucReserved[3]; - -//compare with V3, we flat the struct by merging ATOM_MEMORY_FORMAT (as is) into V4 as the same level - USHORT usEMRS2Value; // EMRS2 Value is used for GDDR2 and GDDR4 memory type - USHORT usEMRS3Value; // EMRS3 Value is used for GDDR2 and GDDR4 memory type - UCHAR ucMemoryVenderID; // Predefined, If not predefined, vendor detection table gets executed - UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) - UCHAR ucFIFODepth; // FIFO depth supposes to be detected during vendor detection, but if we dont do vendor detection we have to hardcode FIFO Depth - UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth - ATOM_MEMORY_TIMING_FORMAT_V2 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock -}ATOM_VRAM_MODULE_V6; - -typedef struct _ATOM_VRAM_MODULE_V7 -{ -// Design Specific Values - ULONG ulChannelMapCfg; // mmMC_SHARED_CHREMAP - USHORT usModuleSize; // Size of ATOM_VRAM_MODULE_V7 - USHORT usPrivateReserved; // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) - USHORT usEnableChannels; // bit vector which indicate which channels are enabled - UCHAR ucExtMemoryID; // Current memory module ID - UCHAR ucMemoryType; // MEM_TYPE_DDR2/DDR3/GDDR3/GDDR5 - UCHAR ucChannelNum; // Number of mem. channels supported in this module - UCHAR ucChannelWidth; // CHANNEL_16BIT/CHANNEL_32BIT/CHANNEL_64BIT - UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 - UCHAR ucReserve; // Former container for Mx_FLAGS like DBI_AC_MODE_ENABLE_ASIC for GDDR4. Not used now. - UCHAR ucMisc; // RANK_OF_THISMEMORY etc. - UCHAR ucVREFI; // Not used. - UCHAR ucNPL_RT; // Round trip delay (MC_SEQ_CAS_TIMING [28:24]:TCL=CL+NPL_RT-2). Always 2. - UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble - UCHAR ucMemorySize; // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros - USHORT usSEQSettingOffset; - UCHAR ucReserved; -// Memory Module specific values - USHORT usEMRS2Value; // EMRS2/MR2 Value. - USHORT usEMRS3Value; // EMRS3/MR3 Value. - UCHAR ucMemoryVenderID; // [7:4] Revision, [3:0] Vendor code - UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) - UCHAR ucFIFODepth; // FIFO depth can be detected during vendor detection, here is hardcoded per memory - UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth - char strMemPNString[20]; // part number end with '0'. -}ATOM_VRAM_MODULE_V7; - -typedef struct _ATOM_VRAM_INFO_V2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucNumOfVRAMModule; - ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; -}ATOM_VRAM_INFO_V2; - -typedef struct _ATOM_VRAM_INFO_V3 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting - USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting - USHORT usRerseved; - UCHAR aVID_PinsShift[9]; // 8 bit strap maximum+terminator - UCHAR ucNumOfVRAMModule; - ATOM_VRAM_MODULE aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; - ATOM_INIT_REG_BLOCK asMemPatch; // for allocation - // ATOM_INIT_REG_BLOCK aMemAdjust; -}ATOM_VRAM_INFO_V3; - -#define ATOM_VRAM_INFO_LAST ATOM_VRAM_INFO_V3 - -typedef struct _ATOM_VRAM_INFO_V4 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting - USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting - USHORT usRerseved; - UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3 - ULONG ulMemDQ7_0BitRemap; // each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21] - UCHAR ucReservde[4]; - UCHAR ucNumOfVRAMModule; - ATOM_VRAM_MODULE_V4 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; - ATOM_INIT_REG_BLOCK asMemPatch; // for allocation - // ATOM_INIT_REG_BLOCK aMemAdjust; -}ATOM_VRAM_INFO_V4; - -typedef struct _ATOM_VRAM_INFO_HEADER_V2_1 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting - USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting - USHORT usPerBytePresetOffset; // offset of ATOM_INIT_REG_BLOCK structure for Per Byte Offset Preset Settings - USHORT usReserved[3]; - UCHAR ucNumOfVRAMModule; // indicate number of VRAM module - UCHAR ucMemoryClkPatchTblVer; // version of memory AC timing register list - UCHAR ucVramModuleVer; // indicate ATOM_VRAM_MODUE version - UCHAR ucReserved; - ATOM_VRAM_MODULE_V7 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; -}ATOM_VRAM_INFO_HEADER_V2_1; - - -typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR aVID_PinsShift[9]; //8 bit strap maximum+terminator -}ATOM_VRAM_GPIO_DETECTION_INFO; - - -typedef struct _ATOM_MEMORY_TRAINING_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucTrainingLoop; - UCHAR ucReserved[3]; - ATOM_INIT_REG_BLOCK asMemTrainingSetting; -}ATOM_MEMORY_TRAINING_INFO; - - -typedef struct SW_I2C_CNTL_DATA_PARAMETERS -{ - UCHAR ucControl; - UCHAR ucData; - UCHAR ucSatus; - UCHAR ucTemp; -} SW_I2C_CNTL_DATA_PARAMETERS; - -#define SW_I2C_CNTL_DATA_PS_ALLOCATION SW_I2C_CNTL_DATA_PARAMETERS - -typedef struct _SW_I2C_IO_DATA_PARAMETERS -{ - USHORT GPIO_Info; - UCHAR ucAct; - UCHAR ucData; - } SW_I2C_IO_DATA_PARAMETERS; - -#define SW_I2C_IO_DATA_PS_ALLOCATION SW_I2C_IO_DATA_PARAMETERS - -/****************************SW I2C CNTL DEFINITIONS**********************/ -#define SW_I2C_IO_RESET 0 -#define SW_I2C_IO_GET 1 -#define SW_I2C_IO_DRIVE 2 -#define SW_I2C_IO_SET 3 -#define SW_I2C_IO_START 4 - -#define SW_I2C_IO_CLOCK 0 -#define SW_I2C_IO_DATA 0x80 - -#define SW_I2C_IO_ZERO 0 -#define SW_I2C_IO_ONE 0x100 - -#define SW_I2C_CNTL_READ 0 -#define SW_I2C_CNTL_WRITE 1 -#define SW_I2C_CNTL_START 2 -#define SW_I2C_CNTL_STOP 3 -#define SW_I2C_CNTL_OPEN 4 -#define SW_I2C_CNTL_CLOSE 5 -#define SW_I2C_CNTL_WRITE1BIT 6 - -//==============================VESA definition Portion=============================== -#define VESA_OEM_PRODUCT_REV "01.00" -#define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support -#define VESA_MODE_WIN_ATTRIBUTE 7 -#define VESA_WIN_SIZE 64 - -typedef struct _PTR_32_BIT_STRUCTURE -{ - USHORT Offset16; - USHORT Segment16; -} PTR_32_BIT_STRUCTURE; - -typedef union _PTR_32_BIT_UNION -{ - PTR_32_BIT_STRUCTURE SegmentOffset; - ULONG Ptr32_Bit; -} PTR_32_BIT_UNION; - -typedef struct _VBE_1_2_INFO_BLOCK_UPDATABLE -{ - UCHAR VbeSignature[4]; - USHORT VbeVersion; - PTR_32_BIT_UNION OemStringPtr; - UCHAR Capabilities[4]; - PTR_32_BIT_UNION VideoModePtr; - USHORT TotalMemory; -} VBE_1_2_INFO_BLOCK_UPDATABLE; - - -typedef struct _VBE_2_0_INFO_BLOCK_UPDATABLE -{ - VBE_1_2_INFO_BLOCK_UPDATABLE CommonBlock; - USHORT OemSoftRev; - PTR_32_BIT_UNION OemVendorNamePtr; - PTR_32_BIT_UNION OemProductNamePtr; - PTR_32_BIT_UNION OemProductRevPtr; -} VBE_2_0_INFO_BLOCK_UPDATABLE; - -typedef union _VBE_VERSION_UNION -{ - VBE_2_0_INFO_BLOCK_UPDATABLE VBE_2_0_InfoBlock; - VBE_1_2_INFO_BLOCK_UPDATABLE VBE_1_2_InfoBlock; -} VBE_VERSION_UNION; - -typedef struct _VBE_INFO_BLOCK -{ - VBE_VERSION_UNION UpdatableVBE_Info; - UCHAR Reserved[222]; - UCHAR OemData[256]; -} VBE_INFO_BLOCK; - -typedef struct _VBE_FP_INFO -{ - USHORT HSize; - USHORT VSize; - USHORT FPType; - UCHAR RedBPP; - UCHAR GreenBPP; - UCHAR BlueBPP; - UCHAR ReservedBPP; - ULONG RsvdOffScrnMemSize; - ULONG RsvdOffScrnMEmPtr; - UCHAR Reserved[14]; -} VBE_FP_INFO; - -typedef struct _VESA_MODE_INFO_BLOCK -{ -// Mandatory information for all VBE revisions - USHORT ModeAttributes; // dw ? ; mode attributes - UCHAR WinAAttributes; // db ? ; window A attributes - UCHAR WinBAttributes; // db ? ; window B attributes - USHORT WinGranularity; // dw ? ; window granularity - USHORT WinSize; // dw ? ; window size - USHORT WinASegment; // dw ? ; window A start segment - USHORT WinBSegment; // dw ? ; window B start segment - ULONG WinFuncPtr; // dd ? ; real mode pointer to window function - USHORT BytesPerScanLine;// dw ? ; bytes per scan line - -//; Mandatory information for VBE 1.2 and above - USHORT XResolution; // dw ? ; horizontal resolution in pixels or characters - USHORT YResolution; // dw ? ; vertical resolution in pixels or characters - UCHAR XCharSize; // db ? ; character cell width in pixels - UCHAR YCharSize; // db ? ; character cell height in pixels - UCHAR NumberOfPlanes; // db ? ; number of memory planes - UCHAR BitsPerPixel; // db ? ; bits per pixel - UCHAR NumberOfBanks; // db ? ; number of banks - UCHAR MemoryModel; // db ? ; memory model type - UCHAR BankSize; // db ? ; bank size in KB - UCHAR NumberOfImagePages;// db ? ; number of images - UCHAR ReservedForPageFunction;//db 1 ; reserved for page function - -//; Direct Color fields(required for direct/6 and YUV/7 memory models) - UCHAR RedMaskSize; // db ? ; size of direct color red mask in bits - UCHAR RedFieldPosition; // db ? ; bit position of lsb of red mask - UCHAR GreenMaskSize; // db ? ; size of direct color green mask in bits - UCHAR GreenFieldPosition; // db ? ; bit position of lsb of green mask - UCHAR BlueMaskSize; // db ? ; size of direct color blue mask in bits - UCHAR BlueFieldPosition; // db ? ; bit position of lsb of blue mask - UCHAR RsvdMaskSize; // db ? ; size of direct color reserved mask in bits - UCHAR RsvdFieldPosition; // db ? ; bit position of lsb of reserved mask - UCHAR DirectColorModeInfo;// db ? ; direct color mode attributes - -//; Mandatory information for VBE 2.0 and above - ULONG PhysBasePtr; // dd ? ; physical address for flat memory frame buffer - ULONG Reserved_1; // dd 0 ; reserved - always set to 0 - USHORT Reserved_2; // dw 0 ; reserved - always set to 0 - -//; Mandatory information for VBE 3.0 and above - USHORT LinBytesPerScanLine; // dw ? ; bytes per scan line for linear modes - UCHAR BnkNumberOfImagePages;// db ? ; number of images for banked modes - UCHAR LinNumberOfImagPages; // db ? ; number of images for linear modes - UCHAR LinRedMaskSize; // db ? ; size of direct color red mask(linear modes) - UCHAR LinRedFieldPosition; // db ? ; bit position of lsb of red mask(linear modes) - UCHAR LinGreenMaskSize; // db ? ; size of direct color green mask(linear modes) - UCHAR LinGreenFieldPosition;// db ? ; bit position of lsb of green mask(linear modes) - UCHAR LinBlueMaskSize; // db ? ; size of direct color blue mask(linear modes) - UCHAR LinBlueFieldPosition; // db ? ; bit position of lsb of blue mask(linear modes) - UCHAR LinRsvdMaskSize; // db ? ; size of direct color reserved mask(linear modes) - UCHAR LinRsvdFieldPosition; // db ? ; bit position of lsb of reserved mask(linear modes) - ULONG MaxPixelClock; // dd ? ; maximum pixel clock(in Hz) for graphics mode - UCHAR Reserved; // db 190 dup (0) -} VESA_MODE_INFO_BLOCK; - -// BIOS function CALLS -#define ATOM_BIOS_EXTENDED_FUNCTION_CODE 0xA0 // ATI Extended Function code -#define ATOM_BIOS_FUNCTION_COP_MODE 0x00 -#define ATOM_BIOS_FUNCTION_SHORT_QUERY1 0x04 -#define ATOM_BIOS_FUNCTION_SHORT_QUERY2 0x05 -#define ATOM_BIOS_FUNCTION_SHORT_QUERY3 0x06 -#define ATOM_BIOS_FUNCTION_GET_DDC 0x0B -#define ATOM_BIOS_FUNCTION_ASIC_DSTATE 0x0E -#define ATOM_BIOS_FUNCTION_DEBUG_PLAY 0x0F -#define ATOM_BIOS_FUNCTION_STV_STD 0x16 -#define ATOM_BIOS_FUNCTION_DEVICE_DET 0x17 -#define ATOM_BIOS_FUNCTION_DEVICE_SWITCH 0x18 - -#define ATOM_BIOS_FUNCTION_PANEL_CONTROL 0x82 -#define ATOM_BIOS_FUNCTION_OLD_DEVICE_DET 0x83 -#define ATOM_BIOS_FUNCTION_OLD_DEVICE_SWITCH 0x84 -#define ATOM_BIOS_FUNCTION_HW_ICON 0x8A -#define ATOM_BIOS_FUNCTION_SET_CMOS 0x8B -#define SUB_FUNCTION_UPDATE_DISPLAY_INFO 0x8000 // Sub function 80 -#define SUB_FUNCTION_UPDATE_EXPANSION_INFO 0x8100 // Sub function 80 - -#define ATOM_BIOS_FUNCTION_DISPLAY_INFO 0x8D -#define ATOM_BIOS_FUNCTION_DEVICE_ON_OFF 0x8E -#define ATOM_BIOS_FUNCTION_VIDEO_STATE 0x8F -#define ATOM_SUB_FUNCTION_GET_CRITICAL_STATE 0x0300 // Sub function 03 -#define ATOM_SUB_FUNCTION_GET_LIDSTATE 0x0700 // Sub function 7 -#define ATOM_SUB_FUNCTION_THERMAL_STATE_NOTICE 0x1400 // Notify caller the current thermal state -#define ATOM_SUB_FUNCTION_CRITICAL_STATE_NOTICE 0x8300 // Notify caller the current critical state -#define ATOM_SUB_FUNCTION_SET_LIDSTATE 0x8500 // Sub function 85 -#define ATOM_SUB_FUNCTION_GET_REQ_DISPLAY_FROM_SBIOS_MODE 0x8900// Sub function 89 -#define ATOM_SUB_FUNCTION_INFORM_ADC_SUPPORT 0x9400 // Notify caller that ADC is supported - - -#define ATOM_BIOS_FUNCTION_VESA_DPMS 0x4F10 // Set DPMS -#define ATOM_SUB_FUNCTION_SET_DPMS 0x0001 // BL: Sub function 01 -#define ATOM_SUB_FUNCTION_GET_DPMS 0x0002 // BL: Sub function 02 -#define ATOM_PARAMETER_VESA_DPMS_ON 0x0000 // BH Parameter for DPMS ON. -#define ATOM_PARAMETER_VESA_DPMS_STANDBY 0x0100 // BH Parameter for DPMS STANDBY -#define ATOM_PARAMETER_VESA_DPMS_SUSPEND 0x0200 // BH Parameter for DPMS SUSPEND -#define ATOM_PARAMETER_VESA_DPMS_OFF 0x0400 // BH Parameter for DPMS OFF -#define ATOM_PARAMETER_VESA_DPMS_REDUCE_ON 0x0800 // BH Parameter for DPMS REDUCE ON (NOT SUPPORTED) - -#define ATOM_BIOS_RETURN_CODE_MASK 0x0000FF00L -#define ATOM_BIOS_REG_HIGH_MASK 0x0000FF00L -#define ATOM_BIOS_REG_LOW_MASK 0x000000FFL - -// structure used for VBIOS only - -//DispOutInfoTable -typedef struct _ASIC_TRANSMITTER_INFO -{ - USHORT usTransmitterObjId; - USHORT usSupportDevice; - UCHAR ucTransmitterCmdTblId; - UCHAR ucConfig; - UCHAR ucEncoderID; //available 1st encoder ( default ) - UCHAR ucOptionEncoderID; //available 2nd encoder ( optional ) - UCHAR uc2ndEncoderID; - UCHAR ucReserved; -}ASIC_TRANSMITTER_INFO; - -#define ASIC_TRANSMITTER_INFO_CONFIG__DVO_SDR_MODE 0x01 -#define ASIC_TRANSMITTER_INFO_CONFIG__COHERENT_MODE 0x02 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODEROBJ_ID_MASK 0xc4 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_A 0x00 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_B 0x04 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_C 0x40 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_D 0x44 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_E 0x80 -#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_F 0x84 - -typedef struct _ASIC_ENCODER_INFO -{ - UCHAR ucEncoderID; - UCHAR ucEncoderConfig; - USHORT usEncoderCmdTblId; -}ASIC_ENCODER_INFO; - -typedef struct _ATOM_DISP_OUT_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT ptrTransmitterInfo; - USHORT ptrEncoderInfo; - ASIC_TRANSMITTER_INFO asTransmitterInfo[1]; - ASIC_ENCODER_INFO asEncoderInfo[1]; -}ATOM_DISP_OUT_INFO; - -typedef struct _ATOM_DISP_OUT_INFO_V2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT ptrTransmitterInfo; - USHORT ptrEncoderInfo; - USHORT ptrMainCallParserFar; // direct address of main parser call in VBIOS binary. - ASIC_TRANSMITTER_INFO asTransmitterInfo[1]; - ASIC_ENCODER_INFO asEncoderInfo[1]; -}ATOM_DISP_OUT_INFO_V2; - - -typedef struct _ATOM_DISP_CLOCK_ID { - UCHAR ucPpllId; - UCHAR ucPpllAttribute; -}ATOM_DISP_CLOCK_ID; - -// ucPpllAttribute -#define CLOCK_SOURCE_SHAREABLE 0x01 -#define CLOCK_SOURCE_DP_MODE 0x02 -#define CLOCK_SOURCE_NONE_DP_MODE 0x04 - -//DispOutInfoTable -typedef struct _ASIC_TRANSMITTER_INFO_V2 -{ - USHORT usTransmitterObjId; - USHORT usDispClkIdOffset; // point to clock source id list supported by Encoder Object - UCHAR ucTransmitterCmdTblId; - UCHAR ucConfig; - UCHAR ucEncoderID; // available 1st encoder ( default ) - UCHAR ucOptionEncoderID; // available 2nd encoder ( optional ) - UCHAR uc2ndEncoderID; - UCHAR ucReserved; -}ASIC_TRANSMITTER_INFO_V2; - -typedef struct _ATOM_DISP_OUT_INFO_V3 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT ptrTransmitterInfo; - USHORT ptrEncoderInfo; - USHORT ptrMainCallParserFar; // direct address of main parser call in VBIOS binary. - USHORT usReserved; - UCHAR ucDCERevision; - UCHAR ucMaxDispEngineNum; - UCHAR ucMaxActiveDispEngineNum; - UCHAR ucMaxPPLLNum; - UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE - UCHAR ucReserved[3]; - ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only -}ATOM_DISP_OUT_INFO_V3; - -typedef enum CORE_REF_CLK_SOURCE{ - CLOCK_SRC_XTALIN=0, - CLOCK_SRC_XO_IN=1, - CLOCK_SRC_XO_IN2=2, -}CORE_REF_CLK_SOURCE; - -// DispDevicePriorityInfo -typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT asDevicePriority[16]; -}ATOM_DISPLAY_DEVICE_PRIORITY_INFO; - -//ProcessAuxChannelTransactionTable -typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS -{ - USHORT lpAuxRequest; - USHORT lpDataOut; - UCHAR ucChannelID; - union - { - UCHAR ucReplyStatus; - UCHAR ucDelay; - }; - UCHAR ucDataOutLen; - UCHAR ucReserved; -}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS; - -//ProcessAuxChannelTransactionTable -typedef struct _PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 -{ - USHORT lpAuxRequest; - USHORT lpDataOut; - UCHAR ucChannelID; - union - { - UCHAR ucReplyStatus; - UCHAR ucDelay; - }; - UCHAR ucDataOutLen; - UCHAR ucHPD_ID; //=0: HPD1, =1: HPD2, =2: HPD3, =3: HPD4, =4: HPD5, =5: HPD6 -}PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2; - -#define PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS - -//GetSinkType - -typedef struct _DP_ENCODER_SERVICE_PARAMETERS -{ - USHORT ucLinkClock; - union - { - UCHAR ucConfig; // for DP training command - UCHAR ucI2cId; // use for GET_SINK_TYPE command - }; - UCHAR ucAction; - UCHAR ucStatus; - UCHAR ucLaneNum; - UCHAR ucReserved[2]; -}DP_ENCODER_SERVICE_PARAMETERS; - -// ucAction -#define ATOM_DP_ACTION_GET_SINK_TYPE 0x01 -/* obselete */ -#define ATOM_DP_ACTION_TRAINING_START 0x02 -#define ATOM_DP_ACTION_TRAINING_COMPLETE 0x03 -#define ATOM_DP_ACTION_TRAINING_PATTERN_SEL 0x04 -#define ATOM_DP_ACTION_SET_VSWING_PREEMP 0x05 -#define ATOM_DP_ACTION_GET_VSWING_PREEMP 0x06 -#define ATOM_DP_ACTION_BLANKING 0x07 - -// ucConfig -#define ATOM_DP_CONFIG_ENCODER_SEL_MASK 0x03 -#define ATOM_DP_CONFIG_DIG1_ENCODER 0x00 -#define ATOM_DP_CONFIG_DIG2_ENCODER 0x01 -#define ATOM_DP_CONFIG_EXTERNAL_ENCODER 0x02 -#define ATOM_DP_CONFIG_LINK_SEL_MASK 0x04 -#define ATOM_DP_CONFIG_LINK_A 0x00 -#define ATOM_DP_CONFIG_LINK_B 0x04 -/* /obselete */ -#define DP_ENCODER_SERVICE_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS - - -typedef struct _DP_ENCODER_SERVICE_PARAMETERS_V2 -{ - USHORT usExtEncoderObjId; // External Encoder Object Id, output parameter only, use when ucAction = DP_SERVICE_V2_ACTION_DET_EXT_CONNECTION - UCHAR ucAuxId; - UCHAR ucAction; - UCHAR ucSinkType; // Iput and Output parameters. - UCHAR ucHPDId; // Input parameter, used when ucAction = DP_SERVICE_V2_ACTION_DET_EXT_CONNECTION - UCHAR ucReserved[2]; -}DP_ENCODER_SERVICE_PARAMETERS_V2; - -typedef struct _DP_ENCODER_SERVICE_PS_ALLOCATION_V2 -{ - DP_ENCODER_SERVICE_PARAMETERS_V2 asDPServiceParam; - PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 asAuxParam; -}DP_ENCODER_SERVICE_PS_ALLOCATION_V2; - -// ucAction -#define DP_SERVICE_V2_ACTION_GET_SINK_TYPE 0x01 -#define DP_SERVICE_V2_ACTION_DET_LCD_CONNECTION 0x02 - - -// DP_TRAINING_TABLE -#define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR ATOM_DP_TRAINING_TBL_ADDR -#define DPCD_SET_SS_CNTL_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 8 ) -#define DPCD_SET_LANE_VSWING_PREEMP_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 16 ) -#define DPCD_SET_TRAINING_PATTERN0_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 24 ) -#define DPCD_SET_TRAINING_PATTERN2_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 32) -#define DPCD_GET_LINKRATE_LANENUM_SS_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 40) -#define DPCD_GET_LANE_STATUS_ADJUST_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 48) -#define DP_I2C_AUX_DDC_WRITE_START_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 60) -#define DP_I2C_AUX_DDC_WRITE_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 64) -#define DP_I2C_AUX_DDC_READ_START_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 72) -#define DP_I2C_AUX_DDC_READ_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 76) -#define DP_I2C_AUX_DDC_WRITE_END_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 80) -#define DP_I2C_AUX_DDC_READ_END_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 84) - -typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS -{ - UCHAR ucI2CSpeed; - union - { - UCHAR ucRegIndex; - UCHAR ucStatus; - }; - USHORT lpI2CDataOut; - UCHAR ucFlag; - UCHAR ucTransBytes; - UCHAR ucSlaveAddr; - UCHAR ucLineNumber; -}PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS; - -#define PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS - -//ucFlag -#define HW_I2C_WRITE 1 -#define HW_I2C_READ 0 -#define I2C_2BYTE_ADDR 0x02 - -/****************************************************************************/ -// Structures used by HW_Misc_OperationTable -/****************************************************************************/ -typedef struct _ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1 -{ - UCHAR ucCmd; // Input: To tell which action to take - UCHAR ucReserved[3]; - ULONG ulReserved; -}ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1; - -typedef struct _ATOM_HW_MISC_OPERATION_OUTPUT_PARAMETER_V1_1 -{ - UCHAR ucReturnCode; // Output: Return value base on action was taken - UCHAR ucReserved[3]; - ULONG ulReserved; -}ATOM_HW_MISC_OPERATION_OUTPUT_PARAMETER_V1_1; - -// Actions code -#define ATOM_GET_SDI_SUPPORT 0xF0 - -// Return code -#define ATOM_UNKNOWN_CMD 0 -#define ATOM_FEATURE_NOT_SUPPORTED 1 -#define ATOM_FEATURE_SUPPORTED 2 - -typedef struct _ATOM_HW_MISC_OPERATION_PS_ALLOCATION -{ - ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1 sInput_Output; - PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS sReserved; -}ATOM_HW_MISC_OPERATION_PS_ALLOCATION; - -/****************************************************************************/ - -typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2 -{ - UCHAR ucHWBlkInst; // HW block instance, 0, 1, 2, ... - UCHAR ucReserved[3]; -}SET_HWBLOCK_INSTANCE_PARAMETER_V2; - -#define HWBLKINST_INSTANCE_MASK 0x07 -#define HWBLKINST_HWBLK_MASK 0xF0 -#define HWBLKINST_HWBLK_SHIFT 0x04 - -//ucHWBlock -#define SELECT_DISP_ENGINE 0 -#define SELECT_DISP_PLL 1 -#define SELECT_DCIO_UNIPHY_LINK0 2 -#define SELECT_DCIO_UNIPHY_LINK1 3 -#define SELECT_DCIO_IMPCAL 4 -#define SELECT_DCIO_DIG 6 -#define SELECT_CRTC_PIXEL_RATE 7 -#define SELECT_VGA_BLK 8 - -// DIGTransmitterInfoTable structure used to program UNIPHY settings -typedef struct _DIG_TRANSMITTER_INFO_HEADER_V3_1{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usDPVsPreEmphSettingOffset; // offset of PHY_ANALOG_SETTING_INFO * with DP Voltage Swing and Pre-Emphasis for each Link clock - USHORT usPhyAnalogRegListOffset; // offset of CLOCK_CONDITION_REGESTER_INFO* with None-DP mode Analog Setting's register Info - USHORT usPhyAnalogSettingOffset; // offset of CLOCK_CONDITION_SETTING_ENTRY* with None-DP mode Analog Setting for each link clock range - USHORT usPhyPllRegListOffset; // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy Pll register Info - USHORT usPhyPllSettingOffset; // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings -}DIG_TRANSMITTER_INFO_HEADER_V3_1; - -typedef struct _CLOCK_CONDITION_REGESTER_INFO{ - USHORT usRegisterIndex; - UCHAR ucStartBit; - UCHAR ucEndBit; -}CLOCK_CONDITION_REGESTER_INFO; - -typedef struct _CLOCK_CONDITION_SETTING_ENTRY{ - USHORT usMaxClockFreq; - UCHAR ucEncodeMode; - UCHAR ucPhySel; - ULONG ulAnalogSetting[1]; -}CLOCK_CONDITION_SETTING_ENTRY; - -typedef struct _CLOCK_CONDITION_SETTING_INFO{ - USHORT usEntrySize; - CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[1]; -}CLOCK_CONDITION_SETTING_INFO; - -typedef struct _PHY_CONDITION_REG_VAL{ - ULONG ulCondition; - ULONG ulRegVal; -}PHY_CONDITION_REG_VAL; - -typedef struct _PHY_CONDITION_REG_INFO{ - USHORT usRegIndex; - USHORT usSize; - PHY_CONDITION_REG_VAL asRegVal[1]; -}PHY_CONDITION_REG_INFO; - -typedef struct _PHY_ANALOG_SETTING_INFO{ - UCHAR ucEncodeMode; - UCHAR ucPhySel; - USHORT usSize; - PHY_CONDITION_REG_INFO asAnalogSetting[1]; -}PHY_ANALOG_SETTING_INFO; - -/****************************************************************************/ -//Portion VI: Definitinos for vbios MC scratch registers that driver used -/****************************************************************************/ - -#define MC_MISC0__MEMORY_TYPE_MASK 0xF0000000 -#define MC_MISC0__MEMORY_TYPE__GDDR1 0x10000000 -#define MC_MISC0__MEMORY_TYPE__DDR2 0x20000000 -#define MC_MISC0__MEMORY_TYPE__GDDR3 0x30000000 -#define MC_MISC0__MEMORY_TYPE__GDDR4 0x40000000 -#define MC_MISC0__MEMORY_TYPE__GDDR5 0x50000000 -#define MC_MISC0__MEMORY_TYPE__DDR3 0xB0000000 - -/****************************************************************************/ -//Portion VI: Definitinos being oboselete -/****************************************************************************/ - -//========================================================================================== -//Remove the definitions below when driver is ready! -typedef struct _ATOM_DAC_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMaxFrequency; // in 10kHz unit - USHORT usReserved; -}ATOM_DAC_INFO; - - -typedef struct _COMPASSIONATE_DATA -{ - ATOM_COMMON_TABLE_HEADER sHeader; - - //============================== DAC1 portion - UCHAR ucDAC1_BG_Adjustment; - UCHAR ucDAC1_DAC_Adjustment; - USHORT usDAC1_FORCE_Data; - //============================== DAC2 portion - UCHAR ucDAC2_CRT2_BG_Adjustment; - UCHAR ucDAC2_CRT2_DAC_Adjustment; - USHORT usDAC2_CRT2_FORCE_Data; - USHORT usDAC2_CRT2_MUX_RegisterIndex; - UCHAR ucDAC2_CRT2_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low - UCHAR ucDAC2_NTSC_BG_Adjustment; - UCHAR ucDAC2_NTSC_DAC_Adjustment; - USHORT usDAC2_TV1_FORCE_Data; - USHORT usDAC2_TV1_MUX_RegisterIndex; - UCHAR ucDAC2_TV1_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low - UCHAR ucDAC2_CV_BG_Adjustment; - UCHAR ucDAC2_CV_DAC_Adjustment; - USHORT usDAC2_CV_FORCE_Data; - USHORT usDAC2_CV_MUX_RegisterIndex; - UCHAR ucDAC2_CV_MUX_RegisterInfo; //Bit[4:0]=Bit position,Bit[7]=1:Active High;=0 Active Low - UCHAR ucDAC2_PAL_BG_Adjustment; - UCHAR ucDAC2_PAL_DAC_Adjustment; - USHORT usDAC2_TV2_FORCE_Data; -}COMPASSIONATE_DATA; - -/****************************Supported Device Info Table Definitions**********************/ -// ucConnectInfo: -// [7:4] - connector type -// = 1 - VGA connector -// = 2 - DVI-I -// = 3 - DVI-D -// = 4 - DVI-A -// = 5 - SVIDEO -// = 6 - COMPOSITE -// = 7 - LVDS -// = 8 - DIGITAL LINK -// = 9 - SCART -// = 0xA - HDMI_type A -// = 0xB - HDMI_type B -// = 0xE - Special case1 (DVI+DIN) -// Others=TBD -// [3:0] - DAC Associated -// = 0 - no DAC -// = 1 - DACA -// = 2 - DACB -// = 3 - External DAC -// Others=TBD -// - -typedef struct _ATOM_CONNECTOR_INFO -{ -#if ATOM_BIG_ENDIAN - UCHAR bfConnectorType:4; - UCHAR bfAssociatedDAC:4; -#else - UCHAR bfAssociatedDAC:4; - UCHAR bfConnectorType:4; -#endif -}ATOM_CONNECTOR_INFO; - -typedef union _ATOM_CONNECTOR_INFO_ACCESS -{ - ATOM_CONNECTOR_INFO sbfAccess; - UCHAR ucAccess; -}ATOM_CONNECTOR_INFO_ACCESS; - -typedef struct _ATOM_CONNECTOR_INFO_I2C -{ - ATOM_CONNECTOR_INFO_ACCESS sucConnectorInfo; - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; -}ATOM_CONNECTOR_INFO_I2C; - - -typedef struct _ATOM_SUPPORTED_DEVICES_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usDeviceSupport; - ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO]; -}ATOM_SUPPORTED_DEVICES_INFO; - -#define NO_INT_SRC_MAPPED 0xFF - -typedef struct _ATOM_CONNECTOR_INC_SRC_BITMAP -{ - UCHAR ucIntSrcBitmap; -}ATOM_CONNECTOR_INC_SRC_BITMAP; - -typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usDeviceSupport; - ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; - ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE_INFO_2]; -}ATOM_SUPPORTED_DEVICES_INFO_2; - -typedef struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usDeviceSupport; - ATOM_CONNECTOR_INFO_I2C asConnInfo[ATOM_MAX_SUPPORTED_DEVICE]; - ATOM_CONNECTOR_INC_SRC_BITMAP asIntSrcInfo[ATOM_MAX_SUPPORTED_DEVICE]; -}ATOM_SUPPORTED_DEVICES_INFO_2d1; - -#define ATOM_SUPPORTED_DEVICES_INFO_LAST ATOM_SUPPORTED_DEVICES_INFO_2d1 - - - -typedef struct _ATOM_MISC_CONTROL_INFO -{ - USHORT usFrequency; - UCHAR ucPLL_ChargePump; // PLL charge-pump gain control - UCHAR ucPLL_DutyCycle; // PLL duty cycle control - UCHAR ucPLL_VCO_Gain; // PLL VCO gain control - UCHAR ucPLL_VoltageSwing; // PLL driver voltage swing control -}ATOM_MISC_CONTROL_INFO; - - -#define ATOM_MAX_MISC_INFO 4 - -typedef struct _ATOM_TMDS_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usMaxFrequency; // in 10Khz - ATOM_MISC_CONTROL_INFO asMiscInfo[ATOM_MAX_MISC_INFO]; -}ATOM_TMDS_INFO; - - -typedef struct _ATOM_ENCODER_ANALOG_ATTRIBUTE -{ - UCHAR ucTVStandard; //Same as TV standards defined above, - UCHAR ucPadding[1]; -}ATOM_ENCODER_ANALOG_ATTRIBUTE; - -typedef struct _ATOM_ENCODER_DIGITAL_ATTRIBUTE -{ - UCHAR ucAttribute; //Same as other digital encoder attributes defined above - UCHAR ucPadding[1]; -}ATOM_ENCODER_DIGITAL_ATTRIBUTE; - -typedef union _ATOM_ENCODER_ATTRIBUTE -{ - ATOM_ENCODER_ANALOG_ATTRIBUTE sAlgAttrib; - ATOM_ENCODER_DIGITAL_ATTRIBUTE sDigAttrib; -}ATOM_ENCODER_ATTRIBUTE; - - -typedef struct _DVO_ENCODER_CONTROL_PARAMETERS -{ - USHORT usPixelClock; - USHORT usEncoderID; - UCHAR ucDeviceType; //Use ATOM_DEVICE_xxx1_Index to indicate device type only. - UCHAR ucAction; //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT - ATOM_ENCODER_ATTRIBUTE usDevAttr; -}DVO_ENCODER_CONTROL_PARAMETERS; - -typedef struct _DVO_ENCODER_CONTROL_PS_ALLOCATION -{ - DVO_ENCODER_CONTROL_PARAMETERS sDVOEncoder; - WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved; //Caller doesn't need to init this portion -}DVO_ENCODER_CONTROL_PS_ALLOCATION; - - -#define ATOM_XTMDS_ASIC_SI164_ID 1 -#define ATOM_XTMDS_ASIC_SI178_ID 2 -#define ATOM_XTMDS_ASIC_TFP513_ID 3 -#define ATOM_XTMDS_SUPPORTED_SINGLELINK 0x00000001 -#define ATOM_XTMDS_SUPPORTED_DUALLINK 0x00000002 -#define ATOM_XTMDS_MVPU_FPGA 0x00000004 - - -typedef struct _ATOM_XTMDS_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - USHORT usSingleLinkMaxFrequency; - ATOM_I2C_ID_CONFIG_ACCESS sucI2cId; //Point the ID on which I2C is used to control external chip - UCHAR ucXtransimitterID; - UCHAR ucSupportedLink; // Bit field, bit0=1, single link supported;bit1=1,dual link supported - UCHAR ucSequnceAlterID; // Even with the same external TMDS asic, it's possible that the program seqence alters - // due to design. This ID is used to alert driver that the sequence is not "standard"! - UCHAR ucMasterAddress; // Address to control Master xTMDS Chip - UCHAR ucSlaveAddress; // Address to control Slave xTMDS Chip -}ATOM_XTMDS_INFO; - -typedef struct _DFP_DPMS_STATUS_CHANGE_PARAMETERS -{ - UCHAR ucEnable; // ATOM_ENABLE=On or ATOM_DISABLE=Off - UCHAR ucDevice; // ATOM_DEVICE_DFP1_INDEX.... - UCHAR ucPadding[2]; -}DFP_DPMS_STATUS_CHANGE_PARAMETERS; - -/****************************Legacy Power Play Table Definitions **********************/ - -//Definitions for ulPowerPlayMiscInfo -#define ATOM_PM_MISCINFO_SPLIT_CLOCK 0x00000000L -#define ATOM_PM_MISCINFO_USING_MCLK_SRC 0x00000001L -#define ATOM_PM_MISCINFO_USING_SCLK_SRC 0x00000002L - -#define ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT 0x00000004L -#define ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH 0x00000008L - -#define ATOM_PM_MISCINFO_LOAD_PERFORMANCE_EN 0x00000010L - -#define ATOM_PM_MISCINFO_ENGINE_CLOCK_CONTRL_EN 0x00000020L -#define ATOM_PM_MISCINFO_MEMORY_CLOCK_CONTRL_EN 0x00000040L -#define ATOM_PM_MISCINFO_PROGRAM_VOLTAGE 0x00000080L //When this bit set, ucVoltageDropIndex is not an index for GPIO pin, but a voltage ID that SW needs program - -#define ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN 0x00000100L -#define ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN 0x00000200L -#define ATOM_PM_MISCINFO_ASIC_SLEEP_MODE_EN 0x00000400L -#define ATOM_PM_MISCINFO_LOAD_BALANCE_EN 0x00000800L -#define ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE 0x00001000L -#define ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE 0x00002000L -#define ATOM_PM_MISCINFO_LOW_LCD_REFRESH_RATE 0x00004000L - -#define ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE 0x00008000L -#define ATOM_PM_MISCINFO_OVER_CLOCK_MODE 0x00010000L -#define ATOM_PM_MISCINFO_OVER_DRIVE_MODE 0x00020000L -#define ATOM_PM_MISCINFO_POWER_SAVING_MODE 0x00040000L -#define ATOM_PM_MISCINFO_THERMAL_DIODE_MODE 0x00080000L - -#define ATOM_PM_MISCINFO_FRAME_MODULATION_MASK 0x00300000L //0-FM Disable, 1-2 level FM, 2-4 level FM, 3-Reserved -#define ATOM_PM_MISCINFO_FRAME_MODULATION_SHIFT 20 - -#define ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE 0x00400000L -#define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2 0x00800000L -#define ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4 0x01000000L -#define ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN 0x02000000L //When set, Dynamic -#define ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN 0x04000000L //When set, Dynamic -#define ATOM_PM_MISCINFO_3D_ACCELERATION_EN 0x08000000L //When set, This mode is for acceleated 3D mode - -#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_MASK 0x70000000L //1-Optimal Battery Life Group, 2-High Battery, 3-Balanced, 4-High Performance, 5- Optimal Performance (Default state with Default clocks) -#define ATOM_PM_MISCINFO_POWERPLAY_SETTINGS_GROUP_SHIFT 28 -#define ATOM_PM_MISCINFO_ENABLE_BACK_BIAS 0x80000000L - -#define ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE 0x00000001L -#define ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT 0x00000002L -#define ATOM_PM_MISCINFO2_DYNAMIC_BACK_BIAS_EN 0x00000004L -#define ATOM_PM_MISCINFO2_FS3D_OVERDRIVE_INFO 0x00000008L -#define ATOM_PM_MISCINFO2_FORCEDLOWPWR_MODE 0x00000010L -#define ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN 0x00000020L -#define ATOM_PM_MISCINFO2_VIDEO_PLAYBACK_CAPABLE 0x00000040L //If this bit is set in multi-pp mode, then driver will pack up one with the minior power consumption. - //If it's not set in any pp mode, driver will use its default logic to pick a pp mode in video playback -#define ATOM_PM_MISCINFO2_NOT_VALID_ON_DC 0x00000080L -#define ATOM_PM_MISCINFO2_STUTTER_MODE_EN 0x00000100L -#define ATOM_PM_MISCINFO2_UVD_SUPPORT_MODE 0x00000200L - -//ucTableFormatRevision=1 -//ucTableContentRevision=1 -typedef struct _ATOM_POWERMODE_INFO -{ - ULONG ulMiscInfo; //The power level should be arranged in ascending order - ULONG ulReserved1; // must set to 0 - ULONG ulReserved2; // must set to 0 - USHORT usEngineClock; - USHORT usMemoryClock; - UCHAR ucVoltageDropIndex; // index to GPIO table - UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate - UCHAR ucMinTemperature; - UCHAR ucMaxTemperature; - UCHAR ucNumPciELanes; // number of PCIE lanes -}ATOM_POWERMODE_INFO; - -//ucTableFormatRevision=2 -//ucTableContentRevision=1 -typedef struct _ATOM_POWERMODE_INFO_V2 -{ - ULONG ulMiscInfo; //The power level should be arranged in ascending order - ULONG ulMiscInfo2; - ULONG ulEngineClock; - ULONG ulMemoryClock; - UCHAR ucVoltageDropIndex; // index to GPIO table - UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate - UCHAR ucMinTemperature; - UCHAR ucMaxTemperature; - UCHAR ucNumPciELanes; // number of PCIE lanes -}ATOM_POWERMODE_INFO_V2; - -//ucTableFormatRevision=2 -//ucTableContentRevision=2 -typedef struct _ATOM_POWERMODE_INFO_V3 -{ - ULONG ulMiscInfo; //The power level should be arranged in ascending order - ULONG ulMiscInfo2; - ULONG ulEngineClock; - ULONG ulMemoryClock; - UCHAR ucVoltageDropIndex; // index to Core (VDDC) votage table - UCHAR ucSelectedPanel_RefreshRate;// panel refresh rate - UCHAR ucMinTemperature; - UCHAR ucMaxTemperature; - UCHAR ucNumPciELanes; // number of PCIE lanes - UCHAR ucVDDCI_VoltageDropIndex; // index to VDDCI votage table -}ATOM_POWERMODE_INFO_V3; - - -#define ATOM_MAX_NUMBEROF_POWER_BLOCK 8 - -#define ATOM_PP_OVERDRIVE_INTBITMAP_AUXWIN 0x01 -#define ATOM_PP_OVERDRIVE_INTBITMAP_OVERDRIVE 0x02 - -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM63 0x01 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ADM1032 0x02 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ADM1030 0x03 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_MUA6649 0x04 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_LM64 0x05 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_F75375 0x06 -#define ATOM_PP_OVERDRIVE_THERMALCONTROLLER_ASC7512 0x07 // Andigilog - - -typedef struct _ATOM_POWERPLAY_INFO -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucOverdriveThermalController; - UCHAR ucOverdriveI2cLine; - UCHAR ucOverdriveIntBitmap; - UCHAR ucOverdriveControllerAddress; - UCHAR ucSizeOfPowerModeEntry; - UCHAR ucNumOfPowerModeEntries; - ATOM_POWERMODE_INFO asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; -}ATOM_POWERPLAY_INFO; - -typedef struct _ATOM_POWERPLAY_INFO_V2 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucOverdriveThermalController; - UCHAR ucOverdriveI2cLine; - UCHAR ucOverdriveIntBitmap; - UCHAR ucOverdriveControllerAddress; - UCHAR ucSizeOfPowerModeEntry; - UCHAR ucNumOfPowerModeEntries; - ATOM_POWERMODE_INFO_V2 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; -}ATOM_POWERPLAY_INFO_V2; - -typedef struct _ATOM_POWERPLAY_INFO_V3 -{ - ATOM_COMMON_TABLE_HEADER sHeader; - UCHAR ucOverdriveThermalController; - UCHAR ucOverdriveI2cLine; - UCHAR ucOverdriveIntBitmap; - UCHAR ucOverdriveControllerAddress; - UCHAR ucSizeOfPowerModeEntry; - UCHAR ucNumOfPowerModeEntries; - ATOM_POWERMODE_INFO_V3 asPowerPlayInfo[ATOM_MAX_NUMBEROF_POWER_BLOCK]; -}ATOM_POWERPLAY_INFO_V3; - -/* New PPlib */ -/**************************************************************************/ -typedef struct _ATOM_PPLIB_THERMALCONTROLLER - -{ - UCHAR ucType; // one of ATOM_PP_THERMALCONTROLLER_* - UCHAR ucI2cLine; // as interpreted by DAL I2C - UCHAR ucI2cAddress; - UCHAR ucFanParameters; // Fan Control Parameters. - UCHAR ucFanMinRPM; // Fan Minimum RPM (hundreds) -- for display purposes only. - UCHAR ucFanMaxRPM; // Fan Maximum RPM (hundreds) -- for display purposes only. - UCHAR ucReserved; // ---- - UCHAR ucFlags; // to be defined -} ATOM_PPLIB_THERMALCONTROLLER; - -#define ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f -#define ATOM_PP_FANPARAMETERS_NOFAN 0x80 // No fan is connected to this controller. - -#define ATOM_PP_THERMALCONTROLLER_NONE 0 -#define ATOM_PP_THERMALCONTROLLER_LM63 1 // Not used by PPLib -#define ATOM_PP_THERMALCONTROLLER_ADM1032 2 // Not used by PPLib -#define ATOM_PP_THERMALCONTROLLER_ADM1030 3 // Not used by PPLib -#define ATOM_PP_THERMALCONTROLLER_MUA6649 4 // Not used by PPLib -#define ATOM_PP_THERMALCONTROLLER_LM64 5 -#define ATOM_PP_THERMALCONTROLLER_F75375 6 // Not used by PPLib -#define ATOM_PP_THERMALCONTROLLER_RV6xx 7 -#define ATOM_PP_THERMALCONTROLLER_RV770 8 -#define ATOM_PP_THERMALCONTROLLER_ADT7473 9 -#define ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO 11 -#define ATOM_PP_THERMALCONTROLLER_EVERGREEN 12 -#define ATOM_PP_THERMALCONTROLLER_EMC2103 13 /* 0x0D */ // Only fan control will be implemented, do NOT show this in PPGen. -#define ATOM_PP_THERMALCONTROLLER_SUMO 14 /* 0x0E */ // Sumo type, used internally -#define ATOM_PP_THERMALCONTROLLER_NISLANDS 15 -#define ATOM_PP_THERMALCONTROLLER_SISLANDS 16 -#define ATOM_PP_THERMALCONTROLLER_LM96163 17 - -// Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal. -// We probably should reserve the bit 0x80 for this use. -// To keep the number of these types low we should also use the same code for all ASICs (i.e. do not distinguish RV6xx and RV7xx Internal here). -// The driver can pick the correct internal controller based on the ASIC. - -#define ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL 0x89 // ADT7473 Fan Control + Internal Thermal Controller -#define ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL 0x8D // EMC2103 Fan Control + Internal Thermal Controller - -typedef struct _ATOM_PPLIB_STATE -{ - UCHAR ucNonClockStateIndex; - UCHAR ucClockStateIndices[1]; // variable-sized -} ATOM_PPLIB_STATE; - - -typedef struct _ATOM_PPLIB_FANTABLE -{ - UCHAR ucFanTableFormat; // Change this if the table format changes or version changes so that the other fields are not the same. - UCHAR ucTHyst; // Temperature hysteresis. Integer. - USHORT usTMin; // The temperature, in 0.01 centigrades, below which we just run at a minimal PWM. - USHORT usTMed; // The middle temperature where we change slopes. - USHORT usTHigh; // The high point above TMed for adjusting the second slope. - USHORT usPWMMin; // The minimum PWM value in percent (0.01% increments). - USHORT usPWMMed; // The PWM value (in percent) at TMed. - USHORT usPWMHigh; // The PWM value at THigh. -} ATOM_PPLIB_FANTABLE; - -typedef struct _ATOM_PPLIB_FANTABLE2 -{ - ATOM_PPLIB_FANTABLE basicTable; - USHORT usTMax; // The max temperature -} ATOM_PPLIB_FANTABLE2; - -typedef struct _ATOM_PPLIB_EXTENDEDHEADER -{ - USHORT usSize; - ULONG ulMaxEngineClock; // For Overdrive. - ULONG ulMaxMemoryClock; // For Overdrive. - // Add extra system parameters here, always adjust size to include all fields. - USHORT usVCETableOffset; //points to ATOM_PPLIB_VCE_Table - USHORT usUVDTableOffset; //points to ATOM_PPLIB_UVD_Table -} ATOM_PPLIB_EXTENDEDHEADER; - -//// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps -#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1 -#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2 -#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4 -#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8 -#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16 -#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32 -#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64 -#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128 -#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256 -#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512 -#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024 -#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048 -#define ATOM_PP_PLATFORM_CAP_MVDDCONTROL 4096 -#define ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT 0x2000 // Go to boot state on alerts, e.g. on an AC->DC transition. -#define ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT 0x4000 // Do NOT wait for VBLANK during an alert (e.g. AC->DC transition). -#define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000 // Does the driver control VDDCI independently from VDDC. -#define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000 // Enable the 'regulator hot' feature. -#define ATOM_PP_PLATFORM_CAP_BACO 0x00020000 // Does the driver supports BACO state. - - -typedef struct _ATOM_PPLIB_POWERPLAYTABLE -{ - ATOM_COMMON_TABLE_HEADER sHeader; - - UCHAR ucDataRevision; - - UCHAR ucNumStates; - UCHAR ucStateEntrySize; - UCHAR ucClockInfoSize; - UCHAR ucNonClockSize; - - // offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures - USHORT usStateArrayOffset; - - // offset from start of this table to array of ASIC-specific structures, - // currently ATOM_PPLIB_CLOCK_INFO. - USHORT usClockInfoArrayOffset; - - // offset from start of this table to array of ATOM_PPLIB_NONCLOCK_INFO - USHORT usNonClockInfoArrayOffset; - - USHORT usBackbiasTime; // in microseconds - USHORT usVoltageTime; // in microseconds - USHORT usTableSize; //the size of this structure, or the extended structure - - ULONG ulPlatformCaps; // See ATOM_PPLIB_CAPS_* - - ATOM_PPLIB_THERMALCONTROLLER sThermalController; - - USHORT usBootClockInfoOffset; - USHORT usBootNonClockInfoOffset; - -} ATOM_PPLIB_POWERPLAYTABLE; - -typedef struct _ATOM_PPLIB_POWERPLAYTABLE2 -{ - ATOM_PPLIB_POWERPLAYTABLE basicTable; - UCHAR ucNumCustomThermalPolicy; - USHORT usCustomThermalPolicyArrayOffset; -}ATOM_PPLIB_POWERPLAYTABLE2, *LPATOM_PPLIB_POWERPLAYTABLE2; - -typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 -{ - ATOM_PPLIB_POWERPLAYTABLE2 basicTable2; - USHORT usFormatID; // To be used ONLY by PPGen. - USHORT usFanTableOffset; - USHORT usExtendendedHeaderOffset; -} ATOM_PPLIB_POWERPLAYTABLE3, *LPATOM_PPLIB_POWERPLAYTABLE3; - -typedef struct _ATOM_PPLIB_POWERPLAYTABLE4 -{ - ATOM_PPLIB_POWERPLAYTABLE3 basicTable3; - ULONG ulGoldenPPID; // PPGen use only - ULONG ulGoldenRevision; // PPGen use only - USHORT usVddcDependencyOnSCLKOffset; - USHORT usVddciDependencyOnMCLKOffset; - USHORT usVddcDependencyOnMCLKOffset; - USHORT usMaxClockVoltageOnDCOffset; - USHORT usVddcPhaseShedLimitsTableOffset; // Points to ATOM_PPLIB_PhaseSheddingLimits_Table - USHORT usReserved; -} ATOM_PPLIB_POWERPLAYTABLE4, *LPATOM_PPLIB_POWERPLAYTABLE4; - -typedef struct _ATOM_PPLIB_POWERPLAYTABLE5 -{ - ATOM_PPLIB_POWERPLAYTABLE4 basicTable4; - ULONG ulTDPLimit; - ULONG ulNearTDPLimit; - ULONG ulSQRampingThreshold; - USHORT usCACLeakageTableOffset; // Points to ATOM_PPLIB_CAC_Leakage_Table - ULONG ulCACLeakage; // The iLeakage for driver calculated CAC leakage table - USHORT usTDPODLimit; - USHORT usLoadLineSlope; // in milliOhms * 100 -} ATOM_PPLIB_POWERPLAYTABLE5, *LPATOM_PPLIB_POWERPLAYTABLE5; - -//// ATOM_PPLIB_NONCLOCK_INFO::usClassification -#define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 -#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 -#define ATOM_PPLIB_CLASSIFICATION_UI_NONE 0 -#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 -#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 -#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 -// 2, 4, 6, 7 are reserved - -#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 -#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 -#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 -#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 -#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 -#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100 -#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200 -#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400 -#define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800 -#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 -#define ATOM_PPLIB_CLASSIFICATION_HD2STATE 0x2000 -#define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 -#define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 - -//// ATOM_PPLIB_NONCLOCK_INFO::usClassification2 -#define ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2 0x0001 -#define ATOM_PPLIB_CLASSIFICATION2_ULV 0x0002 -#define ATOM_PPLIB_CLASSIFICATION2_MVC 0x0004 //Multi-View Codec (BD-3D) - -//// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings -#define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001 -#define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002 - -// 0 is 2.5Gb/s, 1 is 5Gb/s -#define ATOM_PPLIB_PCIE_LINK_SPEED_MASK 0x00000004 -#define ATOM_PPLIB_PCIE_LINK_SPEED_SHIFT 2 - -// lanes - 1: 1, 2, 4, 8, 12, 16 permitted by PCIE spec -#define ATOM_PPLIB_PCIE_LINK_WIDTH_MASK 0x000000F8 -#define ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT 3 - -// lookup into reduced refresh-rate table -#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_MASK 0x00000F00 -#define ATOM_PPLIB_LIMITED_REFRESHRATE_VALUE_SHIFT 8 - -#define ATOM_PPLIB_LIMITED_REFRESHRATE_UNLIMITED 0 -#define ATOM_PPLIB_LIMITED_REFRESHRATE_50HZ 1 -// 2-15 TBD as needed. - -#define ATOM_PPLIB_SOFTWARE_DISABLE_LOADBALANCING 0x00001000 -#define ATOM_PPLIB_SOFTWARE_ENABLE_SLEEP_FOR_TIMESTAMPS 0x00002000 - -#define ATOM_PPLIB_DISALLOW_ON_DC 0x00004000 - -#define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000 - -//memory related flags -#define ATOM_PPLIB_SWSTATE_MEMORY_DLL_OFF 0x000010000 - -//M3 Arb //2bits, current 3 sets of parameters in total -#define ATOM_PPLIB_M3ARB_MASK 0x00060000 -#define ATOM_PPLIB_M3ARB_SHIFT 17 - -#define ATOM_PPLIB_ENABLE_DRR 0x00080000 - -// remaining 16 bits are reserved -typedef struct _ATOM_PPLIB_THERMAL_STATE -{ - UCHAR ucMinTemperature; - UCHAR ucMaxTemperature; - UCHAR ucThermalAction; -}ATOM_PPLIB_THERMAL_STATE, *LPATOM_PPLIB_THERMAL_STATE; - -// Contained in an array starting at the offset -// in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset. -// referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex -#define ATOM_PPLIB_NONCLOCKINFO_VER1 12 -#define ATOM_PPLIB_NONCLOCKINFO_VER2 24 -typedef struct _ATOM_PPLIB_NONCLOCK_INFO -{ - USHORT usClassification; - UCHAR ucMinTemperature; - UCHAR ucMaxTemperature; - ULONG ulCapsAndSettings; - UCHAR ucRequiredPower; - USHORT usClassification2; - ULONG ulVCLK; - ULONG ulDCLK; - UCHAR ucUnused[5]; -} ATOM_PPLIB_NONCLOCK_INFO; - -// Contained in an array starting at the offset -// in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset. -// referenced from ATOM_PPLIB_STATE::ucClockStateIndices -typedef struct _ATOM_PPLIB_R600_CLOCK_INFO -{ - USHORT usEngineClockLow; - UCHAR ucEngineClockHigh; - - USHORT usMemoryClockLow; - UCHAR ucMemoryClockHigh; - - USHORT usVDDC; - USHORT usUnused1; - USHORT usUnused2; - - ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_* - -} ATOM_PPLIB_R600_CLOCK_INFO; - -// ulFlags in ATOM_PPLIB_R600_CLOCK_INFO -#define ATOM_PPLIB_R600_FLAGS_PCIEGEN2 1 -#define ATOM_PPLIB_R600_FLAGS_UVDSAFE 2 -#define ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE 4 -#define ATOM_PPLIB_R600_FLAGS_MEMORY_ODT_OFF 8 -#define ATOM_PPLIB_R600_FLAGS_MEMORY_DLL_OFF 16 -#define ATOM_PPLIB_R600_FLAGS_LOWPOWER 32 // On the RV770 use 'low power' setting (sequencer S0). - -typedef struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO -{ - USHORT usEngineClockLow; - UCHAR ucEngineClockHigh; - - USHORT usMemoryClockLow; - UCHAR ucMemoryClockHigh; - - USHORT usVDDC; - USHORT usVDDCI; - USHORT usUnused; - - ULONG ulFlags; // ATOM_PPLIB_R600_FLAGS_* - -} ATOM_PPLIB_EVERGREEN_CLOCK_INFO; - -typedef struct _ATOM_PPLIB_SI_CLOCK_INFO -{ - USHORT usEngineClockLow; - UCHAR ucEngineClockHigh; - - USHORT usMemoryClockLow; - UCHAR ucMemoryClockHigh; - - USHORT usVDDC; - USHORT usVDDCI; - UCHAR ucPCIEGen; - UCHAR ucUnused1; - - ULONG ulFlags; // ATOM_PPLIB_SI_FLAGS_*, no flag is necessary for now - -} ATOM_PPLIB_SI_CLOCK_INFO; - - -typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO - -{ - USHORT usLowEngineClockLow; // Low Engine clock in MHz (the same way as on the R600). - UCHAR ucLowEngineClockHigh; - USHORT usHighEngineClockLow; // High Engine clock in MHz. - UCHAR ucHighEngineClockHigh; - USHORT usMemoryClockLow; // For now one of the ATOM_PPLIB_RS780_SPMCLK_XXXX constants. - UCHAR ucMemoryClockHigh; // Currentyl unused. - UCHAR ucPadding; // For proper alignment and size. - USHORT usVDDC; // For the 780, use: None, Low, High, Variable - UCHAR ucMaxHTLinkWidth; // From SBIOS - {2, 4, 8, 16} - UCHAR ucMinHTLinkWidth; // From SBIOS - {2, 4, 8, 16}. Effective only if CDLW enabled. Minimum down stream width could be bigger as display BW requriement. - USHORT usHTLinkFreq; // See definition ATOM_PPLIB_RS780_HTLINKFREQ_xxx or in MHz(>=200). - ULONG ulFlags; -} ATOM_PPLIB_RS780_CLOCK_INFO; - -#define ATOM_PPLIB_RS780_VOLTAGE_NONE 0 -#define ATOM_PPLIB_RS780_VOLTAGE_LOW 1 -#define ATOM_PPLIB_RS780_VOLTAGE_HIGH 2 -#define ATOM_PPLIB_RS780_VOLTAGE_VARIABLE 3 - -#define ATOM_PPLIB_RS780_SPMCLK_NONE 0 // We cannot change the side port memory clock, leave it as it is. -#define ATOM_PPLIB_RS780_SPMCLK_LOW 1 -#define ATOM_PPLIB_RS780_SPMCLK_HIGH 2 - -#define ATOM_PPLIB_RS780_HTLINKFREQ_NONE 0 -#define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 -#define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 - -typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{ - USHORT usEngineClockLow; //clockfrequency & 0xFFFF. The unit is in 10khz - UCHAR ucEngineClockHigh; //clockfrequency >> 16. - UCHAR vddcIndex; //2-bit vddc index; - USHORT tdpLimit; - //please initalize to 0 - USHORT rsv1; - //please initialize to 0s - ULONG rsv2[2]; -}ATOM_PPLIB_SUMO_CLOCK_INFO; - - - -typedef struct _ATOM_PPLIB_STATE_V2 -{ - //number of valid dpm levels in this state; Driver uses it to calculate the whole - //size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR) - UCHAR ucNumDPMLevels; - - //a index to the array of nonClockInfos - UCHAR nonClockInfoIndex; - /** - * Driver will read the first ucNumDPMLevels in this array - */ - UCHAR clockInfoIndex[1]; -} ATOM_PPLIB_STATE_V2; - -typedef struct _StateArray{ - //how many states we have - UCHAR ucNumEntries; - - ATOM_PPLIB_STATE_V2 states[1]; -}StateArray; - - -typedef struct _ClockInfoArray{ - //how many clock levels we have - UCHAR ucNumEntries; - - //sizeof(ATOM_PPLIB_CLOCK_INFO) - UCHAR ucEntrySize; - - UCHAR clockInfo[1]; -}ClockInfoArray; - -typedef struct _NonClockInfoArray{ - - //how many non-clock levels we have. normally should be same as number of states - UCHAR ucNumEntries; - //sizeof(ATOM_PPLIB_NONCLOCK_INFO) - UCHAR ucEntrySize; - - ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1]; -}NonClockInfoArray; - -typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record -{ - USHORT usClockLow; - UCHAR ucClockHigh; - USHORT usVoltage; -}ATOM_PPLIB_Clock_Voltage_Dependency_Record; - -typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table -{ - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries. -}ATOM_PPLIB_Clock_Voltage_Dependency_Table; - -typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record -{ - USHORT usSclkLow; - UCHAR ucSclkHigh; - USHORT usMclkLow; - UCHAR ucMclkHigh; - USHORT usVddc; - USHORT usVddci; -}ATOM_PPLIB_Clock_Voltage_Limit_Record; - -typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table -{ - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries. -}ATOM_PPLIB_Clock_Voltage_Limit_Table; - -typedef struct _ATOM_PPLIB_CAC_Leakage_Record -{ - USHORT usVddc; // We use this field for the "fake" standardized VDDC for power calculations - ULONG ulLeakageValue; -}ATOM_PPLIB_CAC_Leakage_Record; - -typedef struct _ATOM_PPLIB_CAC_Leakage_Table -{ - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_CAC_Leakage_Record entries[1]; // Dynamically allocate entries. -}ATOM_PPLIB_CAC_Leakage_Table; - -typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record -{ - USHORT usVoltage; - USHORT usSclkLow; - UCHAR ucSclkHigh; - USHORT usMclkLow; - UCHAR ucMclkHigh; -}ATOM_PPLIB_PhaseSheddingLimits_Record; - -typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table -{ - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_PhaseSheddingLimits_Record entries[1]; // Dynamically allocate entries. -}ATOM_PPLIB_PhaseSheddingLimits_Table; - -typedef struct _VCEClockInfo{ - USHORT usEVClkLow; - UCHAR ucEVClkHigh; - USHORT usECClkLow; - UCHAR ucECClkHigh; -}VCEClockInfo; - -typedef struct _VCEClockInfoArray{ - UCHAR ucNumEntries; - VCEClockInfo entries[1]; -}VCEClockInfoArray; - -typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record -{ - USHORT usVoltage; - UCHAR ucVCEClockInfoIndex; -}ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record; - -typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table -{ - UCHAR numEntries; - ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1]; -}ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table; - -typedef struct _ATOM_PPLIB_VCE_State_Record -{ - UCHAR ucVCEClockInfoIndex; - UCHAR ucClockInfoIndex; //highest 2 bits indicates memory p-states, lower 6bits indicates index to ClockInfoArrary -}ATOM_PPLIB_VCE_State_Record; - -typedef struct _ATOM_PPLIB_VCE_State_Table -{ - UCHAR numEntries; - ATOM_PPLIB_VCE_State_Record entries[1]; -}ATOM_PPLIB_VCE_State_Table; - - -typedef struct _ATOM_PPLIB_VCE_Table -{ - UCHAR revid; -// VCEClockInfoArray array; -// ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table limits; -// ATOM_PPLIB_VCE_State_Table states; -}ATOM_PPLIB_VCE_Table; - - -typedef struct _UVDClockInfo{ - USHORT usVClkLow; - UCHAR ucVClkHigh; - USHORT usDClkLow; - UCHAR ucDClkHigh; -}UVDClockInfo; - -typedef struct _UVDClockInfoArray{ - UCHAR ucNumEntries; - UVDClockInfo entries[1]; -}UVDClockInfoArray; - -typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record -{ - USHORT usVoltage; - UCHAR ucUVDClockInfoIndex; -}ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record; - -typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table -{ - UCHAR numEntries; - ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1]; -}ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table; - -typedef struct _ATOM_PPLIB_UVD_State_Record -{ - UCHAR ucUVDClockInfoIndex; - UCHAR ucClockInfoIndex; //highest 2 bits indicates memory p-states, lower 6bits indicates index to ClockInfoArrary -}ATOM_PPLIB_UVD_State_Record; - -typedef struct _ATOM_PPLIB_UVD_State_Table -{ - UCHAR numEntries; - ATOM_PPLIB_UVD_State_Record entries[1]; -}ATOM_PPLIB_UVD_State_Table; - - -typedef struct _ATOM_PPLIB_UVD_Table -{ - UCHAR revid; -// UVDClockInfoArray array; -// ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table limits; -// ATOM_PPLIB_UVD_State_Table states; -}ATOM_PPLIB_UVD_Table; - -/**************************************************************************/ - - -// Following definitions are for compatibility issue in different SW components. -#define ATOM_MASTER_DATA_TABLE_REVISION 0x01 -#define Object_Info Object_Header -#define AdjustARB_SEQ MC_InitParameter -#define VRAM_GPIO_DetectionInfo VoltageObjectInfo -#define ASIC_VDDCI_Info ASIC_ProfilingInfo -#define ASIC_MVDDQ_Info MemoryTrainingInfo -#define SS_Info PPLL_SS_Info -#define ASIC_MVDDC_Info ASIC_InternalSS_Info -#define DispDevicePriorityInfo SaveRestoreInfo -#define DispOutInfo TV_VideoMode - - -#define ATOM_ENCODER_OBJECT_TABLE ATOM_OBJECT_TABLE -#define ATOM_CONNECTOR_OBJECT_TABLE ATOM_OBJECT_TABLE - -//New device naming, remove them when both DAL/VBIOS is ready -#define DFP2I_OUTPUT_CONTROL_PARAMETERS CRT1_OUTPUT_CONTROL_PARAMETERS -#define DFP2I_OUTPUT_CONTROL_PS_ALLOCATION DFP2I_OUTPUT_CONTROL_PARAMETERS - -#define DFP1X_OUTPUT_CONTROL_PARAMETERS CRT1_OUTPUT_CONTROL_PARAMETERS -#define DFP1X_OUTPUT_CONTROL_PS_ALLOCATION DFP1X_OUTPUT_CONTROL_PARAMETERS - -#define DFP1I_OUTPUT_CONTROL_PARAMETERS DFP1_OUTPUT_CONTROL_PARAMETERS -#define DFP1I_OUTPUT_CONTROL_PS_ALLOCATION DFP1_OUTPUT_CONTROL_PS_ALLOCATION - -#define ATOM_DEVICE_DFP1I_SUPPORT ATOM_DEVICE_DFP1_SUPPORT -#define ATOM_DEVICE_DFP1X_SUPPORT ATOM_DEVICE_DFP2_SUPPORT - -#define ATOM_DEVICE_DFP1I_INDEX ATOM_DEVICE_DFP1_INDEX -#define ATOM_DEVICE_DFP1X_INDEX ATOM_DEVICE_DFP2_INDEX - -#define ATOM_DEVICE_DFP2I_INDEX 0x00000009 -#define ATOM_DEVICE_DFP2I_SUPPORT (0x1L << ATOM_DEVICE_DFP2I_INDEX) - -#define ATOM_S0_DFP1I ATOM_S0_DFP1 -#define ATOM_S0_DFP1X ATOM_S0_DFP2 - -#define ATOM_S0_DFP2I 0x00200000L -#define ATOM_S0_DFP2Ib2 0x20 - -#define ATOM_S2_DFP1I_DPMS_STATE ATOM_S2_DFP1_DPMS_STATE -#define ATOM_S2_DFP1X_DPMS_STATE ATOM_S2_DFP2_DPMS_STATE - -#define ATOM_S2_DFP2I_DPMS_STATE 0x02000000L -#define ATOM_S2_DFP2I_DPMS_STATEb3 0x02 - -#define ATOM_S3_DFP2I_ACTIVEb1 0x02 - -#define ATOM_S3_DFP1I_ACTIVE ATOM_S3_DFP1_ACTIVE -#define ATOM_S3_DFP1X_ACTIVE ATOM_S3_DFP2_ACTIVE - -#define ATOM_S3_DFP2I_ACTIVE 0x00000200L - -#define ATOM_S3_DFP1I_CRTC_ACTIVE ATOM_S3_DFP1_CRTC_ACTIVE -#define ATOM_S3_DFP1X_CRTC_ACTIVE ATOM_S3_DFP2_CRTC_ACTIVE -#define ATOM_S3_DFP2I_CRTC_ACTIVE 0x02000000L - -#define ATOM_S3_DFP2I_CRTC_ACTIVEb3 0x02 -#define ATOM_S5_DOS_REQ_DFP2Ib1 0x02 - -#define ATOM_S5_DOS_REQ_DFP2I 0x0200 -#define ATOM_S6_ACC_REQ_DFP1I ATOM_S6_ACC_REQ_DFP1 -#define ATOM_S6_ACC_REQ_DFP1X ATOM_S6_ACC_REQ_DFP2 - -#define ATOM_S6_ACC_REQ_DFP2Ib3 0x02 -#define ATOM_S6_ACC_REQ_DFP2I 0x02000000L - -#define TMDS1XEncoderControl DVOEncoderControl -#define DFP1XOutputControl DVOOutputControl - -#define ExternalDFPOutputControl DFP1XOutputControl -#define EnableExternalTMDS_Encoder TMDS1XEncoderControl - -#define DFP1IOutputControl TMDSAOutputControl -#define DFP2IOutputControl LVTMAOutputControl - -#define DAC1_ENCODER_CONTROL_PARAMETERS DAC_ENCODER_CONTROL_PARAMETERS -#define DAC1_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION - -#define DAC2_ENCODER_CONTROL_PARAMETERS DAC_ENCODER_CONTROL_PARAMETERS -#define DAC2_ENCODER_CONTROL_PS_ALLOCATION DAC_ENCODER_CONTROL_PS_ALLOCATION - -#define ucDac1Standard ucDacStandard -#define ucDac2Standard ucDacStandard - -#define TMDS1EncoderControl TMDSAEncoderControl -#define TMDS2EncoderControl LVTMAEncoderControl - -#define DFP1OutputControl TMDSAOutputControl -#define DFP2OutputControl LVTMAOutputControl -#define CRT1OutputControl DAC1OutputControl -#define CRT2OutputControl DAC2OutputControl - -//These two lines will be removed for sure in a few days, will follow up with Michael V. -#define EnableLVDS_SS EnableSpreadSpectrumOnPPLL -#define ENABLE_LVDS_SS_PARAMETERS_V3 ENABLE_SPREAD_SPECTRUM_ON_PPLL - -//#define ATOM_S2_CRT1_DPMS_STATE 0x00010000L -//#define ATOM_S2_LCD1_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE -//#define ATOM_S2_TV1_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE -//#define ATOM_S2_DFP1_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE -//#define ATOM_S2_CRT2_DPMS_STATE ATOM_S2_CRT1_DPMS_STATE - -#define ATOM_S6_ACC_REQ_TV2 0x00400000L -#define ATOM_DEVICE_TV2_INDEX 0x00000006 -#define ATOM_DEVICE_TV2_SUPPORT (0x1L << ATOM_DEVICE_TV2_INDEX) -#define ATOM_S0_TV2 0x00100000L -#define ATOM_S3_TV2_ACTIVE ATOM_S3_DFP6_ACTIVE -#define ATOM_S3_TV2_CRTC_ACTIVE ATOM_S3_DFP6_CRTC_ACTIVE - -// -#define ATOM_S2_CRT1_DPMS_STATE 0x00010000L -#define ATOM_S2_LCD1_DPMS_STATE 0x00020000L -#define ATOM_S2_TV1_DPMS_STATE 0x00040000L -#define ATOM_S2_DFP1_DPMS_STATE 0x00080000L -#define ATOM_S2_CRT2_DPMS_STATE 0x00100000L -#define ATOM_S2_LCD2_DPMS_STATE 0x00200000L -#define ATOM_S2_TV2_DPMS_STATE 0x00400000L -#define ATOM_S2_DFP2_DPMS_STATE 0x00800000L -#define ATOM_S2_CV_DPMS_STATE 0x01000000L -#define ATOM_S2_DFP3_DPMS_STATE 0x02000000L -#define ATOM_S2_DFP4_DPMS_STATE 0x04000000L -#define ATOM_S2_DFP5_DPMS_STATE 0x08000000L - -#define ATOM_S2_CRT1_DPMS_STATEb2 0x01 -#define ATOM_S2_LCD1_DPMS_STATEb2 0x02 -#define ATOM_S2_TV1_DPMS_STATEb2 0x04 -#define ATOM_S2_DFP1_DPMS_STATEb2 0x08 -#define ATOM_S2_CRT2_DPMS_STATEb2 0x10 -#define ATOM_S2_LCD2_DPMS_STATEb2 0x20 -#define ATOM_S2_TV2_DPMS_STATEb2 0x40 -#define ATOM_S2_DFP2_DPMS_STATEb2 0x80 -#define ATOM_S2_CV_DPMS_STATEb3 0x01 -#define ATOM_S2_DFP3_DPMS_STATEb3 0x02 -#define ATOM_S2_DFP4_DPMS_STATEb3 0x04 -#define ATOM_S2_DFP5_DPMS_STATEb3 0x08 - -#define ATOM_S3_ASIC_GUI_ENGINE_HUNGb3 0x20 -#define ATOM_S3_ALLOW_FAST_PWR_SWITCHb3 0x40 -#define ATOM_S3_RQST_GPU_USE_MIN_PWRb3 0x80 - -/*********************************************************************************/ - -#pragma pack() // BIOS data must use byte aligment - -// -// AMD ACPI Table -// -#pragma pack(1) - -typedef struct { - ULONG Signature; - ULONG TableLength; //Length - UCHAR Revision; - UCHAR Checksum; - UCHAR OemId[6]; - UCHAR OemTableId[8]; //UINT64 OemTableId; - ULONG OemRevision; - ULONG CreatorId; - ULONG CreatorRevision; -} AMD_ACPI_DESCRIPTION_HEADER; -/* -//EFI_ACPI_DESCRIPTION_HEADER from AcpiCommon.h -typedef struct { - UINT32 Signature; //0x0 - UINT32 Length; //0x4 - UINT8 Revision; //0x8 - UINT8 Checksum; //0x9 - UINT8 OemId[6]; //0xA - UINT64 OemTableId; //0x10 - UINT32 OemRevision; //0x18 - UINT32 CreatorId; //0x1C - UINT32 CreatorRevision; //0x20 -}EFI_ACPI_DESCRIPTION_HEADER; -*/ -typedef struct { - AMD_ACPI_DESCRIPTION_HEADER SHeader; - UCHAR TableUUID[16]; //0x24 - ULONG VBIOSImageOffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the stucture. - ULONG Lib1ImageOffset; //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the stucture. - ULONG Reserved[4]; //0x3C -}UEFI_ACPI_VFCT; - -typedef struct { - ULONG PCIBus; //0x4C - ULONG PCIDevice; //0x50 - ULONG PCIFunction; //0x54 - USHORT VendorID; //0x58 - USHORT DeviceID; //0x5A - USHORT SSVID; //0x5C - USHORT SSID; //0x5E - ULONG Revision; //0x60 - ULONG ImageLength; //0x64 -}VFCT_IMAGE_HEADER; - - -typedef struct { - VFCT_IMAGE_HEADER VbiosHeader; - UCHAR VbiosContent[1]; -}GOP_VBIOS_CONTENT; - -typedef struct { - VFCT_IMAGE_HEADER Lib1Header; - UCHAR Lib1Content[1]; -}GOP_LIB1_CONTENT; - -#pragma pack() - - -#endif /* _ATOMBIOS_H */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_crtc.c deleted file mode 100644 index af1054f8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_crtc.c +++ /dev/null @@ -1,1727 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include -#include -#include -#include -#include "radeon.h" -#include "atom.h" -#include "atom-bits.h" - -static void atombios_overscan_setup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - SET_CRTC_OVERSCAN_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); - int a1, a2; - - memset(&args, 0, sizeof(args)); - - args.ucCRTC = radeon_crtc->crtc_id; - - switch (radeon_crtc->rmx_type) { - case RMX_CENTER: - args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); - args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); - args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); - args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); - break; - case RMX_ASPECT: - a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; - a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; - - if (a1 > a2) { - args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); - args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); - } else if (a2 > a1) { - args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); - args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); - } - break; - case RMX_FULL: - default: - args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border); - args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border); - args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border); - args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border); - break; - } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_scaler_setup(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - ENABLE_SCALER_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); - - /* fixme - fill in enc_priv for atom dac */ - enum radeon_tv_std tv_std = TV_STD_NTSC; - bool is_tv = false, is_cv = false; - struct drm_encoder *encoder; - - if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) - return; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - /* find tv std */ - if (encoder->crtc == crtc) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { - struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; - tv_std = tv_dac->tv_std; - is_tv = true; - } - } - } - - memset(&args, 0, sizeof(args)); - - args.ucScaler = radeon_crtc->crtc_id; - - if (is_tv) { - switch (tv_std) { - case TV_STD_NTSC: - default: - args.ucTVStandard = ATOM_TV_NTSC; - break; - case TV_STD_PAL: - args.ucTVStandard = ATOM_TV_PAL; - break; - case TV_STD_PAL_M: - args.ucTVStandard = ATOM_TV_PALM; - break; - case TV_STD_PAL_60: - args.ucTVStandard = ATOM_TV_PAL60; - break; - case TV_STD_NTSC_J: - args.ucTVStandard = ATOM_TV_NTSCJ; - break; - case TV_STD_SCART_PAL: - args.ucTVStandard = ATOM_TV_PAL; /* ??? */ - break; - case TV_STD_SECAM: - args.ucTVStandard = ATOM_TV_SECAM; - break; - case TV_STD_PAL_CN: - args.ucTVStandard = ATOM_TV_PALCN; - break; - } - args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; - } else if (is_cv) { - args.ucTVStandard = ATOM_TV_CV; - args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; - } else { - switch (radeon_crtc->rmx_type) { - case RMX_FULL: - args.ucEnable = ATOM_SCALER_EXPANSION; - break; - case RMX_CENTER: - args.ucEnable = ATOM_SCALER_CENTER; - break; - case RMX_ASPECT: - args.ucEnable = ATOM_SCALER_EXPANSION; - break; - default: - if (ASIC_IS_AVIVO(rdev)) - args.ucEnable = ATOM_SCALER_DISABLE; - else - args.ucEnable = ATOM_SCALER_CENTER; - break; - } - } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if ((is_tv || is_cv) - && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) { - atom_rv515_force_tv_scaler(rdev, radeon_crtc); - } -} - -static void atombios_lock_crtc(struct drm_crtc *crtc, int lock) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int index = - GetIndexIntoMasterTable(COMMAND, UpdateCRTC_DoubleBufferRegisters); - ENABLE_CRTC_PS_ALLOCATION args; - - memset(&args, 0, sizeof(args)); - - args.ucCRTC = radeon_crtc->crtc_id; - args.ucEnable = lock; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_enable_crtc(struct drm_crtc *crtc, int state) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int index = GetIndexIntoMasterTable(COMMAND, EnableCRTC); - ENABLE_CRTC_PS_ALLOCATION args; - - memset(&args, 0, sizeof(args)); - - args.ucCRTC = radeon_crtc->crtc_id; - args.ucEnable = state; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_enable_crtc_memreq(struct drm_crtc *crtc, int state) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int index = GetIndexIntoMasterTable(COMMAND, EnableCRTCMemReq); - ENABLE_CRTC_PS_ALLOCATION args; - - memset(&args, 0, sizeof(args)); - - args.ucCRTC = radeon_crtc->crtc_id; - args.ucEnable = state; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_blank_crtc(struct drm_crtc *crtc, int state) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int index = GetIndexIntoMasterTable(COMMAND, BlankCRTC); - BLANK_CRTC_PS_ALLOCATION args; - - memset(&args, 0, sizeof(args)); - - args.ucCRTC = radeon_crtc->crtc_id; - args.ucBlanking = state; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_powergate_crtc(struct drm_crtc *crtc, int state) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating); - ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args; - - memset(&args, 0, sizeof(args)); - - args.ucDispPipeId = radeon_crtc->crtc_id; - args.ucEnable = state; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - switch (mode) { - case DRM_MODE_DPMS_ON: - radeon_crtc->enabled = true; - /* adjust pm to dpms changes BEFORE enabling crtcs */ - radeon_pm_compute_clocks(rdev); - /* disable crtc pair power gating before programming */ - if (ASIC_IS_DCE6(rdev)) - atombios_powergate_crtc(crtc, ATOM_DISABLE); - atombios_enable_crtc(crtc, ATOM_ENABLE); - if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) - atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); - atombios_blank_crtc(crtc, ATOM_DISABLE); - drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); - radeon_crtc_load_lut(crtc); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); - if (radeon_crtc->enabled) - atombios_blank_crtc(crtc, ATOM_ENABLE); - if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) - atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); - atombios_enable_crtc(crtc, ATOM_DISABLE); - radeon_crtc->enabled = false; - /* power gating is per-pair */ - if (ASIC_IS_DCE6(rdev)) { - struct drm_crtc *other_crtc; - struct radeon_crtc *other_radeon_crtc; - list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { - other_radeon_crtc = to_radeon_crtc(other_crtc); - if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || - ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || - ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || - ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || - ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || - ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { - /* if both crtcs in the pair are off, enable power gating */ - if (other_radeon_crtc->enabled == false) - atombios_powergate_crtc(crtc, ATOM_ENABLE); - break; - } - } - } - /* adjust pm to dpms changes AFTER disabling crtcs */ - radeon_pm_compute_clocks(rdev); - break; - } -} - -static void -atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - SET_CRTC_USING_DTD_TIMING_PARAMETERS args; - int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); - u16 misc = 0; - - memset(&args, 0, sizeof(args)); - args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2)); - args.usH_Blanking_Time = - cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2)); - args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2)); - args.usV_Blanking_Time = - cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2)); - args.usH_SyncOffset = - cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border); - args.usH_SyncWidth = - cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); - args.usV_SyncOffset = - cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border); - args.usV_SyncWidth = - cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); - args.ucH_Border = radeon_crtc->h_border; - args.ucV_Border = radeon_crtc->v_border; - - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - misc |= ATOM_VSYNC_POLARITY; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - misc |= ATOM_HSYNC_POLARITY; - if (mode->flags & DRM_MODE_FLAG_CSYNC) - misc |= ATOM_COMPOSITESYNC; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - misc |= ATOM_INTERLACE; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - misc |= ATOM_DOUBLE_CLOCK_MODE; - - args.susModeMiscInfo.usAccess = cpu_to_le16(misc); - args.ucCRTC = radeon_crtc->crtc_id; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_crtc_set_timing(struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); - u16 misc = 0; - - memset(&args, 0, sizeof(args)); - args.usH_Total = cpu_to_le16(mode->crtc_htotal); - args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay); - args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start); - args.usH_SyncWidth = - cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); - args.usV_Total = cpu_to_le16(mode->crtc_vtotal); - args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay); - args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start); - args.usV_SyncWidth = - cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); - - args.ucOverscanRight = radeon_crtc->h_border; - args.ucOverscanLeft = radeon_crtc->h_border; - args.ucOverscanBottom = radeon_crtc->v_border; - args.ucOverscanTop = radeon_crtc->v_border; - - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - misc |= ATOM_VSYNC_POLARITY; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - misc |= ATOM_HSYNC_POLARITY; - if (mode->flags & DRM_MODE_FLAG_CSYNC) - misc |= ATOM_COMPOSITESYNC; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - misc |= ATOM_INTERLACE; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) - misc |= ATOM_DOUBLE_CLOCK_MODE; - - args.susModeMiscInfo.usAccess = cpu_to_le16(misc); - args.ucCRTC = radeon_crtc->crtc_id; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_disable_ss(struct radeon_device *rdev, int pll_id) -{ - u32 ss_cntl; - - if (ASIC_IS_DCE4(rdev)) { - switch (pll_id) { - case ATOM_PPLL1: - ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); - ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; - WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl); - break; - case ATOM_PPLL2: - ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL); - ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; - WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl); - break; - case ATOM_DCPLL: - case ATOM_PPLL_INVALID: - return; - } - } else if (ASIC_IS_AVIVO(rdev)) { - switch (pll_id) { - case ATOM_PPLL1: - ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); - ss_cntl &= ~1; - WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl); - break; - case ATOM_PPLL2: - ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); - ss_cntl &= ~1; - WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl); - break; - case ATOM_DCPLL: - case ATOM_PPLL_INVALID: - return; - } - } -} - - -union atom_enable_ss { - ENABLE_LVDS_SS_PARAMETERS lvds_ss; - ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2; - ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; - ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2; - ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; -}; - -static void atombios_crtc_program_ss(struct radeon_device *rdev, - int enable, - int pll_id, - struct radeon_atom_ss *ss) -{ - int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); - union atom_enable_ss args; - - memset(&args, 0, sizeof(args)); - - if (ASIC_IS_DCE5(rdev)) { - args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0); - args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; - switch (pll_id) { - case ATOM_PPLL1: - args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; - args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); - break; - case ATOM_PPLL2: - args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; - args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); - break; - case ATOM_DCPLL: - args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; - args.v3.usSpreadSpectrumAmount = cpu_to_le16(0); - args.v3.usSpreadSpectrumStep = cpu_to_le16(0); - break; - case ATOM_PPLL_INVALID: - return; - } - args.v3.ucEnable = enable; - if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev)) - args.v3.ucEnable = ATOM_DISABLE; - } else if (ASIC_IS_DCE4(rdev)) { - args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); - args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; - switch (pll_id) { - case ATOM_PPLL1: - args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; - args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); - break; - case ATOM_PPLL2: - args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; - args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); - break; - case ATOM_DCPLL: - args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; - args.v2.usSpreadSpectrumAmount = cpu_to_le16(0); - args.v2.usSpreadSpectrumStep = cpu_to_le16(0); - break; - case ATOM_PPLL_INVALID: - return; - } - args.v2.ucEnable = enable; - if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev)) - args.v2.ucEnable = ATOM_DISABLE; - } else if (ASIC_IS_DCE3(rdev)) { - args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); - args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; - args.v1.ucSpreadSpectrumStep = ss->step; - args.v1.ucSpreadSpectrumDelay = ss->delay; - args.v1.ucSpreadSpectrumRange = ss->range; - args.v1.ucPpll = pll_id; - args.v1.ucEnable = enable; - } else if (ASIC_IS_AVIVO(rdev)) { - if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || - (ss->type & ATOM_EXTERNAL_SS_MASK)) { - atombios_disable_ss(rdev, pll_id); - return; - } - args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); - args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; - args.lvds_ss_2.ucSpreadSpectrumStep = ss->step; - args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay; - args.lvds_ss_2.ucSpreadSpectrumRange = ss->range; - args.lvds_ss_2.ucEnable = enable; - } else { - if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || - (ss->type & ATOM_EXTERNAL_SS_MASK)) { - atombios_disable_ss(rdev, pll_id); - return; - } - args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); - args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK; - args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2; - args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4; - args.lvds_ss.ucEnable = enable; - } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -union adjust_pixel_clock { - ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; - ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3; -}; - -static u32 atombios_adjust_pll(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct radeon_pll *pll, - bool ss_enabled, - struct radeon_atom_ss *ss) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder = NULL; - struct radeon_encoder *radeon_encoder = NULL; - struct drm_connector *connector = NULL; - u32 adjusted_clock = mode->clock; - int encoder_mode = 0; - u32 dp_clock = mode->clock; - int bpc = 8; - bool is_duallink = false; - - /* reset the pll flags */ - pll->flags = 0; - - if (ASIC_IS_AVIVO(rdev)) { - if ((rdev->family == CHIP_RS600) || - (rdev->family == CHIP_RS690) || - (rdev->family == CHIP_RS740)) - pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ - RADEON_PLL_PREFER_CLOSEST_LOWER); - - if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ - pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; - else - pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; - - if (rdev->family < CHIP_RV770) - pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; - /* use frac fb div on APUs */ - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; - } else { - pll->flags |= RADEON_PLL_LEGACY; - - if (mode->clock > 200000) /* range limits??? */ - pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; - else - pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; - } - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - radeon_encoder = to_radeon_encoder(encoder); - connector = radeon_get_connector_for_encoder(encoder); - /* if (connector && connector->display_info.bpc) - bpc = connector->display_info.bpc; */ - encoder_mode = atombios_get_encoder_mode(encoder); - is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); - if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || - (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; - - dp_clock = dig_connector->dp_clock; - } - } - - /* use recommended ref_div for ss */ - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (ss_enabled) { - if (ss->refdiv) { - pll->flags |= RADEON_PLL_USE_REF_DIV; - pll->reference_div = ss->refdiv; - if (ASIC_IS_AVIVO(rdev)) - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; - } - } - } - - if (ASIC_IS_AVIVO(rdev)) { - /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ - if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) - adjusted_clock = mode->clock * 2; - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - pll->flags |= RADEON_PLL_IS_LCD; - } else { - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) - pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; - if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) - pll->flags |= RADEON_PLL_USE_REF_DIV; - } - break; - } - } - - /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock - * accordingly based on the encoder/transmitter to work around - * special hw requirements. - */ - if (ASIC_IS_DCE3(rdev)) { - union adjust_pixel_clock args; - u8 frev, crev; - int index; - - index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, - &crev)) - return adjusted_clock; - - memset(&args, 0, sizeof(args)); - - switch (frev) { - case 1: - switch (crev) { - case 1: - case 2: - args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); - args.v1.ucTransmitterID = radeon_encoder->encoder_id; - args.v1.ucEncodeMode = encoder_mode; - if (ss_enabled && ss->percentage) - args.v1.ucConfig |= - ADJUST_DISPLAY_CONFIG_SS_ENABLE; - - atom_execute_table(rdev->mode_info.atom_context, - index, (uint32_t *)&args); - adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; - break; - case 3: - args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); - args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; - args.v3.sInput.ucEncodeMode = encoder_mode; - args.v3.sInput.ucDispPllConfig = 0; - if (ss_enabled && ss->percentage) - args.v3.sInput.ucDispPllConfig |= - DISPPLL_CONFIG_SS_ENABLE; - if (ENCODER_MODE_IS_DP(encoder_mode)) { - args.v3.sInput.ucDispPllConfig |= - DISPPLL_CONFIG_COHERENT_MODE; - /* 16200 or 27000 */ - args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); - } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - if (encoder_mode == ATOM_ENCODER_MODE_HDMI) - /* deep color support */ - args.v3.sInput.usPixelClock = - cpu_to_le16((mode->clock * bpc / 8) / 10); - if (dig->coherent_mode) - args.v3.sInput.ucDispPllConfig |= - DISPPLL_CONFIG_COHERENT_MODE; - if (is_duallink) - args.v3.sInput.ucDispPllConfig |= - DISPPLL_CONFIG_DUAL_LINK; - } - if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != - ENCODER_OBJECT_ID_NONE) - args.v3.sInput.ucExtTransmitterID = - radeon_encoder_get_dp_bridge_encoder_id(encoder); - else - args.v3.sInput.ucExtTransmitterID = 0; - - atom_execute_table(rdev->mode_info.atom_context, - index, (uint32_t *)&args); - adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; - if (args.v3.sOutput.ucRefDiv) { - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; - pll->flags |= RADEON_PLL_USE_REF_DIV; - pll->reference_div = args.v3.sOutput.ucRefDiv; - } - if (args.v3.sOutput.ucPostDiv) { - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; - pll->flags |= RADEON_PLL_USE_POST_DIV; - pll->post_div = args.v3.sOutput.ucPostDiv; - } - break; - default: - DRM_ERROR("Unknown table version %d %d\n", frev, crev); - return adjusted_clock; - } - break; - default: - DRM_ERROR("Unknown table version %d %d\n", frev, crev); - return adjusted_clock; - } - } - return adjusted_clock; -} - -union set_pixel_clock { - SET_PIXEL_CLOCK_PS_ALLOCATION base; - PIXEL_CLOCK_PARAMETERS v1; - PIXEL_CLOCK_PARAMETERS_V2 v2; - PIXEL_CLOCK_PARAMETERS_V3 v3; - PIXEL_CLOCK_PARAMETERS_V5 v5; - PIXEL_CLOCK_PARAMETERS_V6 v6; -}; - -/* on DCE5, make sure the voltage is high enough to support the - * required disp clk. - */ -static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev, - u32 dispclk) -{ - u8 frev, crev; - int index; - union set_pixel_clock args; - - memset(&args, 0, sizeof(args)); - - index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, - &crev)) - return; - - switch (frev) { - case 1: - switch (crev) { - case 5: - /* if the default dcpll clock is specified, - * SetPixelClock provides the dividers - */ - args.v5.ucCRTC = ATOM_CRTC_INVALID; - args.v5.usPixelClock = cpu_to_le16(dispclk); - args.v5.ucPpll = ATOM_DCPLL; - break; - case 6: - /* if the default dcpll clock is specified, - * SetPixelClock provides the dividers - */ - args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk); - if (ASIC_IS_DCE61(rdev)) - args.v6.ucPpll = ATOM_EXT_PLL1; - else if (ASIC_IS_DCE6(rdev)) - args.v6.ucPpll = ATOM_PPLL0; - else - args.v6.ucPpll = ATOM_DCPLL; - break; - default: - DRM_ERROR("Unknown table version %d %d\n", frev, crev); - return; - } - break; - default: - DRM_ERROR("Unknown table version %d %d\n", frev, crev); - return; - } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_crtc_program_pll(struct drm_crtc *crtc, - u32 crtc_id, - int pll_id, - u32 encoder_mode, - u32 encoder_id, - u32 clock, - u32 ref_div, - u32 fb_div, - u32 frac_fb_div, - u32 post_div, - int bpc, - bool ss_enabled, - struct radeon_atom_ss *ss) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - u8 frev, crev; - int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); - union set_pixel_clock args; - - memset(&args, 0, sizeof(args)); - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, - &crev)) - return; - - switch (frev) { - case 1: - switch (crev) { - case 1: - if (clock == ATOM_DISABLE) - return; - args.v1.usPixelClock = cpu_to_le16(clock / 10); - args.v1.usRefDiv = cpu_to_le16(ref_div); - args.v1.usFbDiv = cpu_to_le16(fb_div); - args.v1.ucFracFbDiv = frac_fb_div; - args.v1.ucPostDiv = post_div; - args.v1.ucPpll = pll_id; - args.v1.ucCRTC = crtc_id; - args.v1.ucRefDivSrc = 1; - break; - case 2: - args.v2.usPixelClock = cpu_to_le16(clock / 10); - args.v2.usRefDiv = cpu_to_le16(ref_div); - args.v2.usFbDiv = cpu_to_le16(fb_div); - args.v2.ucFracFbDiv = frac_fb_div; - args.v2.ucPostDiv = post_div; - args.v2.ucPpll = pll_id; - args.v2.ucCRTC = crtc_id; - args.v2.ucRefDivSrc = 1; - break; - case 3: - args.v3.usPixelClock = cpu_to_le16(clock / 10); - args.v3.usRefDiv = cpu_to_le16(ref_div); - args.v3.usFbDiv = cpu_to_le16(fb_div); - args.v3.ucFracFbDiv = frac_fb_div; - args.v3.ucPostDiv = post_div; - args.v3.ucPpll = pll_id; - args.v3.ucMiscInfo = (pll_id << 2); - if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) - args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC; - args.v3.ucTransmitterId = encoder_id; - args.v3.ucEncoderMode = encoder_mode; - break; - case 5: - args.v5.ucCRTC = crtc_id; - args.v5.usPixelClock = cpu_to_le16(clock / 10); - args.v5.ucRefDiv = ref_div; - args.v5.usFbDiv = cpu_to_le16(fb_div); - args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); - args.v5.ucPostDiv = post_div; - args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ - if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) - args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC; - switch (bpc) { - case 8: - default: - args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP; - break; - case 10: - args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; - break; - } - args.v5.ucTransmitterID = encoder_id; - args.v5.ucEncoderMode = encoder_mode; - args.v5.ucPpll = pll_id; - break; - case 6: - args.v6.ulDispEngClkFreq = cpu_to_le32(crtc_id << 24 | clock / 10); - args.v6.ucRefDiv = ref_div; - args.v6.usFbDiv = cpu_to_le16(fb_div); - args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); - args.v6.ucPostDiv = post_div; - args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */ - if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK)) - args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC; - switch (bpc) { - case 8: - default: - args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP; - break; - case 10: - args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP; - break; - case 12: - args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP; - break; - case 16: - args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; - break; - } - args.v6.ucTransmitterID = encoder_id; - args.v6.ucEncoderMode = encoder_mode; - args.v6.ucPpll = pll_id; - break; - default: - DRM_ERROR("Unknown table version %d %d\n", frev, crev); - return; - } - break; - default: - DRM_ERROR("Unknown table version %d %d\n", frev, crev); - return; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder = NULL; - struct radeon_encoder *radeon_encoder = NULL; - u32 pll_clock = mode->clock; - u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; - struct radeon_pll *pll; - u32 adjusted_clock; - int encoder_mode = 0; - struct radeon_atom_ss ss; - bool ss_enabled = false; - int bpc = 8; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - radeon_encoder = to_radeon_encoder(encoder); - encoder_mode = atombios_get_encoder_mode(encoder); - break; - } - } - - if (!radeon_encoder) - return; - - switch (radeon_crtc->pll_id) { - case ATOM_PPLL1: - pll = &rdev->clock.p1pll; - break; - case ATOM_PPLL2: - pll = &rdev->clock.p2pll; - break; - case ATOM_DCPLL: - case ATOM_PPLL_INVALID: - default: - pll = &rdev->clock.dcpll; - break; - } - - if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || - (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - struct drm_connector *connector = - radeon_get_connector_for_encoder(encoder); - struct radeon_connector *radeon_connector = - to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; - int dp_clock; - - /* if (connector->display_info.bpc) - bpc = connector->display_info.bpc; */ - - switch (encoder_mode) { - case ATOM_ENCODER_MODE_DP_MST: - case ATOM_ENCODER_MODE_DP: - /* DP/eDP */ - dp_clock = dig_connector->dp_clock / 10; - if (ASIC_IS_DCE4(rdev)) - ss_enabled = - radeon_atombios_get_asic_ss_info(rdev, &ss, - ASIC_INTERNAL_SS_ON_DP, - dp_clock); - else { - if (dp_clock == 16200) { - ss_enabled = - radeon_atombios_get_ppll_ss_info(rdev, &ss, - ATOM_DP_SS_ID2); - if (!ss_enabled) - ss_enabled = - radeon_atombios_get_ppll_ss_info(rdev, &ss, - ATOM_DP_SS_ID1); - } else - ss_enabled = - radeon_atombios_get_ppll_ss_info(rdev, &ss, - ATOM_DP_SS_ID1); - } - break; - case ATOM_ENCODER_MODE_LVDS: - if (ASIC_IS_DCE4(rdev)) - ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, - dig->lcd_ss_id, - mode->clock / 10); - else - ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss, - dig->lcd_ss_id); - break; - case ATOM_ENCODER_MODE_DVI: - if (ASIC_IS_DCE4(rdev)) - ss_enabled = - radeon_atombios_get_asic_ss_info(rdev, &ss, - ASIC_INTERNAL_SS_ON_TMDS, - mode->clock / 10); - break; - case ATOM_ENCODER_MODE_HDMI: - if (ASIC_IS_DCE4(rdev)) - ss_enabled = - radeon_atombios_get_asic_ss_info(rdev, &ss, - ASIC_INTERNAL_SS_ON_HDMI, - mode->clock / 10); - break; - default: - break; - } - } - - /* adjust pixel clock as needed */ - adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); - - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - /* TV seems to prefer the legacy algo on some boards */ - radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, - &ref_div, &post_div); - else if (ASIC_IS_AVIVO(rdev)) - radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, - &ref_div, &post_div); - else - radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, - &ref_div, &post_div); - - atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); - - atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, - encoder_mode, radeon_encoder->encoder_id, mode->clock, - ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss); - - if (ss_enabled) { - /* calculate ss amount and step size */ - if (ASIC_IS_DCE4(rdev)) { - u32 step_size; - u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000; - ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK; - ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) & - ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK; - if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) - step_size = (4 * amount * ref_div * (ss.rate * 2048)) / - (125 * 25 * pll->reference_freq / 100); - else - step_size = (2 * amount * ref_div * (ss.rate * 2048)) / - (125 * 25 * pll->reference_freq / 100); - ss.step = step_size; - } - - atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); - } -} - -static int dce4_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_framebuffer *radeon_fb; - struct drm_framebuffer *target_fb; - struct drm_gem_object *obj; - struct radeon_bo *rbo; - uint64_t fb_location; - uint32_t fb_format, fb_pitch_pixels, tiling_flags; - unsigned bankw, bankh, mtaspect, tile_split; - u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); - u32 tmp, viewport_w, viewport_h; - int r; - - /* no fb bound */ - if (!atomic && !crtc->fb) { - DRM_DEBUG_KMS("No FB bound\n"); - return 0; - } - - if (atomic) { - radeon_fb = to_radeon_framebuffer(fb); - target_fb = fb; - } - else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; - } - - /* If atomic, assume fb object is pinned & idle & fenced and - * just update base pointers - */ - obj = radeon_fb->obj; - rbo = gem_to_radeon_bo(obj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - return r; - - if (atomic) - fb_location = radeon_bo_gpu_offset(rbo); - else { - r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); - if (unlikely(r != 0)) { - radeon_bo_unreserve(rbo); - return -EINVAL; - } - } - - radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); - radeon_bo_unreserve(rbo); - - switch (target_fb->bits_per_pixel) { - case 8: - fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | - EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); - break; - case 15: - fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | - EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555)); - break; - case 16: - fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | - EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); -#ifdef __BIG_ENDIAN - fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); -#endif - break; - case 24: - case 32: - fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | - EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); -#ifdef __BIG_ENDIAN - fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); -#endif - break; - default: - DRM_ERROR("Unsupported screen depth %d\n", - target_fb->bits_per_pixel); - return -EINVAL; - } - - if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_CAYMAN) - tmp = rdev->config.cayman.tile_config; - else - tmp = rdev->config.evergreen.tile_config; - - switch ((tmp & 0xf0) >> 4) { - case 0: /* 4 banks */ - fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); - break; - case 1: /* 8 banks */ - default: - fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); - break; - case 2: /* 16 banks */ - fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); - break; - } - - fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); - - evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); - fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split); - fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw); - fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh); - fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect); - } else if (tiling_flags & RADEON_TILING_MICRO) - fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); - - switch (radeon_crtc->crtc_id) { - case 0: - WREG32(AVIVO_D1VGA_CONTROL, 0); - break; - case 1: - WREG32(AVIVO_D2VGA_CONTROL, 0); - break; - case 2: - WREG32(EVERGREEN_D3VGA_CONTROL, 0); - break; - case 3: - WREG32(EVERGREEN_D4VGA_CONTROL, 0); - break; - case 4: - WREG32(EVERGREEN_D5VGA_CONTROL, 0); - break; - case 5: - WREG32(EVERGREEN_D6VGA_CONTROL, 0); - break; - default: - break; - } - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, - upper_32_bits(fb_location)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, - upper_32_bits(fb_location)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); - WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); - WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); - - WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); - WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); - - fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8); - WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); - WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); - - WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); - x &= ~3; - y &= ~1; - WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, - (x << 16) | y); - viewport_w = crtc->mode.hdisplay; - viewport_h = (crtc->mode.vdisplay + 1) & ~1; - WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, - (viewport_w << 16) | viewport_h); - - /* pageflip setup */ - /* make sure flip is at vb rather than hb */ - tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen anywhere in vblank interval */ - WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - - if (!atomic && fb && fb != crtc->fb) { - radeon_fb = to_radeon_framebuffer(fb); - rbo = gem_to_radeon_bo(radeon_fb->obj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - return r; - radeon_bo_unpin(rbo); - radeon_bo_unreserve(rbo); - } - - /* Bytes per pixel may have changed */ - radeon_bandwidth_update(rdev); - - return 0; -} - -static int avivo_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_framebuffer *radeon_fb; - struct drm_gem_object *obj; - struct radeon_bo *rbo; - struct drm_framebuffer *target_fb; - uint64_t fb_location; - uint32_t fb_format, fb_pitch_pixels, tiling_flags; - u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; - u32 tmp, viewport_w, viewport_h; - int r; - - /* no fb bound */ - if (!atomic && !crtc->fb) { - DRM_DEBUG_KMS("No FB bound\n"); - return 0; - } - - if (atomic) { - radeon_fb = to_radeon_framebuffer(fb); - target_fb = fb; - } - else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; - } - - obj = radeon_fb->obj; - rbo = gem_to_radeon_bo(obj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - return r; - - /* If atomic, assume fb object is pinned & idle & fenced and - * just update base pointers - */ - if (atomic) - fb_location = radeon_bo_gpu_offset(rbo); - else { - r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); - if (unlikely(r != 0)) { - radeon_bo_unreserve(rbo); - return -EINVAL; - } - } - radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); - radeon_bo_unreserve(rbo); - - switch (target_fb->bits_per_pixel) { - case 8: - fb_format = - AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | - AVIVO_D1GRPH_CONTROL_8BPP_INDEXED; - break; - case 15: - fb_format = - AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | - AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; - break; - case 16: - fb_format = - AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | - AVIVO_D1GRPH_CONTROL_16BPP_RGB565; -#ifdef __BIG_ENDIAN - fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT; -#endif - break; - case 24: - case 32: - fb_format = - AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | - AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; -#ifdef __BIG_ENDIAN - fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; -#endif - break; - default: - DRM_ERROR("Unsupported screen depth %d\n", - target_fb->bits_per_pixel); - return -EINVAL; - } - - if (rdev->family >= CHIP_R600) { - if (tiling_flags & RADEON_TILING_MACRO) - fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1; - else if (tiling_flags & RADEON_TILING_MICRO) - fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1; - } else { - if (tiling_flags & RADEON_TILING_MACRO) - fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; - - if (tiling_flags & RADEON_TILING_MICRO) - fb_format |= AVIVO_D1GRPH_TILED; - } - - if (radeon_crtc->crtc_id == 0) - WREG32(AVIVO_D1VGA_CONTROL, 0); - else - WREG32(AVIVO_D2VGA_CONTROL, 0); - - if (rdev->family >= CHIP_RV770) { - if (radeon_crtc->crtc_id) { - WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); - WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); - } else { - WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); - WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); - } - } - WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32) fb_location); - WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + - radeon_crtc->crtc_offset, (u32) fb_location); - WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); - if (rdev->family >= CHIP_R600) - WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); - - WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); - WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); - WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); - WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); - WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); - WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); - - fb_pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8); - WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); - WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); - - WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); - x &= ~3; - y &= ~1; - WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, - (x << 16) | y); - viewport_w = crtc->mode.hdisplay; - viewport_h = (crtc->mode.vdisplay + 1) & ~1; - WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, - (viewport_w << 16) | viewport_h); - - /* pageflip setup */ - /* make sure flip is at vb rather than hb */ - tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen anywhere in vblank interval */ - WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - - if (!atomic && fb && fb != crtc->fb) { - radeon_fb = to_radeon_framebuffer(fb); - rbo = gem_to_radeon_bo(radeon_fb->obj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - return r; - radeon_bo_unpin(rbo); - radeon_bo_unreserve(rbo); - } - - /* Bytes per pixel may have changed */ - radeon_bandwidth_update(rdev); - - return 0; -} - -int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) - return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0); - else if (ASIC_IS_AVIVO(rdev)) - return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); - else - return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0); -} - -int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) - return dce4_crtc_do_set_base(crtc, fb, x, y, 1); - else if (ASIC_IS_AVIVO(rdev)) - return avivo_crtc_do_set_base(crtc, fb, x, y, 1); - else - return radeon_crtc_do_set_base(crtc, fb, x, y, 1); -} - -/* properly set additional regs when using atombios */ -static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - u32 disp_merge_cntl; - - switch (radeon_crtc->crtc_id) { - case 0: - disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL); - disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; - WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl); - break; - case 1: - disp_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL); - disp_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; - WREG32(RADEON_DISP2_MERGE_CNTL, disp_merge_cntl); - WREG32(RADEON_FP_H2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_H_SYNC_STRT_WID)); - WREG32(RADEON_FP_V2_SYNC_STRT_WID, RREG32(RADEON_CRTC2_V_SYNC_STRT_WID)); - break; - } -} - -static int radeon_atom_pick_pll(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *test_encoder; - struct drm_crtc *test_crtc; - uint32_t pll_in_use = 0; - - if (ASIC_IS_DCE61(rdev)) { - list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { - if (test_encoder->crtc && (test_encoder->crtc == crtc)) { - struct radeon_encoder *test_radeon_encoder = - to_radeon_encoder(test_encoder); - struct radeon_encoder_atom_dig *dig = - test_radeon_encoder->enc_priv; - - if ((test_radeon_encoder->encoder_id == - ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && - (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ - return ATOM_PPLL2; - } - } - /* UNIPHY B/C/D/E/F */ - list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { - struct radeon_crtc *radeon_test_crtc; - - if (crtc == test_crtc) - continue; - - radeon_test_crtc = to_radeon_crtc(test_crtc); - if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || - (radeon_test_crtc->pll_id == ATOM_PPLL1)) - pll_in_use |= (1 << radeon_test_crtc->pll_id); - } - if (!(pll_in_use & 4)) - return ATOM_PPLL0; - return ATOM_PPLL1; - } else if (ASIC_IS_DCE4(rdev)) { - list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { - if (test_encoder->crtc && (test_encoder->crtc == crtc)) { - /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, - * depending on the asic: - * DCE4: PPLL or ext clock - * DCE5: DCPLL or ext clock - * - * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip - * PPLL/DCPLL programming and only program the DP DTO for the - * crtc virtual pixel clock. - */ - if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { - if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk) - return ATOM_PPLL_INVALID; - } - } - } - - /* otherwise, pick one of the plls */ - list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { - struct radeon_crtc *radeon_test_crtc; - - if (crtc == test_crtc) - continue; - - radeon_test_crtc = to_radeon_crtc(test_crtc); - if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && - (radeon_test_crtc->pll_id <= ATOM_PPLL2)) - pll_in_use |= (1 << radeon_test_crtc->pll_id); - } - if (!(pll_in_use & 1)) - return ATOM_PPLL1; - return ATOM_PPLL2; - } else - return radeon_crtc->crtc_id; - -} - -void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) -{ - /* always set DCPLL */ - if (ASIC_IS_DCE6(rdev)) - atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); - else if (ASIC_IS_DCE4(rdev)) { - struct radeon_atom_ss ss; - bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, - ASIC_INTERNAL_SS_ON_DCPLL, - rdev->clock.default_dispclk); - if (ss_enabled) - atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); - /* XXX: DCE5, make sure voltage, dispclk is high enough */ - atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); - if (ss_enabled) - atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); - } - -} - -int atombios_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - bool is_tvcv = false; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - /* find tv std */ - if (encoder->crtc == crtc) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->active_device & - (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - is_tvcv = true; - } - } - - atombios_crtc_set_pll(crtc, adjusted_mode); - - if (ASIC_IS_DCE4(rdev)) - atombios_set_crtc_dtd_timing(crtc, adjusted_mode); - else if (ASIC_IS_AVIVO(rdev)) { - if (is_tvcv) - atombios_crtc_set_timing(crtc, adjusted_mode); - else - atombios_set_crtc_dtd_timing(crtc, adjusted_mode); - } else { - atombios_crtc_set_timing(crtc, adjusted_mode); - if (radeon_crtc->crtc_id == 0) - atombios_set_crtc_dtd_timing(crtc, adjusted_mode); - radeon_legacy_atom_fixup(crtc); - } - atombios_crtc_set_base(crtc, x, y, old_fb); - atombios_overscan_setup(crtc, mode, adjusted_mode); - atombios_scaler_setup(crtc); - return 0; -} - -static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) - return false; - return true; -} - -static void atombios_crtc_prepare(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - /* pick pll */ - radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); - - atombios_lock_crtc(crtc, ATOM_ENABLE); - atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); -} - -static void atombios_crtc_commit(struct drm_crtc *crtc) -{ - atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); - atombios_lock_crtc(crtc, ATOM_DISABLE); -} - -static void atombios_crtc_disable(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_atom_ss ss; - - atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - - switch (radeon_crtc->pll_id) { - case ATOM_PPLL1: - case ATOM_PPLL2: - /* disable the ppll */ - atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, - 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); - break; - case ATOM_PPLL0: - /* disable the ppll */ - if (ASIC_IS_DCE61(rdev)) - atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, - 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss); - break; - default: - break; - } - radeon_crtc->pll_id = -1; -} - -static const struct drm_crtc_helper_funcs atombios_helper_funcs = { - .dpms = atombios_crtc_dpms, - .mode_fixup = atombios_crtc_mode_fixup, - .mode_set = atombios_crtc_mode_set, - .mode_set_base = atombios_crtc_set_base, - .mode_set_base_atomic = atombios_crtc_set_base_atomic, - .prepare = atombios_crtc_prepare, - .commit = atombios_crtc_commit, - .load_lut = radeon_crtc_load_lut, - .disable = atombios_crtc_disable, -}; - -void radeon_atombios_init_crtc(struct drm_device *dev, - struct radeon_crtc *radeon_crtc) -{ - struct radeon_device *rdev = dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) { - switch (radeon_crtc->crtc_id) { - case 0: - default: - radeon_crtc->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET; - break; - case 1: - radeon_crtc->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET; - break; - case 2: - radeon_crtc->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET; - break; - case 3: - radeon_crtc->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET; - break; - case 4: - radeon_crtc->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET; - break; - case 5: - radeon_crtc->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET; - break; - } - } else { - if (radeon_crtc->crtc_id == 1) - radeon_crtc->crtc_offset = - AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; - else - radeon_crtc->crtc_offset = 0; - } - radeon_crtc->pll_id = -1; - drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_dp.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_dp.c deleted file mode 100644 index c57d8566..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_dp.c +++ /dev/null @@ -1,987 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" - -#include "atom.h" -#include "atom-bits.h" -#include "drm_dp_helper.h" - -/* move these to drm_dp_helper.c/h */ -#define DP_LINK_CONFIGURATION_SIZE 9 -#define DP_LINK_STATUS_SIZE 6 -#define DP_DPCD_SIZE 8 - -static char *voltage_names[] = { - "0.4V", "0.6V", "0.8V", "1.2V" -}; -static char *pre_emph_names[] = { - "0dB", "3.5dB", "6dB", "9.5dB" -}; - -/***** radeon AUX functions *****/ -union aux_channel_transaction { - PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; - PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; -}; - -static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, - u8 *send, int send_bytes, - u8 *recv, int recv_size, - u8 delay, u8 *ack) -{ - struct drm_device *dev = chan->dev; - struct radeon_device *rdev = dev->dev_private; - union aux_channel_transaction args; - int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); - unsigned char *base; - int recv_bytes; - - memset(&args, 0, sizeof(args)); - - base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); - - memcpy(base, send, send_bytes); - - args.v1.lpAuxRequest = 0 + 4; - args.v1.lpDataOut = 16 + 4; - args.v1.ucDataOutLen = 0; - args.v1.ucChannelID = chan->rec.i2c_id; - args.v1.ucDelay = delay / 10; - if (ASIC_IS_DCE4(rdev)) - args.v2.ucHPD_ID = chan->rec.hpd; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - *ack = args.v1.ucReplyStatus; - - /* timeout */ - if (args.v1.ucReplyStatus == 1) { - DRM_DEBUG_KMS("dp_aux_ch timeout\n"); - return -ETIMEDOUT; - } - - /* flags not zero */ - if (args.v1.ucReplyStatus == 2) { - DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); - return -EBUSY; - } - - /* error */ - if (args.v1.ucReplyStatus == 3) { - DRM_DEBUG_KMS("dp_aux_ch error\n"); - return -EIO; - } - - recv_bytes = args.v1.ucDataOutLen; - if (recv_bytes > recv_size) - recv_bytes = recv_size; - - if (recv && recv_size) - memcpy(recv, base + 16, recv_bytes); - - return recv_bytes; -} - -static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, - u16 address, u8 *send, u8 send_bytes, u8 delay) -{ - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - int ret; - u8 msg[20]; - int msg_bytes = send_bytes + 4; - u8 ack; - unsigned retry; - - if (send_bytes > 16) - return -1; - - msg[0] = address; - msg[1] = address >> 8; - msg[2] = AUX_NATIVE_WRITE << 4; - msg[3] = (msg_bytes << 4) | (send_bytes - 1); - memcpy(&msg[4], send, send_bytes); - - for (retry = 0; retry < 4; retry++) { - ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, - msg, msg_bytes, NULL, 0, delay, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return send_bytes; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(400); - else - return -EIO; - } - - return -EIO; -} - -static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, - u16 address, u8 *recv, int recv_bytes, u8 delay) -{ - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - u8 msg[4]; - int msg_bytes = 4; - u8 ack; - int ret; - unsigned retry; - - msg[0] = address; - msg[1] = address >> 8; - msg[2] = AUX_NATIVE_READ << 4; - msg[3] = (msg_bytes << 4) | (recv_bytes - 1); - - for (retry = 0; retry < 4; retry++) { - ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, - msg, msg_bytes, recv, recv_bytes, delay, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) - return ret; - if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) - return ret; - else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) - udelay(400); - else if (ret == 0) - return -EPROTO; - else - return -EIO; - } - - return -EIO; -} - -static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, - u16 reg, u8 val) -{ - radeon_dp_aux_native_write(radeon_connector, reg, &val, 1, 0); -} - -static u8 radeon_read_dpcd_reg(struct radeon_connector *radeon_connector, - u16 reg) -{ - u8 val = 0; - - radeon_dp_aux_native_read(radeon_connector, reg, &val, 1, 0); - - return val; -} - -int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, - u8 write_byte, u8 *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; - u16 address = algo_data->address; - u8 msg[5]; - u8 reply[2]; - unsigned retry; - int msg_bytes; - int reply_bytes = 1; - int ret; - u8 ack; - - /* Set up the command byte */ - if (mode & MODE_I2C_READ) - msg[2] = AUX_I2C_READ << 4; - else - msg[2] = AUX_I2C_WRITE << 4; - - if (!(mode & MODE_I2C_STOP)) - msg[2] |= AUX_I2C_MOT << 4; - - msg[0] = address; - msg[1] = address >> 8; - - switch (mode) { - case MODE_I2C_WRITE: - msg_bytes = 5; - msg[3] = msg_bytes << 4; - msg[4] = write_byte; - break; - case MODE_I2C_READ: - msg_bytes = 4; - msg[3] = msg_bytes << 4; - break; - default: - msg_bytes = 4; - msg[3] = 3 << 4; - break; - } - - for (retry = 0; retry < 4; retry++) { - ret = radeon_process_aux_ch(auxch, - msg, msg_bytes, reply, reply_bytes, 0, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) { - DRM_DEBUG_KMS("aux_ch failed %d\n", ret); - return ret; - } - - switch (ack & AUX_NATIVE_REPLY_MASK) { - case AUX_NATIVE_REPLY_ACK: - /* I2C-over-AUX Reply field is only valid - * when paired with AUX ACK. - */ - break; - case AUX_NATIVE_REPLY_NACK: - DRM_DEBUG_KMS("aux_ch native nack\n"); - return -EREMOTEIO; - case AUX_NATIVE_REPLY_DEFER: - DRM_DEBUG_KMS("aux_ch native defer\n"); - udelay(400); - continue; - default: - DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack); - return -EREMOTEIO; - } - - switch (ack & AUX_I2C_REPLY_MASK) { - case AUX_I2C_REPLY_ACK: - if (mode == MODE_I2C_READ) - *read_byte = reply[0]; - return ret; - case AUX_I2C_REPLY_NACK: - DRM_DEBUG_KMS("aux_i2c nack\n"); - return -EREMOTEIO; - case AUX_I2C_REPLY_DEFER: - DRM_DEBUG_KMS("aux_i2c defer\n"); - udelay(400); - break; - default: - DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack); - return -EREMOTEIO; - } - } - - DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); - return -EREMOTEIO; -} - -/***** general DP utility functions *****/ - -static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r) -{ - return link_status[r - DP_LANE0_1_STATUS]; -} - -static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_LANE0_1_STATUS + (lane >> 1); - int s = (lane & 1) * 4; - u8 l = dp_link_status(link_status, i); - return (l >> s) & 0xf; -} - -static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE], - int lane_count) -{ - int lane; - u8 lane_status; - - for (lane = 0; lane < lane_count; lane++) { - lane_status = dp_get_lane_status(link_status, lane); - if ((lane_status & DP_LANE_CR_DONE) == 0) - return false; - } - return true; -} - -static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE], - int lane_count) -{ - u8 lane_align; - u8 lane_status; - int lane; - - lane_align = dp_link_status(link_status, - DP_LANE_ALIGN_STATUS_UPDATED); - if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) - return false; - for (lane = 0; lane < lane_count; lane++) { - lane_status = dp_get_lane_status(link_status, lane); - if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS) - return false; - } - return true; -} - -static u8 dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], - int lane) - -{ - int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); - int s = ((lane & 1) ? - DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : - DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); - u8 l = dp_link_status(link_status, i); - - return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; -} - -static u8 dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE], - int lane) -{ - int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); - int s = ((lane & 1) ? - DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : - DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); - u8 l = dp_link_status(link_status, i); - - return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; -} - -#define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200 -#define DP_PRE_EMPHASIS_MAX DP_TRAIN_PRE_EMPHASIS_9_5 - -static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], - int lane_count, - u8 train_set[4]) -{ - u8 v = 0; - u8 p = 0; - int lane; - - for (lane = 0; lane < lane_count; lane++) { - u8 this_v = dp_get_adjust_request_voltage(link_status, lane); - u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane); - - DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n", - lane, - voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT], - pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); - - if (this_v > v) - v = this_v; - if (this_p > p) - p = this_p; - } - - if (v >= DP_VOLTAGE_MAX) - v |= DP_TRAIN_MAX_SWING_REACHED; - - if (p >= DP_PRE_EMPHASIS_MAX) - p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; - - DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n", - voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT], - pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]); - - for (lane = 0; lane < 4; lane++) - train_set[lane] = v | p; -} - -/* convert bits per color to bits per pixel */ -/* get bpc from the EDID */ -static int convert_bpc_to_bpp(int bpc) -{ -#if 0 - if (bpc == 0) - return 24; - else - return bpc * 3; -#endif - return 24; -} - -/* get the max pix clock supported by the link rate and lane num */ -static int dp_get_max_dp_pix_clock(int link_rate, - int lane_num, - int bpp) -{ - return (link_rate * lane_num * 8) / bpp; -} - -static int dp_get_max_link_rate(u8 dpcd[DP_DPCD_SIZE]) -{ - switch (dpcd[DP_MAX_LINK_RATE]) { - case DP_LINK_BW_1_62: - default: - return 162000; - case DP_LINK_BW_2_7: - return 270000; - case DP_LINK_BW_5_4: - return 540000; - } -} - -static u8 dp_get_max_lane_number(u8 dpcd[DP_DPCD_SIZE]) -{ - return dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK; -} - -static u8 dp_get_dp_link_rate_coded(int link_rate) -{ - switch (link_rate) { - case 162000: - default: - return DP_LINK_BW_1_62; - case 270000: - return DP_LINK_BW_2_7; - case 540000: - return DP_LINK_BW_5_4; - } -} - -/***** radeon specific DP functions *****/ - -/* First get the min lane# when low rate is used according to pixel clock - * (prefer low rate), second check max lane# supported by DP panel, - * if the max lane# < low rate lane# then use max lane# instead. - */ -static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE], - int pix_clock) -{ - int bpp = convert_bpc_to_bpp(connector->display_info.bpc); - int max_link_rate = dp_get_max_link_rate(dpcd); - int max_lane_num = dp_get_max_lane_number(dpcd); - int lane_num; - int max_dp_pix_clock; - - for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { - max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); - if (pix_clock <= max_dp_pix_clock) - break; - } - - return lane_num; -} - -static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, - u8 dpcd[DP_DPCD_SIZE], - int pix_clock) -{ - int bpp = convert_bpc_to_bpp(connector->display_info.bpc); - int lane_num, max_pix_clock; - - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_NUTMEG) - return 270000; - - lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); - max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 162000; - max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 270000; - if (radeon_connector_is_dp12_capable(connector)) { - max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); - if (pix_clock <= max_pix_clock) - return 540000; - } - - return dp_get_max_link_rate(dpcd); -} - -static u8 radeon_dp_encoder_service(struct radeon_device *rdev, - int action, int dp_clock, - u8 ucconfig, u8 lane_num) -{ - DP_ENCODER_SERVICE_PARAMETERS args; - int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); - - memset(&args, 0, sizeof(args)); - args.ucLinkClock = dp_clock / 10; - args.ucConfig = ucconfig; - args.ucAction = action; - args.ucLaneNum = lane_num; - args.ucStatus = 0; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return args.ucStatus; -} - -u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) -{ - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - struct drm_device *dev = radeon_connector->base.dev; - struct radeon_device *rdev = dev->dev_private; - - return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, - dig_connector->dp_i2c_bus->rec.i2c_id, 0); -} - -bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) -{ - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - u8 msg[25]; - int ret, i; - - ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg, 8, 0); - if (ret > 0) { - memcpy(dig_connector->dpcd, msg, 8); - DRM_DEBUG_KMS("DPCD: "); - for (i = 0; i < 8; i++) - DRM_DEBUG_KMS("%02x ", msg[i]); - DRM_DEBUG_KMS("\n"); - return true; - } - dig_connector->dpcd[0] = 0; - return false; -} - -int radeon_dp_get_panel_mode(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; - - if (!ASIC_IS_DCE4(rdev)) - return panel_mode; - - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_NUTMEG) - panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; - else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_TRAVIS) { - u8 id[6]; - int i; - for (i = 0; i < 6; i++) - id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); - if (id[0] == 0x73 && - id[1] == 0x69 && - id[2] == 0x76 && - id[3] == 0x61 && - id[4] == 0x72 && - id[5] == 0x54) - panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; - else - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; - } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { - u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); - if (tmp & 1) - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; - } - - return panel_mode; -} - -void radeon_dp_set_link_config(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector; - - if (!radeon_connector->con_priv) - return; - dig_connector = radeon_connector->con_priv; - - if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || - (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { - dig_connector->dp_clock = - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); - dig_connector->dp_lane_count = - radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); - } -} - -int radeon_dp_mode_valid_helper(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector; - int dp_clock; - - if (!radeon_connector->con_priv) - return MODE_CLOCK_HIGH; - dig_connector = radeon_connector->con_priv; - - dp_clock = - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); - - if ((dp_clock == 540000) && - (!radeon_connector_is_dp12_capable(connector))) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector, - u8 link_status[DP_LINK_STATUS_SIZE]) -{ - int ret; - ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, - link_status, DP_LINK_STATUS_SIZE, 100); - if (ret <= 0) { - DRM_ERROR("displayport link status failed\n"); - return false; - } - - DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n", - link_status[0], link_status[1], link_status[2], - link_status[3], link_status[4], link_status[5]); - return true; -} - -bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) -{ - u8 link_status[DP_LINK_STATUS_SIZE]; - struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - - if (!radeon_dp_get_link_status(radeon_connector, link_status)) - return false; - if (dp_channel_eq_ok(link_status, dig->dp_lane_count)) - return false; - return true; -} - -struct radeon_dp_link_train_info { - struct radeon_device *rdev; - struct drm_encoder *encoder; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - int enc_id; - int dp_clock; - int dp_lane_count; - int rd_interval; - bool tp3_supported; - u8 dpcd[8]; - u8 train_set[4]; - u8 link_status[DP_LINK_STATUS_SIZE]; - u8 tries; - bool use_dpencoder; -}; - -static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info) -{ - /* set the initial vs/emph on the source */ - atombios_dig_transmitter_setup(dp_info->encoder, - ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH, - 0, dp_info->train_set[0]); /* sets all lanes at once */ - - /* set the vs/emph on the sink */ - radeon_dp_aux_native_write(dp_info->radeon_connector, DP_TRAINING_LANE0_SET, - dp_info->train_set, dp_info->dp_lane_count, 0); -} - -static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) -{ - int rtp = 0; - - /* set training pattern on the source */ - if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) { - switch (tp) { - case DP_TRAINING_PATTERN_1: - rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1; - break; - case DP_TRAINING_PATTERN_2: - rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2; - break; - case DP_TRAINING_PATTERN_3: - rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3; - break; - } - atombios_dig_encoder_setup(dp_info->encoder, rtp, 0); - } else { - switch (tp) { - case DP_TRAINING_PATTERN_1: - rtp = 0; - break; - case DP_TRAINING_PATTERN_2: - rtp = 1; - break; - } - radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL, - dp_info->dp_clock, dp_info->enc_id, rtp); - } - - /* enable training pattern on the sink */ - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, tp); -} - -static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - u8 tmp; - - /* power up the sink */ - if (dp_info->dpcd[0] >= 0x11) - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_SET_POWER, DP_SET_POWER_D0); - - /* possibly enable downspread on the sink */ - if (dp_info->dpcd[3] & 0x1) - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5); - else - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_DOWNSPREAD_CTRL, 0); - - if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && - (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); - } - - /* set the lane count on the sink */ - tmp = dp_info->dp_lane_count; - if (dp_info->dpcd[DP_DPCD_REV] >= 0x11 && - dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP) - tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN; - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp); - - /* set the link rate on the sink */ - tmp = dp_get_dp_link_rate_coded(dp_info->dp_clock); - radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp); - - /* start training on the source */ - if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) - atombios_dig_encoder_setup(dp_info->encoder, - ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0); - else - radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_START, - dp_info->dp_clock, dp_info->enc_id, 0); - - /* disable the training pattern on the sink */ - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_TRAINING_PATTERN_SET, - DP_TRAINING_PATTERN_DISABLE); - - return 0; -} - -static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info) -{ - udelay(400); - - /* disable the training pattern on the sink */ - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_TRAINING_PATTERN_SET, - DP_TRAINING_PATTERN_DISABLE); - - /* disable the training pattern on the source */ - if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) - atombios_dig_encoder_setup(dp_info->encoder, - ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0); - else - radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, - dp_info->dp_clock, dp_info->enc_id, 0); - - return 0; -} - -static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info) -{ - bool clock_recovery; - u8 voltage; - int i; - - radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_1); - memset(dp_info->train_set, 0, 4); - radeon_dp_update_vs_emph(dp_info); - - udelay(400); - - /* clock recovery loop */ - clock_recovery = false; - dp_info->tries = 0; - voltage = 0xff; - while (1) { - if (dp_info->rd_interval == 0) - udelay(100); - else - mdelay(dp_info->rd_interval * 4); - - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) - break; - - if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) { - clock_recovery = true; - break; - } - - for (i = 0; i < dp_info->dp_lane_count; i++) { - if ((dp_info->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) - break; - } - if (i == dp_info->dp_lane_count) { - DRM_ERROR("clock recovery reached max voltage\n"); - break; - } - - if ((dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { - ++dp_info->tries; - if (dp_info->tries == 5) { - DRM_ERROR("clock recovery tried 5 times\n"); - break; - } - } else - dp_info->tries = 0; - - voltage = dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; - - /* Compute new train_set as requested by sink */ - dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set); - - radeon_dp_update_vs_emph(dp_info); - } - if (!clock_recovery) { - DRM_ERROR("clock recovery failed\n"); - return -1; - } else { - DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n", - dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, - (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >> - DP_TRAIN_PRE_EMPHASIS_SHIFT); - return 0; - } -} - -static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info) -{ - bool channel_eq; - - if (dp_info->tp3_supported) - radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_3); - else - radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_2); - - /* channel equalization loop */ - dp_info->tries = 0; - channel_eq = false; - while (1) { - if (dp_info->rd_interval == 0) - udelay(400); - else - mdelay(dp_info->rd_interval * 4); - - if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) - break; - - if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { - channel_eq = true; - break; - } - - /* Try 5 times */ - if (dp_info->tries > 5) { - DRM_ERROR("channel eq failed: 5 tries\n"); - break; - } - - /* Compute new train_set as requested by sink */ - dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set); - - radeon_dp_update_vs_emph(dp_info); - dp_info->tries++; - } - - if (!channel_eq) { - DRM_ERROR("channel eq failed\n"); - return -1; - } else { - DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n", - dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK, - (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) - >> DP_TRAIN_PRE_EMPHASIS_SHIFT); - return 0; - } -} - -void radeon_dp_link_train(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; - struct radeon_dp_link_train_info dp_info; - int index; - u8 tmp, frev, crev; - - if (!radeon_encoder->enc_priv) - return; - dig = radeon_encoder->enc_priv; - - radeon_connector = to_radeon_connector(connector); - if (!radeon_connector->con_priv) - return; - dig_connector = radeon_connector->con_priv; - - if ((dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) && - (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP)) - return; - - /* DPEncoderService newer than 1.1 can't program properly the - * training pattern. When facing such version use the - * DIGXEncoderControl (X== 1 | 2) - */ - dp_info.use_dpencoder = true; - index = GetIndexIntoMasterTable(COMMAND, DPEncoderService); - if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) { - if (crev > 1) { - dp_info.use_dpencoder = false; - } - } - - dp_info.enc_id = 0; - if (dig->dig_encoder) - dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; - else - dp_info.enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; - if (dig->linkb) - dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B; - else - dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; - - dp_info.rd_interval = radeon_read_dpcd_reg(radeon_connector, DP_TRAINING_AUX_RD_INTERVAL); - tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT); - if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) - dp_info.tp3_supported = true; - else - dp_info.tp3_supported = false; - - memcpy(dp_info.dpcd, dig_connector->dpcd, 8); - dp_info.rdev = rdev; - dp_info.encoder = encoder; - dp_info.connector = connector; - dp_info.radeon_connector = radeon_connector; - dp_info.dp_lane_count = dig_connector->dp_lane_count; - dp_info.dp_clock = dig_connector->dp_clock; - - if (radeon_dp_link_train_init(&dp_info)) - goto done; - if (radeon_dp_link_train_cr(&dp_info)) - goto done; - if (radeon_dp_link_train_ce(&dp_info)) - goto done; -done: - if (radeon_dp_link_train_finish(&dp_info)) - return; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_encoders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_encoders.c deleted file mode 100644 index 2d39f997..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_encoders.c +++ /dev/null @@ -1,2424 +0,0 @@ -/* - * Copyright 2007-11 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" - -extern int atom_debug; - -/* evil but including atombios.h is much worse */ -bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, - struct drm_display_mode *mode); - - -static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - return true; - default: - return false; - } -} - -static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - - /* set the active encoder to connector routing */ - radeon_encoder_set_active_device(encoder); - drm_mode_set_crtcinfo(adjusted_mode, 0); - - /* hw bug */ - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) - && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) - adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; - - /* get the native mode for LVDS */ - if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) - radeon_panel_mode_fixup(encoder, adjusted_mode); - - /* get the native mode for TV */ - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { - struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; - if (tv_dac) { - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M) - radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); - else - radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); - } - } - - if (ASIC_IS_DCE3(rdev) && - ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || - (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) { - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - radeon_dp_set_link_config(connector, mode); - } - - return true; -} - -static void -atombios_dac_setup(struct drm_encoder *encoder, int action) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DAC_ENCODER_CONTROL_PS_ALLOCATION args; - int index = 0; - struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; - - memset(&args, 0, sizeof(args)); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); - break; - } - - args.ucAction = action; - - if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) - args.ucDacStandard = ATOM_DAC1_PS2; - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.ucDacStandard = ATOM_DAC1_CV; - else { - switch (dac_info->tv_std) { - case TV_STD_PAL: - case TV_STD_PAL_M: - case TV_STD_SCART_PAL: - case TV_STD_SECAM: - case TV_STD_PAL_CN: - args.ucDacStandard = ATOM_DAC1_PAL; - break; - case TV_STD_NTSC: - case TV_STD_NTSC_J: - case TV_STD_PAL_60: - default: - args.ucDacStandard = ATOM_DAC1_NTSC; - break; - } - } - args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - -} - -static void -atombios_tv_setup(struct drm_encoder *encoder, int action) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - TV_ENCODER_CONTROL_PS_ALLOCATION args; - int index = 0; - struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; - - memset(&args, 0, sizeof(args)); - - index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); - - args.sTVEncoder.ucAction = action; - - if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.sTVEncoder.ucTvStandard = ATOM_TV_CV; - else { - switch (dac_info->tv_std) { - case TV_STD_NTSC: - args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; - break; - case TV_STD_PAL: - args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; - break; - case TV_STD_PAL_M: - args.sTVEncoder.ucTvStandard = ATOM_TV_PALM; - break; - case TV_STD_PAL_60: - args.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; - break; - case TV_STD_NTSC_J: - args.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; - break; - case TV_STD_SCART_PAL: - args.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ - break; - case TV_STD_SECAM: - args.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; - break; - case TV_STD_PAL_CN: - args.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; - break; - default: - args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; - break; - } - } - - args.sTVEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - -} - -union dvo_encoder_control { - ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds; - DVO_ENCODER_CONTROL_PS_ALLOCATION dvo; - DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3; -}; - -void -atombios_dvo_setup(struct drm_encoder *encoder, int action) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - union dvo_encoder_control args; - int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl); - uint8_t frev, crev; - - memset(&args, 0, sizeof(args)); - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - /* some R4xx chips have the wrong frev */ - if (rdev->family <= CHIP_RV410) - frev = 1; - - switch (frev) { - case 1: - switch (crev) { - case 1: - /* R4xx, R5xx */ - args.ext_tmds.sXTmdsEncoder.ucEnable = action; - - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; - - args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; - break; - case 2: - /* RS600/690/740 */ - args.dvo.sDVOEncoder.ucAction = action; - args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - /* DFP1, CRT1, TV1 depending on the type of port */ - args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; - - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; - break; - case 3: - /* R6xx */ - args.dvo_v3.ucAction = action; - args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - args.dvo_v3.ucDVOConfig = 0; /* XXX */ - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -union lvds_encoder_control { - LVDS_ENCODER_CONTROL_PS_ALLOCATION v1; - LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 v2; -}; - -void -atombios_digital_setup(struct drm_encoder *encoder, int action) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - union lvds_encoder_control args; - int index = 0; - int hdmi_detected = 0; - uint8_t frev, crev; - - if (!dig) - return; - - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) - hdmi_detected = 1; - - memset(&args, 0, sizeof(args)); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl); - else - index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl); - break; - } - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - switch (frev) { - case 1: - case 2: - switch (crev) { - case 1: - args.v1.ucMisc = 0; - args.v1.ucAction = action; - if (hdmi_detected) - args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; - args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) - args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) - args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; - } else { - if (dig->linkb) - args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; - /*if (pScrn->rgbBits == 8) */ - args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; - } - break; - case 2: - case 3: - args.v2.ucMisc = 0; - args.v2.ucAction = action; - if (crev == 3) { - if (dig->coherent_mode) - args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; - } - if (hdmi_detected) - args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; - args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - args.v2.ucTruncate = 0; - args.v2.ucSpatial = 0; - args.v2.ucTemporal = 0; - args.v2.ucFRC = 0; - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL) - args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; - if (dig->lcd_misc & ATOM_PANEL_MISC_SPATIAL) { - args.v2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN; - if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) - args.v2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH; - } - if (dig->lcd_misc & ATOM_PANEL_MISC_TEMPORAL) { - args.v2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN; - if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB) - args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH; - if (((dig->lcd_misc >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT) & 0x3) == 2) - args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; - } - } else { - if (dig->linkb) - args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; - } - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -int -atombios_get_encoder_mode(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; - - /* dp bridges are always DP */ - if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) - return ATOM_ENCODER_MODE_DP; - - /* DVO is always DVO */ - if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO) - return ATOM_ENCODER_MODE_DVO; - - connector = radeon_get_connector_for_encoder(encoder); - /* if we don't have an active device yet, just use one of - * the connectors tied to the encoder. - */ - if (!connector) - connector = radeon_get_connector_for_encoder_init(encoder); - radeon_connector = to_radeon_connector(connector); - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ - if (drm_detect_hdmi_monitor(radeon_connector->edid) && - radeon_audio) - return ATOM_ENCODER_MODE_HDMI; - else if (radeon_connector->use_digital) - return ATOM_ENCODER_MODE_DVI; - else - return ATOM_ENCODER_MODE_CRT; - break; - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_HDMIA: - default: - if (drm_detect_hdmi_monitor(radeon_connector->edid) && - radeon_audio) - return ATOM_ENCODER_MODE_HDMI; - else - return ATOM_ENCODER_MODE_DVI; - break; - case DRM_MODE_CONNECTOR_LVDS: - return ATOM_ENCODER_MODE_LVDS; - break; - case DRM_MODE_CONNECTOR_DisplayPort: - dig_connector = radeon_connector->con_priv; - if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || - (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) - return ATOM_ENCODER_MODE_DP; - else if (drm_detect_hdmi_monitor(radeon_connector->edid) && - radeon_audio) - return ATOM_ENCODER_MODE_HDMI; - else - return ATOM_ENCODER_MODE_DVI; - break; - case DRM_MODE_CONNECTOR_eDP: - return ATOM_ENCODER_MODE_DP; - case DRM_MODE_CONNECTOR_DVIA: - case DRM_MODE_CONNECTOR_VGA: - return ATOM_ENCODER_MODE_CRT; - break; - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_9PinDIN: - /* fix me */ - return ATOM_ENCODER_MODE_TV; - /*return ATOM_ENCODER_MODE_CV;*/ - break; - } -} - -/* - * DIG Encoder/Transmitter Setup - * - * DCE 3.0/3.1 - * - 2 DIG transmitter blocks. UNIPHY (links A and B) and LVTMA. - * Supports up to 3 digital outputs - * - 2 DIG encoder blocks. - * DIG1 can drive UNIPHY link A or link B - * DIG2 can drive UNIPHY link B or LVTMA - * - * DCE 3.2 - * - 3 DIG transmitter blocks. UNIPHY0/1/2 (links A and B). - * Supports up to 5 digital outputs - * - 2 DIG encoder blocks. - * DIG1/2 can drive UNIPHY0/1/2 link A or link B - * - * DCE 4.0/5.0/6.0 - * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). - * Supports up to 6 digital outputs - * - 6 DIG encoder blocks. - * - DIG to PHY mapping is hardcoded - * DIG1 drives UNIPHY0 link A, A+B - * DIG2 drives UNIPHY0 link B - * DIG3 drives UNIPHY1 link A, A+B - * DIG4 drives UNIPHY1 link B - * DIG5 drives UNIPHY2 link A, A+B - * DIG6 drives UNIPHY2 link B - * - * DCE 4.1 - * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). - * Supports up to 6 digital outputs - * - 2 DIG encoder blocks. - * llano - * DIG1/2 can drive UNIPHY0/1/2 link A or link B - * ontario - * DIG1 drives UNIPHY0/1/2 link A - * DIG2 drives UNIPHY0/1/2 link B - * - * Routing - * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) - * Examples: - * crtc0 -> dig2 -> LVTMA links A+B -> TMDS/HDMI - * crtc1 -> dig1 -> UNIPHY0 link B -> DP - * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS - * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI - */ - -union dig_encoder_control { - DIG_ENCODER_CONTROL_PS_ALLOCATION v1; - DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; - DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; - DIG_ENCODER_CONTROL_PARAMETERS_V4 v4; -}; - -void -atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - union dig_encoder_control args; - int index = 0; - uint8_t frev, crev; - int dp_clock = 0; - int dp_lane_count = 0; - int hpd_id = RADEON_HPD_NONE; - int bpc = 8; - - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; - - dp_clock = dig_connector->dp_clock; - dp_lane_count = dig_connector->dp_lane_count; - hpd_id = radeon_connector->hpd.hpd; - /* bpc = connector->display_info.bpc; */ - } - - /* no dig encoder assigned */ - if (dig->dig_encoder == -1) - return; - - memset(&args, 0, sizeof(args)); - - if (ASIC_IS_DCE4(rdev)) - index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); - else { - if (dig->dig_encoder) - index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); - else - index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); - } - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - switch (frev) { - case 1: - switch (crev) { - case 1: - args.v1.ucAction = action; - args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) - args.v3.ucPanelMode = panel_mode; - else - args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) - args.v1.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v1.ucLaneNum = 8; - else - args.v1.ucLaneNum = 4; - - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) - args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; - break; - } - if (dig->linkb) - args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; - else - args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; - break; - case 2: - case 3: - args.v3.ucAction = action; - args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) - args.v3.ucPanelMode = panel_mode; - else - args.v3.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) - args.v3.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v3.ucLaneNum = 8; - else - args.v3.ucLaneNum = 4; - - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000)) - args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; - args.v3.acConfig.ucDigSel = dig->dig_encoder; - switch (bpc) { - case 0: - args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; - break; - case 6: - args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; - break; - case 8: - default: - args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; - break; - case 10: - args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; - break; - case 12: - args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; - break; - case 16: - args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; - break; - } - break; - case 4: - args.v4.ucAction = action; - args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) - args.v4.ucPanelMode = panel_mode; - else - args.v4.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) - args.v4.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v4.ucLaneNum = 8; - else - args.v4.ucLaneNum = 4; - - if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) { - if (dp_clock == 270000) - args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ; - else if (dp_clock == 540000) - args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; - } - args.v4.acConfig.ucDigSel = dig->dig_encoder; - switch (bpc) { - case 0: - args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; - break; - case 6: - args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; - break; - case 8: - default: - args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; - break; - case 10: - args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; - break; - case 12: - args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; - break; - case 16: - args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; - break; - } - if (hpd_id == RADEON_HPD_NONE) - args.v4.ucHPD_ID = 0; - else - args.v4.ucHPD_ID = hpd_id + 1; - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - -} - -union dig_transmitter_control { - DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; - DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; - DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; - DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4; - DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 v5; -}; - -void -atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t lane_num, uint8_t lane_set) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - struct drm_connector *connector; - union dig_transmitter_control args; - int index = 0; - uint8_t frev, crev; - bool is_dp = false; - int pll_id = 0; - int dp_clock = 0; - int dp_lane_count = 0; - int connector_object_id = 0; - int igp_lane_info = 0; - int dig_encoder = dig->dig_encoder; - int hpd_id = RADEON_HPD_NONE; - - if (action == ATOM_TRANSMITTER_ACTION_INIT) { - connector = radeon_get_connector_for_encoder_init(encoder); - /* just needed to avoid bailing in the encoder check. the encoder - * isn't used for init - */ - dig_encoder = 0; - } else - connector = radeon_get_connector_for_encoder(encoder); - - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; - - hpd_id = radeon_connector->hpd.hpd; - dp_clock = dig_connector->dp_clock; - dp_lane_count = dig_connector->dp_lane_count; - connector_object_id = - (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - igp_lane_info = dig_connector->igp_lane_info; - } - - if (encoder->crtc) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - pll_id = radeon_crtc->pll_id; - } - - /* no dig encoder assigned */ - if (dig_encoder == -1) - return; - - if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder))) - is_dp = true; - - memset(&args, 0, sizeof(args)); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); - break; - } - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - switch (frev) { - case 1: - switch (crev) { - case 1: - args.v1.ucAction = action; - if (action == ATOM_TRANSMITTER_ACTION_INIT) { - args.v1.usInitInfo = cpu_to_le16(connector_object_id); - } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { - args.v1.asMode.ucLaneSel = lane_num; - args.v1.asMode.ucLaneSet = lane_set; - } else { - if (is_dp) - args.v1.usPixelClock = - cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); - else - args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - } - - args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; - - if (dig_encoder) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER; - else - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; - - if ((rdev->flags & RADEON_IS_IGP) && - (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { - if (is_dp || - !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) { - if (igp_lane_info & 0x1) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; - else if (igp_lane_info & 0x2) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; - else if (igp_lane_info & 0x4) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; - else if (igp_lane_info & 0x8) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; - } else { - if (igp_lane_info & 0x3) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; - else if (igp_lane_info & 0xc) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; - } - } - - if (dig->linkb) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; - else - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; - - if (is_dp) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; - else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (dig->coherent_mode) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; - } - break; - case 2: - args.v2.ucAction = action; - if (action == ATOM_TRANSMITTER_ACTION_INIT) { - args.v2.usInitInfo = cpu_to_le16(connector_object_id); - } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { - args.v2.asMode.ucLaneSel = lane_num; - args.v2.asMode.ucLaneSet = lane_set; - } else { - if (is_dp) - args.v2.usPixelClock = - cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); - else - args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - } - - args.v2.acConfig.ucEncoderSel = dig_encoder; - if (dig->linkb) - args.v2.acConfig.ucLinkSel = 1; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.v2.acConfig.ucTransmitterSel = 0; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - args.v2.acConfig.ucTransmitterSel = 1; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - args.v2.acConfig.ucTransmitterSel = 2; - break; - } - - if (is_dp) { - args.v2.acConfig.fCoherentMode = 1; - args.v2.acConfig.fDPConnector = 1; - } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (dig->coherent_mode) - args.v2.acConfig.fCoherentMode = 1; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v2.acConfig.fDualLinkConnector = 1; - } - break; - case 3: - args.v3.ucAction = action; - if (action == ATOM_TRANSMITTER_ACTION_INIT) { - args.v3.usInitInfo = cpu_to_le16(connector_object_id); - } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { - args.v3.asMode.ucLaneSel = lane_num; - args.v3.asMode.ucLaneSet = lane_set; - } else { - if (is_dp) - args.v3.usPixelClock = - cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); - else - args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - } - - if (is_dp) - args.v3.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v3.ucLaneNum = 8; - else - args.v3.ucLaneNum = 4; - - if (dig->linkb) - args.v3.acConfig.ucLinkSel = 1; - if (dig_encoder & 1) - args.v3.acConfig.ucEncoderSel = 1; - - /* Select the PLL for the PHY - * DP PHY should be clocked from external src if there is - * one. - */ - /* On DCE4, if there is an external clock, it generates the DP ref clock */ - if (is_dp && rdev->clock.dp_extclk) - args.v3.acConfig.ucRefClkSource = 2; /* external src */ - else - args.v3.acConfig.ucRefClkSource = pll_id; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.v3.acConfig.ucTransmitterSel = 0; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - args.v3.acConfig.ucTransmitterSel = 1; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - args.v3.acConfig.ucTransmitterSel = 2; - break; - } - - if (is_dp) - args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ - else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (dig->coherent_mode) - args.v3.acConfig.fCoherentMode = 1; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v3.acConfig.fDualLinkConnector = 1; - } - break; - case 4: - args.v4.ucAction = action; - if (action == ATOM_TRANSMITTER_ACTION_INIT) { - args.v4.usInitInfo = cpu_to_le16(connector_object_id); - } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { - args.v4.asMode.ucLaneSel = lane_num; - args.v4.asMode.ucLaneSet = lane_set; - } else { - if (is_dp) - args.v4.usPixelClock = - cpu_to_le16(dp_clock / 10); - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); - else - args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - } - - if (is_dp) - args.v4.ucLaneNum = dp_lane_count; - else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v4.ucLaneNum = 8; - else - args.v4.ucLaneNum = 4; - - if (dig->linkb) - args.v4.acConfig.ucLinkSel = 1; - if (dig_encoder & 1) - args.v4.acConfig.ucEncoderSel = 1; - - /* Select the PLL for the PHY - * DP PHY should be clocked from external src if there is - * one. - */ - /* On DCE5 DCPLL usually generates the DP ref clock */ - if (is_dp) { - if (rdev->clock.dp_extclk) - args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK; - else - args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL; - } else - args.v4.acConfig.ucRefClkSource = pll_id; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - args.v4.acConfig.ucTransmitterSel = 0; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - args.v4.acConfig.ucTransmitterSel = 1; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - args.v4.acConfig.ucTransmitterSel = 2; - break; - } - - if (is_dp) - args.v4.acConfig.fCoherentMode = 1; /* DP requires coherent */ - else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (dig->coherent_mode) - args.v4.acConfig.fCoherentMode = 1; - if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v4.acConfig.fDualLinkConnector = 1; - } - break; - case 5: - args.v5.ucAction = action; - if (is_dp) - args.v5.usSymClock = cpu_to_le16(dp_clock / 10); - else - args.v5.usSymClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - if (dig->linkb) - args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYB; - else - args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYA; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - if (dig->linkb) - args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYD; - else - args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYC; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - if (dig->linkb) - args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYF; - else - args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYE; - break; - } - if (is_dp) - args.v5.ucLaneNum = dp_lane_count; - else if (radeon_encoder->pixel_clock > 165000) - args.v5.ucLaneNum = 8; - else - args.v5.ucLaneNum = 4; - args.v5.ucConnObjId = connector_object_id; - args.v5.ucDigMode = atombios_get_encoder_mode(encoder); - - if (is_dp && rdev->clock.dp_extclk) - args.v5.asConfig.ucPhyClkSrcId = ENCODER_REFCLK_SRC_EXTCLK; - else - args.v5.asConfig.ucPhyClkSrcId = pll_id; - - if (is_dp) - args.v5.asConfig.ucCoherentMode = 1; /* DP requires coherent */ - else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (dig->coherent_mode) - args.v5.asConfig.ucCoherentMode = 1; - } - if (hpd_id == RADEON_HPD_NONE) - args.v5.asConfig.ucHPDSel = 0; - else - args.v5.asConfig.ucHPDSel = hpd_id + 1; - args.v5.ucDigEncoderSel = 1 << dig_encoder; - args.v5.ucDPLaneSet = lane_set; - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - break; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -bool -atombios_set_edp_panel_power(struct drm_connector *connector, int action) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_device *dev = radeon_connector->base.dev; - struct radeon_device *rdev = dev->dev_private; - union dig_transmitter_control args; - int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); - uint8_t frev, crev; - - if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) - goto done; - - if (!ASIC_IS_DCE4(rdev)) - goto done; - - if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && - (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) - goto done; - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - goto done; - - memset(&args, 0, sizeof(args)); - - args.v1.ucAction = action; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - /* wait for the panel to power up */ - if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) { - int i; - - for (i = 0; i < 300; i++) { - if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) - return true; - mdelay(1); - } - return false; - } -done: - return true; -} - -union external_encoder_control { - EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; - EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; -}; - -static void -atombios_external_encoder_setup(struct drm_encoder *encoder, - struct drm_encoder *ext_encoder, - int action) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); - union external_encoder_control args; - struct drm_connector *connector; - int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); - u8 frev, crev; - int dp_clock = 0; - int dp_lane_count = 0; - int connector_object_id = 0; - u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - int bpc = 8; - - if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) - connector = radeon_get_connector_for_encoder_init(encoder); - else - connector = radeon_get_connector_for_encoder(encoder); - - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *dig_connector = - radeon_connector->con_priv; - - dp_clock = dig_connector->dp_clock; - dp_lane_count = dig_connector->dp_lane_count; - connector_object_id = - (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - /* bpc = connector->display_info.bpc; */ - } - - memset(&args, 0, sizeof(args)); - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - switch (frev) { - case 1: - /* no params on frev 1 */ - break; - case 2: - switch (crev) { - case 1: - case 2: - args.v1.sDigEncoder.ucAction = action; - args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (ENCODER_MODE_IS_DP(args.v1.sDigEncoder.ucEncoderMode)) { - if (dp_clock == 270000) - args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; - args.v1.sDigEncoder.ucLaneNum = dp_lane_count; - } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v1.sDigEncoder.ucLaneNum = 8; - else - args.v1.sDigEncoder.ucLaneNum = 4; - break; - case 3: - args.v3.sExtEncoder.ucAction = action; - if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) - args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); - else - args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); - args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); - - if (ENCODER_MODE_IS_DP(args.v3.sExtEncoder.ucEncoderMode)) { - if (dp_clock == 270000) - args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; - else if (dp_clock == 540000) - args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; - args.v3.sExtEncoder.ucLaneNum = dp_lane_count; - } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) - args.v3.sExtEncoder.ucLaneNum = 8; - else - args.v3.sExtEncoder.ucLaneNum = 4; - switch (ext_enum) { - case GRAPH_OBJECT_ENUM_ID1: - args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; - break; - case GRAPH_OBJECT_ENUM_ID2: - args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; - break; - case GRAPH_OBJECT_ENUM_ID3: - args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; - break; - } - switch (bpc) { - case 0: - args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; - break; - case 6: - args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; - break; - case 8: - default: - args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; - break; - case 10: - args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; - break; - case 12: - args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; - break; - case 16: - args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; - break; - } - break; - default: - DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); - return; - } - break; - default: - DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); - return; - } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static void -atombios_yuv_setup(struct drm_encoder *encoder, bool enable) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - ENABLE_YUV_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, EnableYUV); - uint32_t temp, reg; - - memset(&args, 0, sizeof(args)); - - if (rdev->family >= CHIP_R600) - reg = R600_BIOS_3_SCRATCH; - else - reg = RADEON_BIOS_3_SCRATCH; - - /* XXX: fix up scratch reg handling */ - temp = RREG32(reg); - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - WREG32(reg, (ATOM_S3_TV1_ACTIVE | - (radeon_crtc->crtc_id << 18))); - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); - else - WREG32(reg, 0); - - if (enable) - args.ucEnable = ATOM_ENABLE; - args.ucCRTC = radeon_crtc->crtc_id; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - WREG32(reg, temp); -} - -static void -radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; - int index = 0; - - memset(&args, 0, sizeof(args)); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); - break; - default: - return; - } - - switch (mode) { - case DRM_MODE_DPMS_ON: - args.ucAction = ATOM_ENABLE; - /* workaround for DVOOutputControl on some RS690 systems */ - if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { - u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); - WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - WREG32(RADEON_BIOS_3_SCRATCH, reg); - } else - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - args.ucAction = ATOM_LCD_BLON; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - } - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - args.ucAction = ATOM_DISABLE; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - args.ucAction = ATOM_LCD_BLOFF; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - } - break; - } -} - -static void -radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - struct radeon_connector *radeon_connector = NULL; - struct radeon_connector_atom_dig *radeon_dig_connector = NULL; - - if (connector) { - radeon_connector = to_radeon_connector(connector); - radeon_dig_connector = radeon_connector->con_priv; - } - - switch (mode) { - case DRM_MODE_DPMS_ON: - /* some early dce3.2 boards have a bug in their transmitter control table */ - if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || - ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); - else - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); - if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_ON); - radeon_dig_connector->edp_on = true; - } - radeon_dp_link_train(encoder, connector); - if (ASIC_IS_DCE4(rdev)) - atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); - } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - else - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); - if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { - if (ASIC_IS_DCE4(rdev)) - atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_OFF); - radeon_dig_connector->edp_on = false; - } - } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); - break; - } -} - -static void -radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder, - struct drm_encoder *ext_encoder, - int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - - switch (mode) { - case DRM_MODE_DPMS_ON: - default: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) { - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT); - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF); - } else - atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) { - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING); - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT); - } else - atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); - break; - } -} - -static void -radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); - - DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", - radeon_encoder->encoder_id, mode, radeon_encoder->devices, - radeon_encoder->active_device); - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - radeon_atom_encoder_dpms_avivo(encoder, mode); - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - radeon_atom_encoder_dpms_dig(encoder, mode); - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - if (ASIC_IS_DCE5(rdev)) { - switch (mode) { - case DRM_MODE_DPMS_ON: - atombios_dvo_setup(encoder, ATOM_ENABLE); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - atombios_dvo_setup(encoder, ATOM_DISABLE); - break; - } - } else if (ASIC_IS_DCE3(rdev)) - radeon_atom_encoder_dpms_dig(encoder, mode); - else - radeon_atom_encoder_dpms_avivo(encoder, mode); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - if (ASIC_IS_DCE5(rdev)) { - switch (mode) { - case DRM_MODE_DPMS_ON: - atombios_dac_setup(encoder, ATOM_ENABLE); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - atombios_dac_setup(encoder, ATOM_DISABLE); - break; - } - } else - radeon_atom_encoder_dpms_avivo(encoder, mode); - break; - default: - return; - } - - if (ext_encoder) - radeon_atom_encoder_dpms_ext(encoder, ext_encoder, mode); - - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - -} - -union crtc_source_param { - SELECT_CRTC_SOURCE_PS_ALLOCATION v1; - SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; -}; - -static void -atombios_set_encoder_crtc_source(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - union crtc_source_param args; - int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); - uint8_t frev, crev; - struct radeon_encoder_atom_dig *dig; - - memset(&args, 0, sizeof(args)); - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - switch (frev) { - case 1: - switch (crev) { - case 1: - default: - if (ASIC_IS_AVIVO(rdev)) - args.v1.ucCRTC = radeon_crtc->crtc_id; - else { - if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) { - args.v1.ucCRTC = radeon_crtc->crtc_id; - } else { - args.v1.ucCRTC = radeon_crtc->crtc_id << 2; - } - } - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - args.v1.ucDevice = ATOM_DEVICE_DFP1_INDEX; - break; - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) - args.v1.ucDevice = ATOM_DEVICE_LCD1_INDEX; - else - args.v1.ucDevice = ATOM_DEVICE_DFP3_INDEX; - break; - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - args.v1.ucDevice = ATOM_DEVICE_DFP2_INDEX; - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; - else - args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; - else - args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; - break; - } - break; - case 2: - args.v2.ucCRTC = radeon_crtc->crtc_id; - if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) { - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - - if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) - args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; - else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) - args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; - else - args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); - } else - args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - dig = radeon_encoder->enc_priv; - switch (dig->dig_encoder) { - case 0: - args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; - break; - case 1: - args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; - break; - case 2: - args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; - break; - case 3: - args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; - break; - case 4: - args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; - break; - case 5: - args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; - break; - } - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - else - args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - else - args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; - break; - } - break; - } - break; - default: - DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); - return; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - /* update scratch regs with new routing */ - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); -} - -static void -atombios_apply_encoder_quirks(struct drm_encoder *encoder, - struct drm_display_mode *mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - - /* Funky macbooks */ - if ((dev->pdev->device == 0x71C5) && - (dev->pdev->subsystem_vendor == 0x106b) && - (dev->pdev->subsystem_device == 0x0080)) { - if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { - uint32_t lvtma_bit_depth_control = RREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL); - - lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN; - lvtma_bit_depth_control &= ~AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN; - - WREG32(AVIVO_LVTMA_BIT_DEPTH_CONTROL, lvtma_bit_depth_control); - } - } - - /* set scaler clears this on some chips */ - if (ASIC_IS_AVIVO(rdev) && - (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { - if (ASIC_IS_DCE4(rdev)) { - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, - EVERGREEN_INTERLEAVE_EN); - else - WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); - } else { - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, - AVIVO_D1MODE_INTERLEAVE_EN); - else - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); - } - } -} - -static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *test_encoder; - struct radeon_encoder_atom_dig *dig; - uint32_t dig_enc_in_use = 0; - - /* DCE4/5 */ - if (ASIC_IS_DCE4(rdev)) { - dig = radeon_encoder->enc_priv; - if (ASIC_IS_DCE41(rdev)) { - /* ontario follows DCE4 */ - if (rdev->family == CHIP_PALM) { - if (dig->linkb) - return 1; - else - return 0; - } else - /* llano follows DCE3.2 */ - return radeon_crtc->crtc_id; - } else { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - if (dig->linkb) - return 1; - else - return 0; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - if (dig->linkb) - return 3; - else - return 2; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - if (dig->linkb) - return 5; - else - return 4; - break; - } - } - } - - /* on DCE32 and encoder can driver any block so just crtc id */ - if (ASIC_IS_DCE32(rdev)) { - return radeon_crtc->crtc_id; - } - - /* on DCE3 - LVTMA can only be driven by DIGB */ - list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { - struct radeon_encoder *radeon_test_encoder; - - if (encoder == test_encoder) - continue; - - if (!radeon_encoder_is_digital(test_encoder)) - continue; - - radeon_test_encoder = to_radeon_encoder(test_encoder); - dig = radeon_test_encoder->enc_priv; - - if (dig->dig_encoder >= 0) - dig_enc_in_use |= (1 << dig->dig_encoder); - } - - if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA) { - if (dig_enc_in_use & 0x2) - DRM_ERROR("LVDS required digital encoder 2 but it was in use - stealing\n"); - return 1; - } - if (!(dig_enc_in_use & 1)) - return 0; - return 1; -} - -/* This only needs to be called once at startup */ -void -radeon_atom_encoder_init(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_encoder *encoder; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); - break; - default: - break; - } - - if (ext_encoder && (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))) - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); - } -} - -static void -radeon_atom_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); - - radeon_encoder->pixel_clock = adjusted_mode->clock; - - if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { - if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) - atombios_yuv_setup(encoder, true); - else - atombios_yuv_setup(encoder, false); - } - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - - if (!connector) - dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; - else - dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); - - /* setup and enable the encoder */ - atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); - atombios_dig_encoder_setup(encoder, - ATOM_ENCODER_CMD_SETUP_PANEL_MODE, - dig->panel_mode); - } else if (ASIC_IS_DCE4(rdev)) { - /* disable the transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - /* setup and enable the encoder */ - atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); - - /* enable the transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); - } else { - /* disable the encoder and transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); - - /* setup and enable the encoder and transmitter */ - atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); - } - break; - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - atombios_dvo_setup(encoder, ATOM_ENABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - atombios_dac_setup(encoder, ATOM_ENABLE); - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { - if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - atombios_tv_setup(encoder, ATOM_ENABLE); - else - atombios_tv_setup(encoder, ATOM_DISABLE); - } - break; - } - - if (ext_encoder) { - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); - else - atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); - } - - atombios_apply_encoder_quirks(encoder, adjusted_mode); - - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { - r600_hdmi_enable(encoder); - r600_hdmi_setmode(encoder, adjusted_mode); - } -} - -static bool -atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | - ATOM_DEVICE_CV_SUPPORT | - ATOM_DEVICE_CRT_SUPPORT)) { - DAC_LOAD_DETECTION_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); - uint8_t frev, crev; - - memset(&args, 0, sizeof(args)); - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return false; - - args.sDacload.ucMisc = 0; - - if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1) || - (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1)) - args.sDacload.ucDacType = ATOM_DAC_A; - else - args.sDacload.ucDacType = ATOM_DAC_B; - - if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); - else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); - else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); - if (crev >= 3) - args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; - } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); - if (crev >= 3) - args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - return true; - } else - return false; -} - -static enum drm_connector_status -radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - uint32_t bios_0_scratch; - - if (!atombios_dac_load_detect(encoder, connector)) { - DRM_DEBUG_KMS("detect returned false \n"); - return connector_status_unknown; - } - - if (rdev->family >= CHIP_R600) - bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); - else - bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); - - DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); - if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT1_MASK) - return connector_status_connected; - } - if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT2_MASK) - return connector_status_connected; - } - if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) - return connector_status_connected; - } - if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) - return connector_status_connected; /* CTV */ - else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) - return connector_status_connected; /* STV */ - } - return connector_status_disconnected; -} - -static enum drm_connector_status -radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); - u32 bios_0_scratch; - - if (!ASIC_IS_DCE4(rdev)) - return connector_status_unknown; - - if (!ext_encoder) - return connector_status_unknown; - - if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0) - return connector_status_unknown; - - /* load detect on the dp bridge */ - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION); - - bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); - - DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); - if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT1_MASK) - return connector_status_connected; - } - if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT2_MASK) - return connector_status_connected; - } - if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) - return connector_status_connected; - } - if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) - return connector_status_connected; /* CTV */ - else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) - return connector_status_connected; /* STV */ - } - return connector_status_disconnected; -} - -void -radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) -{ - struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); - - if (ext_encoder) - /* ddc_setup on the dp bridge */ - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); - -} - -static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); - - if ((radeon_encoder->active_device & - (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || - (radeon_encoder_get_dp_bridge_encoder_id(encoder) != - ENCODER_OBJECT_ID_NONE)) { - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - if (dig) - dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); - } - - radeon_atom_output_lock(encoder, true); - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); - - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - /* select the clock/data port if it uses a router */ - if (radeon_connector->router.cd_valid) - radeon_router_select_cd_port(radeon_connector); - - /* turn eDP panel on for mode set */ - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_ON); - } - - /* this is needed for the pll/ss setup to work correctly in some cases */ - atombios_set_encoder_crtc_source(encoder); -} - -static void radeon_atom_encoder_commit(struct drm_encoder *encoder) -{ - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); - radeon_atom_output_lock(encoder, false); -} - -static void radeon_atom_encoder_disable(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig; - - /* check for pre-DCE3 cards with shared encoders; - * can't really use the links individually, so don't disable - * the encoder if it's in use by another connector - */ - if (!ASIC_IS_DCE3(rdev)) { - struct drm_encoder *other_encoder; - struct radeon_encoder *other_radeon_encoder; - - list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { - other_radeon_encoder = to_radeon_encoder(other_encoder); - if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && - drm_helper_encoder_in_use(other_encoder)) - goto disable_done; - } - } - - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_DISABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - if (ASIC_IS_DCE4(rdev)) - /* disable the transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - else { - /* disable the encoder and transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); - atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); - } - break; - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - atombios_dvo_setup(encoder, ATOM_DISABLE); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - atombios_dac_setup(encoder, ATOM_DISABLE); - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - atombios_tv_setup(encoder, ATOM_DISABLE); - break; - } - -disable_done: - if (radeon_encoder_is_digital(encoder)) { - if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) - r600_hdmi_disable(encoder); - dig = radeon_encoder->enc_priv; - dig->dig_encoder = -1; - } - radeon_encoder->active_device = 0; -} - -/* these are handled by the primary encoders */ -static void radeon_atom_ext_prepare(struct drm_encoder *encoder) -{ - -} - -static void radeon_atom_ext_commit(struct drm_encoder *encoder) -{ - -} - -static void -radeon_atom_ext_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - -} - -static void radeon_atom_ext_disable(struct drm_encoder *encoder) -{ - -} - -static void -radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) -{ - -} - -static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { - .dpms = radeon_atom_ext_dpms, - .mode_fixup = radeon_atom_ext_mode_fixup, - .prepare = radeon_atom_ext_prepare, - .mode_set = radeon_atom_ext_mode_set, - .commit = radeon_atom_ext_commit, - .disable = radeon_atom_ext_disable, - /* no detect for TMDS/LVDS yet */ -}; - -static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { - .dpms = radeon_atom_encoder_dpms, - .mode_fixup = radeon_atom_mode_fixup, - .prepare = radeon_atom_encoder_prepare, - .mode_set = radeon_atom_encoder_mode_set, - .commit = radeon_atom_encoder_commit, - .disable = radeon_atom_encoder_disable, - .detect = radeon_atom_dig_detect, -}; - -static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { - .dpms = radeon_atom_encoder_dpms, - .mode_fixup = radeon_atom_mode_fixup, - .prepare = radeon_atom_encoder_prepare, - .mode_set = radeon_atom_encoder_mode_set, - .commit = radeon_atom_encoder_commit, - .detect = radeon_atom_dac_detect, -}; - -void radeon_enc_destroy(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - kfree(radeon_encoder->enc_priv); - drm_encoder_cleanup(encoder); - kfree(radeon_encoder); -} - -static const struct drm_encoder_funcs radeon_atom_enc_funcs = { - .destroy = radeon_enc_destroy, -}; - -struct radeon_encoder_atom_dac * -radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); - - if (!dac) - return NULL; - - dac->tv_std = radeon_atombios_get_tv_info(rdev); - return dac; -} - -struct radeon_encoder_atom_dig * -radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) -{ - int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); - - if (!dig) - return NULL; - - /* coherent mode by default */ - dig->coherent_mode = true; - dig->dig_encoder = -1; - - if (encoder_enum == 2) - dig->linkb = true; - else - dig->linkb = false; - - return dig; -} - -void -radeon_add_atom_encoder(struct drm_device *dev, - uint32_t encoder_enum, - uint32_t supported_device, - u16 caps) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - - /* see if we already added it */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->encoder_enum == encoder_enum) { - radeon_encoder->devices |= supported_device; - return; - } - - } - - /* add a new one */ - radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); - if (!radeon_encoder) - return; - - encoder = &radeon_encoder->base; - switch (rdev->num_crtc) { - case 1: - encoder->possible_crtcs = 0x1; - break; - case 2: - default: - encoder->possible_crtcs = 0x3; - break; - case 4: - encoder->possible_crtcs = 0xf; - break; - case 6: - encoder->possible_crtcs = 0x3f; - break; - } - - radeon_encoder->enc_priv = NULL; - - radeon_encoder->encoder_enum = encoder_enum; - radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - radeon_encoder->devices = supported_device; - radeon_encoder->rmx_type = RMX_OFF; - radeon_encoder->underscan_type = UNDERSCAN_OFF; - radeon_encoder->is_ext_encoder = false; - radeon_encoder->caps = caps; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - radeon_encoder->rmx_type = RMX_FULL; - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); - radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); - } else { - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); - radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); - } - drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); - radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); - drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); - radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); - drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); - break; - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: - case ENCODER_OBJECT_ID_INTERNAL_DDI: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - radeon_encoder->rmx_type = RMX_FULL; - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); - radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); - } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); - radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); - } else { - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); - radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); - } - drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); - break; - case ENCODER_OBJECT_ID_SI170B: - case ENCODER_OBJECT_ID_CH7303: - case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: - case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: - case ENCODER_OBJECT_ID_TITFP513: - case ENCODER_OBJECT_ID_VT1623: - case ENCODER_OBJECT_ID_HDMI_SI1930: - case ENCODER_OBJECT_ID_TRAVIS: - case ENCODER_OBJECT_ID_NUTMEG: - /* these are handled by the primary encoders */ - radeon_encoder->is_ext_encoder = true; - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); - else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); - else - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); - break; - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_i2c.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_i2c.c deleted file mode 100644 index 44d87b6b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/atombios_i2c.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2011 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - * - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" - -#define TARGET_HW_I2C_CLOCK 50 - -/* these are a limitation of ProcessI2cChannelTransaction not the hw */ -#define ATOM_MAX_HW_I2C_WRITE 2 -#define ATOM_MAX_HW_I2C_READ 255 - -static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, - u8 slave_addr, u8 flags, - u8 *buf, u8 num) -{ - struct drm_device *dev = chan->dev; - struct radeon_device *rdev = dev->dev_private; - PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); - unsigned char *base; - u16 out; - - memset(&args, 0, sizeof(args)); - - base = (unsigned char *)rdev->mode_info.atom_context->scratch; - - if (flags & HW_I2C_WRITE) { - if (num > ATOM_MAX_HW_I2C_WRITE) { - DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num); - return -EINVAL; - } - memcpy(&out, buf, num); - args.lpI2CDataOut = cpu_to_le16(out); - } else { - if (num > ATOM_MAX_HW_I2C_READ) { - DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); - return -EINVAL; - } - } - - args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; - args.ucRegIndex = 0; - args.ucTransBytes = num; - args.ucSlaveAddr = slave_addr << 1; - args.ucLineNumber = chan->rec.i2c_id; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - /* error */ - if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { - DRM_DEBUG_KMS("hw_i2c error\n"); - return -EIO; - } - - if (!(flags & HW_I2C_WRITE)) - memcpy(buf, base, num); - - return 0; -} - -int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); - struct i2c_msg *p; - int i, remaining, current_count, buffer_offset, max_bytes, ret; - u8 buf = 0, flags; - - /* check for bus probe */ - p = &msgs[0]; - if ((num == 1) && (p->len == 0)) { - ret = radeon_process_i2c_ch(i2c, - p->addr, HW_I2C_WRITE, - &buf, 1); - if (ret) - return ret; - else - return num; - } - - for (i = 0; i < num; i++) { - p = &msgs[i]; - remaining = p->len; - buffer_offset = 0; - /* max_bytes are a limitation of ProcessI2cChannelTransaction not the hw */ - if (p->flags & I2C_M_RD) { - max_bytes = ATOM_MAX_HW_I2C_READ; - flags = HW_I2C_READ; - } else { - max_bytes = ATOM_MAX_HW_I2C_WRITE; - flags = HW_I2C_WRITE; - } - while (remaining) { - if (remaining > max_bytes) - current_count = max_bytes; - else - current_count = remaining; - ret = radeon_process_i2c_ch(i2c, - p->addr, flags, - &p->buf[buffer_offset], current_count); - if (ret) - return ret; - remaining -= current_count; - buffer_offset += current_count; - } - } - - return num; -} - -u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/avivod.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/avivod.h deleted file mode 100644 index 3c391e7e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/avivod.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef AVIVOD_H -#define AVIVOD_H - - -#define D1CRTC_CONTROL 0x6080 -#define CRTC_EN (1 << 0) -#define D1CRTC_STATUS 0x609c -#define D1CRTC_UPDATE_LOCK 0x60E8 -#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 -#define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 - -#define D2CRTC_CONTROL 0x6880 -#define D2CRTC_STATUS 0x689c -#define D2CRTC_UPDATE_LOCK 0x68E8 -#define D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910 -#define D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918 - -#define D1VGA_CONTROL 0x0330 -#define DVGA_CONTROL_MODE_ENABLE (1 << 0) -#define DVGA_CONTROL_TIMING_SELECT (1 << 8) -#define DVGA_CONTROL_SYNC_POLARITY_SELECT (1 << 9) -#define DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1 << 10) -#define DVGA_CONTROL_OVERSCAN_COLOR_EN (1 << 16) -#define DVGA_CONTROL_ROTATE (1 << 24) -#define D2VGA_CONTROL 0x0338 - -#define VGA_HDP_CONTROL 0x328 -#define VGA_MEM_PAGE_SELECT_EN (1 << 0) -#define VGA_MEMORY_DISABLE (1 << 4) -#define VGA_RBBM_LOCK_DISABLE (1 << 8) -#define VGA_SOFT_RESET (1 << 16) -#define VGA_MEMORY_BASE_ADDRESS 0x0310 -#define VGA_RENDER_CONTROL 0x0300 -#define VGA_VSTATUS_CNTL_MASK 0x00030000 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.c deleted file mode 100644 index 19a0114d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Alex Deucher - */ - -#include -#include -#include - -/* - * evergreen cards need to use the 3D engine to blit data which requires - * quite a bit of hw state setup. Rather than pull the whole 3D driver - * (which normally generates the 3D state) into the DRM, we opt to use - * statically generated state tables. The regsiter state and shaders - * were hand generated to support blitting functionality. See the 3D - * driver or documentation for descriptions of the registers and - * shader instructions. - */ - -const u32 cayman_default_state[] = -{ - 0xc0066900, - 0x00000000, - 0x00000060, /* DB_RENDER_CONTROL */ - 0x00000000, /* DB_COUNT_CONTROL */ - 0x00000000, /* DB_DEPTH_VIEW */ - 0x0000002a, /* DB_RENDER_OVERRIDE */ - 0x00000000, /* DB_RENDER_OVERRIDE2 */ - 0x00000000, /* DB_HTILE_DATA_BASE */ - - 0xc0026900, - 0x0000000a, - 0x00000000, /* DB_STENCIL_CLEAR */ - 0x00000000, /* DB_DEPTH_CLEAR */ - - 0xc0036900, - 0x0000000f, - 0x00000000, /* DB_DEPTH_INFO */ - 0x00000000, /* DB_Z_INFO */ - 0x00000000, /* DB_STENCIL_INFO */ - - 0xc0016900, - 0x00000080, - 0x00000000, /* PA_SC_WINDOW_OFFSET */ - - 0xc00d6900, - 0x00000083, - 0x0000ffff, /* PA_SC_CLIPRECT_RULE */ - 0x00000000, /* PA_SC_CLIPRECT_0_TL */ - 0x20002000, /* PA_SC_CLIPRECT_0_BR */ - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0xaaaaaaaa, /* PA_SC_EDGERULE */ - 0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */ - 0x0000000f, /* CB_TARGET_MASK */ - 0x0000000f, /* CB_SHADER_MASK */ - - 0xc0226900, - 0x00000094, - 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, /* PA_SC_VPORT_ZMAX_0 */ - - 0xc0016900, - 0x000000d4, - 0x00000000, /* SX_MISC */ - - 0xc0026900, - 0x000000d9, - 0x00000000, /* CP_RINGID */ - 0x00000000, /* CP_VMID */ - - 0xc0096900, - 0x00000100, - 0x00ffffff, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* VGT_MIN_VTX_INDX */ - 0x00000000, /* VGT_INDX_OFFSET */ - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ - 0x00000000, /* SX_ALPHA_TEST_CONTROL */ - 0x00000000, /* CB_BLEND_RED */ - 0x00000000, /* CB_BLEND_GREEN */ - 0x00000000, /* CB_BLEND_BLUE */ - 0x00000000, /* CB_BLEND_ALPHA */ - - 0xc0016900, - 0x00000187, - 0x00000100, /* SPI_VS_OUT_ID_0 */ - - 0xc0026900, - 0x00000191, - 0x00000100, /* SPI_PS_INPUT_CNTL_0 */ - 0x00000101, /* SPI_PS_INPUT_CNTL_1 */ - - 0xc0016900, - 0x000001b1, - 0x00000000, /* SPI_VS_OUT_CONFIG */ - - 0xc0106900, - 0x000001b3, - 0x20000001, /* SPI_PS_IN_CONTROL_0 */ - 0x00000000, /* SPI_PS_IN_CONTROL_1 */ - 0x00000000, /* SPI_INTERP_CONTROL_0 */ - 0x00000000, /* SPI_INPUT_Z */ - 0x00000000, /* SPI_FOG_CNTL */ - 0x00100000, /* SPI_BARYC_CNTL */ - 0x00000000, /* SPI_PS_IN_CONTROL_2 */ - 0x00000000, /* SPI_COMPUTE_INPUT_CNTL */ - 0x00000000, /* SPI_COMPUTE_NUM_THREAD_X */ - 0x00000000, /* SPI_COMPUTE_NUM_THREAD_Y */ - 0x00000000, /* SPI_COMPUTE_NUM_THREAD_Z */ - 0x00000000, /* SPI_GPR_MGMT */ - 0x00000000, /* SPI_LDS_MGMT */ - 0x00000000, /* SPI_STACK_MGMT */ - 0x00000000, /* SPI_WAVE_MGMT_1 */ - 0x00000000, /* SPI_WAVE_MGMT_2 */ - - 0xc0016900, - 0x000001e0, - 0x00000000, /* CB_BLEND0_CONTROL */ - - 0xc00e6900, - 0x00000200, - 0x00000000, /* DB_DEPTH_CONTROL */ - 0x00000000, /* DB_EQAA */ - 0x00cc0010, /* CB_COLOR_CONTROL */ - 0x00000210, /* DB_SHADER_CONTROL */ - 0x00010000, /* PA_CL_CLIP_CNTL */ - 0x00000004, /* PA_SU_SC_MODE_CNTL */ - 0x00000100, /* PA_CL_VTE_CNTL */ - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ - 0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */ - 0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */ - 0x00000000, /* PA_SU_PRIM_FILTER_CNTL */ - 0x00000000, /* */ - 0x00000000, /* */ - - 0xc0026900, - 0x00000229, - 0x00000000, /* SQ_PGM_START_FS */ - 0x00000000, - - 0xc0016900, - 0x0000023b, - 0x00000000, /* SQ_LDS_ALLOC_PS */ - - 0xc0066900, - 0x00000240, - 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0046900, - 0x00000247, - 0x00000000, /* SQ_GS_VERT_ITEMSIZE */ - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0116900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ - 0x00000008, /* PA_SU_LINE_CNTL */ - 0x00000000, /* PA_SC_LINE_STIPPLE */ - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - 0x00000000, /* VGT_HOS_CNTL */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, /* VGT_GS_MODE */ - - 0xc0026900, - 0x00000292, - 0x00000000, /* PA_SC_MODE_CNTL_0 */ - 0x00000000, /* PA_SC_MODE_CNTL_1 */ - - 0xc0016900, - 0x000002a1, - 0x00000000, /* VGT_PRIMITIVEID_EN */ - - 0xc0016900, - 0x000002a5, - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */ - - 0xc0026900, - 0x000002a8, - 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - 0x00000000, - - 0xc0026900, - 0x000002ad, - 0x00000000, /* VGT_REUSE_OFF */ - 0x00000000, - - 0xc0016900, - 0x000002d5, - 0x00000000, /* VGT_SHADER_STAGES_EN */ - - 0xc0016900, - 0x000002dc, - 0x0000aa00, /* DB_ALPHA_TO_MASK */ - - 0xc0066900, - 0x000002de, - 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0026900, - 0x000002e5, - 0x00000000, /* VGT_STRMOUT_CONFIG */ - 0x00000000, - - 0xc01b6900, - 0x000002f5, - 0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */ - 0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */ - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - 0x00000005, /* PA_SU_VTX_CNTL */ - 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ - 0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */ - 0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */ - 0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */ - 0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */ - 0xffffffff, - - 0xc0026900, - 0x00000316, - 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - 0x00000010, /* */ -}; - -const u32 cayman_vs[] = -{ - 0x00000004, - 0x80400400, - 0x0000a03c, - 0x95000688, - 0x00004000, - 0x15000688, - 0x00000000, - 0x88000000, - 0x04000000, - 0x67961001, -#ifdef __BIG_ENDIAN - 0x00020000, -#else - 0x00000000, -#endif - 0x00000000, - 0x04000000, - 0x67961000, -#ifdef __BIG_ENDIAN - 0x00020008, -#else - 0x00000008, -#endif - 0x00000000, -}; - -const u32 cayman_ps[] = -{ - 0x00000004, - 0xa00c0000, - 0x00000008, - 0x80400000, - 0x00000000, - 0x95000688, - 0x00000000, - 0x88000000, - 0x00380400, - 0x00146b10, - 0x00380000, - 0x20146b10, - 0x00380400, - 0x40146b00, - 0x80380000, - 0x60146b00, - 0x00000010, - 0x000d1000, - 0xb0800000, - 0x00000000, -}; - -const u32 cayman_ps_size = ARRAY_SIZE(cayman_ps); -const u32 cayman_vs_size = ARRAY_SIZE(cayman_vs); -const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.h deleted file mode 100644 index f5d0e9a6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/cayman_blit_shaders.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef CAYMAN_BLIT_SHADERS_H -#define CAYMAN_BLIT_SHADERS_H - -extern const u32 cayman_ps[]; -extern const u32 cayman_vs[]; -extern const u32 cayman_default_state[]; - -extern const u32 cayman_ps_size, cayman_vs_size; -extern const u32 cayman_default_size; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen.c deleted file mode 100644 index e72c03ff..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen.c +++ /dev/null @@ -1,3507 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#include -#include -#include -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "radeon_drm.h" -#include "evergreend.h" -#include "atom.h" -#include "avivod.h" -#include "evergreen_reg.h" -#include "evergreen_blit_shaders.h" - -#define EVERGREEN_PFP_UCODE_SIZE 1120 -#define EVERGREEN_PM4_UCODE_SIZE 1376 - -static void evergreen_gpu_init(struct radeon_device *rdev); -void evergreen_fini(struct radeon_device *rdev); -void evergreen_pcie_gen2_enable(struct radeon_device *rdev); -extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, - int ring, u32 cp_int_cntl); - -void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, - unsigned *bankh, unsigned *mtaspect, - unsigned *tile_split) -{ - *bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; - *bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; - *mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; - *tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK; - switch (*bankw) { - default: - case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break; - case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break; - case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break; - case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break; - } - switch (*bankh) { - default: - case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break; - case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break; - case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break; - case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break; - } - switch (*mtaspect) { - default: - case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break; - case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break; - case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break; - case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break; - } -} - -void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) -{ - u16 ctl, v; - int cap, err; - - cap = pci_pcie_cap(rdev->pdev); - if (!cap) - return; - - err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); - if (err) - return; - - v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; - - /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it - * to avoid hangs or perfomance issues - */ - if ((v == 0) || (v == 6) || (v == 7)) { - ctl &= ~PCI_EXP_DEVCTL_READRQ; - ctl |= (2 << 12); - pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); - } -} - -void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - int i; - - if (RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_MASTER_EN) { - for (i = 0; i < rdev->usec_timeout; i++) { - if (!(RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK)) - break; - udelay(1); - } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK) - break; - udelay(1); - } - } -} - -void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) -{ - /* enable the pflip int */ - radeon_irq_kms_pflip_irq_get(rdev, crtc); -} - -void evergreen_post_page_flip(struct radeon_device *rdev, int crtc) -{ - /* disable the pflip int */ - radeon_irq_kms_pflip_irq_put(rdev, crtc); -} - -u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; - u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); - int i; - - /* Lock the graphics update lock */ - tmp |= EVERGREEN_GRPH_UPDATE_LOCK; - WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); - - /* update the scanout addresses */ - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, - upper_32_bits(crtc_base)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)crtc_base); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, - upper_32_bits(crtc_base)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)crtc_base); - - /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) - break; - udelay(1); - } - DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); - - /* Unlock the lock, so double-buffering can take place inside vblank */ - tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK; - WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); - - /* Return current update_pending status: */ - return RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING; -} - -/* get temperature in millidegrees */ -int evergreen_get_temp(struct radeon_device *rdev) -{ - u32 temp, toffset; - int actual_temp = 0; - - if (rdev->family == CHIP_JUNIPER) { - toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> - TOFFSET_SHIFT; - temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >> - TS0_ADC_DOUT_SHIFT; - - if (toffset & 0x100) - actual_temp = temp / 2 - (0x200 - toffset); - else - actual_temp = temp / 2 + toffset; - - actual_temp = actual_temp * 1000; - - } else { - temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> - ASIC_T_SHIFT; - - if (temp & 0x400) - actual_temp = -256; - else if (temp & 0x200) - actual_temp = 255; - else if (temp & 0x100) { - actual_temp = temp & 0x1ff; - actual_temp |= ~0x1ff; - } else - actual_temp = temp & 0xff; - - actual_temp = (actual_temp * 1000) / 2; - } - - return actual_temp; -} - -int sumo_get_temp(struct radeon_device *rdev) -{ - u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; - int actual_temp = temp - 49; - - return actual_temp * 1000; -} - -void sumo_pm_init_profile(struct radeon_device *rdev) -{ - int idx; - - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - - /* low,mid sh/mh */ - if (rdev->flags & RADEON_IS_MOBILITY) - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); - else - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - - /* high sh/mh */ - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = - rdev->pm.power_state[idx].num_clock_modes - 1; - - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = - rdev->pm.power_state[idx].num_clock_modes - 1; -} - -void evergreen_pm_misc(struct radeon_device *rdev) -{ - int req_ps_idx = rdev->pm.requested_power_state_index; - int req_cm_idx = rdev->pm.requested_clock_mode_index; - struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - - if (voltage->type == VOLTAGE_SW) { - /* 0xff01 is a flag rather then an actual voltage */ - if (voltage->voltage == 0xff01) - return; - if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { - radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); - } - /* 0xff01 is a flag rather then an actual voltage */ - if (voltage->vddci == 0xff01) - return; - if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { - radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); - rdev->pm.current_vddci = voltage->vddci; - DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci); - } - } -} - -void evergreen_pm_prepare(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* disable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - -void evergreen_pm_finish(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* enable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - -bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) -{ - bool connected = false; - - switch (hpd) { - case RADEON_HPD_1: - if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_2: - if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_3: - if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_4: - if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_5: - if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_6: - if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - default: - break; - } - - return connected; -} - -void evergreen_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd) -{ - u32 tmp; - bool connected = evergreen_hpd_sense(rdev, hpd); - - switch (hpd) { - case RADEON_HPD_1: - tmp = RREG32(DC_HPD1_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD1_INT_CONTROL, tmp); - break; - case RADEON_HPD_2: - tmp = RREG32(DC_HPD2_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD2_INT_CONTROL, tmp); - break; - case RADEON_HPD_3: - tmp = RREG32(DC_HPD3_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD3_INT_CONTROL, tmp); - break; - case RADEON_HPD_4: - tmp = RREG32(DC_HPD4_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD4_INT_CONTROL, tmp); - break; - case RADEON_HPD_5: - tmp = RREG32(DC_HPD5_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, tmp); - break; - case RADEON_HPD_6: - tmp = RREG32(DC_HPD6_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, tmp); - break; - default: - break; - } -} - -void evergreen_hpd_init(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | - DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(DC_HPD1_CONTROL, tmp); - rdev->irq.hpd[0] = true; - break; - case RADEON_HPD_2: - WREG32(DC_HPD2_CONTROL, tmp); - rdev->irq.hpd[1] = true; - break; - case RADEON_HPD_3: - WREG32(DC_HPD3_CONTROL, tmp); - rdev->irq.hpd[2] = true; - break; - case RADEON_HPD_4: - WREG32(DC_HPD4_CONTROL, tmp); - rdev->irq.hpd[3] = true; - break; - case RADEON_HPD_5: - WREG32(DC_HPD5_CONTROL, tmp); - rdev->irq.hpd[4] = true; - break; - case RADEON_HPD_6: - WREG32(DC_HPD6_CONTROL, tmp); - rdev->irq.hpd[5] = true; - break; - default: - break; - } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - } - if (rdev->irq.installed) - evergreen_irq_set(rdev); -} - -void evergreen_hpd_fini(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(DC_HPD1_CONTROL, 0); - rdev->irq.hpd[0] = false; - break; - case RADEON_HPD_2: - WREG32(DC_HPD2_CONTROL, 0); - rdev->irq.hpd[1] = false; - break; - case RADEON_HPD_3: - WREG32(DC_HPD3_CONTROL, 0); - rdev->irq.hpd[2] = false; - break; - case RADEON_HPD_4: - WREG32(DC_HPD4_CONTROL, 0); - rdev->irq.hpd[3] = false; - break; - case RADEON_HPD_5: - WREG32(DC_HPD5_CONTROL, 0); - rdev->irq.hpd[4] = false; - break; - case RADEON_HPD_6: - WREG32(DC_HPD6_CONTROL, 0); - rdev->irq.hpd[5] = false; - break; - default: - break; - } - } -} - -/* watermark setup */ - -static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, - struct radeon_crtc *radeon_crtc, - struct drm_display_mode *mode, - struct drm_display_mode *other_mode) -{ - u32 tmp; - /* - * Line Buffer Setup - * There are 3 line buffers, each one shared by 2 display controllers. - * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between - * the display controllers. The paritioning is done via one of four - * preset allocations specified in bits 2:0: - * first display controller - * 0 - first half of lb (3840 * 2) - * 1 - first 3/4 of lb (5760 * 2) - * 2 - whole lb (7680 * 2), other crtc must be disabled - * 3 - first 1/4 of lb (1920 * 2) - * second display controller - * 4 - second half of lb (3840 * 2) - * 5 - second 3/4 of lb (5760 * 2) - * 6 - whole lb (7680 * 2), other crtc must be disabled - * 7 - last 1/4 of lb (1920 * 2) - */ - /* this can get tricky if we have two large displays on a paired group - * of crtcs. Ideally for multiple large displays we'd assign them to - * non-linked crtcs for maximum line buffer allocation. - */ - if (radeon_crtc->base.enabled && mode) { - if (other_mode) - tmp = 0; /* 1/2 */ - else - tmp = 2; /* whole */ - } else - tmp = 0; - - /* second controller of the pair uses second half of the lb */ - if (radeon_crtc->crtc_id % 2) - tmp += 4; - WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); - - if (radeon_crtc->base.enabled && mode) { - switch (tmp) { - case 0: - case 4: - default: - if (ASIC_IS_DCE5(rdev)) - return 4096 * 2; - else - return 3840 * 2; - case 1: - case 5: - if (ASIC_IS_DCE5(rdev)) - return 6144 * 2; - else - return 5760 * 2; - case 2: - case 6: - if (ASIC_IS_DCE5(rdev)) - return 8192 * 2; - else - return 7680 * 2; - case 3: - case 7: - if (ASIC_IS_DCE5(rdev)) - return 2048 * 2; - else - return 1920 * 2; - } - } - - /* controller not enabled, so no lb used */ - return 0; -} - -u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) -{ - u32 tmp = RREG32(MC_SHARED_CHMAP); - - switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { - case 0: - default: - return 1; - case 1: - return 2; - case 2: - return 4; - case 3: - return 8; - } -} - -struct evergreen_wm_params { - u32 dram_channels; /* number of dram channels */ - u32 yclk; /* bandwidth per dram data pin in kHz */ - u32 sclk; /* engine clock in kHz */ - u32 disp_clk; /* display clock in kHz */ - u32 src_width; /* viewport width */ - u32 active_time; /* active display time in ns */ - u32 blank_time; /* blank time in ns */ - bool interlaced; /* mode is interlaced */ - fixed20_12 vsc; /* vertical scale ratio */ - u32 num_heads; /* number of active crtcs */ - u32 bytes_per_pixel; /* bytes per pixel display + overlay */ - u32 lb_size; /* line buffer allocated to pipe */ - u32 vtaps; /* vertical scaler taps */ -}; - -static u32 evergreen_dram_bandwidth(struct evergreen_wm_params *wm) -{ - /* Calculate DRAM Bandwidth and the part allocated to display. */ - fixed20_12 dram_efficiency; /* 0.7 */ - fixed20_12 yclk, dram_channels, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - yclk.full = dfixed_const(wm->yclk); - yclk.full = dfixed_div(yclk, a); - dram_channels.full = dfixed_const(wm->dram_channels * 4); - a.full = dfixed_const(10); - dram_efficiency.full = dfixed_const(7); - dram_efficiency.full = dfixed_div(dram_efficiency, a); - bandwidth.full = dfixed_mul(dram_channels, yclk); - bandwidth.full = dfixed_mul(bandwidth, dram_efficiency); - - return dfixed_trunc(bandwidth); -} - -static u32 evergreen_dram_bandwidth_for_display(struct evergreen_wm_params *wm) -{ - /* Calculate DRAM Bandwidth and the part allocated to display. */ - fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */ - fixed20_12 yclk, dram_channels, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - yclk.full = dfixed_const(wm->yclk); - yclk.full = dfixed_div(yclk, a); - dram_channels.full = dfixed_const(wm->dram_channels * 4); - a.full = dfixed_const(10); - disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */ - disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a); - bandwidth.full = dfixed_mul(dram_channels, yclk); - bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation); - - return dfixed_trunc(bandwidth); -} - -static u32 evergreen_data_return_bandwidth(struct evergreen_wm_params *wm) -{ - /* Calculate the display Data return Bandwidth */ - fixed20_12 return_efficiency; /* 0.8 */ - fixed20_12 sclk, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - sclk.full = dfixed_const(wm->sclk); - sclk.full = dfixed_div(sclk, a); - a.full = dfixed_const(10); - return_efficiency.full = dfixed_const(8); - return_efficiency.full = dfixed_div(return_efficiency, a); - a.full = dfixed_const(32); - bandwidth.full = dfixed_mul(a, sclk); - bandwidth.full = dfixed_mul(bandwidth, return_efficiency); - - return dfixed_trunc(bandwidth); -} - -static u32 evergreen_dmif_request_bandwidth(struct evergreen_wm_params *wm) -{ - /* Calculate the DMIF Request Bandwidth */ - fixed20_12 disp_clk_request_efficiency; /* 0.8 */ - fixed20_12 disp_clk, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - disp_clk.full = dfixed_const(wm->disp_clk); - disp_clk.full = dfixed_div(disp_clk, a); - a.full = dfixed_const(10); - disp_clk_request_efficiency.full = dfixed_const(8); - disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a); - a.full = dfixed_const(32); - bandwidth.full = dfixed_mul(a, disp_clk); - bandwidth.full = dfixed_mul(bandwidth, disp_clk_request_efficiency); - - return dfixed_trunc(bandwidth); -} - -static u32 evergreen_available_bandwidth(struct evergreen_wm_params *wm) -{ - /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */ - u32 dram_bandwidth = evergreen_dram_bandwidth(wm); - u32 data_return_bandwidth = evergreen_data_return_bandwidth(wm); - u32 dmif_req_bandwidth = evergreen_dmif_request_bandwidth(wm); - - return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth)); -} - -static u32 evergreen_average_bandwidth(struct evergreen_wm_params *wm) -{ - /* Calculate the display mode Average Bandwidth - * DisplayMode should contain the source and destination dimensions, - * timing, etc. - */ - fixed20_12 bpp; - fixed20_12 line_time; - fixed20_12 src_width; - fixed20_12 bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - line_time.full = dfixed_const(wm->active_time + wm->blank_time); - line_time.full = dfixed_div(line_time, a); - bpp.full = dfixed_const(wm->bytes_per_pixel); - src_width.full = dfixed_const(wm->src_width); - bandwidth.full = dfixed_mul(src_width, bpp); - bandwidth.full = dfixed_mul(bandwidth, wm->vsc); - bandwidth.full = dfixed_div(bandwidth, line_time); - - return dfixed_trunc(bandwidth); -} - -static u32 evergreen_latency_watermark(struct evergreen_wm_params *wm) -{ - /* First calcualte the latency in ns */ - u32 mc_latency = 2000; /* 2000 ns. */ - u32 available_bandwidth = evergreen_available_bandwidth(wm); - u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; - u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; - u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ - u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + - (wm->num_heads * cursor_line_pair_return_time); - u32 latency = mc_latency + other_heads_data_return_time + dc_latency; - u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; - fixed20_12 a, b, c; - - if (wm->num_heads == 0) - return 0; - - a.full = dfixed_const(2); - b.full = dfixed_const(1); - if ((wm->vsc.full > a.full) || - ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) || - (wm->vtaps >= 5) || - ((wm->vsc.full >= a.full) && wm->interlaced)) - max_src_lines_per_dst_line = 4; - else - max_src_lines_per_dst_line = 2; - - a.full = dfixed_const(available_bandwidth); - b.full = dfixed_const(wm->num_heads); - a.full = dfixed_div(a, b); - - b.full = dfixed_const(1000); - c.full = dfixed_const(wm->disp_clk); - b.full = dfixed_div(c, b); - c.full = dfixed_const(wm->bytes_per_pixel); - b.full = dfixed_mul(b, c); - - lb_fill_bw = min(dfixed_trunc(a), dfixed_trunc(b)); - - a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); - b.full = dfixed_const(1000); - c.full = dfixed_const(lb_fill_bw); - b.full = dfixed_div(c, b); - a.full = dfixed_div(a, b); - line_fill_time = dfixed_trunc(a); - - if (line_fill_time < wm->active_time) - return latency; - else - return latency + (line_fill_time - wm->active_time); - -} - -static bool evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params *wm) -{ - if (evergreen_average_bandwidth(wm) <= - (evergreen_dram_bandwidth_for_display(wm) / wm->num_heads)) - return true; - else - return false; -}; - -static bool evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params *wm) -{ - if (evergreen_average_bandwidth(wm) <= - (evergreen_available_bandwidth(wm) / wm->num_heads)) - return true; - else - return false; -}; - -static bool evergreen_check_latency_hiding(struct evergreen_wm_params *wm) -{ - u32 lb_partitions = wm->lb_size / wm->src_width; - u32 line_time = wm->active_time + wm->blank_time; - u32 latency_tolerant_lines; - u32 latency_hiding; - fixed20_12 a; - - a.full = dfixed_const(1); - if (wm->vsc.full > a.full) - latency_tolerant_lines = 1; - else { - if (lb_partitions <= (wm->vtaps + 1)) - latency_tolerant_lines = 1; - else - latency_tolerant_lines = 2; - } - - latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time); - - if (evergreen_latency_watermark(wm) <= latency_hiding) - return true; - else - return false; -} - -static void evergreen_program_watermarks(struct radeon_device *rdev, - struct radeon_crtc *radeon_crtc, - u32 lb_size, u32 num_heads) -{ - struct drm_display_mode *mode = &radeon_crtc->base.mode; - struct evergreen_wm_params wm; - u32 pixel_period; - u32 line_time = 0; - u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 priority_a_mark = 0, priority_b_mark = 0; - u32 priority_a_cnt = PRIORITY_OFF; - u32 priority_b_cnt = PRIORITY_OFF; - u32 pipe_offset = radeon_crtc->crtc_id * 16; - u32 tmp, arb_control3; - fixed20_12 a, b, c; - - if (radeon_crtc->base.enabled && num_heads && mode) { - pixel_period = 1000000 / (u32)mode->clock; - line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535); - priority_a_cnt = 0; - priority_b_cnt = 0; - - wm.yclk = rdev->pm.current_mclk * 10; - wm.sclk = rdev->pm.current_sclk * 10; - wm.disp_clk = mode->clock; - wm.src_width = mode->crtc_hdisplay; - wm.active_time = mode->crtc_hdisplay * pixel_period; - wm.blank_time = line_time - wm.active_time; - wm.interlaced = false; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - wm.interlaced = true; - wm.vsc = radeon_crtc->vsc; - wm.vtaps = 1; - if (radeon_crtc->rmx_type != RMX_OFF) - wm.vtaps = 2; - wm.bytes_per_pixel = 4; /* XXX: get this from fb config */ - wm.lb_size = lb_size; - wm.dram_channels = evergreen_get_number_of_dram_channels(rdev); - wm.num_heads = num_heads; - - /* set for high clocks */ - latency_watermark_a = min(evergreen_latency_watermark(&wm), (u32)65535); - /* set for low clocks */ - /* wm.yclk = low clk; wm.sclk = low clk */ - latency_watermark_b = min(evergreen_latency_watermark(&wm), (u32)65535); - - /* possibly force display priority to high */ - /* should really do this at mode validation time... */ - if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm) || - !evergreen_average_bandwidth_vs_available_bandwidth(&wm) || - !evergreen_check_latency_hiding(&wm) || - (rdev->disp_priority == 2)) { - DRM_DEBUG_KMS("force priority to high\n"); - priority_a_cnt |= PRIORITY_ALWAYS_ON; - priority_b_cnt |= PRIORITY_ALWAYS_ON; - } - - a.full = dfixed_const(1000); - b.full = dfixed_const(mode->clock); - b.full = dfixed_div(b, a); - c.full = dfixed_const(latency_watermark_a); - c.full = dfixed_mul(c, b); - c.full = dfixed_mul(c, radeon_crtc->hsc); - c.full = dfixed_div(c, a); - a.full = dfixed_const(16); - c.full = dfixed_div(c, a); - priority_a_mark = dfixed_trunc(c); - priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK; - - a.full = dfixed_const(1000); - b.full = dfixed_const(mode->clock); - b.full = dfixed_div(b, a); - c.full = dfixed_const(latency_watermark_b); - c.full = dfixed_mul(c, b); - c.full = dfixed_mul(c, radeon_crtc->hsc); - c.full = dfixed_div(c, a); - a.full = dfixed_const(16); - c.full = dfixed_div(c, a); - priority_b_mark = dfixed_trunc(c); - priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; - } - - /* select wm A */ - arb_control3 = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset); - tmp = arb_control3; - tmp &= ~LATENCY_WATERMARK_MASK(3); - tmp |= LATENCY_WATERMARK_MASK(1); - WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp); - WREG32(PIPE0_LATENCY_CONTROL + pipe_offset, - (LATENCY_LOW_WATERMARK(latency_watermark_a) | - LATENCY_HIGH_WATERMARK(line_time))); - /* select wm B */ - tmp = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset); - tmp &= ~LATENCY_WATERMARK_MASK(3); - tmp |= LATENCY_WATERMARK_MASK(2); - WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp); - WREG32(PIPE0_LATENCY_CONTROL + pipe_offset, - (LATENCY_LOW_WATERMARK(latency_watermark_b) | - LATENCY_HIGH_WATERMARK(line_time))); - /* restore original selection */ - WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, arb_control3); - - /* write the priority marks */ - WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt); - WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt); - -} - -void evergreen_bandwidth_update(struct radeon_device *rdev) -{ - struct drm_display_mode *mode0 = NULL; - struct drm_display_mode *mode1 = NULL; - u32 num_heads = 0, lb_size; - int i; - - radeon_update_display_priority(rdev); - - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->mode_info.crtcs[i]->base.enabled) - num_heads++; - } - for (i = 0; i < rdev->num_crtc; i += 2) { - mode0 = &rdev->mode_info.crtcs[i]->base.mode; - mode1 = &rdev->mode_info.crtcs[i+1]->base.mode; - lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1); - evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads); - lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0); - evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads); - } -} - -int evergreen_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - u32 tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(SRBM_STATUS) & 0x1F00; - if (!tmp) - return 0; - udelay(1); - } - return -1; -} - -/* - * GART - */ -void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev) -{ - unsigned i; - u32 tmp; - - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - - WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE); - tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT; - if (tmp == 2) { - printk(KERN_WARNING "[drm] r600 flush TLB failed\n"); - return; - } - if (tmp) { - return; - } - udelay(1); - } -} - -int evergreen_pcie_gart_enable(struct radeon_device *rdev) -{ - u32 tmp; - int r; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); - /* Setup TLB control */ - tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - if (rdev->flags & RADEON_IS_IGP) { - WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); - } else { - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - if ((rdev->family == CHIP_JUNIPER) || - (rdev->family == CHIP_CYPRESS) || - (rdev->family == CHIP_HEMLOCK) || - (rdev->family == CHIP_BARTS)) - WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); - } - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); - WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - WREG32(VM_CONTEXT1_CNTL, 0); - - evergreen_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void evergreen_pcie_gart_disable(struct radeon_device *rdev) -{ - u32 tmp; - - /* Disable all tables */ - WREG32(VM_CONTEXT0_CNTL, 0); - WREG32(VM_CONTEXT1_CNTL, 0); - - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); - /* Setup TLB control */ - tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - radeon_gart_table_vram_unpin(rdev); -} - -void evergreen_pcie_gart_fini(struct radeon_device *rdev) -{ - evergreen_pcie_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); - radeon_gart_fini(rdev); -} - - -void evergreen_agp_enable(struct radeon_device *rdev) -{ - u32 tmp; - - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); - /* Setup TLB control */ - tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - WREG32(VM_CONTEXT0_CNTL, 0); - WREG32(VM_CONTEXT1_CNTL, 0); -} - -void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) -{ - save->vga_control[0] = RREG32(D1VGA_CONTROL); - save->vga_control[1] = RREG32(D2VGA_CONTROL); - save->vga_render_control = RREG32(VGA_RENDER_CONTROL); - save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); - save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); - save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); - if (rdev->num_crtc >= 4) { - save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); - save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); - save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); - save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); - } - if (rdev->num_crtc >= 6) { - save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); - save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); - save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); - save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); - } - - /* Stop all video */ - WREG32(VGA_RENDER_CONTROL, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); - } - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - - WREG32(D1VGA_CONTROL, 0); - WREG32(D2VGA_CONTROL, 0); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_D3VGA_CONTROL, 0); - WREG32(EVERGREEN_D4VGA_CONTROL, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_D5VGA_CONTROL, 0); - WREG32(EVERGREEN_D6VGA_CONTROL, 0); - } -} - -void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) -{ - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - } - - WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); - /* Unlock host access */ - WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); - mdelay(1); - /* Restore video state */ - WREG32(D1VGA_CONTROL, save->vga_control[0]); - WREG32(D2VGA_CONTROL, save->vga_control[1]); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); - WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); - WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); - } - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); - } - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); - } - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - WREG32(VGA_RENDER_CONTROL, save->vga_render_control); -} - -void evergreen_mc_program(struct radeon_device *rdev) -{ - struct evergreen_mc_save save; - u32 tmp; - int i, j; - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); - - evergreen_mc_stop(rdev, &save); - if (evergreen_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Lockout access through VGA aperture*/ - WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); - /* Update configuration */ - if (rdev->flags & RADEON_IS_AGP) { - if (rdev->mc.vram_start < rdev->mc.gtt_start) { - /* VRAM before AGP */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.gtt_end >> 12); - } else { - /* VRAM after AGP */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.gtt_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.vram_end >> 12); - } - } else { - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.vram_end >> 12); - } - WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); - /* llano/ontario only */ - if ((rdev->family == CHIP_PALM) || - (rdev->family == CHIP_SUMO) || - (rdev->family == CHIP_SUMO2)) { - tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; - tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; - tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; - WREG32(MC_FUS_VM_FB_OFFSET, tmp); - } - tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; - tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); - WREG32(MC_VM_FB_LOCATION, tmp); - WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); - WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); - if (rdev->flags & RADEON_IS_AGP) { - WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); - WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); - WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); - } else { - WREG32(MC_VM_AGP_BASE, 0); - WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); - WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); - } - if (evergreen_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - evergreen_mc_resume(rdev, &save); - /* we need to own VRAM, so turn off the VGA renderer here - * to stop it overwriting our objects */ - rv515_vga_render_disable(rdev); -} - -/* - * CP. - */ -void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -{ - struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; - - /* set to DX10/11 mode */ - radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); - radeon_ring_write(ring, 1); - /* FIXME: implement */ - radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (ib->gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); - radeon_ring_write(ring, ib->length_dw); -} - - -static int evergreen_cp_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - int i; - - if (!rdev->me_fw || !rdev->pfp_fw) - return -EINVAL; - - r700_cp_stop(rdev); - WREG32(CP_RB_CNTL, -#ifdef __BIG_ENDIAN - BUF_SWAP_32BIT | -#endif - RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); - - fw_data = (const __be32 *)rdev->pfp_fw->data; - WREG32(CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < EVERGREEN_PFP_UCODE_SIZE; i++) - WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_PFP_UCODE_ADDR, 0); - - fw_data = (const __be32 *)rdev->me_fw->data; - WREG32(CP_ME_RAM_WADDR, 0); - for (i = 0; i < EVERGREEN_PM4_UCODE_SIZE; i++) - WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); - - WREG32(CP_PFP_UCODE_ADDR, 0); - WREG32(CP_ME_RAM_WADDR, 0); - WREG32(CP_ME_RAM_RADDR, 0); - return 0; -} - -static int evergreen_cp_start(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r, i; - uint32_t cp_me; - - r = radeon_ring_lock(rdev, ring, 7); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); - radeon_ring_write(ring, 0x1); - radeon_ring_write(ring, 0x0); - radeon_ring_write(ring, rdev->config.evergreen.max_hw_contexts - 1); - radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_unlock_commit(rdev, ring); - - cp_me = 0xff; - WREG32(CP_ME_CNTL, cp_me); - - r = radeon_ring_lock(rdev, ring, evergreen_default_size + 19); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - - /* setup clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - for (i = 0; i < evergreen_default_size; i++) - radeon_ring_write(ring, evergreen_default_state[i]); - - radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); - - /* set clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(ring, 0); - - /* SQ_VTX_BASE_VTX_LOC */ - radeon_ring_write(ring, 0xc0026f00); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - - /* Clear consts */ - radeon_ring_write(ring, 0xc0036f00); - radeon_ring_write(ring, 0x00000bc4); - radeon_ring_write(ring, 0xffffffff); - radeon_ring_write(ring, 0xffffffff); - radeon_ring_write(ring, 0xffffffff); - - radeon_ring_write(ring, 0xc0026900); - radeon_ring_write(ring, 0x00000316); - radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - radeon_ring_write(ring, 0x00000010); /* */ - - radeon_ring_unlock_commit(rdev, ring); - - return 0; -} - -int evergreen_cp_resume(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 tmp; - u32 rb_bufsz; - int r; - - /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ - WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | - SOFT_RESET_PA | - SOFT_RESET_SH | - SOFT_RESET_VGT | - SOFT_RESET_SPI | - SOFT_RESET_SX)); - RREG32(GRBM_SOFT_RESET); - mdelay(15); - WREG32(GRBM_SOFT_RESET, 0); - RREG32(GRBM_SOFT_RESET); - - /* Set ring buffer size */ - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB_CNTL, tmp); - WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); - - /* Set the write pointer delay */ - WREG32(CP_RB_WPTR_DELAY, 0); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); - WREG32(CP_RB_RPTR_WR, 0); - ring->wptr = 0; - WREG32(CP_RB_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB_RPTR_ADDR, - ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); - WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); - WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); - - if (rdev->wb.enabled) - WREG32(SCRATCH_UMSK, 0xff); - else { - tmp |= RB_NO_UPDATE; - WREG32(SCRATCH_UMSK, 0); - } - - mdelay(1); - WREG32(CP_RB_CNTL, tmp); - - WREG32(CP_RB_BASE, ring->gpu_addr >> 8); - WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); - - ring->rptr = RREG32(CP_RB_RPTR); - - evergreen_cp_start(rdev); - ring->ready = true; - r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); - if (r) { - ring->ready = false; - return r; - } - return 0; -} - -/* - * Core functions - */ -static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask = 0; - u32 enabled_backends_count = 0; - u32 cur_pipe; - u32 swizzle_pipe[EVERGREEN_MAX_PIPES]; - u32 cur_backend = 0; - u32 i; - bool force_no_swizzle; - - if (num_tile_pipes > EVERGREEN_MAX_PIPES) - num_tile_pipes = EVERGREEN_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > EVERGREEN_MAX_BACKENDS) - num_backends = EVERGREEN_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - for (i = 0; i < EVERGREEN_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * EVERGREEN_MAX_PIPES); - switch (rdev->family) { - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_PALM: - case CHIP_SUMO: - case CHIP_SUMO2: - case CHIP_TURKS: - case CHIP_CAICOS: - force_no_swizzle = false; - break; - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - case CHIP_JUNIPER: - case CHIP_BARTS: - default: - force_no_swizzle = true; - break; - } - if (force_no_swizzle) { - bool last_backend_enabled = false; - - force_no_swizzle = false; - for (i = 0; i < EVERGREEN_MAX_BACKENDS; ++i) { - if (((enabled_backends_mask >> i) & 1) == 1) { - if (last_backend_enabled) - force_no_swizzle = true; - last_backend_enabled = true; - } else - last_backend_enabled = false; - } - } - - switch (num_tile_pipes) { - case 1: - case 3: - case 5: - case 7: - DRM_ERROR("odd number of pipes!\n"); - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - swizzle_pipe[3] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - } - break; - } - - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % EVERGREEN_MAX_BACKENDS; - - backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); - - cur_backend = (cur_backend + 1) % EVERGREEN_MAX_BACKENDS; - } - - return backend_map; -} - -static void evergreen_gpu_init(struct radeon_device *rdev) -{ - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config; - u32 gb_addr_config = 0; - u32 mc_shared_chmap, mc_arb_ramcfg; - u32 gb_backend_map; - u32 grbm_gfx_index; - u32 sx_debug_1; - u32 smx_dc_ctl0; - u32 sq_config; - u32 sq_lds_resource_mgmt; - u32 sq_gpr_resource_mgmt_1; - u32 sq_gpr_resource_mgmt_2; - u32 sq_gpr_resource_mgmt_3; - u32 sq_thread_resource_mgmt; - u32 sq_thread_resource_mgmt_2; - u32 sq_stack_resource_mgmt_1; - u32 sq_stack_resource_mgmt_2; - u32 sq_stack_resource_mgmt_3; - u32 vgt_cache_invalidation; - u32 hdp_host_path_cntl, tmp; - int i, j, num_shader_engines, ps_thread_count; - - switch (rdev->family) { - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - rdev->config.evergreen.num_ses = 2; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 8; - rdev->config.evergreen.max_simds = 10; - rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 512; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x100; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_JUNIPER: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 4; - rdev->config.evergreen.max_simds = 10; - rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 512; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x100; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_REDWOOD: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 4; - rdev->config.evergreen.max_simds = 5; - rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 256; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x100; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_CEDAR: - default: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 2; - rdev->config.evergreen.max_tile_pipes = 2; - rdev->config.evergreen.max_simds = 2; - rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 192; - rdev->config.evergreen.max_gs_threads = 16; - rdev->config.evergreen.max_stack_entries = 256; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 128; - rdev->config.evergreen.sx_max_export_pos_size = 32; - rdev->config.evergreen.sx_max_export_smx_size = 96; - rdev->config.evergreen.max_hw_contexts = 4; - rdev->config.evergreen.sq_num_cf_insts = 1; - - rdev->config.evergreen.sc_prim_fifo_size = 0x40; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_PALM: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 2; - rdev->config.evergreen.max_tile_pipes = 2; - rdev->config.evergreen.max_simds = 2; - rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 192; - rdev->config.evergreen.max_gs_threads = 16; - rdev->config.evergreen.max_stack_entries = 256; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 128; - rdev->config.evergreen.sx_max_export_pos_size = 32; - rdev->config.evergreen.sx_max_export_smx_size = 96; - rdev->config.evergreen.max_hw_contexts = 4; - rdev->config.evergreen.sq_num_cf_insts = 1; - - rdev->config.evergreen.sc_prim_fifo_size = 0x40; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_SUMO: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 2; - if (rdev->pdev->device == 0x9648) - rdev->config.evergreen.max_simds = 3; - else if ((rdev->pdev->device == 0x9647) || - (rdev->pdev->device == 0x964a)) - rdev->config.evergreen.max_simds = 4; - else - rdev->config.evergreen.max_simds = 5; - rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 256; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x40; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_SUMO2: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 4; - rdev->config.evergreen.max_simds = 2; - rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 512; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x40; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_BARTS: - rdev->config.evergreen.num_ses = 2; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 8; - rdev->config.evergreen.max_simds = 7; - rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 512; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x100; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_TURKS: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 4; - rdev->config.evergreen.max_simds = 6; - rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 248; - rdev->config.evergreen.max_gs_threads = 32; - rdev->config.evergreen.max_stack_entries = 256; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 256; - rdev->config.evergreen.sx_max_export_pos_size = 64; - rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; - rdev->config.evergreen.sq_num_cf_insts = 2; - - rdev->config.evergreen.sc_prim_fifo_size = 0x100; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_CAICOS: - rdev->config.evergreen.num_ses = 1; - rdev->config.evergreen.max_pipes = 4; - rdev->config.evergreen.max_tile_pipes = 2; - rdev->config.evergreen.max_simds = 2; - rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; - rdev->config.evergreen.max_gprs = 256; - rdev->config.evergreen.max_threads = 192; - rdev->config.evergreen.max_gs_threads = 16; - rdev->config.evergreen.max_stack_entries = 256; - rdev->config.evergreen.sx_num_of_sets = 4; - rdev->config.evergreen.sx_max_export_size = 128; - rdev->config.evergreen.sx_max_export_pos_size = 32; - rdev->config.evergreen.sx_max_export_smx_size = 96; - rdev->config.evergreen.max_hw_contexts = 4; - rdev->config.evergreen.sq_num_cf_insts = 1; - - rdev->config.evergreen.sc_prim_fifo_size = 0x40; - rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; - rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; - break; - } - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - - WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - - evergreen_fix_pci_max_read_req_size(rdev); - - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; - - cc_gc_shader_pipe_config |= - INACTIVE_QD_PIPES((EVERGREEN_MAX_PIPES_MASK << rdev->config.evergreen.max_pipes) - & EVERGREEN_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - INACTIVE_SIMDS((EVERGREEN_MAX_SIMDS_MASK << rdev->config.evergreen.max_simds) - & EVERGREEN_MAX_SIMDS_MASK); - - cc_rb_backend_disable = - BACKEND_DISABLE((EVERGREEN_MAX_BACKENDS_MASK << rdev->config.evergreen.max_backends) - & EVERGREEN_MAX_BACKENDS_MASK); - - - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); - if ((rdev->family == CHIP_PALM) || - (rdev->family == CHIP_SUMO) || - (rdev->family == CHIP_SUMO2)) - mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); - else - mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - - switch (rdev->config.evergreen.max_tile_pipes) { - case 1: - default: - gb_addr_config |= NUM_PIPES(0); - break; - case 2: - gb_addr_config |= NUM_PIPES(1); - break; - case 4: - gb_addr_config |= NUM_PIPES(2); - break; - case 8: - gb_addr_config |= NUM_PIPES(3); - break; - } - - gb_addr_config |= PIPE_INTERLEAVE_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - gb_addr_config |= BANK_INTERLEAVE_SIZE(0); - gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.evergreen.num_ses - 1); - gb_addr_config |= SHADER_ENGINE_TILE_SIZE(1); - gb_addr_config |= NUM_GPUS(0); /* Hemlock? */ - gb_addr_config |= MULTI_GPU_TILE_SIZE(2); - - if (((mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT) > 2) - gb_addr_config |= ROW_SIZE(2); - else - gb_addr_config |= ROW_SIZE((mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT); - - if (rdev->ddev->pdev->device == 0x689e) { - u32 efuse_straps_4; - u32 efuse_straps_3; - u8 efuse_box_bit_131_124; - - WREG32(RCU_IND_INDEX, 0x204); - efuse_straps_4 = RREG32(RCU_IND_DATA); - WREG32(RCU_IND_INDEX, 0x203); - efuse_straps_3 = RREG32(RCU_IND_DATA); - efuse_box_bit_131_124 = (u8)(((efuse_straps_4 & 0xf) << 4) | ((efuse_straps_3 & 0xf0000000) >> 28)); - - switch(efuse_box_bit_131_124) { - case 0x00: - gb_backend_map = 0x76543210; - break; - case 0x55: - gb_backend_map = 0x77553311; - break; - case 0x56: - gb_backend_map = 0x77553300; - break; - case 0x59: - gb_backend_map = 0x77552211; - break; - case 0x66: - gb_backend_map = 0x77443300; - break; - case 0x99: - gb_backend_map = 0x66552211; - break; - case 0x5a: - gb_backend_map = 0x77552200; - break; - case 0xaa: - gb_backend_map = 0x66442200; - break; - case 0x95: - gb_backend_map = 0x66553311; - break; - default: - DRM_ERROR("bad backend map, using default\n"); - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); - break; - } - } else if (rdev->ddev->pdev->device == 0x68b9) { - u32 efuse_straps_3; - u8 efuse_box_bit_127_124; - - WREG32(RCU_IND_INDEX, 0x203); - efuse_straps_3 = RREG32(RCU_IND_DATA); - efuse_box_bit_127_124 = (u8)((efuse_straps_3 & 0xF0000000) >> 28); - - switch(efuse_box_bit_127_124) { - case 0x0: - gb_backend_map = 0x00003210; - break; - case 0x5: - case 0x6: - case 0x9: - case 0xa: - gb_backend_map = 0x00003311; - break; - default: - DRM_ERROR("bad backend map, using default\n"); - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); - break; - } - } else { - switch (rdev->family) { - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - case CHIP_BARTS: - gb_backend_map = 0x66442200; - break; - case CHIP_JUNIPER: - gb_backend_map = 0x00002200; - break; - default: - gb_backend_map = - evergreen_get_tile_pipe_to_backend_map(rdev, - rdev->config.evergreen.max_tile_pipes, - rdev->config.evergreen.max_backends, - ((EVERGREEN_MAX_BACKENDS_MASK << - rdev->config.evergreen.max_backends) & - EVERGREEN_MAX_BACKENDS_MASK)); - } - } - - /* setup tiling info dword. gb_addr_config is not adequate since it does - * not have bank info, so create a custom tiling dword. - * bits 3:0 num_pipes - * bits 7:4 num_banks - * bits 11:8 group_size - * bits 15:12 row_size - */ - rdev->config.evergreen.tile_config = 0; - switch (rdev->config.evergreen.max_tile_pipes) { - case 1: - default: - rdev->config.evergreen.tile_config |= (0 << 0); - break; - case 2: - rdev->config.evergreen.tile_config |= (1 << 0); - break; - case 4: - rdev->config.evergreen.tile_config |= (2 << 0); - break; - case 8: - rdev->config.evergreen.tile_config |= (3 << 0); - break; - } - /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ - if (rdev->flags & RADEON_IS_IGP) - rdev->config.evergreen.tile_config |= 1 << 4; - else { - if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) - rdev->config.evergreen.tile_config |= 1 << 4; - else - rdev->config.evergreen.tile_config |= 0 << 4; - } - rdev->config.evergreen.tile_config |= - ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8; - rdev->config.evergreen.tile_config |= - ((gb_addr_config & 0x30000000) >> 28) << 12; - - rdev->config.evergreen.backend_map = gb_backend_map; - WREG32(GB_BACKEND_MAP, gb_backend_map); - WREG32(GB_ADDR_CONFIG, gb_addr_config); - WREG32(DMIF_ADDR_CONFIG, gb_addr_config); - WREG32(HDP_ADDR_CONFIG, gb_addr_config); - - num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; - grbm_gfx_index = INSTANCE_BROADCAST_WRITES; - - for (i = 0; i < rdev->config.evergreen.num_ses; i++) { - u32 rb = cc_rb_backend_disable | (0xf0 << 16); - u32 sp = cc_gc_shader_pipe_config; - u32 gfx = grbm_gfx_index | SE_INDEX(i); - - if (i == num_shader_engines) { - rb |= BACKEND_DISABLE(EVERGREEN_MAX_BACKENDS_MASK); - sp |= INACTIVE_SIMDS(EVERGREEN_MAX_SIMDS_MASK); - } - - WREG32(GRBM_GFX_INDEX, gfx); - WREG32(RLC_GFX_INDEX, gfx); - - WREG32(CC_RB_BACKEND_DISABLE, rb); - WREG32(CC_SYS_RB_BACKEND_DISABLE, rb); - WREG32(GC_USER_RB_BACKEND_DISABLE, rb); - WREG32(CC_GC_SHADER_PIPE_CONFIG, sp); - } - - grbm_gfx_index = INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES; - WREG32(GRBM_GFX_INDEX, grbm_gfx_index); - WREG32(RLC_GFX_INDEX, grbm_gfx_index); - - WREG32(CGTS_SYS_TCC_DISABLE, 0); - WREG32(CGTS_TCC_DISABLE, 0); - WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); - WREG32(CGTS_USER_TCC_DISABLE, 0); - - /* set HW defaults for 3D engine */ - WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | - ROQ_IB2_START(0x2b))); - - WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); - - WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | - SYNC_GRADIENT | - SYNC_WALKER | - SYNC_ALIGNER)); - - sx_debug_1 = RREG32(SX_DEBUG_1); - sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; - WREG32(SX_DEBUG_1, sx_debug_1); - - - smx_dc_ctl0 = RREG32(SMX_DC_CTL0); - smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); - smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); - WREG32(SMX_DC_CTL0, smx_dc_ctl0); - - if (rdev->family <= CHIP_SUMO2) - WREG32(SMX_SAR_CTL0, 0x00010000); - - WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | - POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | - SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); - - WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | - SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | - SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); - - WREG32(VGT_NUM_INSTANCES, 1); - WREG32(SPI_CONFIG_CNTL, 0); - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); - WREG32(CP_PERFMON_CNTL, 0); - - WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | - FETCH_FIFO_HIWATER(0x4) | - DONE_FIFO_HIWATER(0xe0) | - ALU_UPDATE_FIFO_HIWATER(0x8))); - - sq_config = RREG32(SQ_CONFIG); - sq_config &= ~(PS_PRIO(3) | - VS_PRIO(3) | - GS_PRIO(3) | - ES_PRIO(3)); - sq_config |= (VC_ENABLE | - EXPORT_SRC_C | - PS_PRIO(0) | - VS_PRIO(1) | - GS_PRIO(2) | - ES_PRIO(3)); - - switch (rdev->family) { - case CHIP_CEDAR: - case CHIP_PALM: - case CHIP_SUMO: - case CHIP_SUMO2: - case CHIP_CAICOS: - /* no vertex cache */ - sq_config &= ~VC_ENABLE; - break; - default: - break; - } - - sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); - - sq_gpr_resource_mgmt_1 = NUM_PS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2))* 12 / 32); - sq_gpr_resource_mgmt_1 |= NUM_VS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 6 / 32); - sq_gpr_resource_mgmt_1 |= NUM_CLAUSE_TEMP_GPRS(4); - sq_gpr_resource_mgmt_2 = NUM_GS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32); - sq_gpr_resource_mgmt_2 |= NUM_ES_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32); - sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); - sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); - - switch (rdev->family) { - case CHIP_CEDAR: - case CHIP_PALM: - case CHIP_SUMO: - case CHIP_SUMO2: - ps_thread_count = 96; - break; - default: - ps_thread_count = 128; - break; - } - - sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); - sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt |= NUM_GS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt |= NUM_ES_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt_2 = NUM_HS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - sq_thread_resource_mgmt_2 |= NUM_LS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); - - sq_stack_resource_mgmt_1 = NUM_PS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); - sq_stack_resource_mgmt_1 |= NUM_VS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); - sq_stack_resource_mgmt_2 = NUM_GS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); - sq_stack_resource_mgmt_2 |= NUM_ES_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); - sq_stack_resource_mgmt_3 = NUM_HS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); - sq_stack_resource_mgmt_3 |= NUM_LS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); - - WREG32(SQ_CONFIG, sq_config); - WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); - WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); - WREG32(SQ_GPR_RESOURCE_MGMT_3, sq_gpr_resource_mgmt_3); - WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - WREG32(SQ_THREAD_RESOURCE_MGMT_2, sq_thread_resource_mgmt_2); - WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); - WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); - WREG32(SQ_STACK_RESOURCE_MGMT_3, sq_stack_resource_mgmt_3); - WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0); - WREG32(SQ_LDS_RESOURCE_MGMT, sq_lds_resource_mgmt); - - WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | - FORCE_EOV_MAX_REZ_CNT(255))); - - switch (rdev->family) { - case CHIP_CEDAR: - case CHIP_PALM: - case CHIP_SUMO: - case CHIP_SUMO2: - case CHIP_CAICOS: - vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); - break; - default: - vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); - break; - } - vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); - WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); - - WREG32(VGT_GS_VERTEX_REUSE, 16); - WREG32(PA_SU_LINE_STIPPLE_VALUE, 0); - WREG32(PA_SC_LINE_STIPPLE_STATE, 0); - - WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); - WREG32(VGT_OUT_DEALLOC_CNTL, 16); - - WREG32(CB_PERF_CTR0_SEL_0, 0); - WREG32(CB_PERF_CTR0_SEL_1, 0); - WREG32(CB_PERF_CTR1_SEL_0, 0); - WREG32(CB_PERF_CTR1_SEL_1, 0); - WREG32(CB_PERF_CTR2_SEL_0, 0); - WREG32(CB_PERF_CTR2_SEL_1, 0); - WREG32(CB_PERF_CTR3_SEL_0, 0); - WREG32(CB_PERF_CTR3_SEL_1, 0); - - /* clear render buffer base addresses */ - WREG32(CB_COLOR0_BASE, 0); - WREG32(CB_COLOR1_BASE, 0); - WREG32(CB_COLOR2_BASE, 0); - WREG32(CB_COLOR3_BASE, 0); - WREG32(CB_COLOR4_BASE, 0); - WREG32(CB_COLOR5_BASE, 0); - WREG32(CB_COLOR6_BASE, 0); - WREG32(CB_COLOR7_BASE, 0); - WREG32(CB_COLOR8_BASE, 0); - WREG32(CB_COLOR9_BASE, 0); - WREG32(CB_COLOR10_BASE, 0); - WREG32(CB_COLOR11_BASE, 0); - - /* set the shader const cache sizes to 0 */ - for (i = SQ_ALU_CONST_BUFFER_SIZE_PS_0; i < 0x28200; i += 4) - WREG32(i, 0); - for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) - WREG32(i, 0); - - tmp = RREG32(HDP_MISC_CNTL); - tmp |= HDP_FLUSH_INVALIDATE_CACHE; - WREG32(HDP_MISC_CNTL, tmp); - - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); - - udelay(50); - -} - -int evergreen_mc_init(struct radeon_device *rdev) -{ - u32 tmp; - int chansize, numchan; - - /* Get VRAM informations */ - rdev->mc.vram_is_ddr = true; - if ((rdev->family == CHIP_PALM) || - (rdev->family == CHIP_SUMO) || - (rdev->family == CHIP_SUMO2)) - tmp = RREG32(FUS_MC_ARB_RAMCFG); - else - tmp = RREG32(MC_ARB_RAMCFG); - if (tmp & CHANSIZE_OVERRIDE) { - chansize = 16; - } else if (tmp & CHANSIZE_MASK) { - chansize = 64; - } else { - chansize = 32; - } - tmp = RREG32(MC_SHARED_CHMAP); - switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { - case 0: - default: - numchan = 1; - break; - case 1: - numchan = 2; - break; - case 2: - numchan = 4; - break; - case 3: - numchan = 8; - break; - } - rdev->mc.vram_width = numchan * chansize; - /* Could aper size report 0 ? */ - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - /* Setup GPU memory space */ - if ((rdev->family == CHIP_PALM) || - (rdev->family == CHIP_SUMO) || - (rdev->family == CHIP_SUMO2)) { - /* size in bytes on fusion */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); - } else { - /* size in MB on evergreen/cayman/tn */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; - } - rdev->mc.visible_vram_size = rdev->mc.aper_size; - r700_vram_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); - - return 0; -} - -bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 srbm_status; - u32 grbm_status; - u32 grbm_status_se0, grbm_status_se1; - struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup; - int r; - - srbm_status = RREG32(SRBM_STATUS); - grbm_status = RREG32(GRBM_STATUS); - grbm_status_se0 = RREG32(GRBM_STATUS_SE0); - grbm_status_se1 = RREG32(GRBM_STATUS_SE1); - if (!(grbm_status & GUI_ACTIVE)) { - r100_gpu_lockup_update(lockup, ring); - return false; - } - /* force CP activities */ - r = radeon_ring_lock(rdev, ring, 2); - if (!r) { - /* PACKET2 NOP */ - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - radeon_ring_unlock_commit(rdev, ring); - } - ring->rptr = RREG32(CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, lockup, ring); -} - -static int evergreen_gpu_soft_reset(struct radeon_device *rdev) -{ - struct evergreen_mc_save save; - u32 grbm_reset = 0; - - if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) - return 0; - - dev_info(rdev->dev, "GPU softreset \n"); - dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(GRBM_STATUS)); - dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(GRBM_STATUS_SE0)); - dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(GRBM_STATUS_SE1)); - dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(SRBM_STATUS)); - evergreen_mc_stop(rdev, &save); - if (evergreen_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Disable CP parsing/prefetching */ - WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); - - /* reset all the gfx blocks */ - grbm_reset = (SOFT_RESET_CP | - SOFT_RESET_CB | - SOFT_RESET_DB | - SOFT_RESET_PA | - SOFT_RESET_SC | - SOFT_RESET_SPI | - SOFT_RESET_SH | - SOFT_RESET_SX | - SOFT_RESET_TC | - SOFT_RESET_TA | - SOFT_RESET_VC | - SOFT_RESET_VGT); - - dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset); - WREG32(GRBM_SOFT_RESET, grbm_reset); - (void)RREG32(GRBM_SOFT_RESET); - udelay(50); - WREG32(GRBM_SOFT_RESET, 0); - (void)RREG32(GRBM_SOFT_RESET); - /* Wait a little for things to settle down */ - udelay(50); - dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(GRBM_STATUS)); - dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(GRBM_STATUS_SE0)); - dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(GRBM_STATUS_SE1)); - dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(SRBM_STATUS)); - evergreen_mc_resume(rdev, &save); - return 0; -} - -int evergreen_asic_reset(struct radeon_device *rdev) -{ - return evergreen_gpu_soft_reset(rdev); -} - -/* Interrupts */ - -u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc) -{ - switch (crtc) { - case 0: - return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC0_REGISTER_OFFSET); - case 1: - return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC1_REGISTER_OFFSET); - case 2: - return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC2_REGISTER_OFFSET); - case 3: - return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC3_REGISTER_OFFSET); - case 4: - return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC4_REGISTER_OFFSET); - case 5: - return RREG32(CRTC_STATUS_FRAME_COUNT + EVERGREEN_CRTC5_REGISTER_OFFSET); - default: - return 0; - } -} - -void evergreen_disable_interrupt_state(struct radeon_device *rdev) -{ - u32 tmp; - - if (rdev->family >= CHIP_CAYMAN) { - cayman_cp_int_cntl_setup(rdev, 0, - CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); - cayman_cp_int_cntl_setup(rdev, 1, 0); - cayman_cp_int_cntl_setup(rdev, 2, 0); - } else - WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); - WREG32(GRBM_INT_CNTL, 0); - WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - - /* only one DAC on DCE6 */ - if (!ASIC_IS_DCE6(rdev)) - WREG32(DACA_AUTODETECT_INT_CONTROL, 0); - WREG32(DACB_AUTODETECT_INT_CONTROL, 0); - - tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD1_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD2_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD3_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD4_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, tmp); - -} - -int evergreen_irq_set(struct radeon_device *rdev) -{ - u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; - u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; - u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; - u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; - u32 grbm_int_cntl = 0; - u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; - - if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); - return -EINVAL; - } - /* don't enable anything if the ih is disabled */ - if (!rdev->ih.enabled) { - r600_disable_interrupts(rdev); - /* force the active interrupt state to all disabled */ - evergreen_disable_interrupt_state(rdev); - return 0; - } - - hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; - - if (rdev->family >= CHIP_CAYMAN) { - /* enable CP interrupts on all rings */ - if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { - DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); - cp_int_cntl |= TIME_STAMP_INT_ENABLE; - } - if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) { - DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); - cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; - } - if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) { - DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); - cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; - } - } else { - if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { - DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); - cp_int_cntl |= RB_INT_ENABLE; - cp_int_cntl |= TIME_STAMP_INT_ENABLE; - } - } - - if (rdev->irq.crtc_vblank_int[0] || - rdev->irq.pflip[0]) { - DRM_DEBUG("evergreen_irq_set: vblank 0\n"); - crtc1 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[1] || - rdev->irq.pflip[1]) { - DRM_DEBUG("evergreen_irq_set: vblank 1\n"); - crtc2 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[2] || - rdev->irq.pflip[2]) { - DRM_DEBUG("evergreen_irq_set: vblank 2\n"); - crtc3 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[3] || - rdev->irq.pflip[3]) { - DRM_DEBUG("evergreen_irq_set: vblank 3\n"); - crtc4 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[4] || - rdev->irq.pflip[4]) { - DRM_DEBUG("evergreen_irq_set: vblank 4\n"); - crtc5 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[5] || - rdev->irq.pflip[5]) { - DRM_DEBUG("evergreen_irq_set: vblank 5\n"); - crtc6 |= VBLANK_INT_MASK; - } - if (rdev->irq.hpd[0]) { - DRM_DEBUG("evergreen_irq_set: hpd 1\n"); - hpd1 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[1]) { - DRM_DEBUG("evergreen_irq_set: hpd 2\n"); - hpd2 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[2]) { - DRM_DEBUG("evergreen_irq_set: hpd 3\n"); - hpd3 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[3]) { - DRM_DEBUG("evergreen_irq_set: hpd 4\n"); - hpd4 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[4]) { - DRM_DEBUG("evergreen_irq_set: hpd 5\n"); - hpd5 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[5]) { - DRM_DEBUG("evergreen_irq_set: hpd 6\n"); - hpd6 |= DC_HPDx_INT_EN; - } - if (rdev->irq.gui_idle) { - DRM_DEBUG("gui idle\n"); - grbm_int_cntl |= GUI_IDLE_INT_ENABLE; - } - - if (rdev->family >= CHIP_CAYMAN) { - cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); - cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1); - cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); - } else - WREG32(CP_INT_CNTL, cp_int_cntl); - WREG32(GRBM_INT_CNTL, grbm_int_cntl); - - WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); - WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); - if (rdev->num_crtc >= 4) { - WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); - WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); - } - if (rdev->num_crtc >= 6) { - WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); - WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); - } - - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); - if (rdev->num_crtc >= 4) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); - } - if (rdev->num_crtc >= 6) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); - } - - WREG32(DC_HPD1_INT_CONTROL, hpd1); - WREG32(DC_HPD2_INT_CONTROL, hpd2); - WREG32(DC_HPD3_INT_CONTROL, hpd3); - WREG32(DC_HPD4_INT_CONTROL, hpd4); - WREG32(DC_HPD5_INT_CONTROL, hpd5); - WREG32(DC_HPD6_INT_CONTROL, hpd6); - - return 0; -} - -static void evergreen_irq_ack(struct radeon_device *rdev) -{ - u32 tmp; - - rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); - rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); - rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); - rdev->irq.stat_regs.evergreen.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); - rdev->irq.stat_regs.evergreen.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); - rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); - rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); - rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); - if (rdev->num_crtc >= 4) { - rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); - rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); - } - if (rdev->num_crtc >= 6) { - rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); - rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); - } - - if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); - - if (rdev->num_crtc >= 4) { - if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); - } - - if (rdev->num_crtc >= 6) { - if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); - } - - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { - tmp = RREG32(DC_HPD1_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD1_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { - tmp = RREG32(DC_HPD2_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD2_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { - tmp = RREG32(DC_HPD3_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD3_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { - tmp = RREG32(DC_HPD4_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD4_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { - tmp = RREG32(DC_HPD5_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD5_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { - tmp = RREG32(DC_HPD5_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD6_INT_CONTROL, tmp); - } -} - -void evergreen_irq_disable(struct radeon_device *rdev) -{ - r600_disable_interrupts(rdev); - /* Wait and acknowledge irq */ - mdelay(1); - evergreen_irq_ack(rdev); - evergreen_disable_interrupt_state(rdev); -} - -void evergreen_irq_suspend(struct radeon_device *rdev) -{ - evergreen_irq_disable(rdev); - r600_rlc_stop(rdev); -} - -static u32 evergreen_get_ih_wptr(struct radeon_device *rdev) -{ - u32 wptr, tmp; - - if (rdev->wb.enabled) - wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); - else - wptr = RREG32(IH_RB_WPTR); - - if (wptr & RB_OVERFLOW) { - /* When a ring buffer overflow happen start parsing interrupt - * from the last not overwritten vector (wptr + 16). Hopefully - * this should allow us to catchup. - */ - dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", - wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); - rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; - tmp = RREG32(IH_RB_CNTL); - tmp |= IH_WPTR_OVERFLOW_CLEAR; - WREG32(IH_RB_CNTL, tmp); - } - return (wptr & rdev->ih.ptr_mask); -} - -int evergreen_irq_process(struct radeon_device *rdev) -{ - u32 wptr; - u32 rptr; - u32 src_id, src_data; - u32 ring_index; - unsigned long flags; - bool queue_hotplug = false; - - if (!rdev->ih.enabled || rdev->shutdown) - return IRQ_NONE; - - wptr = evergreen_get_ih_wptr(rdev); - rptr = rdev->ih.rptr; - DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - - spin_lock_irqsave(&rdev->ih.lock, flags); - if (rptr == wptr) { - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_NONE; - } -restart_ih: - /* Order reading of wptr vs. reading of IH ring data */ - rmb(); - - /* display interrupts */ - evergreen_irq_ack(rdev); - - rdev->ih.wptr = wptr; - while (rptr != wptr) { - /* wptr/rptr are in bytes! */ - ring_index = rptr / 4; - src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; - src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; - - switch (src_id) { - case 1: /* D1 vblank/vline */ - switch (src_data) { - case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); - } - break; - case 1: /* D1 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 2: /* D2 vblank/vline */ - switch (src_data) { - case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); - } - break; - case 1: /* D2 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 3: /* D3 vblank/vline */ - switch (src_data) { - case 0: /* D3 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[2]) { - drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[2]) - radeon_crtc_handle_flip(rdev, 2); - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D3 vblank\n"); - } - break; - case 1: /* D3 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; - DRM_DEBUG("IH: D3 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 4: /* D4 vblank/vline */ - switch (src_data) { - case 0: /* D4 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[3]) { - drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[3]) - radeon_crtc_handle_flip(rdev, 3); - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D4 vblank\n"); - } - break; - case 1: /* D4 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; - DRM_DEBUG("IH: D4 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 5: /* D5 vblank/vline */ - switch (src_data) { - case 0: /* D5 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[4]) { - drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[4]) - radeon_crtc_handle_flip(rdev, 4); - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D5 vblank\n"); - } - break; - case 1: /* D5 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; - DRM_DEBUG("IH: D5 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 6: /* D6 vblank/vline */ - switch (src_data) { - case 0: /* D6 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[5]) { - drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[5]) - radeon_crtc_handle_flip(rdev, 5); - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D6 vblank\n"); - } - break; - case 1: /* D6 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; - DRM_DEBUG("IH: D6 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 42: /* HPD hotplug */ - switch (src_data) { - case 0: - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } - break; - case 1: - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } - break; - case 2: - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } - break; - case 3: - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } - break; - case 4: - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } - break; - case 5: - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 176: /* CP_INT in ring buffer */ - case 177: /* CP_INT in IB1 */ - case 178: /* CP_INT in IB2 */ - DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 181: /* CP EOP event */ - DRM_DEBUG("IH: CP EOP\n"); - if (rdev->family >= CHIP_CAYMAN) { - switch (src_data) { - case 0: - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 1: - radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); - break; - case 2: - radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); - break; - } - } else - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 233: /* GUI IDLE */ - DRM_DEBUG("IH: GUI idle\n"); - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - - /* wptr/rptr are in bytes! */ - rptr += 16; - rptr &= rdev->ih.ptr_mask; - } - /* make sure wptr hasn't changed while processing */ - wptr = evergreen_get_ih_wptr(rdev); - if (wptr != rdev->ih.wptr) - goto restart_ih; - if (queue_hotplug) - schedule_work(&rdev->hotplug_work); - rdev->ih.rptr = rptr; - WREG32(IH_RB_RPTR, rdev->ih.rptr); - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_HANDLED; -} - -static int evergreen_startup(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - - /* enable pcie gen2 link */ - evergreen_pcie_gen2_enable(rdev); - - if (ASIC_IS_DCE5(rdev)) { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { - r = ni_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - r = ni_mc_load_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load MC firmware!\n"); - return r; - } - } else { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = r600_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - } - - r = r600_vram_scratch_init(rdev); - if (r) - return r; - - evergreen_mc_program(rdev); - if (rdev->flags & RADEON_IS_AGP) { - evergreen_agp_enable(rdev); - } else { - r = evergreen_pcie_gart_enable(rdev); - if (r) - return r; - } - evergreen_gpu_init(rdev); - - r = evergreen_blit_init(rdev); - if (r) { - r600_blit_fini(rdev); - rdev->asic->copy.copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r = r600_irq_init(rdev); - if (r) { - DRM_ERROR("radeon: IH init failed (%d).\n", r); - radeon_irq_kms_fini(rdev); - return r; - } - evergreen_irq_set(rdev); - - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (r) - return r; - r = evergreen_cp_load_microcode(rdev); - if (r) - return r; - r = evergreen_cp_resume(rdev); - if (r) - return r; - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - r = r600_audio_init(rdev); - if (r) { - DRM_ERROR("radeon: audio init failed\n"); - return r; - } - - return 0; -} - -int evergreen_resume(struct radeon_device *rdev) -{ - int r; - - /* reset the asic, the gfx blocks are often in a bad state - * after the driver is unloaded or after a resume - */ - if (radeon_asic_reset(rdev)) - dev_warn(rdev->dev, "GPU reset failed !\n"); - /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, - * posting will perform necessary task to bring back GPU into good - * shape. - */ - /* post card */ - atom_asic_init(rdev->mode_info.atom_context); - - rdev->accel_working = true; - r = evergreen_startup(rdev); - if (r) { - DRM_ERROR("evergreen startup failed on resume\n"); - rdev->accel_working = false; - return r; - } - - return r; - -} - -int evergreen_suspend(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - - r600_audio_fini(rdev); - /* FIXME: we should wait for ring to be empty */ - radeon_ib_pool_suspend(rdev); - r600_blit_suspend(rdev); - r700_cp_stop(rdev); - ring->ready = false; - evergreen_irq_suspend(rdev); - radeon_wb_disable(rdev); - evergreen_pcie_gart_disable(rdev); - - return 0; -} - -/* Plan is to move initialization in that function and use - * helper function so that radeon_device_init pretty much - * do nothing more than calling asic specific function. This - * should also allow to remove a bunch of callback function - * like vram_info. - */ -int evergreen_init(struct radeon_device *rdev) -{ - int r; - - /* This don't do much */ - r = radeon_gem_init(rdev); - if (r) - return r; - /* Read BIOS */ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting atombios for evergreen GPU\n"); - return -EINVAL; - } - r = radeon_atombios_init(rdev); - if (r) - return r; - /* reset the asic, the gfx blocks are often in a bad state - * after the driver is unloaded or after a resume - */ - if (radeon_asic_reset(rdev)) - dev_warn(rdev->dev, "GPU reset failed !\n"); - /* Post card if necessary */ - if (!radeon_card_posted(rdev)) { - if (!rdev->bios) { - dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); - return -EINVAL; - } - DRM_INFO("GPU not posted. posting now...\n"); - atom_asic_init(rdev->mode_info.atom_context); - } - /* Initialize scratch registers */ - r600_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) - radeon_agp_disable(rdev); - } - /* initialize memory controller */ - r = evergreen_mc_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - - r = radeon_irq_kms_init(rdev); - if (r) - return r; - - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); - - rdev->ih.ring_obj = NULL; - r600_ih_ring_init(rdev, 64 * 1024); - - r = r600_pcie_gart_init(rdev); - if (r) - return r; - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = evergreen_startup(rdev); - if (r) { - dev_err(rdev->dev, "disabling GPU acceleration\n"); - r700_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - evergreen_pcie_gart_fini(rdev); - rdev->accel_working = false; - } - - /* Don't start up if the MC ucode is missing on BTC parts. - * The default clocks and voltages before the MC ucode - * is loaded are not suffient for advanced operations. - */ - if (ASIC_IS_DCE5(rdev)) { - if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { - DRM_ERROR("radeon: MC ucode required for NI+.\n"); - return -EINVAL; - } - } - - return 0; -} - -void evergreen_fini(struct radeon_device *rdev) -{ - r600_audio_fini(rdev); - r600_blit_fini(rdev); - r700_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - evergreen_pcie_gart_fini(rdev); - r600_vram_scratch_fini(rdev); - radeon_gem_fini(rdev); - radeon_semaphore_driver_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_agp_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -void evergreen_pcie_gen2_enable(struct radeon_device *rdev) -{ - u32 link_width_cntl, speed_cntl; - - if (radeon_pcie_gen2 == 0) - return; - - if (rdev->flags & RADEON_IS_IGP) - return; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return; - - /* x2 cards have a special sequence */ - if (ASIC_IS_X2(rdev)) - return; - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || - (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { - - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - link_width_cntl &= ~LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl |= LC_GEN2_EN_STRAP; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - } else { - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ - if (1) - link_width_cntl |= LC_UPCONFIGURE_DIS; - else - link_width_cntl &= ~LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_kms.c deleted file mode 100644 index 222acd2d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Alex Deucher - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon.h" - -#include "evergreend.h" -#include "evergreen_blit_shaders.h" -#include "cayman_blit_shaders.h" -#include "radeon_blit_common.h" - -/* emits 17 */ -static void -set_render_target(struct radeon_device *rdev, int format, - int w, int h, u64 gpu_addr) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 cb_color_info; - int pitch, slice; - - h = ALIGN(h, 8); - if (h < 8) - h = 8; - - cb_color_info = CB_FORMAT(format) | - CB_SOURCE_FORMAT(CB_SF_EXPORT_NORM) | - CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - pitch = (w / 8) - 1; - slice = ((w * h) / 64) - 1; - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 15)); - radeon_ring_write(ring, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, pitch); - radeon_ring_write(ring, slice); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, cb_color_info); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, (w - 1) | ((h - 1) << 16)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); -} - -/* emits 5dw */ -static void -cp_set_surface_sync(struct radeon_device *rdev, - u32 sync_type, u32 size, - u64 mc_addr) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 cp_coher_size; - - if (size == 0xffffffff) - cp_coher_size = 0xffffffff; - else - cp_coher_size = ((size + 255) >> 8); - - if (rdev->family >= CHIP_CAYMAN) { - /* CP_COHER_CNTL2 has to be set manually when submitting a surface_sync - * to the RB directly. For IBs, the CP programs this as part of the - * surface_sync packet. - */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, 0); /* CP_COHER_CNTL2 */ - } - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, sync_type); - radeon_ring_write(ring, cp_coher_size); - radeon_ring_write(ring, mc_addr >> 8); - radeon_ring_write(ring, 10); /* poll interval */ -} - -/* emits 11dw + 1 surface sync = 16dw */ -static void -set_shaders(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u64 gpu_addr; - - /* VS */ - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 3)); - radeon_ring_write(ring, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, 2); - radeon_ring_write(ring, 0); - - /* PS */ - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 4)); - radeon_ring_write(ring, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, 1); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 2); - - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); -} - -/* emits 10 + 1 sync (5) = 15 */ -static void -set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 sq_vtx_constant_word2, sq_vtx_constant_word3; - - /* high addr, stride */ - sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) | - SQ_VTXC_STRIDE(16); -#ifdef __BIG_ENDIAN - sq_vtx_constant_word2 |= SQ_VTXC_ENDIAN_SWAP(SQ_ENDIAN_8IN32); -#endif - /* xyzw swizzles */ - sq_vtx_constant_word3 = SQ_VTCX_SEL_X(SQ_SEL_X) | - SQ_VTCX_SEL_Y(SQ_SEL_Y) | - SQ_VTCX_SEL_Z(SQ_SEL_Z) | - SQ_VTCX_SEL_W(SQ_SEL_W); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 8)); - radeon_ring_write(ring, 0x580); - radeon_ring_write(ring, gpu_addr & 0xffffffff); - radeon_ring_write(ring, 48 - 1); /* size */ - radeon_ring_write(ring, sq_vtx_constant_word2); - radeon_ring_write(ring, sq_vtx_constant_word3); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_BUFFER)); - - if ((rdev->family == CHIP_CEDAR) || - (rdev->family == CHIP_PALM) || - (rdev->family == CHIP_SUMO) || - (rdev->family == CHIP_SUMO2) || - (rdev->family == CHIP_CAICOS)) - cp_set_surface_sync(rdev, - PACKET3_TC_ACTION_ENA, 48, gpu_addr); - else - cp_set_surface_sync(rdev, - PACKET3_VC_ACTION_ENA, 48, gpu_addr); - -} - -/* emits 10 */ -static void -set_tex_resource(struct radeon_device *rdev, - int format, int w, int h, int pitch, - u64 gpu_addr, u32 size) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 sq_tex_resource_word0, sq_tex_resource_word1; - u32 sq_tex_resource_word4, sq_tex_resource_word7; - - if (h < 1) - h = 1; - - sq_tex_resource_word0 = TEX_DIM(SQ_TEX_DIM_2D); - sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 6) | - ((w - 1) << 18)); - sq_tex_resource_word1 = ((h - 1) << 0) | - TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - /* xyzw swizzles */ - sq_tex_resource_word4 = TEX_DST_SEL_X(SQ_SEL_X) | - TEX_DST_SEL_Y(SQ_SEL_Y) | - TEX_DST_SEL_Z(SQ_SEL_Z) | - TEX_DST_SEL_W(SQ_SEL_W); - - sq_tex_resource_word7 = format | - S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE); - - cp_set_surface_sync(rdev, - PACKET3_TC_ACTION_ENA, size, gpu_addr); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 8)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, sq_tex_resource_word0); - radeon_ring_write(ring, sq_tex_resource_word1); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, sq_tex_resource_word4); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, sq_tex_resource_word7); -} - -/* emits 12 */ -static void -set_scissors(struct radeon_device *rdev, int x1, int y1, - int x2, int y2) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - /* workaround some hw bugs */ - if (x2 == 0) - x1 = 1; - if (y2 == 0) - y1 = 1; - if (rdev->family >= CHIP_CAYMAN) { - if ((x2 == 1) && (y2 == 1)) - x2 = 2; - } - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(ring, (x1 << 0) | (y1 << 16)); - radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); -} - -/* emits 10 */ -static void -draw_auto(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, DI_PT_RECTLIST); - - radeon_ring_write(ring, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 2) | -#endif - DI_INDEX_SIZE_16_BIT); - - radeon_ring_write(ring, PACKET3(PACKET3_NUM_INSTANCES, 0)); - radeon_ring_write(ring, 1); - - radeon_ring_write(ring, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); - radeon_ring_write(ring, 3); - radeon_ring_write(ring, DI_SRC_SEL_AUTO_INDEX); - -} - -/* emits 39 */ -static void -set_default_state(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2, sq_gpr_resource_mgmt_3; - u32 sq_thread_resource_mgmt, sq_thread_resource_mgmt_2; - u32 sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2, sq_stack_resource_mgmt_3; - int num_ps_gprs, num_vs_gprs, num_temp_gprs; - int num_gs_gprs, num_es_gprs, num_hs_gprs, num_ls_gprs; - int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; - int num_hs_threads, num_ls_threads; - int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; - int num_hs_stack_entries, num_ls_stack_entries; - u64 gpu_addr; - int dwords; - - /* set clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(ring, 0); - - if (rdev->family < CHIP_CAYMAN) { - switch (rdev->family) { - case CHIP_CEDAR: - default: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 96; - num_vs_threads = 16; - num_gs_threads = 16; - num_es_threads = 16; - num_hs_threads = 16; - num_ls_threads = 16; - num_ps_stack_entries = 42; - num_vs_stack_entries = 42; - num_gs_stack_entries = 42; - num_es_stack_entries = 42; - num_hs_stack_entries = 42; - num_ls_stack_entries = 42; - break; - case CHIP_REDWOOD: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 128; - num_vs_threads = 20; - num_gs_threads = 20; - num_es_threads = 20; - num_hs_threads = 20; - num_ls_threads = 20; - num_ps_stack_entries = 42; - num_vs_stack_entries = 42; - num_gs_stack_entries = 42; - num_es_stack_entries = 42; - num_hs_stack_entries = 42; - num_ls_stack_entries = 42; - break; - case CHIP_JUNIPER: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 128; - num_vs_threads = 20; - num_gs_threads = 20; - num_es_threads = 20; - num_hs_threads = 20; - num_ls_threads = 20; - num_ps_stack_entries = 85; - num_vs_stack_entries = 85; - num_gs_stack_entries = 85; - num_es_stack_entries = 85; - num_hs_stack_entries = 85; - num_ls_stack_entries = 85; - break; - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 128; - num_vs_threads = 20; - num_gs_threads = 20; - num_es_threads = 20; - num_hs_threads = 20; - num_ls_threads = 20; - num_ps_stack_entries = 85; - num_vs_stack_entries = 85; - num_gs_stack_entries = 85; - num_es_stack_entries = 85; - num_hs_stack_entries = 85; - num_ls_stack_entries = 85; - break; - case CHIP_PALM: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 96; - num_vs_threads = 16; - num_gs_threads = 16; - num_es_threads = 16; - num_hs_threads = 16; - num_ls_threads = 16; - num_ps_stack_entries = 42; - num_vs_stack_entries = 42; - num_gs_stack_entries = 42; - num_es_stack_entries = 42; - num_hs_stack_entries = 42; - num_ls_stack_entries = 42; - break; - case CHIP_SUMO: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 96; - num_vs_threads = 25; - num_gs_threads = 25; - num_es_threads = 25; - num_hs_threads = 25; - num_ls_threads = 25; - num_ps_stack_entries = 42; - num_vs_stack_entries = 42; - num_gs_stack_entries = 42; - num_es_stack_entries = 42; - num_hs_stack_entries = 42; - num_ls_stack_entries = 42; - break; - case CHIP_SUMO2: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 96; - num_vs_threads = 25; - num_gs_threads = 25; - num_es_threads = 25; - num_hs_threads = 25; - num_ls_threads = 25; - num_ps_stack_entries = 85; - num_vs_stack_entries = 85; - num_gs_stack_entries = 85; - num_es_stack_entries = 85; - num_hs_stack_entries = 85; - num_ls_stack_entries = 85; - break; - case CHIP_BARTS: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 128; - num_vs_threads = 20; - num_gs_threads = 20; - num_es_threads = 20; - num_hs_threads = 20; - num_ls_threads = 20; - num_ps_stack_entries = 85; - num_vs_stack_entries = 85; - num_gs_stack_entries = 85; - num_es_stack_entries = 85; - num_hs_stack_entries = 85; - num_ls_stack_entries = 85; - break; - case CHIP_TURKS: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 128; - num_vs_threads = 20; - num_gs_threads = 20; - num_es_threads = 20; - num_hs_threads = 20; - num_ls_threads = 20; - num_ps_stack_entries = 42; - num_vs_stack_entries = 42; - num_gs_stack_entries = 42; - num_es_stack_entries = 42; - num_hs_stack_entries = 42; - num_ls_stack_entries = 42; - break; - case CHIP_CAICOS: - num_ps_gprs = 93; - num_vs_gprs = 46; - num_temp_gprs = 4; - num_gs_gprs = 31; - num_es_gprs = 31; - num_hs_gprs = 23; - num_ls_gprs = 23; - num_ps_threads = 128; - num_vs_threads = 10; - num_gs_threads = 10; - num_es_threads = 10; - num_hs_threads = 10; - num_ls_threads = 10; - num_ps_stack_entries = 42; - num_vs_stack_entries = 42; - num_gs_stack_entries = 42; - num_es_stack_entries = 42; - num_hs_stack_entries = 42; - num_ls_stack_entries = 42; - break; - } - - if ((rdev->family == CHIP_CEDAR) || - (rdev->family == CHIP_PALM) || - (rdev->family == CHIP_SUMO) || - (rdev->family == CHIP_SUMO2) || - (rdev->family == CHIP_CAICOS)) - sq_config = 0; - else - sq_config = VC_ENABLE; - - sq_config |= (EXPORT_SRC_C | - CS_PRIO(0) | - LS_PRIO(0) | - HS_PRIO(0) | - PS_PRIO(0) | - VS_PRIO(1) | - GS_PRIO(2) | - ES_PRIO(3)); - - sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | - NUM_VS_GPRS(num_vs_gprs) | - NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); - sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | - NUM_ES_GPRS(num_es_gprs)); - sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) | - NUM_LS_GPRS(num_ls_gprs)); - sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | - NUM_VS_THREADS(num_vs_threads) | - NUM_GS_THREADS(num_gs_threads) | - NUM_ES_THREADS(num_es_threads)); - sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) | - NUM_LS_THREADS(num_ls_threads)); - sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | - NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); - sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | - NUM_ES_STACK_ENTRIES(num_es_stack_entries)); - sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) | - NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); - - /* disable dyn gprs */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, 0); - - /* setup LDS */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (SQ_LDS_RESOURCE_MGMT - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, 0x10001000); - - /* SQ config */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 11)); - radeon_ring_write(ring, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, sq_config); - radeon_ring_write(ring, sq_gpr_resource_mgmt_1); - radeon_ring_write(ring, sq_gpr_resource_mgmt_2); - radeon_ring_write(ring, sq_gpr_resource_mgmt_3); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, sq_thread_resource_mgmt); - radeon_ring_write(ring, sq_thread_resource_mgmt_2); - radeon_ring_write(ring, sq_stack_resource_mgmt_1); - radeon_ring_write(ring, sq_stack_resource_mgmt_2); - radeon_ring_write(ring, sq_stack_resource_mgmt_3); - } - - /* CONTEXT_CONTROL */ - radeon_ring_write(ring, 0xc0012800); - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - - /* SQ_VTX_BASE_VTX_LOC */ - radeon_ring_write(ring, 0xc0026f00); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - - /* SET_SAMPLER */ - radeon_ring_write(ring, 0xc0036e00); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000012); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - - /* set to DX10/11 mode */ - radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); - radeon_ring_write(ring, 1); - - /* emit an IB pointing at default state */ - dwords = ALIGN(rdev->r600_blit.state_len, 0x10); - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; - radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(ring, gpu_addr & 0xFFFFFFFC); - radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xFF); - radeon_ring_write(ring, dwords); - -} - -int evergreen_blit_init(struct radeon_device *rdev) -{ - u32 obj_size; - int i, r, dwords; - void *ptr; - u32 packet2s[16]; - int num_packet2s = 0; - - rdev->r600_blit.primitives.set_render_target = set_render_target; - rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync; - rdev->r600_blit.primitives.set_shaders = set_shaders; - rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource; - rdev->r600_blit.primitives.set_tex_resource = set_tex_resource; - rdev->r600_blit.primitives.set_scissors = set_scissors; - rdev->r600_blit.primitives.draw_auto = draw_auto; - rdev->r600_blit.primitives.set_default_state = set_default_state; - - rdev->r600_blit.ring_size_common = 55; /* shaders + def state */ - rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ - rdev->r600_blit.ring_size_common += 5; /* done copy */ - rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ - - rdev->r600_blit.ring_size_per_loop = 74; - if (rdev->family >= CHIP_CAYMAN) - rdev->r600_blit.ring_size_per_loop += 9; /* additional DWs for surface sync */ - - rdev->r600_blit.max_dim = 16384; - - /* pin copy shader into vram if already initialized */ - if (rdev->r600_blit.shader_obj) - goto done; - - mutex_init(&rdev->r600_blit.mutex); - rdev->r600_blit.state_offset = 0; - - if (rdev->family < CHIP_CAYMAN) - rdev->r600_blit.state_len = evergreen_default_size; - else - rdev->r600_blit.state_len = cayman_default_size; - - dwords = rdev->r600_blit.state_len; - while (dwords & 0xf) { - packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); - dwords++; - } - - obj_size = dwords * 4; - obj_size = ALIGN(obj_size, 256); - - rdev->r600_blit.vs_offset = obj_size; - if (rdev->family < CHIP_CAYMAN) - obj_size += evergreen_vs_size * 4; - else - obj_size += cayman_vs_size * 4; - obj_size = ALIGN(obj_size, 256); - - rdev->r600_blit.ps_offset = obj_size; - if (rdev->family < CHIP_CAYMAN) - obj_size += evergreen_ps_size * 4; - else - obj_size += cayman_ps_size * 4; - obj_size = ALIGN(obj_size, 256); - - r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, - &rdev->r600_blit.shader_obj); - if (r) { - DRM_ERROR("evergreen failed to allocate shader\n"); - return r; - } - - DRM_DEBUG("evergreen blit allocated bo %08x vs %08x ps %08x\n", - obj_size, - rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); - - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr); - if (r) { - DRM_ERROR("failed to map blit object %d\n", r); - return r; - } - - if (rdev->family < CHIP_CAYMAN) { - memcpy_toio(ptr + rdev->r600_blit.state_offset, - evergreen_default_state, rdev->r600_blit.state_len * 4); - - if (num_packet2s) - memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), - packet2s, num_packet2s * 4); - for (i = 0; i < evergreen_vs_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); - for (i = 0; i < evergreen_ps_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); - } else { - memcpy_toio(ptr + rdev->r600_blit.state_offset, - cayman_default_state, rdev->r600_blit.state_len * 4); - - if (num_packet2s) - memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), - packet2s, num_packet2s * 4); - for (i = 0; i < cayman_vs_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(cayman_vs[i]); - for (i = 0; i < cayman_ps_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(cayman_ps[i]); - } - radeon_bo_kunmap(rdev->r600_blit.shader_obj); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - -done: - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, - &rdev->r600_blit.shader_gpu_addr); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - if (r) { - dev_err(rdev->dev, "(%d) pin blit object failed\n", r); - return r; - } - radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.c deleted file mode 100644 index f85c0af1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Alex Deucher - */ - -#include -#include -#include - -/* - * evergreen cards need to use the 3D engine to blit data which requires - * quite a bit of hw state setup. Rather than pull the whole 3D driver - * (which normally generates the 3D state) into the DRM, we opt to use - * statically generated state tables. The regsiter state and shaders - * were hand generated to support blitting functionality. See the 3D - * driver or documentation for descriptions of the registers and - * shader instructions. - */ - -const u32 evergreen_default_state[] = -{ - 0xc0016900, - 0x0000023b, - 0x00000000, /* SQ_LDS_ALLOC_PS */ - - 0xc0066900, - 0x00000240, - 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0046900, - 0x00000247, - 0x00000000, /* SQ_GS_VERT_ITEMSIZE */ - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0026900, - 0x00000010, - 0x00000000, /* DB_Z_INFO */ - 0x00000000, /* DB_STENCIL_INFO */ - - 0xc0016900, - 0x00000200, - 0x00000000, /* DB_DEPTH_CONTROL */ - - 0xc0066900, - 0x00000000, - 0x00000060, /* DB_RENDER_CONTROL */ - 0x00000000, /* DB_COUNT_CONTROL */ - 0x00000000, /* DB_DEPTH_VIEW */ - 0x0000002a, /* DB_RENDER_OVERRIDE */ - 0x00000000, /* DB_RENDER_OVERRIDE2 */ - 0x00000000, /* DB_HTILE_DATA_BASE */ - - 0xc0026900, - 0x0000000a, - 0x00000000, /* DB_STENCIL_CLEAR */ - 0x00000000, /* DB_DEPTH_CLEAR */ - - 0xc0016900, - 0x000002dc, - 0x0000aa00, /* DB_ALPHA_TO_MASK */ - - 0xc0016900, - 0x00000080, - 0x00000000, /* PA_SC_WINDOW_OFFSET */ - - 0xc00d6900, - 0x00000083, - 0x0000ffff, /* PA_SC_CLIPRECT_RULE */ - 0x00000000, /* PA_SC_CLIPRECT_0_TL */ - 0x20002000, /* PA_SC_CLIPRECT_0_BR */ - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0xaaaaaaaa, /* PA_SC_EDGERULE */ - 0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */ - 0x0000000f, /* CB_TARGET_MASK */ - 0x0000000f, /* CB_SHADER_MASK */ - - 0xc0226900, - 0x00000094, - 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, /* PA_SC_VPORT_ZMAX_0 */ - - 0xc0016900, - 0x000000d4, - 0x00000000, /* SX_MISC */ - - 0xc0026900, - 0x00000292, - 0x00000000, /* PA_SC_MODE_CNTL_0 */ - 0x00000000, /* PA_SC_MODE_CNTL_1 */ - - 0xc0106900, - 0x00000300, - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - 0x00000005, /* PA_SU_VTX_CNTL */ - 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ - 0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */ - 0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */ - 0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */ - 0x00000000, /* PA_SC_AA_SAMPLE_LOCS_0 */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* PA_SC_AA_SAMPLE_LOCS_7 */ - 0xffffffff, /* PA_SC_AA_MASK */ - - 0xc00d6900, - 0x00000202, - 0x00cc0010, /* CB_COLOR_CONTROL */ - 0x00000210, /* DB_SHADER_CONTROL */ - 0x00010000, /* PA_CL_CLIP_CNTL */ - 0x00000004, /* PA_SU_SC_MODE_CNTL */ - 0x00000100, /* PA_CL_VTE_CNTL */ - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ - 0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */ - 0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */ - 0x00000000, /* PA_SU_PRIM_FILTER_CNTL */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* SQ_DYN_GPR_RESOURCE_LIMIT_1 */ - - 0xc0066900, - 0x000002de, - 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - - 0xc0016900, - 0x00000229, - 0x00000000, /* SQ_PGM_START_FS */ - - 0xc0016900, - 0x0000022a, - 0x00000000, /* SQ_PGM_RESOURCES_FS */ - - 0xc0096900, - 0x00000100, - 0x00ffffff, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* SX_ALPHA_TEST_CONTROL */ - 0x00000000, /* CB_BLEND_RED */ - 0x00000000, /* CB_BLEND_GREEN */ - 0x00000000, /* CB_BLEND_BLUE */ - 0x00000000, /* CB_BLEND_ALPHA */ - - 0xc0026900, - 0x000002a8, - 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - 0x00000000, /* */ - - 0xc0026900, - 0x000002ad, - 0x00000000, /* VGT_REUSE_OFF */ - 0x00000000, /* */ - - 0xc0116900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ - 0x00000008, /* PA_SU_LINE_CNTL */ - 0x00000000, /* PA_SC_LINE_STIPPLE */ - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - 0x00000000, /* VGT_HOS_CNTL */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* VGT_GS_MODE */ - - 0xc0016900, - 0x000002a1, - 0x00000000, /* VGT_PRIMITIVEID_EN */ - - 0xc0016900, - 0x000002a5, - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */ - - 0xc0016900, - 0x000002d5, - 0x00000000, /* VGT_SHADER_STAGES_EN */ - - 0xc0026900, - 0x000002e5, - 0x00000000, /* VGT_STRMOUT_CONFIG */ - 0x00000000, /* */ - - 0xc0016900, - 0x000001e0, - 0x00000000, /* CB_BLEND0_CONTROL */ - - 0xc0016900, - 0x000001b1, - 0x00000000, /* SPI_VS_OUT_CONFIG */ - - 0xc0016900, - 0x00000187, - 0x00000000, /* SPI_VS_OUT_ID_0 */ - - 0xc0016900, - 0x00000191, - 0x00000100, /* SPI_PS_INPUT_CNTL_0 */ - - 0xc00b6900, - 0x000001b3, - 0x20000001, /* SPI_PS_IN_CONTROL_0 */ - 0x00000000, /* SPI_PS_IN_CONTROL_1 */ - 0x00000000, /* SPI_INTERP_CONTROL_0 */ - 0x00000000, /* SPI_INPUT_Z */ - 0x00000000, /* SPI_FOG_CNTL */ - 0x00100000, /* SPI_BARYC_CNTL */ - 0x00000000, /* SPI_PS_IN_CONTROL_2 */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - 0x00000000, /* */ - - 0xc0026900, - 0x00000316, - 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - 0x00000010, /* */ -}; - -const u32 evergreen_vs[] = -{ - 0x00000004, - 0x80800400, - 0x0000a03c, - 0x95000688, - 0x00004000, - 0x15200688, - 0x00000000, - 0x00000000, - 0x3c000000, - 0x67961001, -#ifdef __BIG_ENDIAN - 0x000a0000, -#else - 0x00080000, -#endif - 0x00000000, - 0x1c000000, - 0x67961000, -#ifdef __BIG_ENDIAN - 0x00020008, -#else - 0x00000008, -#endif - 0x00000000, -}; - -const u32 evergreen_ps[] = -{ - 0x00000003, - 0xa00c0000, - 0x00000008, - 0x80400000, - 0x00000000, - 0x95200688, - 0x00380400, - 0x00146b10, - 0x00380000, - 0x20146b10, - 0x00380400, - 0x40146b00, - 0x80380000, - 0x60146b00, - 0x00000000, - 0x00000000, - 0x00000010, - 0x000d1000, - 0xb0800000, - 0x00000000, -}; - -const u32 evergreen_ps_size = ARRAY_SIZE(evergreen_ps); -const u32 evergreen_vs_size = ARRAY_SIZE(evergreen_vs); -const u32 evergreen_default_size = ARRAY_SIZE(evergreen_default_state); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.h deleted file mode 100644 index bb8d6c75..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_blit_shaders.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef EVERGREEN_BLIT_SHADERS_H -#define EVERGREEN_BLIT_SHADERS_H - -extern const u32 evergreen_ps[]; -extern const u32 evergreen_vs[]; -extern const u32 evergreen_default_state[]; - -extern const u32 evergreen_ps_size, evergreen_vs_size; -extern const u32 evergreen_default_size; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_cs.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_cs.c deleted file mode 100644 index ea69daef..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_cs.c +++ /dev/null @@ -1,2902 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon.h" -#include "evergreend.h" -#include "evergreen_reg_safe.h" -#include "cayman_reg_safe.h" - -#define MAX(a,b) (((a)>(b))?(a):(b)) -#define MIN(a,b) (((a)<(b))?(a):(b)) - -static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); - -struct evergreen_cs_track { - u32 group_size; - u32 nbanks; - u32 npipes; - u32 row_size; - /* value we track */ - u32 nsamples; /* unused */ - struct radeon_bo *cb_color_bo[12]; - u32 cb_color_bo_offset[12]; - struct radeon_bo *cb_color_fmask_bo[8]; /* unused */ - struct radeon_bo *cb_color_cmask_bo[8]; /* unused */ - u32 cb_color_info[12]; - u32 cb_color_view[12]; - u32 cb_color_pitch[12]; - u32 cb_color_slice[12]; - u32 cb_color_slice_idx[12]; - u32 cb_color_attrib[12]; - u32 cb_color_cmask_slice[8];/* unused */ - u32 cb_color_fmask_slice[8];/* unused */ - u32 cb_target_mask; - u32 cb_shader_mask; /* unused */ - u32 vgt_strmout_config; - u32 vgt_strmout_buffer_config; - struct radeon_bo *vgt_strmout_bo[4]; - u32 vgt_strmout_bo_offset[4]; - u32 vgt_strmout_size[4]; - u32 db_depth_control; - u32 db_depth_view; - u32 db_depth_slice; - u32 db_depth_size; - u32 db_z_info; - u32 db_z_read_offset; - u32 db_z_write_offset; - struct radeon_bo *db_z_read_bo; - struct radeon_bo *db_z_write_bo; - u32 db_s_info; - u32 db_s_read_offset; - u32 db_s_write_offset; - struct radeon_bo *db_s_read_bo; - struct radeon_bo *db_s_write_bo; - bool sx_misc_kill_all_prims; - bool cb_dirty; - bool db_dirty; - bool streamout_dirty; - u32 htile_offset; - u32 htile_surface; - struct radeon_bo *htile_bo; -}; - -static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) -{ - if (tiling_flags & RADEON_TILING_MACRO) - return ARRAY_2D_TILED_THIN1; - else if (tiling_flags & RADEON_TILING_MICRO) - return ARRAY_1D_TILED_THIN1; - else - return ARRAY_LINEAR_GENERAL; -} - -static u32 evergreen_cs_get_num_banks(u32 nbanks) -{ - switch (nbanks) { - case 2: - return ADDR_SURF_2_BANK; - case 4: - return ADDR_SURF_4_BANK; - case 8: - default: - return ADDR_SURF_8_BANK; - case 16: - return ADDR_SURF_16_BANK; - } -} - -static void evergreen_cs_track_init(struct evergreen_cs_track *track) -{ - int i; - - for (i = 0; i < 8; i++) { - track->cb_color_fmask_bo[i] = NULL; - track->cb_color_cmask_bo[i] = NULL; - track->cb_color_cmask_slice[i] = 0; - track->cb_color_fmask_slice[i] = 0; - } - - for (i = 0; i < 12; i++) { - track->cb_color_bo[i] = NULL; - track->cb_color_bo_offset[i] = 0xFFFFFFFF; - track->cb_color_info[i] = 0; - track->cb_color_view[i] = 0xFFFFFFFF; - track->cb_color_pitch[i] = 0; - track->cb_color_slice[i] = 0xfffffff; - track->cb_color_slice_idx[i] = 0; - } - track->cb_target_mask = 0xFFFFFFFF; - track->cb_shader_mask = 0xFFFFFFFF; - track->cb_dirty = true; - - track->db_depth_slice = 0xffffffff; - track->db_depth_view = 0xFFFFC000; - track->db_depth_size = 0xFFFFFFFF; - track->db_depth_control = 0xFFFFFFFF; - track->db_z_info = 0xFFFFFFFF; - track->db_z_read_offset = 0xFFFFFFFF; - track->db_z_write_offset = 0xFFFFFFFF; - track->db_z_read_bo = NULL; - track->db_z_write_bo = NULL; - track->db_s_info = 0xFFFFFFFF; - track->db_s_read_offset = 0xFFFFFFFF; - track->db_s_write_offset = 0xFFFFFFFF; - track->db_s_read_bo = NULL; - track->db_s_write_bo = NULL; - track->db_dirty = true; - track->htile_bo = NULL; - track->htile_offset = 0xFFFFFFFF; - track->htile_surface = 0; - - for (i = 0; i < 4; i++) { - track->vgt_strmout_size[i] = 0; - track->vgt_strmout_bo[i] = NULL; - track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF; - } - track->streamout_dirty = true; - track->sx_misc_kill_all_prims = false; -} - -struct eg_surface { - /* value gathered from cs */ - unsigned nbx; - unsigned nby; - unsigned format; - unsigned mode; - unsigned nbanks; - unsigned bankw; - unsigned bankh; - unsigned tsplit; - unsigned mtilea; - unsigned nsamples; - /* output value */ - unsigned bpe; - unsigned layer_size; - unsigned palign; - unsigned halign; - unsigned long base_align; -}; - -static int evergreen_surface_check_linear(struct radeon_cs_parser *p, - struct eg_surface *surf, - const char *prefix) -{ - surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples; - surf->base_align = surf->bpe; - surf->palign = 1; - surf->halign = 1; - return 0; -} - -static int evergreen_surface_check_linear_aligned(struct radeon_cs_parser *p, - struct eg_surface *surf, - const char *prefix) -{ - struct evergreen_cs_track *track = p->track; - unsigned palign; - - palign = MAX(64, track->group_size / surf->bpe); - surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples; - surf->base_align = track->group_size; - surf->palign = palign; - surf->halign = 1; - if (surf->nbx & (palign - 1)) { - if (prefix) { - dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n", - __func__, __LINE__, prefix, surf->nbx, palign); - } - return -EINVAL; - } - return 0; -} - -static int evergreen_surface_check_1d(struct radeon_cs_parser *p, - struct eg_surface *surf, - const char *prefix) -{ - struct evergreen_cs_track *track = p->track; - unsigned palign; - - palign = track->group_size / (8 * surf->bpe * surf->nsamples); - palign = MAX(8, palign); - surf->layer_size = surf->nbx * surf->nby * surf->bpe; - surf->base_align = track->group_size; - surf->palign = palign; - surf->halign = 8; - if ((surf->nbx & (palign - 1))) { - if (prefix) { - dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d (%d %d %d)\n", - __func__, __LINE__, prefix, surf->nbx, palign, - track->group_size, surf->bpe, surf->nsamples); - } - return -EINVAL; - } - if ((surf->nby & (8 - 1))) { - if (prefix) { - dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with 8\n", - __func__, __LINE__, prefix, surf->nby); - } - return -EINVAL; - } - return 0; -} - -static int evergreen_surface_check_2d(struct radeon_cs_parser *p, - struct eg_surface *surf, - const char *prefix) -{ - struct evergreen_cs_track *track = p->track; - unsigned palign, halign, tileb, slice_pt; - unsigned mtile_pr, mtile_ps, mtileb; - - tileb = 64 * surf->bpe * surf->nsamples; - slice_pt = 1; - if (tileb > surf->tsplit) { - slice_pt = tileb / surf->tsplit; - } - tileb = tileb / slice_pt; - /* macro tile width & height */ - palign = (8 * surf->bankw * track->npipes) * surf->mtilea; - halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - mtileb = (palign / 8) * (halign / 8) * tileb;; - mtile_pr = surf->nbx / palign; - mtile_ps = (mtile_pr * surf->nby) / halign; - surf->layer_size = mtile_ps * mtileb * slice_pt; - surf->base_align = (palign / 8) * (halign / 8) * tileb; - surf->palign = palign; - surf->halign = halign; - - if ((surf->nbx & (palign - 1))) { - if (prefix) { - dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n", - __func__, __LINE__, prefix, surf->nbx, palign); - } - return -EINVAL; - } - if ((surf->nby & (halign - 1))) { - if (prefix) { - dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with %d\n", - __func__, __LINE__, prefix, surf->nby, halign); - } - return -EINVAL; - } - - return 0; -} - -static int evergreen_surface_check(struct radeon_cs_parser *p, - struct eg_surface *surf, - const char *prefix) -{ - /* some common value computed here */ - surf->bpe = r600_fmt_get_blocksize(surf->format); - - switch (surf->mode) { - case ARRAY_LINEAR_GENERAL: - return evergreen_surface_check_linear(p, surf, prefix); - case ARRAY_LINEAR_ALIGNED: - return evergreen_surface_check_linear_aligned(p, surf, prefix); - case ARRAY_1D_TILED_THIN1: - return evergreen_surface_check_1d(p, surf, prefix); - case ARRAY_2D_TILED_THIN1: - return evergreen_surface_check_2d(p, surf, prefix); - default: - dev_warn(p->dev, "%s:%d %s invalid array mode %d\n", - __func__, __LINE__, prefix, surf->mode); - return -EINVAL; - } - return -EINVAL; -} - -static int evergreen_surface_value_conv_check(struct radeon_cs_parser *p, - struct eg_surface *surf, - const char *prefix) -{ - switch (surf->mode) { - case ARRAY_2D_TILED_THIN1: - break; - case ARRAY_LINEAR_GENERAL: - case ARRAY_LINEAR_ALIGNED: - case ARRAY_1D_TILED_THIN1: - return 0; - default: - dev_warn(p->dev, "%s:%d %s invalid array mode %d\n", - __func__, __LINE__, prefix, surf->mode); - return -EINVAL; - } - - switch (surf->nbanks) { - case 0: surf->nbanks = 2; break; - case 1: surf->nbanks = 4; break; - case 2: surf->nbanks = 8; break; - case 3: surf->nbanks = 16; break; - default: - dev_warn(p->dev, "%s:%d %s invalid number of banks %d\n", - __func__, __LINE__, prefix, surf->nbanks); - return -EINVAL; - } - switch (surf->bankw) { - case 0: surf->bankw = 1; break; - case 1: surf->bankw = 2; break; - case 2: surf->bankw = 4; break; - case 3: surf->bankw = 8; break; - default: - dev_warn(p->dev, "%s:%d %s invalid bankw %d\n", - __func__, __LINE__, prefix, surf->bankw); - return -EINVAL; - } - switch (surf->bankh) { - case 0: surf->bankh = 1; break; - case 1: surf->bankh = 2; break; - case 2: surf->bankh = 4; break; - case 3: surf->bankh = 8; break; - default: - dev_warn(p->dev, "%s:%d %s invalid bankh %d\n", - __func__, __LINE__, prefix, surf->bankh); - return -EINVAL; - } - switch (surf->mtilea) { - case 0: surf->mtilea = 1; break; - case 1: surf->mtilea = 2; break; - case 2: surf->mtilea = 4; break; - case 3: surf->mtilea = 8; break; - default: - dev_warn(p->dev, "%s:%d %s invalid macro tile aspect %d\n", - __func__, __LINE__, prefix, surf->mtilea); - return -EINVAL; - } - switch (surf->tsplit) { - case 0: surf->tsplit = 64; break; - case 1: surf->tsplit = 128; break; - case 2: surf->tsplit = 256; break; - case 3: surf->tsplit = 512; break; - case 4: surf->tsplit = 1024; break; - case 5: surf->tsplit = 2048; break; - case 6: surf->tsplit = 4096; break; - default: - dev_warn(p->dev, "%s:%d %s invalid tile split %d\n", - __func__, __LINE__, prefix, surf->tsplit); - return -EINVAL; - } - return 0; -} - -static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned id) -{ - struct evergreen_cs_track *track = p->track; - struct eg_surface surf; - unsigned pitch, slice, mslice; - unsigned long offset; - int r; - - mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1; - pitch = track->cb_color_pitch[id]; - slice = track->cb_color_slice[id]; - surf.nbx = (pitch + 1) * 8; - surf.nby = ((slice + 1) * 64) / surf.nbx; - surf.mode = G_028C70_ARRAY_MODE(track->cb_color_info[id]); - surf.format = G_028C70_FORMAT(track->cb_color_info[id]); - surf.tsplit = G_028C74_TILE_SPLIT(track->cb_color_attrib[id]); - surf.nbanks = G_028C74_NUM_BANKS(track->cb_color_attrib[id]); - surf.bankw = G_028C74_BANK_WIDTH(track->cb_color_attrib[id]); - surf.bankh = G_028C74_BANK_HEIGHT(track->cb_color_attrib[id]); - surf.mtilea = G_028C74_MACRO_TILE_ASPECT(track->cb_color_attrib[id]); - surf.nsamples = 1; - - if (!r600_fmt_is_valid_color(surf.format)) { - dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08x)\n", - __func__, __LINE__, surf.format, - id, track->cb_color_info[id]); - return -EINVAL; - } - - r = evergreen_surface_value_conv_check(p, &surf, "cb"); - if (r) { - return r; - } - - r = evergreen_surface_check(p, &surf, "cb"); - if (r) { - dev_warn(p->dev, "%s:%d cb[%d] invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", - __func__, __LINE__, id, track->cb_color_pitch[id], - track->cb_color_slice[id], track->cb_color_attrib[id], - track->cb_color_info[id]); - return r; - } - - offset = track->cb_color_bo_offset[id] << 8; - if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n", - __func__, __LINE__, id, offset, surf.base_align); - return -EINVAL; - } - - offset += surf.layer_size * mslice; - if (offset > radeon_bo_size(track->cb_color_bo[id])) { - /* old ddx are broken they allocate bo with w*h*bpp but - * program slice with ALIGN(h, 8), catch this and patch - * command stream. - */ - if (!surf.mode) { - volatile u32 *ib = p->ib->ptr; - unsigned long tmp, nby, bsize, size, min = 0; - - /* find the height the ddx wants */ - if (surf.nby > 8) { - min = surf.nby - 8; - } - bsize = radeon_bo_size(track->cb_color_bo[id]); - tmp = track->cb_color_bo_offset[id] << 8; - for (nby = surf.nby; nby > min; nby--) { - size = nby * surf.nbx * surf.bpe * surf.nsamples; - if ((tmp + size * mslice) <= bsize) { - break; - } - } - if (nby > min) { - surf.nby = nby; - slice = ((nby * surf.nbx) / 64) - 1; - if (!evergreen_surface_check(p, &surf, "cb")) { - /* check if this one works */ - tmp += surf.layer_size * mslice; - if (tmp <= bsize) { - ib[track->cb_color_slice_idx[id]] = slice; - goto old_ddx_ok; - } - } - } - } - dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " - "offset %d, max layer %d, bo size %ld, slice %d)\n", - __func__, __LINE__, id, surf.layer_size, - track->cb_color_bo_offset[id] << 8, mslice, - radeon_bo_size(track->cb_color_bo[id]), slice); - dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", - __func__, __LINE__, surf.nbx, surf.nby, - surf.mode, surf.bpe, surf.nsamples, - surf.bankw, surf.bankh, - surf.tsplit, surf.mtilea); - return -EINVAL; - } -old_ddx_ok: - - return 0; -} - -static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p, - unsigned nbx, unsigned nby) -{ - struct evergreen_cs_track *track = p->track; - unsigned long size; - - if (track->htile_bo == NULL) { - dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n", - __func__, __LINE__, track->db_z_info); - return -EINVAL; - } - - if (G_028ABC_LINEAR(track->htile_surface)) { - /* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */ - nbx = round_up(nbx, 16 * 8); - /* height is npipes htiles aligned == npipes * 8 pixel aligned */ - nby = round_up(nby, track->npipes * 8); - } else { - switch (track->npipes) { - case 8: - nbx = round_up(nbx, 64 * 8); - nby = round_up(nby, 64 * 8); - break; - case 4: - nbx = round_up(nbx, 64 * 8); - nby = round_up(nby, 32 * 8); - break; - case 2: - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 32 * 8); - break; - case 1: - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 16 * 8); - break; - default: - dev_warn(p->dev, "%s:%d invalid num pipes %d\n", - __func__, __LINE__, track->npipes); - return -EINVAL; - } - } - /* compute number of htile */ - nbx = nbx / 8; - nby = nby / 8; - size = nbx * nby * 4; - size += track->htile_offset; - - if (size > radeon_bo_size(track->htile_bo)) { - dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n", - __func__, __LINE__, radeon_bo_size(track->htile_bo), - size, nbx, nby); - return -EINVAL; - } - return 0; -} - -static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p) -{ - struct evergreen_cs_track *track = p->track; - struct eg_surface surf; - unsigned pitch, slice, mslice; - unsigned long offset; - int r; - - mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; - pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size); - slice = track->db_depth_slice; - surf.nbx = (pitch + 1) * 8; - surf.nby = ((slice + 1) * 64) / surf.nbx; - surf.mode = G_028040_ARRAY_MODE(track->db_z_info); - surf.format = G_028044_FORMAT(track->db_s_info); - surf.tsplit = G_028044_TILE_SPLIT(track->db_s_info); - surf.nbanks = G_028040_NUM_BANKS(track->db_z_info); - surf.bankw = G_028040_BANK_WIDTH(track->db_z_info); - surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info); - surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info); - surf.nsamples = 1; - - if (surf.format != 1) { - dev_warn(p->dev, "%s:%d stencil invalid format %d\n", - __func__, __LINE__, surf.format); - return -EINVAL; - } - /* replace by color format so we can use same code */ - surf.format = V_028C70_COLOR_8; - - r = evergreen_surface_value_conv_check(p, &surf, "stencil"); - if (r) { - return r; - } - - r = evergreen_surface_check(p, &surf, NULL); - if (r) { - /* old userspace doesn't compute proper depth/stencil alignment - * check that alignment against a bigger byte per elements and - * only report if that alignment is wrong too. - */ - surf.format = V_028C70_COLOR_8_8_8_8; - r = evergreen_surface_check(p, &surf, "stencil"); - if (r) { - dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", - __func__, __LINE__, track->db_depth_size, - track->db_depth_slice, track->db_s_info, track->db_z_info); - } - return r; - } - - offset = track->db_s_read_offset << 8; - if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", - __func__, __LINE__, offset, surf.base_align); - return -EINVAL; - } - offset += surf.layer_size * mslice; - if (offset > radeon_bo_size(track->db_s_read_bo)) { - dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", - __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_s_read_offset << 8, mslice, - radeon_bo_size(track->db_s_read_bo)); - dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", - __func__, __LINE__, track->db_depth_size, - track->db_depth_slice, track->db_s_info, track->db_z_info); - return -EINVAL; - } - - offset = track->db_s_write_offset << 8; - if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", - __func__, __LINE__, offset, surf.base_align); - return -EINVAL; - } - offset += surf.layer_size * mslice; - if (offset > radeon_bo_size(track->db_s_write_bo)) { - dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", - __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_s_write_offset << 8, mslice, - radeon_bo_size(track->db_s_write_bo)); - return -EINVAL; - } - - /* hyperz */ - if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) { - r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby); - if (r) { - return r; - } - } - - return 0; -} - -static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p) -{ - struct evergreen_cs_track *track = p->track; - struct eg_surface surf; - unsigned pitch, slice, mslice; - unsigned long offset; - int r; - - mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; - pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size); - slice = track->db_depth_slice; - surf.nbx = (pitch + 1) * 8; - surf.nby = ((slice + 1) * 64) / surf.nbx; - surf.mode = G_028040_ARRAY_MODE(track->db_z_info); - surf.format = G_028040_FORMAT(track->db_z_info); - surf.tsplit = G_028040_TILE_SPLIT(track->db_z_info); - surf.nbanks = G_028040_NUM_BANKS(track->db_z_info); - surf.bankw = G_028040_BANK_WIDTH(track->db_z_info); - surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info); - surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info); - surf.nsamples = 1; - - switch (surf.format) { - case V_028040_Z_16: - surf.format = V_028C70_COLOR_16; - break; - case V_028040_Z_24: - case V_028040_Z_32_FLOAT: - surf.format = V_028C70_COLOR_8_8_8_8; - break; - default: - dev_warn(p->dev, "%s:%d depth invalid format %d\n", - __func__, __LINE__, surf.format); - return -EINVAL; - } - - r = evergreen_surface_value_conv_check(p, &surf, "depth"); - if (r) { - dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n", - __func__, __LINE__, track->db_depth_size, - track->db_depth_slice, track->db_z_info); - return r; - } - - r = evergreen_surface_check(p, &surf, "depth"); - if (r) { - dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n", - __func__, __LINE__, track->db_depth_size, - track->db_depth_slice, track->db_z_info); - return r; - } - - offset = track->db_z_read_offset << 8; - if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", - __func__, __LINE__, offset, surf.base_align); - return -EINVAL; - } - offset += surf.layer_size * mslice; - if (offset > radeon_bo_size(track->db_z_read_bo)) { - dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", - __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_z_read_offset << 8, mslice, - radeon_bo_size(track->db_z_read_bo)); - return -EINVAL; - } - - offset = track->db_z_write_offset << 8; - if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", - __func__, __LINE__, offset, surf.base_align); - return -EINVAL; - } - offset += surf.layer_size * mslice; - if (offset > radeon_bo_size(track->db_z_write_bo)) { - dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", - __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_z_write_offset << 8, mslice, - radeon_bo_size(track->db_z_write_bo)); - return -EINVAL; - } - - /* hyperz */ - if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) { - r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby); - if (r) { - return r; - } - } - - return 0; -} - -static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, - struct radeon_bo *texture, - struct radeon_bo *mipmap, - unsigned idx) -{ - struct eg_surface surf; - unsigned long toffset, moffset; - unsigned dim, llevel, mslice, width, height, depth, i; - u32 texdw[8]; - int r; - - texdw[0] = radeon_get_ib_value(p, idx + 0); - texdw[1] = radeon_get_ib_value(p, idx + 1); - texdw[2] = radeon_get_ib_value(p, idx + 2); - texdw[3] = radeon_get_ib_value(p, idx + 3); - texdw[4] = radeon_get_ib_value(p, idx + 4); - texdw[5] = radeon_get_ib_value(p, idx + 5); - texdw[6] = radeon_get_ib_value(p, idx + 6); - texdw[7] = radeon_get_ib_value(p, idx + 7); - dim = G_030000_DIM(texdw[0]); - llevel = G_030014_LAST_LEVEL(texdw[5]); - mslice = G_030014_LAST_ARRAY(texdw[5]) + 1; - width = G_030000_TEX_WIDTH(texdw[0]) + 1; - height = G_030004_TEX_HEIGHT(texdw[1]) + 1; - depth = G_030004_TEX_DEPTH(texdw[1]) + 1; - surf.format = G_03001C_DATA_FORMAT(texdw[7]); - surf.nbx = (G_030000_PITCH(texdw[0]) + 1) * 8; - surf.nbx = r600_fmt_get_nblocksx(surf.format, surf.nbx); - surf.nby = r600_fmt_get_nblocksy(surf.format, height); - surf.mode = G_030004_ARRAY_MODE(texdw[1]); - surf.tsplit = G_030018_TILE_SPLIT(texdw[6]); - surf.nbanks = G_03001C_NUM_BANKS(texdw[7]); - surf.bankw = G_03001C_BANK_WIDTH(texdw[7]); - surf.bankh = G_03001C_BANK_HEIGHT(texdw[7]); - surf.mtilea = G_03001C_MACRO_TILE_ASPECT(texdw[7]); - surf.nsamples = 1; - toffset = texdw[2] << 8; - moffset = texdw[3] << 8; - - if (!r600_fmt_is_valid_texture(surf.format, p->family)) { - dev_warn(p->dev, "%s:%d texture invalid format %d\n", - __func__, __LINE__, surf.format); - return -EINVAL; - } - switch (dim) { - case V_030000_SQ_TEX_DIM_1D: - case V_030000_SQ_TEX_DIM_2D: - case V_030000_SQ_TEX_DIM_CUBEMAP: - case V_030000_SQ_TEX_DIM_1D_ARRAY: - case V_030000_SQ_TEX_DIM_2D_ARRAY: - depth = 1; - case V_030000_SQ_TEX_DIM_3D: - break; - default: - dev_warn(p->dev, "%s:%d texture invalid dimension %d\n", - __func__, __LINE__, dim); - return -EINVAL; - } - - r = evergreen_surface_value_conv_check(p, &surf, "texture"); - if (r) { - return r; - } - - /* align height */ - evergreen_surface_check(p, &surf, NULL); - surf.nby = ALIGN(surf.nby, surf.halign); - - r = evergreen_surface_check(p, &surf, "texture"); - if (r) { - dev_warn(p->dev, "%s:%d texture invalid 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", - __func__, __LINE__, texdw[0], texdw[1], texdw[4], - texdw[5], texdw[6], texdw[7]); - return r; - } - - /* check texture size */ - if (toffset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d texture bo base %ld not aligned with %ld\n", - __func__, __LINE__, toffset, surf.base_align); - return -EINVAL; - } - if (moffset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n", - __func__, __LINE__, moffset, surf.base_align); - return -EINVAL; - } - if (dim == SQ_TEX_DIM_3D) { - toffset += surf.layer_size * depth; - } else { - toffset += surf.layer_size * mslice; - } - if (toffset > radeon_bo_size(texture)) { - dev_warn(p->dev, "%s:%d texture bo too small (layer size %d, " - "offset %ld, max layer %d, depth %d, bo size %ld) (%d %d)\n", - __func__, __LINE__, surf.layer_size, - (unsigned long)texdw[2] << 8, mslice, - depth, radeon_bo_size(texture), - surf.nbx, surf.nby); - return -EINVAL; - } - - /* check mipmap size */ - for (i = 1; i <= llevel; i++) { - unsigned w, h, d; - - w = r600_mip_minify(width, i); - h = r600_mip_minify(height, i); - d = r600_mip_minify(depth, i); - surf.nbx = r600_fmt_get_nblocksx(surf.format, w); - surf.nby = r600_fmt_get_nblocksy(surf.format, h); - - switch (surf.mode) { - case ARRAY_2D_TILED_THIN1: - if (surf.nbx < surf.palign || surf.nby < surf.halign) { - surf.mode = ARRAY_1D_TILED_THIN1; - } - /* recompute alignment */ - evergreen_surface_check(p, &surf, NULL); - break; - case ARRAY_LINEAR_GENERAL: - case ARRAY_LINEAR_ALIGNED: - case ARRAY_1D_TILED_THIN1: - break; - default: - dev_warn(p->dev, "%s:%d invalid array mode %d\n", - __func__, __LINE__, surf.mode); - return -EINVAL; - } - surf.nbx = ALIGN(surf.nbx, surf.palign); - surf.nby = ALIGN(surf.nby, surf.halign); - - r = evergreen_surface_check(p, &surf, "mipmap"); - if (r) { - return r; - } - - if (dim == SQ_TEX_DIM_3D) { - moffset += surf.layer_size * d; - } else { - moffset += surf.layer_size * mslice; - } - if (moffset > radeon_bo_size(mipmap)) { - dev_warn(p->dev, "%s:%d mipmap [%d] bo too small (layer size %d, " - "offset %ld, coffset %ld, max layer %d, depth %d, " - "bo size %ld) level0 (%d %d %d)\n", - __func__, __LINE__, i, surf.layer_size, - (unsigned long)texdw[3] << 8, moffset, mslice, - d, radeon_bo_size(mipmap), - width, height, depth); - dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", - __func__, __LINE__, surf.nbx, surf.nby, - surf.mode, surf.bpe, surf.nsamples, - surf.bankw, surf.bankh, - surf.tsplit, surf.mtilea); - return -EINVAL; - } - } - - return 0; -} - -static int evergreen_cs_track_check(struct radeon_cs_parser *p) -{ - struct evergreen_cs_track *track = p->track; - unsigned tmp, i; - int r; - unsigned buffer_mask = 0; - - /* check streamout */ - if (track->streamout_dirty && track->vgt_strmout_config) { - for (i = 0; i < 4; i++) { - if (track->vgt_strmout_config & (1 << i)) { - buffer_mask |= (track->vgt_strmout_buffer_config >> (i * 4)) & 0xf; - } - } - - for (i = 0; i < 4; i++) { - if (buffer_mask & (1 << i)) { - if (track->vgt_strmout_bo[i]) { - u64 offset = (u64)track->vgt_strmout_bo_offset[i] + - (u64)track->vgt_strmout_size[i]; - if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) { - DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n", - i, offset, - radeon_bo_size(track->vgt_strmout_bo[i])); - return -EINVAL; - } - } else { - dev_warn(p->dev, "No buffer for streamout %d\n", i); - return -EINVAL; - } - } - } - track->streamout_dirty = false; - } - - if (track->sx_misc_kill_all_prims) - return 0; - - /* check that we have a cb for each enabled target - */ - if (track->cb_dirty) { - tmp = track->cb_target_mask; - for (i = 0; i < 8; i++) { - if ((tmp >> (i * 4)) & 0xF) { - /* at least one component is enabled */ - if (track->cb_color_bo[i] == NULL) { - dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n", - __func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i); - return -EINVAL; - } - /* check cb */ - r = evergreen_cs_track_validate_cb(p, i); - if (r) { - return r; - } - } - } - track->cb_dirty = false; - } - - if (track->db_dirty) { - /* Check stencil buffer */ - if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { - r = evergreen_cs_track_validate_stencil(p); - if (r) - return r; - } - /* Check depth buffer */ - if (G_028800_Z_ENABLE(track->db_depth_control)) { - r = evergreen_cs_track_validate_depth(p); - if (r) - return r; - } - track->db_dirty = false; - } - - return 0; -} - -/** - * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet - * @parser: parser structure holding parsing context. - * @pkt: where to store packet informations - * - * Assume that chunk_ib_index is properly set. Will return -EINVAL - * if packet is bigger than remaining ib size. or if packets is unknown. - **/ -int evergreen_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx) -{ - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - uint32_t header; - - if (idx >= ib_chunk->length_dw) { - DRM_ERROR("Can not parse packet at %d after CS end %d !\n", - idx, ib_chunk->length_dw); - return -EINVAL; - } - header = radeon_get_ib_value(p, idx); - pkt->idx = idx; - pkt->type = CP_PACKET_GET_TYPE(header); - pkt->count = CP_PACKET_GET_COUNT(header); - pkt->one_reg_wr = 0; - switch (pkt->type) { - case PACKET_TYPE0: - pkt->reg = CP_PACKET0_GET_REG(header); - break; - case PACKET_TYPE3: - pkt->opcode = CP_PACKET3_GET_OPCODE(header); - break; - case PACKET_TYPE2: - pkt->count = -1; - break; - default: - DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); - return -EINVAL; - } - if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { - DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", - pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); - return -EINVAL; - } - return 0; -} - -/** - * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3 - * @parser: parser structure holding parsing context. - * @data: pointer to relocation data - * @offset_start: starting offset - * @offset_mask: offset mask (to align start offset on) - * @reloc: reloc informations - * - * Check next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_packet p3reloc; - unsigned idx; - int r; - - if (p->chunk_relocs_idx == -1) { - DRM_ERROR("No relocation chunk !\n"); - return -EINVAL; - } - *cs_reloc = NULL; - relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return r; - } - p->idx += p3reloc.count + 2; - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - return -EINVAL; - } - idx = radeon_get_ib_value(p, p3reloc.idx + 1); - if (idx >= relocs_chunk->length_dw) { - DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", - idx, relocs_chunk->length_dw); - return -EINVAL; - } - /* FIXME: we assume reloc size is 4 dwords */ - *cs_reloc = p->relocs_ptr[(idx / 4)]; - return 0; -} - -/** - * evergreen_cs_packet_next_vline() - parse userspace VLINE packet - * @parser: parser structure holding parsing context. - * - * Userspace sends a special sequence for VLINE waits. - * PACKET0 - VLINE_START_END + value - * PACKET3 - WAIT_REG_MEM poll vline status reg - * RELOC (P3) - crtc_id in reloc. - * - * This function parses this and relocates the VLINE START END - * and WAIT_REG_MEM packets to the correct crtc. - * It also detects a switched off crtc and nulls out the - * wait in that case. - */ -static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) -{ - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - struct radeon_cs_packet p3reloc, wait_reg_mem; - int crtc_id; - int r; - uint32_t header, h_idx, reg, wait_reg_mem_info; - volatile uint32_t *ib; - - ib = p->ib->ptr; - - /* parse the WAIT_REG_MEM */ - r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx); - if (r) - return r; - - /* check its a WAIT_REG_MEM */ - if (wait_reg_mem.type != PACKET_TYPE3 || - wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { - DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); - return -EINVAL; - } - - wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); - /* bit 4 is reg (0) or mem (1) */ - if (wait_reg_mem_info & 0x10) { - DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); - return -EINVAL; - } - /* waiting for value to be equal */ - if ((wait_reg_mem_info & 0x7) != 0x3) { - DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); - return -EINVAL; - } - if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) { - DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); - return -EINVAL; - } - - if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) { - DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); - return -EINVAL; - } - - /* jump over the NOP */ - r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); - if (r) - return r; - - h_idx = p->idx - 2; - p->idx += wait_reg_mem.count + 2; - p->idx += p3reloc.count + 2; - - header = radeon_get_ib_value(p, h_idx); - crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); - reg = CP_PACKET0_GET_REG(header); - obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_ERROR("cannot find crtc %d\n", crtc_id); - return -EINVAL; - } - crtc = obj_to_crtc(obj); - radeon_crtc = to_radeon_crtc(crtc); - crtc_id = radeon_crtc->crtc_id; - - if (!crtc->enabled) { - /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ - ib[h_idx + 2] = PACKET2(0); - ib[h_idx + 3] = PACKET2(0); - ib[h_idx + 4] = PACKET2(0); - ib[h_idx + 5] = PACKET2(0); - ib[h_idx + 6] = PACKET2(0); - ib[h_idx + 7] = PACKET2(0); - ib[h_idx + 8] = PACKET2(0); - } else { - switch (reg) { - case EVERGREEN_VLINE_START_END: - header &= ~R600_CP_PACKET0_REG_MASK; - header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2; - ib[h_idx] = header; - ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2; - break; - default: - DRM_ERROR("unknown crtc reloc\n"); - return -EINVAL; - } - } - return 0; -} - -static int evergreen_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg) -{ - int r; - - switch (reg) { - case EVERGREEN_VLINE_START_END: - r = evergreen_cs_packet_parse_vline(p); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - return r; - } - break; - default: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", - reg, idx); - return -EINVAL; - } - return 0; -} - -static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - unsigned reg, i; - unsigned idx; - int r; - - idx = pkt->idx + 1; - reg = pkt->reg; - for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { - r = evergreen_packet0_check(p, pkt, idx, reg); - if (r) { - return r; - } - } - return 0; -} - -/** - * evergreen_cs_check_reg() - check if register is authorized or not - * @parser: parser structure holding parsing context - * @reg: register we are testing - * @idx: index into the cs buffer - * - * This function will test against evergreen_reg_safe_bm and return 0 - * if register is safe. If register is not flag as safe this function - * will test it against a list of register needind special handling. - */ -static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) -{ - struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; - struct radeon_cs_reloc *reloc; - u32 last_reg; - u32 m, i, tmp, *ib; - int r; - - if (p->rdev->family >= CHIP_CAYMAN) - last_reg = ARRAY_SIZE(cayman_reg_safe_bm); - else - last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); - - i = (reg >> 7); - if (i >= last_reg) { - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return -EINVAL; - } - m = 1 << ((reg >> 2) & 31); - if (p->rdev->family >= CHIP_CAYMAN) { - if (!(cayman_reg_safe_bm[i] & m)) - return 0; - } else { - if (!(evergreen_reg_safe_bm[i] & m)) - return 0; - } - ib = p->ib->ptr; - switch (reg) { - /* force following reg to 0 in an attempt to disable out buffer - * which will need us to better understand how it works to perform - * security check on it (Jerome) - */ - case SQ_ESGS_RING_SIZE: - case SQ_GSVS_RING_SIZE: - case SQ_ESTMP_RING_SIZE: - case SQ_GSTMP_RING_SIZE: - case SQ_HSTMP_RING_SIZE: - case SQ_LSTMP_RING_SIZE: - case SQ_PSTMP_RING_SIZE: - case SQ_VSTMP_RING_SIZE: - case SQ_ESGS_RING_ITEMSIZE: - case SQ_ESTMP_RING_ITEMSIZE: - case SQ_GSTMP_RING_ITEMSIZE: - case SQ_GSVS_RING_ITEMSIZE: - case SQ_GS_VERT_ITEMSIZE: - case SQ_GS_VERT_ITEMSIZE_1: - case SQ_GS_VERT_ITEMSIZE_2: - case SQ_GS_VERT_ITEMSIZE_3: - case SQ_GSVS_RING_OFFSET_1: - case SQ_GSVS_RING_OFFSET_2: - case SQ_GSVS_RING_OFFSET_3: - case SQ_HSTMP_RING_ITEMSIZE: - case SQ_LSTMP_RING_ITEMSIZE: - case SQ_PSTMP_RING_ITEMSIZE: - case SQ_VSTMP_RING_ITEMSIZE: - case VGT_TF_RING_SIZE: - /* get value to populate the IB don't remove */ - /*tmp =radeon_get_ib_value(p, idx); - ib[idx] = 0;*/ - break; - case SQ_ESGS_RING_BASE: - case SQ_GSVS_RING_BASE: - case SQ_ESTMP_RING_BASE: - case SQ_GSTMP_RING_BASE: - case SQ_HSTMP_RING_BASE: - case SQ_LSTMP_RING_BASE: - case SQ_PSTMP_RING_BASE: - case SQ_VSTMP_RING_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case DB_DEPTH_CONTROL: - track->db_depth_control = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case CAYMAN_DB_EQAA: - if (p->rdev->family < CHIP_CAYMAN) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - break; - case CAYMAN_DB_DEPTH_INFO: - if (p->rdev->family < CHIP_CAYMAN) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - break; - case DB_Z_INFO: - track->db_z_info = radeon_get_ib_value(p, idx); - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] &= ~Z_ARRAY_MODE(0xf); - track->db_z_info &= ~Z_ARRAY_MODE(0xf); - ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - unsigned bankw, bankh, mtaspect, tile_split; - - evergreen_tiling_fields(reloc->lobj.tiling_flags, - &bankw, &bankh, &mtaspect, - &tile_split); - ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); - ib[idx] |= DB_TILE_SPLIT(tile_split) | - DB_BANK_WIDTH(bankw) | - DB_BANK_HEIGHT(bankh) | - DB_MACRO_TILE_ASPECT(mtaspect); - } - } - track->db_dirty = true; - break; - case DB_STENCIL_INFO: - track->db_s_info = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case DB_DEPTH_VIEW: - track->db_depth_view = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case DB_DEPTH_SIZE: - track->db_depth_size = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case R_02805C_DB_DEPTH_SLICE: - track->db_depth_slice = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case DB_Z_READ_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->db_z_read_offset = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->db_z_read_bo = reloc->robj; - track->db_dirty = true; - break; - case DB_Z_WRITE_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->db_z_write_offset = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->db_z_write_bo = reloc->robj; - track->db_dirty = true; - break; - case DB_STENCIL_READ_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->db_s_read_offset = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->db_s_read_bo = reloc->robj; - track->db_dirty = true; - break; - case DB_STENCIL_WRITE_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->db_s_write_offset = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->db_s_write_bo = reloc->robj; - track->db_dirty = true; - break; - case VGT_STRMOUT_CONFIG: - track->vgt_strmout_config = radeon_get_ib_value(p, idx); - track->streamout_dirty = true; - break; - case VGT_STRMOUT_BUFFER_CONFIG: - track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx); - track->streamout_dirty = true; - break; - case VGT_STRMOUT_BUFFER_BASE_0: - case VGT_STRMOUT_BUFFER_BASE_1: - case VGT_STRMOUT_BUFFER_BASE_2: - case VGT_STRMOUT_BUFFER_BASE_3: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16; - track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->vgt_strmout_bo[tmp] = reloc->robj; - track->streamout_dirty = true; - break; - case VGT_STRMOUT_BUFFER_SIZE_0: - case VGT_STRMOUT_BUFFER_SIZE_1: - case VGT_STRMOUT_BUFFER_SIZE_2: - case VGT_STRMOUT_BUFFER_SIZE_3: - tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16; - /* size in register is DWs, convert to bytes */ - track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4; - track->streamout_dirty = true; - break; - case CP_COHER_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "missing reloc for CP_COHER_BASE " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - case CB_TARGET_MASK: - track->cb_target_mask = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case CB_SHADER_MASK: - track->cb_shader_mask = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case PA_SC_AA_CONFIG: - if (p->rdev->family >= CHIP_CAYMAN) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK; - track->nsamples = 1 << tmp; - break; - case CAYMAN_PA_SC_AA_CONFIG: - if (p->rdev->family < CHIP_CAYMAN) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = radeon_get_ib_value(p, idx) & CAYMAN_MSAA_NUM_SAMPLES_MASK; - track->nsamples = 1 << tmp; - break; - case CB_COLOR0_VIEW: - case CB_COLOR1_VIEW: - case CB_COLOR2_VIEW: - case CB_COLOR3_VIEW: - case CB_COLOR4_VIEW: - case CB_COLOR5_VIEW: - case CB_COLOR6_VIEW: - case CB_COLOR7_VIEW: - tmp = (reg - CB_COLOR0_VIEW) / 0x3c; - track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case CB_COLOR8_VIEW: - case CB_COLOR9_VIEW: - case CB_COLOR10_VIEW: - case CB_COLOR11_VIEW: - tmp = ((reg - CB_COLOR8_VIEW) / 0x1c) + 8; - track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case CB_COLOR0_INFO: - case CB_COLOR1_INFO: - case CB_COLOR2_INFO: - case CB_COLOR3_INFO: - case CB_COLOR4_INFO: - case CB_COLOR5_INFO: - case CB_COLOR6_INFO: - case CB_COLOR7_INFO: - tmp = (reg - CB_COLOR0_INFO) / 0x3c; - track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - } - track->cb_dirty = true; - break; - case CB_COLOR8_INFO: - case CB_COLOR9_INFO: - case CB_COLOR10_INFO: - case CB_COLOR11_INFO: - tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; - track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - } - track->cb_dirty = true; - break; - case CB_COLOR0_PITCH: - case CB_COLOR1_PITCH: - case CB_COLOR2_PITCH: - case CB_COLOR3_PITCH: - case CB_COLOR4_PITCH: - case CB_COLOR5_PITCH: - case CB_COLOR6_PITCH: - case CB_COLOR7_PITCH: - tmp = (reg - CB_COLOR0_PITCH) / 0x3c; - track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case CB_COLOR8_PITCH: - case CB_COLOR9_PITCH: - case CB_COLOR10_PITCH: - case CB_COLOR11_PITCH: - tmp = ((reg - CB_COLOR8_PITCH) / 0x1c) + 8; - track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case CB_COLOR0_SLICE: - case CB_COLOR1_SLICE: - case CB_COLOR2_SLICE: - case CB_COLOR3_SLICE: - case CB_COLOR4_SLICE: - case CB_COLOR5_SLICE: - case CB_COLOR6_SLICE: - case CB_COLOR7_SLICE: - tmp = (reg - CB_COLOR0_SLICE) / 0x3c; - track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); - track->cb_color_slice_idx[tmp] = idx; - track->cb_dirty = true; - break; - case CB_COLOR8_SLICE: - case CB_COLOR9_SLICE: - case CB_COLOR10_SLICE: - case CB_COLOR11_SLICE: - tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8; - track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); - track->cb_color_slice_idx[tmp] = idx; - track->cb_dirty = true; - break; - case CB_COLOR0_ATTRIB: - case CB_COLOR1_ATTRIB: - case CB_COLOR2_ATTRIB: - case CB_COLOR3_ATTRIB: - case CB_COLOR4_ATTRIB: - case CB_COLOR5_ATTRIB: - case CB_COLOR6_ATTRIB: - case CB_COLOR7_ATTRIB: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - unsigned bankw, bankh, mtaspect, tile_split; - - evergreen_tiling_fields(reloc->lobj.tiling_flags, - &bankw, &bankh, &mtaspect, - &tile_split); - ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); - ib[idx] |= CB_TILE_SPLIT(tile_split) | - CB_BANK_WIDTH(bankw) | - CB_BANK_HEIGHT(bankh) | - CB_MACRO_TILE_ASPECT(mtaspect); - } - } - tmp = ((reg - CB_COLOR0_ATTRIB) / 0x3c); - track->cb_color_attrib[tmp] = ib[idx]; - track->cb_dirty = true; - break; - case CB_COLOR8_ATTRIB: - case CB_COLOR9_ATTRIB: - case CB_COLOR10_ATTRIB: - case CB_COLOR11_ATTRIB: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - unsigned bankw, bankh, mtaspect, tile_split; - - evergreen_tiling_fields(reloc->lobj.tiling_flags, - &bankw, &bankh, &mtaspect, - &tile_split); - ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); - ib[idx] |= CB_TILE_SPLIT(tile_split) | - CB_BANK_WIDTH(bankw) | - CB_BANK_HEIGHT(bankh) | - CB_MACRO_TILE_ASPECT(mtaspect); - } - } - tmp = ((reg - CB_COLOR8_ATTRIB) / 0x1c) + 8; - track->cb_color_attrib[tmp] = ib[idx]; - track->cb_dirty = true; - break; - case CB_COLOR0_FMASK: - case CB_COLOR1_FMASK: - case CB_COLOR2_FMASK: - case CB_COLOR3_FMASK: - case CB_COLOR4_FMASK: - case CB_COLOR5_FMASK: - case CB_COLOR6_FMASK: - case CB_COLOR7_FMASK: - tmp = (reg - CB_COLOR0_FMASK) / 0x3c; - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_fmask_bo[tmp] = reloc->robj; - break; - case CB_COLOR0_CMASK: - case CB_COLOR1_CMASK: - case CB_COLOR2_CMASK: - case CB_COLOR3_CMASK: - case CB_COLOR4_CMASK: - case CB_COLOR5_CMASK: - case CB_COLOR6_CMASK: - case CB_COLOR7_CMASK: - tmp = (reg - CB_COLOR0_CMASK) / 0x3c; - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_cmask_bo[tmp] = reloc->robj; - break; - case CB_COLOR0_FMASK_SLICE: - case CB_COLOR1_FMASK_SLICE: - case CB_COLOR2_FMASK_SLICE: - case CB_COLOR3_FMASK_SLICE: - case CB_COLOR4_FMASK_SLICE: - case CB_COLOR5_FMASK_SLICE: - case CB_COLOR6_FMASK_SLICE: - case CB_COLOR7_FMASK_SLICE: - tmp = (reg - CB_COLOR0_FMASK_SLICE) / 0x3c; - track->cb_color_fmask_slice[tmp] = radeon_get_ib_value(p, idx); - break; - case CB_COLOR0_CMASK_SLICE: - case CB_COLOR1_CMASK_SLICE: - case CB_COLOR2_CMASK_SLICE: - case CB_COLOR3_CMASK_SLICE: - case CB_COLOR4_CMASK_SLICE: - case CB_COLOR5_CMASK_SLICE: - case CB_COLOR6_CMASK_SLICE: - case CB_COLOR7_CMASK_SLICE: - tmp = (reg - CB_COLOR0_CMASK_SLICE) / 0x3c; - track->cb_color_cmask_slice[tmp] = radeon_get_ib_value(p, idx); - break; - case CB_COLOR0_BASE: - case CB_COLOR1_BASE: - case CB_COLOR2_BASE: - case CB_COLOR3_BASE: - case CB_COLOR4_BASE: - case CB_COLOR5_BASE: - case CB_COLOR6_BASE: - case CB_COLOR7_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = (reg - CB_COLOR0_BASE) / 0x3c; - track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_bo[tmp] = reloc->robj; - track->cb_dirty = true; - break; - case CB_COLOR8_BASE: - case CB_COLOR9_BASE: - case CB_COLOR10_BASE: - case CB_COLOR11_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = ((reg - CB_COLOR8_BASE) / 0x1c) + 8; - track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_bo[tmp] = reloc->robj; - track->cb_dirty = true; - break; - case DB_HTILE_DATA_BASE: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->htile_offset = radeon_get_ib_value(p, idx); - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->htile_bo = reloc->robj; - track->db_dirty = true; - break; - case DB_HTILE_SURFACE: - /* 8x8 only */ - track->htile_surface = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case CB_IMMED0_BASE: - case CB_IMMED1_BASE: - case CB_IMMED2_BASE: - case CB_IMMED3_BASE: - case CB_IMMED4_BASE: - case CB_IMMED5_BASE: - case CB_IMMED6_BASE: - case CB_IMMED7_BASE: - case CB_IMMED8_BASE: - case CB_IMMED9_BASE: - case CB_IMMED10_BASE: - case CB_IMMED11_BASE: - case SQ_PGM_START_FS: - case SQ_PGM_START_ES: - case SQ_PGM_START_VS: - case SQ_PGM_START_GS: - case SQ_PGM_START_PS: - case SQ_PGM_START_HS: - case SQ_PGM_START_LS: - case SQ_CONST_MEM_BASE: - case SQ_ALU_CONST_CACHE_GS_0: - case SQ_ALU_CONST_CACHE_GS_1: - case SQ_ALU_CONST_CACHE_GS_2: - case SQ_ALU_CONST_CACHE_GS_3: - case SQ_ALU_CONST_CACHE_GS_4: - case SQ_ALU_CONST_CACHE_GS_5: - case SQ_ALU_CONST_CACHE_GS_6: - case SQ_ALU_CONST_CACHE_GS_7: - case SQ_ALU_CONST_CACHE_GS_8: - case SQ_ALU_CONST_CACHE_GS_9: - case SQ_ALU_CONST_CACHE_GS_10: - case SQ_ALU_CONST_CACHE_GS_11: - case SQ_ALU_CONST_CACHE_GS_12: - case SQ_ALU_CONST_CACHE_GS_13: - case SQ_ALU_CONST_CACHE_GS_14: - case SQ_ALU_CONST_CACHE_GS_15: - case SQ_ALU_CONST_CACHE_PS_0: - case SQ_ALU_CONST_CACHE_PS_1: - case SQ_ALU_CONST_CACHE_PS_2: - case SQ_ALU_CONST_CACHE_PS_3: - case SQ_ALU_CONST_CACHE_PS_4: - case SQ_ALU_CONST_CACHE_PS_5: - case SQ_ALU_CONST_CACHE_PS_6: - case SQ_ALU_CONST_CACHE_PS_7: - case SQ_ALU_CONST_CACHE_PS_8: - case SQ_ALU_CONST_CACHE_PS_9: - case SQ_ALU_CONST_CACHE_PS_10: - case SQ_ALU_CONST_CACHE_PS_11: - case SQ_ALU_CONST_CACHE_PS_12: - case SQ_ALU_CONST_CACHE_PS_13: - case SQ_ALU_CONST_CACHE_PS_14: - case SQ_ALU_CONST_CACHE_PS_15: - case SQ_ALU_CONST_CACHE_VS_0: - case SQ_ALU_CONST_CACHE_VS_1: - case SQ_ALU_CONST_CACHE_VS_2: - case SQ_ALU_CONST_CACHE_VS_3: - case SQ_ALU_CONST_CACHE_VS_4: - case SQ_ALU_CONST_CACHE_VS_5: - case SQ_ALU_CONST_CACHE_VS_6: - case SQ_ALU_CONST_CACHE_VS_7: - case SQ_ALU_CONST_CACHE_VS_8: - case SQ_ALU_CONST_CACHE_VS_9: - case SQ_ALU_CONST_CACHE_VS_10: - case SQ_ALU_CONST_CACHE_VS_11: - case SQ_ALU_CONST_CACHE_VS_12: - case SQ_ALU_CONST_CACHE_VS_13: - case SQ_ALU_CONST_CACHE_VS_14: - case SQ_ALU_CONST_CACHE_VS_15: - case SQ_ALU_CONST_CACHE_HS_0: - case SQ_ALU_CONST_CACHE_HS_1: - case SQ_ALU_CONST_CACHE_HS_2: - case SQ_ALU_CONST_CACHE_HS_3: - case SQ_ALU_CONST_CACHE_HS_4: - case SQ_ALU_CONST_CACHE_HS_5: - case SQ_ALU_CONST_CACHE_HS_6: - case SQ_ALU_CONST_CACHE_HS_7: - case SQ_ALU_CONST_CACHE_HS_8: - case SQ_ALU_CONST_CACHE_HS_9: - case SQ_ALU_CONST_CACHE_HS_10: - case SQ_ALU_CONST_CACHE_HS_11: - case SQ_ALU_CONST_CACHE_HS_12: - case SQ_ALU_CONST_CACHE_HS_13: - case SQ_ALU_CONST_CACHE_HS_14: - case SQ_ALU_CONST_CACHE_HS_15: - case SQ_ALU_CONST_CACHE_LS_0: - case SQ_ALU_CONST_CACHE_LS_1: - case SQ_ALU_CONST_CACHE_LS_2: - case SQ_ALU_CONST_CACHE_LS_3: - case SQ_ALU_CONST_CACHE_LS_4: - case SQ_ALU_CONST_CACHE_LS_5: - case SQ_ALU_CONST_CACHE_LS_6: - case SQ_ALU_CONST_CACHE_LS_7: - case SQ_ALU_CONST_CACHE_LS_8: - case SQ_ALU_CONST_CACHE_LS_9: - case SQ_ALU_CONST_CACHE_LS_10: - case SQ_ALU_CONST_CACHE_LS_11: - case SQ_ALU_CONST_CACHE_LS_12: - case SQ_ALU_CONST_CACHE_LS_13: - case SQ_ALU_CONST_CACHE_LS_14: - case SQ_ALU_CONST_CACHE_LS_15: - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case SX_MEMORY_EXPORT_BASE: - if (p->rdev->family >= CHIP_CAYMAN) { - dev_warn(p->dev, "bad SET_CONFIG_REG " - "0x%04X\n", reg); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONFIG_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case CAYMAN_SX_SCATTER_EXPORT_BASE: - if (p->rdev->family < CHIP_CAYMAN) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case SX_MISC: - track->sx_misc_kill_all_prims = (radeon_get_ib_value(p, idx) & 0x1) != 0; - break; - default: - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return -EINVAL; - } - return 0; -} - -static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) -{ - u32 last_reg, m, i; - - if (p->rdev->family >= CHIP_CAYMAN) - last_reg = ARRAY_SIZE(cayman_reg_safe_bm); - else - last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); - - i = (reg >> 7); - if (i >= last_reg) { - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return false; - } - m = 1 << ((reg >> 2) & 31); - if (p->rdev->family >= CHIP_CAYMAN) { - if (!(cayman_reg_safe_bm[i] & m)) - return true; - } else { - if (!(evergreen_reg_safe_bm[i] & m)) - return true; - } - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return false; -} - -static int evergreen_packet3_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - struct radeon_cs_reloc *reloc; - struct evergreen_cs_track *track; - volatile u32 *ib; - unsigned idx; - unsigned i; - unsigned start_reg, end_reg, reg; - int r; - u32 idx_value; - - track = (struct evergreen_cs_track *)p->track; - ib = p->ib->ptr; - idx = pkt->idx + 1; - idx_value = radeon_get_ib_value(p, idx); - - switch (pkt->opcode) { - case PACKET3_SET_PREDICATION: - { - int pred_op; - int tmp; - uint64_t offset; - - if (pkt->count != 1) { - DRM_ERROR("bad SET PREDICATION\n"); - return -EINVAL; - } - - tmp = radeon_get_ib_value(p, idx + 1); - pred_op = (tmp >> 16) & 0x7; - - /* for the clear predicate operation */ - if (pred_op == 0) - return 0; - - if (pred_op > 2) { - DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op); - return -EINVAL; - } - - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET PREDICATION\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (idx_value & 0xfffffff0) + - ((u64)(tmp & 0xff) << 32); - - ib[idx + 0] = offset; - ib[idx + 1] = (tmp & 0xffffff00) | (upper_32_bits(offset) & 0xff); - } - break; - case PACKET3_CONTEXT_CONTROL: - if (pkt->count != 1) { - DRM_ERROR("bad CONTEXT_CONTROL\n"); - return -EINVAL; - } - break; - case PACKET3_INDEX_TYPE: - case PACKET3_NUM_INSTANCES: - case PACKET3_CLEAR_STATE: - if (pkt->count) { - DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n"); - return -EINVAL; - } - break; - case CAYMAN_PACKET3_DEALLOC_STATE: - if (p->rdev->family < CHIP_CAYMAN) { - DRM_ERROR("bad PACKET3_DEALLOC_STATE\n"); - return -EINVAL; - } - if (pkt->count) { - DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n"); - return -EINVAL; - } - break; - case PACKET3_INDEX_BASE: - { - uint64_t offset; - - if (pkt->count != 1) { - DRM_ERROR("bad INDEX_BASE\n"); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad INDEX_BASE\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - idx_value + - ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); - - ib[idx+0] = offset; - ib[idx+1] = upper_32_bits(offset) & 0xff; - - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - } - case PACKET3_DRAW_INDEX: - { - uint64_t offset; - if (pkt->count != 3) { - DRM_ERROR("bad DRAW_INDEX\n"); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad DRAW_INDEX\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - idx_value + - ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); - - ib[idx+0] = offset; - ib[idx+1] = upper_32_bits(offset) & 0xff; - - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - } - case PACKET3_DRAW_INDEX_2: - { - uint64_t offset; - - if (pkt->count != 4) { - DRM_ERROR("bad DRAW_INDEX_2\n"); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad DRAW_INDEX_2\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - radeon_get_ib_value(p, idx+1) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = offset; - ib[idx+2] = upper_32_bits(offset) & 0xff; - - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - } - case PACKET3_DRAW_INDEX_AUTO: - if (pkt->count != 1) { - DRM_ERROR("bad DRAW_INDEX_AUTO\n"); - return -EINVAL; - } - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); - return r; - } - break; - case PACKET3_DRAW_INDEX_MULTI_AUTO: - if (pkt->count != 2) { - DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n"); - return -EINVAL; - } - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); - return r; - } - break; - case PACKET3_DRAW_INDEX_IMMD: - if (pkt->count < 2) { - DRM_ERROR("bad DRAW_INDEX_IMMD\n"); - return -EINVAL; - } - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - case PACKET3_DRAW_INDEX_OFFSET: - if (pkt->count != 2) { - DRM_ERROR("bad DRAW_INDEX_OFFSET\n"); - return -EINVAL; - } - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - case PACKET3_DRAW_INDEX_OFFSET_2: - if (pkt->count != 3) { - DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n"); - return -EINVAL; - } - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - case PACKET3_DISPATCH_DIRECT: - if (pkt->count != 3) { - DRM_ERROR("bad DISPATCH_DIRECT\n"); - return -EINVAL; - } - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); - return r; - } - break; - case PACKET3_DISPATCH_INDIRECT: - if (pkt->count != 1) { - DRM_ERROR("bad DISPATCH_INDIRECT\n"); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad DISPATCH_INDIRECT\n"); - return -EINVAL; - } - ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); - r = evergreen_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - case PACKET3_WAIT_REG_MEM: - if (pkt->count != 5) { - DRM_ERROR("bad WAIT_REG_MEM\n"); - return -EINVAL; - } - /* bit 4 is reg (0) or mem (1) */ - if (idx_value & 0x10) { - uint64_t offset; - - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad WAIT_REG_MEM\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffffc) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc); - ib[idx+2] = upper_32_bits(offset) & 0xff; - } - break; - case PACKET3_SURFACE_SYNC: - if (pkt->count != 3) { - DRM_ERROR("bad SURFACE_SYNC\n"); - return -EINVAL; - } - /* 0xffffffff/0x0 is flush all cache flag */ - if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || - radeon_get_ib_value(p, idx + 2) != 0) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SURFACE_SYNC\n"); - return -EINVAL; - } - ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - } - break; - case PACKET3_EVENT_WRITE: - if (pkt->count != 2 && pkt->count != 0) { - DRM_ERROR("bad EVENT_WRITE\n"); - return -EINVAL; - } - if (pkt->count) { - uint64_t offset; - - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad EVENT_WRITE\n"); - return -EINVAL; - } - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffff8) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = offset & 0xfffffff8; - ib[idx+2] = upper_32_bits(offset) & 0xff; - } - break; - case PACKET3_EVENT_WRITE_EOP: - { - uint64_t offset; - - if (pkt->count != 4) { - DRM_ERROR("bad EVENT_WRITE_EOP\n"); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad EVENT_WRITE_EOP\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffffc) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = offset & 0xfffffffc; - ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff); - break; - } - case PACKET3_EVENT_WRITE_EOS: - { - uint64_t offset; - - if (pkt->count != 3) { - DRM_ERROR("bad EVENT_WRITE_EOS\n"); - return -EINVAL; - } - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad EVENT_WRITE_EOS\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffffc) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = offset & 0xfffffffc; - ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff); - break; - } - case PACKET3_SET_CONFIG_REG: - start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CONFIG_REG_START) || - (start_reg >= PACKET3_SET_CONFIG_REG_END) || - (end_reg >= PACKET3_SET_CONFIG_REG_END)) { - DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); - return -EINVAL; - } - for (i = 0; i < pkt->count; i++) { - reg = start_reg + (4 * i); - r = evergreen_cs_check_reg(p, reg, idx+1+i); - if (r) - return r; - } - break; - case PACKET3_SET_CONTEXT_REG: - start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CONTEXT_REG_START) || - (start_reg >= PACKET3_SET_CONTEXT_REG_END) || - (end_reg >= PACKET3_SET_CONTEXT_REG_END)) { - DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n"); - return -EINVAL; - } - for (i = 0; i < pkt->count; i++) { - reg = start_reg + (4 * i); - r = evergreen_cs_check_reg(p, reg, idx+1+i); - if (r) - return r; - } - break; - case PACKET3_SET_RESOURCE: - if (pkt->count % 8) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_RESOURCE_START) || - (start_reg >= PACKET3_SET_RESOURCE_END) || - (end_reg >= PACKET3_SET_RESOURCE_END)) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - for (i = 0; i < (pkt->count / 8); i++) { - struct radeon_bo *texture, *mipmap; - u32 toffset, moffset; - u32 size, offset; - - switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { - case SQ_TEX_VTX_VALID_TEXTURE: - /* tex base */ - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET_RESOURCE (tex)\n"); - return -EINVAL; - } - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - ib[idx+1+(i*8)+1] |= - TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - unsigned bankw, bankh, mtaspect, tile_split; - - evergreen_tiling_fields(reloc->lobj.tiling_flags, - &bankw, &bankh, &mtaspect, - &tile_split); - ib[idx+1+(i*8)+6] |= TEX_TILE_SPLIT(tile_split); - ib[idx+1+(i*8)+7] |= - TEX_BANK_WIDTH(bankw) | - TEX_BANK_HEIGHT(bankh) | - MACRO_TILE_ASPECT(mtaspect) | - TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); - } - } - texture = reloc->robj; - toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - /* tex mip base */ - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET_RESOURCE (tex)\n"); - return -EINVAL; - } - moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - mipmap = reloc->robj; - r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8)); - if (r) - return r; - ib[idx+1+(i*8)+2] += toffset; - ib[idx+1+(i*8)+3] += moffset; - break; - case SQ_TEX_VTX_VALID_BUFFER: - { - uint64_t offset64; - /* vtx base */ - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET_RESOURCE (vtx)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+1+(i*8)+0); - size = radeon_get_ib_value(p, idx+1+(i*8)+1); - if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { - /* force size to size of the buffer */ - dev_warn(p->dev, "vbo resource seems too big for the bo\n"); - ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj) - offset; - } - - offset64 = reloc->lobj.gpu_offset + offset; - ib[idx+1+(i*8)+0] = offset64; - ib[idx+1+(i*8)+2] = (ib[idx+1+(i*8)+2] & 0xffffff00) | - (upper_32_bits(offset64) & 0xff); - break; - } - case SQ_TEX_VTX_INVALID_TEXTURE: - case SQ_TEX_VTX_INVALID_BUFFER: - default: - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - } - break; - case PACKET3_SET_ALU_CONST: - /* XXX fix me ALU const buffers only */ - break; - case PACKET3_SET_BOOL_CONST: - start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_BOOL_CONST_START) || - (start_reg >= PACKET3_SET_BOOL_CONST_END) || - (end_reg >= PACKET3_SET_BOOL_CONST_END)) { - DRM_ERROR("bad SET_BOOL_CONST\n"); - return -EINVAL; - } - break; - case PACKET3_SET_LOOP_CONST: - start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_LOOP_CONST_START) || - (start_reg >= PACKET3_SET_LOOP_CONST_END) || - (end_reg >= PACKET3_SET_LOOP_CONST_END)) { - DRM_ERROR("bad SET_LOOP_CONST\n"); - return -EINVAL; - } - break; - case PACKET3_SET_CTL_CONST: - start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CTL_CONST_START) || - (start_reg >= PACKET3_SET_CTL_CONST_END) || - (end_reg >= PACKET3_SET_CTL_CONST_END)) { - DRM_ERROR("bad SET_CTL_CONST\n"); - return -EINVAL; - } - break; - case PACKET3_SET_SAMPLER: - if (pkt->count % 3) { - DRM_ERROR("bad SET_SAMPLER\n"); - return -EINVAL; - } - start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_SAMPLER_START) || - (start_reg >= PACKET3_SET_SAMPLER_END) || - (end_reg >= PACKET3_SET_SAMPLER_END)) { - DRM_ERROR("bad SET_SAMPLER\n"); - return -EINVAL; - } - break; - case PACKET3_STRMOUT_BUFFER_UPDATE: - if (pkt->count != 4) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n"); - return -EINVAL; - } - /* Updating memory at DST_ADDRESS. */ - if (idx_value & 0x1) { - u64 offset; - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+1); - offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+1] = offset; - ib[idx+2] = upper_32_bits(offset) & 0xff; - } - /* Reading data from SRC_ADDRESS. */ - if (((idx_value >> 1) & 0x3) == 2) { - u64 offset; - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+3); - offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+3] = offset; - ib[idx+4] = upper_32_bits(offset) & 0xff; - } - break; - case PACKET3_COPY_DW: - if (pkt->count != 4) { - DRM_ERROR("bad COPY_DW (invalid count)\n"); - return -EINVAL; - } - if (idx_value & 0x1) { - u64 offset; - /* SRC is memory. */ - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad COPY_DW (missing src reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+1); - offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+1] = offset; - ib[idx+2] = upper_32_bits(offset) & 0xff; - } else { - /* SRC is a reg. */ - reg = radeon_get_ib_value(p, idx+1) << 2; - if (!evergreen_is_safe_reg(p, reg, idx+1)) - return -EINVAL; - } - if (idx_value & 0x2) { - u64 offset; - /* DST is memory. */ - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+3); - offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+3] = offset; - ib[idx+4] = upper_32_bits(offset) & 0xff; - } else { - /* DST is a reg. */ - reg = radeon_get_ib_value(p, idx+3) << 2; - if (!evergreen_is_safe_reg(p, reg, idx+3)) - return -EINVAL; - } - break; - case PACKET3_NOP: - break; - default: - DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -int evergreen_cs_parse(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet pkt; - struct evergreen_cs_track *track; - u32 tmp; - int r; - - if (p->track == NULL) { - /* initialize tracker, we are in kms */ - track = kzalloc(sizeof(*track), GFP_KERNEL); - if (track == NULL) - return -ENOMEM; - evergreen_cs_track_init(track); - if (p->rdev->family >= CHIP_CAYMAN) - tmp = p->rdev->config.cayman.tile_config; - else - tmp = p->rdev->config.evergreen.tile_config; - - switch (tmp & 0xf) { - case 0: - track->npipes = 1; - break; - case 1: - default: - track->npipes = 2; - break; - case 2: - track->npipes = 4; - break; - case 3: - track->npipes = 8; - break; - } - - switch ((tmp & 0xf0) >> 4) { - case 0: - track->nbanks = 4; - break; - case 1: - default: - track->nbanks = 8; - break; - case 2: - track->nbanks = 16; - break; - } - - switch ((tmp & 0xf00) >> 8) { - case 0: - track->group_size = 256; - break; - case 1: - default: - track->group_size = 512; - break; - } - - switch ((tmp & 0xf000) >> 12) { - case 0: - track->row_size = 1; - break; - case 1: - default: - track->row_size = 2; - break; - case 2: - track->row_size = 4; - break; - } - - p->track = track; - } - do { - r = evergreen_cs_packet_parse(p, &pkt, p->idx); - if (r) { - kfree(p->track); - p->track = NULL; - return r; - } - p->idx += pkt.count + 2; - switch (pkt.type) { - case PACKET_TYPE0: - r = evergreen_cs_parse_packet0(p, &pkt); - break; - case PACKET_TYPE2: - break; - case PACKET_TYPE3: - r = evergreen_packet3_check(p, &pkt); - break; - default: - DRM_ERROR("Unknown packet type %d !\n", pkt.type); - kfree(p->track); - p->track = NULL; - return -EINVAL; - } - if (r) { - kfree(p->track); - p->track = NULL; - return r; - } - } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); -#if 0 - for (r = 0; r < p->ib->length_dw; r++) { - printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); - mdelay(1); - } -#endif - kfree(p->track); - p->track = NULL; - return 0; -} - -/* vm parser */ -static bool evergreen_vm_reg_valid(u32 reg) -{ - /* context regs are fine */ - if (reg >= 0x28000) - return true; - - /* check config regs */ - switch (reg) { - case GRBM_GFX_INDEX: - case VGT_VTX_VECT_EJECT_REG: - case VGT_CACHE_INVALIDATION: - case VGT_GS_VERTEX_REUSE: - case VGT_PRIMITIVE_TYPE: - case VGT_INDEX_TYPE: - case VGT_NUM_INDICES: - case VGT_NUM_INSTANCES: - case VGT_COMPUTE_DIM_X: - case VGT_COMPUTE_DIM_Y: - case VGT_COMPUTE_DIM_Z: - case VGT_COMPUTE_START_X: - case VGT_COMPUTE_START_Y: - case VGT_COMPUTE_START_Z: - case VGT_COMPUTE_INDEX: - case VGT_COMPUTE_THREAD_GROUP_SIZE: - case VGT_HS_OFFCHIP_PARAM: - case PA_CL_ENHANCE: - case PA_SU_LINE_STIPPLE_VALUE: - case PA_SC_LINE_STIPPLE_STATE: - case PA_SC_ENHANCE: - case SQ_DYN_GPR_CNTL_PS_FLUSH_REQ: - case SQ_DYN_GPR_SIMD_LOCK_EN: - case SQ_CONFIG: - case SQ_GPR_RESOURCE_MGMT_1: - case SQ_GLOBAL_GPR_RESOURCE_MGMT_1: - case SQ_GLOBAL_GPR_RESOURCE_MGMT_2: - case SQ_CONST_MEM_BASE: - case SQ_STATIC_THREAD_MGMT_1: - case SQ_STATIC_THREAD_MGMT_2: - case SQ_STATIC_THREAD_MGMT_3: - case SPI_CONFIG_CNTL: - case SPI_CONFIG_CNTL_1: - case TA_CNTL_AUX: - case DB_DEBUG: - case DB_DEBUG2: - case DB_DEBUG3: - case DB_DEBUG4: - case DB_WATERMARKS: - case TD_PS_BORDER_COLOR_INDEX: - case TD_PS_BORDER_COLOR_RED: - case TD_PS_BORDER_COLOR_GREEN: - case TD_PS_BORDER_COLOR_BLUE: - case TD_PS_BORDER_COLOR_ALPHA: - case TD_VS_BORDER_COLOR_INDEX: - case TD_VS_BORDER_COLOR_RED: - case TD_VS_BORDER_COLOR_GREEN: - case TD_VS_BORDER_COLOR_BLUE: - case TD_VS_BORDER_COLOR_ALPHA: - case TD_GS_BORDER_COLOR_INDEX: - case TD_GS_BORDER_COLOR_RED: - case TD_GS_BORDER_COLOR_GREEN: - case TD_GS_BORDER_COLOR_BLUE: - case TD_GS_BORDER_COLOR_ALPHA: - case TD_HS_BORDER_COLOR_INDEX: - case TD_HS_BORDER_COLOR_RED: - case TD_HS_BORDER_COLOR_GREEN: - case TD_HS_BORDER_COLOR_BLUE: - case TD_HS_BORDER_COLOR_ALPHA: - case TD_LS_BORDER_COLOR_INDEX: - case TD_LS_BORDER_COLOR_RED: - case TD_LS_BORDER_COLOR_GREEN: - case TD_LS_BORDER_COLOR_BLUE: - case TD_LS_BORDER_COLOR_ALPHA: - case TD_CS_BORDER_COLOR_INDEX: - case TD_CS_BORDER_COLOR_RED: - case TD_CS_BORDER_COLOR_GREEN: - case TD_CS_BORDER_COLOR_BLUE: - case TD_CS_BORDER_COLOR_ALPHA: - case SQ_ESGS_RING_SIZE: - case SQ_GSVS_RING_SIZE: - case SQ_ESTMP_RING_SIZE: - case SQ_GSTMP_RING_SIZE: - case SQ_HSTMP_RING_SIZE: - case SQ_LSTMP_RING_SIZE: - case SQ_PSTMP_RING_SIZE: - case SQ_VSTMP_RING_SIZE: - case SQ_ESGS_RING_ITEMSIZE: - case SQ_ESTMP_RING_ITEMSIZE: - case SQ_GSTMP_RING_ITEMSIZE: - case SQ_GSVS_RING_ITEMSIZE: - case SQ_GS_VERT_ITEMSIZE: - case SQ_GS_VERT_ITEMSIZE_1: - case SQ_GS_VERT_ITEMSIZE_2: - case SQ_GS_VERT_ITEMSIZE_3: - case SQ_GSVS_RING_OFFSET_1: - case SQ_GSVS_RING_OFFSET_2: - case SQ_GSVS_RING_OFFSET_3: - case SQ_HSTMP_RING_ITEMSIZE: - case SQ_LSTMP_RING_ITEMSIZE: - case SQ_PSTMP_RING_ITEMSIZE: - case SQ_VSTMP_RING_ITEMSIZE: - case VGT_TF_RING_SIZE: - case SQ_ESGS_RING_BASE: - case SQ_GSVS_RING_BASE: - case SQ_ESTMP_RING_BASE: - case SQ_GSTMP_RING_BASE: - case SQ_HSTMP_RING_BASE: - case SQ_LSTMP_RING_BASE: - case SQ_PSTMP_RING_BASE: - case SQ_VSTMP_RING_BASE: - case CAYMAN_VGT_OFFCHIP_LDS_BASE: - case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: - return true; - default: - return false; - } -} - -static int evergreen_vm_packet3_check(struct radeon_device *rdev, - u32 *ib, struct radeon_cs_packet *pkt) -{ - u32 idx = pkt->idx + 1; - u32 idx_value = ib[idx]; - u32 start_reg, end_reg, reg, i; - - switch (pkt->opcode) { - case PACKET3_NOP: - case PACKET3_SET_BASE: - case PACKET3_CLEAR_STATE: - case PACKET3_INDEX_BUFFER_SIZE: - case PACKET3_DISPATCH_DIRECT: - case PACKET3_DISPATCH_INDIRECT: - case PACKET3_MODE_CONTROL: - case PACKET3_SET_PREDICATION: - case PACKET3_COND_EXEC: - case PACKET3_PRED_EXEC: - case PACKET3_DRAW_INDIRECT: - case PACKET3_DRAW_INDEX_INDIRECT: - case PACKET3_INDEX_BASE: - case PACKET3_DRAW_INDEX_2: - case PACKET3_CONTEXT_CONTROL: - case PACKET3_DRAW_INDEX_OFFSET: - case PACKET3_INDEX_TYPE: - case PACKET3_DRAW_INDEX: - case PACKET3_DRAW_INDEX_AUTO: - case PACKET3_DRAW_INDEX_IMMD: - case PACKET3_NUM_INSTANCES: - case PACKET3_DRAW_INDEX_MULTI_AUTO: - case PACKET3_STRMOUT_BUFFER_UPDATE: - case PACKET3_DRAW_INDEX_OFFSET_2: - case PACKET3_DRAW_INDEX_MULTI_ELEMENT: - case PACKET3_MPEG_INDEX: - case PACKET3_WAIT_REG_MEM: - case PACKET3_MEM_WRITE: - case PACKET3_SURFACE_SYNC: - case PACKET3_EVENT_WRITE: - case PACKET3_EVENT_WRITE_EOP: - case PACKET3_EVENT_WRITE_EOS: - case PACKET3_SET_CONTEXT_REG: - case PACKET3_SET_BOOL_CONST: - case PACKET3_SET_LOOP_CONST: - case PACKET3_SET_RESOURCE: - case PACKET3_SET_SAMPLER: - case PACKET3_SET_CTL_CONST: - case PACKET3_SET_RESOURCE_OFFSET: - case PACKET3_SET_CONTEXT_REG_INDIRECT: - case PACKET3_SET_RESOURCE_INDIRECT: - case CAYMAN_PACKET3_DEALLOC_STATE: - break; - case PACKET3_COND_WRITE: - if (idx_value & 0x100) { - reg = ib[idx + 5] * 4; - if (!evergreen_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_COPY_DW: - if (idx_value & 0x2) { - reg = ib[idx + 3] * 4; - if (!evergreen_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_SET_CONFIG_REG: - start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CONFIG_REG_START) || - (start_reg >= PACKET3_SET_CONFIG_REG_END) || - (end_reg >= PACKET3_SET_CONFIG_REG_END)) { - DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); - return -EINVAL; - } - for (i = 0; i < pkt->count; i++) { - reg = start_reg + (4 * i); - if (!evergreen_vm_reg_valid(reg)) - return -EINVAL; - } - break; - default: - return -EINVAL; - } - return 0; -} - -int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) -{ - int ret = 0; - u32 idx = 0; - struct radeon_cs_packet pkt; - - do { - pkt.idx = idx; - pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]); - pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]); - pkt.one_reg_wr = 0; - switch (pkt.type) { - case PACKET_TYPE0: - dev_err(rdev->dev, "Packet0 not allowed!\n"); - ret = -EINVAL; - break; - case PACKET_TYPE2: - idx += 1; - break; - case PACKET_TYPE3: - pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); - ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); - idx += pkt.count + 2; - break; - default: - dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type); - ret = -EINVAL; - break; - } - if (ret) - break; - } while (idx < ib->length_dw); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_reg.h deleted file mode 100644 index 96c10b39..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreen_reg.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#ifndef __EVERGREEN_REG_H__ -#define __EVERGREEN_REG_H__ - -/* evergreen */ -#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS 0x310 -#define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH 0x324 -#define EVERGREEN_D3VGA_CONTROL 0x3e0 -#define EVERGREEN_D4VGA_CONTROL 0x3e4 -#define EVERGREEN_D5VGA_CONTROL 0x3e8 -#define EVERGREEN_D6VGA_CONTROL 0x3ec - -#define EVERGREEN_P1PLL_SS_CNTL 0x414 -#define EVERGREEN_P2PLL_SS_CNTL 0x454 -# define EVERGREEN_PxPLL_SS_EN (1 << 12) - -#define EVERGREEN_AUDIO_PLL1_MUL 0x5b0 -#define EVERGREEN_AUDIO_PLL1_DIV 0x5b4 -#define EVERGREEN_AUDIO_PLL1_UNK 0x5bc - -#define EVERGREEN_AUDIO_ENABLE 0x5e78 -#define EVERGREEN_AUDIO_VENDOR_ID 0x5ec0 - -/* GRPH blocks at 0x6800, 0x7400, 0x10000, 0x10c00, 0x11800, 0x12400 */ -#define EVERGREEN_GRPH_ENABLE 0x6800 -#define EVERGREEN_GRPH_CONTROL 0x6804 -# define EVERGREEN_GRPH_DEPTH(x) (((x) & 0x3) << 0) -# define EVERGREEN_GRPH_DEPTH_8BPP 0 -# define EVERGREEN_GRPH_DEPTH_16BPP 1 -# define EVERGREEN_GRPH_DEPTH_32BPP 2 -# define EVERGREEN_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) -# define EVERGREEN_ADDR_SURF_2_BANK 0 -# define EVERGREEN_ADDR_SURF_4_BANK 1 -# define EVERGREEN_ADDR_SURF_8_BANK 2 -# define EVERGREEN_ADDR_SURF_16_BANK 3 -# define EVERGREEN_GRPH_Z(x) (((x) & 0x3) << 4) -# define EVERGREEN_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) -# define EVERGREEN_ADDR_SURF_BANK_WIDTH_1 0 -# define EVERGREEN_ADDR_SURF_BANK_WIDTH_2 1 -# define EVERGREEN_ADDR_SURF_BANK_WIDTH_4 2 -# define EVERGREEN_ADDR_SURF_BANK_WIDTH_8 3 -# define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8) -/* 8 BPP */ -# define EVERGREEN_GRPH_FORMAT_INDEXED 0 -/* 16 BPP */ -# define EVERGREEN_GRPH_FORMAT_ARGB1555 0 -# define EVERGREEN_GRPH_FORMAT_ARGB565 1 -# define EVERGREEN_GRPH_FORMAT_ARGB4444 2 -# define EVERGREEN_GRPH_FORMAT_AI88 3 -# define EVERGREEN_GRPH_FORMAT_MONO16 4 -# define EVERGREEN_GRPH_FORMAT_BGRA5551 5 -/* 32 BPP */ -# define EVERGREEN_GRPH_FORMAT_ARGB8888 0 -# define EVERGREEN_GRPH_FORMAT_ARGB2101010 1 -# define EVERGREEN_GRPH_FORMAT_32BPP_DIG 2 -# define EVERGREEN_GRPH_FORMAT_8B_ARGB2101010 3 -# define EVERGREEN_GRPH_FORMAT_BGRA1010102 4 -# define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 -# define EVERGREEN_GRPH_FORMAT_RGB111110 6 -# define EVERGREEN_GRPH_FORMAT_BGR101111 7 -# define EVERGREEN_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) -# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_1 0 -# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_2 1 -# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_4 2 -# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_8 3 -# define EVERGREEN_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B 0 -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B 1 -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B 2 -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B 3 -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB 4 -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB 5 -# define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB 6 -# define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) -# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1 0 -# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2 1 -# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4 2 -# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8 3 -# define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) -# define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0 -# define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 -# define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1 2 -# define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1 4 -#define EVERGREEN_GRPH_SWAP_CONTROL 0x680c -# define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) -# define EVERGREEN_GRPH_ENDIAN_NONE 0 -# define EVERGREEN_GRPH_ENDIAN_8IN16 1 -# define EVERGREEN_GRPH_ENDIAN_8IN32 2 -# define EVERGREEN_GRPH_ENDIAN_8IN64 3 -# define EVERGREEN_GRPH_RED_CROSSBAR(x) (((x) & 0x3) << 4) -# define EVERGREEN_GRPH_RED_SEL_R 0 -# define EVERGREEN_GRPH_RED_SEL_G 1 -# define EVERGREEN_GRPH_RED_SEL_B 2 -# define EVERGREEN_GRPH_RED_SEL_A 3 -# define EVERGREEN_GRPH_GREEN_CROSSBAR(x) (((x) & 0x3) << 6) -# define EVERGREEN_GRPH_GREEN_SEL_G 0 -# define EVERGREEN_GRPH_GREEN_SEL_B 1 -# define EVERGREEN_GRPH_GREEN_SEL_A 2 -# define EVERGREEN_GRPH_GREEN_SEL_R 3 -# define EVERGREEN_GRPH_BLUE_CROSSBAR(x) (((x) & 0x3) << 8) -# define EVERGREEN_GRPH_BLUE_SEL_B 0 -# define EVERGREEN_GRPH_BLUE_SEL_A 1 -# define EVERGREEN_GRPH_BLUE_SEL_R 2 -# define EVERGREEN_GRPH_BLUE_SEL_G 3 -# define EVERGREEN_GRPH_ALPHA_CROSSBAR(x) (((x) & 0x3) << 10) -# define EVERGREEN_GRPH_ALPHA_SEL_A 0 -# define EVERGREEN_GRPH_ALPHA_SEL_R 1 -# define EVERGREEN_GRPH_ALPHA_SEL_G 2 -# define EVERGREEN_GRPH_ALPHA_SEL_B 3 -#define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS 0x6810 -#define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS 0x6814 -# define EVERGREEN_GRPH_DFQ_ENABLE (1 << 0) -# define EVERGREEN_GRPH_SURFACE_ADDRESS_MASK 0xffffff00 -#define EVERGREEN_GRPH_PITCH 0x6818 -#define EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x681c -#define EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x6820 -#define EVERGREEN_GRPH_SURFACE_OFFSET_X 0x6824 -#define EVERGREEN_GRPH_SURFACE_OFFSET_Y 0x6828 -#define EVERGREEN_GRPH_X_START 0x682c -#define EVERGREEN_GRPH_Y_START 0x6830 -#define EVERGREEN_GRPH_X_END 0x6834 -#define EVERGREEN_GRPH_Y_END 0x6838 -#define EVERGREEN_GRPH_UPDATE 0x6844 -# define EVERGREEN_GRPH_SURFACE_UPDATE_PENDING (1 << 2) -# define EVERGREEN_GRPH_UPDATE_LOCK (1 << 16) -#define EVERGREEN_GRPH_FLIP_CONTROL 0x6848 -# define EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN (1 << 0) - -/* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */ -#define EVERGREEN_CUR_CONTROL 0x6998 -# define EVERGREEN_CURSOR_EN (1 << 0) -# define EVERGREEN_CURSOR_MODE(x) (((x) & 0x3) << 8) -# define EVERGREEN_CURSOR_MONO 0 -# define EVERGREEN_CURSOR_24_1 1 -# define EVERGREEN_CURSOR_24_8_PRE_MULT 2 -# define EVERGREEN_CURSOR_24_8_UNPRE_MULT 3 -# define EVERGREEN_CURSOR_2X_MAGNIFY (1 << 16) -# define EVERGREEN_CURSOR_FORCE_MC_ON (1 << 20) -# define EVERGREEN_CURSOR_URGENT_CONTROL(x) (((x) & 0x7) << 24) -# define EVERGREEN_CURSOR_URGENT_ALWAYS 0 -# define EVERGREEN_CURSOR_URGENT_1_8 1 -# define EVERGREEN_CURSOR_URGENT_1_4 2 -# define EVERGREEN_CURSOR_URGENT_3_8 3 -# define EVERGREEN_CURSOR_URGENT_1_2 4 -#define EVERGREEN_CUR_SURFACE_ADDRESS 0x699c -# define EVERGREEN_CUR_SURFACE_ADDRESS_MASK 0xfffff000 -#define EVERGREEN_CUR_SIZE 0x69a0 -#define EVERGREEN_CUR_SURFACE_ADDRESS_HIGH 0x69a4 -#define EVERGREEN_CUR_POSITION 0x69a8 -#define EVERGREEN_CUR_HOT_SPOT 0x69ac -#define EVERGREEN_CUR_COLOR1 0x69b0 -#define EVERGREEN_CUR_COLOR2 0x69b4 -#define EVERGREEN_CUR_UPDATE 0x69b8 -# define EVERGREEN_CURSOR_UPDATE_PENDING (1 << 0) -# define EVERGREEN_CURSOR_UPDATE_TAKEN (1 << 1) -# define EVERGREEN_CURSOR_UPDATE_LOCK (1 << 16) -# define EVERGREEN_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24) - -/* LUT blocks at 0x69e0, 0x75e0, 0x101e0, 0x10de0, 0x119e0, 0x125e0 */ -#define EVERGREEN_DC_LUT_RW_MODE 0x69e0 -#define EVERGREEN_DC_LUT_RW_INDEX 0x69e4 -#define EVERGREEN_DC_LUT_SEQ_COLOR 0x69e8 -#define EVERGREEN_DC_LUT_PWL_DATA 0x69ec -#define EVERGREEN_DC_LUT_30_COLOR 0x69f0 -#define EVERGREEN_DC_LUT_VGA_ACCESS_ENABLE 0x69f4 -#define EVERGREEN_DC_LUT_WRITE_EN_MASK 0x69f8 -#define EVERGREEN_DC_LUT_AUTOFILL 0x69fc -#define EVERGREEN_DC_LUT_CONTROL 0x6a00 -#define EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE 0x6a04 -#define EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN 0x6a08 -#define EVERGREEN_DC_LUT_BLACK_OFFSET_RED 0x6a0c -#define EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE 0x6a10 -#define EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN 0x6a14 -#define EVERGREEN_DC_LUT_WHITE_OFFSET_RED 0x6a18 - -#define EVERGREEN_DATA_FORMAT 0x6b00 -# define EVERGREEN_INTERLEAVE_EN (1 << 0) -#define EVERGREEN_DESKTOP_HEIGHT 0x6b04 -#define EVERGREEN_VLINE_START_END 0x6b08 -#define EVERGREEN_VLINE_STATUS 0x6bb8 -# define EVERGREEN_VLINE_STAT (1 << 12) - -#define EVERGREEN_VIEWPORT_START 0x6d70 -#define EVERGREEN_VIEWPORT_SIZE 0x6d74 - -/* display controller offsets used for crtc/cur/lut/grph/viewport/etc. */ -#define EVERGREEN_CRTC0_REGISTER_OFFSET (0x6df0 - 0x6df0) -#define EVERGREEN_CRTC1_REGISTER_OFFSET (0x79f0 - 0x6df0) -#define EVERGREEN_CRTC2_REGISTER_OFFSET (0x105f0 - 0x6df0) -#define EVERGREEN_CRTC3_REGISTER_OFFSET (0x111f0 - 0x6df0) -#define EVERGREEN_CRTC4_REGISTER_OFFSET (0x11df0 - 0x6df0) -#define EVERGREEN_CRTC5_REGISTER_OFFSET (0x129f0 - 0x6df0) - -/* CRTC blocks at 0x6df0, 0x79f0, 0x105f0, 0x111f0, 0x11df0, 0x129f0 */ -#define EVERGREEN_CRTC_V_BLANK_START_END 0x6e34 -#define EVERGREEN_CRTC_CONTROL 0x6e70 -# define EVERGREEN_CRTC_MASTER_EN (1 << 0) -# define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) -#define EVERGREEN_CRTC_STATUS 0x6e8c -# define EVERGREEN_CRTC_V_BLANK (1 << 0) -#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 -#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 -#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 - -#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 -#define EVERGREEN_DC_GPIO_HPD_A 0x64b4 -#define EVERGREEN_DC_GPIO_HPD_EN 0x64b8 -#define EVERGREEN_DC_GPIO_HPD_Y 0x64bc - -/* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ -#define EVERGREEN_HDMI_BASE 0x7030 - -#define EVERGREEN_HDMI_CONFIG_OFFSET 0xf0 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreend.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreend.h deleted file mode 100644 index f62ccd35..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/evergreend.h +++ /dev/null @@ -1,1652 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#ifndef EVERGREEND_H -#define EVERGREEND_H - -#define EVERGREEN_MAX_SH_GPRS 256 -#define EVERGREEN_MAX_TEMP_GPRS 16 -#define EVERGREEN_MAX_SH_THREADS 256 -#define EVERGREEN_MAX_SH_STACK_ENTRIES 4096 -#define EVERGREEN_MAX_FRC_EOV_CNT 16384 -#define EVERGREEN_MAX_BACKENDS 8 -#define EVERGREEN_MAX_BACKENDS_MASK 0xFF -#define EVERGREEN_MAX_SIMDS 16 -#define EVERGREEN_MAX_SIMDS_MASK 0xFFFF -#define EVERGREEN_MAX_PIPES 8 -#define EVERGREEN_MAX_PIPES_MASK 0xFF -#define EVERGREEN_MAX_LDS_NUM 0xFFFF - -/* Registers */ - -#define RCU_IND_INDEX 0x100 -#define RCU_IND_DATA 0x104 - -#define GRBM_GFX_INDEX 0x802C -#define INSTANCE_INDEX(x) ((x) << 0) -#define SE_INDEX(x) ((x) << 16) -#define INSTANCE_BROADCAST_WRITES (1 << 30) -#define SE_BROADCAST_WRITES (1 << 31) -#define RLC_GFX_INDEX 0x3fC4 -#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -#define WRITE_DIS (1 << 0) -#define CC_RB_BACKEND_DISABLE 0x98F4 -#define BACKEND_DISABLE(x) ((x) << 16) -#define GB_ADDR_CONFIG 0x98F8 -#define NUM_PIPES(x) ((x) << 0) -#define PIPE_INTERLEAVE_SIZE(x) ((x) << 4) -#define BANK_INTERLEAVE_SIZE(x) ((x) << 8) -#define NUM_SHADER_ENGINES(x) ((x) << 12) -#define SHADER_ENGINE_TILE_SIZE(x) ((x) << 16) -#define NUM_GPUS(x) ((x) << 20) -#define MULTI_GPU_TILE_SIZE(x) ((x) << 24) -#define ROW_SIZE(x) ((x) << 28) -#define GB_BACKEND_MAP 0x98FC -#define DMIF_ADDR_CONFIG 0xBD4 -#define HDP_ADDR_CONFIG 0x2F48 -#define HDP_MISC_CNTL 0x2F4C -#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) - -#define CC_SYS_RB_BACKEND_DISABLE 0x3F88 -#define GC_USER_RB_BACKEND_DISABLE 0x9B7C - -#define CGTS_SYS_TCC_DISABLE 0x3F90 -#define CGTS_TCC_DISABLE 0x9148 -#define CGTS_USER_SYS_TCC_DISABLE 0x3F94 -#define CGTS_USER_TCC_DISABLE 0x914C - -#define CONFIG_MEMSIZE 0x5428 - -#define CP_COHER_BASE 0x85F8 -#define CP_ME_CNTL 0x86D8 -#define CP_ME_HALT (1 << 28) -#define CP_PFP_HALT (1 << 26) -#define CP_ME_RAM_DATA 0xC160 -#define CP_ME_RAM_RADDR 0xC158 -#define CP_ME_RAM_WADDR 0xC15C -#define CP_MEQ_THRESHOLDS 0x8764 -#define STQ_SPLIT(x) ((x) << 0) -#define CP_PERFMON_CNTL 0x87FC -#define CP_PFP_UCODE_ADDR 0xC150 -#define CP_PFP_UCODE_DATA 0xC154 -#define CP_QUEUE_THRESHOLDS 0x8760 -#define ROQ_IB1_START(x) ((x) << 0) -#define ROQ_IB2_START(x) ((x) << 8) -#define CP_RB_BASE 0xC100 -#define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) -#define BUF_SWAP_32BIT (2 << 16) -#define CP_RB_RPTR 0x8700 -#define CP_RB_RPTR_ADDR 0xC10C -#define RB_RPTR_SWAP(x) ((x) << 0) -#define CP_RB_RPTR_ADDR_HI 0xC110 -#define CP_RB_RPTR_WR 0xC108 -#define CP_RB_WPTR 0xC114 -#define CP_RB_WPTR_ADDR 0xC118 -#define CP_RB_WPTR_ADDR_HI 0xC11C -#define CP_RB_WPTR_DELAY 0x8704 -#define CP_SEM_WAIT_TIMER 0x85BC -#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 -#define CP_DEBUG 0xC1FC - - -#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -#define INACTIVE_QD_PIPES(x) ((x) << 8) -#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -#define INACTIVE_SIMDS(x) ((x) << 16) -#define INACTIVE_SIMDS_MASK 0x00FF0000 - -#define GRBM_CNTL 0x8000 -#define GRBM_READ_TIMEOUT(x) ((x) << 0) -#define GRBM_SOFT_RESET 0x8020 -#define SOFT_RESET_CP (1 << 0) -#define SOFT_RESET_CB (1 << 1) -#define SOFT_RESET_DB (1 << 3) -#define SOFT_RESET_PA (1 << 5) -#define SOFT_RESET_SC (1 << 6) -#define SOFT_RESET_SPI (1 << 8) -#define SOFT_RESET_SH (1 << 9) -#define SOFT_RESET_SX (1 << 10) -#define SOFT_RESET_TC (1 << 11) -#define SOFT_RESET_TA (1 << 12) -#define SOFT_RESET_VC (1 << 13) -#define SOFT_RESET_VGT (1 << 14) - -#define GRBM_STATUS 0x8010 -#define CMDFIFO_AVAIL_MASK 0x0000000F -#define SRBM_RQ_PENDING (1 << 5) -#define CF_RQ_PENDING (1 << 7) -#define PF_RQ_PENDING (1 << 8) -#define GRBM_EE_BUSY (1 << 10) -#define SX_CLEAN (1 << 11) -#define DB_CLEAN (1 << 12) -#define CB_CLEAN (1 << 13) -#define TA_BUSY (1 << 14) -#define VGT_BUSY_NO_DMA (1 << 16) -#define VGT_BUSY (1 << 17) -#define SX_BUSY (1 << 20) -#define SH_BUSY (1 << 21) -#define SPI_BUSY (1 << 22) -#define SC_BUSY (1 << 24) -#define PA_BUSY (1 << 25) -#define DB_BUSY (1 << 26) -#define CP_COHERENCY_BUSY (1 << 28) -#define CP_BUSY (1 << 29) -#define CB_BUSY (1 << 30) -#define GUI_ACTIVE (1 << 31) -#define GRBM_STATUS_SE0 0x8014 -#define GRBM_STATUS_SE1 0x8018 -#define SE_SX_CLEAN (1 << 0) -#define SE_DB_CLEAN (1 << 1) -#define SE_CB_CLEAN (1 << 2) -#define SE_TA_BUSY (1 << 25) -#define SE_SX_BUSY (1 << 26) -#define SE_SPI_BUSY (1 << 27) -#define SE_SH_BUSY (1 << 28) -#define SE_SC_BUSY (1 << 29) -#define SE_DB_BUSY (1 << 30) -#define SE_CB_BUSY (1 << 31) -/* evergreen */ -#define CG_THERMAL_CTRL 0x72c -#define TOFFSET_MASK 0x00003FE0 -#define TOFFSET_SHIFT 5 -#define CG_MULT_THERMAL_STATUS 0x740 -#define ASIC_T(x) ((x) << 16) -#define ASIC_T_MASK 0x07FF0000 -#define ASIC_T_SHIFT 16 -#define CG_TS0_STATUS 0x760 -#define TS0_ADC_DOUT_MASK 0x000003FF -#define TS0_ADC_DOUT_SHIFT 0 -/* APU */ -#define CG_THERMAL_STATUS 0x678 - -#define HDP_HOST_PATH_CNTL 0x2C00 -#define HDP_NONSURFACE_BASE 0x2C04 -#define HDP_NONSURFACE_INFO 0x2C08 -#define HDP_NONSURFACE_SIZE 0x2C0C -#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 -#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 -#define HDP_TILING_CONFIG 0x2F3C - -#define MC_SHARED_CHMAP 0x2004 -#define NOOFCHAN_SHIFT 12 -#define NOOFCHAN_MASK 0x00003000 -#define MC_SHARED_CHREMAP 0x2008 - -#define MC_ARB_RAMCFG 0x2760 -#define NOOFBANK_SHIFT 0 -#define NOOFBANK_MASK 0x00000003 -#define NOOFRANK_SHIFT 2 -#define NOOFRANK_MASK 0x00000004 -#define NOOFROWS_SHIFT 3 -#define NOOFROWS_MASK 0x00000038 -#define NOOFCOLS_SHIFT 6 -#define NOOFCOLS_MASK 0x000000C0 -#define CHANSIZE_SHIFT 8 -#define CHANSIZE_MASK 0x00000100 -#define BURSTLENGTH_SHIFT 9 -#define BURSTLENGTH_MASK 0x00000200 -#define CHANSIZE_OVERRIDE (1 << 11) -#define FUS_MC_ARB_RAMCFG 0x2768 -#define MC_VM_AGP_TOP 0x2028 -#define MC_VM_AGP_BOT 0x202C -#define MC_VM_AGP_BASE 0x2030 -#define MC_VM_FB_LOCATION 0x2024 -#define MC_FUS_VM_FB_OFFSET 0x2898 -#define MC_VM_MB_L1_TLB0_CNTL 0x2234 -#define MC_VM_MB_L1_TLB1_CNTL 0x2238 -#define MC_VM_MB_L1_TLB2_CNTL 0x223C -#define MC_VM_MB_L1_TLB3_CNTL 0x2240 -#define ENABLE_L1_TLB (1 << 0) -#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) -#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) -#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) -#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -#define EFFECTIVE_L1_TLB_SIZE(x) ((x)<<15) -#define EFFECTIVE_L1_QUEUE_SIZE(x) ((x)<<18) -#define MC_VM_MD_L1_TLB0_CNTL 0x2654 -#define MC_VM_MD_L1_TLB1_CNTL 0x2658 -#define MC_VM_MD_L1_TLB2_CNTL 0x265C -#define MC_VM_MD_L1_TLB3_CNTL 0x2698 - -#define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C -#define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 -#define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 - -#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C -#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 - -#define PA_CL_ENHANCE 0x8A14 -#define CLIP_VTX_REORDER_ENA (1 << 0) -#define NUM_CLIP_SEQ(x) ((x) << 1) -#define PA_SC_ENHANCE 0x8BF0 -#define PA_SC_AA_CONFIG 0x28C04 -#define MSAA_NUM_SAMPLES_SHIFT 0 -#define MSAA_NUM_SAMPLES_MASK 0x3 -#define PA_SC_CLIPRECT_RULE 0x2820C -#define PA_SC_EDGERULE 0x28230 -#define PA_SC_FIFO_SIZE 0x8BCC -#define SC_PRIM_FIFO_SIZE(x) ((x) << 0) -#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) -#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 -#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -#define FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) -#define PA_SC_LINE_STIPPLE 0x28A0C -#define PA_SU_LINE_STIPPLE_VALUE 0x8A60 -#define PA_SC_LINE_STIPPLE_STATE 0x8B10 - -#define SCRATCH_REG0 0x8500 -#define SCRATCH_REG1 0x8504 -#define SCRATCH_REG2 0x8508 -#define SCRATCH_REG3 0x850C -#define SCRATCH_REG4 0x8510 -#define SCRATCH_REG5 0x8514 -#define SCRATCH_REG6 0x8518 -#define SCRATCH_REG7 0x851C -#define SCRATCH_UMSK 0x8540 -#define SCRATCH_ADDR 0x8544 - -#define SMX_SAR_CTL0 0xA008 -#define SMX_DC_CTL0 0xA020 -#define USE_HASH_FUNCTION (1 << 0) -#define NUMBER_OF_SETS(x) ((x) << 1) -#define FLUSH_ALL_ON_EVENT (1 << 10) -#define STALL_ON_EVENT (1 << 11) -#define SMX_EVENT_CTL 0xA02C -#define ES_FLUSH_CTL(x) ((x) << 0) -#define GS_FLUSH_CTL(x) ((x) << 3) -#define ACK_FLUSH_CTL(x) ((x) << 6) -#define SYNC_FLUSH_CTL (1 << 8) - -#define SPI_CONFIG_CNTL 0x9100 -#define GPR_WRITE_PRIORITY(x) ((x) << 0) -#define SPI_CONFIG_CNTL_1 0x913C -#define VTX_DONE_DELAY(x) ((x) << 0) -#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -#define SPI_INPUT_Z 0x286D8 -#define SPI_PS_IN_CONTROL_0 0x286CC -#define NUM_INTERP(x) ((x)<<0) -#define POSITION_ENA (1<<8) -#define POSITION_CENTROID (1<<9) -#define POSITION_ADDR(x) ((x)<<10) -#define PARAM_GEN(x) ((x)<<15) -#define PARAM_GEN_ADDR(x) ((x)<<19) -#define BARYC_SAMPLE_CNTL(x) ((x)<<26) -#define PERSP_GRADIENT_ENA (1<<28) -#define LINEAR_GRADIENT_ENA (1<<29) -#define POSITION_SAMPLE (1<<30) -#define BARYC_AT_SAMPLE_ENA (1<<31) - -#define SQ_CONFIG 0x8C00 -#define VC_ENABLE (1 << 0) -#define EXPORT_SRC_C (1 << 1) -#define CS_PRIO(x) ((x) << 18) -#define LS_PRIO(x) ((x) << 20) -#define HS_PRIO(x) ((x) << 22) -#define PS_PRIO(x) ((x) << 24) -#define VS_PRIO(x) ((x) << 26) -#define GS_PRIO(x) ((x) << 28) -#define ES_PRIO(x) ((x) << 30) -#define SQ_GPR_RESOURCE_MGMT_1 0x8C04 -#define NUM_PS_GPRS(x) ((x) << 0) -#define NUM_VS_GPRS(x) ((x) << 16) -#define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -#define SQ_GPR_RESOURCE_MGMT_2 0x8C08 -#define NUM_GS_GPRS(x) ((x) << 0) -#define NUM_ES_GPRS(x) ((x) << 16) -#define SQ_GPR_RESOURCE_MGMT_3 0x8C0C -#define NUM_HS_GPRS(x) ((x) << 0) -#define NUM_LS_GPRS(x) ((x) << 16) -#define SQ_GLOBAL_GPR_RESOURCE_MGMT_1 0x8C10 -#define SQ_GLOBAL_GPR_RESOURCE_MGMT_2 0x8C14 -#define SQ_THREAD_RESOURCE_MGMT 0x8C18 -#define NUM_PS_THREADS(x) ((x) << 0) -#define NUM_VS_THREADS(x) ((x) << 8) -#define NUM_GS_THREADS(x) ((x) << 16) -#define NUM_ES_THREADS(x) ((x) << 24) -#define SQ_THREAD_RESOURCE_MGMT_2 0x8C1C -#define NUM_HS_THREADS(x) ((x) << 0) -#define NUM_LS_THREADS(x) ((x) << 8) -#define SQ_STACK_RESOURCE_MGMT_1 0x8C20 -#define NUM_PS_STACK_ENTRIES(x) ((x) << 0) -#define NUM_VS_STACK_ENTRIES(x) ((x) << 16) -#define SQ_STACK_RESOURCE_MGMT_2 0x8C24 -#define NUM_GS_STACK_ENTRIES(x) ((x) << 0) -#define NUM_ES_STACK_ENTRIES(x) ((x) << 16) -#define SQ_STACK_RESOURCE_MGMT_3 0x8C28 -#define NUM_HS_STACK_ENTRIES(x) ((x) << 0) -#define NUM_LS_STACK_ENTRIES(x) ((x) << 16) -#define SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 0x8D8C -#define SQ_DYN_GPR_SIMD_LOCK_EN 0x8D94 -#define SQ_STATIC_THREAD_MGMT_1 0x8E20 -#define SQ_STATIC_THREAD_MGMT_2 0x8E24 -#define SQ_STATIC_THREAD_MGMT_3 0x8E28 -#define SQ_LDS_RESOURCE_MGMT 0x8E2C - -#define SQ_MS_FIFO_SIZES 0x8CF0 -#define CACHE_FIFO_SIZE(x) ((x) << 0) -#define FETCH_FIFO_HIWATER(x) ((x) << 8) -#define DONE_FIFO_HIWATER(x) ((x) << 16) -#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) - -#define SX_DEBUG_1 0x9058 -#define ENABLE_NEW_SMX_ADDRESS (1 << 16) -#define SX_EXPORT_BUFFER_SIZES 0x900C -#define COLOR_BUFFER_SIZE(x) ((x) << 0) -#define POSITION_BUFFER_SIZE(x) ((x) << 8) -#define SMX_BUFFER_SIZE(x) ((x) << 16) -#define SX_MEMORY_EXPORT_BASE 0x9010 -#define SX_MISC 0x28350 - -#define CB_PERF_CTR0_SEL_0 0x9A20 -#define CB_PERF_CTR0_SEL_1 0x9A24 -#define CB_PERF_CTR1_SEL_0 0x9A28 -#define CB_PERF_CTR1_SEL_1 0x9A2C -#define CB_PERF_CTR2_SEL_0 0x9A30 -#define CB_PERF_CTR2_SEL_1 0x9A34 -#define CB_PERF_CTR3_SEL_0 0x9A38 -#define CB_PERF_CTR3_SEL_1 0x9A3C - -#define TA_CNTL_AUX 0x9508 -#define DISABLE_CUBE_WRAP (1 << 0) -#define DISABLE_CUBE_ANISO (1 << 1) -#define SYNC_GRADIENT (1 << 24) -#define SYNC_WALKER (1 << 25) -#define SYNC_ALIGNER (1 << 26) - -#define TCP_CHAN_STEER_LO 0x960c -#define TCP_CHAN_STEER_HI 0x9610 - -#define VGT_CACHE_INVALIDATION 0x88C4 -#define CACHE_INVALIDATION(x) ((x) << 0) -#define VC_ONLY 0 -#define TC_ONLY 1 -#define VC_AND_TC 2 -#define AUTO_INVLD_EN(x) ((x) << 6) -#define NO_AUTO 0 -#define ES_AUTO 1 -#define GS_AUTO 2 -#define ES_AND_GS_AUTO 3 -#define VGT_GS_VERTEX_REUSE 0x88D4 -#define VGT_NUM_INSTANCES 0x8974 -#define VGT_OUT_DEALLOC_CNTL 0x28C5C -#define DEALLOC_DIST_MASK 0x0000007F -#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 -#define VTX_REUSE_DEPTH_MASK 0x000000FF - -#define VM_CONTEXT0_CNTL 0x1410 -#define ENABLE_CONTEXT (1 << 0) -#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -#define VM_CONTEXT1_CNTL 0x1414 -#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C -#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C -#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C -#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 -#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -#define REQUEST_TYPE(x) (((x) & 0xf) << 0) -#define RESPONSE_TYPE_MASK 0x000000F0 -#define RESPONSE_TYPE_SHIFT 4 -#define VM_L2_CNTL 0x1400 -#define ENABLE_L2_CACHE (1 << 0) -#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14) -#define VM_L2_CNTL2 0x1404 -#define INVALIDATE_ALL_L1_TLBS (1 << 0) -#define INVALIDATE_L2_CACHE (1 << 1) -#define VM_L2_CNTL3 0x1408 -#define BANK_SELECT(x) ((x) << 0) -#define CACHE_UPDATE_MODE(x) ((x) << 6) -#define VM_L2_STATUS 0x140C -#define L2_BUSY (1 << 0) - -#define WAIT_UNTIL 0x8040 - -#define SRBM_STATUS 0x0E50 -#define SRBM_SOFT_RESET 0x0E60 -#define SRBM_SOFT_RESET_ALL_MASK 0x00FEEFA6 -#define SOFT_RESET_BIF (1 << 1) -#define SOFT_RESET_CG (1 << 2) -#define SOFT_RESET_DC (1 << 5) -#define SOFT_RESET_GRBM (1 << 8) -#define SOFT_RESET_HDP (1 << 9) -#define SOFT_RESET_IH (1 << 10) -#define SOFT_RESET_MC (1 << 11) -#define SOFT_RESET_RLC (1 << 13) -#define SOFT_RESET_ROM (1 << 14) -#define SOFT_RESET_SEM (1 << 15) -#define SOFT_RESET_VMC (1 << 17) -#define SOFT_RESET_TST (1 << 21) -#define SOFT_RESET_REGBB (1 << 22) -#define SOFT_RESET_ORB (1 << 23) - -/* display watermarks */ -#define DC_LB_MEMORY_SPLIT 0x6b0c -#define PRIORITY_A_CNT 0x6b18 -#define PRIORITY_MARK_MASK 0x7fff -#define PRIORITY_OFF (1 << 16) -#define PRIORITY_ALWAYS_ON (1 << 20) -#define PRIORITY_B_CNT 0x6b1c -#define PIPE0_ARBITRATION_CONTROL3 0x0bf0 -# define LATENCY_WATERMARK_MASK(x) ((x) << 16) -#define PIPE0_LATENCY_CONTROL 0x0bf4 -# define LATENCY_LOW_WATERMARK(x) ((x) << 0) -# define LATENCY_HIGH_WATERMARK(x) ((x) << 16) - -#define IH_RB_CNTL 0x3e00 -# define IH_RB_ENABLE (1 << 0) -# define IH_IB_SIZE(x) ((x) << 1) /* log2 */ -# define IH_RB_FULL_DRAIN_ENABLE (1 << 6) -# define IH_WPTR_WRITEBACK_ENABLE (1 << 8) -# define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */ -# define IH_WPTR_OVERFLOW_ENABLE (1 << 16) -# define IH_WPTR_OVERFLOW_CLEAR (1 << 31) -#define IH_RB_BASE 0x3e04 -#define IH_RB_RPTR 0x3e08 -#define IH_RB_WPTR 0x3e0c -# define RB_OVERFLOW (1 << 0) -# define WPTR_OFFSET_MASK 0x3fffc -#define IH_RB_WPTR_ADDR_HI 0x3e10 -#define IH_RB_WPTR_ADDR_LO 0x3e14 -#define IH_CNTL 0x3e18 -# define ENABLE_INTR (1 << 0) -# define IH_MC_SWAP(x) ((x) << 1) -# define IH_MC_SWAP_NONE 0 -# define IH_MC_SWAP_16BIT 1 -# define IH_MC_SWAP_32BIT 2 -# define IH_MC_SWAP_64BIT 3 -# define RPTR_REARM (1 << 4) -# define MC_WRREQ_CREDIT(x) ((x) << 15) -# define MC_WR_CLEAN_CNT(x) ((x) << 20) - -#define CP_INT_CNTL 0xc124 -# define CNTX_BUSY_INT_ENABLE (1 << 19) -# define CNTX_EMPTY_INT_ENABLE (1 << 20) -# define SCRATCH_INT_ENABLE (1 << 25) -# define TIME_STAMP_INT_ENABLE (1 << 26) -# define IB2_INT_ENABLE (1 << 29) -# define IB1_INT_ENABLE (1 << 30) -# define RB_INT_ENABLE (1 << 31) -#define CP_INT_STATUS 0xc128 -# define SCRATCH_INT_STAT (1 << 25) -# define TIME_STAMP_INT_STAT (1 << 26) -# define IB2_INT_STAT (1 << 29) -# define IB1_INT_STAT (1 << 30) -# define RB_INT_STAT (1 << 31) - -#define GRBM_INT_CNTL 0x8060 -# define RDERR_INT_ENABLE (1 << 0) -# define GUI_IDLE_INT_ENABLE (1 << 19) - -/* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ -#define CRTC_STATUS_FRAME_COUNT 0x6e98 - -/* 0x6bb8, 0x77b8, 0x103b8, 0x10fb8, 0x11bb8, 0x127b8 */ -#define VLINE_STATUS 0x6bb8 -# define VLINE_OCCURRED (1 << 0) -# define VLINE_ACK (1 << 4) -# define VLINE_STAT (1 << 12) -# define VLINE_INTERRUPT (1 << 16) -# define VLINE_INTERRUPT_TYPE (1 << 17) -/* 0x6bbc, 0x77bc, 0x103bc, 0x10fbc, 0x11bbc, 0x127bc */ -#define VBLANK_STATUS 0x6bbc -# define VBLANK_OCCURRED (1 << 0) -# define VBLANK_ACK (1 << 4) -# define VBLANK_STAT (1 << 12) -# define VBLANK_INTERRUPT (1 << 16) -# define VBLANK_INTERRUPT_TYPE (1 << 17) - -/* 0x6b40, 0x7740, 0x10340, 0x10f40, 0x11b40, 0x12740 */ -#define INT_MASK 0x6b40 -# define VBLANK_INT_MASK (1 << 0) -# define VLINE_INT_MASK (1 << 4) - -#define DISP_INTERRUPT_STATUS 0x60f4 -# define LB_D1_VLINE_INTERRUPT (1 << 2) -# define LB_D1_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD1_INTERRUPT (1 << 17) -# define DC_HPD1_RX_INTERRUPT (1 << 18) -# define DACA_AUTODETECT_INTERRUPT (1 << 22) -# define DACB_AUTODETECT_INTERRUPT (1 << 23) -# define DC_I2C_SW_DONE_INTERRUPT (1 << 24) -# define DC_I2C_HW_DONE_INTERRUPT (1 << 25) -#define DISP_INTERRUPT_STATUS_CONTINUE 0x60f8 -# define LB_D2_VLINE_INTERRUPT (1 << 2) -# define LB_D2_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD2_INTERRUPT (1 << 17) -# define DC_HPD2_RX_INTERRUPT (1 << 18) -# define DISP_TIMER_INTERRUPT (1 << 24) -#define DISP_INTERRUPT_STATUS_CONTINUE2 0x60fc -# define LB_D3_VLINE_INTERRUPT (1 << 2) -# define LB_D3_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD3_INTERRUPT (1 << 17) -# define DC_HPD3_RX_INTERRUPT (1 << 18) -#define DISP_INTERRUPT_STATUS_CONTINUE3 0x6100 -# define LB_D4_VLINE_INTERRUPT (1 << 2) -# define LB_D4_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD4_INTERRUPT (1 << 17) -# define DC_HPD4_RX_INTERRUPT (1 << 18) -#define DISP_INTERRUPT_STATUS_CONTINUE4 0x614c -# define LB_D5_VLINE_INTERRUPT (1 << 2) -# define LB_D5_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD5_INTERRUPT (1 << 17) -# define DC_HPD5_RX_INTERRUPT (1 << 18) -#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150 -# define LB_D6_VLINE_INTERRUPT (1 << 2) -# define LB_D6_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD6_INTERRUPT (1 << 17) -# define DC_HPD6_RX_INTERRUPT (1 << 18) - -/* 0x6858, 0x7458, 0x10058, 0x10c58, 0x11858, 0x12458 */ -#define GRPH_INT_STATUS 0x6858 -# define GRPH_PFLIP_INT_OCCURRED (1 << 0) -# define GRPH_PFLIP_INT_CLEAR (1 << 8) -/* 0x685c, 0x745c, 0x1005c, 0x10c5c, 0x1185c, 0x1245c */ -#define GRPH_INT_CONTROL 0x685c -# define GRPH_PFLIP_INT_MASK (1 << 0) -# define GRPH_PFLIP_INT_TYPE (1 << 8) - -#define DACA_AUTODETECT_INT_CONTROL 0x66c8 -#define DACB_AUTODETECT_INT_CONTROL 0x67c8 - -#define DC_HPD1_INT_STATUS 0x601c -#define DC_HPD2_INT_STATUS 0x6028 -#define DC_HPD3_INT_STATUS 0x6034 -#define DC_HPD4_INT_STATUS 0x6040 -#define DC_HPD5_INT_STATUS 0x604c -#define DC_HPD6_INT_STATUS 0x6058 -# define DC_HPDx_INT_STATUS (1 << 0) -# define DC_HPDx_SENSE (1 << 1) -# define DC_HPDx_RX_INT_STATUS (1 << 8) - -#define DC_HPD1_INT_CONTROL 0x6020 -#define DC_HPD2_INT_CONTROL 0x602c -#define DC_HPD3_INT_CONTROL 0x6038 -#define DC_HPD4_INT_CONTROL 0x6044 -#define DC_HPD5_INT_CONTROL 0x6050 -#define DC_HPD6_INT_CONTROL 0x605c -# define DC_HPDx_INT_ACK (1 << 0) -# define DC_HPDx_INT_POLARITY (1 << 8) -# define DC_HPDx_INT_EN (1 << 16) -# define DC_HPDx_RX_INT_ACK (1 << 20) -# define DC_HPDx_RX_INT_EN (1 << 24) - -#define DC_HPD1_CONTROL 0x6024 -#define DC_HPD2_CONTROL 0x6030 -#define DC_HPD3_CONTROL 0x603c -#define DC_HPD4_CONTROL 0x6048 -#define DC_HPD5_CONTROL 0x6054 -#define DC_HPD6_CONTROL 0x6060 -# define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) -# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) -# define DC_HPDx_EN (1 << 28) - -/* PCIE link stuff */ -#define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ -#define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ -# define LC_LINK_WIDTH_SHIFT 0 -# define LC_LINK_WIDTH_MASK 0x7 -# define LC_LINK_WIDTH_X0 0 -# define LC_LINK_WIDTH_X1 1 -# define LC_LINK_WIDTH_X2 2 -# define LC_LINK_WIDTH_X4 3 -# define LC_LINK_WIDTH_X8 4 -# define LC_LINK_WIDTH_X16 6 -# define LC_LINK_WIDTH_RD_SHIFT 4 -# define LC_LINK_WIDTH_RD_MASK 0x70 -# define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) -# define LC_RECONFIG_NOW (1 << 8) -# define LC_RENEGOTIATION_SUPPORT (1 << 9) -# define LC_RENEGOTIATE_EN (1 << 10) -# define LC_SHORT_RECONFIG_EN (1 << 11) -# define LC_UPCONFIGURE_SUPPORT (1 << 12) -# define LC_UPCONFIGURE_DIS (1 << 13) -#define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ -# define LC_GEN2_EN_STRAP (1 << 0) -# define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) -# define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) -# define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) -# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) -# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 -# define LC_CURRENT_DATA_RATE (1 << 11) -# define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) -# define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) -# define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) -# define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) -#define MM_CFGREGS_CNTL 0x544c -# define MM_WR_TO_CFG_EN (1 << 3) -#define LINK_CNTL2 0x88 /* F0 */ -# define TARGET_LINK_SPEED_MASK (0xf << 0) -# define SELECTABLE_DEEMPHASIS (1 << 6) - -/* - * PM4 - */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ - (((reg) >> 2) & 0xFFFF) | \ - ((n) & 0x3FFF) << 16) -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) - -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) - -#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ - (((op) & 0xFF) << 8) | \ - ((n) & 0x3FFF) << 16) - -/* Packet 3 types */ -#define PACKET3_NOP 0x10 -#define PACKET3_SET_BASE 0x11 -#define PACKET3_CLEAR_STATE 0x12 -#define PACKET3_INDEX_BUFFER_SIZE 0x13 -#define PACKET3_DISPATCH_DIRECT 0x15 -#define PACKET3_DISPATCH_INDIRECT 0x16 -#define PACKET3_INDIRECT_BUFFER_END 0x17 -#define PACKET3_MODE_CONTROL 0x18 -#define PACKET3_SET_PREDICATION 0x20 -#define PACKET3_REG_RMW 0x21 -#define PACKET3_COND_EXEC 0x22 -#define PACKET3_PRED_EXEC 0x23 -#define PACKET3_DRAW_INDIRECT 0x24 -#define PACKET3_DRAW_INDEX_INDIRECT 0x25 -#define PACKET3_INDEX_BASE 0x26 -#define PACKET3_DRAW_INDEX_2 0x27 -#define PACKET3_CONTEXT_CONTROL 0x28 -#define PACKET3_DRAW_INDEX_OFFSET 0x29 -#define PACKET3_INDEX_TYPE 0x2A -#define PACKET3_DRAW_INDEX 0x2B -#define PACKET3_DRAW_INDEX_AUTO 0x2D -#define PACKET3_DRAW_INDEX_IMMD 0x2E -#define PACKET3_NUM_INSTANCES 0x2F -#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30 -#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 -#define PACKET3_DRAW_INDEX_OFFSET_2 0x35 -#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 -#define PACKET3_MEM_SEMAPHORE 0x39 -#define PACKET3_MPEG_INDEX 0x3A -#define PACKET3_COPY_DW 0x3B -#define PACKET3_WAIT_REG_MEM 0x3C -#define PACKET3_MEM_WRITE 0x3D -#define PACKET3_INDIRECT_BUFFER 0x32 -#define PACKET3_SURFACE_SYNC 0x43 -# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) -# define PACKET3_CB1_DEST_BASE_ENA (1 << 7) -# define PACKET3_CB2_DEST_BASE_ENA (1 << 8) -# define PACKET3_CB3_DEST_BASE_ENA (1 << 9) -# define PACKET3_CB4_DEST_BASE_ENA (1 << 10) -# define PACKET3_CB5_DEST_BASE_ENA (1 << 11) -# define PACKET3_CB6_DEST_BASE_ENA (1 << 12) -# define PACKET3_CB7_DEST_BASE_ENA (1 << 13) -# define PACKET3_DB_DEST_BASE_ENA (1 << 14) -# define PACKET3_CB8_DEST_BASE_ENA (1 << 15) -# define PACKET3_CB9_DEST_BASE_ENA (1 << 16) -# define PACKET3_CB10_DEST_BASE_ENA (1 << 17) -# define PACKET3_CB11_DEST_BASE_ENA (1 << 18) -# define PACKET3_FULL_CACHE_ENA (1 << 20) -# define PACKET3_TC_ACTION_ENA (1 << 23) -# define PACKET3_VC_ACTION_ENA (1 << 24) -# define PACKET3_CB_ACTION_ENA (1 << 25) -# define PACKET3_DB_ACTION_ENA (1 << 26) -# define PACKET3_SH_ACTION_ENA (1 << 27) -# define PACKET3_SX_ACTION_ENA (1 << 28) -#define PACKET3_ME_INITIALIZE 0x44 -#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -#define PACKET3_COND_WRITE 0x45 -#define PACKET3_EVENT_WRITE 0x46 -#define PACKET3_EVENT_WRITE_EOP 0x47 -#define PACKET3_EVENT_WRITE_EOS 0x48 -#define PACKET3_PREAMBLE_CNTL 0x4A -# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28) -# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28) -#define PACKET3_RB_OFFSET 0x4B -#define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C -#define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D -#define PACKET3_ALU_PS_CONST_UPDATE 0x4E -#define PACKET3_ALU_VS_CONST_UPDATE 0x4F -#define PACKET3_ONE_REG_WRITE 0x57 -#define PACKET3_SET_CONFIG_REG 0x68 -#define PACKET3_SET_CONFIG_REG_START 0x00008000 -#define PACKET3_SET_CONFIG_REG_END 0x0000ac00 -#define PACKET3_SET_CONTEXT_REG 0x69 -#define PACKET3_SET_CONTEXT_REG_START 0x00028000 -#define PACKET3_SET_CONTEXT_REG_END 0x00029000 -#define PACKET3_SET_ALU_CONST 0x6A -/* alu const buffers only; no reg file */ -#define PACKET3_SET_BOOL_CONST 0x6B -#define PACKET3_SET_BOOL_CONST_START 0x0003a500 -#define PACKET3_SET_BOOL_CONST_END 0x0003a518 -#define PACKET3_SET_LOOP_CONST 0x6C -#define PACKET3_SET_LOOP_CONST_START 0x0003a200 -#define PACKET3_SET_LOOP_CONST_END 0x0003a500 -#define PACKET3_SET_RESOURCE 0x6D -#define PACKET3_SET_RESOURCE_START 0x00030000 -#define PACKET3_SET_RESOURCE_END 0x00038000 -#define PACKET3_SET_SAMPLER 0x6E -#define PACKET3_SET_SAMPLER_START 0x0003c000 -#define PACKET3_SET_SAMPLER_END 0x0003c600 -#define PACKET3_SET_CTL_CONST 0x6F -#define PACKET3_SET_CTL_CONST_START 0x0003cff0 -#define PACKET3_SET_CTL_CONST_END 0x0003ff0c -#define PACKET3_SET_RESOURCE_OFFSET 0x70 -#define PACKET3_SET_ALU_CONST_VS 0x71 -#define PACKET3_SET_ALU_CONST_DI 0x72 -#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 -#define PACKET3_SET_RESOURCE_INDIRECT 0x74 -#define PACKET3_SET_APPEND_CNT 0x75 - -#define SQ_RESOURCE_CONSTANT_WORD7_0 0x3001c -#define S__SQ_CONSTANT_TYPE(x) (((x) & 3) << 30) -#define G__SQ_CONSTANT_TYPE(x) (((x) >> 30) & 3) -#define SQ_TEX_VTX_INVALID_TEXTURE 0x0 -#define SQ_TEX_VTX_INVALID_BUFFER 0x1 -#define SQ_TEX_VTX_VALID_TEXTURE 0x2 -#define SQ_TEX_VTX_VALID_BUFFER 0x3 - -#define VGT_VTX_VECT_EJECT_REG 0x88b0 - -#define SQ_CONST_MEM_BASE 0x8df8 - -#define SQ_ESGS_RING_BASE 0x8c40 -#define SQ_ESGS_RING_SIZE 0x8c44 -#define SQ_GSVS_RING_BASE 0x8c48 -#define SQ_GSVS_RING_SIZE 0x8c4c -#define SQ_ESTMP_RING_BASE 0x8c50 -#define SQ_ESTMP_RING_SIZE 0x8c54 -#define SQ_GSTMP_RING_BASE 0x8c58 -#define SQ_GSTMP_RING_SIZE 0x8c5c -#define SQ_VSTMP_RING_BASE 0x8c60 -#define SQ_VSTMP_RING_SIZE 0x8c64 -#define SQ_PSTMP_RING_BASE 0x8c68 -#define SQ_PSTMP_RING_SIZE 0x8c6c -#define SQ_LSTMP_RING_BASE 0x8e10 -#define SQ_LSTMP_RING_SIZE 0x8e14 -#define SQ_HSTMP_RING_BASE 0x8e18 -#define SQ_HSTMP_RING_SIZE 0x8e1c -#define VGT_TF_RING_SIZE 0x8988 - -#define SQ_ESGS_RING_ITEMSIZE 0x28900 -#define SQ_GSVS_RING_ITEMSIZE 0x28904 -#define SQ_ESTMP_RING_ITEMSIZE 0x28908 -#define SQ_GSTMP_RING_ITEMSIZE 0x2890c -#define SQ_VSTMP_RING_ITEMSIZE 0x28910 -#define SQ_PSTMP_RING_ITEMSIZE 0x28914 -#define SQ_LSTMP_RING_ITEMSIZE 0x28830 -#define SQ_HSTMP_RING_ITEMSIZE 0x28834 - -#define SQ_GS_VERT_ITEMSIZE 0x2891c -#define SQ_GS_VERT_ITEMSIZE_1 0x28920 -#define SQ_GS_VERT_ITEMSIZE_2 0x28924 -#define SQ_GS_VERT_ITEMSIZE_3 0x28928 -#define SQ_GSVS_RING_OFFSET_1 0x2892c -#define SQ_GSVS_RING_OFFSET_2 0x28930 -#define SQ_GSVS_RING_OFFSET_3 0x28934 - -#define SQ_ALU_CONST_BUFFER_SIZE_PS_0 0x28140 -#define SQ_ALU_CONST_BUFFER_SIZE_HS_0 0x28f80 - -#define SQ_ALU_CONST_CACHE_PS_0 0x28940 -#define SQ_ALU_CONST_CACHE_PS_1 0x28944 -#define SQ_ALU_CONST_CACHE_PS_2 0x28948 -#define SQ_ALU_CONST_CACHE_PS_3 0x2894c -#define SQ_ALU_CONST_CACHE_PS_4 0x28950 -#define SQ_ALU_CONST_CACHE_PS_5 0x28954 -#define SQ_ALU_CONST_CACHE_PS_6 0x28958 -#define SQ_ALU_CONST_CACHE_PS_7 0x2895c -#define SQ_ALU_CONST_CACHE_PS_8 0x28960 -#define SQ_ALU_CONST_CACHE_PS_9 0x28964 -#define SQ_ALU_CONST_CACHE_PS_10 0x28968 -#define SQ_ALU_CONST_CACHE_PS_11 0x2896c -#define SQ_ALU_CONST_CACHE_PS_12 0x28970 -#define SQ_ALU_CONST_CACHE_PS_13 0x28974 -#define SQ_ALU_CONST_CACHE_PS_14 0x28978 -#define SQ_ALU_CONST_CACHE_PS_15 0x2897c -#define SQ_ALU_CONST_CACHE_VS_0 0x28980 -#define SQ_ALU_CONST_CACHE_VS_1 0x28984 -#define SQ_ALU_CONST_CACHE_VS_2 0x28988 -#define SQ_ALU_CONST_CACHE_VS_3 0x2898c -#define SQ_ALU_CONST_CACHE_VS_4 0x28990 -#define SQ_ALU_CONST_CACHE_VS_5 0x28994 -#define SQ_ALU_CONST_CACHE_VS_6 0x28998 -#define SQ_ALU_CONST_CACHE_VS_7 0x2899c -#define SQ_ALU_CONST_CACHE_VS_8 0x289a0 -#define SQ_ALU_CONST_CACHE_VS_9 0x289a4 -#define SQ_ALU_CONST_CACHE_VS_10 0x289a8 -#define SQ_ALU_CONST_CACHE_VS_11 0x289ac -#define SQ_ALU_CONST_CACHE_VS_12 0x289b0 -#define SQ_ALU_CONST_CACHE_VS_13 0x289b4 -#define SQ_ALU_CONST_CACHE_VS_14 0x289b8 -#define SQ_ALU_CONST_CACHE_VS_15 0x289bc -#define SQ_ALU_CONST_CACHE_GS_0 0x289c0 -#define SQ_ALU_CONST_CACHE_GS_1 0x289c4 -#define SQ_ALU_CONST_CACHE_GS_2 0x289c8 -#define SQ_ALU_CONST_CACHE_GS_3 0x289cc -#define SQ_ALU_CONST_CACHE_GS_4 0x289d0 -#define SQ_ALU_CONST_CACHE_GS_5 0x289d4 -#define SQ_ALU_CONST_CACHE_GS_6 0x289d8 -#define SQ_ALU_CONST_CACHE_GS_7 0x289dc -#define SQ_ALU_CONST_CACHE_GS_8 0x289e0 -#define SQ_ALU_CONST_CACHE_GS_9 0x289e4 -#define SQ_ALU_CONST_CACHE_GS_10 0x289e8 -#define SQ_ALU_CONST_CACHE_GS_11 0x289ec -#define SQ_ALU_CONST_CACHE_GS_12 0x289f0 -#define SQ_ALU_CONST_CACHE_GS_13 0x289f4 -#define SQ_ALU_CONST_CACHE_GS_14 0x289f8 -#define SQ_ALU_CONST_CACHE_GS_15 0x289fc -#define SQ_ALU_CONST_CACHE_HS_0 0x28f00 -#define SQ_ALU_CONST_CACHE_HS_1 0x28f04 -#define SQ_ALU_CONST_CACHE_HS_2 0x28f08 -#define SQ_ALU_CONST_CACHE_HS_3 0x28f0c -#define SQ_ALU_CONST_CACHE_HS_4 0x28f10 -#define SQ_ALU_CONST_CACHE_HS_5 0x28f14 -#define SQ_ALU_CONST_CACHE_HS_6 0x28f18 -#define SQ_ALU_CONST_CACHE_HS_7 0x28f1c -#define SQ_ALU_CONST_CACHE_HS_8 0x28f20 -#define SQ_ALU_CONST_CACHE_HS_9 0x28f24 -#define SQ_ALU_CONST_CACHE_HS_10 0x28f28 -#define SQ_ALU_CONST_CACHE_HS_11 0x28f2c -#define SQ_ALU_CONST_CACHE_HS_12 0x28f30 -#define SQ_ALU_CONST_CACHE_HS_13 0x28f34 -#define SQ_ALU_CONST_CACHE_HS_14 0x28f38 -#define SQ_ALU_CONST_CACHE_HS_15 0x28f3c -#define SQ_ALU_CONST_CACHE_LS_0 0x28f40 -#define SQ_ALU_CONST_CACHE_LS_1 0x28f44 -#define SQ_ALU_CONST_CACHE_LS_2 0x28f48 -#define SQ_ALU_CONST_CACHE_LS_3 0x28f4c -#define SQ_ALU_CONST_CACHE_LS_4 0x28f50 -#define SQ_ALU_CONST_CACHE_LS_5 0x28f54 -#define SQ_ALU_CONST_CACHE_LS_6 0x28f58 -#define SQ_ALU_CONST_CACHE_LS_7 0x28f5c -#define SQ_ALU_CONST_CACHE_LS_8 0x28f60 -#define SQ_ALU_CONST_CACHE_LS_9 0x28f64 -#define SQ_ALU_CONST_CACHE_LS_10 0x28f68 -#define SQ_ALU_CONST_CACHE_LS_11 0x28f6c -#define SQ_ALU_CONST_CACHE_LS_12 0x28f70 -#define SQ_ALU_CONST_CACHE_LS_13 0x28f74 -#define SQ_ALU_CONST_CACHE_LS_14 0x28f78 -#define SQ_ALU_CONST_CACHE_LS_15 0x28f7c - -#define PA_SC_SCREEN_SCISSOR_TL 0x28030 -#define PA_SC_GENERIC_SCISSOR_TL 0x28240 -#define PA_SC_WINDOW_SCISSOR_TL 0x28204 - -#define VGT_PRIMITIVE_TYPE 0x8958 -#define VGT_INDEX_TYPE 0x895C - -#define VGT_NUM_INDICES 0x8970 - -#define VGT_COMPUTE_DIM_X 0x8990 -#define VGT_COMPUTE_DIM_Y 0x8994 -#define VGT_COMPUTE_DIM_Z 0x8998 -#define VGT_COMPUTE_START_X 0x899C -#define VGT_COMPUTE_START_Y 0x89A0 -#define VGT_COMPUTE_START_Z 0x89A4 -#define VGT_COMPUTE_INDEX 0x89A8 -#define VGT_COMPUTE_THREAD_GROUP_SIZE 0x89AC -#define VGT_HS_OFFCHIP_PARAM 0x89B0 - -#define DB_DEBUG 0x9830 -#define DB_DEBUG2 0x9834 -#define DB_DEBUG3 0x9838 -#define DB_DEBUG4 0x983C -#define DB_WATERMARKS 0x9854 -#define DB_DEPTH_CONTROL 0x28800 -#define R_028800_DB_DEPTH_CONTROL 0x028800 -#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0) -#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1) -#define C_028800_STENCIL_ENABLE 0xFFFFFFFE -#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1) -#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1) -#define C_028800_Z_ENABLE 0xFFFFFFFD -#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2) -#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1) -#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB -#define S_028800_ZFUNC(x) (((x) & 0x7) << 4) -#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7) -#define C_028800_ZFUNC 0xFFFFFF8F -#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7) -#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1) -#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F -#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8) -#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7) -#define C_028800_STENCILFUNC 0xFFFFF8FF -#define V_028800_STENCILFUNC_NEVER 0x00000000 -#define V_028800_STENCILFUNC_LESS 0x00000001 -#define V_028800_STENCILFUNC_EQUAL 0x00000002 -#define V_028800_STENCILFUNC_LEQUAL 0x00000003 -#define V_028800_STENCILFUNC_GREATER 0x00000004 -#define V_028800_STENCILFUNC_NOTEQUAL 0x00000005 -#define V_028800_STENCILFUNC_GEQUAL 0x00000006 -#define V_028800_STENCILFUNC_ALWAYS 0x00000007 -#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11) -#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7) -#define C_028800_STENCILFAIL 0xFFFFC7FF -#define V_028800_STENCIL_KEEP 0x00000000 -#define V_028800_STENCIL_ZERO 0x00000001 -#define V_028800_STENCIL_REPLACE 0x00000002 -#define V_028800_STENCIL_INCR 0x00000003 -#define V_028800_STENCIL_DECR 0x00000004 -#define V_028800_STENCIL_INVERT 0x00000005 -#define V_028800_STENCIL_INCR_WRAP 0x00000006 -#define V_028800_STENCIL_DECR_WRAP 0x00000007 -#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14) -#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7) -#define C_028800_STENCILZPASS 0xFFFE3FFF -#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17) -#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7) -#define C_028800_STENCILZFAIL 0xFFF1FFFF -#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20) -#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7) -#define C_028800_STENCILFUNC_BF 0xFF8FFFFF -#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23) -#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7) -#define C_028800_STENCILFAIL_BF 0xFC7FFFFF -#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26) -#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7) -#define C_028800_STENCILZPASS_BF 0xE3FFFFFF -#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29) -#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7) -#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF -#define DB_DEPTH_VIEW 0x28008 -#define R_028008_DB_DEPTH_VIEW 0x00028008 -#define S_028008_SLICE_START(x) (((x) & 0x7FF) << 0) -#define G_028008_SLICE_START(x) (((x) >> 0) & 0x7FF) -#define C_028008_SLICE_START 0xFFFFF800 -#define S_028008_SLICE_MAX(x) (((x) & 0x7FF) << 13) -#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF) -#define C_028008_SLICE_MAX 0xFF001FFF -#define DB_HTILE_DATA_BASE 0x28014 -#define DB_HTILE_SURFACE 0x28abc -#define S_028ABC_HTILE_WIDTH(x) (((x) & 0x1) << 0) -#define G_028ABC_HTILE_WIDTH(x) (((x) >> 0) & 0x1) -#define C_028ABC_HTILE_WIDTH 0xFFFFFFFE -#define S_028ABC_HTILE_HEIGHT(x) (((x) & 0x1) << 1) -#define G_028ABC_HTILE_HEIGHT(x) (((x) >> 1) & 0x1) -#define C_028ABC_HTILE_HEIGHT 0xFFFFFFFD -#define G_028ABC_LINEAR(x) (((x) >> 2) & 0x1) -#define DB_Z_INFO 0x28040 -# define Z_ARRAY_MODE(x) ((x) << 4) -# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8) -# define DB_NUM_BANKS(x) (((x) & 0x3) << 12) -# define DB_BANK_WIDTH(x) (((x) & 0x3) << 16) -# define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20) -# define DB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24) -#define R_028040_DB_Z_INFO 0x028040 -#define S_028040_FORMAT(x) (((x) & 0x3) << 0) -#define G_028040_FORMAT(x) (((x) >> 0) & 0x3) -#define C_028040_FORMAT 0xFFFFFFFC -#define V_028040_Z_INVALID 0x00000000 -#define V_028040_Z_16 0x00000001 -#define V_028040_Z_24 0x00000002 -#define V_028040_Z_32_FLOAT 0x00000003 -#define S_028040_ARRAY_MODE(x) (((x) & 0xF) << 4) -#define G_028040_ARRAY_MODE(x) (((x) >> 4) & 0xF) -#define C_028040_ARRAY_MODE 0xFFFFFF0F -#define S_028040_READ_SIZE(x) (((x) & 0x1) << 28) -#define G_028040_READ_SIZE(x) (((x) >> 28) & 0x1) -#define C_028040_READ_SIZE 0xEFFFFFFF -#define S_028040_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 29) -#define G_028040_TILE_SURFACE_ENABLE(x) (((x) >> 29) & 0x1) -#define C_028040_TILE_SURFACE_ENABLE 0xDFFFFFFF -#define S_028040_ZRANGE_PRECISION(x) (((x) & 0x1) << 31) -#define G_028040_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1) -#define C_028040_ZRANGE_PRECISION 0x7FFFFFFF -#define S_028040_TILE_SPLIT(x) (((x) & 0x7) << 8) -#define G_028040_TILE_SPLIT(x) (((x) >> 8) & 0x7) -#define S_028040_NUM_BANKS(x) (((x) & 0x3) << 12) -#define G_028040_NUM_BANKS(x) (((x) >> 12) & 0x3) -#define S_028040_BANK_WIDTH(x) (((x) & 0x3) << 16) -#define G_028040_BANK_WIDTH(x) (((x) >> 16) & 0x3) -#define S_028040_BANK_HEIGHT(x) (((x) & 0x3) << 20) -#define G_028040_BANK_HEIGHT(x) (((x) >> 20) & 0x3) -#define S_028040_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24) -#define G_028040_MACRO_TILE_ASPECT(x) (((x) >> 24) & 0x3) -#define DB_STENCIL_INFO 0x28044 -#define R_028044_DB_STENCIL_INFO 0x028044 -#define S_028044_FORMAT(x) (((x) & 0x1) << 0) -#define G_028044_FORMAT(x) (((x) >> 0) & 0x1) -#define C_028044_FORMAT 0xFFFFFFFE -#define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) -#define DB_Z_READ_BASE 0x28048 -#define DB_STENCIL_READ_BASE 0x2804c -#define DB_Z_WRITE_BASE 0x28050 -#define DB_STENCIL_WRITE_BASE 0x28054 -#define DB_DEPTH_SIZE 0x28058 -#define R_028058_DB_DEPTH_SIZE 0x028058 -#define S_028058_PITCH_TILE_MAX(x) (((x) & 0x7FF) << 0) -#define G_028058_PITCH_TILE_MAX(x) (((x) >> 0) & 0x7FF) -#define C_028058_PITCH_TILE_MAX 0xFFFFF800 -#define S_028058_HEIGHT_TILE_MAX(x) (((x) & 0x7FF) << 11) -#define G_028058_HEIGHT_TILE_MAX(x) (((x) >> 11) & 0x7FF) -#define C_028058_HEIGHT_TILE_MAX 0xFFC007FF -#define R_02805C_DB_DEPTH_SLICE 0x02805C -#define S_02805C_SLICE_TILE_MAX(x) (((x) & 0x3FFFFF) << 0) -#define G_02805C_SLICE_TILE_MAX(x) (((x) >> 0) & 0x3FFFFF) -#define C_02805C_SLICE_TILE_MAX 0xFFC00000 - -#define SQ_PGM_START_PS 0x28840 -#define SQ_PGM_START_VS 0x2885c -#define SQ_PGM_START_GS 0x28874 -#define SQ_PGM_START_ES 0x2888c -#define SQ_PGM_START_FS 0x288a4 -#define SQ_PGM_START_HS 0x288b8 -#define SQ_PGM_START_LS 0x288d0 - -#define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8 -#define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8 -#define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8 -#define VGT_STRMOUT_BUFFER_BASE_3 0x28B08 -#define VGT_STRMOUT_BUFFER_SIZE_0 0x28AD0 -#define VGT_STRMOUT_BUFFER_SIZE_1 0x28AE0 -#define VGT_STRMOUT_BUFFER_SIZE_2 0x28AF0 -#define VGT_STRMOUT_BUFFER_SIZE_3 0x28B00 -#define VGT_STRMOUT_CONFIG 0x28b94 -#define VGT_STRMOUT_BUFFER_CONFIG 0x28b98 - -#define CB_TARGET_MASK 0x28238 -#define CB_SHADER_MASK 0x2823c - -#define GDS_ADDR_BASE 0x28720 - -#define CB_IMMED0_BASE 0x28b9c -#define CB_IMMED1_BASE 0x28ba0 -#define CB_IMMED2_BASE 0x28ba4 -#define CB_IMMED3_BASE 0x28ba8 -#define CB_IMMED4_BASE 0x28bac -#define CB_IMMED5_BASE 0x28bb0 -#define CB_IMMED6_BASE 0x28bb4 -#define CB_IMMED7_BASE 0x28bb8 -#define CB_IMMED8_BASE 0x28bbc -#define CB_IMMED9_BASE 0x28bc0 -#define CB_IMMED10_BASE 0x28bc4 -#define CB_IMMED11_BASE 0x28bc8 - -/* all 12 CB blocks have these regs */ -#define CB_COLOR0_BASE 0x28c60 -#define CB_COLOR0_PITCH 0x28c64 -#define CB_COLOR0_SLICE 0x28c68 -#define CB_COLOR0_VIEW 0x28c6c -#define R_028C6C_CB_COLOR0_VIEW 0x00028C6C -#define S_028C6C_SLICE_START(x) (((x) & 0x7FF) << 0) -#define G_028C6C_SLICE_START(x) (((x) >> 0) & 0x7FF) -#define C_028C6C_SLICE_START 0xFFFFF800 -#define S_028C6C_SLICE_MAX(x) (((x) & 0x7FF) << 13) -#define G_028C6C_SLICE_MAX(x) (((x) >> 13) & 0x7FF) -#define C_028C6C_SLICE_MAX 0xFF001FFF -#define R_028C70_CB_COLOR0_INFO 0x028C70 -#define S_028C70_ENDIAN(x) (((x) & 0x3) << 0) -#define G_028C70_ENDIAN(x) (((x) >> 0) & 0x3) -#define C_028C70_ENDIAN 0xFFFFFFFC -#define S_028C70_FORMAT(x) (((x) & 0x3F) << 2) -#define G_028C70_FORMAT(x) (((x) >> 2) & 0x3F) -#define C_028C70_FORMAT 0xFFFFFF03 -#define V_028C70_COLOR_INVALID 0x00000000 -#define V_028C70_COLOR_8 0x00000001 -#define V_028C70_COLOR_4_4 0x00000002 -#define V_028C70_COLOR_3_3_2 0x00000003 -#define V_028C70_COLOR_16 0x00000005 -#define V_028C70_COLOR_16_FLOAT 0x00000006 -#define V_028C70_COLOR_8_8 0x00000007 -#define V_028C70_COLOR_5_6_5 0x00000008 -#define V_028C70_COLOR_6_5_5 0x00000009 -#define V_028C70_COLOR_1_5_5_5 0x0000000A -#define V_028C70_COLOR_4_4_4_4 0x0000000B -#define V_028C70_COLOR_5_5_5_1 0x0000000C -#define V_028C70_COLOR_32 0x0000000D -#define V_028C70_COLOR_32_FLOAT 0x0000000E -#define V_028C70_COLOR_16_16 0x0000000F -#define V_028C70_COLOR_16_16_FLOAT 0x00000010 -#define V_028C70_COLOR_8_24 0x00000011 -#define V_028C70_COLOR_8_24_FLOAT 0x00000012 -#define V_028C70_COLOR_24_8 0x00000013 -#define V_028C70_COLOR_24_8_FLOAT 0x00000014 -#define V_028C70_COLOR_10_11_11 0x00000015 -#define V_028C70_COLOR_10_11_11_FLOAT 0x00000016 -#define V_028C70_COLOR_11_11_10 0x00000017 -#define V_028C70_COLOR_11_11_10_FLOAT 0x00000018 -#define V_028C70_COLOR_2_10_10_10 0x00000019 -#define V_028C70_COLOR_8_8_8_8 0x0000001A -#define V_028C70_COLOR_10_10_10_2 0x0000001B -#define V_028C70_COLOR_X24_8_32_FLOAT 0x0000001C -#define V_028C70_COLOR_32_32 0x0000001D -#define V_028C70_COLOR_32_32_FLOAT 0x0000001E -#define V_028C70_COLOR_16_16_16_16 0x0000001F -#define V_028C70_COLOR_16_16_16_16_FLOAT 0x00000020 -#define V_028C70_COLOR_32_32_32_32 0x00000022 -#define V_028C70_COLOR_32_32_32_32_FLOAT 0x00000023 -#define V_028C70_COLOR_32_32_32_FLOAT 0x00000030 -#define S_028C70_ARRAY_MODE(x) (((x) & 0xF) << 8) -#define G_028C70_ARRAY_MODE(x) (((x) >> 8) & 0xF) -#define C_028C70_ARRAY_MODE 0xFFFFF0FF -#define V_028C70_ARRAY_LINEAR_GENERAL 0x00000000 -#define V_028C70_ARRAY_LINEAR_ALIGNED 0x00000001 -#define V_028C70_ARRAY_1D_TILED_THIN1 0x00000002 -#define V_028C70_ARRAY_2D_TILED_THIN1 0x00000004 -#define S_028C70_NUMBER_TYPE(x) (((x) & 0x7) << 12) -#define G_028C70_NUMBER_TYPE(x) (((x) >> 12) & 0x7) -#define C_028C70_NUMBER_TYPE 0xFFFF8FFF -#define V_028C70_NUMBER_UNORM 0x00000000 -#define V_028C70_NUMBER_SNORM 0x00000001 -#define V_028C70_NUMBER_USCALED 0x00000002 -#define V_028C70_NUMBER_SSCALED 0x00000003 -#define V_028C70_NUMBER_UINT 0x00000004 -#define V_028C70_NUMBER_SINT 0x00000005 -#define V_028C70_NUMBER_SRGB 0x00000006 -#define V_028C70_NUMBER_FLOAT 0x00000007 -#define S_028C70_COMP_SWAP(x) (((x) & 0x3) << 15) -#define G_028C70_COMP_SWAP(x) (((x) >> 15) & 0x3) -#define C_028C70_COMP_SWAP 0xFFFE7FFF -#define V_028C70_SWAP_STD 0x00000000 -#define V_028C70_SWAP_ALT 0x00000001 -#define V_028C70_SWAP_STD_REV 0x00000002 -#define V_028C70_SWAP_ALT_REV 0x00000003 -#define S_028C70_FAST_CLEAR(x) (((x) & 0x1) << 17) -#define G_028C70_FAST_CLEAR(x) (((x) >> 17) & 0x1) -#define C_028C70_FAST_CLEAR 0xFFFDFFFF -#define S_028C70_COMPRESSION(x) (((x) & 0x3) << 18) -#define G_028C70_COMPRESSION(x) (((x) >> 18) & 0x3) -#define C_028C70_COMPRESSION 0xFFF3FFFF -#define S_028C70_BLEND_CLAMP(x) (((x) & 0x1) << 19) -#define G_028C70_BLEND_CLAMP(x) (((x) >> 19) & 0x1) -#define C_028C70_BLEND_CLAMP 0xFFF7FFFF -#define S_028C70_BLEND_BYPASS(x) (((x) & 0x1) << 20) -#define G_028C70_BLEND_BYPASS(x) (((x) >> 20) & 0x1) -#define C_028C70_BLEND_BYPASS 0xFFEFFFFF -#define S_028C70_SIMPLE_FLOAT(x) (((x) & 0x1) << 21) -#define G_028C70_SIMPLE_FLOAT(x) (((x) >> 21) & 0x1) -#define C_028C70_SIMPLE_FLOAT 0xFFDFFFFF -#define S_028C70_ROUND_MODE(x) (((x) & 0x1) << 22) -#define G_028C70_ROUND_MODE(x) (((x) >> 22) & 0x1) -#define C_028C70_ROUND_MODE 0xFFBFFFFF -#define S_028C70_TILE_COMPACT(x) (((x) & 0x1) << 23) -#define G_028C70_TILE_COMPACT(x) (((x) >> 23) & 0x1) -#define C_028C70_TILE_COMPACT 0xFF7FFFFF -#define S_028C70_SOURCE_FORMAT(x) (((x) & 0x3) << 24) -#define G_028C70_SOURCE_FORMAT(x) (((x) >> 24) & 0x3) -#define C_028C70_SOURCE_FORMAT 0xFCFFFFFF -#define V_028C70_EXPORT_4C_32BPC 0x0 -#define V_028C70_EXPORT_4C_16BPC 0x1 -#define V_028C70_EXPORT_2C_32BPC 0x2 /* Do not use */ -#define S_028C70_RAT(x) (((x) & 0x1) << 26) -#define G_028C70_RAT(x) (((x) >> 26) & 0x1) -#define C_028C70_RAT 0xFBFFFFFF -#define S_028C70_RESOURCE_TYPE(x) (((x) & 0x7) << 27) -#define G_028C70_RESOURCE_TYPE(x) (((x) >> 27) & 0x7) -#define C_028C70_RESOURCE_TYPE 0xC7FFFFFF - -#define CB_COLOR0_INFO 0x28c70 -# define CB_FORMAT(x) ((x) << 2) -# define CB_ARRAY_MODE(x) ((x) << 8) -# define ARRAY_LINEAR_GENERAL 0 -# define ARRAY_LINEAR_ALIGNED 1 -# define ARRAY_1D_TILED_THIN1 2 -# define ARRAY_2D_TILED_THIN1 4 -# define CB_SOURCE_FORMAT(x) ((x) << 24) -# define CB_SF_EXPORT_FULL 0 -# define CB_SF_EXPORT_NORM 1 -#define R_028C74_CB_COLOR0_ATTRIB 0x028C74 -#define S_028C74_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 4) -#define G_028C74_NON_DISP_TILING_ORDER(x) (((x) >> 4) & 0x1) -#define C_028C74_NON_DISP_TILING_ORDER 0xFFFFFFEF -#define S_028C74_TILE_SPLIT(x) (((x) & 0xf) << 5) -#define G_028C74_TILE_SPLIT(x) (((x) >> 5) & 0xf) -#define S_028C74_NUM_BANKS(x) (((x) & 0x3) << 10) -#define G_028C74_NUM_BANKS(x) (((x) >> 10) & 0x3) -#define S_028C74_BANK_WIDTH(x) (((x) & 0x3) << 13) -#define G_028C74_BANK_WIDTH(x) (((x) >> 13) & 0x3) -#define S_028C74_BANK_HEIGHT(x) (((x) & 0x3) << 16) -#define G_028C74_BANK_HEIGHT(x) (((x) >> 16) & 0x3) -#define S_028C74_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19) -#define G_028C74_MACRO_TILE_ASPECT(x) (((x) >> 19) & 0x3) -#define CB_COLOR0_ATTRIB 0x28c74 -# define CB_TILE_SPLIT(x) (((x) & 0x7) << 5) -# define ADDR_SURF_TILE_SPLIT_64B 0 -# define ADDR_SURF_TILE_SPLIT_128B 1 -# define ADDR_SURF_TILE_SPLIT_256B 2 -# define ADDR_SURF_TILE_SPLIT_512B 3 -# define ADDR_SURF_TILE_SPLIT_1KB 4 -# define ADDR_SURF_TILE_SPLIT_2KB 5 -# define ADDR_SURF_TILE_SPLIT_4KB 6 -# define CB_NUM_BANKS(x) (((x) & 0x3) << 10) -# define ADDR_SURF_2_BANK 0 -# define ADDR_SURF_4_BANK 1 -# define ADDR_SURF_8_BANK 2 -# define ADDR_SURF_16_BANK 3 -# define CB_BANK_WIDTH(x) (((x) & 0x3) << 13) -# define ADDR_SURF_BANK_WIDTH_1 0 -# define ADDR_SURF_BANK_WIDTH_2 1 -# define ADDR_SURF_BANK_WIDTH_4 2 -# define ADDR_SURF_BANK_WIDTH_8 3 -# define CB_BANK_HEIGHT(x) (((x) & 0x3) << 16) -# define ADDR_SURF_BANK_HEIGHT_1 0 -# define ADDR_SURF_BANK_HEIGHT_2 1 -# define ADDR_SURF_BANK_HEIGHT_4 2 -# define ADDR_SURF_BANK_HEIGHT_8 3 -# define CB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19) -#define CB_COLOR0_DIM 0x28c78 -/* only CB0-7 blocks have these regs */ -#define CB_COLOR0_CMASK 0x28c7c -#define CB_COLOR0_CMASK_SLICE 0x28c80 -#define CB_COLOR0_FMASK 0x28c84 -#define CB_COLOR0_FMASK_SLICE 0x28c88 -#define CB_COLOR0_CLEAR_WORD0 0x28c8c -#define CB_COLOR0_CLEAR_WORD1 0x28c90 -#define CB_COLOR0_CLEAR_WORD2 0x28c94 -#define CB_COLOR0_CLEAR_WORD3 0x28c98 - -#define CB_COLOR1_BASE 0x28c9c -#define CB_COLOR2_BASE 0x28cd8 -#define CB_COLOR3_BASE 0x28d14 -#define CB_COLOR4_BASE 0x28d50 -#define CB_COLOR5_BASE 0x28d8c -#define CB_COLOR6_BASE 0x28dc8 -#define CB_COLOR7_BASE 0x28e04 -#define CB_COLOR8_BASE 0x28e40 -#define CB_COLOR9_BASE 0x28e5c -#define CB_COLOR10_BASE 0x28e78 -#define CB_COLOR11_BASE 0x28e94 - -#define CB_COLOR1_PITCH 0x28ca0 -#define CB_COLOR2_PITCH 0x28cdc -#define CB_COLOR3_PITCH 0x28d18 -#define CB_COLOR4_PITCH 0x28d54 -#define CB_COLOR5_PITCH 0x28d90 -#define CB_COLOR6_PITCH 0x28dcc -#define CB_COLOR7_PITCH 0x28e08 -#define CB_COLOR8_PITCH 0x28e44 -#define CB_COLOR9_PITCH 0x28e60 -#define CB_COLOR10_PITCH 0x28e7c -#define CB_COLOR11_PITCH 0x28e98 - -#define CB_COLOR1_SLICE 0x28ca4 -#define CB_COLOR2_SLICE 0x28ce0 -#define CB_COLOR3_SLICE 0x28d1c -#define CB_COLOR4_SLICE 0x28d58 -#define CB_COLOR5_SLICE 0x28d94 -#define CB_COLOR6_SLICE 0x28dd0 -#define CB_COLOR7_SLICE 0x28e0c -#define CB_COLOR8_SLICE 0x28e48 -#define CB_COLOR9_SLICE 0x28e64 -#define CB_COLOR10_SLICE 0x28e80 -#define CB_COLOR11_SLICE 0x28e9c - -#define CB_COLOR1_VIEW 0x28ca8 -#define CB_COLOR2_VIEW 0x28ce4 -#define CB_COLOR3_VIEW 0x28d20 -#define CB_COLOR4_VIEW 0x28d5c -#define CB_COLOR5_VIEW 0x28d98 -#define CB_COLOR6_VIEW 0x28dd4 -#define CB_COLOR7_VIEW 0x28e10 -#define CB_COLOR8_VIEW 0x28e4c -#define CB_COLOR9_VIEW 0x28e68 -#define CB_COLOR10_VIEW 0x28e84 -#define CB_COLOR11_VIEW 0x28ea0 - -#define CB_COLOR1_INFO 0x28cac -#define CB_COLOR2_INFO 0x28ce8 -#define CB_COLOR3_INFO 0x28d24 -#define CB_COLOR4_INFO 0x28d60 -#define CB_COLOR5_INFO 0x28d9c -#define CB_COLOR6_INFO 0x28dd8 -#define CB_COLOR7_INFO 0x28e14 -#define CB_COLOR8_INFO 0x28e50 -#define CB_COLOR9_INFO 0x28e6c -#define CB_COLOR10_INFO 0x28e88 -#define CB_COLOR11_INFO 0x28ea4 - -#define CB_COLOR1_ATTRIB 0x28cb0 -#define CB_COLOR2_ATTRIB 0x28cec -#define CB_COLOR3_ATTRIB 0x28d28 -#define CB_COLOR4_ATTRIB 0x28d64 -#define CB_COLOR5_ATTRIB 0x28da0 -#define CB_COLOR6_ATTRIB 0x28ddc -#define CB_COLOR7_ATTRIB 0x28e18 -#define CB_COLOR8_ATTRIB 0x28e54 -#define CB_COLOR9_ATTRIB 0x28e70 -#define CB_COLOR10_ATTRIB 0x28e8c -#define CB_COLOR11_ATTRIB 0x28ea8 - -#define CB_COLOR1_DIM 0x28cb4 -#define CB_COLOR2_DIM 0x28cf0 -#define CB_COLOR3_DIM 0x28d2c -#define CB_COLOR4_DIM 0x28d68 -#define CB_COLOR5_DIM 0x28da4 -#define CB_COLOR6_DIM 0x28de0 -#define CB_COLOR7_DIM 0x28e1c -#define CB_COLOR8_DIM 0x28e58 -#define CB_COLOR9_DIM 0x28e74 -#define CB_COLOR10_DIM 0x28e90 -#define CB_COLOR11_DIM 0x28eac - -#define CB_COLOR1_CMASK 0x28cb8 -#define CB_COLOR2_CMASK 0x28cf4 -#define CB_COLOR3_CMASK 0x28d30 -#define CB_COLOR4_CMASK 0x28d6c -#define CB_COLOR5_CMASK 0x28da8 -#define CB_COLOR6_CMASK 0x28de4 -#define CB_COLOR7_CMASK 0x28e20 - -#define CB_COLOR1_CMASK_SLICE 0x28cbc -#define CB_COLOR2_CMASK_SLICE 0x28cf8 -#define CB_COLOR3_CMASK_SLICE 0x28d34 -#define CB_COLOR4_CMASK_SLICE 0x28d70 -#define CB_COLOR5_CMASK_SLICE 0x28dac -#define CB_COLOR6_CMASK_SLICE 0x28de8 -#define CB_COLOR7_CMASK_SLICE 0x28e24 - -#define CB_COLOR1_FMASK 0x28cc0 -#define CB_COLOR2_FMASK 0x28cfc -#define CB_COLOR3_FMASK 0x28d38 -#define CB_COLOR4_FMASK 0x28d74 -#define CB_COLOR5_FMASK 0x28db0 -#define CB_COLOR6_FMASK 0x28dec -#define CB_COLOR7_FMASK 0x28e28 - -#define CB_COLOR1_FMASK_SLICE 0x28cc4 -#define CB_COLOR2_FMASK_SLICE 0x28d00 -#define CB_COLOR3_FMASK_SLICE 0x28d3c -#define CB_COLOR4_FMASK_SLICE 0x28d78 -#define CB_COLOR5_FMASK_SLICE 0x28db4 -#define CB_COLOR6_FMASK_SLICE 0x28df0 -#define CB_COLOR7_FMASK_SLICE 0x28e2c - -#define CB_COLOR1_CLEAR_WORD0 0x28cc8 -#define CB_COLOR2_CLEAR_WORD0 0x28d04 -#define CB_COLOR3_CLEAR_WORD0 0x28d40 -#define CB_COLOR4_CLEAR_WORD0 0x28d7c -#define CB_COLOR5_CLEAR_WORD0 0x28db8 -#define CB_COLOR6_CLEAR_WORD0 0x28df4 -#define CB_COLOR7_CLEAR_WORD0 0x28e30 - -#define CB_COLOR1_CLEAR_WORD1 0x28ccc -#define CB_COLOR2_CLEAR_WORD1 0x28d08 -#define CB_COLOR3_CLEAR_WORD1 0x28d44 -#define CB_COLOR4_CLEAR_WORD1 0x28d80 -#define CB_COLOR5_CLEAR_WORD1 0x28dbc -#define CB_COLOR6_CLEAR_WORD1 0x28df8 -#define CB_COLOR7_CLEAR_WORD1 0x28e34 - -#define CB_COLOR1_CLEAR_WORD2 0x28cd0 -#define CB_COLOR2_CLEAR_WORD2 0x28d0c -#define CB_COLOR3_CLEAR_WORD2 0x28d48 -#define CB_COLOR4_CLEAR_WORD2 0x28d84 -#define CB_COLOR5_CLEAR_WORD2 0x28dc0 -#define CB_COLOR6_CLEAR_WORD2 0x28dfc -#define CB_COLOR7_CLEAR_WORD2 0x28e38 - -#define CB_COLOR1_CLEAR_WORD3 0x28cd4 -#define CB_COLOR2_CLEAR_WORD3 0x28d10 -#define CB_COLOR3_CLEAR_WORD3 0x28d4c -#define CB_COLOR4_CLEAR_WORD3 0x28d88 -#define CB_COLOR5_CLEAR_WORD3 0x28dc4 -#define CB_COLOR6_CLEAR_WORD3 0x28e00 -#define CB_COLOR7_CLEAR_WORD3 0x28e3c - -#define SQ_TEX_RESOURCE_WORD0_0 0x30000 -# define TEX_DIM(x) ((x) << 0) -# define SQ_TEX_DIM_1D 0 -# define SQ_TEX_DIM_2D 1 -# define SQ_TEX_DIM_3D 2 -# define SQ_TEX_DIM_CUBEMAP 3 -# define SQ_TEX_DIM_1D_ARRAY 4 -# define SQ_TEX_DIM_2D_ARRAY 5 -# define SQ_TEX_DIM_2D_MSAA 6 -# define SQ_TEX_DIM_2D_ARRAY_MSAA 7 -#define SQ_TEX_RESOURCE_WORD1_0 0x30004 -# define TEX_ARRAY_MODE(x) ((x) << 28) -#define SQ_TEX_RESOURCE_WORD2_0 0x30008 -#define SQ_TEX_RESOURCE_WORD3_0 0x3000C -#define SQ_TEX_RESOURCE_WORD4_0 0x30010 -# define TEX_DST_SEL_X(x) ((x) << 16) -# define TEX_DST_SEL_Y(x) ((x) << 19) -# define TEX_DST_SEL_Z(x) ((x) << 22) -# define TEX_DST_SEL_W(x) ((x) << 25) -# define SQ_SEL_X 0 -# define SQ_SEL_Y 1 -# define SQ_SEL_Z 2 -# define SQ_SEL_W 3 -# define SQ_SEL_0 4 -# define SQ_SEL_1 5 -#define SQ_TEX_RESOURCE_WORD5_0 0x30014 -#define SQ_TEX_RESOURCE_WORD6_0 0x30018 -# define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29) -#define SQ_TEX_RESOURCE_WORD7_0 0x3001c -# define MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6) -# define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8) -# define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10) -# define TEX_NUM_BANKS(x) (((x) & 0x3) << 16) -#define R_030000_SQ_TEX_RESOURCE_WORD0_0 0x030000 -#define S_030000_DIM(x) (((x) & 0x7) << 0) -#define G_030000_DIM(x) (((x) >> 0) & 0x7) -#define C_030000_DIM 0xFFFFFFF8 -#define V_030000_SQ_TEX_DIM_1D 0x00000000 -#define V_030000_SQ_TEX_DIM_2D 0x00000001 -#define V_030000_SQ_TEX_DIM_3D 0x00000002 -#define V_030000_SQ_TEX_DIM_CUBEMAP 0x00000003 -#define V_030000_SQ_TEX_DIM_1D_ARRAY 0x00000004 -#define V_030000_SQ_TEX_DIM_2D_ARRAY 0x00000005 -#define V_030000_SQ_TEX_DIM_2D_MSAA 0x00000006 -#define V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 -#define S_030000_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 5) -#define G_030000_NON_DISP_TILING_ORDER(x) (((x) >> 5) & 0x1) -#define C_030000_NON_DISP_TILING_ORDER 0xFFFFFFDF -#define S_030000_PITCH(x) (((x) & 0xFFF) << 6) -#define G_030000_PITCH(x) (((x) >> 6) & 0xFFF) -#define C_030000_PITCH 0xFFFC003F -#define S_030000_TEX_WIDTH(x) (((x) & 0x3FFF) << 18) -#define G_030000_TEX_WIDTH(x) (((x) >> 18) & 0x3FFF) -#define C_030000_TEX_WIDTH 0x0003FFFF -#define R_030004_SQ_TEX_RESOURCE_WORD1_0 0x030004 -#define S_030004_TEX_HEIGHT(x) (((x) & 0x3FFF) << 0) -#define G_030004_TEX_HEIGHT(x) (((x) >> 0) & 0x3FFF) -#define C_030004_TEX_HEIGHT 0xFFFFC000 -#define S_030004_TEX_DEPTH(x) (((x) & 0x1FFF) << 14) -#define G_030004_TEX_DEPTH(x) (((x) >> 14) & 0x1FFF) -#define C_030004_TEX_DEPTH 0xF8003FFF -#define S_030004_ARRAY_MODE(x) (((x) & 0xF) << 28) -#define G_030004_ARRAY_MODE(x) (((x) >> 28) & 0xF) -#define C_030004_ARRAY_MODE 0x0FFFFFFF -#define R_030008_SQ_TEX_RESOURCE_WORD2_0 0x030008 -#define S_030008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_030008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_030008_BASE_ADDRESS 0x00000000 -#define R_03000C_SQ_TEX_RESOURCE_WORD3_0 0x03000C -#define S_03000C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_03000C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_03000C_MIP_ADDRESS 0x00000000 -#define R_030010_SQ_TEX_RESOURCE_WORD4_0 0x030010 -#define S_030010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) -#define G_030010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) -#define C_030010_FORMAT_COMP_X 0xFFFFFFFC -#define V_030010_SQ_FORMAT_COMP_UNSIGNED 0x00000000 -#define V_030010_SQ_FORMAT_COMP_SIGNED 0x00000001 -#define V_030010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002 -#define S_030010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) -#define G_030010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) -#define C_030010_FORMAT_COMP_Y 0xFFFFFFF3 -#define S_030010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) -#define G_030010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) -#define C_030010_FORMAT_COMP_Z 0xFFFFFFCF -#define S_030010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) -#define G_030010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) -#define C_030010_FORMAT_COMP_W 0xFFFFFF3F -#define S_030010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) -#define G_030010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) -#define C_030010_NUM_FORMAT_ALL 0xFFFFFCFF -#define V_030010_SQ_NUM_FORMAT_NORM 0x00000000 -#define V_030010_SQ_NUM_FORMAT_INT 0x00000001 -#define V_030010_SQ_NUM_FORMAT_SCALED 0x00000002 -#define S_030010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) -#define G_030010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) -#define C_030010_SRF_MODE_ALL 0xFFFFFBFF -#define V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 -#define V_030010_SRF_MODE_NO_ZERO 0x00000001 -#define S_030010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) -#define G_030010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) -#define C_030010_FORCE_DEGAMMA 0xFFFFF7FF -#define S_030010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) -#define G_030010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) -#define C_030010_ENDIAN_SWAP 0xFFFFCFFF -#define S_030010_DST_SEL_X(x) (((x) & 0x7) << 16) -#define G_030010_DST_SEL_X(x) (((x) >> 16) & 0x7) -#define C_030010_DST_SEL_X 0xFFF8FFFF -#define V_030010_SQ_SEL_X 0x00000000 -#define V_030010_SQ_SEL_Y 0x00000001 -#define V_030010_SQ_SEL_Z 0x00000002 -#define V_030010_SQ_SEL_W 0x00000003 -#define V_030010_SQ_SEL_0 0x00000004 -#define V_030010_SQ_SEL_1 0x00000005 -#define S_030010_DST_SEL_Y(x) (((x) & 0x7) << 19) -#define G_030010_DST_SEL_Y(x) (((x) >> 19) & 0x7) -#define C_030010_DST_SEL_Y 0xFFC7FFFF -#define S_030010_DST_SEL_Z(x) (((x) & 0x7) << 22) -#define G_030010_DST_SEL_Z(x) (((x) >> 22) & 0x7) -#define C_030010_DST_SEL_Z 0xFE3FFFFF -#define S_030010_DST_SEL_W(x) (((x) & 0x7) << 25) -#define G_030010_DST_SEL_W(x) (((x) >> 25) & 0x7) -#define C_030010_DST_SEL_W 0xF1FFFFFF -#define S_030010_BASE_LEVEL(x) (((x) & 0xF) << 28) -#define G_030010_BASE_LEVEL(x) (((x) >> 28) & 0xF) -#define C_030010_BASE_LEVEL 0x0FFFFFFF -#define R_030014_SQ_TEX_RESOURCE_WORD5_0 0x030014 -#define S_030014_LAST_LEVEL(x) (((x) & 0xF) << 0) -#define G_030014_LAST_LEVEL(x) (((x) >> 0) & 0xF) -#define C_030014_LAST_LEVEL 0xFFFFFFF0 -#define S_030014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) -#define G_030014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) -#define C_030014_BASE_ARRAY 0xFFFE000F -#define S_030014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) -#define G_030014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) -#define C_030014_LAST_ARRAY 0xC001FFFF -#define R_030018_SQ_TEX_RESOURCE_WORD6_0 0x030018 -#define S_030018_MAX_ANISO(x) (((x) & 0x7) << 0) -#define G_030018_MAX_ANISO(x) (((x) >> 0) & 0x7) -#define C_030018_MAX_ANISO 0xFFFFFFF8 -#define S_030018_PERF_MODULATION(x) (((x) & 0x7) << 3) -#define G_030018_PERF_MODULATION(x) (((x) >> 3) & 0x7) -#define C_030018_PERF_MODULATION 0xFFFFFFC7 -#define S_030018_INTERLACED(x) (((x) & 0x1) << 6) -#define G_030018_INTERLACED(x) (((x) >> 6) & 0x1) -#define C_030018_INTERLACED 0xFFFFFFBF -#define S_030018_TILE_SPLIT(x) (((x) & 0x7) << 29) -#define G_030018_TILE_SPLIT(x) (((x) >> 29) & 0x7) -#define R_03001C_SQ_TEX_RESOURCE_WORD7_0 0x03001C -#define S_03001C_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6) -#define G_03001C_MACRO_TILE_ASPECT(x) (((x) >> 6) & 0x3) -#define S_03001C_BANK_WIDTH(x) (((x) & 0x3) << 8) -#define G_03001C_BANK_WIDTH(x) (((x) >> 8) & 0x3) -#define S_03001C_BANK_HEIGHT(x) (((x) & 0x3) << 10) -#define G_03001C_BANK_HEIGHT(x) (((x) >> 10) & 0x3) -#define S_03001C_NUM_BANKS(x) (((x) & 0x3) << 16) -#define G_03001C_NUM_BANKS(x) (((x) >> 16) & 0x3) -#define S_03001C_TYPE(x) (((x) & 0x3) << 30) -#define G_03001C_TYPE(x) (((x) >> 30) & 0x3) -#define C_03001C_TYPE 0x3FFFFFFF -#define V_03001C_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000 -#define V_03001C_SQ_TEX_VTX_INVALID_BUFFER 0x00000001 -#define V_03001C_SQ_TEX_VTX_VALID_TEXTURE 0x00000002 -#define V_03001C_SQ_TEX_VTX_VALID_BUFFER 0x00000003 -#define S_03001C_DATA_FORMAT(x) (((x) & 0x3F) << 0) -#define G_03001C_DATA_FORMAT(x) (((x) >> 0) & 0x3F) -#define C_03001C_DATA_FORMAT 0xFFFFFFC0 - -#define SQ_VTX_CONSTANT_WORD0_0 0x30000 -#define SQ_VTX_CONSTANT_WORD1_0 0x30004 -#define SQ_VTX_CONSTANT_WORD2_0 0x30008 -# define SQ_VTXC_BASE_ADDR_HI(x) ((x) << 0) -# define SQ_VTXC_STRIDE(x) ((x) << 8) -# define SQ_VTXC_ENDIAN_SWAP(x) ((x) << 30) -# define SQ_ENDIAN_NONE 0 -# define SQ_ENDIAN_8IN16 1 -# define SQ_ENDIAN_8IN32 2 -#define SQ_VTX_CONSTANT_WORD3_0 0x3000C -# define SQ_VTCX_SEL_X(x) ((x) << 3) -# define SQ_VTCX_SEL_Y(x) ((x) << 6) -# define SQ_VTCX_SEL_Z(x) ((x) << 9) -# define SQ_VTCX_SEL_W(x) ((x) << 12) -#define SQ_VTX_CONSTANT_WORD4_0 0x30010 -#define SQ_VTX_CONSTANT_WORD5_0 0x30014 -#define SQ_VTX_CONSTANT_WORD6_0 0x30018 -#define SQ_VTX_CONSTANT_WORD7_0 0x3001c - -#define TD_PS_BORDER_COLOR_INDEX 0xA400 -#define TD_PS_BORDER_COLOR_RED 0xA404 -#define TD_PS_BORDER_COLOR_GREEN 0xA408 -#define TD_PS_BORDER_COLOR_BLUE 0xA40C -#define TD_PS_BORDER_COLOR_ALPHA 0xA410 -#define TD_VS_BORDER_COLOR_INDEX 0xA414 -#define TD_VS_BORDER_COLOR_RED 0xA418 -#define TD_VS_BORDER_COLOR_GREEN 0xA41C -#define TD_VS_BORDER_COLOR_BLUE 0xA420 -#define TD_VS_BORDER_COLOR_ALPHA 0xA424 -#define TD_GS_BORDER_COLOR_INDEX 0xA428 -#define TD_GS_BORDER_COLOR_RED 0xA42C -#define TD_GS_BORDER_COLOR_GREEN 0xA430 -#define TD_GS_BORDER_COLOR_BLUE 0xA434 -#define TD_GS_BORDER_COLOR_ALPHA 0xA438 -#define TD_HS_BORDER_COLOR_INDEX 0xA43C -#define TD_HS_BORDER_COLOR_RED 0xA440 -#define TD_HS_BORDER_COLOR_GREEN 0xA444 -#define TD_HS_BORDER_COLOR_BLUE 0xA448 -#define TD_HS_BORDER_COLOR_ALPHA 0xA44C -#define TD_LS_BORDER_COLOR_INDEX 0xA450 -#define TD_LS_BORDER_COLOR_RED 0xA454 -#define TD_LS_BORDER_COLOR_GREEN 0xA458 -#define TD_LS_BORDER_COLOR_BLUE 0xA45C -#define TD_LS_BORDER_COLOR_ALPHA 0xA460 -#define TD_CS_BORDER_COLOR_INDEX 0xA464 -#define TD_CS_BORDER_COLOR_RED 0xA468 -#define TD_CS_BORDER_COLOR_GREEN 0xA46C -#define TD_CS_BORDER_COLOR_BLUE 0xA470 -#define TD_CS_BORDER_COLOR_ALPHA 0xA474 - -/* cayman 3D regs */ -#define CAYMAN_VGT_OFFCHIP_LDS_BASE 0x89B4 -#define CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS 0x8E48 -#define CAYMAN_DB_EQAA 0x28804 -#define CAYMAN_DB_DEPTH_INFO 0x2803C -#define CAYMAN_PA_SC_AA_CONFIG 0x28BE0 -#define CAYMAN_MSAA_NUM_SAMPLES_SHIFT 0 -#define CAYMAN_MSAA_NUM_SAMPLES_MASK 0x7 -#define CAYMAN_SX_SCATTER_EXPORT_BASE 0x28358 -/* cayman packet3 addition */ -#define CAYMAN_PACKET3_DEALLOC_STATE 0x14 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/mkregtable.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/mkregtable.c deleted file mode 100644 index 5a82b6b7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/mkregtable.c +++ /dev/null @@ -1,725 +0,0 @@ -/* utility to create the register check tables - * this includes inlined list.h safe for userspace. - * - * Copyright 2009 Jerome Glisse - * Copyright 2009 Red Hat Inc. - * - * Authors: - * Jerome Glisse - * Dave Airlie - */ - -#include -#include -#include -#include -#include -#include - -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof(((type *)0)->member)*__mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type, member)); }) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -#ifndef CONFIG_DEBUG_LIST -static inline void __list_add(struct list_head *new, - struct list_head *prev, struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} -#else -extern void __list_add(struct list_head *new, - struct list_head *prev, struct list_head *next); -#endif - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head *prev, struct list_head *next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -#ifndef CONFIG_DEBUG_LIST -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = (void *)0xDEADBEEF; - entry->prev = (void *)0xBEEFDEAD; -} -#else -extern void list_del(struct list_head *entry); -#endif - -/** - * list_replace - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * If @old was empty, it will be overwritten. - */ -static inline void list_replace(struct list_head *old, struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_replace_init(struct list_head *old, - struct list_head *new) -{ - list_replace(old, new); - INIT_LIST_HEAD(old); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is empty and not being modified - * @head: the list to test - * - * Description: - * tests whether a list is empty _and_ checks that no other CPU might be - * in the process of modifying either member (next or prev) - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -/** - * list_is_singular - tests whether a list has just one entry. - * @head: the list to test. - */ -static inline int list_is_singular(const struct list_head *head) -{ - return !list_empty(head) && (head->next == head->prev); -} - -static inline void __list_cut_position(struct list_head *list, - struct list_head *head, - struct list_head *entry) -{ - struct list_head *new_first = entry->next; - list->next = head->next; - list->next->prev = list; - list->prev = entry; - entry->next = list; - head->next = new_first; - new_first->prev = head; -} - -/** - * list_cut_position - cut a list into two - * @list: a new list to add all removed entries - * @head: a list with entries - * @entry: an entry within head, could be the head itself - * and if so we won't cut the list - * - * This helper moves the initial part of @head, up to and - * including @entry, from @head to @list. You should - * pass on @entry an element you know is on @head. @list - * should be an empty list or a list you do not care about - * losing its data. - * - */ -static inline void list_cut_position(struct list_head *list, - struct list_head *head, - struct list_head *entry) -{ - if (list_empty(head)) - return; - if (list_is_singular(head) && (head->next != entry && head != entry)) - return; - if (entry == head) - INIT_LIST_HEAD(list); - else - __list_cut_position(list, head, entry); -} - -static inline void __list_splice(const struct list_head *list, - struct list_head *prev, struct list_head *next) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - - first->prev = prev; - prev->next = first; - - last->next = next; - next->prev = last; -} - -/** - * list_splice - join two lists, this is designed for stacks - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(const struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head, head->next); -} - -/** - * list_splice_tail - join two lists, each list being a queue - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice_tail(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head->prev, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head, head->next); - INIT_LIST_HEAD(list); - } -} - -/** - * list_splice_tail_init - join two lists and reinitialise the emptied list - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * Each of the lists is a queue. - * The list at @list is reinitialised - */ -static inline void list_splice_tail_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head->prev, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; prefetch(pos->next), pos != (head); \ - pos = pos->next) - -/** - * __list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. - */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ - pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - prefetch(pos->prev), pos != (head); \ - pos = n, n = pos->prev) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - * - * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - continue iteration over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Continue to iterate over list of given type, continuing after - * the current position. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_continue_reverse - iterate backwards from the given point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Start to iterate over list of given type backwards, continuing after - * the current position. - */ -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type from the current point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing from current position. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type from current point, safe against - * removal of list entry. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate backwards over list of given type, safe against removal - * of list entry. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -struct offset { - struct list_head list; - unsigned offset; -}; - -struct table { - struct list_head offsets; - unsigned offset_max; - unsigned nentry; - unsigned *table; - char *gpu_prefix; -}; - -static struct offset *offset_new(unsigned o) -{ - struct offset *offset; - - offset = (struct offset *)malloc(sizeof(struct offset)); - if (offset) { - INIT_LIST_HEAD(&offset->list); - offset->offset = o; - } - return offset; -} - -static void table_offset_add(struct table *t, struct offset *offset) -{ - list_add_tail(&offset->list, &t->offsets); -} - -static void table_init(struct table *t) -{ - INIT_LIST_HEAD(&t->offsets); - t->offset_max = 0; - t->nentry = 0; - t->table = NULL; -} - -static void table_print(struct table *t) -{ - unsigned nlloop, i, j, n, c, id; - - nlloop = (t->nentry + 3) / 4; - c = t->nentry; - printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix, - t->nentry); - for (i = 0, id = 0; i < nlloop; i++) { - n = 4; - if (n > c) - n = c; - c -= n; - for (j = 0; j < n; j++) { - if (j == 0) - printf("\t"); - else - printf(" "); - printf("0x%08X,", t->table[id++]); - } - printf("\n"); - } - printf("};\n"); -} - -static int table_build(struct table *t) -{ - struct offset *offset; - unsigned i, m; - - t->nentry = ((t->offset_max >> 2) + 31) / 32; - t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry); - if (t->table == NULL) - return -1; - memset(t->table, 0xff, sizeof(unsigned) * t->nentry); - list_for_each_entry(offset, &t->offsets, list) { - i = (offset->offset >> 2) / 32; - m = (offset->offset >> 2) & 31; - m = 1 << m; - t->table[i] ^= m; - } - return 0; -} - -static char gpu_name[10]; -static int parser_auth(struct table *t, const char *filename) -{ - FILE *file; - regex_t mask_rex; - regmatch_t match[4]; - char buf[1024]; - size_t end; - int len; - int done = 0; - int r; - unsigned o; - struct offset *offset; - char last_reg_s[10]; - int last_reg; - - if (regcomp - (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) { - fprintf(stderr, "Failed to compile regular expression\n"); - return -1; - } - file = fopen(filename, "r"); - if (file == NULL) { - fprintf(stderr, "Failed to open: %s\n", filename); - return -1; - } - fseek(file, 0, SEEK_END); - end = ftell(file); - fseek(file, 0, SEEK_SET); - - /* get header */ - if (fgets(buf, 1024, file) == NULL) { - fclose(file); - return -1; - } - - /* first line will contain the last register - * and gpu name */ - sscanf(buf, "%s %s", gpu_name, last_reg_s); - t->gpu_prefix = gpu_name; - last_reg = strtol(last_reg_s, NULL, 16); - - do { - if (fgets(buf, 1024, file) == NULL) { - fclose(file); - return -1; - } - len = strlen(buf); - if (ftell(file) == end) - done = 1; - if (len) { - r = regexec(&mask_rex, buf, 4, match, 0); - if (r == REG_NOMATCH) { - } else if (r) { - fprintf(stderr, - "Error matching regular expression %d in %s\n", - r, filename); - fclose(file); - return -1; - } else { - buf[match[0].rm_eo] = 0; - buf[match[1].rm_eo] = 0; - buf[match[2].rm_eo] = 0; - o = strtol(&buf[match[1].rm_so], NULL, 16); - offset = offset_new(o); - table_offset_add(t, offset); - if (o > t->offset_max) - t->offset_max = o; - } - } - } while (!done); - fclose(file); - if (t->offset_max < last_reg) - t->offset_max = last_reg; - return table_build(t); -} - -int main(int argc, char *argv[]) -{ - struct table t; - - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - exit(1); - } - table_init(&t); - if (parser_auth(&t, argv[1])) { - fprintf(stderr, "Failed to parse file %s\n", argv[1]); - return -1; - } - table_print(&t); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/ni.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/ni.c deleted file mode 100644 index ad0a3800..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/ni.c +++ /dev/null @@ -1,1888 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#include -#include -#include -#include -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "radeon_drm.h" -#include "nid.h" -#include "atom.h" -#include "ni_reg.h" -#include "cayman_blit_shaders.h" - -extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); -extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); -extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); -extern void evergreen_mc_program(struct radeon_device *rdev); -extern void evergreen_irq_suspend(struct radeon_device *rdev); -extern int evergreen_mc_init(struct radeon_device *rdev); -extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); -extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); -extern void si_rlc_fini(struct radeon_device *rdev); -extern int si_rlc_init(struct radeon_device *rdev); - -#define EVERGREEN_PFP_UCODE_SIZE 1120 -#define EVERGREEN_PM4_UCODE_SIZE 1376 -#define EVERGREEN_RLC_UCODE_SIZE 768 -#define BTC_MC_UCODE_SIZE 6024 - -#define CAYMAN_PFP_UCODE_SIZE 2176 -#define CAYMAN_PM4_UCODE_SIZE 2176 -#define CAYMAN_RLC_UCODE_SIZE 1024 -#define CAYMAN_MC_UCODE_SIZE 6037 - -#define ARUBA_RLC_UCODE_SIZE 1536 - -/* Firmware Names */ -MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); -MODULE_FIRMWARE("radeon/BARTS_me.bin"); -MODULE_FIRMWARE("radeon/BARTS_mc.bin"); -MODULE_FIRMWARE("radeon/BTC_rlc.bin"); -MODULE_FIRMWARE("radeon/TURKS_pfp.bin"); -MODULE_FIRMWARE("radeon/TURKS_me.bin"); -MODULE_FIRMWARE("radeon/TURKS_mc.bin"); -MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); -MODULE_FIRMWARE("radeon/CAICOS_me.bin"); -MODULE_FIRMWARE("radeon/CAICOS_mc.bin"); -MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin"); -MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); -MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); -MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin"); -MODULE_FIRMWARE("radeon/ARUBA_pfp.bin"); -MODULE_FIRMWARE("radeon/ARUBA_me.bin"); -MODULE_FIRMWARE("radeon/ARUBA_rlc.bin"); - -#define BTC_IO_MC_REGS_SIZE 29 - -static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { - {0x00000077, 0xff010100}, - {0x00000078, 0x00000000}, - {0x00000079, 0x00001434}, - {0x0000007a, 0xcc08ec08}, - {0x0000007b, 0x00040000}, - {0x0000007c, 0x000080c0}, - {0x0000007d, 0x09000000}, - {0x0000007e, 0x00210404}, - {0x00000081, 0x08a8e800}, - {0x00000082, 0x00030444}, - {0x00000083, 0x00000000}, - {0x00000085, 0x00000001}, - {0x00000086, 0x00000002}, - {0x00000087, 0x48490000}, - {0x00000088, 0x20244647}, - {0x00000089, 0x00000005}, - {0x0000008b, 0x66030000}, - {0x0000008c, 0x00006603}, - {0x0000008d, 0x00000100}, - {0x0000008f, 0x00001c0a}, - {0x00000090, 0xff000001}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00946a00} -}; - -static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { - {0x00000077, 0xff010100}, - {0x00000078, 0x00000000}, - {0x00000079, 0x00001434}, - {0x0000007a, 0xcc08ec08}, - {0x0000007b, 0x00040000}, - {0x0000007c, 0x000080c0}, - {0x0000007d, 0x09000000}, - {0x0000007e, 0x00210404}, - {0x00000081, 0x08a8e800}, - {0x00000082, 0x00030444}, - {0x00000083, 0x00000000}, - {0x00000085, 0x00000001}, - {0x00000086, 0x00000002}, - {0x00000087, 0x48490000}, - {0x00000088, 0x20244647}, - {0x00000089, 0x00000005}, - {0x0000008b, 0x66030000}, - {0x0000008c, 0x00006603}, - {0x0000008d, 0x00000100}, - {0x0000008f, 0x00001c0a}, - {0x00000090, 0xff000001}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00936a00} -}; - -static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { - {0x00000077, 0xff010100}, - {0x00000078, 0x00000000}, - {0x00000079, 0x00001434}, - {0x0000007a, 0xcc08ec08}, - {0x0000007b, 0x00040000}, - {0x0000007c, 0x000080c0}, - {0x0000007d, 0x09000000}, - {0x0000007e, 0x00210404}, - {0x00000081, 0x08a8e800}, - {0x00000082, 0x00030444}, - {0x00000083, 0x00000000}, - {0x00000085, 0x00000001}, - {0x00000086, 0x00000002}, - {0x00000087, 0x48490000}, - {0x00000088, 0x20244647}, - {0x00000089, 0x00000005}, - {0x0000008b, 0x66030000}, - {0x0000008c, 0x00006603}, - {0x0000008d, 0x00000100}, - {0x0000008f, 0x00001c0a}, - {0x00000090, 0xff000001}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00916a00} -}; - -static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { - {0x00000077, 0xff010100}, - {0x00000078, 0x00000000}, - {0x00000079, 0x00001434}, - {0x0000007a, 0xcc08ec08}, - {0x0000007b, 0x00040000}, - {0x0000007c, 0x000080c0}, - {0x0000007d, 0x09000000}, - {0x0000007e, 0x00210404}, - {0x00000081, 0x08a8e800}, - {0x00000082, 0x00030444}, - {0x00000083, 0x00000000}, - {0x00000085, 0x00000001}, - {0x00000086, 0x00000002}, - {0x00000087, 0x48490000}, - {0x00000088, 0x20244647}, - {0x00000089, 0x00000005}, - {0x0000008b, 0x66030000}, - {0x0000008c, 0x00006603}, - {0x0000008d, 0x00000100}, - {0x0000008f, 0x00001c0a}, - {0x00000090, 0xff000001}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00976b00} -}; - -int ni_mc_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - u32 mem_type, running, blackout = 0; - u32 *io_mc_regs; - int i, ucode_size, regs_size; - - if (!rdev->mc_fw) - return -EINVAL; - - switch (rdev->family) { - case CHIP_BARTS: - io_mc_regs = (u32 *)&barts_io_mc_regs; - ucode_size = BTC_MC_UCODE_SIZE; - regs_size = BTC_IO_MC_REGS_SIZE; - break; - case CHIP_TURKS: - io_mc_regs = (u32 *)&turks_io_mc_regs; - ucode_size = BTC_MC_UCODE_SIZE; - regs_size = BTC_IO_MC_REGS_SIZE; - break; - case CHIP_CAICOS: - default: - io_mc_regs = (u32 *)&caicos_io_mc_regs; - ucode_size = BTC_MC_UCODE_SIZE; - regs_size = BTC_IO_MC_REGS_SIZE; - break; - case CHIP_CAYMAN: - io_mc_regs = (u32 *)&cayman_io_mc_regs; - ucode_size = CAYMAN_MC_UCODE_SIZE; - regs_size = BTC_IO_MC_REGS_SIZE; - break; - } - - mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT; - running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; - - if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) { - if (running) { - blackout = RREG32(MC_SHARED_BLACKOUT_CNTL); - WREG32(MC_SHARED_BLACKOUT_CNTL, 1); - } - - /* reset the engine and set to writable */ - WREG32(MC_SEQ_SUP_CNTL, 0x00000008); - WREG32(MC_SEQ_SUP_CNTL, 0x00000010); - - /* load mc io regs */ - for (i = 0; i < regs_size; i++) { - WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); - WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); - } - /* load the MC ucode */ - fw_data = (const __be32 *)rdev->mc_fw->data; - for (i = 0; i < ucode_size; i++) - WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); - - /* put the engine back into the active state */ - WREG32(MC_SEQ_SUP_CNTL, 0x00000008); - WREG32(MC_SEQ_SUP_CNTL, 0x00000004); - WREG32(MC_SEQ_SUP_CNTL, 0x00000001); - - /* wait for training to complete */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD) - break; - udelay(1); - } - - if (running) - WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); - } - - return 0; -} - -int ni_init_microcode(struct radeon_device *rdev) -{ - struct platform_device *pdev; - const char *chip_name; - const char *rlc_chip_name; - size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size; - char fw_name[30]; - int err; - - DRM_DEBUG("\n"); - - pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); - err = IS_ERR(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); - return -EINVAL; - } - - switch (rdev->family) { - case CHIP_BARTS: - chip_name = "BARTS"; - rlc_chip_name = "BTC"; - pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; - me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; - rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; - mc_req_size = BTC_MC_UCODE_SIZE * 4; - break; - case CHIP_TURKS: - chip_name = "TURKS"; - rlc_chip_name = "BTC"; - pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; - me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; - rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; - mc_req_size = BTC_MC_UCODE_SIZE * 4; - break; - case CHIP_CAICOS: - chip_name = "CAICOS"; - rlc_chip_name = "BTC"; - pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; - me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; - rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; - mc_req_size = BTC_MC_UCODE_SIZE * 4; - break; - case CHIP_CAYMAN: - chip_name = "CAYMAN"; - rlc_chip_name = "CAYMAN"; - pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; - me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; - rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; - mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; - break; - case CHIP_ARUBA: - chip_name = "ARUBA"; - rlc_chip_name = "ARUBA"; - /* pfp/me same size as CAYMAN */ - pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; - me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; - rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4; - mc_req_size = 0; - break; - default: BUG(); - } - - DRM_INFO("Loading %s Microcode\n", chip_name); - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); - err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->pfp_fw->size != pfp_req_size) { - printk(KERN_ERR - "ni_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->pfp_fw->size, fw_name); - err = -EINVAL; - goto out; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); - err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->me_fw->size != me_req_size) { - printk(KERN_ERR - "ni_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->me_fw->size, fw_name); - err = -EINVAL; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); - err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->rlc_fw->size != rlc_req_size) { - printk(KERN_ERR - "ni_rlc: Bogus length %zu in firmware \"%s\"\n", - rdev->rlc_fw->size, fw_name); - err = -EINVAL; - } - - /* no MC ucode on TN */ - if (!(rdev->flags & RADEON_IS_IGP)) { - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); - err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->mc_fw->size != mc_req_size) { - printk(KERN_ERR - "ni_mc: Bogus length %zu in firmware \"%s\"\n", - rdev->mc_fw->size, fw_name); - err = -EINVAL; - } - } -out: - platform_device_unregister(pdev); - - if (err) { - if (err != -EINVAL) - printk(KERN_ERR - "ni_cp: Failed to load firmware \"%s\"\n", - fw_name); - release_firmware(rdev->pfp_fw); - rdev->pfp_fw = NULL; - release_firmware(rdev->me_fw); - rdev->me_fw = NULL; - release_firmware(rdev->rlc_fw); - rdev->rlc_fw = NULL; - release_firmware(rdev->mc_fw); - rdev->mc_fw = NULL; - } - return err; -} - -/* - * Core functions - */ -static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends_per_asic, - u32 *backend_disable_mask_per_asic, - u32 num_shader_engines) -{ - u32 backend_map = 0; - u32 enabled_backends_mask = 0; - u32 enabled_backends_count = 0; - u32 num_backends_per_se; - u32 cur_pipe; - u32 swizzle_pipe[CAYMAN_MAX_PIPES]; - u32 cur_backend = 0; - u32 i; - bool force_no_swizzle; - - /* force legal values */ - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_tile_pipes > rdev->config.cayman.max_tile_pipes) - num_tile_pipes = rdev->config.cayman.max_tile_pipes; - if (num_shader_engines < 1) - num_shader_engines = 1; - if (num_shader_engines > rdev->config.cayman.max_shader_engines) - num_shader_engines = rdev->config.cayman.max_shader_engines; - if (num_backends_per_asic < num_shader_engines) - num_backends_per_asic = num_shader_engines; - if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines)) - num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines; - - /* make sure we have the same number of backends per se */ - num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines); - /* set up the number of backends per se */ - num_backends_per_se = num_backends_per_asic / num_shader_engines; - if (num_backends_per_se > rdev->config.cayman.max_backends_per_se) { - num_backends_per_se = rdev->config.cayman.max_backends_per_se; - num_backends_per_asic = num_backends_per_se * num_shader_engines; - } - - /* create enable mask and count for enabled backends */ - for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { - if (((*backend_disable_mask_per_asic >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends_per_asic) - break; - } - - /* force the backends mask to match the current number of backends */ - if (enabled_backends_count != num_backends_per_asic) { - u32 this_backend_enabled; - u32 shader_engine; - u32 backend_per_se; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - *backend_disable_mask_per_asic = CAYMAN_MAX_BACKENDS_MASK; - for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { - /* calc the current se */ - shader_engine = i / rdev->config.cayman.max_backends_per_se; - /* calc the backend per se */ - backend_per_se = i % rdev->config.cayman.max_backends_per_se; - /* default to not enabled */ - this_backend_enabled = 0; - if ((shader_engine < num_shader_engines) && - (backend_per_se < num_backends_per_se)) - this_backend_enabled = 1; - if (this_backend_enabled) { - enabled_backends_mask |= (1 << i); - *backend_disable_mask_per_asic &= ~(1 << i); - ++enabled_backends_count; - } - } - } - - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * CAYMAN_MAX_PIPES); - switch (rdev->family) { - case CHIP_CAYMAN: - case CHIP_ARUBA: - force_no_swizzle = true; - break; - default: - force_no_swizzle = false; - break; - } - if (force_no_swizzle) { - bool last_backend_enabled = false; - - force_no_swizzle = false; - for (i = 0; i < CAYMAN_MAX_BACKENDS; ++i) { - if (((enabled_backends_mask >> i) & 1) == 1) { - if (last_backend_enabled) - force_no_swizzle = true; - last_backend_enabled = true; - } else - last_backend_enabled = false; - } - } - - switch (num_tile_pipes) { - case 1: - case 3: - case 5: - case 7: - DRM_ERROR("odd number of pipes!\n"); - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - swizzle_pipe[3] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - } - break; - } - - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % CAYMAN_MAX_BACKENDS; - - backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); - - cur_backend = (cur_backend + 1) % CAYMAN_MAX_BACKENDS; - } - - return backend_map; -} - -static u32 cayman_get_disable_mask_per_asic(struct radeon_device *rdev, - u32 disable_mask_per_se, - u32 max_disable_mask_per_se, - u32 num_shader_engines) -{ - u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se); - u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se; - - if (num_shader_engines == 1) - return disable_mask_per_asic; - else if (num_shader_engines == 2) - return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se); - else - return 0xffffffff; -} - -static void cayman_gpu_init(struct radeon_device *rdev) -{ - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config; - u32 gb_addr_config = 0; - u32 mc_shared_chmap, mc_arb_ramcfg; - u32 gb_backend_map; - u32 cgts_tcc_disable; - u32 sx_debug_1; - u32 smx_dc_ctl0; - u32 gc_user_shader_pipe_config; - u32 gc_user_rb_backend_disable; - u32 cgts_user_tcc_disable; - u32 cgts_sm_ctrl_reg; - u32 hdp_host_path_cntl; - u32 tmp; - int i, j; - - switch (rdev->family) { - case CHIP_CAYMAN: - rdev->config.cayman.max_shader_engines = 2; - rdev->config.cayman.max_pipes_per_simd = 4; - rdev->config.cayman.max_tile_pipes = 8; - rdev->config.cayman.max_simds_per_se = 12; - rdev->config.cayman.max_backends_per_se = 4; - rdev->config.cayman.max_texture_channel_caches = 8; - rdev->config.cayman.max_gprs = 256; - rdev->config.cayman.max_threads = 256; - rdev->config.cayman.max_gs_threads = 32; - rdev->config.cayman.max_stack_entries = 512; - rdev->config.cayman.sx_num_of_sets = 8; - rdev->config.cayman.sx_max_export_size = 256; - rdev->config.cayman.sx_max_export_pos_size = 64; - rdev->config.cayman.sx_max_export_smx_size = 192; - rdev->config.cayman.max_hw_contexts = 8; - rdev->config.cayman.sq_num_cf_insts = 2; - - rdev->config.cayman.sc_prim_fifo_size = 0x100; - rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; - rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_ARUBA: - default: - rdev->config.cayman.max_shader_engines = 1; - rdev->config.cayman.max_pipes_per_simd = 4; - rdev->config.cayman.max_tile_pipes = 2; - if ((rdev->pdev->device == 0x9900) || - (rdev->pdev->device == 0x9901) || - (rdev->pdev->device == 0x9905) || - (rdev->pdev->device == 0x9906) || - (rdev->pdev->device == 0x9907) || - (rdev->pdev->device == 0x9908) || - (rdev->pdev->device == 0x9909) || - (rdev->pdev->device == 0x9910) || - (rdev->pdev->device == 0x9917)) { - rdev->config.cayman.max_simds_per_se = 6; - rdev->config.cayman.max_backends_per_se = 2; - } else if ((rdev->pdev->device == 0x9903) || - (rdev->pdev->device == 0x9904) || - (rdev->pdev->device == 0x990A) || - (rdev->pdev->device == 0x9913) || - (rdev->pdev->device == 0x9918)) { - rdev->config.cayman.max_simds_per_se = 4; - rdev->config.cayman.max_backends_per_se = 2; - } else if ((rdev->pdev->device == 0x9919) || - (rdev->pdev->device == 0x9990) || - (rdev->pdev->device == 0x9991) || - (rdev->pdev->device == 0x9994) || - (rdev->pdev->device == 0x99A0)) { - rdev->config.cayman.max_simds_per_se = 3; - rdev->config.cayman.max_backends_per_se = 1; - } else { - rdev->config.cayman.max_simds_per_se = 2; - rdev->config.cayman.max_backends_per_se = 1; - } - rdev->config.cayman.max_texture_channel_caches = 2; - rdev->config.cayman.max_gprs = 256; - rdev->config.cayman.max_threads = 256; - rdev->config.cayman.max_gs_threads = 32; - rdev->config.cayman.max_stack_entries = 512; - rdev->config.cayman.sx_num_of_sets = 8; - rdev->config.cayman.sx_max_export_size = 256; - rdev->config.cayman.sx_max_export_pos_size = 64; - rdev->config.cayman.sx_max_export_smx_size = 192; - rdev->config.cayman.max_hw_contexts = 8; - rdev->config.cayman.sq_num_cf_insts = 2; - - rdev->config.cayman.sc_prim_fifo_size = 0x40; - rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; - rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; - break; - } - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - - WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - - evergreen_fix_pci_max_read_req_size(rdev); - - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); - mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); - cgts_tcc_disable = 0xffff0000; - for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++) - cgts_tcc_disable &= ~(1 << (16 + i)); - gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); - gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); - cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); - - rdev->config.cayman.num_shader_engines = rdev->config.cayman.max_shader_engines; - tmp = ((~gc_user_shader_pipe_config) & INACTIVE_QD_PIPES_MASK) >> INACTIVE_QD_PIPES_SHIFT; - rdev->config.cayman.num_shader_pipes_per_simd = r600_count_pipe_bits(tmp); - rdev->config.cayman.num_tile_pipes = rdev->config.cayman.max_tile_pipes; - tmp = ((~gc_user_shader_pipe_config) & INACTIVE_SIMDS_MASK) >> INACTIVE_SIMDS_SHIFT; - rdev->config.cayman.num_simds_per_se = r600_count_pipe_bits(tmp); - tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.cayman.num_backends_per_se = r600_count_pipe_bits(tmp); - tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.cayman.backend_disable_mask_per_asic = - cayman_get_disable_mask_per_asic(rdev, tmp, CAYMAN_MAX_BACKENDS_PER_SE_MASK, - rdev->config.cayman.num_shader_engines); - rdev->config.cayman.backend_map = - cayman_get_tile_pipe_to_backend_map(rdev, rdev->config.cayman.num_tile_pipes, - rdev->config.cayman.num_backends_per_se * - rdev->config.cayman.num_shader_engines, - &rdev->config.cayman.backend_disable_mask_per_asic, - rdev->config.cayman.num_shader_engines); - tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT; - rdev->config.cayman.num_texture_channel_caches = r600_count_pipe_bits(tmp); - tmp = (mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT; - rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256; - if (rdev->config.cayman.mem_max_burst_length_bytes > 512) - rdev->config.cayman.mem_max_burst_length_bytes = 512; - tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; - rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; - if (rdev->config.cayman.mem_row_size_in_kb > 4) - rdev->config.cayman.mem_row_size_in_kb = 4; - /* XXX use MC settings? */ - rdev->config.cayman.shader_engine_tile_size = 32; - rdev->config.cayman.num_gpus = 1; - rdev->config.cayman.multi_gpu_tile_size = 64; - - //gb_addr_config = 0x02011003 -#if 0 - gb_addr_config = RREG32(GB_ADDR_CONFIG); -#else - gb_addr_config = 0; - switch (rdev->config.cayman.num_tile_pipes) { - case 1: - default: - gb_addr_config |= NUM_PIPES(0); - break; - case 2: - gb_addr_config |= NUM_PIPES(1); - break; - case 4: - gb_addr_config |= NUM_PIPES(2); - break; - case 8: - gb_addr_config |= NUM_PIPES(3); - break; - } - - tmp = (rdev->config.cayman.mem_max_burst_length_bytes / 256) - 1; - gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp); - gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.cayman.num_shader_engines - 1); - tmp = (rdev->config.cayman.shader_engine_tile_size / 16) - 1; - gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp); - switch (rdev->config.cayman.num_gpus) { - case 1: - default: - gb_addr_config |= NUM_GPUS(0); - break; - case 2: - gb_addr_config |= NUM_GPUS(1); - break; - case 4: - gb_addr_config |= NUM_GPUS(2); - break; - } - switch (rdev->config.cayman.multi_gpu_tile_size) { - case 16: - gb_addr_config |= MULTI_GPU_TILE_SIZE(0); - break; - case 32: - default: - gb_addr_config |= MULTI_GPU_TILE_SIZE(1); - break; - case 64: - gb_addr_config |= MULTI_GPU_TILE_SIZE(2); - break; - case 128: - gb_addr_config |= MULTI_GPU_TILE_SIZE(3); - break; - } - switch (rdev->config.cayman.mem_row_size_in_kb) { - case 1: - default: - gb_addr_config |= ROW_SIZE(0); - break; - case 2: - gb_addr_config |= ROW_SIZE(1); - break; - case 4: - gb_addr_config |= ROW_SIZE(2); - break; - } -#endif - - tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; - rdev->config.cayman.num_tile_pipes = (1 << tmp); - tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; - rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256; - tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT; - rdev->config.cayman.num_shader_engines = tmp + 1; - tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT; - rdev->config.cayman.num_gpus = tmp + 1; - tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT; - rdev->config.cayman.multi_gpu_tile_size = 1 << tmp; - tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; - rdev->config.cayman.mem_row_size_in_kb = 1 << tmp; - - //gb_backend_map = 0x76541032; -#if 0 - gb_backend_map = RREG32(GB_BACKEND_MAP); -#else - gb_backend_map = - cayman_get_tile_pipe_to_backend_map(rdev, rdev->config.cayman.num_tile_pipes, - rdev->config.cayman.num_backends_per_se * - rdev->config.cayman.num_shader_engines, - &rdev->config.cayman.backend_disable_mask_per_asic, - rdev->config.cayman.num_shader_engines); -#endif - /* setup tiling info dword. gb_addr_config is not adequate since it does - * not have bank info, so create a custom tiling dword. - * bits 3:0 num_pipes - * bits 7:4 num_banks - * bits 11:8 group_size - * bits 15:12 row_size - */ - rdev->config.cayman.tile_config = 0; - switch (rdev->config.cayman.num_tile_pipes) { - case 1: - default: - rdev->config.cayman.tile_config |= (0 << 0); - break; - case 2: - rdev->config.cayman.tile_config |= (1 << 0); - break; - case 4: - rdev->config.cayman.tile_config |= (2 << 0); - break; - case 8: - rdev->config.cayman.tile_config |= (3 << 0); - break; - } - - /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ - if (rdev->flags & RADEON_IS_IGP) - rdev->config.cayman.tile_config |= 1 << 4; - else { - if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) - rdev->config.cayman.tile_config |= 1 << 4; - else - rdev->config.cayman.tile_config |= 0 << 4; - } - rdev->config.cayman.tile_config |= - ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; - rdev->config.cayman.tile_config |= - ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; - - rdev->config.cayman.backend_map = gb_backend_map; - WREG32(GB_BACKEND_MAP, gb_backend_map); - WREG32(GB_ADDR_CONFIG, gb_addr_config); - WREG32(DMIF_ADDR_CONFIG, gb_addr_config); - WREG32(HDP_ADDR_CONFIG, gb_addr_config); - - /* primary versions */ - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); - WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable); - - /* user versions */ - WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable); - WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); - - /* reprogram the shader complex */ - cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG); - for (i = 0; i < 16; i++) - WREG32(CGTS_SM_CTRL_REG, OVERRIDE); - WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg); - - /* set HW defaults for 3D engine */ - WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); - - sx_debug_1 = RREG32(SX_DEBUG_1); - sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; - WREG32(SX_DEBUG_1, sx_debug_1); - - smx_dc_ctl0 = RREG32(SMX_DC_CTL0); - smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); - smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets); - WREG32(SMX_DC_CTL0, smx_dc_ctl0); - - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); - - /* need to be explicitly zero-ed */ - WREG32(VGT_OFFCHIP_LDS_BASE, 0); - WREG32(SQ_LSTMP_RING_BASE, 0); - WREG32(SQ_HSTMP_RING_BASE, 0); - WREG32(SQ_ESTMP_RING_BASE, 0); - WREG32(SQ_GSTMP_RING_BASE, 0); - WREG32(SQ_VSTMP_RING_BASE, 0); - WREG32(SQ_PSTMP_RING_BASE, 0); - - WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); - - WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) | - POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) | - SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1))); - - WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) | - SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) | - SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size))); - - - WREG32(VGT_NUM_INSTANCES, 1); - - WREG32(CP_PERFMON_CNTL, 0); - - WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) | - FETCH_FIFO_HIWATER(0x4) | - DONE_FIFO_HIWATER(0xe0) | - ALU_UPDATE_FIFO_HIWATER(0x8))); - - WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4)); - WREG32(SQ_CONFIG, (VC_ENABLE | - EXPORT_SRC_C | - GFX_PRIO(0) | - CS1_PRIO(0) | - CS2_PRIO(1))); - WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE); - - WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | - FORCE_EOV_MAX_REZ_CNT(255))); - - WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) | - AUTO_INVLD_EN(ES_AND_GS_AUTO)); - - WREG32(VGT_GS_VERTEX_REUSE, 16); - WREG32(PA_SC_LINE_STIPPLE_STATE, 0); - - WREG32(CB_PERF_CTR0_SEL_0, 0); - WREG32(CB_PERF_CTR0_SEL_1, 0); - WREG32(CB_PERF_CTR1_SEL_0, 0); - WREG32(CB_PERF_CTR1_SEL_1, 0); - WREG32(CB_PERF_CTR2_SEL_0, 0); - WREG32(CB_PERF_CTR2_SEL_1, 0); - WREG32(CB_PERF_CTR3_SEL_0, 0); - WREG32(CB_PERF_CTR3_SEL_1, 0); - - tmp = RREG32(HDP_MISC_CNTL); - tmp |= HDP_FLUSH_INVALIDATE_CACHE; - WREG32(HDP_MISC_CNTL, tmp); - - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); - - udelay(50); -} - -/* - * GART - */ -void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev) -{ - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - - /* bits 0-7 are the VM contexts0-7 */ - WREG32(VM_INVALIDATE_REQUEST, 1); -} - -int cayman_pcie_gart_enable(struct radeon_device *rdev) -{ - int i, r; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - /* Setup TLB control */ - WREG32(MC_VM_MX_L1_TLB_CNTL, - (0xA << 7) | - ENABLE_L1_TLB | - ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - ENABLE_ADVANCED_DRIVER_MODEL | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7) | - CONTEXT1_IDENTITY_ACCESS_MODE(1)); - WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); - WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | - L2_CACHE_BIGK_FRAGMENT_SIZE(6)); - /* setup context0 */ - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); - WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - WREG32(VM_CONTEXT0_CNTL2, 0); - WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - - WREG32(0x15D4, 0); - WREG32(0x15D8, 0); - WREG32(0x15DC, 0); - - /* empty context1-7 */ - for (i = 1; i < 8; i++) { - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), - rdev->gart.table_addr >> 12); - } - - /* enable context1-7 */ - WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - WREG32(VM_CONTEXT1_CNTL2, 0); - WREG32(VM_CONTEXT1_CNTL, 0); - WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - - cayman_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void cayman_pcie_gart_disable(struct radeon_device *rdev) -{ - /* Disable all tables */ - WREG32(VM_CONTEXT0_CNTL, 0); - WREG32(VM_CONTEXT1_CNTL, 0); - /* Setup TLB control */ - WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7) | - CONTEXT1_IDENTITY_ACCESS_MODE(1)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | - L2_CACHE_BIGK_FRAGMENT_SIZE(6)); - radeon_gart_table_vram_unpin(rdev); -} - -void cayman_pcie_gart_fini(struct radeon_device *rdev) -{ - cayman_pcie_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); - radeon_gart_fini(rdev); -} - -void cayman_cp_int_cntl_setup(struct radeon_device *rdev, - int ring, u32 cp_int_cntl) -{ - u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3; - - WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3)); - WREG32(CP_INT_CNTL, cp_int_cntl); -} - -/* - * CP. - */ -void cayman_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[fence->ring]; - u64 addr = rdev->fence_drv[fence->ring].gpu_addr; - - /* flush read cache over gart for this vmid */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); - radeon_ring_write(ring, 0xFFFFFFFF); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ - /* EVENT_WRITE_EOP - flush caches, send int */ - radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); - radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); - radeon_ring_write(ring, addr & 0xffffffff); - radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); - radeon_ring_write(ring, fence->seq); - radeon_ring_write(ring, 0); -} - -void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -{ - struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; - - /* set to DX10/11 mode */ - radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); - radeon_ring_write(ring, 1); - radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (ib->gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); - radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); - - /* flush read cache over gart for this vmid */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, ib->vm_id); - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); - radeon_ring_write(ring, 0xFFFFFFFF); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ -} - -static void cayman_cp_enable(struct radeon_device *rdev, bool enable) -{ - if (enable) - WREG32(CP_ME_CNTL, 0); - else { - radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); - WREG32(SCRATCH_UMSK, 0); - } -} - -static int cayman_cp_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - int i; - - if (!rdev->me_fw || !rdev->pfp_fw) - return -EINVAL; - - cayman_cp_enable(rdev, false); - - fw_data = (const __be32 *)rdev->pfp_fw->data; - WREG32(CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++) - WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_PFP_UCODE_ADDR, 0); - - fw_data = (const __be32 *)rdev->me_fw->data; - WREG32(CP_ME_RAM_WADDR, 0); - for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++) - WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); - - WREG32(CP_PFP_UCODE_ADDR, 0); - WREG32(CP_ME_RAM_WADDR, 0); - WREG32(CP_ME_RAM_RADDR, 0); - return 0; -} - -static int cayman_cp_start(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r, i; - - r = radeon_ring_lock(rdev, ring, 7); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); - radeon_ring_write(ring, 0x1); - radeon_ring_write(ring, 0x0); - radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1); - radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_unlock_commit(rdev, ring); - - cayman_cp_enable(rdev, true); - - r = radeon_ring_lock(rdev, ring, cayman_default_size + 19); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - - /* setup clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - for (i = 0; i < cayman_default_size; i++) - radeon_ring_write(ring, cayman_default_state[i]); - - radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); - - /* set clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(ring, 0); - - /* SQ_VTX_BASE_VTX_LOC */ - radeon_ring_write(ring, 0xc0026f00); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - radeon_ring_write(ring, 0x00000000); - - /* Clear consts */ - radeon_ring_write(ring, 0xc0036f00); - radeon_ring_write(ring, 0x00000bc4); - radeon_ring_write(ring, 0xffffffff); - radeon_ring_write(ring, 0xffffffff); - radeon_ring_write(ring, 0xffffffff); - - radeon_ring_write(ring, 0xc0026900); - radeon_ring_write(ring, 0x00000316); - radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - radeon_ring_write(ring, 0x00000010); /* */ - - radeon_ring_unlock_commit(rdev, ring); - - /* XXX init other rings */ - - return 0; -} - -static void cayman_cp_fini(struct radeon_device *rdev) -{ - cayman_cp_enable(rdev, false); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); -} - -int cayman_cp_resume(struct radeon_device *rdev) -{ - struct radeon_ring *ring; - u32 tmp; - u32 rb_bufsz; - int r; - - /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ - WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | - SOFT_RESET_PA | - SOFT_RESET_SH | - SOFT_RESET_VGT | - SOFT_RESET_SPI | - SOFT_RESET_SX)); - RREG32(GRBM_SOFT_RESET); - mdelay(15); - WREG32(GRBM_SOFT_RESET, 0); - RREG32(GRBM_SOFT_RESET); - - WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); - - /* Set the write pointer delay */ - WREG32(CP_RB_WPTR_DELAY, 0); - - WREG32(CP_DEBUG, (1 << 27)); - - /* ring 0 - compute and gfx */ - /* Set ring buffer size */ - ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB0_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB0_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); - WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); - WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); - - if (rdev->wb.enabled) - WREG32(SCRATCH_UMSK, 0xff); - else { - tmp |= RB_NO_UPDATE; - WREG32(SCRATCH_UMSK, 0); - } - - mdelay(1); - WREG32(CP_RB0_CNTL, tmp); - - WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB0_RPTR); - - /* ring1 - compute only */ - /* Set ring buffer size */ - ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB1_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB1_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); - WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); - - mdelay(1); - WREG32(CP_RB1_CNTL, tmp); - - WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB1_RPTR); - - /* ring2 - compute only */ - /* Set ring buffer size */ - ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB2_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB2_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); - WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF); - - mdelay(1); - WREG32(CP_RB2_CNTL, tmp); - - WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB2_RPTR); - - /* start the rings */ - cayman_cp_start(rdev); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; - rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; - /* this only test cp0 */ - r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; - return r; - } - - return 0; -} - -bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 srbm_status; - u32 grbm_status; - u32 grbm_status_se0, grbm_status_se1; - struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup; - int r; - - srbm_status = RREG32(SRBM_STATUS); - grbm_status = RREG32(GRBM_STATUS); - grbm_status_se0 = RREG32(GRBM_STATUS_SE0); - grbm_status_se1 = RREG32(GRBM_STATUS_SE1); - if (!(grbm_status & GUI_ACTIVE)) { - r100_gpu_lockup_update(lockup, ring); - return false; - } - /* force CP activities */ - r = radeon_ring_lock(rdev, ring, 2); - if (!r) { - /* PACKET2 NOP */ - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - radeon_ring_unlock_commit(rdev, ring); - } - /* XXX deal with CP0,1,2 */ - ring->rptr = RREG32(ring->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, lockup, ring); -} - -static int cayman_gpu_soft_reset(struct radeon_device *rdev) -{ - struct evergreen_mc_save save; - u32 grbm_reset = 0; - - if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) - return 0; - - dev_info(rdev->dev, "GPU softreset \n"); - dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(GRBM_STATUS)); - dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(GRBM_STATUS_SE0)); - dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(GRBM_STATUS_SE1)); - dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(SRBM_STATUS)); - dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", - RREG32(0x14F8)); - dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", - RREG32(0x14D8)); - dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", - RREG32(0x14FC)); - dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", - RREG32(0x14DC)); - - evergreen_mc_stop(rdev, &save); - if (evergreen_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Disable CP parsing/prefetching */ - WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); - - /* reset all the gfx blocks */ - grbm_reset = (SOFT_RESET_CP | - SOFT_RESET_CB | - SOFT_RESET_DB | - SOFT_RESET_GDS | - SOFT_RESET_PA | - SOFT_RESET_SC | - SOFT_RESET_SPI | - SOFT_RESET_SH | - SOFT_RESET_SX | - SOFT_RESET_TC | - SOFT_RESET_TA | - SOFT_RESET_VGT | - SOFT_RESET_IA); - - dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset); - WREG32(GRBM_SOFT_RESET, grbm_reset); - (void)RREG32(GRBM_SOFT_RESET); - udelay(50); - WREG32(GRBM_SOFT_RESET, 0); - (void)RREG32(GRBM_SOFT_RESET); - /* Wait a little for things to settle down */ - udelay(50); - - dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(GRBM_STATUS)); - dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(GRBM_STATUS_SE0)); - dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(GRBM_STATUS_SE1)); - dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(SRBM_STATUS)); - evergreen_mc_resume(rdev, &save); - return 0; -} - -int cayman_asic_reset(struct radeon_device *rdev) -{ - return cayman_gpu_soft_reset(rdev); -} - -static int cayman_startup(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - - /* enable pcie gen2 link */ - evergreen_pcie_gen2_enable(rdev); - - if (rdev->flags & RADEON_IS_IGP) { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = ni_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - } else { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { - r = ni_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - - r = ni_mc_load_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load MC firmware!\n"); - return r; - } - } - - r = r600_vram_scratch_init(rdev); - if (r) - return r; - - evergreen_mc_program(rdev); - r = cayman_pcie_gart_enable(rdev); - if (r) - return r; - cayman_gpu_init(rdev); - - r = evergreen_blit_init(rdev); - if (r) { - r600_blit_fini(rdev); - rdev->asic->copy.copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } - - /* allocate rlc buffers */ - if (rdev->flags & RADEON_IS_IGP) { - r = si_rlc_init(rdev); - if (r) { - DRM_ERROR("Failed to init rlc BOs!\n"); - return r; - } - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r = r600_irq_init(rdev); - if (r) { - DRM_ERROR("radeon: IH init failed (%d).\n", r); - radeon_irq_kms_fini(rdev); - return r; - } - evergreen_irq_set(rdev); - - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - CP_RB0_RPTR, CP_RB0_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (r) - return r; - r = cayman_cp_load_microcode(rdev); - if (r) - return r; - r = cayman_cp_resume(rdev); - if (r) - return r; - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - r = radeon_vm_manager_start(rdev); - if (r) - return r; - - return 0; -} - -int cayman_resume(struct radeon_device *rdev) -{ - int r; - - /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, - * posting will perform necessary task to bring back GPU into good - * shape. - */ - /* post card */ - atom_asic_init(rdev->mode_info.atom_context); - - rdev->accel_working = true; - r = cayman_startup(rdev); - if (r) { - DRM_ERROR("cayman startup failed on resume\n"); - rdev->accel_working = false; - return r; - } - return r; -} - -int cayman_suspend(struct radeon_device *rdev) -{ - /* FIXME: we should wait for ring to be empty */ - radeon_ib_pool_suspend(rdev); - radeon_vm_manager_suspend(rdev); - r600_blit_suspend(rdev); - cayman_cp_enable(rdev, false); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - evergreen_irq_suspend(rdev); - radeon_wb_disable(rdev); - cayman_pcie_gart_disable(rdev); - return 0; -} - -/* Plan is to move initialization in that function and use - * helper function so that radeon_device_init pretty much - * do nothing more than calling asic specific function. This - * should also allow to remove a bunch of callback function - * like vram_info. - */ -int cayman_init(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - - /* This don't do much */ - r = radeon_gem_init(rdev); - if (r) - return r; - /* Read BIOS */ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); - return -EINVAL; - } - r = radeon_atombios_init(rdev); - if (r) - return r; - - /* Post card if necessary */ - if (!radeon_card_posted(rdev)) { - if (!rdev->bios) { - dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); - return -EINVAL; - } - DRM_INFO("GPU not posted. posting now...\n"); - atom_asic_init(rdev->mode_info.atom_context); - } - /* Initialize scratch registers */ - r600_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - /* initialize memory controller */ - r = evergreen_mc_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - - r = radeon_irq_kms_init(rdev); - if (r) - return r; - - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 1024 * 1024); - - rdev->ih.ring_obj = NULL; - r600_ih_ring_init(rdev, 64 * 1024); - - r = r600_pcie_gart_init(rdev); - if (r) - return r; - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - r = radeon_vm_manager_init(rdev); - if (r) { - dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); - } - - r = cayman_startup(rdev); - if (r) { - dev_err(rdev->dev, "disabling GPU acceleration\n"); - cayman_cp_fini(rdev); - r600_irq_fini(rdev); - if (rdev->flags & RADEON_IS_IGP) - si_rlc_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_vm_manager_fini(rdev); - radeon_irq_kms_fini(rdev); - cayman_pcie_gart_fini(rdev); - rdev->accel_working = false; - } - - /* Don't start up if the MC ucode is missing. - * The default clocks and voltages before the MC ucode - * is loaded are not suffient for advanced operations. - * - * We can skip this check for TN, because there is no MC - * ucode. - */ - if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { - DRM_ERROR("radeon: MC ucode required for NI+.\n"); - return -EINVAL; - } - - return 0; -} - -void cayman_fini(struct radeon_device *rdev) -{ - r600_blit_fini(rdev); - cayman_cp_fini(rdev); - r600_irq_fini(rdev); - if (rdev->flags & RADEON_IS_IGP) - si_rlc_fini(rdev); - radeon_wb_fini(rdev); - radeon_vm_manager_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - cayman_pcie_gart_fini(rdev); - r600_vram_scratch_fini(rdev); - radeon_gem_fini(rdev); - radeon_semaphore_driver_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -/* - * vm - */ -int cayman_vm_init(struct radeon_device *rdev) -{ - /* number of VMs */ - rdev->vm_manager.nvm = 8; - /* base offset of vram pages */ - if (rdev->flags & RADEON_IS_IGP) { - u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET); - tmp <<= 22; - rdev->vm_manager.vram_base_offset = tmp; - } else - rdev->vm_manager.vram_base_offset = 0; - return 0; -} - -void cayman_vm_fini(struct radeon_device *rdev) -{ -} - -int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id) -{ - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (id << 2), 0); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (id << 2), vm->last_pfn); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12); - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - /* bits 0-7 are the VM contexts0-7 */ - WREG32(VM_INVALIDATE_REQUEST, 1 << id); - return 0; -} - -void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) -{ - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0); - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - /* bits 0-7 are the VM contexts0-7 */ - WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); -} - -void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm) -{ - if (vm->id == -1) - return; - - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - /* bits 0-7 are the VM contexts0-7 */ - WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); -} - -#define R600_PTE_VALID (1 << 0) -#define R600_PTE_SYSTEM (1 << 1) -#define R600_PTE_SNOOPED (1 << 2) -#define R600_PTE_READABLE (1 << 5) -#define R600_PTE_WRITEABLE (1 << 6) - -uint32_t cayman_vm_page_flags(struct radeon_device *rdev, - struct radeon_vm *vm, - uint32_t flags) -{ - uint32_t r600_flags = 0; - - r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0; - r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; - r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; - if (flags & RADEON_VM_PAGE_SYSTEM) { - r600_flags |= R600_PTE_SYSTEM; - r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; - } - return r600_flags; -} - -void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, - unsigned pfn, uint64_t addr, uint32_t flags) -{ - void __iomem *ptr = (void *)vm->pt; - - addr = addr & 0xFFFFFFFFFFFFF000ULL; - addr |= flags; - writeq(addr, ptr + (pfn * 8)); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/ni_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/ni_reg.h deleted file mode 100644 index 5db7b7d6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/ni_reg.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#ifndef __NI_REG_H__ -#define __NI_REG_H__ - -/* northern islands - DCE5 */ - -#define NI_INPUT_GAMMA_CONTROL 0x6840 -# define NI_GRPH_INPUT_GAMMA_MODE(x) (((x) & 0x3) << 0) -# define NI_INPUT_GAMMA_USE_LUT 0 -# define NI_INPUT_GAMMA_BYPASS 1 -# define NI_INPUT_GAMMA_SRGB_24 2 -# define NI_INPUT_GAMMA_XVYCC_222 3 -# define NI_OVL_INPUT_GAMMA_MODE(x) (((x) & 0x3) << 4) - -#define NI_PRESCALE_GRPH_CONTROL 0x68b4 -# define NI_GRPH_PRESCALE_BYPASS (1 << 4) - -#define NI_PRESCALE_OVL_CONTROL 0x68c4 -# define NI_OVL_PRESCALE_BYPASS (1 << 4) - -#define NI_INPUT_CSC_CONTROL 0x68d4 -# define NI_INPUT_CSC_GRPH_MODE(x) (((x) & 0x3) << 0) -# define NI_INPUT_CSC_BYPASS 0 -# define NI_INPUT_CSC_PROG_COEFF 1 -# define NI_INPUT_CSC_PROG_SHARED_MATRIXA 2 -# define NI_INPUT_CSC_OVL_MODE(x) (((x) & 0x3) << 4) - -#define NI_OUTPUT_CSC_CONTROL 0x68f0 -# define NI_OUTPUT_CSC_GRPH_MODE(x) (((x) & 0x7) << 0) -# define NI_OUTPUT_CSC_BYPASS 0 -# define NI_OUTPUT_CSC_TV_RGB 1 -# define NI_OUTPUT_CSC_YCBCR_601 2 -# define NI_OUTPUT_CSC_YCBCR_709 3 -# define NI_OUTPUT_CSC_PROG_COEFF 4 -# define NI_OUTPUT_CSC_PROG_SHARED_MATRIXB 5 -# define NI_OUTPUT_CSC_OVL_MODE(x) (((x) & 0x7) << 4) - -#define NI_DEGAMMA_CONTROL 0x6960 -# define NI_GRPH_DEGAMMA_MODE(x) (((x) & 0x3) << 0) -# define NI_DEGAMMA_BYPASS 0 -# define NI_DEGAMMA_SRGB_24 1 -# define NI_DEGAMMA_XVYCC_222 2 -# define NI_OVL_DEGAMMA_MODE(x) (((x) & 0x3) << 4) -# define NI_ICON_DEGAMMA_MODE(x) (((x) & 0x3) << 8) -# define NI_CURSOR_DEGAMMA_MODE(x) (((x) & 0x3) << 12) - -#define NI_GAMUT_REMAP_CONTROL 0x6964 -# define NI_GRPH_GAMUT_REMAP_MODE(x) (((x) & 0x3) << 0) -# define NI_GAMUT_REMAP_BYPASS 0 -# define NI_GAMUT_REMAP_PROG_COEFF 1 -# define NI_GAMUT_REMAP_PROG_SHARED_MATRIXA 2 -# define NI_GAMUT_REMAP_PROG_SHARED_MATRIXB 3 -# define NI_OVL_GAMUT_REMAP_MODE(x) (((x) & 0x3) << 4) - -#define NI_REGAMMA_CONTROL 0x6a80 -# define NI_GRPH_REGAMMA_MODE(x) (((x) & 0x7) << 0) -# define NI_REGAMMA_BYPASS 0 -# define NI_REGAMMA_SRGB_24 1 -# define NI_REGAMMA_XVYCC_222 2 -# define NI_REGAMMA_PROG_A 3 -# define NI_REGAMMA_PROG_B 4 -# define NI_OVL_REGAMMA_MODE(x) (((x) & 0x7) << 4) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/nid.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/nid.h deleted file mode 100644 index 2aa7046a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/nid.h +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#ifndef NI_H -#define NI_H - -#define CAYMAN_MAX_SH_GPRS 256 -#define CAYMAN_MAX_TEMP_GPRS 16 -#define CAYMAN_MAX_SH_THREADS 256 -#define CAYMAN_MAX_SH_STACK_ENTRIES 4096 -#define CAYMAN_MAX_FRC_EOV_CNT 16384 -#define CAYMAN_MAX_BACKENDS 8 -#define CAYMAN_MAX_BACKENDS_MASK 0xFF -#define CAYMAN_MAX_BACKENDS_PER_SE_MASK 0xF -#define CAYMAN_MAX_SIMDS 16 -#define CAYMAN_MAX_SIMDS_MASK 0xFFFF -#define CAYMAN_MAX_SIMDS_PER_SE_MASK 0xFFF -#define CAYMAN_MAX_PIPES 8 -#define CAYMAN_MAX_PIPES_MASK 0xFF -#define CAYMAN_MAX_LDS_NUM 0xFFFF -#define CAYMAN_MAX_TCC 16 -#define CAYMAN_MAX_TCC_MASK 0xFF - -#define DMIF_ADDR_CONFIG 0xBD4 -#define SRBM_GFX_CNTL 0x0E44 -#define RINGID(x) (((x) & 0x3) << 0) -#define VMID(x) (((x) & 0x7) << 0) -#define SRBM_STATUS 0x0E50 - -#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -#define REQUEST_TYPE(x) (((x) & 0xf) << 0) -#define RESPONSE_TYPE_MASK 0x000000F0 -#define RESPONSE_TYPE_SHIFT 4 -#define VM_L2_CNTL 0x1400 -#define ENABLE_L2_CACHE (1 << 0) -#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -#define ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE (1 << 10) -#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14) -#define CONTEXT1_IDENTITY_ACCESS_MODE(x) (((x) & 3) << 18) -/* CONTEXT1_IDENTITY_ACCESS_MODE - * 0 physical = logical - * 1 logical via context1 page table - * 2 inside identity aperture use translation, outside physical = logical - * 3 inside identity aperture physical = logical, outside use translation - */ -#define VM_L2_CNTL2 0x1404 -#define INVALIDATE_ALL_L1_TLBS (1 << 0) -#define INVALIDATE_L2_CACHE (1 << 1) -#define VM_L2_CNTL3 0x1408 -#define BANK_SELECT(x) ((x) << 0) -#define CACHE_UPDATE_MODE(x) ((x) << 6) -#define L2_CACHE_BIGK_ASSOCIATIVITY (1 << 20) -#define L2_CACHE_BIGK_FRAGMENT_SIZE(x) ((x) << 15) -#define VM_L2_STATUS 0x140C -#define L2_BUSY (1 << 0) -#define VM_CONTEXT0_CNTL 0x1410 -#define ENABLE_CONTEXT (1 << 0) -#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -#define VM_CONTEXT1_CNTL 0x1414 -#define VM_CONTEXT0_CNTL2 0x1430 -#define VM_CONTEXT1_CNTL2 0x1434 -#define VM_INVALIDATE_REQUEST 0x1478 -#define VM_INVALIDATE_RESPONSE 0x147c -#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 -#define VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR 0x151c -#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C -#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C -#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C - -#define MC_SHARED_CHMAP 0x2004 -#define NOOFCHAN_SHIFT 12 -#define NOOFCHAN_MASK 0x00003000 -#define MC_SHARED_CHREMAP 0x2008 - -#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C -#define MC_VM_MX_L1_TLB_CNTL 0x2064 -#define ENABLE_L1_TLB (1 << 0) -#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) -#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) -#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) -#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -#define ENABLE_ADVANCED_DRIVER_MODEL (1 << 6) -#define FUS_MC_VM_FB_OFFSET 0x2068 - -#define MC_SHARED_BLACKOUT_CNTL 0x20ac -#define MC_ARB_RAMCFG 0x2760 -#define NOOFBANK_SHIFT 0 -#define NOOFBANK_MASK 0x00000003 -#define NOOFRANK_SHIFT 2 -#define NOOFRANK_MASK 0x00000004 -#define NOOFROWS_SHIFT 3 -#define NOOFROWS_MASK 0x00000038 -#define NOOFCOLS_SHIFT 6 -#define NOOFCOLS_MASK 0x000000C0 -#define CHANSIZE_SHIFT 8 -#define CHANSIZE_MASK 0x00000100 -#define BURSTLENGTH_SHIFT 9 -#define BURSTLENGTH_MASK 0x00000200 -#define CHANSIZE_OVERRIDE (1 << 11) -#define MC_SEQ_SUP_CNTL 0x28c8 -#define RUN_MASK (1 << 0) -#define MC_SEQ_SUP_PGM 0x28cc -#define MC_IO_PAD_CNTL_D0 0x29d0 -#define MEM_FALL_OUT_CMD (1 << 8) -#define MC_SEQ_MISC0 0x2a00 -#define MC_SEQ_MISC0_GDDR5_SHIFT 28 -#define MC_SEQ_MISC0_GDDR5_MASK 0xf0000000 -#define MC_SEQ_MISC0_GDDR5_VALUE 5 -#define MC_SEQ_IO_DEBUG_INDEX 0x2a44 -#define MC_SEQ_IO_DEBUG_DATA 0x2a48 - -#define HDP_HOST_PATH_CNTL 0x2C00 -#define HDP_NONSURFACE_BASE 0x2C04 -#define HDP_NONSURFACE_INFO 0x2C08 -#define HDP_NONSURFACE_SIZE 0x2C0C -#define HDP_ADDR_CONFIG 0x2F48 -#define HDP_MISC_CNTL 0x2F4C -#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) - -#define CC_SYS_RB_BACKEND_DISABLE 0x3F88 -#define GC_USER_SYS_RB_BACKEND_DISABLE 0x3F8C -#define CGTS_SYS_TCC_DISABLE 0x3F90 -#define CGTS_USER_SYS_TCC_DISABLE 0x3F94 - -#define CONFIG_MEMSIZE 0x5428 - -#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 -#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 - -#define GRBM_CNTL 0x8000 -#define GRBM_READ_TIMEOUT(x) ((x) << 0) -#define GRBM_STATUS 0x8010 -#define CMDFIFO_AVAIL_MASK 0x0000000F -#define RING2_RQ_PENDING (1 << 4) -#define SRBM_RQ_PENDING (1 << 5) -#define RING1_RQ_PENDING (1 << 6) -#define CF_RQ_PENDING (1 << 7) -#define PF_RQ_PENDING (1 << 8) -#define GDS_DMA_RQ_PENDING (1 << 9) -#define GRBM_EE_BUSY (1 << 10) -#define SX_CLEAN (1 << 11) -#define DB_CLEAN (1 << 12) -#define CB_CLEAN (1 << 13) -#define TA_BUSY (1 << 14) -#define GDS_BUSY (1 << 15) -#define VGT_BUSY_NO_DMA (1 << 16) -#define VGT_BUSY (1 << 17) -#define IA_BUSY_NO_DMA (1 << 18) -#define IA_BUSY (1 << 19) -#define SX_BUSY (1 << 20) -#define SH_BUSY (1 << 21) -#define SPI_BUSY (1 << 22) -#define SC_BUSY (1 << 24) -#define PA_BUSY (1 << 25) -#define DB_BUSY (1 << 26) -#define CP_COHERENCY_BUSY (1 << 28) -#define CP_BUSY (1 << 29) -#define CB_BUSY (1 << 30) -#define GUI_ACTIVE (1 << 31) -#define GRBM_STATUS_SE0 0x8014 -#define GRBM_STATUS_SE1 0x8018 -#define SE_SX_CLEAN (1 << 0) -#define SE_DB_CLEAN (1 << 1) -#define SE_CB_CLEAN (1 << 2) -#define SE_VGT_BUSY (1 << 23) -#define SE_PA_BUSY (1 << 24) -#define SE_TA_BUSY (1 << 25) -#define SE_SX_BUSY (1 << 26) -#define SE_SPI_BUSY (1 << 27) -#define SE_SH_BUSY (1 << 28) -#define SE_SC_BUSY (1 << 29) -#define SE_DB_BUSY (1 << 30) -#define SE_CB_BUSY (1 << 31) -#define GRBM_SOFT_RESET 0x8020 -#define SOFT_RESET_CP (1 << 0) -#define SOFT_RESET_CB (1 << 1) -#define SOFT_RESET_DB (1 << 3) -#define SOFT_RESET_GDS (1 << 4) -#define SOFT_RESET_PA (1 << 5) -#define SOFT_RESET_SC (1 << 6) -#define SOFT_RESET_SPI (1 << 8) -#define SOFT_RESET_SH (1 << 9) -#define SOFT_RESET_SX (1 << 10) -#define SOFT_RESET_TC (1 << 11) -#define SOFT_RESET_TA (1 << 12) -#define SOFT_RESET_VGT (1 << 14) -#define SOFT_RESET_IA (1 << 15) - -#define SCRATCH_REG0 0x8500 -#define SCRATCH_REG1 0x8504 -#define SCRATCH_REG2 0x8508 -#define SCRATCH_REG3 0x850C -#define SCRATCH_REG4 0x8510 -#define SCRATCH_REG5 0x8514 -#define SCRATCH_REG6 0x8518 -#define SCRATCH_REG7 0x851C -#define SCRATCH_UMSK 0x8540 -#define SCRATCH_ADDR 0x8544 -#define CP_SEM_WAIT_TIMER 0x85BC -#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 -#define CP_COHER_CNTL2 0x85E8 -#define CP_ME_CNTL 0x86D8 -#define CP_ME_HALT (1 << 28) -#define CP_PFP_HALT (1 << 26) -#define CP_RB2_RPTR 0x86f8 -#define CP_RB1_RPTR 0x86fc -#define CP_RB0_RPTR 0x8700 -#define CP_RB_WPTR_DELAY 0x8704 -#define CP_MEQ_THRESHOLDS 0x8764 -#define MEQ1_START(x) ((x) << 0) -#define MEQ2_START(x) ((x) << 8) -#define CP_PERFMON_CNTL 0x87FC - -#define VGT_CACHE_INVALIDATION 0x88C4 -#define CACHE_INVALIDATION(x) ((x) << 0) -#define VC_ONLY 0 -#define TC_ONLY 1 -#define VC_AND_TC 2 -#define AUTO_INVLD_EN(x) ((x) << 6) -#define NO_AUTO 0 -#define ES_AUTO 1 -#define GS_AUTO 2 -#define ES_AND_GS_AUTO 3 -#define VGT_GS_VERTEX_REUSE 0x88D4 - -#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -#define INACTIVE_QD_PIPES(x) ((x) << 8) -#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -#define INACTIVE_QD_PIPES_SHIFT 8 -#define INACTIVE_SIMDS(x) ((x) << 16) -#define INACTIVE_SIMDS_MASK 0xFFFF0000 -#define INACTIVE_SIMDS_SHIFT 16 - -#define VGT_PRIMITIVE_TYPE 0x8958 -#define VGT_NUM_INSTANCES 0x8974 -#define VGT_TF_RING_SIZE 0x8988 -#define VGT_OFFCHIP_LDS_BASE 0x89b4 - -#define PA_SC_LINE_STIPPLE_STATE 0x8B10 -#define PA_CL_ENHANCE 0x8A14 -#define CLIP_VTX_REORDER_ENA (1 << 0) -#define NUM_CLIP_SEQ(x) ((x) << 1) -#define PA_SC_FIFO_SIZE 0x8BCC -#define SC_PRIM_FIFO_SIZE(x) ((x) << 0) -#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) -#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 -#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -#define FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) - -#define SQ_CONFIG 0x8C00 -#define VC_ENABLE (1 << 0) -#define EXPORT_SRC_C (1 << 1) -#define GFX_PRIO(x) ((x) << 2) -#define CS1_PRIO(x) ((x) << 4) -#define CS2_PRIO(x) ((x) << 6) -#define SQ_GPR_RESOURCE_MGMT_1 0x8C04 -#define NUM_PS_GPRS(x) ((x) << 0) -#define NUM_VS_GPRS(x) ((x) << 16) -#define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -#define SQ_ESGS_RING_SIZE 0x8c44 -#define SQ_GSVS_RING_SIZE 0x8c4c -#define SQ_ESTMP_RING_BASE 0x8c50 -#define SQ_ESTMP_RING_SIZE 0x8c54 -#define SQ_GSTMP_RING_BASE 0x8c58 -#define SQ_GSTMP_RING_SIZE 0x8c5c -#define SQ_VSTMP_RING_BASE 0x8c60 -#define SQ_VSTMP_RING_SIZE 0x8c64 -#define SQ_PSTMP_RING_BASE 0x8c68 -#define SQ_PSTMP_RING_SIZE 0x8c6c -#define SQ_MS_FIFO_SIZES 0x8CF0 -#define CACHE_FIFO_SIZE(x) ((x) << 0) -#define FETCH_FIFO_HIWATER(x) ((x) << 8) -#define DONE_FIFO_HIWATER(x) ((x) << 16) -#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -#define SQ_LSTMP_RING_BASE 0x8e10 -#define SQ_LSTMP_RING_SIZE 0x8e14 -#define SQ_HSTMP_RING_BASE 0x8e18 -#define SQ_HSTMP_RING_SIZE 0x8e1c -#define SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 0x8D8C -#define DYN_GPR_ENABLE (1 << 8) -#define SQ_CONST_MEM_BASE 0x8df8 - -#define SX_EXPORT_BUFFER_SIZES 0x900C -#define COLOR_BUFFER_SIZE(x) ((x) << 0) -#define POSITION_BUFFER_SIZE(x) ((x) << 8) -#define SMX_BUFFER_SIZE(x) ((x) << 16) -#define SX_DEBUG_1 0x9058 -#define ENABLE_NEW_SMX_ADDRESS (1 << 16) - -#define SPI_CONFIG_CNTL 0x9100 -#define GPR_WRITE_PRIORITY(x) ((x) << 0) -#define SPI_CONFIG_CNTL_1 0x913C -#define VTX_DONE_DELAY(x) ((x) << 0) -#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -#define CRC_SIMD_ID_WADDR_DISABLE (1 << 8) - -#define CGTS_TCC_DISABLE 0x9148 -#define CGTS_USER_TCC_DISABLE 0x914C -#define TCC_DISABLE_MASK 0xFFFF0000 -#define TCC_DISABLE_SHIFT 16 -#define CGTS_SM_CTRL_REG 0x9150 -#define OVERRIDE (1 << 21) - -#define TA_CNTL_AUX 0x9508 -#define DISABLE_CUBE_WRAP (1 << 0) -#define DISABLE_CUBE_ANISO (1 << 1) - -#define TCP_CHAN_STEER_LO 0x960c -#define TCP_CHAN_STEER_HI 0x9610 - -#define CC_RB_BACKEND_DISABLE 0x98F4 -#define BACKEND_DISABLE(x) ((x) << 16) -#define GB_ADDR_CONFIG 0x98F8 -#define NUM_PIPES(x) ((x) << 0) -#define NUM_PIPES_MASK 0x00000007 -#define NUM_PIPES_SHIFT 0 -#define PIPE_INTERLEAVE_SIZE(x) ((x) << 4) -#define PIPE_INTERLEAVE_SIZE_MASK 0x00000070 -#define PIPE_INTERLEAVE_SIZE_SHIFT 4 -#define BANK_INTERLEAVE_SIZE(x) ((x) << 8) -#define NUM_SHADER_ENGINES(x) ((x) << 12) -#define NUM_SHADER_ENGINES_MASK 0x00003000 -#define NUM_SHADER_ENGINES_SHIFT 12 -#define SHADER_ENGINE_TILE_SIZE(x) ((x) << 16) -#define SHADER_ENGINE_TILE_SIZE_MASK 0x00070000 -#define SHADER_ENGINE_TILE_SIZE_SHIFT 16 -#define NUM_GPUS(x) ((x) << 20) -#define NUM_GPUS_MASK 0x00700000 -#define NUM_GPUS_SHIFT 20 -#define MULTI_GPU_TILE_SIZE(x) ((x) << 24) -#define MULTI_GPU_TILE_SIZE_MASK 0x03000000 -#define MULTI_GPU_TILE_SIZE_SHIFT 24 -#define ROW_SIZE(x) ((x) << 28) -#define ROW_SIZE_MASK 0x30000000 -#define ROW_SIZE_SHIFT 28 -#define NUM_LOWER_PIPES(x) ((x) << 30) -#define NUM_LOWER_PIPES_MASK 0x40000000 -#define NUM_LOWER_PIPES_SHIFT 30 -#define GB_BACKEND_MAP 0x98FC - -#define CB_PERF_CTR0_SEL_0 0x9A20 -#define CB_PERF_CTR0_SEL_1 0x9A24 -#define CB_PERF_CTR1_SEL_0 0x9A28 -#define CB_PERF_CTR1_SEL_1 0x9A2C -#define CB_PERF_CTR2_SEL_0 0x9A30 -#define CB_PERF_CTR2_SEL_1 0x9A34 -#define CB_PERF_CTR3_SEL_0 0x9A38 -#define CB_PERF_CTR3_SEL_1 0x9A3C - -#define GC_USER_RB_BACKEND_DISABLE 0x9B7C -#define BACKEND_DISABLE_MASK 0x00FF0000 -#define BACKEND_DISABLE_SHIFT 16 - -#define SMX_DC_CTL0 0xA020 -#define USE_HASH_FUNCTION (1 << 0) -#define NUMBER_OF_SETS(x) ((x) << 1) -#define FLUSH_ALL_ON_EVENT (1 << 10) -#define STALL_ON_EVENT (1 << 11) -#define SMX_EVENT_CTL 0xA02C -#define ES_FLUSH_CTL(x) ((x) << 0) -#define GS_FLUSH_CTL(x) ((x) << 3) -#define ACK_FLUSH_CTL(x) ((x) << 6) -#define SYNC_FLUSH_CTL (1 << 8) - -#define CP_RB0_BASE 0xC100 -#define CP_RB0_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) -#define BUF_SWAP_32BIT (2 << 16) -#define CP_RB0_RPTR_ADDR 0xC10C -#define CP_RB0_RPTR_ADDR_HI 0xC110 -#define CP_RB0_WPTR 0xC114 - -#define CP_INT_CNTL 0xC124 -# define CNTX_BUSY_INT_ENABLE (1 << 19) -# define CNTX_EMPTY_INT_ENABLE (1 << 20) -# define TIME_STAMP_INT_ENABLE (1 << 26) - -#define CP_RB1_BASE 0xC180 -#define CP_RB1_CNTL 0xC184 -#define CP_RB1_RPTR_ADDR 0xC188 -#define CP_RB1_RPTR_ADDR_HI 0xC18C -#define CP_RB1_WPTR 0xC190 -#define CP_RB2_BASE 0xC194 -#define CP_RB2_CNTL 0xC198 -#define CP_RB2_RPTR_ADDR 0xC19C -#define CP_RB2_RPTR_ADDR_HI 0xC1A0 -#define CP_RB2_WPTR 0xC1A4 -#define CP_PFP_UCODE_ADDR 0xC150 -#define CP_PFP_UCODE_DATA 0xC154 -#define CP_ME_RAM_RADDR 0xC158 -#define CP_ME_RAM_WADDR 0xC15C -#define CP_ME_RAM_DATA 0xC160 -#define CP_DEBUG 0xC1FC - -#define VGT_EVENT_INITIATOR 0x28a90 -# define CACHE_FLUSH_AND_INV_EVENT_TS (0x14 << 0) -# define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) - -/* - * PM4 - */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ - (((reg) >> 2) & 0xFFFF) | \ - ((n) & 0x3FFF) << 16) -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) - -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) - -#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ - (((op) & 0xFF) << 8) | \ - ((n) & 0x3FFF) << 16) - -/* Packet 3 types */ -#define PACKET3_NOP 0x10 -#define PACKET3_SET_BASE 0x11 -#define PACKET3_CLEAR_STATE 0x12 -#define PACKET3_INDEX_BUFFER_SIZE 0x13 -#define PACKET3_DEALLOC_STATE 0x14 -#define PACKET3_DISPATCH_DIRECT 0x15 -#define PACKET3_DISPATCH_INDIRECT 0x16 -#define PACKET3_INDIRECT_BUFFER_END 0x17 -#define PACKET3_MODE_CONTROL 0x18 -#define PACKET3_SET_PREDICATION 0x20 -#define PACKET3_REG_RMW 0x21 -#define PACKET3_COND_EXEC 0x22 -#define PACKET3_PRED_EXEC 0x23 -#define PACKET3_DRAW_INDIRECT 0x24 -#define PACKET3_DRAW_INDEX_INDIRECT 0x25 -#define PACKET3_INDEX_BASE 0x26 -#define PACKET3_DRAW_INDEX_2 0x27 -#define PACKET3_CONTEXT_CONTROL 0x28 -#define PACKET3_DRAW_INDEX_OFFSET 0x29 -#define PACKET3_INDEX_TYPE 0x2A -#define PACKET3_DRAW_INDEX 0x2B -#define PACKET3_DRAW_INDEX_AUTO 0x2D -#define PACKET3_DRAW_INDEX_IMMD 0x2E -#define PACKET3_NUM_INSTANCES 0x2F -#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30 -#define PACKET3_INDIRECT_BUFFER 0x32 -#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 -#define PACKET3_DRAW_INDEX_OFFSET_2 0x35 -#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 -#define PACKET3_WRITE_DATA 0x37 -#define PACKET3_MEM_SEMAPHORE 0x39 -#define PACKET3_MPEG_INDEX 0x3A -#define PACKET3_WAIT_REG_MEM 0x3C -#define PACKET3_MEM_WRITE 0x3D -#define PACKET3_SURFACE_SYNC 0x43 -# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) -# define PACKET3_CB1_DEST_BASE_ENA (1 << 7) -# define PACKET3_CB2_DEST_BASE_ENA (1 << 8) -# define PACKET3_CB3_DEST_BASE_ENA (1 << 9) -# define PACKET3_CB4_DEST_BASE_ENA (1 << 10) -# define PACKET3_CB5_DEST_BASE_ENA (1 << 11) -# define PACKET3_CB6_DEST_BASE_ENA (1 << 12) -# define PACKET3_CB7_DEST_BASE_ENA (1 << 13) -# define PACKET3_DB_DEST_BASE_ENA (1 << 14) -# define PACKET3_CB8_DEST_BASE_ENA (1 << 15) -# define PACKET3_CB9_DEST_BASE_ENA (1 << 16) -# define PACKET3_CB10_DEST_BASE_ENA (1 << 17) -# define PACKET3_CB11_DEST_BASE_ENA (1 << 18) -# define PACKET3_FULL_CACHE_ENA (1 << 20) -# define PACKET3_TC_ACTION_ENA (1 << 23) -# define PACKET3_CB_ACTION_ENA (1 << 25) -# define PACKET3_DB_ACTION_ENA (1 << 26) -# define PACKET3_SH_ACTION_ENA (1 << 27) -# define PACKET3_SX_ACTION_ENA (1 << 28) -#define PACKET3_ME_INITIALIZE 0x44 -#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -#define PACKET3_COND_WRITE 0x45 -#define PACKET3_EVENT_WRITE 0x46 -#define EVENT_TYPE(x) ((x) << 0) -#define EVENT_INDEX(x) ((x) << 8) - /* 0 - any non-TS event - * 1 - ZPASS_DONE - * 2 - SAMPLE_PIPELINESTAT - * 3 - SAMPLE_STREAMOUTSTAT* - * 4 - *S_PARTIAL_FLUSH - * 5 - TS events - */ -#define PACKET3_EVENT_WRITE_EOP 0x47 -#define DATA_SEL(x) ((x) << 29) - /* 0 - discard - * 1 - send low 32bit data - * 2 - send 64bit data - * 3 - send 64bit counter value - */ -#define INT_SEL(x) ((x) << 24) - /* 0 - none - * 1 - interrupt only (DATA_SEL = 0) - * 2 - interrupt when data write is confirmed - */ -#define PACKET3_EVENT_WRITE_EOS 0x48 -#define PACKET3_PREAMBLE_CNTL 0x4A -# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28) -# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28) -#define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C -#define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D -#define PACKET3_ALU_PS_CONST_UPDATE 0x4E -#define PACKET3_ALU_VS_CONST_UPDATE 0x4F -#define PACKET3_ONE_REG_WRITE 0x57 -#define PACKET3_SET_CONFIG_REG 0x68 -#define PACKET3_SET_CONFIG_REG_START 0x00008000 -#define PACKET3_SET_CONFIG_REG_END 0x0000ac00 -#define PACKET3_SET_CONTEXT_REG 0x69 -#define PACKET3_SET_CONTEXT_REG_START 0x00028000 -#define PACKET3_SET_CONTEXT_REG_END 0x00029000 -#define PACKET3_SET_ALU_CONST 0x6A -/* alu const buffers only; no reg file */ -#define PACKET3_SET_BOOL_CONST 0x6B -#define PACKET3_SET_BOOL_CONST_START 0x0003a500 -#define PACKET3_SET_BOOL_CONST_END 0x0003a518 -#define PACKET3_SET_LOOP_CONST 0x6C -#define PACKET3_SET_LOOP_CONST_START 0x0003a200 -#define PACKET3_SET_LOOP_CONST_END 0x0003a500 -#define PACKET3_SET_RESOURCE 0x6D -#define PACKET3_SET_RESOURCE_START 0x00030000 -#define PACKET3_SET_RESOURCE_END 0x00038000 -#define PACKET3_SET_SAMPLER 0x6E -#define PACKET3_SET_SAMPLER_START 0x0003c000 -#define PACKET3_SET_SAMPLER_END 0x0003c600 -#define PACKET3_SET_CTL_CONST 0x6F -#define PACKET3_SET_CTL_CONST_START 0x0003cff0 -#define PACKET3_SET_CTL_CONST_END 0x0003ff0c -#define PACKET3_SET_RESOURCE_OFFSET 0x70 -#define PACKET3_SET_ALU_CONST_VS 0x71 -#define PACKET3_SET_ALU_CONST_DI 0x72 -#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 -#define PACKET3_SET_RESOURCE_INDIRECT 0x74 -#define PACKET3_SET_APPEND_CNT 0x75 - -#endif - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100.c deleted file mode 100644 index fe33d35d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100.c +++ /dev/null @@ -1,4190 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "r100d.h" -#include "rs100d.h" -#include "rv200d.h" -#include "rv250d.h" -#include "atom.h" - -#include -#include -#include - -#include "r100_reg_safe.h" -#include "rn50_reg_safe.h" - -/* Firmware Names */ -#define FIRMWARE_R100 "radeon/R100_cp.bin" -#define FIRMWARE_R200 "radeon/R200_cp.bin" -#define FIRMWARE_R300 "radeon/R300_cp.bin" -#define FIRMWARE_R420 "radeon/R420_cp.bin" -#define FIRMWARE_RS690 "radeon/RS690_cp.bin" -#define FIRMWARE_RS600 "radeon/RS600_cp.bin" -#define FIRMWARE_R520 "radeon/R520_cp.bin" - -MODULE_FIRMWARE(FIRMWARE_R100); -MODULE_FIRMWARE(FIRMWARE_R200); -MODULE_FIRMWARE(FIRMWARE_R300); -MODULE_FIRMWARE(FIRMWARE_R420); -MODULE_FIRMWARE(FIRMWARE_RS690); -MODULE_FIRMWARE(FIRMWARE_RS600); -MODULE_FIRMWARE(FIRMWARE_R520); - -#include "r100_track.h" - -void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - int i; - - if (radeon_crtc->crtc_id == 0) { - if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) { - for (i = 0; i < rdev->usec_timeout; i++) { - if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)) - break; - udelay(1); - } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR) - break; - udelay(1); - } - } - } else { - if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN) { - for (i = 0; i < rdev->usec_timeout; i++) { - if (!(RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)) - break; - udelay(1); - } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR) - break; - udelay(1); - } - } - } -} - -/* This files gather functions specifics to: - * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 - */ - -int r100_reloc_pitch_offset(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, - unsigned reg) -{ - int r; - u32 tile_flags = 0; - u32 tmp; - struct radeon_cs_reloc *reloc; - u32 value; - - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - - value = radeon_get_ib_value(p, idx); - tmp = value & 0x003fffff; - tmp += (((u32)reloc->lobj.gpu_offset) >> 10); - - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_DST_TILE_MACRO; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { - if (reg == RADEON_SRC_PITCH_OFFSET) { - DRM_ERROR("Cannot src blit from microtiled surface\n"); - r100_cs_dump_packet(p, pkt); - return -EINVAL; - } - tile_flags |= RADEON_DST_TILE_MICRO; - } - - tmp |= tile_flags; - p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; - } else - p->ib->ptr[idx] = (value & 0xffc00000) | tmp; - return 0; -} - -int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - int idx) -{ - unsigned c, i; - struct radeon_cs_reloc *reloc; - struct r100_cs_track *track; - int r = 0; - volatile uint32_t *ib; - u32 idx_value; - - ib = p->ib->ptr; - track = (struct r100_cs_track *)p->track; - c = radeon_get_ib_value(p, idx++) & 0x1F; - if (c > 16) { - DRM_ERROR("Only 16 vertex buffers are allowed %d\n", - pkt->opcode); - r100_cs_dump_packet(p, pkt); - return -EINVAL; - } - track->num_arrays = c; - for (i = 0; i < (c - 1); i+=2, idx+=3) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", - pkt->opcode); - r100_cs_dump_packet(p, pkt); - return r; - } - idx_value = radeon_get_ib_value(p, idx); - ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); - - track->arrays[i + 0].esize = idx_value >> 8; - track->arrays[i + 0].robj = reloc->robj; - track->arrays[i + 0].esize &= 0x7F; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", - pkt->opcode); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); - track->arrays[i + 1].robj = reloc->robj; - track->arrays[i + 1].esize = idx_value >> 24; - track->arrays[i + 1].esize &= 0x7F; - } - if (c & 1) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", - pkt->opcode); - r100_cs_dump_packet(p, pkt); - return r; - } - idx_value = radeon_get_ib_value(p, idx); - ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); - track->arrays[i + 0].robj = reloc->robj; - track->arrays[i + 0].esize = idx_value >> 8; - track->arrays[i + 0].esize &= 0x7F; - } - return r; -} - -void r100_pre_page_flip(struct radeon_device *rdev, int crtc) -{ - /* enable the pflip int */ - radeon_irq_kms_pflip_irq_get(rdev, crtc); -} - -void r100_post_page_flip(struct radeon_device *rdev, int crtc) -{ - /* disable the pflip int */ - radeon_irq_kms_pflip_irq_put(rdev, crtc); -} - -u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; - u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; - int i; - - /* Lock the graphics update lock */ - /* update the scanout addresses */ - WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); - - /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) - break; - udelay(1); - } - DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); - - /* Unlock the lock, so double-buffering can take place inside vblank */ - tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK; - WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); - - /* Return current update_pending status: */ - return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET; -} - -void r100_pm_get_dynpm_state(struct radeon_device *rdev) -{ - int i; - rdev->pm.dynpm_can_upclock = true; - rdev->pm.dynpm_can_downclock = true; - - switch (rdev->pm.dynpm_planned_action) { - case DYNPM_ACTION_MINIMUM: - rdev->pm.requested_power_state_index = 0; - rdev->pm.dynpm_can_downclock = false; - break; - case DYNPM_ACTION_DOWNCLOCK: - if (rdev->pm.current_power_state_index == 0) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_downclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = 0; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i >= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index - 1; - } - /* don't use the power state if crtcs are active and no display flag is set */ - if ((rdev->pm.active_crtc_count > 0) && - (rdev->pm.power_state[rdev->pm.requested_power_state_index].clock_info[0].flags & - RADEON_PM_MODE_NO_DISPLAY)) { - rdev->pm.requested_power_state_index++; - } - break; - case DYNPM_ACTION_UPCLOCK: - if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_upclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i <= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index + 1; - } - break; - case DYNPM_ACTION_DEFAULT: - rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.dynpm_can_upclock = false; - break; - case DYNPM_ACTION_NONE: - default: - DRM_ERROR("Requested mode for not defined action\n"); - return; - } - /* only one clock mode per power state */ - rdev->pm.requested_clock_mode_index = 0; - - DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n", - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].sclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].mclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - pcie_lanes); -} - -void r100_pm_init_profile(struct radeon_device *rdev) -{ - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; -} - -void r100_pm_misc(struct radeon_device *rdev) -{ - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - u32 tmp, sclk_cntl, sclk_cntl2, sclk_more_cntl; - - if ((voltage->type == VOLTAGE_GPIO) && (voltage->gpio.valid)) { - if (ps->misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp |= voltage->gpio.mask; - else - tmp &= ~(voltage->gpio.mask); - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } else { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp &= ~voltage->gpio.mask; - else - tmp |= voltage->gpio.mask; - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } - } - - sclk_cntl = RREG32_PLL(SCLK_CNTL); - sclk_cntl2 = RREG32_PLL(SCLK_CNTL2); - sclk_cntl2 &= ~REDUCED_SPEED_SCLK_SEL(3); - sclk_more_cntl = RREG32_PLL(SCLK_MORE_CNTL); - sclk_more_cntl &= ~VOLTAGE_DELAY_SEL(3); - if (ps->misc & ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN) { - sclk_more_cntl |= REDUCED_SPEED_SCLK_EN; - if (ps->misc & ATOM_PM_MISCINFO_DYN_CLK_3D_IDLE) - sclk_cntl2 |= REDUCED_SPEED_SCLK_MODE; - else - sclk_cntl2 &= ~REDUCED_SPEED_SCLK_MODE; - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2) - sclk_cntl2 |= REDUCED_SPEED_SCLK_SEL(0); - else if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4) - sclk_cntl2 |= REDUCED_SPEED_SCLK_SEL(2); - } else - sclk_more_cntl &= ~REDUCED_SPEED_SCLK_EN; - - if (ps->misc & ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN) { - sclk_more_cntl |= IO_CG_VOLTAGE_DROP; - if (voltage->delay) { - sclk_more_cntl |= VOLTAGE_DROP_SYNC; - switch (voltage->delay) { - case 33: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(0); - break; - case 66: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(1); - break; - case 99: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(2); - break; - case 132: - sclk_more_cntl |= VOLTAGE_DELAY_SEL(3); - break; - } - } else - sclk_more_cntl &= ~VOLTAGE_DROP_SYNC; - } else - sclk_more_cntl &= ~IO_CG_VOLTAGE_DROP; - - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN) - sclk_cntl &= ~FORCE_HDP; - else - sclk_cntl |= FORCE_HDP; - - WREG32_PLL(SCLK_CNTL, sclk_cntl); - WREG32_PLL(SCLK_CNTL2, sclk_cntl2); - WREG32_PLL(SCLK_MORE_CNTL, sclk_more_cntl); - - /* set pcie lanes */ - if ((rdev->flags & RADEON_IS_PCIE) && - !(rdev->flags & RADEON_IS_IGP) && - rdev->asic->pm.set_pcie_lanes && - (ps->pcie_lanes != - rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { - radeon_set_pcie_lanes(rdev, - ps->pcie_lanes); - DRM_DEBUG_DRIVER("Setting: p: %d\n", ps->pcie_lanes); - } -} - -void r100_pm_prepare(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* disable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - if (radeon_crtc->crtc_id) { - tmp = RREG32(RADEON_CRTC2_GEN_CNTL); - tmp |= RADEON_CRTC2_DISP_REQ_EN_B; - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); - } else { - tmp = RREG32(RADEON_CRTC_GEN_CNTL); - tmp |= RADEON_CRTC_DISP_REQ_EN_B; - WREG32(RADEON_CRTC_GEN_CNTL, tmp); - } - } - } -} - -void r100_pm_finish(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* enable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - if (radeon_crtc->crtc_id) { - tmp = RREG32(RADEON_CRTC2_GEN_CNTL); - tmp &= ~RADEON_CRTC2_DISP_REQ_EN_B; - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); - } else { - tmp = RREG32(RADEON_CRTC_GEN_CNTL); - tmp &= ~RADEON_CRTC_DISP_REQ_EN_B; - WREG32(RADEON_CRTC_GEN_CNTL, tmp); - } - } - } -} - -bool r100_gui_idle(struct radeon_device *rdev) -{ - if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) - return false; - else - return true; -} - -/* hpd for digital panel detect/disconnect */ -bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) -{ - bool connected = false; - - switch (hpd) { - case RADEON_HPD_1: - if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE) - connected = true; - break; - case RADEON_HPD_2: - if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE) - connected = true; - break; - default: - break; - } - return connected; -} - -void r100_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd) -{ - u32 tmp; - bool connected = r100_hpd_sense(rdev, hpd); - - switch (hpd) { - case RADEON_HPD_1: - tmp = RREG32(RADEON_FP_GEN_CNTL); - if (connected) - tmp &= ~RADEON_FP_DETECT_INT_POL; - else - tmp |= RADEON_FP_DETECT_INT_POL; - WREG32(RADEON_FP_GEN_CNTL, tmp); - break; - case RADEON_HPD_2: - tmp = RREG32(RADEON_FP2_GEN_CNTL); - if (connected) - tmp &= ~RADEON_FP2_DETECT_INT_POL; - else - tmp |= RADEON_FP2_DETECT_INT_POL; - WREG32(RADEON_FP2_GEN_CNTL, tmp); - break; - default: - break; - } -} - -void r100_hpd_init(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - rdev->irq.hpd[0] = true; - break; - case RADEON_HPD_2: - rdev->irq.hpd[1] = true; - break; - default: - break; - } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - } - if (rdev->irq.installed) - r100_irq_set(rdev); -} - -void r100_hpd_fini(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - rdev->irq.hpd[0] = false; - break; - case RADEON_HPD_2: - rdev->irq.hpd[1] = false; - break; - default: - break; - } - } -} - -/* - * PCI GART - */ -void r100_pci_gart_tlb_flush(struct radeon_device *rdev) -{ - /* TODO: can we do somethings here ? */ - /* It seems hw only cache one entry so we should discard this - * entry otherwise if first GPU GART read hit this entry it - * could end up in wrong address. */ -} - -int r100_pci_gart_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.ptr) { - WARN(1, "R100 PCI GART already initialized\n"); - return 0; - } - /* Initialize common gart structure */ - r = radeon_gart_init(rdev); - if (r) - return r; - rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; - rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; - rdev->asic->gart.set_page = &r100_pci_gart_set_page; - return radeon_gart_table_ram_alloc(rdev); -} - -/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ -void r100_enable_bm(struct radeon_device *rdev) -{ - uint32_t tmp; - /* Enable bus mastering */ - tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - WREG32(RADEON_BUS_CNTL, tmp); -} - -int r100_pci_gart_enable(struct radeon_device *rdev) -{ - uint32_t tmp; - - radeon_gart_restore(rdev); - /* discard memory request outside of configured range */ - tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; - WREG32(RADEON_AIC_CNTL, tmp); - /* set address range for PCI address translate */ - WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_start); - WREG32(RADEON_AIC_HI_ADDR, rdev->mc.gtt_end); - /* set PCI GART page-table base address */ - WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); - tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; - WREG32(RADEON_AIC_CNTL, tmp); - r100_pci_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void r100_pci_gart_disable(struct radeon_device *rdev) -{ - uint32_t tmp; - - /* discard memory request outside of configured range */ - tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; - WREG32(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN); - WREG32(RADEON_AIC_LO_ADDR, 0); - WREG32(RADEON_AIC_HI_ADDR, 0); -} - -int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) -{ - u32 *gtt = rdev->gart.ptr; - - if (i < 0 || i > rdev->gart.num_gpu_pages) { - return -EINVAL; - } - gtt[i] = cpu_to_le32(lower_32_bits(addr)); - return 0; -} - -void r100_pci_gart_fini(struct radeon_device *rdev) -{ - radeon_gart_fini(rdev); - r100_pci_gart_disable(rdev); - radeon_gart_table_ram_free(rdev); -} - -int r100_irq_set(struct radeon_device *rdev) -{ - uint32_t tmp = 0; - - if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); - WREG32(R_000040_GEN_INT_CNTL, 0); - return -EINVAL; - } - if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { - tmp |= RADEON_SW_INT_ENABLE; - } - if (rdev->irq.gui_idle) { - tmp |= RADEON_GUI_IDLE_MASK; - } - if (rdev->irq.crtc_vblank_int[0] || - rdev->irq.pflip[0]) { - tmp |= RADEON_CRTC_VBLANK_MASK; - } - if (rdev->irq.crtc_vblank_int[1] || - rdev->irq.pflip[1]) { - tmp |= RADEON_CRTC2_VBLANK_MASK; - } - if (rdev->irq.hpd[0]) { - tmp |= RADEON_FP_DETECT_MASK; - } - if (rdev->irq.hpd[1]) { - tmp |= RADEON_FP2_DETECT_MASK; - } - WREG32(RADEON_GEN_INT_CNTL, tmp); - return 0; -} - -void r100_irq_disable(struct radeon_device *rdev) -{ - u32 tmp; - - WREG32(R_000040_GEN_INT_CNTL, 0); - /* Wait and acknowledge irq */ - mdelay(1); - tmp = RREG32(R_000044_GEN_INT_STATUS); - WREG32(R_000044_GEN_INT_STATUS, tmp); -} - -static uint32_t r100_irq_ack(struct radeon_device *rdev) -{ - uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); - uint32_t irq_mask = RADEON_SW_INT_TEST | - RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | - RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; - - /* the interrupt works, but the status bit is permanently asserted */ - if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { - if (!rdev->irq.gui_idle_acked) - irq_mask |= RADEON_GUI_IDLE_STAT; - } - - if (irqs) { - WREG32(RADEON_GEN_INT_STATUS, irqs); - } - return irqs & irq_mask; -} - -int r100_irq_process(struct radeon_device *rdev) -{ - uint32_t status, msi_rearm; - bool queue_hotplug = false; - - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; - - status = r100_irq_ack(rdev); - if (!status) { - return IRQ_NONE; - } - if (rdev->shutdown) { - return IRQ_NONE; - } - while (status) { - /* SW interrupt */ - if (status & RADEON_SW_INT_TEST) { - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - } - /* gui idle interrupt */ - if (status & RADEON_GUI_IDLE_STAT) { - rdev->irq.gui_idle_acked = true; - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - } - /* Vertical blank interrupts */ - if (status & RADEON_CRTC_VBLANK_STAT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); - } - if (status & RADEON_CRTC2_VBLANK_STAT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); - } - if (status & RADEON_FP_DETECT_STAT) { - queue_hotplug = true; - DRM_DEBUG("HPD1\n"); - } - if (status & RADEON_FP2_DETECT_STAT) { - queue_hotplug = true; - DRM_DEBUG("HPD2\n"); - } - status = r100_irq_ack(rdev); - } - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; - if (queue_hotplug) - schedule_work(&rdev->hotplug_work); - if (rdev->msi_enabled) { - switch (rdev->family) { - case CHIP_RS400: - case CHIP_RS480: - msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM; - WREG32(RADEON_AIC_CNTL, msi_rearm); - WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); - break; - default: - WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); - break; - } - } - return IRQ_HANDLED; -} - -u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) -{ - if (crtc == 0) - return RREG32(RADEON_CRTC_CRNT_FRAME); - else - return RREG32(RADEON_CRTC2_CRNT_FRAME); -} - -/* Who ever call radeon_fence_emit should call ring_lock and ask - * for enough space (today caller are ib schedule and buffer move) */ -void r100_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[fence->ring]; - - /* We have to make sure that caches are flushed before - * CPU might read something from VRAM. */ - radeon_ring_write(ring, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, RADEON_RB3D_DC_FLUSH_ALL); - radeon_ring_write(ring, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, RADEON_RB3D_ZC_FLUSH_ALL); - /* Wait until IDLE & CLEAN */ - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(ring, rdev->config.r100.hdp_cntl | - RADEON_HDP_READ_BUFFER_INVALIDATE); - radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(ring, rdev->config.r100.hdp_cntl); - /* Emit fence sequence & fire IRQ */ - radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); - radeon_ring_write(ring, fence->seq); - radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0)); - radeon_ring_write(ring, RADEON_SW_INT_FIRE); -} - -void r100_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -{ - /* Unused on older asics, since we don't have semaphores or multiple rings */ - BUG(); -} - -int r100_copy_blit(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - uint32_t cur_pages; - uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; - uint32_t pitch; - uint32_t stride_pixels; - unsigned ndw; - int num_loops; - int r = 0; - - /* radeon limited to 16k stride */ - stride_bytes &= 0x3fff; - /* radeon pitch is /64 */ - pitch = stride_bytes / 64; - stride_pixels = stride_bytes / 4; - num_loops = DIV_ROUND_UP(num_gpu_pages, 8191); - - /* Ask for enough room for blit + flush + fence */ - ndw = 64 + (10 * num_loops); - r = radeon_ring_lock(rdev, ring, ndw); - if (r) { - DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); - return -EINVAL; - } - while (num_gpu_pages > 0) { - cur_pages = num_gpu_pages; - if (cur_pages > 8191) { - cur_pages = 8191; - } - num_gpu_pages -= cur_pages; - - /* pages are in Y direction - height - page width in X direction - width */ - radeon_ring_write(ring, PACKET3(PACKET3_BITBLT_MULTI, 8)); - radeon_ring_write(ring, - RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_SRC_CLIPPING | - RADEON_GMC_DST_CLIPPING | - RADEON_GMC_BRUSH_NONE | - (RADEON_COLOR_FORMAT_ARGB8888 << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | - RADEON_GMC_WR_MSK_DIS); - radeon_ring_write(ring, (pitch << 22) | (src_offset >> 10)); - radeon_ring_write(ring, (pitch << 22) | (dst_offset >> 10)); - radeon_ring_write(ring, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(ring, num_gpu_pages); - radeon_ring_write(ring, num_gpu_pages); - radeon_ring_write(ring, cur_pages | (stride_pixels << 16)); - } - radeon_ring_write(ring, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, RADEON_RB2D_DC_FLUSH_ALL); - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, - RADEON_WAIT_2D_IDLECLEAN | - RADEON_WAIT_HOST_IDLECLEAN | - RADEON_WAIT_DMA_GUI_IDLE); - if (fence) { - r = radeon_fence_emit(rdev, fence); - } - radeon_ring_unlock_commit(rdev, ring); - return r; -} - -static int r100_cp_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - u32 tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(R_000E40_RBBM_STATUS); - if (!G_000E40_CP_CMDSTRM_BUSY(tmp)) { - return 0; - } - udelay(1); - } - return -1; -} - -void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) -{ - int r; - - r = radeon_ring_lock(rdev, ring, 2); - if (r) { - return; - } - radeon_ring_write(ring, PACKET0(RADEON_ISYNC_CNTL, 0)); - radeon_ring_write(ring, - RADEON_ISYNC_ANY2D_IDLE3D | - RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_unlock_commit(rdev, ring); -} - - -/* Load the microcode for the CP */ -static int r100_cp_init_microcode(struct radeon_device *rdev) -{ - struct platform_device *pdev; - const char *fw_name = NULL; - int err; - - DRM_DEBUG_KMS("\n"); - - pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); - err = IS_ERR(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); - return -EINVAL; - } - if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || - (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || - (rdev->family == CHIP_RS200)) { - DRM_INFO("Loading R100 Microcode\n"); - fw_name = FIRMWARE_R100; - } else if ((rdev->family == CHIP_R200) || - (rdev->family == CHIP_RV250) || - (rdev->family == CHIP_RV280) || - (rdev->family == CHIP_RS300)) { - DRM_INFO("Loading R200 Microcode\n"); - fw_name = FIRMWARE_R200; - } else if ((rdev->family == CHIP_R300) || - (rdev->family == CHIP_R350) || - (rdev->family == CHIP_RV350) || - (rdev->family == CHIP_RV380) || - (rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { - DRM_INFO("Loading R300 Microcode\n"); - fw_name = FIRMWARE_R300; - } else if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { - DRM_INFO("Loading R400 Microcode\n"); - fw_name = FIRMWARE_R420; - } else if ((rdev->family == CHIP_RS690) || - (rdev->family == CHIP_RS740)) { - DRM_INFO("Loading RS690/RS740 Microcode\n"); - fw_name = FIRMWARE_RS690; - } else if (rdev->family == CHIP_RS600) { - DRM_INFO("Loading RS600 Microcode\n"); - fw_name = FIRMWARE_RS600; - } else if ((rdev->family == CHIP_RV515) || - (rdev->family == CHIP_R520) || - (rdev->family == CHIP_RV530) || - (rdev->family == CHIP_R580) || - (rdev->family == CHIP_RV560) || - (rdev->family == CHIP_RV570)) { - DRM_INFO("Loading R500 Microcode\n"); - fw_name = FIRMWARE_R520; - } - - err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); - platform_device_unregister(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", - fw_name); - } else if (rdev->me_fw->size % 8) { - printk(KERN_ERR - "radeon_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->me_fw->size, fw_name); - err = -EINVAL; - release_firmware(rdev->me_fw); - rdev->me_fw = NULL; - } - return err; -} - -static void r100_cp_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - int i, size; - - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } - - if (rdev->me_fw) { - size = rdev->me_fw->size / 4; - fw_data = (const __be32 *)&rdev->me_fw->data[0]; - WREG32(RADEON_CP_ME_RAM_ADDR, 0); - for (i = 0; i < size; i += 2) { - WREG32(RADEON_CP_ME_RAM_DATAH, - be32_to_cpup(&fw_data[i])); - WREG32(RADEON_CP_ME_RAM_DATAL, - be32_to_cpup(&fw_data[i + 1])); - } - } -} - -int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - unsigned rb_bufsz; - unsigned rb_blksz; - unsigned max_fetch; - unsigned pre_write_timer; - unsigned pre_write_limit; - unsigned indirect2_start; - unsigned indirect1_start; - uint32_t tmp; - int r; - - if (r100_debugfs_cp_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for CP !\n"); - } - if (!rdev->me_fw) { - r = r100_cp_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - - /* Align ring size */ - rb_bufsz = drm_order(ring_size / 8); - ring_size = (1 << (rb_bufsz + 1)) * 4; - r100_cp_load_microcode(rdev); - r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, - RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR, - 0, 0x7fffff, RADEON_CP_PACKET2); - if (r) { - return r; - } - /* Each time the cp read 1024 bytes (16 dword/quadword) update - * the rptr copy in system ram */ - rb_blksz = 9; - /* cp will read 128bytes at a time (4 dwords) */ - max_fetch = 1; - ring->align_mask = 16 - 1; - /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ - pre_write_timer = 64; - /* Force CP_RB_WPTR write if written more than one time before the - * delay expire - */ - pre_write_limit = 0; - /* Setup the cp cache like this (cache size is 96 dwords) : - * RING 0 to 15 - * INDIRECT1 16 to 79 - * INDIRECT2 80 to 95 - * So ring cache size is 16dwords (> (2 * max_fetch = 2 * 4dwords)) - * indirect1 cache size is 64dwords (> (2 * max_fetch = 2 * 4dwords)) - * indirect2 cache size is 16dwords (> (2 * max_fetch = 2 * 4dwords)) - * Idea being that most of the gpu cmd will be through indirect1 buffer - * so it gets the bigger cache. - */ - indirect2_start = 80; - indirect1_start = 16; - /* cp setup */ - WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); - tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | - REG_SET(RADEON_RB_BLKSZ, rb_blksz) | - REG_SET(RADEON_MAX_FETCH, max_fetch)); -#ifdef __BIG_ENDIAN - tmp |= RADEON_BUF_SWAP_32BIT; -#endif - WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_NO_UPDATE); - - /* Set ring address */ - DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)ring->gpu_addr); - WREG32(RADEON_CP_RB_BASE, ring->gpu_addr); - /* Force read & write ptr to 0 */ - WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); - WREG32(RADEON_CP_RB_RPTR_WR, 0); - ring->wptr = 0; - WREG32(RADEON_CP_RB_WPTR, ring->wptr); - - /* set the wb address whether it's enabled or not */ - WREG32(R_00070C_CP_RB_RPTR_ADDR, - S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) >> 2)); - WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET); - - if (rdev->wb.enabled) - WREG32(R_000770_SCRATCH_UMSK, 0xff); - else { - tmp |= RADEON_RB_NO_UPDATE; - WREG32(R_000770_SCRATCH_UMSK, 0); - } - - WREG32(RADEON_CP_RB_CNTL, tmp); - udelay(10); - ring->rptr = RREG32(RADEON_CP_RB_RPTR); - /* Set cp mode to bus mastering & enable cp*/ - WREG32(RADEON_CP_CSQ_MODE, - REG_SET(RADEON_INDIRECT2_START, indirect2_start) | - REG_SET(RADEON_INDIRECT1_START, indirect1_start)); - WREG32(RADEON_CP_RB_WPTR_DELAY, 0); - WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); - WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); - radeon_ring_start(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); - if (r) { - DRM_ERROR("radeon: cp isn't working (%d).\n", r); - return r; - } - ring->ready = true; - radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); - return 0; -} - -void r100_cp_fini(struct radeon_device *rdev) -{ - if (r100_cp_wait_for_idle(rdev)) { - DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n"); - } - /* Disable ring */ - r100_cp_disable(rdev); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - DRM_INFO("radeon: cp finalized\n"); -} - -void r100_cp_disable(struct radeon_device *rdev) -{ - /* Disable ring */ - radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - WREG32(RADEON_CP_CSQ_MODE, 0); - WREG32(RADEON_CP_CSQ_CNTL, 0); - WREG32(R_000770_SCRATCH_UMSK, 0); - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } -} - -/* - * CS functions - */ -int r100_cs_parse_packet0(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - const unsigned *auth, unsigned n, - radeon_packet0_check_t check) -{ - unsigned reg; - unsigned i, j, m; - unsigned idx; - int r; - - idx = pkt->idx + 1; - reg = pkt->reg; - /* Check that register fall into register range - * determined by the number of entry (n) in the - * safe register bitmap. - */ - if (pkt->one_reg_wr) { - if ((reg >> 7) > n) { - return -EINVAL; - } - } else { - if (((reg + (pkt->count << 2)) >> 7) > n) { - return -EINVAL; - } - } - for (i = 0; i <= pkt->count; i++, idx++) { - j = (reg >> 7); - m = 1 << ((reg >> 2) & 31); - if (auth[j] & m) { - r = check(p, pkt, idx, reg); - if (r) { - return r; - } - } - if (pkt->one_reg_wr) { - if (!(auth[j] & m)) { - break; - } - } else { - reg += 4; - } - } - return 0; -} - -void r100_cs_dump_packet(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - volatile uint32_t *ib; - unsigned i; - unsigned idx; - - ib = p->ib->ptr; - idx = pkt->idx; - for (i = 0; i <= (pkt->count + 1); i++, idx++) { - DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); - } -} - -/** - * r100_cs_packet_parse() - parse cp packet and point ib index to next packet - * @parser: parser structure holding parsing context. - * @pkt: where to store packet informations - * - * Assume that chunk_ib_index is properly set. Will return -EINVAL - * if packet is bigger than remaining ib size. or if packets is unknown. - **/ -int r100_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx) -{ - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - uint32_t header; - - if (idx >= ib_chunk->length_dw) { - DRM_ERROR("Can not parse packet at %d after CS end %d !\n", - idx, ib_chunk->length_dw); - return -EINVAL; - } - header = radeon_get_ib_value(p, idx); - pkt->idx = idx; - pkt->type = CP_PACKET_GET_TYPE(header); - pkt->count = CP_PACKET_GET_COUNT(header); - switch (pkt->type) { - case PACKET_TYPE0: - pkt->reg = CP_PACKET0_GET_REG(header); - pkt->one_reg_wr = CP_PACKET0_GET_ONE_REG_WR(header); - break; - case PACKET_TYPE3: - pkt->opcode = CP_PACKET3_GET_OPCODE(header); - break; - case PACKET_TYPE2: - pkt->count = -1; - break; - default: - DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); - return -EINVAL; - } - if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { - DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", - pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); - return -EINVAL; - } - return 0; -} - -/** - * r100_cs_packet_next_vline() - parse userspace VLINE packet - * @parser: parser structure holding parsing context. - * - * Userspace sends a special sequence for VLINE waits. - * PACKET0 - VLINE_START_END + value - * PACKET0 - WAIT_UNTIL +_value - * RELOC (P3) - crtc_id in reloc. - * - * This function parses this and relocates the VLINE START END - * and WAIT UNTIL packets to the correct crtc. - * It also detects a switched off crtc and nulls out the - * wait in that case. - */ -int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) -{ - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - struct radeon_cs_packet p3reloc, waitreloc; - int crtc_id; - int r; - uint32_t header, h_idx, reg; - volatile uint32_t *ib; - - ib = p->ib->ptr; - - /* parse the wait until */ - r = r100_cs_packet_parse(p, &waitreloc, p->idx); - if (r) - return r; - - /* check its a wait until and only 1 count */ - if (waitreloc.reg != RADEON_WAIT_UNTIL || - waitreloc.count != 0) { - DRM_ERROR("vline wait had illegal wait until segment\n"); - return -EINVAL; - } - - if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) { - DRM_ERROR("vline wait had illegal wait until\n"); - return -EINVAL; - } - - /* jump over the NOP */ - r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2); - if (r) - return r; - - h_idx = p->idx - 2; - p->idx += waitreloc.count + 2; - p->idx += p3reloc.count + 2; - - header = radeon_get_ib_value(p, h_idx); - crtc_id = radeon_get_ib_value(p, h_idx + 5); - reg = CP_PACKET0_GET_REG(header); - obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_ERROR("cannot find crtc %d\n", crtc_id); - return -EINVAL; - } - crtc = obj_to_crtc(obj); - radeon_crtc = to_radeon_crtc(crtc); - crtc_id = radeon_crtc->crtc_id; - - if (!crtc->enabled) { - /* if the CRTC isn't enabled - we need to nop out the wait until */ - ib[h_idx + 2] = PACKET2(0); - ib[h_idx + 3] = PACKET2(0); - } else if (crtc_id == 1) { - switch (reg) { - case AVIVO_D1MODE_VLINE_START_END: - header &= ~R300_CP_PACKET0_REG_MASK; - header |= AVIVO_D2MODE_VLINE_START_END >> 2; - break; - case RADEON_CRTC_GUI_TRIG_VLINE: - header &= ~R300_CP_PACKET0_REG_MASK; - header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; - break; - default: - DRM_ERROR("unknown crtc reloc\n"); - return -EINVAL; - } - ib[h_idx] = header; - ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; - } - - return 0; -} - -/** - * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 - * @parser: parser structure holding parsing context. - * @data: pointer to relocation data - * @offset_start: starting offset - * @offset_mask: offset mask (to align start offset on) - * @reloc: reloc informations - * - * Check next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_packet p3reloc; - unsigned idx; - int r; - - if (p->chunk_relocs_idx == -1) { - DRM_ERROR("No relocation chunk !\n"); - return -EINVAL; - } - *cs_reloc = NULL; - relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = r100_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return r; - } - p->idx += p3reloc.count + 2; - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - r100_cs_dump_packet(p, &p3reloc); - return -EINVAL; - } - idx = radeon_get_ib_value(p, p3reloc.idx + 1); - if (idx >= relocs_chunk->length_dw) { - DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", - idx, relocs_chunk->length_dw); - r100_cs_dump_packet(p, &p3reloc); - return -EINVAL; - } - /* FIXME: we assume reloc size is 4 dwords */ - *cs_reloc = p->relocs_ptr[(idx / 4)]; - return 0; -} - -static int r100_get_vtx_size(uint32_t vtx_fmt) -{ - int vtx_size; - vtx_size = 2; - /* ordered according to bits in spec */ - if (vtx_fmt & RADEON_SE_VTX_FMT_W0) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR) - vtx_size += 3; - if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC) - vtx_size += 3; - if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_ST0) - vtx_size += 2; - if (vtx_fmt & RADEON_SE_VTX_FMT_ST1) - vtx_size += 2; - if (vtx_fmt & RADEON_SE_VTX_FMT_Q1) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_ST2) - vtx_size += 2; - if (vtx_fmt & RADEON_SE_VTX_FMT_Q2) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_ST3) - vtx_size += 2; - if (vtx_fmt & RADEON_SE_VTX_FMT_Q3) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_Q0) - vtx_size++; - /* blend weight */ - if (vtx_fmt & (0x7 << 15)) - vtx_size += (vtx_fmt >> 15) & 0x7; - if (vtx_fmt & RADEON_SE_VTX_FMT_N0) - vtx_size += 3; - if (vtx_fmt & RADEON_SE_VTX_FMT_XY1) - vtx_size += 2; - if (vtx_fmt & RADEON_SE_VTX_FMT_Z1) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_W1) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_N1) - vtx_size++; - if (vtx_fmt & RADEON_SE_VTX_FMT_Z) - vtx_size++; - return vtx_size; -} - -static int r100_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg) -{ - struct radeon_cs_reloc *reloc; - struct r100_cs_track *track; - volatile uint32_t *ib; - uint32_t tmp; - int r; - int i, face; - u32 tile_flags = 0; - u32 idx_value; - - ib = p->ib->ptr; - track = (struct r100_cs_track *)p->track; - - idx_value = radeon_get_ib_value(p, idx); - - switch (reg) { - case RADEON_CRTC_GUI_TRIG_VLINE: - r = r100_cs_packet_parse_vline(p); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - break; - /* FIXME: only allow PACKET3 blit? easier to check for out of - * range access */ - case RADEON_DST_PITCH_OFFSET: - case RADEON_SRC_PITCH_OFFSET: - r = r100_reloc_pitch_offset(p, pkt, idx, reg); - if (r) - return r; - break; - case RADEON_RB3D_DEPTHOFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->zb.robj = reloc->robj; - track->zb.offset = idx_value; - track->zb_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case RADEON_RB3D_COLOROFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->cb[0].robj = reloc->robj; - track->cb[0].offset = idx_value; - track->cb_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case RADEON_PP_TXOFFSET_0: - case RADEON_PP_TXOFFSET_1: - case RADEON_PP_TXOFFSET_2: - i = (reg - RADEON_PP_TXOFFSET_0) / 24; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_TXO_MACRO_TILE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_TXO_MICRO_TILE_X2; - - tmp = idx_value & ~(0x7 << 2); - tmp |= tile_flags; - ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); - } else - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - track->textures[i].robj = reloc->robj; - track->tex_dirty = true; - break; - case RADEON_PP_CUBIC_OFFSET_T0_0: - case RADEON_PP_CUBIC_OFFSET_T0_1: - case RADEON_PP_CUBIC_OFFSET_T0_2: - case RADEON_PP_CUBIC_OFFSET_T0_3: - case RADEON_PP_CUBIC_OFFSET_T0_4: - i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->textures[0].cube_info[i].offset = idx_value; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - track->textures[0].cube_info[i].robj = reloc->robj; - track->tex_dirty = true; - break; - case RADEON_PP_CUBIC_OFFSET_T1_0: - case RADEON_PP_CUBIC_OFFSET_T1_1: - case RADEON_PP_CUBIC_OFFSET_T1_2: - case RADEON_PP_CUBIC_OFFSET_T1_3: - case RADEON_PP_CUBIC_OFFSET_T1_4: - i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->textures[1].cube_info[i].offset = idx_value; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - track->textures[1].cube_info[i].robj = reloc->robj; - track->tex_dirty = true; - break; - case RADEON_PP_CUBIC_OFFSET_T2_0: - case RADEON_PP_CUBIC_OFFSET_T2_1: - case RADEON_PP_CUBIC_OFFSET_T2_2: - case RADEON_PP_CUBIC_OFFSET_T2_3: - case RADEON_PP_CUBIC_OFFSET_T2_4: - i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->textures[2].cube_info[i].offset = idx_value; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - track->textures[2].cube_info[i].robj = reloc->robj; - track->tex_dirty = true; - break; - case RADEON_RE_WIDTH_HEIGHT: - track->maxy = ((idx_value >> 16) & 0x7FF); - track->cb_dirty = true; - track->zb_dirty = true; - break; - case RADEON_RB3D_COLORPITCH: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; - } else - ib[idx] = idx_value; - - track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; - track->cb_dirty = true; - break; - case RADEON_RB3D_DEPTHPITCH: - track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; - track->zb_dirty = true; - break; - case RADEON_RB3D_CNTL: - switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { - case 7: - case 8: - case 9: - case 11: - case 12: - track->cb[0].cpp = 1; - break; - case 3: - case 4: - case 15: - track->cb[0].cpp = 2; - break; - case 6: - track->cb[0].cpp = 4; - break; - default: - DRM_ERROR("Invalid color buffer format (%d) !\n", - ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); - return -EINVAL; - } - track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); - track->cb_dirty = true; - track->zb_dirty = true; - break; - case RADEON_RB3D_ZSTENCILCNTL: - switch (idx_value & 0xf) { - case 0: - track->zb.cpp = 2; - break; - case 2: - case 3: - case 4: - case 5: - case 9: - case 11: - track->zb.cpp = 4; - break; - default: - break; - } - track->zb_dirty = true; - break; - case RADEON_RB3D_ZPASS_ADDR: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case RADEON_PP_CNTL: - { - uint32_t temp = idx_value >> 4; - for (i = 0; i < track->num_texture; i++) - track->textures[i].enabled = !!(temp & (1 << i)); - track->tex_dirty = true; - } - break; - case RADEON_SE_VF_CNTL: - track->vap_vf_cntl = idx_value; - break; - case RADEON_SE_VTX_FMT: - track->vtx_size = r100_get_vtx_size(idx_value); - break; - case RADEON_PP_TEX_SIZE_0: - case RADEON_PP_TEX_SIZE_1: - case RADEON_PP_TEX_SIZE_2: - i = (reg - RADEON_PP_TEX_SIZE_0) / 8; - track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; - track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; - track->tex_dirty = true; - break; - case RADEON_PP_TEX_PITCH_0: - case RADEON_PP_TEX_PITCH_1: - case RADEON_PP_TEX_PITCH_2: - i = (reg - RADEON_PP_TEX_PITCH_0) / 8; - track->textures[i].pitch = idx_value + 32; - track->tex_dirty = true; - break; - case RADEON_PP_TXFILTER_0: - case RADEON_PP_TXFILTER_1: - case RADEON_PP_TXFILTER_2: - i = (reg - RADEON_PP_TXFILTER_0) / 24; - track->textures[i].num_levels = ((idx_value & RADEON_MAX_MIP_LEVEL_MASK) - >> RADEON_MAX_MIP_LEVEL_SHIFT); - tmp = (idx_value >> 23) & 0x7; - if (tmp == 2 || tmp == 6) - track->textures[i].roundup_w = false; - tmp = (idx_value >> 27) & 0x7; - if (tmp == 2 || tmp == 6) - track->textures[i].roundup_h = false; - track->tex_dirty = true; - break; - case RADEON_PP_TXFORMAT_0: - case RADEON_PP_TXFORMAT_1: - case RADEON_PP_TXFORMAT_2: - i = (reg - RADEON_PP_TXFORMAT_0) / 24; - if (idx_value & RADEON_TXFORMAT_NON_POWER2) { - track->textures[i].use_pitch = 1; - } else { - track->textures[i].use_pitch = 0; - track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); - track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); - } - if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) - track->textures[i].tex_coord_type = 2; - switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { - case RADEON_TXFORMAT_I8: - case RADEON_TXFORMAT_RGB332: - case RADEON_TXFORMAT_Y8: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case RADEON_TXFORMAT_AI88: - case RADEON_TXFORMAT_ARGB1555: - case RADEON_TXFORMAT_RGB565: - case RADEON_TXFORMAT_ARGB4444: - case RADEON_TXFORMAT_VYUY422: - case RADEON_TXFORMAT_YVYU422: - case RADEON_TXFORMAT_SHADOW16: - case RADEON_TXFORMAT_LDUDV655: - case RADEON_TXFORMAT_DUDV88: - track->textures[i].cpp = 2; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case RADEON_TXFORMAT_ARGB8888: - case RADEON_TXFORMAT_RGBA8888: - case RADEON_TXFORMAT_SHADOW32: - case RADEON_TXFORMAT_LDUDUV8888: - track->textures[i].cpp = 4; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case RADEON_TXFORMAT_DXT1: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_DXT1; - break; - case RADEON_TXFORMAT_DXT23: - case RADEON_TXFORMAT_DXT45: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_DXT35; - break; - } - track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); - track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); - track->tex_dirty = true; - break; - case RADEON_PP_CUBIC_FACES_0: - case RADEON_PP_CUBIC_FACES_1: - case RADEON_PP_CUBIC_FACES_2: - tmp = idx_value; - i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; - for (face = 0; face < 4; face++) { - track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); - track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); - } - track->tex_dirty = true; - break; - default: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", - reg, idx); - return -EINVAL; - } - return 0; -} - -int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - struct radeon_bo *robj) -{ - unsigned idx; - u32 value; - idx = pkt->idx + 1; - value = radeon_get_ib_value(p, idx + 2); - if ((value + 1) > radeon_bo_size(robj)) { - DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " - "(need %u have %lu) !\n", - value + 1, - radeon_bo_size(robj)); - return -EINVAL; - } - return 0; -} - -static int r100_packet3_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - struct radeon_cs_reloc *reloc; - struct r100_cs_track *track; - unsigned idx; - volatile uint32_t *ib; - int r; - - ib = p->ib->ptr; - idx = pkt->idx + 1; - track = (struct r100_cs_track *)p->track; - switch (pkt->opcode) { - case PACKET3_3D_LOAD_VBPNTR: - r = r100_packet3_load_vbpntr(p, pkt, idx); - if (r) - return r; - break; - case PACKET3_INDX_BUFFER: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx+1] = radeon_get_ib_value(p, idx+1) + ((u32)reloc->lobj.gpu_offset); - r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); - if (r) { - return r; - } - break; - case 0x23: - /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */ - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx] = radeon_get_ib_value(p, idx) + ((u32)reloc->lobj.gpu_offset); - track->num_arrays = 1; - track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 2)); - - track->arrays[0].robj = reloc->robj; - track->arrays[0].esize = track->vtx_size; - - track->max_indx = radeon_get_ib_value(p, idx+1); - - track->vap_vf_cntl = radeon_get_ib_value(p, idx+3); - track->immd_dwords = pkt->count - 1; - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - case PACKET3_3D_DRAW_IMMD: - if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) { - DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); - return -EINVAL; - } - track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 0)); - track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); - track->immd_dwords = pkt->count - 1; - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - /* triggers drawing using in-packet vertex data */ - case PACKET3_3D_DRAW_IMMD_2: - if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) { - DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); - return -EINVAL; - } - track->vap_vf_cntl = radeon_get_ib_value(p, idx); - track->immd_dwords = pkt->count; - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - /* triggers drawing using in-packet vertex data */ - case PACKET3_3D_DRAW_VBUF_2: - track->vap_vf_cntl = radeon_get_ib_value(p, idx); - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - /* triggers drawing of vertex buffers setup elsewhere */ - case PACKET3_3D_DRAW_INDX_2: - track->vap_vf_cntl = radeon_get_ib_value(p, idx); - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - /* triggers drawing using indices to vertex buffer */ - case PACKET3_3D_DRAW_VBUF: - track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - /* triggers drawing of vertex buffers setup elsewhere */ - case PACKET3_3D_DRAW_INDX: - track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); - r = r100_cs_track_check(p->rdev, track); - if (r) - return r; - break; - /* triggers drawing using indices to vertex buffer */ - case PACKET3_3D_CLEAR_HIZ: - case PACKET3_3D_CLEAR_ZMASK: - if (p->rdev->hyperz_filp != p->filp) - return -EINVAL; - break; - case PACKET3_NOP: - break; - default: - DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -int r100_cs_parse(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet pkt; - struct r100_cs_track *track; - int r; - - track = kzalloc(sizeof(*track), GFP_KERNEL); - r100_cs_track_clear(p->rdev, track); - p->track = track; - do { - r = r100_cs_packet_parse(p, &pkt, p->idx); - if (r) { - return r; - } - p->idx += pkt.count + 2; - switch (pkt.type) { - case PACKET_TYPE0: - if (p->rdev->family >= CHIP_R200) - r = r100_cs_parse_packet0(p, &pkt, - p->rdev->config.r100.reg_safe_bm, - p->rdev->config.r100.reg_safe_bm_size, - &r200_packet0_check); - else - r = r100_cs_parse_packet0(p, &pkt, - p->rdev->config.r100.reg_safe_bm, - p->rdev->config.r100.reg_safe_bm_size, - &r100_packet0_check); - break; - case PACKET_TYPE2: - break; - case PACKET_TYPE3: - r = r100_packet3_check(p, &pkt); - break; - default: - DRM_ERROR("Unknown packet type %d !\n", - pkt.type); - return -EINVAL; - } - if (r) { - return r; - } - } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); - return 0; -} - - -/* - * Global GPU functions - */ -void r100_errata(struct radeon_device *rdev) -{ - rdev->pll_errata = 0; - - if (rdev->family == CHIP_RV200 || rdev->family == CHIP_RS200) { - rdev->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; - } - - if (rdev->family == CHIP_RV100 || - rdev->family == CHIP_RS100 || - rdev->family == CHIP_RS200) { - rdev->pll_errata |= CHIP_ERRATA_PLL_DELAY; - } -} - -/* Wait for vertical sync on primary CRTC */ -void r100_gpu_wait_for_vsync(struct radeon_device *rdev) -{ - uint32_t crtc_gen_cntl, tmp; - int i; - - crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); - if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) || - !(crtc_gen_cntl & RADEON_CRTC_EN)) { - return; - } - /* Clear the CRTC_VBLANK_SAVE bit */ - WREG32(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(RADEON_CRTC_STATUS); - if (tmp & RADEON_CRTC_VBLANK_SAVE) { - return; - } - DRM_UDELAY(1); - } -} - -/* Wait for vertical sync on secondary CRTC */ -void r100_gpu_wait_for_vsync2(struct radeon_device *rdev) -{ - uint32_t crtc2_gen_cntl, tmp; - int i; - - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || - !(crtc2_gen_cntl & RADEON_CRTC2_EN)) - return; - - /* Clear the CRTC_VBLANK_SAVE bit */ - WREG32(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(RADEON_CRTC2_STATUS); - if (tmp & RADEON_CRTC2_VBLANK_SAVE) { - return; - } - DRM_UDELAY(1); - } -} - -int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; - if (tmp >= n) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -int r100_gui_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - if (r100_rbbm_fifo_wait_for_entry(rdev, 64)) { - printk(KERN_WARNING "radeon: wait for empty RBBM fifo failed !" - " Bad things might happen.\n"); - } - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(RADEON_RBBM_STATUS); - if (!(tmp & RADEON_RBBM_ACTIVE)) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -int r100_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(RADEON_MC_STATUS); - if (tmp & RADEON_MC_IDLE) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring *ring) -{ - lockup->last_cp_rptr = ring->rptr; - lockup->last_jiffies = jiffies; -} - -/** - * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information - * @rdev: radeon device structure - * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations - * @cp: radeon_cp structure holding CP information - * - * We don't need to initialize the lockup tracking information as we will either - * have CP rptr to a different value of jiffies wrap around which will force - * initialization of the lockup tracking informations. - * - * A possible false positivie is if we get call after while and last_cp_rptr == - * the current CP rptr, even if it's unlikely it might happen. To avoid this - * if the elapsed time since last call is bigger than 2 second than we return - * false and update the tracking information. Due to this the caller must call - * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported - * the fencing code should be cautious about that. - * - * Caller should write to the ring to force CP to do something so we don't get - * false positive when CP is just gived nothing to do. - * - **/ -bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_ring *ring) -{ - unsigned long cjiffies, elapsed; - - cjiffies = jiffies; - if (!time_after(cjiffies, lockup->last_jiffies)) { - /* likely a wrap around */ - lockup->last_cp_rptr = ring->rptr; - lockup->last_jiffies = jiffies; - return false; - } - if (ring->rptr != lockup->last_cp_rptr) { - /* CP is still working no lockup */ - lockup->last_cp_rptr = ring->rptr; - lockup->last_jiffies = jiffies; - return false; - } - elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); - if (elapsed >= 10000) { - dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); - return true; - } - /* give a chance to the GPU ... */ - return false; -} - -bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 rbbm_status; - int r; - - rbbm_status = RREG32(R_000E40_RBBM_STATUS); - if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - r100_gpu_lockup_update(&rdev->config.r100.lockup, ring); - return false; - } - /* force CP activities */ - r = radeon_ring_lock(rdev, ring, 2); - if (!r) { - /* PACKET2 NOP */ - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - radeon_ring_unlock_commit(rdev, ring); - } - ring->rptr = RREG32(ring->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, ring); -} - -void r100_bm_disable(struct radeon_device *rdev) -{ - u32 tmp; - - /* disable bus mastering */ - tmp = RREG32(R_000030_BUS_CNTL); - WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000044); - mdelay(1); - WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042); - mdelay(1); - WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); - tmp = RREG32(RADEON_BUS_CNTL); - mdelay(1); - pci_clear_master(rdev->pdev); - mdelay(1); -} - -int r100_asic_reset(struct radeon_device *rdev) -{ - struct r100_mc_save save; - u32 status, tmp; - int ret = 0; - - status = RREG32(R_000E40_RBBM_STATUS); - if (!G_000E40_GUI_ACTIVE(status)) { - return 0; - } - r100_mc_stop(rdev, &save); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* stop CP */ - WREG32(RADEON_CP_CSQ_CNTL, 0); - tmp = RREG32(RADEON_CP_RB_CNTL); - WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); - WREG32(RADEON_CP_RB_RPTR_WR, 0); - WREG32(RADEON_CP_RB_WPTR, 0); - WREG32(RADEON_CP_RB_CNTL, tmp); - /* save PCI state */ - pci_save_state(rdev->pdev); - /* disable bus mastering */ - r100_bm_disable(rdev); - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_SE(1) | - S_0000F0_SOFT_RESET_RE(1) | - S_0000F0_SOFT_RESET_PP(1) | - S_0000F0_SOFT_RESET_RB(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* reset CP */ - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* restore PCI & busmastering */ - pci_restore_state(rdev->pdev); - r100_enable_bm(rdev); - /* Check if GPU is idle */ - if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || - G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { - dev_err(rdev->dev, "failed to reset GPU\n"); - rdev->gpu_lockup = true; - ret = -1; - } else - dev_info(rdev->dev, "GPU reset succeed\n"); - r100_mc_resume(rdev, &save); - return ret; -} - -void r100_set_common_regs(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - bool force_dac2 = false; - u32 tmp; - - /* set these so they don't interfere with anything */ - WREG32(RADEON_OV0_SCALE_CNTL, 0); - WREG32(RADEON_SUBPIC_CNTL, 0); - WREG32(RADEON_VIPH_CONTROL, 0); - WREG32(RADEON_I2C_CNTL_1, 0); - WREG32(RADEON_DVI_I2C_CNTL_1, 0); - WREG32(RADEON_CAP0_TRIG_CNTL, 0); - WREG32(RADEON_CAP1_TRIG_CNTL, 0); - - /* always set up dac2 on rn50 and some rv100 as lots - * of servers seem to wire it up to a VGA port but - * don't report it in the bios connector - * table. - */ - switch (dev->pdev->device) { - /* RN50 */ - case 0x515e: - case 0x5969: - force_dac2 = true; - break; - /* RV100*/ - case 0x5159: - case 0x515a: - /* DELL triple head servers */ - if ((dev->pdev->subsystem_vendor == 0x1028 /* DELL */) && - ((dev->pdev->subsystem_device == 0x016c) || - (dev->pdev->subsystem_device == 0x016d) || - (dev->pdev->subsystem_device == 0x016e) || - (dev->pdev->subsystem_device == 0x016f) || - (dev->pdev->subsystem_device == 0x0170) || - (dev->pdev->subsystem_device == 0x017d) || - (dev->pdev->subsystem_device == 0x017e) || - (dev->pdev->subsystem_device == 0x0183) || - (dev->pdev->subsystem_device == 0x018a) || - (dev->pdev->subsystem_device == 0x019a))) - force_dac2 = true; - break; - } - - if (force_dac2) { - u32 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - u32 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - u32 dac2_cntl = RREG32(RADEON_DAC_CNTL2); - - /* For CRT on DAC2, don't turn it on if BIOS didn't - enable it, even it's detected. - */ - - /* force it to crtc0 */ - dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL; - dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL; - disp_hw_debug |= RADEON_CRT2_DISP1_SEL; - - /* set up the TV DAC */ - tv_dac_cntl &= ~(RADEON_TV_DAC_PEDESTAL | - RADEON_TV_DAC_STD_MASK | - RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD | - RADEON_TV_DAC_BGADJ_MASK | - RADEON_TV_DAC_DACADJ_MASK); - tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | - RADEON_TV_DAC_NHOLD | - RADEON_TV_DAC_STD_PS2 | - (0x58 << 16)); - - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - } - - /* switch PM block to ACPI mode */ - tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL); - tmp &= ~RADEON_PM_MODE_SEL; - WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); - -} - -/* - * VRAM info - */ -static void r100_vram_get_type(struct radeon_device *rdev) -{ - uint32_t tmp; - - rdev->mc.vram_is_ddr = false; - if (rdev->flags & RADEON_IS_IGP) - rdev->mc.vram_is_ddr = true; - else if (RREG32(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR) - rdev->mc.vram_is_ddr = true; - if ((rdev->family == CHIP_RV100) || - (rdev->family == CHIP_RS100) || - (rdev->family == CHIP_RS200)) { - tmp = RREG32(RADEON_MEM_CNTL); - if (tmp & RV100_HALF_MODE) { - rdev->mc.vram_width = 32; - } else { - rdev->mc.vram_width = 64; - } - if (rdev->flags & RADEON_SINGLE_CRTC) { - rdev->mc.vram_width /= 4; - rdev->mc.vram_is_ddr = true; - } - } else if (rdev->family <= CHIP_RV280) { - tmp = RREG32(RADEON_MEM_CNTL); - if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) { - rdev->mc.vram_width = 128; - } else { - rdev->mc.vram_width = 64; - } - } else { - /* newer IGPs */ - rdev->mc.vram_width = 128; - } -} - -static u32 r100_get_accessible_vram(struct radeon_device *rdev) -{ - u32 aper_size; - u8 byte; - - aper_size = RREG32(RADEON_CONFIG_APER_SIZE); - - /* Set HDP_APER_CNTL only on cards that are known not to be broken, - * that is has the 2nd generation multifunction PCI interface - */ - if (rdev->family == CHIP_RV280 || - rdev->family >= CHIP_RV350) { - WREG32_P(RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, - ~RADEON_HDP_APER_CNTL); - DRM_INFO("Generation 2 PCI interface, using max accessible memory\n"); - return aper_size * 2; - } - - /* Older cards have all sorts of funny issues to deal with. First - * check if it's a multifunction card by reading the PCI config - * header type... Limit those to one aperture size - */ - pci_read_config_byte(rdev->pdev, 0xe, &byte); - if (byte & 0x80) { - DRM_INFO("Generation 1 PCI interface in multifunction mode\n"); - DRM_INFO("Limiting VRAM to one aperture\n"); - return aper_size; - } - - /* Single function older card. We read HDP_APER_CNTL to see how the BIOS - * have set it up. We don't write this as it's broken on some ASICs but - * we expect the BIOS to have done the right thing (might be too optimistic...) - */ - if (RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) - return aper_size * 2; - return aper_size; -} - -void r100_vram_init_sizes(struct radeon_device *rdev) -{ - u64 config_aper_size; - - /* work out accessible VRAM */ - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); - /* FIXME we don't use the second aperture yet when we could use it */ - if (rdev->mc.visible_vram_size > rdev->mc.aper_size) - rdev->mc.visible_vram_size = rdev->mc.aper_size; - config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); - if (rdev->flags & RADEON_IS_IGP) { - uint32_t tom; - /* read NB_TOM to get the amount of ram stolen for the GPU */ - tom = RREG32(RADEON_NB_TOM); - rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16); - WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); - rdev->mc.mc_vram_size = rdev->mc.real_vram_size; - } else { - rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); - /* Some production boards of m6 will report 0 - * if it's 8 MB - */ - if (rdev->mc.real_vram_size == 0) { - rdev->mc.real_vram_size = 8192 * 1024; - WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); - } - /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - - * Novell bug 204882 + along with lots of ubuntu ones - */ - if (rdev->mc.aper_size > config_aper_size) - config_aper_size = rdev->mc.aper_size; - - if (config_aper_size > rdev->mc.real_vram_size) - rdev->mc.mc_vram_size = config_aper_size; - else - rdev->mc.mc_vram_size = rdev->mc.real_vram_size; - } -} - -void r100_vga_set_state(struct radeon_device *rdev, bool state) -{ - uint32_t temp; - - temp = RREG32(RADEON_CONFIG_CNTL); - if (state == false) { - temp &= ~RADEON_CFG_VGA_RAM_EN; - temp |= RADEON_CFG_VGA_IO_DIS; - } else { - temp &= ~RADEON_CFG_VGA_IO_DIS; - } - WREG32(RADEON_CONFIG_CNTL, temp); -} - -void r100_mc_init(struct radeon_device *rdev) -{ - u64 base; - - r100_vram_get_type(rdev); - r100_vram_init_sizes(rdev); - base = rdev->mc.aper_base; - if (rdev->flags & RADEON_IS_IGP) - base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; - radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; - if (!(rdev->flags & RADEON_IS_AGP)) - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - - -/* - * Indirect registers accessor - */ -void r100_pll_errata_after_index(struct radeon_device *rdev) -{ - if (rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS) { - (void)RREG32(RADEON_CLOCK_CNTL_DATA); - (void)RREG32(RADEON_CRTC_GEN_CNTL); - } -} - -static void r100_pll_errata_after_data(struct radeon_device *rdev) -{ - /* This workarounds is necessary on RV100, RS100 and RS200 chips - * or the chip could hang on a subsequent access - */ - if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { - mdelay(5); - } - - /* This function is required to workaround a hardware bug in some (all?) - * revisions of the R300. This workaround should be called after every - * CLOCK_CNTL_INDEX register access. If not, register reads afterward - * may not be correct. - */ - if (rdev->pll_errata & CHIP_ERRATA_R300_CG) { - uint32_t save, tmp; - - save = RREG32(RADEON_CLOCK_CNTL_INDEX); - tmp = save & ~(0x3f | RADEON_PLL_WR_EN); - WREG32(RADEON_CLOCK_CNTL_INDEX, tmp); - tmp = RREG32(RADEON_CLOCK_CNTL_DATA); - WREG32(RADEON_CLOCK_CNTL_INDEX, save); - } -} - -uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg) -{ - uint32_t data; - - WREG8(RADEON_CLOCK_CNTL_INDEX, reg & 0x3f); - r100_pll_errata_after_index(rdev); - data = RREG32(RADEON_CLOCK_CNTL_DATA); - r100_pll_errata_after_data(rdev); - return data; -} - -void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - WREG8(RADEON_CLOCK_CNTL_INDEX, ((reg & 0x3f) | RADEON_PLL_WR_EN)); - r100_pll_errata_after_index(rdev); - WREG32(RADEON_CLOCK_CNTL_DATA, v); - r100_pll_errata_after_data(rdev); -} - -void r100_set_safe_registers(struct radeon_device *rdev) -{ - if (ASIC_IS_RN50(rdev)) { - rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; - rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); - } else if (rdev->family < CHIP_R200) { - rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; - rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); - } else { - r200_set_safe_registers(rdev); - } -} - -/* - * Debugfs info - */ -#if defined(CONFIG_DEBUG_FS) -static int r100_debugfs_rbbm_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t reg, value; - unsigned i; - - seq_printf(m, "RBBM_STATUS 0x%08x\n", RREG32(RADEON_RBBM_STATUS)); - seq_printf(m, "RBBM_CMDFIFO_STAT 0x%08x\n", RREG32(0xE7C)); - seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); - for (i = 0; i < 64; i++) { - WREG32(RADEON_RBBM_CMDFIFO_ADDR, i | 0x100); - reg = (RREG32(RADEON_RBBM_CMDFIFO_DATA) - 1) >> 2; - WREG32(RADEON_RBBM_CMDFIFO_ADDR, i); - value = RREG32(RADEON_RBBM_CMDFIFO_DATA); - seq_printf(m, "[0x%03X] 0x%04X=0x%08X\n", i, reg, value); - } - return 0; -} - -static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - uint32_t rdp, wdp; - unsigned count, i, j; - - radeon_ring_free_size(rdev, ring); - rdp = RREG32(RADEON_CP_RB_RPTR); - wdp = RREG32(RADEON_CP_RB_WPTR); - count = (rdp + ring->ring_size - wdp) & ring->ptr_mask; - seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); - seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); - seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); - seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); - seq_printf(m, "%u dwords in ring\n", count); - for (j = 0; j <= count; j++) { - i = (rdp + j) & ring->ptr_mask; - seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); - } - return 0; -} - - -static int r100_debugfs_cp_csq_fifo(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t csq_stat, csq2_stat, tmp; - unsigned r_rptr, r_wptr, ib1_rptr, ib1_wptr, ib2_rptr, ib2_wptr; - unsigned i; - - seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); - seq_printf(m, "CP_CSQ_MODE 0x%08x\n", RREG32(RADEON_CP_CSQ_MODE)); - csq_stat = RREG32(RADEON_CP_CSQ_STAT); - csq2_stat = RREG32(RADEON_CP_CSQ2_STAT); - r_rptr = (csq_stat >> 0) & 0x3ff; - r_wptr = (csq_stat >> 10) & 0x3ff; - ib1_rptr = (csq_stat >> 20) & 0x3ff; - ib1_wptr = (csq2_stat >> 0) & 0x3ff; - ib2_rptr = (csq2_stat >> 10) & 0x3ff; - ib2_wptr = (csq2_stat >> 20) & 0x3ff; - seq_printf(m, "CP_CSQ_STAT 0x%08x\n", csq_stat); - seq_printf(m, "CP_CSQ2_STAT 0x%08x\n", csq2_stat); - seq_printf(m, "Ring rptr %u\n", r_rptr); - seq_printf(m, "Ring wptr %u\n", r_wptr); - seq_printf(m, "Indirect1 rptr %u\n", ib1_rptr); - seq_printf(m, "Indirect1 wptr %u\n", ib1_wptr); - seq_printf(m, "Indirect2 rptr %u\n", ib2_rptr); - seq_printf(m, "Indirect2 wptr %u\n", ib2_wptr); - /* FIXME: 0, 128, 640 depends on fifo setup see cp_init_kms - * 128 = indirect1_start * 8 & 640 = indirect2_start * 8 */ - seq_printf(m, "Ring fifo:\n"); - for (i = 0; i < 256; i++) { - WREG32(RADEON_CP_CSQ_ADDR, i << 2); - tmp = RREG32(RADEON_CP_CSQ_DATA); - seq_printf(m, "rfifo[%04d]=0x%08X\n", i, tmp); - } - seq_printf(m, "Indirect1 fifo:\n"); - for (i = 256; i <= 512; i++) { - WREG32(RADEON_CP_CSQ_ADDR, i << 2); - tmp = RREG32(RADEON_CP_CSQ_DATA); - seq_printf(m, "ib1fifo[%04d]=0x%08X\n", i, tmp); - } - seq_printf(m, "Indirect2 fifo:\n"); - for (i = 640; i < ib1_wptr; i++) { - WREG32(RADEON_CP_CSQ_ADDR, i << 2); - tmp = RREG32(RADEON_CP_CSQ_DATA); - seq_printf(m, "ib2fifo[%04d]=0x%08X\n", i, tmp); - } - return 0; -} - -static int r100_debugfs_mc_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - tmp = RREG32(RADEON_CONFIG_MEMSIZE); - seq_printf(m, "CONFIG_MEMSIZE 0x%08x\n", tmp); - tmp = RREG32(RADEON_MC_FB_LOCATION); - seq_printf(m, "MC_FB_LOCATION 0x%08x\n", tmp); - tmp = RREG32(RADEON_BUS_CNTL); - seq_printf(m, "BUS_CNTL 0x%08x\n", tmp); - tmp = RREG32(RADEON_MC_AGP_LOCATION); - seq_printf(m, "MC_AGP_LOCATION 0x%08x\n", tmp); - tmp = RREG32(RADEON_AGP_BASE); - seq_printf(m, "AGP_BASE 0x%08x\n", tmp); - tmp = RREG32(RADEON_HOST_PATH_CNTL); - seq_printf(m, "HOST_PATH_CNTL 0x%08x\n", tmp); - tmp = RREG32(0x01D0); - seq_printf(m, "AIC_CTRL 0x%08x\n", tmp); - tmp = RREG32(RADEON_AIC_LO_ADDR); - seq_printf(m, "AIC_LO_ADDR 0x%08x\n", tmp); - tmp = RREG32(RADEON_AIC_HI_ADDR); - seq_printf(m, "AIC_HI_ADDR 0x%08x\n", tmp); - tmp = RREG32(0x01E4); - seq_printf(m, "AIC_TLB_ADDR 0x%08x\n", tmp); - return 0; -} - -static struct drm_info_list r100_debugfs_rbbm_list[] = { - {"r100_rbbm_info", r100_debugfs_rbbm_info, 0, NULL}, -}; - -static struct drm_info_list r100_debugfs_cp_list[] = { - {"r100_cp_ring_info", r100_debugfs_cp_ring_info, 0, NULL}, - {"r100_cp_csq_fifo", r100_debugfs_cp_csq_fifo, 0, NULL}, -}; - -static struct drm_info_list r100_debugfs_mc_info_list[] = { - {"r100_mc_info", r100_debugfs_mc_info, 0, NULL}, -}; -#endif - -int r100_debugfs_rbbm_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, r100_debugfs_rbbm_list, 1); -#else - return 0; -#endif -} - -int r100_debugfs_cp_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, r100_debugfs_cp_list, 2); -#else - return 0; -#endif -} - -int r100_debugfs_mc_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, r100_debugfs_mc_info_list, 1); -#else - return 0; -#endif -} - -int r100_set_surface_reg(struct radeon_device *rdev, int reg, - uint32_t tiling_flags, uint32_t pitch, - uint32_t offset, uint32_t obj_size) -{ - int surf_index = reg * 16; - int flags = 0; - - if (rdev->family <= CHIP_RS200) { - if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) - == (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) - flags |= RADEON_SURF_TILE_COLOR_BOTH; - if (tiling_flags & RADEON_TILING_MACRO) - flags |= RADEON_SURF_TILE_COLOR_MACRO; - } else if (rdev->family <= CHIP_RV280) { - if (tiling_flags & (RADEON_TILING_MACRO)) - flags |= R200_SURF_TILE_COLOR_MACRO; - if (tiling_flags & RADEON_TILING_MICRO) - flags |= R200_SURF_TILE_COLOR_MICRO; - } else { - if (tiling_flags & RADEON_TILING_MACRO) - flags |= R300_SURF_TILE_MACRO; - if (tiling_flags & RADEON_TILING_MICRO) - flags |= R300_SURF_TILE_MICRO; - } - - if (tiling_flags & RADEON_TILING_SWAP_16BIT) - flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP; - if (tiling_flags & RADEON_TILING_SWAP_32BIT) - flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP; - - /* when we aren't tiling the pitch seems to needs to be furtherdivided down. - tested on power5 + rn50 server */ - if (tiling_flags & (RADEON_TILING_SWAP_16BIT | RADEON_TILING_SWAP_32BIT)) { - if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) - if (ASIC_IS_RN50(rdev)) - pitch /= 16; - } - - /* r100/r200 divide by 16 */ - if (rdev->family < CHIP_R300) - flags |= pitch / 16; - else - flags |= pitch / 8; - - - DRM_DEBUG_KMS("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); - WREG32(RADEON_SURFACE0_INFO + surf_index, flags); - WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); - WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); - return 0; -} - -void r100_clear_surface_reg(struct radeon_device *rdev, int reg) -{ - int surf_index = reg * 16; - WREG32(RADEON_SURFACE0_INFO + surf_index, 0); -} - -void r100_bandwidth_update(struct radeon_device *rdev) -{ - fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff; - fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff; - fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; - uint32_t temp, data, mem_trcd, mem_trp, mem_tras; - fixed20_12 memtcas_ff[8] = { - dfixed_init(1), - dfixed_init(2), - dfixed_init(3), - dfixed_init(0), - dfixed_init_half(1), - dfixed_init_half(2), - dfixed_init(0), - }; - fixed20_12 memtcas_rs480_ff[8] = { - dfixed_init(0), - dfixed_init(1), - dfixed_init(2), - dfixed_init(3), - dfixed_init(0), - dfixed_init_half(1), - dfixed_init_half(2), - dfixed_init_half(3), - }; - fixed20_12 memtcas2_ff[8] = { - dfixed_init(0), - dfixed_init(1), - dfixed_init(2), - dfixed_init(3), - dfixed_init(4), - dfixed_init(5), - dfixed_init(6), - dfixed_init(7), - }; - fixed20_12 memtrbs[8] = { - dfixed_init(1), - dfixed_init_half(1), - dfixed_init(2), - dfixed_init_half(2), - dfixed_init(3), - dfixed_init_half(3), - dfixed_init(4), - dfixed_init_half(4) - }; - fixed20_12 memtrbs_r4xx[8] = { - dfixed_init(4), - dfixed_init(5), - dfixed_init(6), - dfixed_init(7), - dfixed_init(8), - dfixed_init(9), - dfixed_init(10), - dfixed_init(11) - }; - fixed20_12 min_mem_eff; - fixed20_12 mc_latency_sclk, mc_latency_mclk, k1; - fixed20_12 cur_latency_mclk, cur_latency_sclk; - fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate, - disp_drain_rate2, read_return_rate; - fixed20_12 time_disp1_drop_priority; - int c; - int cur_size = 16; /* in octawords */ - int critical_point = 0, critical_point2; -/* uint32_t read_return_rate, time_disp1_drop_priority; */ - int stop_req, max_stop_req; - struct drm_display_mode *mode1 = NULL; - struct drm_display_mode *mode2 = NULL; - uint32_t pixel_bytes1 = 0; - uint32_t pixel_bytes2 = 0; - - radeon_update_display_priority(rdev); - - if (rdev->mode_info.crtcs[0]->base.enabled) { - mode1 = &rdev->mode_info.crtcs[0]->base.mode; - pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; - } - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - if (rdev->mode_info.crtcs[1]->base.enabled) { - mode2 = &rdev->mode_info.crtcs[1]->base.mode; - pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; - } - } - - min_mem_eff.full = dfixed_const_8(0); - /* get modes */ - if ((rdev->disp_priority == 2) && ASIC_IS_R300(rdev)) { - uint32_t mc_init_misc_lat_timer = RREG32(R300_MC_INIT_MISC_LAT_TIMER); - mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); - mc_init_misc_lat_timer &= ~(R300_MC_DISP0R_INIT_LAT_MASK << R300_MC_DISP0R_INIT_LAT_SHIFT); - /* check crtc enables */ - if (mode2) - mc_init_misc_lat_timer |= (1 << R300_MC_DISP1R_INIT_LAT_SHIFT); - if (mode1) - mc_init_misc_lat_timer |= (1 << R300_MC_DISP0R_INIT_LAT_SHIFT); - WREG32(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); - } - - /* - * determine is there is enough bw for current mode - */ - sclk_ff = rdev->pm.sclk; - mclk_ff = rdev->pm.mclk; - - temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); - temp_ff.full = dfixed_const(temp); - mem_bw.full = dfixed_mul(mclk_ff, temp_ff); - - pix_clk.full = 0; - pix_clk2.full = 0; - peak_disp_bw.full = 0; - if (mode1) { - temp_ff.full = dfixed_const(1000); - pix_clk.full = dfixed_const(mode1->clock); /* convert to fixed point */ - pix_clk.full = dfixed_div(pix_clk, temp_ff); - temp_ff.full = dfixed_const(pixel_bytes1); - peak_disp_bw.full += dfixed_mul(pix_clk, temp_ff); - } - if (mode2) { - temp_ff.full = dfixed_const(1000); - pix_clk2.full = dfixed_const(mode2->clock); /* convert to fixed point */ - pix_clk2.full = dfixed_div(pix_clk2, temp_ff); - temp_ff.full = dfixed_const(pixel_bytes2); - peak_disp_bw.full += dfixed_mul(pix_clk2, temp_ff); - } - - mem_bw.full = dfixed_mul(mem_bw, min_mem_eff); - if (peak_disp_bw.full >= mem_bw.full) { - DRM_ERROR("You may not have enough display bandwidth for current mode\n" - "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); - } - - /* Get values from the EXT_MEM_CNTL register...converting its contents. */ - temp = RREG32(RADEON_MEM_TIMING_CNTL); - if ((rdev->family == CHIP_RV100) || (rdev->flags & RADEON_IS_IGP)) { /* RV100, M6, IGPs */ - mem_trcd = ((temp >> 2) & 0x3) + 1; - mem_trp = ((temp & 0x3)) + 1; - mem_tras = ((temp & 0x70) >> 4) + 1; - } else if (rdev->family == CHIP_R300 || - rdev->family == CHIP_R350) { /* r300, r350 */ - mem_trcd = (temp & 0x7) + 1; - mem_trp = ((temp >> 8) & 0x7) + 1; - mem_tras = ((temp >> 11) & 0xf) + 4; - } else if (rdev->family == CHIP_RV350 || - rdev->family <= CHIP_RV380) { - /* rv3x0 */ - mem_trcd = (temp & 0x7) + 3; - mem_trp = ((temp >> 8) & 0x7) + 3; - mem_tras = ((temp >> 11) & 0xf) + 6; - } else if (rdev->family == CHIP_R420 || - rdev->family == CHIP_R423 || - rdev->family == CHIP_RV410) { - /* r4xx */ - mem_trcd = (temp & 0xf) + 3; - if (mem_trcd > 15) - mem_trcd = 15; - mem_trp = ((temp >> 8) & 0xf) + 3; - if (mem_trp > 15) - mem_trp = 15; - mem_tras = ((temp >> 12) & 0x1f) + 6; - if (mem_tras > 31) - mem_tras = 31; - } else { /* RV200, R200 */ - mem_trcd = (temp & 0x7) + 1; - mem_trp = ((temp >> 8) & 0x7) + 1; - mem_tras = ((temp >> 12) & 0xf) + 4; - } - /* convert to FF */ - trcd_ff.full = dfixed_const(mem_trcd); - trp_ff.full = dfixed_const(mem_trp); - tras_ff.full = dfixed_const(mem_tras); - - /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ - temp = RREG32(RADEON_MEM_SDRAM_MODE_REG); - data = (temp & (7 << 20)) >> 20; - if ((rdev->family == CHIP_RV100) || rdev->flags & RADEON_IS_IGP) { - if (rdev->family == CHIP_RS480) /* don't think rs400 */ - tcas_ff = memtcas_rs480_ff[data]; - else - tcas_ff = memtcas_ff[data]; - } else - tcas_ff = memtcas2_ff[data]; - - if (rdev->family == CHIP_RS400 || - rdev->family == CHIP_RS480) { - /* extra cas latency stored in bits 23-25 0-4 clocks */ - data = (temp >> 23) & 0x7; - if (data < 5) - tcas_ff.full += dfixed_const(data); - } - - if (ASIC_IS_R300(rdev) && !(rdev->flags & RADEON_IS_IGP)) { - /* on the R300, Tcas is included in Trbs. - */ - temp = RREG32(RADEON_MEM_CNTL); - data = (R300_MEM_NUM_CHANNELS_MASK & temp); - if (data == 1) { - if (R300_MEM_USE_CD_CH_ONLY & temp) { - temp = RREG32(R300_MC_IND_INDEX); - temp &= ~R300_MC_IND_ADDR_MASK; - temp |= R300_MC_READ_CNTL_CD_mcind; - WREG32(R300_MC_IND_INDEX, temp); - temp = RREG32(R300_MC_IND_DATA); - data = (R300_MEM_RBS_POSITION_C_MASK & temp); - } else { - temp = RREG32(R300_MC_READ_CNTL_AB); - data = (R300_MEM_RBS_POSITION_A_MASK & temp); - } - } else { - temp = RREG32(R300_MC_READ_CNTL_AB); - data = (R300_MEM_RBS_POSITION_A_MASK & temp); - } - if (rdev->family == CHIP_RV410 || - rdev->family == CHIP_R420 || - rdev->family == CHIP_R423) - trbs_ff = memtrbs_r4xx[data]; - else - trbs_ff = memtrbs[data]; - tcas_ff.full += trbs_ff.full; - } - - sclk_eff_ff.full = sclk_ff.full; - - if (rdev->flags & RADEON_IS_AGP) { - fixed20_12 agpmode_ff; - agpmode_ff.full = dfixed_const(radeon_agpmode); - temp_ff.full = dfixed_const_666(16); - sclk_eff_ff.full -= dfixed_mul(agpmode_ff, temp_ff); - } - /* TODO PCIE lanes may affect this - agpmode == 16?? */ - - if (ASIC_IS_R300(rdev)) { - sclk_delay_ff.full = dfixed_const(250); - } else { - if ((rdev->family == CHIP_RV100) || - rdev->flags & RADEON_IS_IGP) { - if (rdev->mc.vram_is_ddr) - sclk_delay_ff.full = dfixed_const(41); - else - sclk_delay_ff.full = dfixed_const(33); - } else { - if (rdev->mc.vram_width == 128) - sclk_delay_ff.full = dfixed_const(57); - else - sclk_delay_ff.full = dfixed_const(41); - } - } - - mc_latency_sclk.full = dfixed_div(sclk_delay_ff, sclk_eff_ff); - - if (rdev->mc.vram_is_ddr) { - if (rdev->mc.vram_width == 32) { - k1.full = dfixed_const(40); - c = 3; - } else { - k1.full = dfixed_const(20); - c = 1; - } - } else { - k1.full = dfixed_const(40); - c = 3; - } - - temp_ff.full = dfixed_const(2); - mc_latency_mclk.full = dfixed_mul(trcd_ff, temp_ff); - temp_ff.full = dfixed_const(c); - mc_latency_mclk.full += dfixed_mul(tcas_ff, temp_ff); - temp_ff.full = dfixed_const(4); - mc_latency_mclk.full += dfixed_mul(tras_ff, temp_ff); - mc_latency_mclk.full += dfixed_mul(trp_ff, temp_ff); - mc_latency_mclk.full += k1.full; - - mc_latency_mclk.full = dfixed_div(mc_latency_mclk, mclk_ff); - mc_latency_mclk.full += dfixed_div(temp_ff, sclk_eff_ff); - - /* - HW cursor time assuming worst case of full size colour cursor. - */ - temp_ff.full = dfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1)))); - temp_ff.full += trcd_ff.full; - if (temp_ff.full < tras_ff.full) - temp_ff.full = tras_ff.full; - cur_latency_mclk.full = dfixed_div(temp_ff, mclk_ff); - - temp_ff.full = dfixed_const(cur_size); - cur_latency_sclk.full = dfixed_div(temp_ff, sclk_eff_ff); - /* - Find the total latency for the display data. - */ - disp_latency_overhead.full = dfixed_const(8); - disp_latency_overhead.full = dfixed_div(disp_latency_overhead, sclk_ff); - mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; - mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; - - if (mc_latency_mclk.full > mc_latency_sclk.full) - disp_latency.full = mc_latency_mclk.full; - else - disp_latency.full = mc_latency_sclk.full; - - /* setup Max GRPH_STOP_REQ default value */ - if (ASIC_IS_RV100(rdev)) - max_stop_req = 0x5c; - else - max_stop_req = 0x7c; - - if (mode1) { - /* CRTC1 - Set GRPH_BUFFER_CNTL register using h/w defined optimal values. - GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ] - */ - stop_req = mode1->hdisplay * pixel_bytes1 / 16; - - if (stop_req > max_stop_req) - stop_req = max_stop_req; - - /* - Find the drain rate of the display buffer. - */ - temp_ff.full = dfixed_const((16/pixel_bytes1)); - disp_drain_rate.full = dfixed_div(pix_clk, temp_ff); - - /* - Find the critical point of the display buffer. - */ - crit_point_ff.full = dfixed_mul(disp_drain_rate, disp_latency); - crit_point_ff.full += dfixed_const_half(0); - - critical_point = dfixed_trunc(crit_point_ff); - - if (rdev->disp_priority == 2) { - critical_point = 0; - } - - /* - The critical point should never be above max_stop_req-4. Setting - GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time. - */ - if (max_stop_req - critical_point < 4) - critical_point = 0; - - if (critical_point == 0 && mode2 && rdev->family == CHIP_R300) { - /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ - critical_point = 0x10; - } - - temp = RREG32(RADEON_GRPH_BUFFER_CNTL); - temp &= ~(RADEON_GRPH_STOP_REQ_MASK); - temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); - temp &= ~(RADEON_GRPH_START_REQ_MASK); - if ((rdev->family == CHIP_R350) && - (stop_req > 0x15)) { - stop_req -= 0x10; - } - temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); - temp |= RADEON_GRPH_BUFFER_SIZE; - temp &= ~(RADEON_GRPH_CRITICAL_CNTL | - RADEON_GRPH_CRITICAL_AT_SOF | - RADEON_GRPH_STOP_CNTL); - /* - Write the result into the register. - */ - WREG32(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | - (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT))); - -#if 0 - if ((rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { - /* attempt to program RS400 disp regs correctly ??? */ - temp = RREG32(RS400_DISP1_REG_CNTL); - temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK | - RS400_DISP1_STOP_REQ_LEVEL_MASK); - WREG32(RS400_DISP1_REQ_CNTL1, (temp | - (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) | - (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT))); - temp = RREG32(RS400_DMIF_MEM_CNTL1); - temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK | - RS400_DISP1_CRITICAL_POINT_STOP_MASK); - WREG32(RS400_DMIF_MEM_CNTL1, (temp | - (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) | - (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT))); - } -#endif - - DRM_DEBUG_KMS("GRPH_BUFFER_CNTL from to %x\n", - /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ - (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); - } - - if (mode2) { - u32 grph2_cntl; - stop_req = mode2->hdisplay * pixel_bytes2 / 16; - - if (stop_req > max_stop_req) - stop_req = max_stop_req; - - /* - Find the drain rate of the display buffer. - */ - temp_ff.full = dfixed_const((16/pixel_bytes2)); - disp_drain_rate2.full = dfixed_div(pix_clk2, temp_ff); - - grph2_cntl = RREG32(RADEON_GRPH2_BUFFER_CNTL); - grph2_cntl &= ~(RADEON_GRPH_STOP_REQ_MASK); - grph2_cntl |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); - grph2_cntl &= ~(RADEON_GRPH_START_REQ_MASK); - if ((rdev->family == CHIP_R350) && - (stop_req > 0x15)) { - stop_req -= 0x10; - } - grph2_cntl |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); - grph2_cntl |= RADEON_GRPH_BUFFER_SIZE; - grph2_cntl &= ~(RADEON_GRPH_CRITICAL_CNTL | - RADEON_GRPH_CRITICAL_AT_SOF | - RADEON_GRPH_STOP_CNTL); - - if ((rdev->family == CHIP_RS100) || - (rdev->family == CHIP_RS200)) - critical_point2 = 0; - else { - temp = (rdev->mc.vram_width * rdev->mc.vram_is_ddr + 1)/128; - temp_ff.full = dfixed_const(temp); - temp_ff.full = dfixed_mul(mclk_ff, temp_ff); - if (sclk_ff.full < temp_ff.full) - temp_ff.full = sclk_ff.full; - - read_return_rate.full = temp_ff.full; - - if (mode1) { - temp_ff.full = read_return_rate.full - disp_drain_rate.full; - time_disp1_drop_priority.full = dfixed_div(crit_point_ff, temp_ff); - } else { - time_disp1_drop_priority.full = 0; - } - crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full; - crit_point_ff.full = dfixed_mul(crit_point_ff, disp_drain_rate2); - crit_point_ff.full += dfixed_const_half(0); - - critical_point2 = dfixed_trunc(crit_point_ff); - - if (rdev->disp_priority == 2) { - critical_point2 = 0; - } - - if (max_stop_req - critical_point2 < 4) - critical_point2 = 0; - - } - - if (critical_point2 == 0 && rdev->family == CHIP_R300) { - /* some R300 cards have problem with this set to 0 */ - critical_point2 = 0x10; - } - - WREG32(RADEON_GRPH2_BUFFER_CNTL, ((grph2_cntl & ~RADEON_GRPH_CRITICAL_POINT_MASK) | - (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT))); - - if ((rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { -#if 0 - /* attempt to program RS400 disp2 regs correctly ??? */ - temp = RREG32(RS400_DISP2_REQ_CNTL1); - temp &= ~(RS400_DISP2_START_REQ_LEVEL_MASK | - RS400_DISP2_STOP_REQ_LEVEL_MASK); - WREG32(RS400_DISP2_REQ_CNTL1, (temp | - (critical_point2 << RS400_DISP1_START_REQ_LEVEL_SHIFT) | - (critical_point2 << RS400_DISP1_STOP_REQ_LEVEL_SHIFT))); - temp = RREG32(RS400_DISP2_REQ_CNTL2); - temp &= ~(RS400_DISP2_CRITICAL_POINT_START_MASK | - RS400_DISP2_CRITICAL_POINT_STOP_MASK); - WREG32(RS400_DISP2_REQ_CNTL2, (temp | - (critical_point2 << RS400_DISP2_CRITICAL_POINT_START_SHIFT) | - (critical_point2 << RS400_DISP2_CRITICAL_POINT_STOP_SHIFT))); -#endif - WREG32(RS400_DISP2_REQ_CNTL1, 0x105DC1CC); - WREG32(RS400_DISP2_REQ_CNTL2, 0x2749D000); - WREG32(RS400_DMIF_MEM_CNTL1, 0x29CA71DC); - WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); - } - - DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", - (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); - } -} - -static void r100_cs_track_texture_print(struct r100_cs_track_texture *t) -{ - DRM_ERROR("pitch %d\n", t->pitch); - DRM_ERROR("use_pitch %d\n", t->use_pitch); - DRM_ERROR("width %d\n", t->width); - DRM_ERROR("width_11 %d\n", t->width_11); - DRM_ERROR("height %d\n", t->height); - DRM_ERROR("height_11 %d\n", t->height_11); - DRM_ERROR("num levels %d\n", t->num_levels); - DRM_ERROR("depth %d\n", t->txdepth); - DRM_ERROR("bpp %d\n", t->cpp); - DRM_ERROR("coordinate type %d\n", t->tex_coord_type); - DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); - DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); - DRM_ERROR("compress format %d\n", t->compress_format); -} - -static int r100_track_compress_size(int compress_format, int w, int h) -{ - int block_width, block_height, block_bytes; - int wblocks, hblocks; - int min_wblocks; - int sz; - - block_width = 4; - block_height = 4; - - switch (compress_format) { - case R100_TRACK_COMP_DXT1: - block_bytes = 8; - min_wblocks = 4; - break; - default: - case R100_TRACK_COMP_DXT35: - block_bytes = 16; - min_wblocks = 2; - break; - } - - hblocks = (h + block_height - 1) / block_height; - wblocks = (w + block_width - 1) / block_width; - if (wblocks < min_wblocks) - wblocks = min_wblocks; - sz = wblocks * hblocks * block_bytes; - return sz; -} - -static int r100_cs_track_cube(struct radeon_device *rdev, - struct r100_cs_track *track, unsigned idx) -{ - unsigned face, w, h; - struct radeon_bo *cube_robj; - unsigned long size; - unsigned compress_format = track->textures[idx].compress_format; - - for (face = 0; face < 5; face++) { - cube_robj = track->textures[idx].cube_info[face].robj; - w = track->textures[idx].cube_info[face].width; - h = track->textures[idx].cube_info[face].height; - - if (compress_format) { - size = r100_track_compress_size(compress_format, w, h); - } else - size = w * h; - size *= track->textures[idx].cpp; - - size += track->textures[idx].cube_info[face].offset; - - if (size > radeon_bo_size(cube_robj)) { - DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", - size, radeon_bo_size(cube_robj)); - r100_cs_track_texture_print(&track->textures[idx]); - return -1; - } - } - return 0; -} - -static int r100_cs_track_texture_check(struct radeon_device *rdev, - struct r100_cs_track *track) -{ - struct radeon_bo *robj; - unsigned long size; - unsigned u, i, w, h, d; - int ret; - - for (u = 0; u < track->num_texture; u++) { - if (!track->textures[u].enabled) - continue; - if (track->textures[u].lookup_disable) - continue; - robj = track->textures[u].robj; - if (robj == NULL) { - DRM_ERROR("No texture bound to unit %u\n", u); - return -EINVAL; - } - size = 0; - for (i = 0; i <= track->textures[u].num_levels; i++) { - if (track->textures[u].use_pitch) { - if (rdev->family < CHIP_R300) - w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); - else - w = track->textures[u].pitch / (1 << i); - } else { - w = track->textures[u].width; - if (rdev->family >= CHIP_RV515) - w |= track->textures[u].width_11; - w = w / (1 << i); - if (track->textures[u].roundup_w) - w = roundup_pow_of_two(w); - } - h = track->textures[u].height; - if (rdev->family >= CHIP_RV515) - h |= track->textures[u].height_11; - h = h / (1 << i); - if (track->textures[u].roundup_h) - h = roundup_pow_of_two(h); - if (track->textures[u].tex_coord_type == 1) { - d = (1 << track->textures[u].txdepth) / (1 << i); - if (!d) - d = 1; - } else { - d = 1; - } - if (track->textures[u].compress_format) { - - size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; - /* compressed textures are block based */ - } else - size += w * h * d; - } - size *= track->textures[u].cpp; - - switch (track->textures[u].tex_coord_type) { - case 0: - case 1: - break; - case 2: - if (track->separate_cube) { - ret = r100_cs_track_cube(rdev, track, u); - if (ret) - return ret; - } else - size *= 6; - break; - default: - DRM_ERROR("Invalid texture coordinate type %u for unit " - "%u\n", track->textures[u].tex_coord_type, u); - return -EINVAL; - } - if (size > radeon_bo_size(robj)) { - DRM_ERROR("Texture of unit %u needs %lu bytes but is " - "%lu\n", u, size, radeon_bo_size(robj)); - r100_cs_track_texture_print(&track->textures[u]); - return -EINVAL; - } - } - return 0; -} - -int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) -{ - unsigned i; - unsigned long size; - unsigned prim_walk; - unsigned nverts; - unsigned num_cb = track->cb_dirty ? track->num_cb : 0; - - if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && - !track->blend_read_enable) - num_cb = 0; - - for (i = 0; i < num_cb; i++) { - if (track->cb[i].robj == NULL) { - DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); - return -EINVAL; - } - size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; - size += track->cb[i].offset; - if (size > radeon_bo_size(track->cb[i].robj)) { - DRM_ERROR("[drm] Buffer too small for color buffer %d " - "(need %lu have %lu) !\n", i, size, - radeon_bo_size(track->cb[i].robj)); - DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", - i, track->cb[i].pitch, track->cb[i].cpp, - track->cb[i].offset, track->maxy); - return -EINVAL; - } - } - track->cb_dirty = false; - - if (track->zb_dirty && track->z_enabled) { - if (track->zb.robj == NULL) { - DRM_ERROR("[drm] No buffer for z buffer !\n"); - return -EINVAL; - } - size = track->zb.pitch * track->zb.cpp * track->maxy; - size += track->zb.offset; - if (size > radeon_bo_size(track->zb.robj)) { - DRM_ERROR("[drm] Buffer too small for z buffer " - "(need %lu have %lu) !\n", size, - radeon_bo_size(track->zb.robj)); - DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", - track->zb.pitch, track->zb.cpp, - track->zb.offset, track->maxy); - return -EINVAL; - } - } - track->zb_dirty = false; - - if (track->aa_dirty && track->aaresolve) { - if (track->aa.robj == NULL) { - DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); - return -EINVAL; - } - /* I believe the format comes from colorbuffer0. */ - size = track->aa.pitch * track->cb[0].cpp * track->maxy; - size += track->aa.offset; - if (size > radeon_bo_size(track->aa.robj)) { - DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " - "(need %lu have %lu) !\n", i, size, - radeon_bo_size(track->aa.robj)); - DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", - i, track->aa.pitch, track->cb[0].cpp, - track->aa.offset, track->maxy); - return -EINVAL; - } - } - track->aa_dirty = false; - - prim_walk = (track->vap_vf_cntl >> 4) & 0x3; - if (track->vap_vf_cntl & (1 << 14)) { - nverts = track->vap_alt_nverts; - } else { - nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; - } - switch (prim_walk) { - case 1: - for (i = 0; i < track->num_arrays; i++) { - size = track->arrays[i].esize * track->max_indx * 4; - if (track->arrays[i].robj == NULL) { - DRM_ERROR("(PW %u) Vertex array %u no buffer " - "bound\n", prim_walk, i); - return -EINVAL; - } - if (size > radeon_bo_size(track->arrays[i].robj)) { - dev_err(rdev->dev, "(PW %u) Vertex array %u " - "need %lu dwords have %lu dwords\n", - prim_walk, i, size >> 2, - radeon_bo_size(track->arrays[i].robj) - >> 2); - DRM_ERROR("Max indices %u\n", track->max_indx); - return -EINVAL; - } - } - break; - case 2: - for (i = 0; i < track->num_arrays; i++) { - size = track->arrays[i].esize * (nverts - 1) * 4; - if (track->arrays[i].robj == NULL) { - DRM_ERROR("(PW %u) Vertex array %u no buffer " - "bound\n", prim_walk, i); - return -EINVAL; - } - if (size > radeon_bo_size(track->arrays[i].robj)) { - dev_err(rdev->dev, "(PW %u) Vertex array %u " - "need %lu dwords have %lu dwords\n", - prim_walk, i, size >> 2, - radeon_bo_size(track->arrays[i].robj) - >> 2); - return -EINVAL; - } - } - break; - case 3: - size = track->vtx_size * nverts; - if (size != track->immd_dwords) { - DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", - track->immd_dwords, size); - DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", - nverts, track->vtx_size); - return -EINVAL; - } - break; - default: - DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", - prim_walk); - return -EINVAL; - } - - if (track->tex_dirty) { - track->tex_dirty = false; - return r100_cs_track_texture_check(rdev, track); - } - return 0; -} - -void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) -{ - unsigned i, face; - - track->cb_dirty = true; - track->zb_dirty = true; - track->tex_dirty = true; - track->aa_dirty = true; - - if (rdev->family < CHIP_R300) { - track->num_cb = 1; - if (rdev->family <= CHIP_RS200) - track->num_texture = 3; - else - track->num_texture = 6; - track->maxy = 2048; - track->separate_cube = 1; - } else { - track->num_cb = 4; - track->num_texture = 16; - track->maxy = 4096; - track->separate_cube = 0; - track->aaresolve = false; - track->aa.robj = NULL; - } - - for (i = 0; i < track->num_cb; i++) { - track->cb[i].robj = NULL; - track->cb[i].pitch = 8192; - track->cb[i].cpp = 16; - track->cb[i].offset = 0; - } - track->z_enabled = true; - track->zb.robj = NULL; - track->zb.pitch = 8192; - track->zb.cpp = 4; - track->zb.offset = 0; - track->vtx_size = 0x7F; - track->immd_dwords = 0xFFFFFFFFUL; - track->num_arrays = 11; - track->max_indx = 0x00FFFFFFUL; - for (i = 0; i < track->num_arrays; i++) { - track->arrays[i].robj = NULL; - track->arrays[i].esize = 0x7F; - } - for (i = 0; i < track->num_texture; i++) { - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - track->textures[i].pitch = 16536; - track->textures[i].width = 16536; - track->textures[i].height = 16536; - track->textures[i].width_11 = 1 << 11; - track->textures[i].height_11 = 1 << 11; - track->textures[i].num_levels = 12; - if (rdev->family <= CHIP_RS200) { - track->textures[i].tex_coord_type = 0; - track->textures[i].txdepth = 0; - } else { - track->textures[i].txdepth = 16; - track->textures[i].tex_coord_type = 1; - } - track->textures[i].cpp = 64; - track->textures[i].robj = NULL; - /* CS IB emission code makes sure texture unit are disabled */ - track->textures[i].enabled = false; - track->textures[i].lookup_disable = false; - track->textures[i].roundup_w = true; - track->textures[i].roundup_h = true; - if (track->separate_cube) - for (face = 0; face < 5; face++) { - track->textures[i].cube_info[face].robj = NULL; - track->textures[i].cube_info[face].width = 16536; - track->textures[i].cube_info[face].height = 16536; - track->textures[i].cube_info[face].offset = 0; - } - } -} - -int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) -{ - uint32_t scratch; - uint32_t tmp = 0; - unsigned i; - int r; - - r = radeon_scratch_get(rdev, &scratch); - if (r) { - DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); - return r; - } - WREG32(scratch, 0xCAFEDEAD); - r = radeon_ring_lock(rdev, ring, 2); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - radeon_scratch_free(rdev, scratch); - return r; - } - radeon_ring_write(ring, PACKET0(scratch, 0)); - radeon_ring_write(ring, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, ring); - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(scratch); - if (tmp == 0xDEADBEEF) { - break; - } - DRM_UDELAY(1); - } - if (i < rdev->usec_timeout) { - DRM_INFO("ring test succeeded in %d usecs\n", i); - } else { - DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n", - scratch, tmp); - r = -EINVAL; - } - radeon_scratch_free(rdev, scratch); - return r; -} - -void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - - radeon_ring_write(ring, PACKET0(RADEON_CP_IB_BASE, 1)); - radeon_ring_write(ring, ib->gpu_addr); - radeon_ring_write(ring, ib->length_dw); -} - -int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) -{ - struct radeon_ib *ib; - uint32_t scratch; - uint32_t tmp = 0; - unsigned i; - int r; - - r = radeon_scratch_get(rdev, &scratch); - if (r) { - DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); - return r; - } - WREG32(scratch, 0xCAFEDEAD); - r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib, 256); - if (r) { - return r; - } - ib->ptr[0] = PACKET0(scratch, 0); - ib->ptr[1] = 0xDEADBEEF; - ib->ptr[2] = PACKET2(0); - ib->ptr[3] = PACKET2(0); - ib->ptr[4] = PACKET2(0); - ib->ptr[5] = PACKET2(0); - ib->ptr[6] = PACKET2(0); - ib->ptr[7] = PACKET2(0); - ib->length_dw = 8; - r = radeon_ib_schedule(rdev, ib); - if (r) { - radeon_scratch_free(rdev, scratch); - radeon_ib_free(rdev, &ib); - return r; - } - r = radeon_fence_wait(ib->fence, false); - if (r) { - return r; - } - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(scratch); - if (tmp == 0xDEADBEEF) { - break; - } - DRM_UDELAY(1); - } - if (i < rdev->usec_timeout) { - DRM_INFO("ib test succeeded in %u usecs\n", i); - } else { - DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", - scratch, tmp); - r = -EINVAL; - } - radeon_scratch_free(rdev, scratch); - radeon_ib_free(rdev, &ib); - return r; -} - -void r100_ib_fini(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - radeon_ib_pool_fini(rdev); -} - -void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) -{ - /* Shutdown CP we shouldn't need to do that but better be safe than - * sorry - */ - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - WREG32(R_000740_CP_CSQ_CNTL, 0); - - /* Save few CRTC registers */ - save->GENMO_WT = RREG8(R_0003C2_GENMO_WT); - save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); - save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); - save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL); - save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET); - } - - /* Disable VGA aperture access */ - WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT); - /* Disable cursor, overlay, crtc */ - WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); - WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | - S_000054_CRTC_DISPLAY_DIS(1)); - WREG32(R_000050_CRTC_GEN_CNTL, - (C_000050_CRTC_CUR_EN & save->CRTC_GEN_CNTL) | - S_000050_CRTC_DISP_REQ_EN_B(1)); - WREG32(R_000420_OV0_SCALE_CNTL, - C_000420_OV0_OVERLAY_EN & RREG32(R_000420_OV0_SCALE_CNTL)); - WREG32(R_000260_CUR_OFFSET, C_000260_CUR_LOCK & save->CUR_OFFSET); - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - WREG32(R_000360_CUR2_OFFSET, save->CUR2_OFFSET | - S_000360_CUR2_LOCK(1)); - WREG32(R_0003F8_CRTC2_GEN_CNTL, - (C_0003F8_CRTC2_CUR_EN & save->CRTC2_GEN_CNTL) | - S_0003F8_CRTC2_DISPLAY_DIS(1) | - S_0003F8_CRTC2_DISP_REQ_EN_B(1)); - WREG32(R_000360_CUR2_OFFSET, - C_000360_CUR2_LOCK & save->CUR2_OFFSET); - } -} - -void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save) -{ - /* Update base address for crtc */ - WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_start); - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, rdev->mc.vram_start); - } - /* Restore CRTC registers */ - WREG8(R_0003C2_GENMO_WT, save->GENMO_WT); - WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); - WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); - } -} - -void r100_vga_render_disable(struct radeon_device *rdev) -{ - u32 tmp; - - tmp = RREG8(R_0003C2_GENMO_WT); - WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp); -} - -static void r100_debugfs(struct radeon_device *rdev) -{ - int r; - - r = r100_debugfs_mc_info_init(rdev); - if (r) - dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n"); -} - -static void r100_mc_program(struct radeon_device *rdev) -{ - struct r100_mc_save save; - - /* Stops all mc clients */ - r100_mc_stop(rdev, &save); - if (rdev->flags & RADEON_IS_AGP) { - WREG32(R_00014C_MC_AGP_LOCATION, - S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | - S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); - WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); - if (rdev->family > CHIP_RV200) - WREG32(R_00015C_AGP_BASE_2, - upper_32_bits(rdev->mc.agp_base) & 0xff); - } else { - WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF); - WREG32(R_000170_AGP_BASE, 0); - if (rdev->family > CHIP_RV200) - WREG32(R_00015C_AGP_BASE_2, 0); - } - /* Wait for mc idle */ - if (r100_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait for MC idle timeout.\n"); - /* Program MC, should be a 32bits limited address space */ - WREG32(R_000148_MC_FB_LOCATION, - S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); - r100_mc_resume(rdev, &save); -} - -void r100_clock_startup(struct radeon_device *rdev) -{ - u32 tmp; - - if (radeon_dynclks != -1 && radeon_dynclks) - radeon_legacy_set_clock_gating(rdev, 1); - /* We need to force on some of the block */ - tmp = RREG32_PLL(R_00000D_SCLK_CNTL); - tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); - if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280)) - tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1); - WREG32_PLL(R_00000D_SCLK_CNTL, tmp); -} - -static int r100_startup(struct radeon_device *rdev) -{ - int r; - - /* set common regs */ - r100_set_common_regs(rdev); - /* program mc */ - r100_mc_program(rdev); - /* Resume clock */ - r100_clock_startup(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - r100_enable_bm(rdev); - if (rdev->flags & RADEON_IS_PCI) { - r = r100_pci_gart_enable(rdev); - if (r) - return r; - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r100_irq_set(rdev); - rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int r100_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_disable(rdev); - /* Resume clock before doing reset */ - r100_clock_startup(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - radeon_combios_asic_init(rdev->ddev); - /* Resume clock after posting */ - r100_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = r100_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int r100_suspend(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - r100_irq_disable(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_disable(rdev); - return 0; -} - -void r100_fini(struct radeon_device *rdev) -{ - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_fini(rdev); - radeon_agp_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -/* - * Due to how kexec works, it can leave the hw fully initialised when it - * boots the new kernel. However doing our init sequence with the CP and - * WB stuff setup causes GPU hangs on the RN50 at least. So at startup - * do some quick sanity checks and restore sane values to avoid this - * problem. - */ -void r100_restore_sanity(struct radeon_device *rdev) -{ - u32 tmp; - - tmp = RREG32(RADEON_CP_CSQ_CNTL); - if (tmp) { - WREG32(RADEON_CP_CSQ_CNTL, 0); - } - tmp = RREG32(RADEON_CP_RB_CNTL); - if (tmp) { - WREG32(RADEON_CP_RB_CNTL, 0); - } - tmp = RREG32(RADEON_SCRATCH_UMSK); - if (tmp) { - WREG32(RADEON_SCRATCH_UMSK, 0); - } -} - -int r100_init(struct radeon_device *rdev) -{ - int r; - - /* Register debugfs file specific to this group of asics */ - r100_debugfs(rdev); - /* Disable VGA */ - r100_vga_render_disable(rdev); - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* sanity check some register to avoid hangs like after kexec */ - r100_restore_sanity(rdev); - /* TODO: disable VGA need to use VGA request */ - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); - return -EINVAL; - } else { - r = radeon_combios_init(rdev); - if (r) - return r; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - /* Set asic errata */ - r100_errata(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } - } - /* initialize VRAM */ - r100_mc_init(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - if (rdev->flags & RADEON_IS_PCI) { - r = r100_pci_gart_init(rdev); - if (r) - return r; - } - r100_set_safe_registers(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = r100_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_fini(rdev); - rdev->accel_working = false; - } - return 0; -} - -uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) -{ - if (reg < rdev->rmmio_size) - return readl(((void __iomem *)rdev->rmmio) + reg); - else { - writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); - return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); - } -} - -void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - if (reg < rdev->rmmio_size) - writel(v, ((void __iomem *)rdev->rmmio) + reg); - else { - writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); - writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); - } -} - -u32 r100_io_rreg(struct radeon_device *rdev, u32 reg) -{ - if (reg < rdev->rio_mem_size) - return ioread32(rdev->rio_mem + reg); - else { - iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); - return ioread32(rdev->rio_mem + RADEON_MM_DATA); - } -} - -void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) -{ - if (reg < rdev->rio_mem_size) - iowrite32(v, rdev->rio_mem + reg); - else { - iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); - iowrite32(v, rdev->rio_mem + RADEON_MM_DATA); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100_track.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100_track.h deleted file mode 100644 index 6a603b37..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100_track.h +++ /dev/null @@ -1,101 +0,0 @@ - -#define R100_TRACK_MAX_TEXTURE 3 -#define R200_TRACK_MAX_TEXTURE 6 -#define R300_TRACK_MAX_TEXTURE 16 - -#define R100_MAX_CB 1 -#define R300_MAX_CB 4 - -/* - * CS functions - */ -struct r100_cs_track_cb { - struct radeon_bo *robj; - unsigned pitch; - unsigned cpp; - unsigned offset; -}; - -struct r100_cs_track_array { - struct radeon_bo *robj; - unsigned esize; -}; - -struct r100_cs_cube_info { - struct radeon_bo *robj; - unsigned offset; - unsigned width; - unsigned height; -}; - -#define R100_TRACK_COMP_NONE 0 -#define R100_TRACK_COMP_DXT1 1 -#define R100_TRACK_COMP_DXT35 2 - -struct r100_cs_track_texture { - struct radeon_bo *robj; - struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ - unsigned pitch; - unsigned width; - unsigned height; - unsigned num_levels; - unsigned cpp; - unsigned tex_coord_type; - unsigned txdepth; - unsigned width_11; - unsigned height_11; - bool use_pitch; - bool enabled; - bool lookup_disable; - bool roundup_w; - bool roundup_h; - unsigned compress_format; -}; - -struct r100_cs_track { - unsigned num_cb; - unsigned num_texture; - unsigned maxy; - unsigned vtx_size; - unsigned vap_vf_cntl; - unsigned vap_alt_nverts; - unsigned immd_dwords; - unsigned num_arrays; - unsigned max_indx; - unsigned color_channel_mask; - struct r100_cs_track_array arrays[16]; - struct r100_cs_track_cb cb[R300_MAX_CB]; - struct r100_cs_track_cb zb; - struct r100_cs_track_cb aa; - struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; - bool z_enabled; - bool separate_cube; - bool zb_cb_clear; - bool blend_read_enable; - bool cb_dirty; - bool zb_dirty; - bool tex_dirty; - bool aa_dirty; - bool aaresolve; -}; - -int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); -void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track); -int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); -void r100_cs_dump_packet(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt); - -int r100_cs_packet_parse_vline(struct radeon_cs_parser *p); - -int r200_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg); - -int r100_reloc_pitch_offset(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, - unsigned reg); -int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - int idx); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100d.h deleted file mode 100644 index eab91760..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r100d.h +++ /dev/null @@ -1,880 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __R100D_H__ -#define __R100D_H__ - -#define CP_PACKET0 0x00000000 -#define PACKET0_BASE_INDEX_SHIFT 0 -#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) -#define PACKET0_COUNT_SHIFT 16 -#define PACKET0_COUNT_MASK (0x3fff << 16) -#define CP_PACKET1 0x40000000 -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) -#define CP_PACKET3 0xC0000000 -#define PACKET3_IT_OPCODE_SHIFT 8 -#define PACKET3_IT_OPCODE_MASK (0xff << 8) -#define PACKET3_COUNT_SHIFT 16 -#define PACKET3_COUNT_MASK (0x3fff << 16) -/* PACKET3 op code */ -#define PACKET3_NOP 0x10 -#define PACKET3_3D_DRAW_VBUF 0x28 -#define PACKET3_3D_DRAW_IMMD 0x29 -#define PACKET3_3D_DRAW_INDX 0x2A -#define PACKET3_3D_LOAD_VBPNTR 0x2F -#define PACKET3_3D_CLEAR_ZMASK 0x32 -#define PACKET3_INDX_BUFFER 0x33 -#define PACKET3_3D_DRAW_VBUF_2 0x34 -#define PACKET3_3D_DRAW_IMMD_2 0x35 -#define PACKET3_3D_DRAW_INDX_2 0x36 -#define PACKET3_3D_CLEAR_HIZ 0x37 -#define PACKET3_BITBLT_MULTI 0x9B - -#define PACKET0(reg, n) (CP_PACKET0 | \ - REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ - REG_SET(PACKET0_COUNT, (n))) -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -#define PACKET3(op, n) (CP_PACKET3 | \ - REG_SET(PACKET3_IT_OPCODE, (op)) | \ - REG_SET(PACKET3_COUNT, (n))) - -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) - -/* Registers */ -#define R_0000F0_RBBM_SOFT_RESET 0x0000F0 -#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) -#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) -#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE -#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) -#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) -#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD -#define S_0000F0_SOFT_RESET_SE(x) (((x) & 0x1) << 2) -#define G_0000F0_SOFT_RESET_SE(x) (((x) >> 2) & 0x1) -#define C_0000F0_SOFT_RESET_SE 0xFFFFFFFB -#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) -#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) -#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 -#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) -#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) -#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF -#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) -#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) -#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF -#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) -#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) -#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF -#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) -#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) -#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F -#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) -#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) -#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF -#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) -#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) -#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF -#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) -#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) -#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF -#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) -#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) -#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF -#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) -#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) -#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF -#define R_000030_BUS_CNTL 0x000030 -#define S_000030_BUS_DBL_RESYNC(x) (((x) & 0x1) << 0) -#define G_000030_BUS_DBL_RESYNC(x) (((x) >> 0) & 0x1) -#define C_000030_BUS_DBL_RESYNC 0xFFFFFFFE -#define S_000030_BUS_MSTR_RESET(x) (((x) & 0x1) << 1) -#define G_000030_BUS_MSTR_RESET(x) (((x) >> 1) & 0x1) -#define C_000030_BUS_MSTR_RESET 0xFFFFFFFD -#define S_000030_BUS_FLUSH_BUF(x) (((x) & 0x1) << 2) -#define G_000030_BUS_FLUSH_BUF(x) (((x) >> 2) & 0x1) -#define C_000030_BUS_FLUSH_BUF 0xFFFFFFFB -#define S_000030_BUS_STOP_REQ_DIS(x) (((x) & 0x1) << 3) -#define G_000030_BUS_STOP_REQ_DIS(x) (((x) >> 3) & 0x1) -#define C_000030_BUS_STOP_REQ_DIS 0xFFFFFFF7 -#define S_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 4) -#define G_000030_BUS_PM4_READ_COMBINE_EN(x) (((x) >> 4) & 0x1) -#define C_000030_BUS_PM4_READ_COMBINE_EN 0xFFFFFFEF -#define S_000030_BUS_WRT_COMBINE_EN(x) (((x) & 0x1) << 5) -#define G_000030_BUS_WRT_COMBINE_EN(x) (((x) >> 5) & 0x1) -#define C_000030_BUS_WRT_COMBINE_EN 0xFFFFFFDF -#define S_000030_BUS_MASTER_DIS(x) (((x) & 0x1) << 6) -#define G_000030_BUS_MASTER_DIS(x) (((x) >> 6) & 0x1) -#define C_000030_BUS_MASTER_DIS 0xFFFFFFBF -#define S_000030_BIOS_ROM_WRT_EN(x) (((x) & 0x1) << 7) -#define G_000030_BIOS_ROM_WRT_EN(x) (((x) >> 7) & 0x1) -#define C_000030_BIOS_ROM_WRT_EN 0xFFFFFF7F -#define S_000030_BM_DAC_CRIPPLE(x) (((x) & 0x1) << 8) -#define G_000030_BM_DAC_CRIPPLE(x) (((x) >> 8) & 0x1) -#define C_000030_BM_DAC_CRIPPLE 0xFFFFFEFF -#define S_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) & 0x1) << 9) -#define G_000030_BUS_NON_PM4_READ_COMBINE_EN(x) (((x) >> 9) & 0x1) -#define C_000030_BUS_NON_PM4_READ_COMBINE_EN 0xFFFFFDFF -#define S_000030_BUS_XFERD_DISCARD_EN(x) (((x) & 0x1) << 10) -#define G_000030_BUS_XFERD_DISCARD_EN(x) (((x) >> 10) & 0x1) -#define C_000030_BUS_XFERD_DISCARD_EN 0xFFFFFBFF -#define S_000030_BUS_SGL_READ_DISABLE(x) (((x) & 0x1) << 11) -#define G_000030_BUS_SGL_READ_DISABLE(x) (((x) >> 11) & 0x1) -#define C_000030_BUS_SGL_READ_DISABLE 0xFFFFF7FF -#define S_000030_BIOS_DIS_ROM(x) (((x) & 0x1) << 12) -#define G_000030_BIOS_DIS_ROM(x) (((x) >> 12) & 0x1) -#define C_000030_BIOS_DIS_ROM 0xFFFFEFFF -#define S_000030_BUS_PCI_READ_RETRY_EN(x) (((x) & 0x1) << 13) -#define G_000030_BUS_PCI_READ_RETRY_EN(x) (((x) >> 13) & 0x1) -#define C_000030_BUS_PCI_READ_RETRY_EN 0xFFFFDFFF -#define S_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) & 0x1) << 14) -#define G_000030_BUS_AGP_AD_STEPPING_EN(x) (((x) >> 14) & 0x1) -#define C_000030_BUS_AGP_AD_STEPPING_EN 0xFFFFBFFF -#define S_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) & 0x1) << 15) -#define G_000030_BUS_PCI_WRT_RETRY_EN(x) (((x) >> 15) & 0x1) -#define C_000030_BUS_PCI_WRT_RETRY_EN 0xFFFF7FFF -#define S_000030_BUS_RETRY_WS(x) (((x) & 0xF) << 16) -#define G_000030_BUS_RETRY_WS(x) (((x) >> 16) & 0xF) -#define C_000030_BUS_RETRY_WS 0xFFF0FFFF -#define S_000030_BUS_MSTR_RD_MULT(x) (((x) & 0x1) << 20) -#define G_000030_BUS_MSTR_RD_MULT(x) (((x) >> 20) & 0x1) -#define C_000030_BUS_MSTR_RD_MULT 0xFFEFFFFF -#define S_000030_BUS_MSTR_RD_LINE(x) (((x) & 0x1) << 21) -#define G_000030_BUS_MSTR_RD_LINE(x) (((x) >> 21) & 0x1) -#define C_000030_BUS_MSTR_RD_LINE 0xFFDFFFFF -#define S_000030_BUS_SUSPEND(x) (((x) & 0x1) << 22) -#define G_000030_BUS_SUSPEND(x) (((x) >> 22) & 0x1) -#define C_000030_BUS_SUSPEND 0xFFBFFFFF -#define S_000030_LAT_16X(x) (((x) & 0x1) << 23) -#define G_000030_LAT_16X(x) (((x) >> 23) & 0x1) -#define C_000030_LAT_16X 0xFF7FFFFF -#define S_000030_BUS_RD_DISCARD_EN(x) (((x) & 0x1) << 24) -#define G_000030_BUS_RD_DISCARD_EN(x) (((x) >> 24) & 0x1) -#define C_000030_BUS_RD_DISCARD_EN 0xFEFFFFFF -#define S_000030_ENFRCWRDY(x) (((x) & 0x1) << 25) -#define G_000030_ENFRCWRDY(x) (((x) >> 25) & 0x1) -#define C_000030_ENFRCWRDY 0xFDFFFFFF -#define S_000030_BUS_MSTR_WS(x) (((x) & 0x1) << 26) -#define G_000030_BUS_MSTR_WS(x) (((x) >> 26) & 0x1) -#define C_000030_BUS_MSTR_WS 0xFBFFFFFF -#define S_000030_BUS_PARKING_DIS(x) (((x) & 0x1) << 27) -#define G_000030_BUS_PARKING_DIS(x) (((x) >> 27) & 0x1) -#define C_000030_BUS_PARKING_DIS 0xF7FFFFFF -#define S_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) & 0x1) << 28) -#define G_000030_BUS_MSTR_DISCONNECT_EN(x) (((x) >> 28) & 0x1) -#define C_000030_BUS_MSTR_DISCONNECT_EN 0xEFFFFFFF -#define S_000030_SERR_EN(x) (((x) & 0x1) << 29) -#define G_000030_SERR_EN(x) (((x) >> 29) & 0x1) -#define C_000030_SERR_EN 0xDFFFFFFF -#define S_000030_BUS_READ_BURST(x) (((x) & 0x1) << 30) -#define G_000030_BUS_READ_BURST(x) (((x) >> 30) & 0x1) -#define C_000030_BUS_READ_BURST 0xBFFFFFFF -#define S_000030_BUS_RDY_READ_DLY(x) (((x) & 0x1) << 31) -#define G_000030_BUS_RDY_READ_DLY(x) (((x) >> 31) & 0x1) -#define C_000030_BUS_RDY_READ_DLY 0x7FFFFFFF -#define R_000040_GEN_INT_CNTL 0x000040 -#define S_000040_CRTC_VBLANK(x) (((x) & 0x1) << 0) -#define G_000040_CRTC_VBLANK(x) (((x) >> 0) & 0x1) -#define C_000040_CRTC_VBLANK 0xFFFFFFFE -#define S_000040_CRTC_VLINE(x) (((x) & 0x1) << 1) -#define G_000040_CRTC_VLINE(x) (((x) >> 1) & 0x1) -#define C_000040_CRTC_VLINE 0xFFFFFFFD -#define S_000040_CRTC_VSYNC(x) (((x) & 0x1) << 2) -#define G_000040_CRTC_VSYNC(x) (((x) >> 2) & 0x1) -#define C_000040_CRTC_VSYNC 0xFFFFFFFB -#define S_000040_SNAPSHOT(x) (((x) & 0x1) << 3) -#define G_000040_SNAPSHOT(x) (((x) >> 3) & 0x1) -#define C_000040_SNAPSHOT 0xFFFFFFF7 -#define S_000040_FP_DETECT(x) (((x) & 0x1) << 4) -#define G_000040_FP_DETECT(x) (((x) >> 4) & 0x1) -#define C_000040_FP_DETECT 0xFFFFFFEF -#define S_000040_CRTC2_VLINE(x) (((x) & 0x1) << 5) -#define G_000040_CRTC2_VLINE(x) (((x) >> 5) & 0x1) -#define C_000040_CRTC2_VLINE 0xFFFFFFDF -#define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12) -#define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1) -#define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF -#define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6) -#define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1) -#define C_000040_CRTC2_VSYNC 0xFFFFFFBF -#define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7) -#define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1) -#define C_000040_SNAPSHOT2 0xFFFFFF7F -#define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9) -#define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1) -#define C_000040_CRTC2_VBLANK 0xFFFFFDFF -#define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10) -#define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1) -#define C_000040_FP2_DETECT 0xFFFFFBFF -#define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11) -#define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1) -#define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF -#define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) -#define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) -#define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF -#define S_000040_DMA_VIPH2_INT_EN(x) (((x) & 0x1) << 14) -#define G_000040_DMA_VIPH2_INT_EN(x) (((x) >> 14) & 0x1) -#define C_000040_DMA_VIPH2_INT_EN 0xFFFFBFFF -#define S_000040_DMA_VIPH3_INT_EN(x) (((x) & 0x1) << 15) -#define G_000040_DMA_VIPH3_INT_EN(x) (((x) >> 15) & 0x1) -#define C_000040_DMA_VIPH3_INT_EN 0xFFFF7FFF -#define S_000040_I2C_INT_EN(x) (((x) & 0x1) << 17) -#define G_000040_I2C_INT_EN(x) (((x) >> 17) & 0x1) -#define C_000040_I2C_INT_EN 0xFFFDFFFF -#define S_000040_GUI_IDLE(x) (((x) & 0x1) << 19) -#define G_000040_GUI_IDLE(x) (((x) >> 19) & 0x1) -#define C_000040_GUI_IDLE 0xFFF7FFFF -#define S_000040_VIPH_INT_EN(x) (((x) & 0x1) << 24) -#define G_000040_VIPH_INT_EN(x) (((x) >> 24) & 0x1) -#define C_000040_VIPH_INT_EN 0xFEFFFFFF -#define S_000040_SW_INT_EN(x) (((x) & 0x1) << 25) -#define G_000040_SW_INT_EN(x) (((x) >> 25) & 0x1) -#define C_000040_SW_INT_EN 0xFDFFFFFF -#define S_000040_GEYSERVILLE(x) (((x) & 0x1) << 27) -#define G_000040_GEYSERVILLE(x) (((x) >> 27) & 0x1) -#define C_000040_GEYSERVILLE 0xF7FFFFFF -#define S_000040_HDCP_AUTHORIZED_INT(x) (((x) & 0x1) << 28) -#define G_000040_HDCP_AUTHORIZED_INT(x) (((x) >> 28) & 0x1) -#define C_000040_HDCP_AUTHORIZED_INT 0xEFFFFFFF -#define S_000040_DVI_I2C_INT(x) (((x) & 0x1) << 29) -#define G_000040_DVI_I2C_INT(x) (((x) >> 29) & 0x1) -#define C_000040_DVI_I2C_INT 0xDFFFFFFF -#define S_000040_GUIDMA(x) (((x) & 0x1) << 30) -#define G_000040_GUIDMA(x) (((x) >> 30) & 0x1) -#define C_000040_GUIDMA 0xBFFFFFFF -#define S_000040_VIDDMA(x) (((x) & 0x1) << 31) -#define G_000040_VIDDMA(x) (((x) >> 31) & 0x1) -#define C_000040_VIDDMA 0x7FFFFFFF -#define R_000044_GEN_INT_STATUS 0x000044 -#define S_000044_CRTC_VBLANK_STAT(x) (((x) & 0x1) << 0) -#define G_000044_CRTC_VBLANK_STAT(x) (((x) >> 0) & 0x1) -#define C_000044_CRTC_VBLANK_STAT 0xFFFFFFFE -#define S_000044_CRTC_VBLANK_STAT_AK(x) (((x) & 0x1) << 0) -#define G_000044_CRTC_VBLANK_STAT_AK(x) (((x) >> 0) & 0x1) -#define C_000044_CRTC_VBLANK_STAT_AK 0xFFFFFFFE -#define S_000044_CRTC_VLINE_STAT(x) (((x) & 0x1) << 1) -#define G_000044_CRTC_VLINE_STAT(x) (((x) >> 1) & 0x1) -#define C_000044_CRTC_VLINE_STAT 0xFFFFFFFD -#define S_000044_CRTC_VLINE_STAT_AK(x) (((x) & 0x1) << 1) -#define G_000044_CRTC_VLINE_STAT_AK(x) (((x) >> 1) & 0x1) -#define C_000044_CRTC_VLINE_STAT_AK 0xFFFFFFFD -#define S_000044_CRTC_VSYNC_STAT(x) (((x) & 0x1) << 2) -#define G_000044_CRTC_VSYNC_STAT(x) (((x) >> 2) & 0x1) -#define C_000044_CRTC_VSYNC_STAT 0xFFFFFFFB -#define S_000044_CRTC_VSYNC_STAT_AK(x) (((x) & 0x1) << 2) -#define G_000044_CRTC_VSYNC_STAT_AK(x) (((x) >> 2) & 0x1) -#define C_000044_CRTC_VSYNC_STAT_AK 0xFFFFFFFB -#define S_000044_SNAPSHOT_STAT(x) (((x) & 0x1) << 3) -#define G_000044_SNAPSHOT_STAT(x) (((x) >> 3) & 0x1) -#define C_000044_SNAPSHOT_STAT 0xFFFFFFF7 -#define S_000044_SNAPSHOT_STAT_AK(x) (((x) & 0x1) << 3) -#define G_000044_SNAPSHOT_STAT_AK(x) (((x) >> 3) & 0x1) -#define C_000044_SNAPSHOT_STAT_AK 0xFFFFFFF7 -#define S_000044_FP_DETECT_STAT(x) (((x) & 0x1) << 4) -#define G_000044_FP_DETECT_STAT(x) (((x) >> 4) & 0x1) -#define C_000044_FP_DETECT_STAT 0xFFFFFFEF -#define S_000044_FP_DETECT_STAT_AK(x) (((x) & 0x1) << 4) -#define G_000044_FP_DETECT_STAT_AK(x) (((x) >> 4) & 0x1) -#define C_000044_FP_DETECT_STAT_AK 0xFFFFFFEF -#define S_000044_CRTC2_VLINE_STAT(x) (((x) & 0x1) << 5) -#define G_000044_CRTC2_VLINE_STAT(x) (((x) >> 5) & 0x1) -#define C_000044_CRTC2_VLINE_STAT 0xFFFFFFDF -#define S_000044_CRTC2_VLINE_STAT_AK(x) (((x) & 0x1) << 5) -#define G_000044_CRTC2_VLINE_STAT_AK(x) (((x) >> 5) & 0x1) -#define C_000044_CRTC2_VLINE_STAT_AK 0xFFFFFFDF -#define S_000044_CRTC2_VSYNC_STAT(x) (((x) & 0x1) << 6) -#define G_000044_CRTC2_VSYNC_STAT(x) (((x) >> 6) & 0x1) -#define C_000044_CRTC2_VSYNC_STAT 0xFFFFFFBF -#define S_000044_CRTC2_VSYNC_STAT_AK(x) (((x) & 0x1) << 6) -#define G_000044_CRTC2_VSYNC_STAT_AK(x) (((x) >> 6) & 0x1) -#define C_000044_CRTC2_VSYNC_STAT_AK 0xFFFFFFBF -#define S_000044_SNAPSHOT2_STAT(x) (((x) & 0x1) << 7) -#define G_000044_SNAPSHOT2_STAT(x) (((x) >> 7) & 0x1) -#define C_000044_SNAPSHOT2_STAT 0xFFFFFF7F -#define S_000044_SNAPSHOT2_STAT_AK(x) (((x) & 0x1) << 7) -#define G_000044_SNAPSHOT2_STAT_AK(x) (((x) >> 7) & 0x1) -#define C_000044_SNAPSHOT2_STAT_AK 0xFFFFFF7F -#define S_000044_CAP0_INT_ACTIVE(x) (((x) & 0x1) << 8) -#define G_000044_CAP0_INT_ACTIVE(x) (((x) >> 8) & 0x1) -#define C_000044_CAP0_INT_ACTIVE 0xFFFFFEFF -#define S_000044_CRTC2_VBLANK_STAT(x) (((x) & 0x1) << 9) -#define G_000044_CRTC2_VBLANK_STAT(x) (((x) >> 9) & 0x1) -#define C_000044_CRTC2_VBLANK_STAT 0xFFFFFDFF -#define S_000044_CRTC2_VBLANK_STAT_AK(x) (((x) & 0x1) << 9) -#define G_000044_CRTC2_VBLANK_STAT_AK(x) (((x) >> 9) & 0x1) -#define C_000044_CRTC2_VBLANK_STAT_AK 0xFFFFFDFF -#define S_000044_FP2_DETECT_STAT(x) (((x) & 0x1) << 10) -#define G_000044_FP2_DETECT_STAT(x) (((x) >> 10) & 0x1) -#define C_000044_FP2_DETECT_STAT 0xFFFFFBFF -#define S_000044_FP2_DETECT_STAT_AK(x) (((x) & 0x1) << 10) -#define G_000044_FP2_DETECT_STAT_AK(x) (((x) >> 10) & 0x1) -#define C_000044_FP2_DETECT_STAT_AK 0xFFFFFBFF -#define S_000044_VSYNC_DIFF_OVER_LIMIT_STAT(x) (((x) & 0x1) << 11) -#define G_000044_VSYNC_DIFF_OVER_LIMIT_STAT(x) (((x) >> 11) & 0x1) -#define C_000044_VSYNC_DIFF_OVER_LIMIT_STAT 0xFFFFF7FF -#define S_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK(x) (((x) & 0x1) << 11) -#define G_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK(x) (((x) >> 11) & 0x1) -#define C_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK 0xFFFFF7FF -#define S_000044_DMA_VIPH0_INT(x) (((x) & 0x1) << 12) -#define G_000044_DMA_VIPH0_INT(x) (((x) >> 12) & 0x1) -#define C_000044_DMA_VIPH0_INT 0xFFFFEFFF -#define S_000044_DMA_VIPH0_INT_AK(x) (((x) & 0x1) << 12) -#define G_000044_DMA_VIPH0_INT_AK(x) (((x) >> 12) & 0x1) -#define C_000044_DMA_VIPH0_INT_AK 0xFFFFEFFF -#define S_000044_DMA_VIPH1_INT(x) (((x) & 0x1) << 13) -#define G_000044_DMA_VIPH1_INT(x) (((x) >> 13) & 0x1) -#define C_000044_DMA_VIPH1_INT 0xFFFFDFFF -#define S_000044_DMA_VIPH1_INT_AK(x) (((x) & 0x1) << 13) -#define G_000044_DMA_VIPH1_INT_AK(x) (((x) >> 13) & 0x1) -#define C_000044_DMA_VIPH1_INT_AK 0xFFFFDFFF -#define S_000044_DMA_VIPH2_INT(x) (((x) & 0x1) << 14) -#define G_000044_DMA_VIPH2_INT(x) (((x) >> 14) & 0x1) -#define C_000044_DMA_VIPH2_INT 0xFFFFBFFF -#define S_000044_DMA_VIPH2_INT_AK(x) (((x) & 0x1) << 14) -#define G_000044_DMA_VIPH2_INT_AK(x) (((x) >> 14) & 0x1) -#define C_000044_DMA_VIPH2_INT_AK 0xFFFFBFFF -#define S_000044_DMA_VIPH3_INT(x) (((x) & 0x1) << 15) -#define G_000044_DMA_VIPH3_INT(x) (((x) >> 15) & 0x1) -#define C_000044_DMA_VIPH3_INT 0xFFFF7FFF -#define S_000044_DMA_VIPH3_INT_AK(x) (((x) & 0x1) << 15) -#define G_000044_DMA_VIPH3_INT_AK(x) (((x) >> 15) & 0x1) -#define C_000044_DMA_VIPH3_INT_AK 0xFFFF7FFF -#define S_000044_I2C_INT(x) (((x) & 0x1) << 17) -#define G_000044_I2C_INT(x) (((x) >> 17) & 0x1) -#define C_000044_I2C_INT 0xFFFDFFFF -#define S_000044_I2C_INT_AK(x) (((x) & 0x1) << 17) -#define G_000044_I2C_INT_AK(x) (((x) >> 17) & 0x1) -#define C_000044_I2C_INT_AK 0xFFFDFFFF -#define S_000044_GUI_IDLE_STAT(x) (((x) & 0x1) << 19) -#define G_000044_GUI_IDLE_STAT(x) (((x) >> 19) & 0x1) -#define C_000044_GUI_IDLE_STAT 0xFFF7FFFF -#define S_000044_GUI_IDLE_STAT_AK(x) (((x) & 0x1) << 19) -#define G_000044_GUI_IDLE_STAT_AK(x) (((x) >> 19) & 0x1) -#define C_000044_GUI_IDLE_STAT_AK 0xFFF7FFFF -#define S_000044_VIPH_INT(x) (((x) & 0x1) << 24) -#define G_000044_VIPH_INT(x) (((x) >> 24) & 0x1) -#define C_000044_VIPH_INT 0xFEFFFFFF -#define S_000044_SW_INT(x) (((x) & 0x1) << 25) -#define G_000044_SW_INT(x) (((x) >> 25) & 0x1) -#define C_000044_SW_INT 0xFDFFFFFF -#define S_000044_SW_INT_AK(x) (((x) & 0x1) << 25) -#define G_000044_SW_INT_AK(x) (((x) >> 25) & 0x1) -#define C_000044_SW_INT_AK 0xFDFFFFFF -#define S_000044_SW_INT_SET(x) (((x) & 0x1) << 26) -#define G_000044_SW_INT_SET(x) (((x) >> 26) & 0x1) -#define C_000044_SW_INT_SET 0xFBFFFFFF -#define S_000044_GEYSERVILLE_STAT(x) (((x) & 0x1) << 27) -#define G_000044_GEYSERVILLE_STAT(x) (((x) >> 27) & 0x1) -#define C_000044_GEYSERVILLE_STAT 0xF7FFFFFF -#define S_000044_GEYSERVILLE_STAT_AK(x) (((x) & 0x1) << 27) -#define G_000044_GEYSERVILLE_STAT_AK(x) (((x) >> 27) & 0x1) -#define C_000044_GEYSERVILLE_STAT_AK 0xF7FFFFFF -#define S_000044_HDCP_AUTHORIZED_INT_STAT(x) (((x) & 0x1) << 28) -#define G_000044_HDCP_AUTHORIZED_INT_STAT(x) (((x) >> 28) & 0x1) -#define C_000044_HDCP_AUTHORIZED_INT_STAT 0xEFFFFFFF -#define S_000044_HDCP_AUTHORIZED_INT_AK(x) (((x) & 0x1) << 28) -#define G_000044_HDCP_AUTHORIZED_INT_AK(x) (((x) >> 28) & 0x1) -#define C_000044_HDCP_AUTHORIZED_INT_AK 0xEFFFFFFF -#define S_000044_DVI_I2C_INT_STAT(x) (((x) & 0x1) << 29) -#define G_000044_DVI_I2C_INT_STAT(x) (((x) >> 29) & 0x1) -#define C_000044_DVI_I2C_INT_STAT 0xDFFFFFFF -#define S_000044_DVI_I2C_INT_AK(x) (((x) & 0x1) << 29) -#define G_000044_DVI_I2C_INT_AK(x) (((x) >> 29) & 0x1) -#define C_000044_DVI_I2C_INT_AK 0xDFFFFFFF -#define S_000044_GUIDMA_STAT(x) (((x) & 0x1) << 30) -#define G_000044_GUIDMA_STAT(x) (((x) >> 30) & 0x1) -#define C_000044_GUIDMA_STAT 0xBFFFFFFF -#define S_000044_GUIDMA_AK(x) (((x) & 0x1) << 30) -#define G_000044_GUIDMA_AK(x) (((x) >> 30) & 0x1) -#define C_000044_GUIDMA_AK 0xBFFFFFFF -#define S_000044_VIDDMA_STAT(x) (((x) & 0x1) << 31) -#define G_000044_VIDDMA_STAT(x) (((x) >> 31) & 0x1) -#define C_000044_VIDDMA_STAT 0x7FFFFFFF -#define S_000044_VIDDMA_AK(x) (((x) & 0x1) << 31) -#define G_000044_VIDDMA_AK(x) (((x) >> 31) & 0x1) -#define C_000044_VIDDMA_AK 0x7FFFFFFF -#define R_000050_CRTC_GEN_CNTL 0x000050 -#define S_000050_CRTC_DBL_SCAN_EN(x) (((x) & 0x1) << 0) -#define G_000050_CRTC_DBL_SCAN_EN(x) (((x) >> 0) & 0x1) -#define C_000050_CRTC_DBL_SCAN_EN 0xFFFFFFFE -#define S_000050_CRTC_INTERLACE_EN(x) (((x) & 0x1) << 1) -#define G_000050_CRTC_INTERLACE_EN(x) (((x) >> 1) & 0x1) -#define C_000050_CRTC_INTERLACE_EN 0xFFFFFFFD -#define S_000050_CRTC_C_SYNC_EN(x) (((x) & 0x1) << 4) -#define G_000050_CRTC_C_SYNC_EN(x) (((x) >> 4) & 0x1) -#define C_000050_CRTC_C_SYNC_EN 0xFFFFFFEF -#define S_000050_CRTC_PIX_WIDTH(x) (((x) & 0xF) << 8) -#define G_000050_CRTC_PIX_WIDTH(x) (((x) >> 8) & 0xF) -#define C_000050_CRTC_PIX_WIDTH 0xFFFFF0FF -#define S_000050_CRTC_ICON_EN(x) (((x) & 0x1) << 15) -#define G_000050_CRTC_ICON_EN(x) (((x) >> 15) & 0x1) -#define C_000050_CRTC_ICON_EN 0xFFFF7FFF -#define S_000050_CRTC_CUR_EN(x) (((x) & 0x1) << 16) -#define G_000050_CRTC_CUR_EN(x) (((x) >> 16) & 0x1) -#define C_000050_CRTC_CUR_EN 0xFFFEFFFF -#define S_000050_CRTC_VSTAT_MODE(x) (((x) & 0x3) << 17) -#define G_000050_CRTC_VSTAT_MODE(x) (((x) >> 17) & 0x3) -#define C_000050_CRTC_VSTAT_MODE 0xFFF9FFFF -#define S_000050_CRTC_CUR_MODE(x) (((x) & 0x7) << 20) -#define G_000050_CRTC_CUR_MODE(x) (((x) >> 20) & 0x7) -#define C_000050_CRTC_CUR_MODE 0xFF8FFFFF -#define S_000050_CRTC_EXT_DISP_EN(x) (((x) & 0x1) << 24) -#define G_000050_CRTC_EXT_DISP_EN(x) (((x) >> 24) & 0x1) -#define C_000050_CRTC_EXT_DISP_EN 0xFEFFFFFF -#define S_000050_CRTC_EN(x) (((x) & 0x1) << 25) -#define G_000050_CRTC_EN(x) (((x) >> 25) & 0x1) -#define C_000050_CRTC_EN 0xFDFFFFFF -#define S_000050_CRTC_DISP_REQ_EN_B(x) (((x) & 0x1) << 26) -#define G_000050_CRTC_DISP_REQ_EN_B(x) (((x) >> 26) & 0x1) -#define C_000050_CRTC_DISP_REQ_EN_B 0xFBFFFFFF -#define R_000054_CRTC_EXT_CNTL 0x000054 -#define S_000054_CRTC_VGA_XOVERSCAN(x) (((x) & 0x1) << 0) -#define G_000054_CRTC_VGA_XOVERSCAN(x) (((x) >> 0) & 0x1) -#define C_000054_CRTC_VGA_XOVERSCAN 0xFFFFFFFE -#define S_000054_VGA_BLINK_RATE(x) (((x) & 0x3) << 1) -#define G_000054_VGA_BLINK_RATE(x) (((x) >> 1) & 0x3) -#define C_000054_VGA_BLINK_RATE 0xFFFFFFF9 -#define S_000054_VGA_ATI_LINEAR(x) (((x) & 0x1) << 3) -#define G_000054_VGA_ATI_LINEAR(x) (((x) >> 3) & 0x1) -#define C_000054_VGA_ATI_LINEAR 0xFFFFFFF7 -#define S_000054_VGA_128KAP_PAGING(x) (((x) & 0x1) << 4) -#define G_000054_VGA_128KAP_PAGING(x) (((x) >> 4) & 0x1) -#define C_000054_VGA_128KAP_PAGING 0xFFFFFFEF -#define S_000054_VGA_TEXT_132(x) (((x) & 0x1) << 5) -#define G_000054_VGA_TEXT_132(x) (((x) >> 5) & 0x1) -#define C_000054_VGA_TEXT_132 0xFFFFFFDF -#define S_000054_VGA_XCRT_CNT_EN(x) (((x) & 0x1) << 6) -#define G_000054_VGA_XCRT_CNT_EN(x) (((x) >> 6) & 0x1) -#define C_000054_VGA_XCRT_CNT_EN 0xFFFFFFBF -#define S_000054_CRTC_HSYNC_DIS(x) (((x) & 0x1) << 8) -#define G_000054_CRTC_HSYNC_DIS(x) (((x) >> 8) & 0x1) -#define C_000054_CRTC_HSYNC_DIS 0xFFFFFEFF -#define S_000054_CRTC_VSYNC_DIS(x) (((x) & 0x1) << 9) -#define G_000054_CRTC_VSYNC_DIS(x) (((x) >> 9) & 0x1) -#define C_000054_CRTC_VSYNC_DIS 0xFFFFFDFF -#define S_000054_CRTC_DISPLAY_DIS(x) (((x) & 0x1) << 10) -#define G_000054_CRTC_DISPLAY_DIS(x) (((x) >> 10) & 0x1) -#define C_000054_CRTC_DISPLAY_DIS 0xFFFFFBFF -#define S_000054_CRTC_SYNC_TRISTATE(x) (((x) & 0x1) << 11) -#define G_000054_CRTC_SYNC_TRISTATE(x) (((x) >> 11) & 0x1) -#define C_000054_CRTC_SYNC_TRISTATE 0xFFFFF7FF -#define S_000054_CRTC_HSYNC_TRISTATE(x) (((x) & 0x1) << 12) -#define G_000054_CRTC_HSYNC_TRISTATE(x) (((x) >> 12) & 0x1) -#define C_000054_CRTC_HSYNC_TRISTATE 0xFFFFEFFF -#define S_000054_CRTC_VSYNC_TRISTATE(x) (((x) & 0x1) << 13) -#define G_000054_CRTC_VSYNC_TRISTATE(x) (((x) >> 13) & 0x1) -#define C_000054_CRTC_VSYNC_TRISTATE 0xFFFFDFFF -#define S_000054_CRT_ON(x) (((x) & 0x1) << 15) -#define G_000054_CRT_ON(x) (((x) >> 15) & 0x1) -#define C_000054_CRT_ON 0xFFFF7FFF -#define S_000054_VGA_CUR_B_TEST(x) (((x) & 0x1) << 17) -#define G_000054_VGA_CUR_B_TEST(x) (((x) >> 17) & 0x1) -#define C_000054_VGA_CUR_B_TEST 0xFFFDFFFF -#define S_000054_VGA_PACK_DIS(x) (((x) & 0x1) << 18) -#define G_000054_VGA_PACK_DIS(x) (((x) >> 18) & 0x1) -#define C_000054_VGA_PACK_DIS 0xFFFBFFFF -#define S_000054_VGA_MEM_PS_EN(x) (((x) & 0x1) << 19) -#define G_000054_VGA_MEM_PS_EN(x) (((x) >> 19) & 0x1) -#define C_000054_VGA_MEM_PS_EN 0xFFF7FFFF -#define S_000054_VCRTC_IDX_MASTER(x) (((x) & 0x7F) << 24) -#define G_000054_VCRTC_IDX_MASTER(x) (((x) >> 24) & 0x7F) -#define C_000054_VCRTC_IDX_MASTER 0x80FFFFFF -#define R_000148_MC_FB_LOCATION 0x000148 -#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000148_MC_FB_START 0xFFFF0000 -#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000148_MC_FB_TOP 0x0000FFFF -#define R_00014C_MC_AGP_LOCATION 0x00014C -#define S_00014C_MC_AGP_START(x) (((x) & 0xFFFF) << 0) -#define G_00014C_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) -#define C_00014C_MC_AGP_START 0xFFFF0000 -#define S_00014C_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) -#define G_00014C_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_00014C_MC_AGP_TOP 0x0000FFFF -#define R_000170_AGP_BASE 0x000170 -#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000170_AGP_BASE_ADDR 0x00000000 -#define R_00023C_DISPLAY_BASE_ADDR 0x00023C -#define S_00023C_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_00023C_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_00023C_DISPLAY_BASE_ADDR 0x00000000 -#define R_000260_CUR_OFFSET 0x000260 -#define S_000260_CUR_OFFSET(x) (((x) & 0x7FFFFFF) << 0) -#define G_000260_CUR_OFFSET(x) (((x) >> 0) & 0x7FFFFFF) -#define C_000260_CUR_OFFSET 0xF8000000 -#define S_000260_CUR_LOCK(x) (((x) & 0x1) << 31) -#define G_000260_CUR_LOCK(x) (((x) >> 31) & 0x1) -#define C_000260_CUR_LOCK 0x7FFFFFFF -#define R_00033C_CRTC2_DISPLAY_BASE_ADDR 0x00033C -#define S_00033C_CRTC2_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_00033C_CRTC2_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_00033C_CRTC2_DISPLAY_BASE_ADDR 0x00000000 -#define R_000360_CUR2_OFFSET 0x000360 -#define S_000360_CUR2_OFFSET(x) (((x) & 0x7FFFFFF) << 0) -#define G_000360_CUR2_OFFSET(x) (((x) >> 0) & 0x7FFFFFF) -#define C_000360_CUR2_OFFSET 0xF8000000 -#define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31) -#define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1) -#define C_000360_CUR2_LOCK 0x7FFFFFFF -#define R_0003C2_GENMO_WT 0x0003C2 -#define S_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0) -#define G_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1) -#define C_0003C2_GENMO_MONO_ADDRESS_B 0xFE -#define S_0003C2_VGA_RAM_EN(x) (((x) & 0x1) << 1) -#define G_0003C2_VGA_RAM_EN(x) (((x) >> 1) & 0x1) -#define C_0003C2_VGA_RAM_EN 0xFD -#define S_0003C2_VGA_CKSEL(x) (((x) & 0x3) << 2) -#define G_0003C2_VGA_CKSEL(x) (((x) >> 2) & 0x3) -#define C_0003C2_VGA_CKSEL 0xF3 -#define S_0003C2_ODD_EVEN_MD_PGSEL(x) (((x) & 0x1) << 5) -#define G_0003C2_ODD_EVEN_MD_PGSEL(x) (((x) >> 5) & 0x1) -#define C_0003C2_ODD_EVEN_MD_PGSEL 0xDF -#define S_0003C2_VGA_HSYNC_POL(x) (((x) & 0x1) << 6) -#define G_0003C2_VGA_HSYNC_POL(x) (((x) >> 6) & 0x1) -#define C_0003C2_VGA_HSYNC_POL 0xBF -#define S_0003C2_VGA_VSYNC_POL(x) (((x) & 0x1) << 7) -#define G_0003C2_VGA_VSYNC_POL(x) (((x) >> 7) & 0x1) -#define C_0003C2_VGA_VSYNC_POL 0x7F -#define R_0003F8_CRTC2_GEN_CNTL 0x0003F8 -#define S_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) & 0x1) << 0) -#define G_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) >> 0) & 0x1) -#define C_0003F8_CRTC2_DBL_SCAN_EN 0xFFFFFFFE -#define S_0003F8_CRTC2_INTERLACE_EN(x) (((x) & 0x1) << 1) -#define G_0003F8_CRTC2_INTERLACE_EN(x) (((x) >> 1) & 0x1) -#define C_0003F8_CRTC2_INTERLACE_EN 0xFFFFFFFD -#define S_0003F8_CRTC2_SYNC_TRISTATE(x) (((x) & 0x1) << 4) -#define G_0003F8_CRTC2_SYNC_TRISTATE(x) (((x) >> 4) & 0x1) -#define C_0003F8_CRTC2_SYNC_TRISTATE 0xFFFFFFEF -#define S_0003F8_CRTC2_HSYNC_TRISTATE(x) (((x) & 0x1) << 5) -#define G_0003F8_CRTC2_HSYNC_TRISTATE(x) (((x) >> 5) & 0x1) -#define C_0003F8_CRTC2_HSYNC_TRISTATE 0xFFFFFFDF -#define S_0003F8_CRTC2_VSYNC_TRISTATE(x) (((x) & 0x1) << 6) -#define G_0003F8_CRTC2_VSYNC_TRISTATE(x) (((x) >> 6) & 0x1) -#define C_0003F8_CRTC2_VSYNC_TRISTATE 0xFFFFFFBF -#define S_0003F8_CRT2_ON(x) (((x) & 0x1) << 7) -#define G_0003F8_CRT2_ON(x) (((x) >> 7) & 0x1) -#define C_0003F8_CRT2_ON 0xFFFFFF7F -#define S_0003F8_CRTC2_PIX_WIDTH(x) (((x) & 0xF) << 8) -#define G_0003F8_CRTC2_PIX_WIDTH(x) (((x) >> 8) & 0xF) -#define C_0003F8_CRTC2_PIX_WIDTH 0xFFFFF0FF -#define S_0003F8_CRTC2_ICON_EN(x) (((x) & 0x1) << 15) -#define G_0003F8_CRTC2_ICON_EN(x) (((x) >> 15) & 0x1) -#define C_0003F8_CRTC2_ICON_EN 0xFFFF7FFF -#define S_0003F8_CRTC2_CUR_EN(x) (((x) & 0x1) << 16) -#define G_0003F8_CRTC2_CUR_EN(x) (((x) >> 16) & 0x1) -#define C_0003F8_CRTC2_CUR_EN 0xFFFEFFFF -#define S_0003F8_CRTC2_CUR_MODE(x) (((x) & 0x7) << 20) -#define G_0003F8_CRTC2_CUR_MODE(x) (((x) >> 20) & 0x7) -#define C_0003F8_CRTC2_CUR_MODE 0xFF8FFFFF -#define S_0003F8_CRTC2_DISPLAY_DIS(x) (((x) & 0x1) << 23) -#define G_0003F8_CRTC2_DISPLAY_DIS(x) (((x) >> 23) & 0x1) -#define C_0003F8_CRTC2_DISPLAY_DIS 0xFF7FFFFF -#define S_0003F8_CRTC2_EN(x) (((x) & 0x1) << 25) -#define G_0003F8_CRTC2_EN(x) (((x) >> 25) & 0x1) -#define C_0003F8_CRTC2_EN 0xFDFFFFFF -#define S_0003F8_CRTC2_DISP_REQ_EN_B(x) (((x) & 0x1) << 26) -#define G_0003F8_CRTC2_DISP_REQ_EN_B(x) (((x) >> 26) & 0x1) -#define C_0003F8_CRTC2_DISP_REQ_EN_B 0xFBFFFFFF -#define S_0003F8_CRTC2_C_SYNC_EN(x) (((x) & 0x1) << 27) -#define G_0003F8_CRTC2_C_SYNC_EN(x) (((x) >> 27) & 0x1) -#define C_0003F8_CRTC2_C_SYNC_EN 0xF7FFFFFF -#define S_0003F8_CRTC2_HSYNC_DIS(x) (((x) & 0x1) << 28) -#define G_0003F8_CRTC2_HSYNC_DIS(x) (((x) >> 28) & 0x1) -#define C_0003F8_CRTC2_HSYNC_DIS 0xEFFFFFFF -#define S_0003F8_CRTC2_VSYNC_DIS(x) (((x) & 0x1) << 29) -#define G_0003F8_CRTC2_VSYNC_DIS(x) (((x) >> 29) & 0x1) -#define C_0003F8_CRTC2_VSYNC_DIS 0xDFFFFFFF -#define R_000420_OV0_SCALE_CNTL 0x000420 -#define S_000420_OV0_NO_READ_BEHIND_SCAN(x) (((x) & 0x1) << 1) -#define G_000420_OV0_NO_READ_BEHIND_SCAN(x) (((x) >> 1) & 0x1) -#define C_000420_OV0_NO_READ_BEHIND_SCAN 0xFFFFFFFD -#define S_000420_OV0_HORZ_PICK_NEAREST(x) (((x) & 0x1) << 2) -#define G_000420_OV0_HORZ_PICK_NEAREST(x) (((x) >> 2) & 0x1) -#define C_000420_OV0_HORZ_PICK_NEAREST 0xFFFFFFFB -#define S_000420_OV0_VERT_PICK_NEAREST(x) (((x) & 0x1) << 3) -#define G_000420_OV0_VERT_PICK_NEAREST(x) (((x) >> 3) & 0x1) -#define C_000420_OV0_VERT_PICK_NEAREST 0xFFFFFFF7 -#define S_000420_OV0_SIGNED_UV(x) (((x) & 0x1) << 4) -#define G_000420_OV0_SIGNED_UV(x) (((x) >> 4) & 0x1) -#define C_000420_OV0_SIGNED_UV 0xFFFFFFEF -#define S_000420_OV0_GAMMA_SEL(x) (((x) & 0x7) << 5) -#define G_000420_OV0_GAMMA_SEL(x) (((x) >> 5) & 0x7) -#define C_000420_OV0_GAMMA_SEL 0xFFFFFF1F -#define S_000420_OV0_SURFACE_FORMAT(x) (((x) & 0xF) << 8) -#define G_000420_OV0_SURFACE_FORMAT(x) (((x) >> 8) & 0xF) -#define C_000420_OV0_SURFACE_FORMAT 0xFFFFF0FF -#define S_000420_OV0_ADAPTIVE_DEINT(x) (((x) & 0x1) << 12) -#define G_000420_OV0_ADAPTIVE_DEINT(x) (((x) >> 12) & 0x1) -#define C_000420_OV0_ADAPTIVE_DEINT 0xFFFFEFFF -#define S_000420_OV0_CRTC_SEL(x) (((x) & 0x1) << 14) -#define G_000420_OV0_CRTC_SEL(x) (((x) >> 14) & 0x1) -#define C_000420_OV0_CRTC_SEL 0xFFFFBFFF -#define S_000420_OV0_BURST_PER_PLANE(x) (((x) & 0x7F) << 16) -#define G_000420_OV0_BURST_PER_PLANE(x) (((x) >> 16) & 0x7F) -#define C_000420_OV0_BURST_PER_PLANE 0xFF80FFFF -#define S_000420_OV0_DOUBLE_BUFFER_REGS(x) (((x) & 0x1) << 24) -#define G_000420_OV0_DOUBLE_BUFFER_REGS(x) (((x) >> 24) & 0x1) -#define C_000420_OV0_DOUBLE_BUFFER_REGS 0xFEFFFFFF -#define S_000420_OV0_BANDWIDTH(x) (((x) & 0x1) << 26) -#define G_000420_OV0_BANDWIDTH(x) (((x) >> 26) & 0x1) -#define C_000420_OV0_BANDWIDTH 0xFBFFFFFF -#define S_000420_OV0_LIN_TRANS_BYPASS(x) (((x) & 0x1) << 28) -#define G_000420_OV0_LIN_TRANS_BYPASS(x) (((x) >> 28) & 0x1) -#define C_000420_OV0_LIN_TRANS_BYPASS 0xEFFFFFFF -#define S_000420_OV0_INT_EMU(x) (((x) & 0x1) << 29) -#define G_000420_OV0_INT_EMU(x) (((x) >> 29) & 0x1) -#define C_000420_OV0_INT_EMU 0xDFFFFFFF -#define S_000420_OV0_OVERLAY_EN(x) (((x) & 0x1) << 30) -#define G_000420_OV0_OVERLAY_EN(x) (((x) >> 30) & 0x1) -#define C_000420_OV0_OVERLAY_EN 0xBFFFFFFF -#define S_000420_OV0_SOFT_RESET(x) (((x) & 0x1) << 31) -#define G_000420_OV0_SOFT_RESET(x) (((x) >> 31) & 0x1) -#define C_000420_OV0_SOFT_RESET 0x7FFFFFFF -#define R_00070C_CP_RB_RPTR_ADDR 0x00070C -#define S_00070C_RB_RPTR_SWAP(x) (((x) & 0x3) << 0) -#define G_00070C_RB_RPTR_SWAP(x) (((x) >> 0) & 0x3) -#define C_00070C_RB_RPTR_SWAP 0xFFFFFFFC -#define S_00070C_RB_RPTR_ADDR(x) (((x) & 0x3FFFFFFF) << 2) -#define G_00070C_RB_RPTR_ADDR(x) (((x) >> 2) & 0x3FFFFFFF) -#define C_00070C_RB_RPTR_ADDR 0x00000003 -#define R_000740_CP_CSQ_CNTL 0x000740 -#define S_000740_CSQ_CNT_PRIMARY(x) (((x) & 0xFF) << 0) -#define G_000740_CSQ_CNT_PRIMARY(x) (((x) >> 0) & 0xFF) -#define C_000740_CSQ_CNT_PRIMARY 0xFFFFFF00 -#define S_000740_CSQ_CNT_INDIRECT(x) (((x) & 0xFF) << 8) -#define G_000740_CSQ_CNT_INDIRECT(x) (((x) >> 8) & 0xFF) -#define C_000740_CSQ_CNT_INDIRECT 0xFFFF00FF -#define S_000740_CSQ_MODE(x) (((x) & 0xF) << 28) -#define G_000740_CSQ_MODE(x) (((x) >> 28) & 0xF) -#define C_000740_CSQ_MODE 0x0FFFFFFF -#define R_000770_SCRATCH_UMSK 0x000770 -#define S_000770_SCRATCH_UMSK(x) (((x) & 0x3F) << 0) -#define G_000770_SCRATCH_UMSK(x) (((x) >> 0) & 0x3F) -#define C_000770_SCRATCH_UMSK 0xFFFFFFC0 -#define S_000770_SCRATCH_SWAP(x) (((x) & 0x3) << 16) -#define G_000770_SCRATCH_SWAP(x) (((x) >> 16) & 0x3) -#define C_000770_SCRATCH_SWAP 0xFFFCFFFF -#define R_000774_SCRATCH_ADDR 0x000774 -#define S_000774_SCRATCH_ADDR(x) (((x) & 0x7FFFFFF) << 5) -#define G_000774_SCRATCH_ADDR(x) (((x) >> 5) & 0x7FFFFFF) -#define C_000774_SCRATCH_ADDR 0x0000001F -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_SE_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_SE_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_SE_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF - - -#define R_00000D_SCLK_CNTL 0x00000D -#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) -#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7) -#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8 -#define S_00000D_TCLK_SRC_SEL(x) (((x) & 0x7) << 8) -#define G_00000D_TCLK_SRC_SEL(x) (((x) >> 8) & 0x7) -#define C_00000D_TCLK_SRC_SEL 0xFFFFF8FF -#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16) -#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1) -#define C_00000D_FORCE_CP 0xFFFEFFFF -#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17) -#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1) -#define C_00000D_FORCE_HDP 0xFFFDFFFF -#define S_00000D_FORCE_DISP(x) (((x) & 0x1) << 18) -#define G_00000D_FORCE_DISP(x) (((x) >> 18) & 0x1) -#define C_00000D_FORCE_DISP 0xFFFBFFFF -#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19) -#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1) -#define C_00000D_FORCE_TOP 0xFFF7FFFF -#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20) -#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1) -#define C_00000D_FORCE_E2 0xFFEFFFFF -#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21) -#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1) -#define C_00000D_FORCE_SE 0xFFDFFFFF -#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22) -#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1) -#define C_00000D_FORCE_IDCT 0xFFBFFFFF -#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23) -#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1) -#define C_00000D_FORCE_VIP 0xFF7FFFFF -#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24) -#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1) -#define C_00000D_FORCE_RE 0xFEFFFFFF -#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25) -#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1) -#define C_00000D_FORCE_PB 0xFDFFFFFF -#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26) -#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1) -#define C_00000D_FORCE_TAM 0xFBFFFFFF -#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27) -#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1) -#define C_00000D_FORCE_TDM 0xF7FFFFFF -#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28) -#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1) -#define C_00000D_FORCE_RB 0xEFFFFFFF - -/* PLL regs */ -#define SCLK_CNTL 0xd -#define FORCE_HDP (1 << 17) -#define CLK_PWRMGT_CNTL 0x14 -#define GLOBAL_PMAN_EN (1 << 10) -#define DISP_PM (1 << 20) -#define PLL_PWRMGT_CNTL 0x15 -#define MPLL_TURNOFF (1 << 0) -#define SPLL_TURNOFF (1 << 1) -#define PPLL_TURNOFF (1 << 2) -#define P2PLL_TURNOFF (1 << 3) -#define TVPLL_TURNOFF (1 << 4) -#define MOBILE_SU (1 << 16) -#define SU_SCLK_USE_BCLK (1 << 17) -#define SCLK_CNTL2 0x1e -#define REDUCED_SPEED_SCLK_MODE (1 << 16) -#define REDUCED_SPEED_SCLK_SEL(x) ((x) << 17) -#define MCLK_MISC 0x1f -#define EN_MCLK_TRISTATE_IN_SUSPEND (1 << 18) -#define SCLK_MORE_CNTL 0x35 -#define REDUCED_SPEED_SCLK_EN (1 << 16) -#define IO_CG_VOLTAGE_DROP (1 << 17) -#define VOLTAGE_DELAY_SEL(x) ((x) << 20) -#define VOLTAGE_DROP_SYNC (1 << 19) - -/* mmreg */ -#define DISP_PWR_MAN 0xd08 -#define DISP_D3_GRPH_RST (1 << 18) -#define DISP_D3_SUBPIC_RST (1 << 19) -#define DISP_D3_OV0_RST (1 << 20) -#define DISP_D1D2_GRPH_RST (1 << 21) -#define DISP_D1D2_SUBPIC_RST (1 << 22) -#define DISP_D1D2_OV0_RST (1 << 23) -#define DISP_DVO_ENABLE_RST (1 << 24) -#define TV_ENABLE_RST (1 << 25) -#define AUTO_PWRUP_EN (1 << 26) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r200.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r200.c deleted file mode 100644 index a59cc474..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r200.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "radeon_asic.h" - -#include "r100d.h" -#include "r200_reg_safe.h" - -#include "r100_track.h" - -static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) -{ - int vtx_size, i; - vtx_size = 2; - - if (vtx_fmt_0 & R200_VTX_Z0) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_W0) - vtx_size++; - /* blend weight */ - if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) - vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; - if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_N0) - vtx_size += 3; - if (vtx_fmt_0 & R200_VTX_POINT_SIZE) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_SHININESS_0) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_SHININESS_1) - vtx_size++; - for (i = 0; i < 8; i++) { - int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; - switch (color_size) { - case 0: break; - case 1: vtx_size++; break; - case 2: vtx_size += 3; break; - case 3: vtx_size += 4; break; - } - } - if (vtx_fmt_0 & R200_VTX_XY1) - vtx_size += 2; - if (vtx_fmt_0 & R200_VTX_Z1) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_W1) - vtx_size++; - if (vtx_fmt_0 & R200_VTX_N1) - vtx_size += 3; - return vtx_size; -} - -int r200_copy_dma(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - uint32_t size; - uint32_t cur_size; - int i, num_loops; - int r = 0; - - /* radeon pitch is /64 */ - size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; - num_loops = DIV_ROUND_UP(size, 0x1FFFFF); - r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); - if (r) { - DRM_ERROR("radeon: moving bo (%d).\n", r); - return r; - } - /* Must wait for 2D idle & clean before DMA or hangs might happen */ - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, (1 << 16)); - for (i = 0; i < num_loops; i++) { - cur_size = size; - if (cur_size > 0x1FFFFF) { - cur_size = 0x1FFFFF; - } - size -= cur_size; - radeon_ring_write(ring, PACKET0(0x720, 2)); - radeon_ring_write(ring, src_offset); - radeon_ring_write(ring, dst_offset); - radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30)); - src_offset += cur_size; - dst_offset += cur_size; - } - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); - if (fence) { - r = radeon_fence_emit(rdev, fence); - } - radeon_ring_unlock_commit(rdev, ring); - return r; -} - - -static int r200_get_vtx_size_1(uint32_t vtx_fmt_1) -{ - int vtx_size, i, tex_size; - vtx_size = 0; - for (i = 0; i < 6; i++) { - tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; - if (tex_size > 4) - continue; - vtx_size += tex_size; - } - return vtx_size; -} - -int r200_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg) -{ - struct radeon_cs_reloc *reloc; - struct r100_cs_track *track; - volatile uint32_t *ib; - uint32_t tmp; - int r; - int i; - int face; - u32 tile_flags = 0; - u32 idx_value; - - ib = p->ib->ptr; - track = (struct r100_cs_track *)p->track; - idx_value = radeon_get_ib_value(p, idx); - switch (reg) { - case RADEON_CRTC_GUI_TRIG_VLINE: - r = r100_cs_packet_parse_vline(p); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - break; - /* FIXME: only allow PACKET3 blit? easier to check for out of - * range access */ - case RADEON_DST_PITCH_OFFSET: - case RADEON_SRC_PITCH_OFFSET: - r = r100_reloc_pitch_offset(p, pkt, idx, reg); - if (r) - return r; - break; - case RADEON_RB3D_DEPTHOFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->zb.robj = reloc->robj; - track->zb.offset = idx_value; - track->zb_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case RADEON_RB3D_COLOROFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->cb[0].robj = reloc->robj; - track->cb[0].offset = idx_value; - track->cb_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case R200_PP_TXOFFSET_0: - case R200_PP_TXOFFSET_1: - case R200_PP_TXOFFSET_2: - case R200_PP_TXOFFSET_3: - case R200_PP_TXOFFSET_4: - case R200_PP_TXOFFSET_5: - i = (reg - R200_PP_TXOFFSET_0) / 24; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R200_TXO_MACRO_TILE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R200_TXO_MICRO_TILE; - - tmp = idx_value & ~(0x7 << 2); - tmp |= tile_flags; - ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); - } else - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - track->textures[i].robj = reloc->robj; - track->tex_dirty = true; - break; - case R200_PP_CUBIC_OFFSET_F1_0: - case R200_PP_CUBIC_OFFSET_F2_0: - case R200_PP_CUBIC_OFFSET_F3_0: - case R200_PP_CUBIC_OFFSET_F4_0: - case R200_PP_CUBIC_OFFSET_F5_0: - case R200_PP_CUBIC_OFFSET_F1_1: - case R200_PP_CUBIC_OFFSET_F2_1: - case R200_PP_CUBIC_OFFSET_F3_1: - case R200_PP_CUBIC_OFFSET_F4_1: - case R200_PP_CUBIC_OFFSET_F5_1: - case R200_PP_CUBIC_OFFSET_F1_2: - case R200_PP_CUBIC_OFFSET_F2_2: - case R200_PP_CUBIC_OFFSET_F3_2: - case R200_PP_CUBIC_OFFSET_F4_2: - case R200_PP_CUBIC_OFFSET_F5_2: - case R200_PP_CUBIC_OFFSET_F1_3: - case R200_PP_CUBIC_OFFSET_F2_3: - case R200_PP_CUBIC_OFFSET_F3_3: - case R200_PP_CUBIC_OFFSET_F4_3: - case R200_PP_CUBIC_OFFSET_F5_3: - case R200_PP_CUBIC_OFFSET_F1_4: - case R200_PP_CUBIC_OFFSET_F2_4: - case R200_PP_CUBIC_OFFSET_F3_4: - case R200_PP_CUBIC_OFFSET_F4_4: - case R200_PP_CUBIC_OFFSET_F5_4: - case R200_PP_CUBIC_OFFSET_F1_5: - case R200_PP_CUBIC_OFFSET_F2_5: - case R200_PP_CUBIC_OFFSET_F3_5: - case R200_PP_CUBIC_OFFSET_F4_5: - case R200_PP_CUBIC_OFFSET_F5_5: - i = (reg - R200_PP_TXOFFSET_0) / 24; - face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->textures[i].cube_info[face - 1].offset = idx_value; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - track->textures[i].cube_info[face - 1].robj = reloc->robj; - track->tex_dirty = true; - break; - case RADEON_RE_WIDTH_HEIGHT: - track->maxy = ((idx_value >> 16) & 0x7FF); - track->cb_dirty = true; - track->zb_dirty = true; - break; - case RADEON_RB3D_COLORPITCH: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; - } else - ib[idx] = idx_value; - - track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; - track->cb_dirty = true; - break; - case RADEON_RB3D_DEPTHPITCH: - track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; - track->zb_dirty = true; - break; - case RADEON_RB3D_CNTL: - switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { - case 7: - case 8: - case 9: - case 11: - case 12: - track->cb[0].cpp = 1; - break; - case 3: - case 4: - case 15: - track->cb[0].cpp = 2; - break; - case 6: - track->cb[0].cpp = 4; - break; - default: - DRM_ERROR("Invalid color buffer format (%d) !\n", - ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); - return -EINVAL; - } - if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { - DRM_ERROR("No support for depth xy offset in kms\n"); - return -EINVAL; - } - - track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); - track->cb_dirty = true; - track->zb_dirty = true; - break; - case RADEON_RB3D_ZSTENCILCNTL: - switch (idx_value & 0xf) { - case 0: - track->zb.cpp = 2; - break; - case 2: - case 3: - case 4: - case 5: - case 9: - case 11: - track->zb.cpp = 4; - break; - default: - break; - } - track->zb_dirty = true; - break; - case RADEON_RB3D_ZPASS_ADDR: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case RADEON_PP_CNTL: - { - uint32_t temp = idx_value >> 4; - for (i = 0; i < track->num_texture; i++) - track->textures[i].enabled = !!(temp & (1 << i)); - track->tex_dirty = true; - } - break; - case RADEON_SE_VF_CNTL: - track->vap_vf_cntl = idx_value; - break; - case 0x210c: - /* VAP_VF_MAX_VTX_INDX */ - track->max_indx = idx_value & 0x00FFFFFFUL; - break; - case R200_SE_VTX_FMT_0: - track->vtx_size = r200_get_vtx_size_0(idx_value); - break; - case R200_SE_VTX_FMT_1: - track->vtx_size += r200_get_vtx_size_1(idx_value); - break; - case R200_PP_TXSIZE_0: - case R200_PP_TXSIZE_1: - case R200_PP_TXSIZE_2: - case R200_PP_TXSIZE_3: - case R200_PP_TXSIZE_4: - case R200_PP_TXSIZE_5: - i = (reg - R200_PP_TXSIZE_0) / 32; - track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; - track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; - track->tex_dirty = true; - break; - case R200_PP_TXPITCH_0: - case R200_PP_TXPITCH_1: - case R200_PP_TXPITCH_2: - case R200_PP_TXPITCH_3: - case R200_PP_TXPITCH_4: - case R200_PP_TXPITCH_5: - i = (reg - R200_PP_TXPITCH_0) / 32; - track->textures[i].pitch = idx_value + 32; - track->tex_dirty = true; - break; - case R200_PP_TXFILTER_0: - case R200_PP_TXFILTER_1: - case R200_PP_TXFILTER_2: - case R200_PP_TXFILTER_3: - case R200_PP_TXFILTER_4: - case R200_PP_TXFILTER_5: - i = (reg - R200_PP_TXFILTER_0) / 32; - track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) - >> R200_MAX_MIP_LEVEL_SHIFT); - tmp = (idx_value >> 23) & 0x7; - if (tmp == 2 || tmp == 6) - track->textures[i].roundup_w = false; - tmp = (idx_value >> 27) & 0x7; - if (tmp == 2 || tmp == 6) - track->textures[i].roundup_h = false; - track->tex_dirty = true; - break; - case R200_PP_TXMULTI_CTL_0: - case R200_PP_TXMULTI_CTL_1: - case R200_PP_TXMULTI_CTL_2: - case R200_PP_TXMULTI_CTL_3: - case R200_PP_TXMULTI_CTL_4: - case R200_PP_TXMULTI_CTL_5: - i = (reg - R200_PP_TXMULTI_CTL_0) / 32; - break; - case R200_PP_TXFORMAT_X_0: - case R200_PP_TXFORMAT_X_1: - case R200_PP_TXFORMAT_X_2: - case R200_PP_TXFORMAT_X_3: - case R200_PP_TXFORMAT_X_4: - case R200_PP_TXFORMAT_X_5: - i = (reg - R200_PP_TXFORMAT_X_0) / 32; - track->textures[i].txdepth = idx_value & 0x7; - tmp = (idx_value >> 16) & 0x3; - /* 2D, 3D, CUBE */ - switch (tmp) { - case 0: - case 3: - case 4: - case 5: - case 6: - case 7: - /* 1D/2D */ - track->textures[i].tex_coord_type = 0; - break; - case 1: - /* CUBE */ - track->textures[i].tex_coord_type = 2; - break; - case 2: - /* 3D */ - track->textures[i].tex_coord_type = 1; - break; - } - track->tex_dirty = true; - break; - case R200_PP_TXFORMAT_0: - case R200_PP_TXFORMAT_1: - case R200_PP_TXFORMAT_2: - case R200_PP_TXFORMAT_3: - case R200_PP_TXFORMAT_4: - case R200_PP_TXFORMAT_5: - i = (reg - R200_PP_TXFORMAT_0) / 32; - if (idx_value & R200_TXFORMAT_NON_POWER2) { - track->textures[i].use_pitch = 1; - } else { - track->textures[i].use_pitch = 0; - track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); - track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); - } - if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) - track->textures[i].lookup_disable = true; - switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { - case R200_TXFORMAT_I8: - case R200_TXFORMAT_RGB332: - case R200_TXFORMAT_Y8: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R200_TXFORMAT_AI88: - case R200_TXFORMAT_ARGB1555: - case R200_TXFORMAT_RGB565: - case R200_TXFORMAT_ARGB4444: - case R200_TXFORMAT_VYUY422: - case R200_TXFORMAT_YVYU422: - case R200_TXFORMAT_LDVDU655: - case R200_TXFORMAT_DVDU88: - case R200_TXFORMAT_AVYU4444: - track->textures[i].cpp = 2; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R200_TXFORMAT_ARGB8888: - case R200_TXFORMAT_RGBA8888: - case R200_TXFORMAT_ABGR8888: - case R200_TXFORMAT_BGR111110: - case R200_TXFORMAT_LDVDU8888: - track->textures[i].cpp = 4; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R200_TXFORMAT_DXT1: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_DXT1; - break; - case R200_TXFORMAT_DXT23: - case R200_TXFORMAT_DXT45: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_DXT1; - break; - } - track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); - track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); - track->tex_dirty = true; - break; - case R200_PP_CUBIC_FACES_0: - case R200_PP_CUBIC_FACES_1: - case R200_PP_CUBIC_FACES_2: - case R200_PP_CUBIC_FACES_3: - case R200_PP_CUBIC_FACES_4: - case R200_PP_CUBIC_FACES_5: - tmp = idx_value; - i = (reg - R200_PP_CUBIC_FACES_0) / 32; - for (face = 0; face < 4; face++) { - track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); - track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); - } - track->tex_dirty = true; - break; - default: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", - reg, idx); - return -EINVAL; - } - return 0; -} - -void r200_set_safe_registers(struct radeon_device *rdev) -{ - rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; - rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300.c deleted file mode 100644 index fa14383f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300.c +++ /dev/null @@ -1,1590 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include -#include -#include -#include "radeon_reg.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "radeon_drm.h" -#include "r100_track.h" -#include "r300d.h" -#include "rv350d.h" -#include "r300_reg_safe.h" - -/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 - * - * GPU Errata: - * - HOST_PATH_CNTL: r300 family seems to dislike write to HOST_PATH_CNTL - * using MMIO to flush host path read cache, this lead to HARDLOCKUP. - * However, scheduling such write to the ring seems harmless, i suspect - * the CP read collide with the flush somehow, or maybe the MC, hard to - * tell. (Jerome Glisse) - */ - -/* - * rv370,rv380 PCIE GART - */ -static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev); - -void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) -{ - uint32_t tmp; - int i; - - /* Workaround HW bug do flush 2 times */ - for (i = 0; i < 2; i++) { - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); - WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp | RADEON_PCIE_TX_GART_INVALIDATE_TLB); - (void)RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); - WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - } - mb(); -} - -#define R300_PTE_WRITEABLE (1 << 2) -#define R300_PTE_READABLE (1 << 3) - -int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) -{ - void __iomem *ptr = rdev->gart.ptr; - - if (i < 0 || i > rdev->gart.num_gpu_pages) { - return -EINVAL; - } - addr = (lower_32_bits(addr) >> 8) | - ((upper_32_bits(addr) & 0xff) << 24) | - R300_PTE_WRITEABLE | R300_PTE_READABLE; - /* on x86 we want this to be CPU endian, on powerpc - * on powerpc without HW swappers, it'll get swapped on way - * into VRAM - so no need for cpu_to_le32 on VRAM tables */ - writel(addr, ((void __iomem *)ptr) + (i * 4)); - return 0; -} - -int rv370_pcie_gart_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.robj) { - WARN(1, "RV370 PCIE GART already initialized\n"); - return 0; - } - /* Initialize common gart structure */ - r = radeon_gart_init(rdev); - if (r) - return r; - r = rv370_debugfs_pcie_gart_info_init(rdev); - if (r) - DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); - rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; - rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; - rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; - return radeon_gart_table_vram_alloc(rdev); -} - -int rv370_pcie_gart_enable(struct radeon_device *rdev) -{ - uint32_t table_addr; - uint32_t tmp; - int r; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - /* discard memory request outside of configured range */ - tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; - WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_start); - tmp = rdev->mc.gtt_end & ~RADEON_GPU_PAGE_MASK; - WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); - WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); - WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); - table_addr = rdev->gart.table_addr; - WREG32_PCIE(RADEON_PCIE_TX_GART_BASE, table_addr); - /* FIXME: setup default page */ - WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_start); - WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0); - /* Clear error */ - WREG32_PCIE(RADEON_PCIE_TX_GART_ERROR, 0); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); - tmp |= RADEON_PCIE_TX_GART_EN; - tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; - WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - rv370_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)table_addr); - rdev->gart.ready = true; - return 0; -} - -void rv370_pcie_gart_disable(struct radeon_device *rdev) -{ - u32 tmp; - - WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, 0); - WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, 0); - WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); - WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); - tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; - WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); - radeon_gart_table_vram_unpin(rdev); -} - -void rv370_pcie_gart_fini(struct radeon_device *rdev) -{ - radeon_gart_fini(rdev); - rv370_pcie_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); -} - -void r300_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[fence->ring]; - - /* Who ever call radeon_fence_emit should call ring_lock and ask - * for enough space (today caller are ib schedule and buffer move) */ - /* Write SC register so SC & US assert idle */ - radeon_ring_write(ring, PACKET0(R300_RE_SCISSORS_TL, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(R300_RE_SCISSORS_BR, 0)); - radeon_ring_write(ring, 0); - /* Flush 3D cache */ - radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_RB3D_DC_FLUSH); - radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_ZC_FLUSH); - /* Wait until IDLE & CLEAN */ - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, (RADEON_WAIT_3D_IDLECLEAN | - RADEON_WAIT_2D_IDLECLEAN | - RADEON_WAIT_DMA_GUI_IDLE)); - radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(ring, rdev->config.r300.hdp_cntl | - RADEON_HDP_READ_BUFFER_INVALIDATE); - radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(ring, rdev->config.r300.hdp_cntl); - /* Emit fence sequence & fire IRQ */ - radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); - radeon_ring_write(ring, fence->seq); - radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0)); - radeon_ring_write(ring, RADEON_SW_INT_FIRE); -} - -void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) -{ - unsigned gb_tile_config; - int r; - - /* Sub pixel 1/12 so we can have 4K rendering according to doc */ - gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); - switch(rdev->num_gb_pipes) { - case 2: - gb_tile_config |= R300_PIPE_COUNT_R300; - break; - case 3: - gb_tile_config |= R300_PIPE_COUNT_R420_3P; - break; - case 4: - gb_tile_config |= R300_PIPE_COUNT_R420; - break; - case 1: - default: - gb_tile_config |= R300_PIPE_COUNT_RV350; - break; - } - - r = radeon_ring_lock(rdev, ring, 64); - if (r) { - return; - } - radeon_ring_write(ring, PACKET0(RADEON_ISYNC_CNTL, 0)); - radeon_ring_write(ring, - RADEON_ISYNC_ANY2D_IDLE3D | - RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_write(ring, PACKET0(R300_GB_TILE_CONFIG, 0)); - radeon_ring_write(ring, gb_tile_config); - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, - RADEON_WAIT_2D_IDLECLEAN | - RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); - radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); - radeon_ring_write(ring, PACKET0(R300_GB_SELECT, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(R300_GB_ENABLE, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); - radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_ZC_FLUSH | R300_ZC_FREE); - radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(ring, - RADEON_WAIT_2D_IDLECLEAN | - RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(ring, PACKET0(R300_GB_AA_CONFIG, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); - radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_ZC_FLUSH | R300_ZC_FREE); - radeon_ring_write(ring, PACKET0(R300_GB_MSPOS0, 0)); - radeon_ring_write(ring, - ((6 << R300_MS_X0_SHIFT) | - (6 << R300_MS_Y0_SHIFT) | - (6 << R300_MS_X1_SHIFT) | - (6 << R300_MS_Y1_SHIFT) | - (6 << R300_MS_X2_SHIFT) | - (6 << R300_MS_Y2_SHIFT) | - (6 << R300_MSBD0_Y_SHIFT) | - (6 << R300_MSBD0_X_SHIFT))); - radeon_ring_write(ring, PACKET0(R300_GB_MSPOS1, 0)); - radeon_ring_write(ring, - ((6 << R300_MS_X3_SHIFT) | - (6 << R300_MS_Y3_SHIFT) | - (6 << R300_MS_X4_SHIFT) | - (6 << R300_MS_Y4_SHIFT) | - (6 << R300_MS_X5_SHIFT) | - (6 << R300_MS_Y5_SHIFT) | - (6 << R300_MSBD1_SHIFT))); - radeon_ring_write(ring, PACKET0(R300_GA_ENHANCE, 0)); - radeon_ring_write(ring, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); - radeon_ring_write(ring, PACKET0(R300_GA_POLY_MODE, 0)); - radeon_ring_write(ring, - R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE); - radeon_ring_write(ring, PACKET0(R300_GA_ROUND_MODE, 0)); - radeon_ring_write(ring, - R300_GEOMETRY_ROUND_NEAREST | - R300_COLOR_ROUND_NEAREST); - radeon_ring_unlock_commit(rdev, ring); -} - -void r300_errata(struct radeon_device *rdev) -{ - rdev->pll_errata = 0; - - if (rdev->family == CHIP_R300 && - (RREG32(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) { - rdev->pll_errata |= CHIP_ERRATA_R300_CG; - } -} - -int r300_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(RADEON_MC_STATUS); - if (tmp & R300_MC_IDLE) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -void r300_gpu_init(struct radeon_device *rdev) -{ - uint32_t gb_tile_config, tmp; - - if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || - (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) { - /* r300,r350 */ - rdev->num_gb_pipes = 2; - } else { - /* rv350,rv370,rv380,r300 AD, r350 AH */ - rdev->num_gb_pipes = 1; - } - rdev->num_z_pipes = 1; - gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); - switch (rdev->num_gb_pipes) { - case 2: - gb_tile_config |= R300_PIPE_COUNT_R300; - break; - case 3: - gb_tile_config |= R300_PIPE_COUNT_R420_3P; - break; - case 4: - gb_tile_config |= R300_PIPE_COUNT_R420; - break; - default: - case 1: - gb_tile_config |= R300_PIPE_COUNT_RV350; - break; - } - WREG32(R300_GB_TILE_CONFIG, gb_tile_config); - - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } - - tmp = RREG32(R300_DST_PIPE_CONFIG); - WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG); - - WREG32(R300_RB2D_DSTCACHE_MODE, - R300_DC_AUTOFLUSH_ENABLE | - R300_DC_DC_DISABLE_IGNORE_PE); - - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } - if (r300_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait MC idle while " - "programming pipes. Bad things might happen.\n"); - } - DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n", - rdev->num_gb_pipes, rdev->num_z_pipes); -} - -bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 rbbm_status; - int r; - - rbbm_status = RREG32(R_000E40_RBBM_STATUS); - if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - r100_gpu_lockup_update(&rdev->config.r300.lockup, ring); - return false; - } - /* force CP activities */ - r = radeon_ring_lock(rdev, ring, 2); - if (!r) { - /* PACKET2 NOP */ - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - radeon_ring_unlock_commit(rdev, ring); - } - ring->rptr = RREG32(RADEON_CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, ring); -} - -int r300_asic_reset(struct radeon_device *rdev) -{ - struct r100_mc_save save; - u32 status, tmp; - int ret = 0; - - status = RREG32(R_000E40_RBBM_STATUS); - if (!G_000E40_GUI_ACTIVE(status)) { - return 0; - } - r100_mc_stop(rdev, &save); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* stop CP */ - WREG32(RADEON_CP_CSQ_CNTL, 0); - tmp = RREG32(RADEON_CP_RB_CNTL); - WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); - WREG32(RADEON_CP_RB_RPTR_WR, 0); - WREG32(RADEON_CP_RB_WPTR, 0); - WREG32(RADEON_CP_RB_CNTL, tmp); - /* save PCI state */ - pci_save_state(rdev->pdev); - /* disable bus mastering */ - r100_bm_disable(rdev); - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | - S_0000F0_SOFT_RESET_GA(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* resetting the CP seems to be problematic sometimes it end up - * hard locking the computer, but it's necessary for successful - * reset more test & playing is needed on R3XX/R4XX to find a - * reliable (if any solution) - */ - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* restore PCI & busmastering */ - pci_restore_state(rdev->pdev); - r100_enable_bm(rdev); - /* Check if GPU is idle */ - if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { - dev_err(rdev->dev, "failed to reset GPU\n"); - rdev->gpu_lockup = true; - ret = -1; - } else - dev_info(rdev->dev, "GPU reset succeed\n"); - r100_mc_resume(rdev, &save); - return ret; -} - -/* - * r300,r350,rv350,rv380 VRAM info - */ -void r300_mc_init(struct radeon_device *rdev) -{ - u64 base; - u32 tmp; - - /* DDR for all card after R300 & IGP */ - rdev->mc.vram_is_ddr = true; - tmp = RREG32(RADEON_MEM_CNTL); - tmp &= R300_MEM_NUM_CHANNELS_MASK; - switch (tmp) { - case 0: rdev->mc.vram_width = 64; break; - case 1: rdev->mc.vram_width = 128; break; - case 2: rdev->mc.vram_width = 256; break; - default: rdev->mc.vram_width = 128; break; - } - r100_vram_init_sizes(rdev); - base = rdev->mc.aper_base; - if (rdev->flags & RADEON_IS_IGP) - base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; - radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; - if (!(rdev->flags & RADEON_IS_AGP)) - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - -void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) -{ - uint32_t link_width_cntl, mask; - - if (rdev->flags & RADEON_IS_IGP) - return; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return; - - /* FIXME wait for idle */ - - switch (lanes) { - case 0: - mask = RADEON_PCIE_LC_LINK_WIDTH_X0; - break; - case 1: - mask = RADEON_PCIE_LC_LINK_WIDTH_X1; - break; - case 2: - mask = RADEON_PCIE_LC_LINK_WIDTH_X2; - break; - case 4: - mask = RADEON_PCIE_LC_LINK_WIDTH_X4; - break; - case 8: - mask = RADEON_PCIE_LC_LINK_WIDTH_X8; - break; - case 12: - mask = RADEON_PCIE_LC_LINK_WIDTH_X12; - break; - case 16: - default: - mask = RADEON_PCIE_LC_LINK_WIDTH_X16; - break; - } - - link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); - - if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == - (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) - return; - - link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | - RADEON_PCIE_LC_RECONFIG_NOW | - RADEON_PCIE_LC_RECONFIG_LATER | - RADEON_PCIE_LC_SHORT_RECONFIG_EN); - link_width_cntl |= mask; - WREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - WREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | - RADEON_PCIE_LC_RECONFIG_NOW)); - - /* wait for lane set to complete */ - link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); - while (link_width_cntl == 0xffffffff) - link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); - -} - -int rv370_get_pcie_lanes(struct radeon_device *rdev) -{ - u32 link_width_cntl; - - if (rdev->flags & RADEON_IS_IGP) - return 0; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return 0; - - /* FIXME wait for idle */ - - link_width_cntl = RREG32_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL); - - switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { - case RADEON_PCIE_LC_LINK_WIDTH_X0: - return 0; - case RADEON_PCIE_LC_LINK_WIDTH_X1: - return 1; - case RADEON_PCIE_LC_LINK_WIDTH_X2: - return 2; - case RADEON_PCIE_LC_LINK_WIDTH_X4: - return 4; - case RADEON_PCIE_LC_LINK_WIDTH_X8: - return 8; - case RADEON_PCIE_LC_LINK_WIDTH_X16: - default: - return 16; - } -} - -#if defined(CONFIG_DEBUG_FS) -static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL); - seq_printf(m, "PCIE_TX_GART_CNTL 0x%08x\n", tmp); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_BASE); - seq_printf(m, "PCIE_TX_GART_BASE 0x%08x\n", tmp); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_START_LO); - seq_printf(m, "PCIE_TX_GART_START_LO 0x%08x\n", tmp); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_START_HI); - seq_printf(m, "PCIE_TX_GART_START_HI 0x%08x\n", tmp); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_END_LO); - seq_printf(m, "PCIE_TX_GART_END_LO 0x%08x\n", tmp); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_END_HI); - seq_printf(m, "PCIE_TX_GART_END_HI 0x%08x\n", tmp); - tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_ERROR); - seq_printf(m, "PCIE_TX_GART_ERROR 0x%08x\n", tmp); - return 0; -} - -static struct drm_info_list rv370_pcie_gart_info_list[] = { - {"rv370_pcie_gart_info", rv370_debugfs_pcie_gart_info, 0, NULL}, -}; -#endif - -static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, rv370_pcie_gart_info_list, 1); -#else - return 0; -#endif -} - -static int r300_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg) -{ - struct radeon_cs_reloc *reloc; - struct r100_cs_track *track; - volatile uint32_t *ib; - uint32_t tmp, tile_flags = 0; - unsigned i; - int r; - u32 idx_value; - - ib = p->ib->ptr; - track = (struct r100_cs_track *)p->track; - idx_value = radeon_get_ib_value(p, idx); - - switch(reg) { - case AVIVO_D1MODE_VLINE_START_END: - case RADEON_CRTC_GUI_TRIG_VLINE: - r = r100_cs_packet_parse_vline(p); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - break; - case RADEON_DST_PITCH_OFFSET: - case RADEON_SRC_PITCH_OFFSET: - r = r100_reloc_pitch_offset(p, pkt, idx, reg); - if (r) - return r; - break; - case R300_RB3D_COLOROFFSET0: - case R300_RB3D_COLOROFFSET1: - case R300_RB3D_COLOROFFSET2: - case R300_RB3D_COLOROFFSET3: - i = (reg - R300_RB3D_COLOROFFSET0) >> 2; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->cb[i].robj = reloc->robj; - track->cb[i].offset = idx_value; - track->cb_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case R300_ZB_DEPTHOFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->zb.robj = reloc->robj; - track->zb.offset = idx_value; - track->zb_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case R300_TX_OFFSET_0: - case R300_TX_OFFSET_0+4: - case R300_TX_OFFSET_0+8: - case R300_TX_OFFSET_0+12: - case R300_TX_OFFSET_0+16: - case R300_TX_OFFSET_0+20: - case R300_TX_OFFSET_0+24: - case R300_TX_OFFSET_0+28: - case R300_TX_OFFSET_0+32: - case R300_TX_OFFSET_0+36: - case R300_TX_OFFSET_0+40: - case R300_TX_OFFSET_0+44: - case R300_TX_OFFSET_0+48: - case R300_TX_OFFSET_0+52: - case R300_TX_OFFSET_0+56: - case R300_TX_OFFSET_0+60: - i = (reg - R300_TX_OFFSET_0) >> 2; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - - if (p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) { - ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ - ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); - } else { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R300_TXO_MACRO_TILE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_TXO_MICRO_TILE; - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) - tile_flags |= R300_TXO_MICRO_TILE_SQUARE; - - tmp = idx_value + ((u32)reloc->lobj.gpu_offset); - tmp |= tile_flags; - ib[idx] = tmp; - } - track->textures[i].robj = reloc->robj; - track->tex_dirty = true; - break; - /* Tracked registers */ - case 0x2084: - /* VAP_VF_CNTL */ - track->vap_vf_cntl = idx_value; - break; - case 0x20B4: - /* VAP_VTX_SIZE */ - track->vtx_size = idx_value & 0x7F; - break; - case 0x2134: - /* VAP_VF_MAX_VTX_INDX */ - track->max_indx = idx_value & 0x00FFFFFFUL; - break; - case 0x2088: - /* VAP_ALT_NUM_VERTICES - only valid on r500 */ - if (p->rdev->family < CHIP_RV515) - goto fail; - track->vap_alt_nverts = idx_value & 0xFFFFFF; - break; - case 0x43E4: - /* SC_SCISSOR1 */ - track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; - if (p->rdev->family < CHIP_RV515) { - track->maxy -= 1440; - } - track->cb_dirty = true; - track->zb_dirty = true; - break; - case 0x4E00: - /* RB3D_CCTL */ - if ((idx_value & (1 << 10)) && /* CMASK_ENABLE */ - p->rdev->cmask_filp != p->filp) { - DRM_ERROR("Invalid RB3D_CCTL: Cannot enable CMASK.\n"); - return -EINVAL; - } - track->num_cb = ((idx_value >> 5) & 0x3) + 1; - track->cb_dirty = true; - break; - case 0x4E38: - case 0x4E3C: - case 0x4E40: - case 0x4E44: - /* RB3D_COLORPITCH0 */ - /* RB3D_COLORPITCH1 */ - /* RB3D_COLORPITCH2 */ - /* RB3D_COLORPITCH3 */ - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R300_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_COLOR_MICROTILE_ENABLE; - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) - tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; - - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; - } - i = (reg - 0x4E38) >> 2; - track->cb[i].pitch = idx_value & 0x3FFE; - switch (((idx_value >> 21) & 0xF)) { - case 9: - case 11: - case 12: - track->cb[i].cpp = 1; - break; - case 3: - case 4: - case 13: - case 15: - track->cb[i].cpp = 2; - break; - case 5: - if (p->rdev->family < CHIP_RV515) { - DRM_ERROR("Invalid color buffer format (%d)!\n", - ((idx_value >> 21) & 0xF)); - return -EINVAL; - } - /* Pass through. */ - case 6: - track->cb[i].cpp = 4; - break; - case 10: - track->cb[i].cpp = 8; - break; - case 7: - track->cb[i].cpp = 16; - break; - default: - DRM_ERROR("Invalid color buffer format (%d) !\n", - ((idx_value >> 21) & 0xF)); - return -EINVAL; - } - track->cb_dirty = true; - break; - case 0x4F00: - /* ZB_CNTL */ - if (idx_value & 2) { - track->z_enabled = true; - } else { - track->z_enabled = false; - } - track->zb_dirty = true; - break; - case 0x4F10: - /* ZB_FORMAT */ - switch ((idx_value & 0xF)) { - case 0: - case 1: - track->zb.cpp = 2; - break; - case 2: - track->zb.cpp = 4; - break; - default: - DRM_ERROR("Invalid z buffer format (%d) !\n", - (idx_value & 0xF)); - return -EINVAL; - } - track->zb_dirty = true; - break; - case 0x4F24: - /* ZB_DEPTHPITCH */ - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R300_DEPTHMACROTILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_DEPTHMICROTILE_TILED; - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) - tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; - - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; - } - track->zb.pitch = idx_value & 0x3FFC; - track->zb_dirty = true; - break; - case 0x4104: - /* TX_ENABLE */ - for (i = 0; i < 16; i++) { - bool enabled; - - enabled = !!(idx_value & (1 << i)); - track->textures[i].enabled = enabled; - } - track->tex_dirty = true; - break; - case 0x44C0: - case 0x44C4: - case 0x44C8: - case 0x44CC: - case 0x44D0: - case 0x44D4: - case 0x44D8: - case 0x44DC: - case 0x44E0: - case 0x44E4: - case 0x44E8: - case 0x44EC: - case 0x44F0: - case 0x44F4: - case 0x44F8: - case 0x44FC: - /* TX_FORMAT1_[0-15] */ - i = (reg - 0x44C0) >> 2; - tmp = (idx_value >> 25) & 0x3; - track->textures[i].tex_coord_type = tmp; - switch ((idx_value & 0x1F)) { - case R300_TX_FORMAT_X8: - case R300_TX_FORMAT_Y4X4: - case R300_TX_FORMAT_Z3Y3X2: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R300_TX_FORMAT_X16: - case R300_TX_FORMAT_FL_I16: - case R300_TX_FORMAT_Y8X8: - case R300_TX_FORMAT_Z5Y6X5: - case R300_TX_FORMAT_Z6Y5X5: - case R300_TX_FORMAT_W4Z4Y4X4: - case R300_TX_FORMAT_W1Z5Y5X5: - case R300_TX_FORMAT_D3DMFT_CxV8U8: - case R300_TX_FORMAT_B8G8_B8G8: - case R300_TX_FORMAT_G8R8_G8B8: - track->textures[i].cpp = 2; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R300_TX_FORMAT_Y16X16: - case R300_TX_FORMAT_FL_I16A16: - case R300_TX_FORMAT_Z11Y11X10: - case R300_TX_FORMAT_Z10Y11X11: - case R300_TX_FORMAT_W8Z8Y8X8: - case R300_TX_FORMAT_W2Z10Y10X10: - case 0x17: - case R300_TX_FORMAT_FL_I32: - case 0x1e: - track->textures[i].cpp = 4; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R300_TX_FORMAT_W16Z16Y16X16: - case R300_TX_FORMAT_FL_R16G16B16A16: - case R300_TX_FORMAT_FL_I32A32: - track->textures[i].cpp = 8; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R300_TX_FORMAT_FL_R32G32B32A32: - track->textures[i].cpp = 16; - track->textures[i].compress_format = R100_TRACK_COMP_NONE; - break; - case R300_TX_FORMAT_DXT1: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_DXT1; - break; - case R300_TX_FORMAT_ATI2N: - if (p->rdev->family < CHIP_R420) { - DRM_ERROR("Invalid texture format %u\n", - (idx_value & 0x1F)); - return -EINVAL; - } - /* The same rules apply as for DXT3/5. */ - /* Pass through. */ - case R300_TX_FORMAT_DXT3: - case R300_TX_FORMAT_DXT5: - track->textures[i].cpp = 1; - track->textures[i].compress_format = R100_TRACK_COMP_DXT35; - break; - default: - DRM_ERROR("Invalid texture format %u\n", - (idx_value & 0x1F)); - return -EINVAL; - } - track->tex_dirty = true; - break; - case 0x4400: - case 0x4404: - case 0x4408: - case 0x440C: - case 0x4410: - case 0x4414: - case 0x4418: - case 0x441C: - case 0x4420: - case 0x4424: - case 0x4428: - case 0x442C: - case 0x4430: - case 0x4434: - case 0x4438: - case 0x443C: - /* TX_FILTER0_[0-15] */ - i = (reg - 0x4400) >> 2; - tmp = idx_value & 0x7; - if (tmp == 2 || tmp == 4 || tmp == 6) { - track->textures[i].roundup_w = false; - } - tmp = (idx_value >> 3) & 0x7; - if (tmp == 2 || tmp == 4 || tmp == 6) { - track->textures[i].roundup_h = false; - } - track->tex_dirty = true; - break; - case 0x4500: - case 0x4504: - case 0x4508: - case 0x450C: - case 0x4510: - case 0x4514: - case 0x4518: - case 0x451C: - case 0x4520: - case 0x4524: - case 0x4528: - case 0x452C: - case 0x4530: - case 0x4534: - case 0x4538: - case 0x453C: - /* TX_FORMAT2_[0-15] */ - i = (reg - 0x4500) >> 2; - tmp = idx_value & 0x3FFF; - track->textures[i].pitch = tmp + 1; - if (p->rdev->family >= CHIP_RV515) { - tmp = ((idx_value >> 15) & 1) << 11; - track->textures[i].width_11 = tmp; - tmp = ((idx_value >> 16) & 1) << 11; - track->textures[i].height_11 = tmp; - - /* ATI1N */ - if (idx_value & (1 << 14)) { - /* The same rules apply as for DXT1. */ - track->textures[i].compress_format = - R100_TRACK_COMP_DXT1; - } - } else if (idx_value & (1 << 14)) { - DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); - return -EINVAL; - } - track->tex_dirty = true; - break; - case 0x4480: - case 0x4484: - case 0x4488: - case 0x448C: - case 0x4490: - case 0x4494: - case 0x4498: - case 0x449C: - case 0x44A0: - case 0x44A4: - case 0x44A8: - case 0x44AC: - case 0x44B0: - case 0x44B4: - case 0x44B8: - case 0x44BC: - /* TX_FORMAT0_[0-15] */ - i = (reg - 0x4480) >> 2; - tmp = idx_value & 0x7FF; - track->textures[i].width = tmp + 1; - tmp = (idx_value >> 11) & 0x7FF; - track->textures[i].height = tmp + 1; - tmp = (idx_value >> 26) & 0xF; - track->textures[i].num_levels = tmp; - tmp = idx_value & (1 << 31); - track->textures[i].use_pitch = !!tmp; - tmp = (idx_value >> 22) & 0xF; - track->textures[i].txdepth = tmp; - track->tex_dirty = true; - break; - case R300_ZB_ZPASS_ADDR: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case 0x4e0c: - /* RB3D_COLOR_CHANNEL_MASK */ - track->color_channel_mask = idx_value; - track->cb_dirty = true; - break; - case 0x43a4: - /* SC_HYPERZ_EN */ - /* r300c emits this register - we need to disable hyperz for it - * without complaining */ - if (p->rdev->hyperz_filp != p->filp) { - if (idx_value & 0x1) - ib[idx] = idx_value & ~1; - } - break; - case 0x4f1c: - /* ZB_BW_CNTL */ - track->zb_cb_clear = !!(idx_value & (1 << 5)); - track->cb_dirty = true; - track->zb_dirty = true; - if (p->rdev->hyperz_filp != p->filp) { - if (idx_value & (R300_HIZ_ENABLE | - R300_RD_COMP_ENABLE | - R300_WR_COMP_ENABLE | - R300_FAST_FILL_ENABLE)) - goto fail; - } - break; - case 0x4e04: - /* RB3D_BLENDCNTL */ - track->blend_read_enable = !!(idx_value & (1 << 2)); - track->cb_dirty = true; - break; - case R300_RB3D_AARESOLVE_OFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->aa.robj = reloc->robj; - track->aa.offset = idx_value; - track->aa_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case R300_RB3D_AARESOLVE_PITCH: - track->aa.pitch = idx_value & 0x3FFE; - track->aa_dirty = true; - break; - case R300_RB3D_AARESOLVE_CTL: - track->aaresolve = idx_value & 0x1; - track->aa_dirty = true; - break; - case 0x4f30: /* ZB_MASK_OFFSET */ - case 0x4f34: /* ZB_ZMASK_PITCH */ - case 0x4f44: /* ZB_HIZ_OFFSET */ - case 0x4f54: /* ZB_HIZ_PITCH */ - if (idx_value && (p->rdev->hyperz_filp != p->filp)) - goto fail; - break; - case 0x4028: - if (idx_value && (p->rdev->hyperz_filp != p->filp)) - goto fail; - /* GB_Z_PEQ_CONFIG */ - if (p->rdev->family >= CHIP_RV350) - break; - goto fail; - break; - case 0x4be8: - /* valid register only on RV530 */ - if (p->rdev->family == CHIP_RV530) - break; - /* fallthrough do not move */ - default: - goto fail; - } - return 0; -fail: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d (val=%08x)\n", - reg, idx, idx_value); - return -EINVAL; -} - -static int r300_packet3_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - struct radeon_cs_reloc *reloc; - struct r100_cs_track *track; - volatile uint32_t *ib; - unsigned idx; - int r; - - ib = p->ib->ptr; - idx = pkt->idx + 1; - track = (struct r100_cs_track *)p->track; - switch(pkt->opcode) { - case PACKET3_3D_LOAD_VBPNTR: - r = r100_packet3_load_vbpntr(p, pkt, idx); - if (r) - return r; - break; - case PACKET3_INDX_BUFFER: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); - r100_cs_dump_packet(p, pkt); - return r; - } - ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); - r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); - if (r) { - return r; - } - break; - /* Draw packet */ - case PACKET3_3D_DRAW_IMMD: - /* Number of dwords is vtx_size * (num_vertices - 1) - * PRIM_WALK must be equal to 3 vertex data in embedded - * in cmd stream */ - if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) { - DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); - return -EINVAL; - } - track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); - track->immd_dwords = pkt->count - 1; - r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_IMMD_2: - /* Number of dwords is vtx_size * (num_vertices - 1) - * PRIM_WALK must be equal to 3 vertex data in embedded - * in cmd stream */ - if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) { - DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); - return -EINVAL; - } - track->vap_vf_cntl = radeon_get_ib_value(p, idx); - track->immd_dwords = pkt->count; - r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_VBUF: - track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); - r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_VBUF_2: - track->vap_vf_cntl = radeon_get_ib_value(p, idx); - r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_INDX: - track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); - r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_INDX_2: - track->vap_vf_cntl = radeon_get_ib_value(p, idx); - r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_CLEAR_HIZ: - case PACKET3_3D_CLEAR_ZMASK: - if (p->rdev->hyperz_filp != p->filp) - return -EINVAL; - break; - case PACKET3_3D_CLEAR_CMASK: - if (p->rdev->cmask_filp != p->filp) - return -EINVAL; - break; - case PACKET3_NOP: - break; - default: - DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -int r300_cs_parse(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet pkt; - struct r100_cs_track *track; - int r; - - track = kzalloc(sizeof(*track), GFP_KERNEL); - if (track == NULL) - return -ENOMEM; - r100_cs_track_clear(p->rdev, track); - p->track = track; - do { - r = r100_cs_packet_parse(p, &pkt, p->idx); - if (r) { - return r; - } - p->idx += pkt.count + 2; - switch (pkt.type) { - case PACKET_TYPE0: - r = r100_cs_parse_packet0(p, &pkt, - p->rdev->config.r300.reg_safe_bm, - p->rdev->config.r300.reg_safe_bm_size, - &r300_packet0_check); - break; - case PACKET_TYPE2: - break; - case PACKET_TYPE3: - r = r300_packet3_check(p, &pkt); - break; - default: - DRM_ERROR("Unknown packet type %d !\n", pkt.type); - return -EINVAL; - } - if (r) { - return r; - } - } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); - return 0; -} - -void r300_set_reg_safe(struct radeon_device *rdev) -{ - rdev->config.r300.reg_safe_bm = r300_reg_safe_bm; - rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm); -} - -void r300_mc_program(struct radeon_device *rdev) -{ - struct r100_mc_save save; - int r; - - r = r100_debugfs_mc_info_init(rdev); - if (r) { - dev_err(rdev->dev, "Failed to create r100_mc debugfs file.\n"); - } - - /* Stops all mc clients */ - r100_mc_stop(rdev, &save); - if (rdev->flags & RADEON_IS_AGP) { - WREG32(R_00014C_MC_AGP_LOCATION, - S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | - S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); - WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); - WREG32(R_00015C_AGP_BASE_2, - upper_32_bits(rdev->mc.agp_base) & 0xff); - } else { - WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF); - WREG32(R_000170_AGP_BASE, 0); - WREG32(R_00015C_AGP_BASE_2, 0); - } - /* Wait for mc idle */ - if (r300_mc_wait_for_idle(rdev)) - DRM_INFO("Failed to wait MC idle before programming MC.\n"); - /* Program MC, should be a 32bits limited address space */ - WREG32(R_000148_MC_FB_LOCATION, - S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); - r100_mc_resume(rdev, &save); -} - -void r300_clock_startup(struct radeon_device *rdev) -{ - u32 tmp; - - if (radeon_dynclks != -1 && radeon_dynclks) - radeon_legacy_set_clock_gating(rdev, 1); - /* We need to force on some of the block */ - tmp = RREG32_PLL(R_00000D_SCLK_CNTL); - tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); - if ((rdev->family == CHIP_RV350) || (rdev->family == CHIP_RV380)) - tmp |= S_00000D_FORCE_VAP(1); - WREG32_PLL(R_00000D_SCLK_CNTL, tmp); -} - -static int r300_startup(struct radeon_device *rdev) -{ - int r; - - /* set common regs */ - r100_set_common_regs(rdev); - /* program mc */ - r300_mc_program(rdev); - /* Resume clock */ - r300_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ - r300_gpu_init(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - if (rdev->flags & RADEON_IS_PCIE) { - r = rv370_pcie_gart_enable(rdev); - if (r) - return r; - } - - if (rdev->family == CHIP_R300 || - rdev->family == CHIP_R350 || - rdev->family == CHIP_RV350) - r100_enable_bm(rdev); - - if (rdev->flags & RADEON_IS_PCI) { - r = r100_pci_gart_enable(rdev); - if (r) - return r; - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r100_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int r300_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_disable(rdev); - /* Resume clock before doing reset */ - r300_clock_startup(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - radeon_combios_asic_init(rdev->ddev); - /* Resume clock after posting */ - r300_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = r300_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int r300_suspend(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - r100_irq_disable(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_disable(rdev); - return 0; -} - -void r300_fini(struct radeon_device *rdev) -{ - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_fini(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_fini(rdev); - radeon_agp_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -int r300_init(struct radeon_device *rdev) -{ - int r; - - /* Disable VGA */ - r100_vga_render_disable(rdev); - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* TODO: disable VGA need to use VGA request */ - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); - return -EINVAL; - } else { - r = radeon_combios_init(rdev); - if (r) - return r; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - /* Set asic errata */ - r300_errata(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } - } - /* initialize memory controller */ - r300_mc_init(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - if (rdev->flags & RADEON_IS_PCIE) { - r = rv370_pcie_gart_init(rdev); - if (r) - return r; - } - if (rdev->flags & RADEON_IS_PCI) { - r = r100_pci_gart_init(rdev); - if (r) - return r; - } - r300_set_reg_safe(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = r300_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_fini(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_fini(rdev); - radeon_agp_fini(rdev); - rdev->accel_working = false; - } - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_cmdbuf.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_cmdbuf.c deleted file mode 100644 index 1fe98b42..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ /dev/null @@ -1,1185 +0,0 @@ -/* r300_cmdbuf.c -- Command buffer emission for R300 -*- linux-c -*- - * - * Copyright (C) The Weather Channel, Inc. 2002. - * Copyright (C) 2004 Nicolai Haehnle. - * All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Nicolai Haehnle - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_buffer.h" -#include "radeon_drm.h" -#include "radeon_drv.h" -#include "r300_reg.h" - -#include - -#define R300_SIMULTANEOUS_CLIPRECTS 4 - -/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects - */ -static const int r300_cliprect_cntl[4] = { - 0xAAAA, - 0xEEEE, - 0xFEFE, - 0xFFFE -}; - -/** - * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command - * buffer, starting with index n. - */ -static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, int n) -{ - struct drm_clip_rect box; - int nr; - int i; - RING_LOCALS; - - nr = cmdbuf->nbox - n; - if (nr > R300_SIMULTANEOUS_CLIPRECTS) - nr = R300_SIMULTANEOUS_CLIPRECTS; - - DRM_DEBUG("%i cliprects\n", nr); - - if (nr) { - BEGIN_RING(6 + nr * 2); - OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); - - for (i = 0; i < nr; ++i) { - if (DRM_COPY_FROM_USER_UNCHECKED - (&box, &cmdbuf->boxes[n + i], sizeof(box))) { - DRM_ERROR("copy cliprect faulted\n"); - return -EFAULT; - } - - box.x2--; /* Hardware expects inclusive bottom-right corner */ - box.y2--; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - box.x1 = (box.x1) & - R300_CLIPRECT_MASK; - box.y1 = (box.y1) & - R300_CLIPRECT_MASK; - box.x2 = (box.x2) & - R300_CLIPRECT_MASK; - box.y2 = (box.y2) & - R300_CLIPRECT_MASK; - } else { - box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & - R300_CLIPRECT_MASK; - } - - OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) | - (box.y1 << R300_CLIPRECT_Y_SHIFT)); - OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) | - (box.y2 << R300_CLIPRECT_Y_SHIFT)); - - } - - OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]); - - /* TODO/SECURITY: Force scissors to a safe value, otherwise the - * client might be able to trample over memory. - * The impact should be very limited, but I'd rather be safe than - * sorry. - */ - OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1)); - OUT_RING(0); - OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK); - ADVANCE_RING(); - } else { - /* Why we allow zero cliprect rendering: - * There are some commands in a command buffer that must be submitted - * even when there are no cliprects, e.g. DMA buffer discard - * or state setting (though state setting could be avoided by - * simulating a loss of context). - * - * Now since the cmdbuf interface is so chaotic right now (and is - * bound to remain that way for a bit until things settle down), - * it is basically impossible to filter out the commands that are - * necessary and those that aren't. - * - * So I choose the safe way and don't do any filtering at all; - * instead, I simply set up the engine so that all rendering - * can't produce any fragments. - */ - BEGIN_RING(2); - OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0); - ADVANCE_RING(); - } - - /* flus cache and wait idle clean after cliprect change */ - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(R300_RB3D_DC_FLUSH); - ADVANCE_RING(); - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(RADEON_WAIT_3D_IDLECLEAN); - ADVANCE_RING(); - /* set flush flag */ - dev_priv->track_flush |= RADEON_FLUSH_EMITED; - - return 0; -} - -static u8 r300_reg_flags[0x10000 >> 2]; - -void r300_init_reg_flags(struct drm_device *dev) -{ - int i; - drm_radeon_private_t *dev_priv = dev->dev_private; - - memset(r300_reg_flags, 0, 0x10000 >> 2); -#define ADD_RANGE_MARK(reg, count,mark) \ - for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\ - r300_reg_flags[i]|=(mark); - -#define MARK_SAFE 1 -#define MARK_CHECK_OFFSET 2 - -#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE) - - /* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */ - ADD_RANGE(R300_SE_VPORT_XSCALE, 6); - ADD_RANGE(R300_VAP_CNTL, 1); - ADD_RANGE(R300_SE_VTE_CNTL, 2); - ADD_RANGE(0x2134, 2); - ADD_RANGE(R300_VAP_CNTL_STATUS, 1); - ADD_RANGE(R300_VAP_INPUT_CNTL_0, 2); - ADD_RANGE(0x21DC, 1); - ADD_RANGE(R300_VAP_UNKNOWN_221C, 1); - ADD_RANGE(R300_VAP_CLIP_X_0, 4); - ADD_RANGE(R300_VAP_PVS_STATE_FLUSH_REG, 1); - ADD_RANGE(R300_VAP_UNKNOWN_2288, 1); - ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2); - ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); - ADD_RANGE(R300_GB_ENABLE, 1); - ADD_RANGE(R300_GB_MSPOS0, 5); - ADD_RANGE(R300_TX_INVALTAGS, 1); - ADD_RANGE(R300_TX_ENABLE, 1); - ADD_RANGE(0x4200, 4); - ADD_RANGE(0x4214, 1); - ADD_RANGE(R300_RE_POINTSIZE, 1); - ADD_RANGE(0x4230, 3); - ADD_RANGE(R300_RE_LINE_CNT, 1); - ADD_RANGE(R300_RE_UNK4238, 1); - ADD_RANGE(0x4260, 3); - ADD_RANGE(R300_RE_SHADE, 4); - ADD_RANGE(R300_RE_POLYGON_MODE, 5); - ADD_RANGE(R300_RE_ZBIAS_CNTL, 1); - ADD_RANGE(R300_RE_ZBIAS_T_FACTOR, 4); - ADD_RANGE(R300_RE_OCCLUSION_CNTL, 1); - ADD_RANGE(R300_RE_CULL_CNTL, 1); - ADD_RANGE(0x42C0, 2); - ADD_RANGE(R300_RS_CNTL_0, 2); - - ADD_RANGE(R300_SU_REG_DEST, 1); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) - ADD_RANGE(RV530_FG_ZBREG_DEST, 1); - - ADD_RANGE(R300_SC_HYPERZ, 2); - ADD_RANGE(0x43E8, 1); - - ADD_RANGE(0x46A4, 5); - - ADD_RANGE(R300_RE_FOG_STATE, 1); - ADD_RANGE(R300_FOG_COLOR_R, 3); - ADD_RANGE(R300_PP_ALPHA_TEST, 2); - ADD_RANGE(0x4BD8, 1); - ADD_RANGE(R300_PFS_PARAM_0_X, 64); - ADD_RANGE(0x4E00, 1); - ADD_RANGE(R300_RB3D_CBLEND, 2); - ADD_RANGE(R300_RB3D_COLORMASK, 1); - ADD_RANGE(R300_RB3D_BLEND_COLOR, 3); - ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */ - ADD_RANGE(R300_RB3D_COLORPITCH0, 1); - ADD_RANGE(0x4E50, 9); - ADD_RANGE(0x4E88, 1); - ADD_RANGE(0x4EA0, 2); - ADD_RANGE(R300_ZB_CNTL, 3); - ADD_RANGE(R300_ZB_FORMAT, 4); - ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ - ADD_RANGE(R300_ZB_DEPTHPITCH, 1); - ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1); - ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13); - ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */ - - ADD_RANGE(R300_TX_FILTER_0, 16); - ADD_RANGE(R300_TX_FILTER1_0, 16); - ADD_RANGE(R300_TX_SIZE_0, 16); - ADD_RANGE(R300_TX_FORMAT_0, 16); - ADD_RANGE(R300_TX_PITCH_0, 16); - /* Texture offset is dangerous and needs more checking */ - ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); - ADD_RANGE(R300_TX_CHROMA_KEY_0, 16); - ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); - - /* Sporadic registers used as primitives are emitted */ - ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1); - ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); - ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); - ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - ADD_RANGE(R500_VAP_INDEX_OFFSET, 1); - ADD_RANGE(R500_US_CONFIG, 2); - ADD_RANGE(R500_US_CODE_ADDR, 3); - ADD_RANGE(R500_US_FC_CTRL, 1); - ADD_RANGE(R500_RS_IP_0, 16); - ADD_RANGE(R500_RS_INST_0, 16); - ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); - ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2); - ADD_RANGE(R500_ZB_FIFO_SIZE, 2); - } else { - ADD_RANGE(R300_PFS_CNTL_0, 3); - ADD_RANGE(R300_PFS_NODE_0, 4); - ADD_RANGE(R300_PFS_TEXI_0, 64); - ADD_RANGE(R300_PFS_INSTR0_0, 64); - ADD_RANGE(R300_PFS_INSTR1_0, 64); - ADD_RANGE(R300_PFS_INSTR2_0, 64); - ADD_RANGE(R300_PFS_INSTR3_0, 64); - ADD_RANGE(R300_RS_INTERP_0, 8); - ADD_RANGE(R300_RS_ROUTE_0, 8); - - } -} - -static __inline__ int r300_check_range(unsigned reg, int count) -{ - int i; - if (reg & ~0xffff) - return -1; - for (i = (reg >> 2); i < (reg >> 2) + count; i++) - if (r300_reg_flags[i] != MARK_SAFE) - return 1; - return 0; -} - -static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t * - dev_priv, - drm_radeon_kcmd_buffer_t - * cmdbuf, - drm_r300_cmd_header_t - header) -{ - int reg; - int sz; - int i; - u32 *value; - RING_LOCALS; - - sz = header.packet0.count; - reg = (header.packet0.reghi << 8) | header.packet0.reglo; - - if ((sz > 64) || (sz < 0)) { - DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", - reg, sz); - return -EINVAL; - } - - for (i = 0; i < sz; i++) { - switch (r300_reg_flags[(reg >> 2) + i]) { - case MARK_SAFE: - break; - case MARK_CHECK_OFFSET: - value = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); - if (!radeon_check_offset(dev_priv, *value)) { - DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n", - reg, sz); - return -EINVAL; - } - break; - default: - DRM_ERROR("Register %04x failed check as flag=%02x\n", - reg + i * 4, r300_reg_flags[(reg >> 2) + i]); - return -EINVAL; - } - } - - BEGIN_RING(1 + sz); - OUT_RING(CP_PACKET0(reg, sz - 1)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - - return 0; -} - -/** - * Emits a packet0 setting arbitrary registers. - * Called by r300_do_cp_cmdbuf. - * - * Note that checks are performed on contents and addresses of the registers - */ -static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int reg; - int sz; - RING_LOCALS; - - sz = header.packet0.count; - reg = (header.packet0.reghi << 8) | header.packet0.reglo; - - if (!sz) - return 0; - - if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) - return -EINVAL; - - if (reg + sz * 4 >= 0x10000) { - DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, - sz); - return -EINVAL; - } - - if (r300_check_range(reg, sz)) { - /* go and check everything */ - return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, - header); - } - /* the rest of the data is safe to emit, whatever the values the user passed */ - - BEGIN_RING(1 + sz); - OUT_RING(CP_PACKET0(reg, sz - 1)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - - return 0; -} - -/** - * Uploads user-supplied vertex program instructions or parameters onto - * the graphics card. - * Called by r300_do_cp_cmdbuf. - */ -static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int sz; - int addr; - RING_LOCALS; - - sz = header.vpu.count; - addr = (header.vpu.adrhi << 8) | header.vpu.adrlo; - - if (!sz) - return 0; - if (sz * 16 > drm_buffer_unprocessed(cmdbuf->buffer)) - return -EINVAL; - - /* VAP is very sensitive so we purge cache before we program it - * and we also flush its state before & after */ - BEGIN_RING(6); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(R300_RB3D_DC_FLUSH); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(RADEON_WAIT_3D_IDLECLEAN); - OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0)); - OUT_RING(0); - ADVANCE_RING(); - /* set flush flag */ - dev_priv->track_flush |= RADEON_FLUSH_EMITED; - - BEGIN_RING(3 + sz * 4); - OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr); - OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz * 4); - ADVANCE_RING(); - - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0)); - OUT_RING(0); - ADVANCE_RING(); - - return 0; -} - -/** - * Emit a clear packet from userspace. - * Called by r300_emit_packet3. - */ -static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - RING_LOCALS; - - if (8 * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) - return -EINVAL; - - BEGIN_RING(10); - OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); - OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | - (1 << R300_PRIM_NUM_VERTICES_SHIFT)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, 8); - ADVANCE_RING(); - - BEGIN_RING(4); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(R300_RB3D_DC_FLUSH); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(RADEON_WAIT_3D_IDLECLEAN); - ADVANCE_RING(); - /* set flush flag */ - dev_priv->track_flush |= RADEON_FLUSH_EMITED; - - return 0; -} - -static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - u32 header) -{ - int count, i, k; -#define MAX_ARRAY_PACKET 64 - u32 *data; - u32 narrays; - RING_LOCALS; - - count = (header & RADEON_CP_PACKET_COUNT_MASK) >> 16; - - if ((count + 1) > MAX_ARRAY_PACKET) { - DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", - count); - return -EINVAL; - } - /* carefully check packet contents */ - - /* We have already read the header so advance the buffer. */ - drm_buffer_advance(cmdbuf->buffer, 4); - - narrays = *(u32 *)drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - k = 0; - i = 1; - while ((k < narrays) && (i < (count + 1))) { - i++; /* skip attribute field */ - data = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); - if (!radeon_check_offset(dev_priv, *data)) { - DRM_ERROR - ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - if (k == narrays) - break; - /* have one more to process, they come in pairs */ - data = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); - if (!radeon_check_offset(dev_priv, *data)) { - DRM_ERROR - ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - } - /* do the counts match what we expect ? */ - if ((k != narrays) || (i != (count + 1))) { - DRM_ERROR - ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", - k, i, narrays, count + 1); - return -EINVAL; - } - - /* all clear, output packet */ - - BEGIN_RING(count + 2); - OUT_RING(header); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 1); - ADVANCE_RING(); - - return 0; -} - -static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - int count, ret; - RING_LOCALS; - - - count = (*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16; - - if (*cmd & 0x8000) { - u32 offset; - u32 *cmd1 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - if (*cmd1 & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL - | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - - u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2); - offset = *cmd2 << 10; - ret = !radeon_check_offset(dev_priv, offset); - if (ret) { - DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); - return -EINVAL; - } - } - - if ((*cmd1 & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && - (*cmd1 & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); - offset = *cmd3 << 10; - ret = !radeon_check_offset(dev_priv, offset); - if (ret) { - DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); - return -EINVAL; - } - - } - } - - BEGIN_RING(count+2); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 2); - ADVANCE_RING(); - - return 0; -} - -static __inline__ int r300_emit_draw_indx_2(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - u32 *cmd1 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - int count; - int expected_count; - RING_LOCALS; - - count = (*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16; - - expected_count = *cmd1 >> 16; - if (!(*cmd1 & R300_VAP_VF_CNTL__INDEX_SIZE_32bit)) - expected_count = (expected_count+1)/2; - - if (count && count != expected_count) { - DRM_ERROR("3D_DRAW_INDX_2: packet size %i, expected %i\n", - count, expected_count); - return -EINVAL; - } - - BEGIN_RING(count+2); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 2); - ADVANCE_RING(); - - if (!count) { - drm_r300_cmd_header_t stack_header, *header; - u32 *cmd1, *cmd2, *cmd3; - - if (drm_buffer_unprocessed(cmdbuf->buffer) - < 4*4 + sizeof(stack_header)) { - DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER, but stream is too short.\n"); - return -EINVAL; - } - - header = drm_buffer_read_object(cmdbuf->buffer, - sizeof(stack_header), &stack_header); - - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - cmd1 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2); - cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); - - if (header->header.cmd_type != R300_CMD_PACKET3 || - header->packet3.packet != R300_CMD_PACKET3_RAW || - *cmd != CP_PACKET3(RADEON_CP_INDX_BUFFER, 2)) { - DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER.\n"); - return -EINVAL; - } - - if ((*cmd1 & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", - *cmd1); - return -EINVAL; - } - if (!radeon_check_offset(dev_priv, *cmd2)) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", - *cmd2); - return -EINVAL; - } - if (*cmd3 != expected_count) { - DRM_ERROR("INDX_BUFFER: buffer size %i, expected %i\n", - *cmd3, expected_count); - return -EINVAL; - } - - BEGIN_RING(4); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, 4); - ADVANCE_RING(); - } - - return 0; -} - -static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - u32 *header; - int count; - RING_LOCALS; - - if (4 > drm_buffer_unprocessed(cmdbuf->buffer)) - return -EINVAL; - - /* Fixme !! This simply emits a packet without much checking. - We need to be smarter. */ - - /* obtain first word - actual packet3 header */ - header = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - - /* Is it packet 3 ? */ - if ((*header >> 30) != 0x3) { - DRM_ERROR("Not a packet3 header (0x%08x)\n", *header); - return -EINVAL; - } - - count = (*header >> 16) & 0x3fff; - - /* Check again now that we know how much data to expect */ - if ((count + 2) * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) { - DRM_ERROR - ("Expected packet3 of length %d but have only %d bytes left\n", - (count + 2) * 4, drm_buffer_unprocessed(cmdbuf->buffer)); - return -EINVAL; - } - - /* Is it a packet type we know about ? */ - switch (*header & 0xff00) { - case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ - return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, *header); - - case RADEON_CNTL_BITBLT_MULTI: - return r300_emit_bitblt_multi(dev_priv, cmdbuf); - - case RADEON_CP_INDX_BUFFER: - DRM_ERROR("packet3 INDX_BUFFER without preceding 3D_DRAW_INDX_2 is illegal.\n"); - return -EINVAL; - case RADEON_CP_3D_DRAW_IMMD_2: - /* triggers drawing using in-packet vertex data */ - case RADEON_CP_3D_DRAW_VBUF_2: - /* triggers drawing of vertex buffers setup elsewhere */ - dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED | - RADEON_PURGE_EMITED); - break; - case RADEON_CP_3D_DRAW_INDX_2: - /* triggers drawing using indices to vertex buffer */ - /* whenever we send vertex we clear flush & purge */ - dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED | - RADEON_PURGE_EMITED); - return r300_emit_draw_indx_2(dev_priv, cmdbuf); - case RADEON_WAIT_FOR_IDLE: - case RADEON_CP_NOP: - /* these packets are safe */ - break; - default: - DRM_ERROR("Unknown packet3 header (0x%08x)\n", *header); - return -EINVAL; - } - - BEGIN_RING(count + 2); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, count + 2); - ADVANCE_RING(); - - return 0; -} - -/** - * Emit a rendering packet3 from userspace. - * Called by r300_do_cp_cmdbuf. - */ -static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int n; - int ret; - int orig_iter = cmdbuf->buffer->iterator; - - /* This is a do-while-loop so that we run the interior at least once, - * even if cmdbuf->nbox is 0. Compare r300_emit_cliprects for rationale. - */ - n = 0; - do { - if (cmdbuf->nbox > R300_SIMULTANEOUS_CLIPRECTS) { - ret = r300_emit_cliprects(dev_priv, cmdbuf, n); - if (ret) - return ret; - - cmdbuf->buffer->iterator = orig_iter; - } - - switch (header.packet3.packet) { - case R300_CMD_PACKET3_CLEAR: - DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n"); - ret = r300_emit_clear(dev_priv, cmdbuf); - if (ret) { - DRM_ERROR("r300_emit_clear failed\n"); - return ret; - } - break; - - case R300_CMD_PACKET3_RAW: - DRM_DEBUG("R300_CMD_PACKET3_RAW\n"); - ret = r300_emit_raw_packet3(dev_priv, cmdbuf); - if (ret) { - DRM_ERROR("r300_emit_raw_packet3 failed\n"); - return ret; - } - break; - - default: - DRM_ERROR("bad packet3 type %i at byte %d\n", - header.packet3.packet, - cmdbuf->buffer->iterator - (int)sizeof(header)); - return -EINVAL; - } - - n += R300_SIMULTANEOUS_CLIPRECTS; - } while (n < cmdbuf->nbox); - - return 0; -} - -/* Some of the R300 chips seem to be extremely touchy about the two registers - * that are configured in r300_pacify. - * Among the worst offenders seems to be the R300 ND (0x4E44): When userspace - * sends a command buffer that contains only state setting commands and a - * vertex program/parameter upload sequence, this will eventually lead to a - * lockup, unless the sequence is bracketed by calls to r300_pacify. - * So we should take great care to *always* call r300_pacify before - * *anything* 3D related, and again afterwards. This is what the - * call bracket in r300_do_cp_cmdbuf is for. - */ - -/** - * Emit the sequence to pacify R300. - */ -static void r300_pacify(drm_radeon_private_t *dev_priv) -{ - uint32_t cache_z, cache_3d, cache_2d; - RING_LOCALS; - - cache_z = R300_ZC_FLUSH; - cache_2d = R300_RB2D_DC_FLUSH; - cache_3d = R300_RB3D_DC_FLUSH; - if (!(dev_priv->track_flush & RADEON_PURGE_EMITED)) { - /* we can purge, primitive where draw since last purge */ - cache_z |= R300_ZC_FREE; - cache_2d |= R300_RB2D_DC_FREE; - cache_3d |= R300_RB3D_DC_FREE; - } - - /* flush & purge zbuffer */ - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); - OUT_RING(cache_z); - ADVANCE_RING(); - /* flush & purge 3d */ - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(cache_3d); - ADVANCE_RING(); - /* flush & purge texture */ - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_TX_INVALTAGS, 0)); - OUT_RING(0); - ADVANCE_RING(); - /* FIXME: is this one really needed ? */ - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_RB3D_AARESOLVE_CTL, 0)); - OUT_RING(0); - ADVANCE_RING(); - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(RADEON_WAIT_3D_IDLECLEAN); - ADVANCE_RING(); - /* flush & purge 2d through E2 as RB2D will trigger lockup */ - BEGIN_RING(4); - OUT_RING(CP_PACKET0(R300_DSTCACHE_CTLSTAT, 0)); - OUT_RING(cache_2d); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(RADEON_WAIT_2D_IDLECLEAN | - RADEON_WAIT_HOST_IDLECLEAN); - ADVANCE_RING(); - /* set flush & purge flags */ - dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED; -} - -/** - * Called by r300_do_cp_cmdbuf to update the internal buffer age and state. - * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must - * be careful about how this function is called. - */ -static void r300_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) -{ - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - - buf_priv->age = ++master_priv->sarea_priv->last_dispatch; - buf->pending = 1; - buf->used = 0; -} - -static void r300_cmd_wait(drm_radeon_private_t * dev_priv, - drm_r300_cmd_header_t header) -{ - u32 wait_until; - RING_LOCALS; - - if (!header.wait.flags) - return; - - wait_until = 0; - - switch(header.wait.flags) { - case R300_WAIT_2D: - wait_until = RADEON_WAIT_2D_IDLE; - break; - case R300_WAIT_3D: - wait_until = RADEON_WAIT_3D_IDLE; - break; - case R300_NEW_WAIT_2D_3D: - wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE; - break; - case R300_NEW_WAIT_2D_2D_CLEAN: - wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN; - break; - case R300_NEW_WAIT_3D_3D_CLEAN: - wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN; - break; - case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN: - wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN; - wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN; - break; - default: - return; - } - - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0)); - OUT_RING(wait_until); - ADVANCE_RING(); -} - -static int r300_scratch(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - u32 *ref_age_base; - u32 i, *buf_idx, h_pending; - u64 *ptr_addr; - u64 stack_ptr_addr; - RING_LOCALS; - - if (drm_buffer_unprocessed(cmdbuf->buffer) < - (sizeof(u64) + header.scratch.n_bufs * sizeof(*buf_idx))) { - return -EINVAL; - } - - if (header.scratch.reg >= 5) { - return -EINVAL; - } - - dev_priv->scratch_ages[header.scratch.reg]++; - - ptr_addr = drm_buffer_read_object(cmdbuf->buffer, - sizeof(stack_ptr_addr), &stack_ptr_addr); - ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr); - - for (i=0; i < header.scratch.n_bufs; i++) { - buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - *buf_idx *= 2; /* 8 bytes per buf */ - - if (DRM_COPY_TO_USER(ref_age_base + *buf_idx, - &dev_priv->scratch_ages[header.scratch.reg], - sizeof(u32))) - return -EINVAL; - - if (DRM_COPY_FROM_USER(&h_pending, - ref_age_base + *buf_idx + 1, - sizeof(u32))) - return -EINVAL; - - if (h_pending == 0) - return -EINVAL; - - h_pending--; - - if (DRM_COPY_TO_USER(ref_age_base + *buf_idx + 1, - &h_pending, - sizeof(u32))) - return -EINVAL; - - drm_buffer_advance(cmdbuf->buffer, sizeof(*buf_idx)); - } - - BEGIN_RING(2); - OUT_RING( CP_PACKET0( RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0 ) ); - OUT_RING( dev_priv->scratch_ages[header.scratch.reg] ); - ADVANCE_RING(); - - return 0; -} - -/** - * Uploads user-supplied vertex program instructions or parameters onto - * the graphics card. - * Called by r300_do_cp_cmdbuf. - */ -static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - int sz; - int addr; - int type; - int isclamp; - int stride; - RING_LOCALS; - - sz = header.r500fp.count; - /* address is 9 bits 0 - 8, bit 1 of flags is part of address */ - addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo; - - type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); - isclamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); - - addr |= (type << 16); - addr |= (isclamp << 17); - - stride = type ? 4 : 6; - - DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type); - if (!sz) - return 0; - if (sz * stride * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) - return -EINVAL; - - BEGIN_RING(3 + sz * stride); - OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr); - OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz * stride); - - ADVANCE_RING(); - - return 0; -} - - -/** - * Parses and validates a user-supplied command buffer and emits appropriate - * commands on the DMA ring buffer. - * Called by the ioctl handler function radeon_cp_cmdbuf. - */ -int r300_do_cp_cmdbuf(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf = NULL; - int emit_dispatch_age = 0; - int ret = 0; - - DRM_DEBUG("\n"); - - /* pacify */ - r300_pacify(dev_priv); - - if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) { - ret = r300_emit_cliprects(dev_priv, cmdbuf, 0); - if (ret) - goto cleanup; - } - - while (drm_buffer_unprocessed(cmdbuf->buffer) - >= sizeof(drm_r300_cmd_header_t)) { - int idx; - drm_r300_cmd_header_t *header, stack_header; - - header = drm_buffer_read_object(cmdbuf->buffer, - sizeof(stack_header), &stack_header); - - switch (header->header.cmd_type) { - case R300_CMD_PACKET0: - DRM_DEBUG("R300_CMD_PACKET0\n"); - ret = r300_emit_packet0(dev_priv, cmdbuf, *header); - if (ret) { - DRM_ERROR("r300_emit_packet0 failed\n"); - goto cleanup; - } - break; - - case R300_CMD_VPU: - DRM_DEBUG("R300_CMD_VPU\n"); - ret = r300_emit_vpu(dev_priv, cmdbuf, *header); - if (ret) { - DRM_ERROR("r300_emit_vpu failed\n"); - goto cleanup; - } - break; - - case R300_CMD_PACKET3: - DRM_DEBUG("R300_CMD_PACKET3\n"); - ret = r300_emit_packet3(dev_priv, cmdbuf, *header); - if (ret) { - DRM_ERROR("r300_emit_packet3 failed\n"); - goto cleanup; - } - break; - - case R300_CMD_END3D: - DRM_DEBUG("R300_CMD_END3D\n"); - /* TODO: - Ideally userspace driver should not need to issue this call, - i.e. the drm driver should issue it automatically and prevent - lockups. - - In practice, we do not understand why this call is needed and what - it does (except for some vague guesses that it has to do with cache - coherence) and so the user space driver does it. - - Once we are sure which uses prevent lockups the code could be moved - into the kernel and the userspace driver will not - need to use this command. - - Note that issuing this command does not hurt anything - except, possibly, performance */ - r300_pacify(dev_priv); - break; - - case R300_CMD_CP_DELAY: - /* simple enough, we can do it here */ - DRM_DEBUG("R300_CMD_CP_DELAY\n"); - { - int i; - RING_LOCALS; - - BEGIN_RING(header->delay.count); - for (i = 0; i < header->delay.count; i++) - OUT_RING(RADEON_CP_PACKET2); - ADVANCE_RING(); - } - break; - - case R300_CMD_DMA_DISCARD: - DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); - idx = header->dma.buf_idx; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - idx, dma->buf_count - 1); - ret = -EINVAL; - goto cleanup; - } - - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv || buf->pending) { - DRM_ERROR("bad buffer %p %p %d\n", - buf->file_priv, file_priv, - buf->pending); - ret = -EINVAL; - goto cleanup; - } - - emit_dispatch_age = 1; - r300_discard_buffer(dev, file_priv->master, buf); - break; - - case R300_CMD_WAIT: - DRM_DEBUG("R300_CMD_WAIT\n"); - r300_cmd_wait(dev_priv, *header); - break; - - case R300_CMD_SCRATCH: - DRM_DEBUG("R300_CMD_SCRATCH\n"); - ret = r300_scratch(dev_priv, cmdbuf, *header); - if (ret) { - DRM_ERROR("r300_scratch failed\n"); - goto cleanup; - } - break; - - case R300_CMD_R500FP: - if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) { - DRM_ERROR("Calling r500 command on r300 card\n"); - ret = -EINVAL; - goto cleanup; - } - DRM_DEBUG("R300_CMD_R500FP\n"); - ret = r300_emit_r500fp(dev_priv, cmdbuf, *header); - if (ret) { - DRM_ERROR("r300_emit_r500fp failed\n"); - goto cleanup; - } - break; - default: - DRM_ERROR("bad cmd_type %i at byte %d\n", - header->header.cmd_type, - cmdbuf->buffer->iterator - (int)sizeof(*header)); - ret = -EINVAL; - goto cleanup; - } - } - - DRM_DEBUG("END\n"); - - cleanup: - r300_pacify(dev_priv); - - /* We emit the vertex buffer age here, outside the pacifier "brackets" - * for two reasons: - * (1) This may coalesce multiple age emissions into a single one and - * (2) more importantly, some chips lock up hard when scratch registers - * are written inside the pacifier bracket. - */ - if (emit_dispatch_age) { - RING_LOCALS; - - /* Emit the vertex buffer age */ - BEGIN_RING(2); - RADEON_DISPATCH_AGE(master_priv->sarea_priv->last_dispatch); - ADVANCE_RING(); - } - - COMMIT_RING(); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_reg.h deleted file mode 100644 index 00c0d2ba..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300_reg.h +++ /dev/null @@ -1,1789 +0,0 @@ -/* - * Copyright 2005 Nicolai Haehnle et al. - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Nicolai Haehnle - * Jerome Glisse - */ -#ifndef _R300_REG_H_ -#define _R300_REG_H_ - -#define R300_SURF_TILE_MACRO (1<<16) -#define R300_SURF_TILE_MICRO (2<<16) -#define R300_SURF_TILE_BOTH (3<<16) - - -#define R300_MC_INIT_MISC_LAT_TIMER 0x180 -# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0 -# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4 -# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8 -# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12 -# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16 -# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20 -# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24 -# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28 - -#define R300_MC_INIT_GFX_LAT_TIMER 0x154 -# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0 -# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4 -# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8 -# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12 -# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16 -# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20 -# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24 -# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28 - -/* - * This file contains registers and constants for the R300. They have been - * found mostly by examining command buffers captured using glxtest, as well - * as by extrapolating some known registers and constants from the R200. - * I am fairly certain that they are correct unless stated otherwise - * in comments. - */ - -#define R300_SE_VPORT_XSCALE 0x1D98 -#define R300_SE_VPORT_XOFFSET 0x1D9C -#define R300_SE_VPORT_YSCALE 0x1DA0 -#define R300_SE_VPORT_YOFFSET 0x1DA4 -#define R300_SE_VPORT_ZSCALE 0x1DA8 -#define R300_SE_VPORT_ZOFFSET 0x1DAC - - -/* - * Vertex Array Processing (VAP) Control - * Stolen from r200 code from Christoph Brill (It's a guess!) - */ -#define R300_VAP_CNTL 0x2080 - -/* This register is written directly and also starts data section - * in many 3d CP_PACKET3's - */ -#define R300_VAP_VF_CNTL 0x2084 -# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0 -# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0) -# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0) -# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0) -# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0) -# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0) -# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0) -# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0) -# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0) -# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0) -# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0) -# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0) - -# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4 - /* State based - direct writes to registers trigger vertex - generation */ -# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4) -# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4) -# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4) -# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4) - - /* I don't think I saw these three used.. */ -# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6 -# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9 -# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10 - - /* index size - when not set the indices are assumed to be 16 bit */ -# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11) - /* number of vertices */ -# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16 - -/* BEGIN: Wild guesses */ -#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 -# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1) -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */ -# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */ - -#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094 - /* each of the following is 3 bits wide, specifies number - of components */ -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 -# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 -/* END: Wild guesses */ - -#define R300_SE_VTE_CNTL 0x20b0 -# define R300_VPORT_X_SCALE_ENA 0x00000001 -# define R300_VPORT_X_OFFSET_ENA 0x00000002 -# define R300_VPORT_Y_SCALE_ENA 0x00000004 -# define R300_VPORT_Y_OFFSET_ENA 0x00000008 -# define R300_VPORT_Z_SCALE_ENA 0x00000010 -# define R300_VPORT_Z_OFFSET_ENA 0x00000020 -# define R300_VTX_XY_FMT 0x00000100 -# define R300_VTX_Z_FMT 0x00000200 -# define R300_VTX_W0_FMT 0x00000400 -# define R300_VTX_W0_NORMALIZE 0x00000800 -# define R300_VTX_ST_DENORMALIZED 0x00001000 - -/* BEGIN: Vertex data assembly - lots of uncertainties */ - -/* gap */ - -#define R300_VAP_CNTL_STATUS 0x2140 -# define R300_VC_NO_SWAP (0 << 0) -# define R300_VC_16BIT_SWAP (1 << 0) -# define R300_VC_32BIT_SWAP (2 << 0) -# define R300_VAP_TCL_BYPASS (1 << 8) - -/* gap */ - -/* Where do we get our vertex data? - * - * Vertex data either comes either from immediate mode registers or from - * vertex arrays. - * There appears to be no mixed mode (though we can force the pitch of - * vertex arrays to 0, effectively reusing the same element over and over - * again). - * - * Immediate mode is controlled by the INPUT_CNTL registers. I am not sure - * if these registers influence vertex array processing. - * - * Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3. - * - * In both cases, vertex attributes are then passed through INPUT_ROUTE. - * - * Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data - * into the vertex processor's input registers. - * The first word routes the first input, the second word the second, etc. - * The corresponding input is routed into the register with the given index. - * The list is ended by a word with INPUT_ROUTE_END set. - * - * Always set COMPONENTS_4 in immediate mode. - */ - -#define R300_VAP_INPUT_ROUTE_0_0 0x2150 -# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */ -# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8 -# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */ -# define R300_VAP_INPUT_ROUTE_END (1 << 13) -# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */ -#define R300_VAP_INPUT_ROUTE_0_1 0x2154 -#define R300_VAP_INPUT_ROUTE_0_2 0x2158 -#define R300_VAP_INPUT_ROUTE_0_3 0x215C -#define R300_VAP_INPUT_ROUTE_0_4 0x2160 -#define R300_VAP_INPUT_ROUTE_0_5 0x2164 -#define R300_VAP_INPUT_ROUTE_0_6 0x2168 -#define R300_VAP_INPUT_ROUTE_0_7 0x216C - -/* gap */ - -/* Notes: - * - always set up to produce at least two attributes: - * if vertex program uses only position, fglrx will set normal, too - * - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal. - */ -#define R300_VAP_INPUT_CNTL_0 0x2180 -# define R300_INPUT_CNTL_0_COLOR 0x00000001 -#define R300_VAP_INPUT_CNTL_1 0x2184 -# define R300_INPUT_CNTL_POS 0x00000001 -# define R300_INPUT_CNTL_NORMAL 0x00000002 -# define R300_INPUT_CNTL_COLOR 0x00000004 -# define R300_INPUT_CNTL_TC0 0x00000400 -# define R300_INPUT_CNTL_TC1 0x00000800 -# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */ -# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */ -# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */ -# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */ -# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */ -# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */ - -/* gap */ - -/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0 - * are set to a swizzling bit pattern, other words are 0. - * - * In immediate mode, the pattern is always set to xyzw. In vertex array - * mode, the swizzling pattern is e.g. used to set zw components in texture - * coordinates with only tweo components. - */ -#define R300_VAP_INPUT_ROUTE_1_0 0x21E0 -# define R300_INPUT_ROUTE_SELECT_X 0 -# define R300_INPUT_ROUTE_SELECT_Y 1 -# define R300_INPUT_ROUTE_SELECT_Z 2 -# define R300_INPUT_ROUTE_SELECT_W 3 -# define R300_INPUT_ROUTE_SELECT_ZERO 4 -# define R300_INPUT_ROUTE_SELECT_ONE 5 -# define R300_INPUT_ROUTE_SELECT_MASK 7 -# define R300_INPUT_ROUTE_X_SHIFT 0 -# define R300_INPUT_ROUTE_Y_SHIFT 3 -# define R300_INPUT_ROUTE_Z_SHIFT 6 -# define R300_INPUT_ROUTE_W_SHIFT 9 -# define R300_INPUT_ROUTE_ENABLE (15 << 12) -#define R300_VAP_INPUT_ROUTE_1_1 0x21E4 -#define R300_VAP_INPUT_ROUTE_1_2 0x21E8 -#define R300_VAP_INPUT_ROUTE_1_3 0x21EC -#define R300_VAP_INPUT_ROUTE_1_4 0x21F0 -#define R300_VAP_INPUT_ROUTE_1_5 0x21F4 -#define R300_VAP_INPUT_ROUTE_1_6 0x21F8 -#define R300_VAP_INPUT_ROUTE_1_7 0x21FC - -/* END: Vertex data assembly */ - -/* gap */ - -/* BEGIN: Upload vertex program and data */ - -/* - * The programmable vertex shader unit has a memory bank of unknown size - * that can be written to in 16 byte units by writing the address into - * UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs). - * - * Pointers into the memory bank are always in multiples of 16 bytes. - * - * The memory bank is divided into areas with fixed meaning. - * - * Starting at address UPLOAD_PROGRAM: Vertex program instructions. - * Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB), - * whereas the difference between known addresses suggests size 512. - * - * Starting at address UPLOAD_PARAMETERS: Vertex program parameters. - * Native reported limits and the VPI layout suggest size 256, whereas - * difference between known addresses suggests size 512. - * - * At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the - * floating point pointsize. The exact purpose of this state is uncertain, - * as there is also the R300_RE_POINTSIZE register. - * - * Multiple vertex programs and parameter sets can be loaded at once, - * which could explain the size discrepancy. - */ -#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 -# define R300_PVS_UPLOAD_PROGRAM 0x00000000 -# define R300_PVS_UPLOAD_PARAMETERS 0x00000200 -# define R300_PVS_UPLOAD_POINTSIZE 0x00000406 - -/* gap */ - -#define R300_VAP_PVS_UPLOAD_DATA 0x2208 - -/* END: Upload vertex program and data */ - -/* gap */ - -/* I do not know the purpose of this register. However, I do know that - * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL - * for normal rendering. - */ -#define R300_VAP_UNKNOWN_221C 0x221C -# define R300_221C_NORMAL 0x00000000 -# define R300_221C_CLEAR 0x0001C000 - -/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first - * plane is per-pixel and the second plane is per-vertex. - * - * This was determined by experimentation alone but I believe it is correct. - * - * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest. - */ -#define R300_VAP_CLIP_X_0 0x2220 -#define R300_VAP_CLIP_X_1 0x2224 -#define R300_VAP_CLIP_Y_0 0x2228 -#define R300_VAP_CLIP_Y_1 0x2230 - -/* gap */ - -/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between - * rendering commands and overwriting vertex program parameters. - * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and - * avoids bugs caused by still running shaders reading bad data from memory. - */ -#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284 - -/* Absolutely no clue what this register is about. */ -#define R300_VAP_UNKNOWN_2288 0x2288 -# define R300_2288_R300 0x00750000 /* -- nh */ -# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ - -/* gap */ - -/* Addresses are relative to the vertex program instruction area of the - * memory bank. PROGRAM_END points to the last instruction of the active - * program - * - * The meaning of the two UNKNOWN fields is obviously not known. However, - * experiments so far have shown that both *must* point to an instruction - * inside the vertex program, otherwise the GPU locks up. - * - * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and - * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to - * position takes place. - * - * Most likely this is used to ignore rest of the program in cases - * where group of verts arent visible. For some reason this "section" - * is sometimes accepted other instruction that have no relationship with - * position calculations. - */ -#define R300_VAP_PVS_CNTL_1 0x22D0 -# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 -# define R300_PVS_CNTL_1_POS_END_SHIFT 10 -# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20 -/* Addresses are relative the the vertex program parameters area. */ -#define R300_VAP_PVS_CNTL_2 0x22D4 -# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0 -# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16 -#define R300_VAP_PVS_CNTL_3 0x22D8 -# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10 -# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0 - -/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for - * immediate vertices - */ -#define R300_VAP_VTX_COLOR_R 0x2464 -#define R300_VAP_VTX_COLOR_G 0x2468 -#define R300_VAP_VTX_COLOR_B 0x246C -#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */ -#define R300_VAP_VTX_POS_0_Y_1 0x2494 -#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */ -#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */ -#define R300_VAP_VTX_POS_0_Y_2 0x24A4 -#define R300_VAP_VTX_POS_0_Z_2 0x24A8 -/* write 0 to indicate end of packet? */ -#define R300_VAP_VTX_END_OF_PKT 0x24AC - -/* gap */ - -/* These are values from r300_reg/r300_reg.h - they are known to be correct - * and are here so we can use one register file instead of several - * - Vladimir - */ -#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000 -# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4) -# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5) -# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16) - -#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004 - /* each of the following is 3 bits wide, specifies number - of components */ -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 -# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 - -/* UNK30 seems to enables point to quad transformation on textures - * (or something closely related to that). - * This bit is rather fatal at the time being due to lackings at pixel - * shader side - */ -#define R300_GB_ENABLE 0x4008 -# define R300_GB_POINT_STUFF_ENABLE (1<<0) -# define R300_GB_LINE_STUFF_ENABLE (1<<1) -# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2) -# define R300_GB_STENCIL_AUTO_ENABLE (1<<4) -# define R300_GB_UNK31 (1<<31) - /* each of the following is 2 bits wide */ -#define R300_GB_TEX_REPLICATE 0 -#define R300_GB_TEX_ST 1 -#define R300_GB_TEX_STR 2 -# define R300_GB_TEX0_SOURCE_SHIFT 16 -# define R300_GB_TEX1_SOURCE_SHIFT 18 -# define R300_GB_TEX2_SOURCE_SHIFT 20 -# define R300_GB_TEX3_SOURCE_SHIFT 22 -# define R300_GB_TEX4_SOURCE_SHIFT 24 -# define R300_GB_TEX5_SOURCE_SHIFT 26 -# define R300_GB_TEX6_SOURCE_SHIFT 28 -# define R300_GB_TEX7_SOURCE_SHIFT 30 - -/* MSPOS - positions for multisample antialiasing (?) */ -#define R300_GB_MSPOS0 0x4010 - /* shifts - each of the fields is 4 bits */ -# define R300_GB_MSPOS0__MS_X0_SHIFT 0 -# define R300_GB_MSPOS0__MS_Y0_SHIFT 4 -# define R300_GB_MSPOS0__MS_X1_SHIFT 8 -# define R300_GB_MSPOS0__MS_Y1_SHIFT 12 -# define R300_GB_MSPOS0__MS_X2_SHIFT 16 -# define R300_GB_MSPOS0__MS_Y2_SHIFT 20 -# define R300_GB_MSPOS0__MSBD0_Y 24 -# define R300_GB_MSPOS0__MSBD0_X 28 - -#define R300_GB_MSPOS1 0x4014 -# define R300_GB_MSPOS1__MS_X3_SHIFT 0 -# define R300_GB_MSPOS1__MS_Y3_SHIFT 4 -# define R300_GB_MSPOS1__MS_X4_SHIFT 8 -# define R300_GB_MSPOS1__MS_Y4_SHIFT 12 -# define R300_GB_MSPOS1__MS_X5_SHIFT 16 -# define R300_GB_MSPOS1__MS_Y5_SHIFT 20 -# define R300_GB_MSPOS1__MSBD1 24 - - -#define R300_GB_TILE_CONFIG 0x4018 -# define R300_GB_TILE_ENABLE (1<<0) -# define R300_GB_TILE_PIPE_COUNT_RV300 0 -# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1) -# define R300_GB_TILE_PIPE_COUNT_R420 (7<<1) -# define R300_GB_TILE_PIPE_COUNT_RV410 (3<<1) -# define R300_GB_TILE_SIZE_8 0 -# define R300_GB_TILE_SIZE_16 (1<<4) -# define R300_GB_TILE_SIZE_32 (2<<4) -# define R300_GB_SUPER_SIZE_1 (0<<6) -# define R300_GB_SUPER_SIZE_2 (1<<6) -# define R300_GB_SUPER_SIZE_4 (2<<6) -# define R300_GB_SUPER_SIZE_8 (3<<6) -# define R300_GB_SUPER_SIZE_16 (4<<6) -# define R300_GB_SUPER_SIZE_32 (5<<6) -# define R300_GB_SUPER_SIZE_64 (6<<6) -# define R300_GB_SUPER_SIZE_128 (7<<6) -# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */ -# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */ -# define R300_GB_SUPER_TILE_A 0 -# define R300_GB_SUPER_TILE_B (1<<15) -# define R300_GB_SUBPIXEL_1_12 0 -# define R300_GB_SUBPIXEL_1_16 (1<<16) - -#define R300_GB_FIFO_SIZE 0x4024 - /* each of the following is 2 bits wide */ -#define R300_GB_FIFO_SIZE_32 0 -#define R300_GB_FIFO_SIZE_64 1 -#define R300_GB_FIFO_SIZE_128 2 -#define R300_GB_FIFO_SIZE_256 3 -# define R300_SC_IFIFO_SIZE_SHIFT 0 -# define R300_SC_TZFIFO_SIZE_SHIFT 2 -# define R300_SC_BFIFO_SIZE_SHIFT 4 - -# define R300_US_OFIFO_SIZE_SHIFT 12 -# define R300_US_WFIFO_SIZE_SHIFT 14 - /* the following use the same constants as above, but meaning is - is times 2 (i.e. instead of 32 words it means 64 */ -# define R300_RS_TFIFO_SIZE_SHIFT 6 -# define R300_RS_CFIFO_SIZE_SHIFT 8 -# define R300_US_RAM_SIZE_SHIFT 10 - /* watermarks, 3 bits wide */ -# define R300_RS_HIGHWATER_COL_SHIFT 16 -# define R300_RS_HIGHWATER_TEX_SHIFT 19 -# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */ -# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24 - -#define R300_GB_SELECT 0x401C -# define R300_GB_FOG_SELECT_C0A 0 -# define R300_GB_FOG_SELECT_C1A 1 -# define R300_GB_FOG_SELECT_C2A 2 -# define R300_GB_FOG_SELECT_C3A 3 -# define R300_GB_FOG_SELECT_1_1_W 4 -# define R300_GB_FOG_SELECT_Z 5 -# define R300_GB_DEPTH_SELECT_Z 0 -# define R300_GB_DEPTH_SELECT_1_1_W (1<<3) -# define R300_GB_W_SELECT_1_W 0 -# define R300_GB_W_SELECT_1 (1<<4) - -#define R300_GB_AA_CONFIG 0x4020 -# define R300_AA_DISABLE 0x00 -# define R300_AA_ENABLE 0x01 -# define R300_AA_SUBSAMPLES_2 0 -# define R300_AA_SUBSAMPLES_3 (1<<1) -# define R300_AA_SUBSAMPLES_4 (2<<1) -# define R300_AA_SUBSAMPLES_6 (3<<1) - -/* gap */ - -/* Zero to flush caches. */ -#define R300_TX_INVALTAGS 0x4100 -#define R300_TX_FLUSH 0x0 - -/* The upper enable bits are guessed, based on fglrx reported limits. */ -#define R300_TX_ENABLE 0x4104 -# define R300_TX_ENABLE_0 (1 << 0) -# define R300_TX_ENABLE_1 (1 << 1) -# define R300_TX_ENABLE_2 (1 << 2) -# define R300_TX_ENABLE_3 (1 << 3) -# define R300_TX_ENABLE_4 (1 << 4) -# define R300_TX_ENABLE_5 (1 << 5) -# define R300_TX_ENABLE_6 (1 << 6) -# define R300_TX_ENABLE_7 (1 << 7) -# define R300_TX_ENABLE_8 (1 << 8) -# define R300_TX_ENABLE_9 (1 << 9) -# define R300_TX_ENABLE_10 (1 << 10) -# define R300_TX_ENABLE_11 (1 << 11) -# define R300_TX_ENABLE_12 (1 << 12) -# define R300_TX_ENABLE_13 (1 << 13) -# define R300_TX_ENABLE_14 (1 << 14) -# define R300_TX_ENABLE_15 (1 << 15) - -/* The pointsize is given in multiples of 6. The pointsize can be - * enormous: Clear() renders a single point that fills the entire - * framebuffer. - */ -#define R300_RE_POINTSIZE 0x421C -# define R300_POINTSIZE_Y_SHIFT 0 -# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */ -# define R300_POINTSIZE_X_SHIFT 16 -# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */ -# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6) - -/* The line width is given in multiples of 6. - * In default mode lines are classified as vertical lines. - * HO: horizontal - * VE: vertical or horizontal - * HO & VE: no classification - */ -#define R300_RE_LINE_CNT 0x4234 -# define R300_LINESIZE_SHIFT 0 -# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */ -# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6) -# define R300_LINE_CNT_HO (1 << 16) -# define R300_LINE_CNT_VE (1 << 17) - -/* Some sort of scale or clamp value for texcoordless textures. */ -#define R300_RE_UNK4238 0x4238 - -/* Something shade related */ -#define R300_RE_SHADE 0x4274 - -#define R300_RE_SHADE_MODEL 0x4278 -# define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa -# define R300_RE_SHADE_MODEL_FLAT 0x39595 - -/* Dangerous */ -#define R300_RE_POLYGON_MODE 0x4288 -# define R300_PM_ENABLED (1 << 0) -# define R300_PM_FRONT_POINT (0 << 0) -# define R300_PM_BACK_POINT (0 << 0) -# define R300_PM_FRONT_LINE (1 << 4) -# define R300_PM_FRONT_FILL (1 << 5) -# define R300_PM_BACK_LINE (1 << 7) -# define R300_PM_BACK_FILL (1 << 8) - -/* Fog parameters */ -#define R300_RE_FOG_SCALE 0x4294 -#define R300_RE_FOG_START 0x4298 - -/* Not sure why there are duplicate of factor and constant values. - * My best guess so far is that there are separate zbiases for test and write. - * Ordering might be wrong. - * Some of the tests indicate that fgl has a fallback implementation of zbias - * via pixel shaders. - */ -#define R300_RE_ZBIAS_CNTL 0x42A0 /* GUESS */ -#define R300_RE_ZBIAS_T_FACTOR 0x42A4 -#define R300_RE_ZBIAS_T_CONSTANT 0x42A8 -#define R300_RE_ZBIAS_W_FACTOR 0x42AC -#define R300_RE_ZBIAS_W_CONSTANT 0x42B0 - -/* This register needs to be set to (1<<1) for RV350 to correctly - * perform depth test (see --vb-triangles in r300_demo) - * Don't know about other chips. - Vladimir - * This is set to 3 when GL_POLYGON_OFFSET_FILL is on. - * My guess is that there are two bits for each zbias primitive - * (FILL, LINE, POINT). - * One to enable depth test and one for depth write. - * Yet this doesn't explain why depth writes work ... - */ -#define R300_RE_OCCLUSION_CNTL 0x42B4 -# define R300_OCCLUSION_ON (1<<1) - -#define R300_RE_CULL_CNTL 0x42B8 -# define R300_CULL_FRONT (1 << 0) -# define R300_CULL_BACK (1 << 1) -# define R300_FRONT_FACE_CCW (0 << 2) -# define R300_FRONT_FACE_CW (1 << 2) - - -/* BEGIN: Rasterization / Interpolators - many guesses */ - -/* 0_UNKNOWN_18 has always been set except for clear operations. - * TC_CNT is the number of incoming texture coordinate sets (i.e. it depends - * on the vertex program, *not* the fragment program) - */ -#define R300_RS_CNTL_0 0x4300 -# define R300_RS_CNTL_TC_CNT_SHIFT 2 -# define R300_RS_CNTL_TC_CNT_MASK (7 << 2) - /* number of color interpolators used */ -# define R300_RS_CNTL_CI_CNT_SHIFT 7 -# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18) - /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n - register. */ -#define R300_RS_CNTL_1 0x4304 - -/* gap */ - -/* Only used for texture coordinates. - * Use the source field to route texture coordinate input from the - * vertex program to the desired interpolator. Note that the source - * field is relative to the outputs the vertex program *actually* - * writes. If a vertex program only writes texcoord[1], this will - * be source index 0. - * Set INTERP_USED on all interpolators that produce data used by - * the fragment program. INTERP_USED looks like a swizzling mask, - * but I haven't seen it used that way. - * - * Note: The _UNKNOWN constants are always set in their respective - * register. I don't know if this is necessary. - */ -#define R300_RS_INTERP_0 0x4310 -#define R300_RS_INTERP_1 0x4314 -# define R300_RS_INTERP_1_UNKNOWN 0x40 -#define R300_RS_INTERP_2 0x4318 -# define R300_RS_INTERP_2_UNKNOWN 0x80 -#define R300_RS_INTERP_3 0x431C -# define R300_RS_INTERP_3_UNKNOWN 0xC0 -#define R300_RS_INTERP_4 0x4320 -#define R300_RS_INTERP_5 0x4324 -#define R300_RS_INTERP_6 0x4328 -#define R300_RS_INTERP_7 0x432C -# define R300_RS_INTERP_SRC_SHIFT 2 -# define R300_RS_INTERP_SRC_MASK (7 << 2) -# define R300_RS_INTERP_USED 0x00D10000 - -/* These DWORDs control how vertex data is routed into fragment program - * registers, after interpolators. - */ -#define R300_RS_ROUTE_0 0x4330 -#define R300_RS_ROUTE_1 0x4334 -#define R300_RS_ROUTE_2 0x4338 -#define R300_RS_ROUTE_3 0x433C /* GUESS */ -#define R300_RS_ROUTE_4 0x4340 /* GUESS */ -#define R300_RS_ROUTE_5 0x4344 /* GUESS */ -#define R300_RS_ROUTE_6 0x4348 /* GUESS */ -#define R300_RS_ROUTE_7 0x434C /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_0 0 -# define R300_RS_ROUTE_SOURCE_INTERP_1 1 -# define R300_RS_ROUTE_SOURCE_INTERP_2 2 -# define R300_RS_ROUTE_SOURCE_INTERP_3 3 -# define R300_RS_ROUTE_SOURCE_INTERP_4 4 -# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ -# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ -# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ -# define R300_RS_ROUTE_DEST_SHIFT 6 -# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ - -/* Special handling for color: When the fragment program uses color, - * the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the - * color register index. - * - * Apperently you may set the R300_RS_ROUTE_0_COLOR bit, but not provide any - * R300_RS_ROUTE_0_COLOR_DEST value; this setup is used for clearing the state. - * See r300_ioctl.c:r300EmitClearState. I'm not sure if this setup is strictly - * correct or not. - Oliver. - */ -# define R300_RS_ROUTE_0_COLOR (1 << 14) -# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17 -# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ -/* As above, but for secondary color */ -# define R300_RS_ROUTE_1_COLOR1 (1 << 14) -# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 -# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17) -# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11) -/* END: Rasterization / Interpolators - many guesses */ - -/* Hierarchical Z Enable */ -#define R300_SC_HYPERZ 0x43a4 -# define R300_SC_HYPERZ_DISABLE (0 << 0) -# define R300_SC_HYPERZ_ENABLE (1 << 0) -# define R300_SC_HYPERZ_MIN (0 << 1) -# define R300_SC_HYPERZ_MAX (1 << 1) -# define R300_SC_HYPERZ_ADJ_256 (0 << 2) -# define R300_SC_HYPERZ_ADJ_128 (1 << 2) -# define R300_SC_HYPERZ_ADJ_64 (2 << 2) -# define R300_SC_HYPERZ_ADJ_32 (3 << 2) -# define R300_SC_HYPERZ_ADJ_16 (4 << 2) -# define R300_SC_HYPERZ_ADJ_8 (5 << 2) -# define R300_SC_HYPERZ_ADJ_4 (6 << 2) -# define R300_SC_HYPERZ_ADJ_2 (7 << 2) -# define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5) -# define R300_SC_HYPERZ_HZ_Z0MIN (1 << 5) -# define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6) -# define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6) - -#define R300_SC_EDGERULE 0x43a8 - -/* BEGIN: Scissors and cliprects */ - -/* There are four clipping rectangles. Their corner coordinates are inclusive. - * Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending - * on whether the pixel is inside cliprects 0-3, respectively. For example, - * if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned - * the number 3 (binary 0011). - * Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set, - * the pixel is rasterized. - * - * In addition to this, there is a scissors rectangle. Only pixels inside the - * scissors rectangle are drawn. (coordinates are inclusive) - * - * For some reason, the top-left corner of the framebuffer is at (1440, 1440) - * for the purpose of clipping and scissors. - */ -#define R300_RE_CLIPRECT_TL_0 0x43B0 -#define R300_RE_CLIPRECT_BR_0 0x43B4 -#define R300_RE_CLIPRECT_TL_1 0x43B8 -#define R300_RE_CLIPRECT_BR_1 0x43BC -#define R300_RE_CLIPRECT_TL_2 0x43C0 -#define R300_RE_CLIPRECT_BR_2 0x43C4 -#define R300_RE_CLIPRECT_TL_3 0x43C8 -#define R300_RE_CLIPRECT_BR_3 0x43CC -# define R300_CLIPRECT_OFFSET 1440 -# define R300_CLIPRECT_MASK 0x1FFF -# define R300_CLIPRECT_X_SHIFT 0 -# define R300_CLIPRECT_X_MASK (0x1FFF << 0) -# define R300_CLIPRECT_Y_SHIFT 13 -# define R300_CLIPRECT_Y_MASK (0x1FFF << 13) -#define R300_RE_CLIPRECT_CNTL 0x43D0 -# define R300_CLIP_OUT (1 << 0) -# define R300_CLIP_0 (1 << 1) -# define R300_CLIP_1 (1 << 2) -# define R300_CLIP_10 (1 << 3) -# define R300_CLIP_2 (1 << 4) -# define R300_CLIP_20 (1 << 5) -# define R300_CLIP_21 (1 << 6) -# define R300_CLIP_210 (1 << 7) -# define R300_CLIP_3 (1 << 8) -# define R300_CLIP_30 (1 << 9) -# define R300_CLIP_31 (1 << 10) -# define R300_CLIP_310 (1 << 11) -# define R300_CLIP_32 (1 << 12) -# define R300_CLIP_320 (1 << 13) -# define R300_CLIP_321 (1 << 14) -# define R300_CLIP_3210 (1 << 15) - -/* gap */ - -#define R300_RE_SCISSORS_TL 0x43E0 -#define R300_RE_SCISSORS_BR 0x43E4 -# define R300_SCISSORS_OFFSET 1440 -# define R300_SCISSORS_X_SHIFT 0 -# define R300_SCISSORS_X_MASK (0x1FFF << 0) -# define R300_SCISSORS_Y_SHIFT 13 -# define R300_SCISSORS_Y_MASK (0x1FFF << 13) -/* END: Scissors and cliprects */ - -/* BEGIN: Texture specification */ - -/* - * The texture specification dwords are grouped by meaning and not by texture - * unit. This means that e.g. the offset for texture image unit N is found in - * register TX_OFFSET_0 + (4*N) - */ -#define R300_TX_FILTER_0 0x4400 -# define R300_TX_REPEAT 0 -# define R300_TX_MIRRORED 1 -# define R300_TX_CLAMP 4 -# define R300_TX_CLAMP_TO_EDGE 2 -# define R300_TX_CLAMP_TO_BORDER 6 -# define R300_TX_WRAP_S_SHIFT 0 -# define R300_TX_WRAP_S_MASK (7 << 0) -# define R300_TX_WRAP_T_SHIFT 3 -# define R300_TX_WRAP_T_MASK (7 << 3) -# define R300_TX_WRAP_Q_SHIFT 6 -# define R300_TX_WRAP_Q_MASK (7 << 6) -# define R300_TX_MAG_FILTER_NEAREST (1 << 9) -# define R300_TX_MAG_FILTER_LINEAR (2 << 9) -# define R300_TX_MAG_FILTER_MASK (3 << 9) -# define R300_TX_MIN_FILTER_NEAREST (1 << 11) -# define R300_TX_MIN_FILTER_LINEAR (2 << 11) -# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11) -# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11) -# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) -# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) - -/* NOTE: NEAREST doesn't seem to exist. - * Im not seting MAG_FILTER_MASK and (3 << 11) on for all - * anisotropy modes because that would void selected mag filter - */ -# define R300_TX_MIN_FILTER_ANISO_NEAREST (0 << 13) -# define R300_TX_MIN_FILTER_ANISO_LINEAR (0 << 13) -# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (1 << 13) -# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (2 << 13) -# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) ) -# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21) -# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21) -# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21) -# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21) -# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) -# define R300_TX_MAX_ANISO_MASK (14 << 21) - -#define R300_TX_FILTER1_0 0x4440 -# define R300_CHROMA_KEY_MODE_DISABLE 0 -# define R300_CHROMA_KEY_FORCE 1 -# define R300_CHROMA_KEY_BLEND 2 -# define R300_MC_ROUND_NORMAL (0<<2) -# define R300_MC_ROUND_MPEG4 (1<<2) -# define R300_LOD_BIAS_MASK 0x1fff -# define R300_EDGE_ANISO_EDGE_DIAG (0<<13) -# define R300_EDGE_ANISO_EDGE_ONLY (1<<13) -# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) -# define R300_MC_COORD_TRUNCATE_MPEG (1<<14) -# define R300_TX_TRI_PERF_0_8 (0<<15) -# define R300_TX_TRI_PERF_1_8 (1<<15) -# define R300_TX_TRI_PERF_1_4 (2<<15) -# define R300_TX_TRI_PERF_3_8 (3<<15) -# define R300_ANISO_THRESHOLD_MASK (7<<17) - -#define R300_TX_SIZE_0 0x4480 -# define R300_TX_WIDTHMASK_SHIFT 0 -# define R300_TX_WIDTHMASK_MASK (2047 << 0) -# define R300_TX_HEIGHTMASK_SHIFT 11 -# define R300_TX_HEIGHTMASK_MASK (2047 << 11) -# define R300_TX_UNK23 (1 << 23) -# define R300_TX_MAX_MIP_LEVEL_SHIFT 26 -# define R300_TX_MAX_MIP_LEVEL_MASK (0xf << 26) -# define R300_TX_SIZE_PROJECTED (1<<30) -# define R300_TX_SIZE_TXPITCH_EN (1<<31) -#define R300_TX_FORMAT_0 0x44C0 - /* The interpretation of the format word by Wladimir van der Laan */ - /* The X, Y, Z and W refer to the layout of the components. - They are given meanings as R, G, B and Alpha by the swizzle - specification */ -# define R300_TX_FORMAT_X8 0x0 -# define R300_TX_FORMAT_X16 0x1 -# define R300_TX_FORMAT_Y4X4 0x2 -# define R300_TX_FORMAT_Y8X8 0x3 -# define R300_TX_FORMAT_Y16X16 0x4 -# define R300_TX_FORMAT_Z3Y3X2 0x5 -# define R300_TX_FORMAT_Z5Y6X5 0x6 -# define R300_TX_FORMAT_Z6Y5X5 0x7 -# define R300_TX_FORMAT_Z11Y11X10 0x8 -# define R300_TX_FORMAT_Z10Y11X11 0x9 -# define R300_TX_FORMAT_W4Z4Y4X4 0xA -# define R300_TX_FORMAT_W1Z5Y5X5 0xB -# define R300_TX_FORMAT_W8Z8Y8X8 0xC -# define R300_TX_FORMAT_W2Z10Y10X10 0xD -# define R300_TX_FORMAT_W16Z16Y16X16 0xE -# define R300_TX_FORMAT_DXT1 0xF -# define R300_TX_FORMAT_DXT3 0x10 -# define R300_TX_FORMAT_DXT5 0x11 -# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ -# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ -# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ -# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ - /* 0x16 - some 16 bit green format.. ?? */ -# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ -# define R300_TX_FORMAT_CUBIC_MAP (1 << 26) - - /* gap */ - /* Floating point formats */ - /* Note - hardware supports both 16 and 32 bit floating point */ -# define R300_TX_FORMAT_FL_I16 0x18 -# define R300_TX_FORMAT_FL_I16A16 0x19 -# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A -# define R300_TX_FORMAT_FL_I32 0x1B -# define R300_TX_FORMAT_FL_I32A32 0x1C -# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D -# define R300_TX_FORMAT_ATI2N 0x1F - /* alpha modes, convenience mostly */ - /* if you have alpha, pick constant appropriate to the - number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ -# define R300_TX_FORMAT_ALPHA_1CH 0x000 -# define R300_TX_FORMAT_ALPHA_2CH 0x200 -# define R300_TX_FORMAT_ALPHA_4CH 0x600 -# define R300_TX_FORMAT_ALPHA_NONE 0xA00 - /* Swizzling */ - /* constants */ -# define R300_TX_FORMAT_X 0 -# define R300_TX_FORMAT_Y 1 -# define R300_TX_FORMAT_Z 2 -# define R300_TX_FORMAT_W 3 -# define R300_TX_FORMAT_ZERO 4 -# define R300_TX_FORMAT_ONE 5 - /* 2.0*Z, everything above 1.0 is set to 0.0 */ -# define R300_TX_FORMAT_CUT_Z 6 - /* 2.0*W, everything above 1.0 is set to 0.0 */ -# define R300_TX_FORMAT_CUT_W 7 - -# define R300_TX_FORMAT_B_SHIFT 18 -# define R300_TX_FORMAT_G_SHIFT 15 -# define R300_TX_FORMAT_R_SHIFT 12 -# define R300_TX_FORMAT_A_SHIFT 9 - /* Convenience macro to take care of layout and swizzling */ -# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) ( \ - ((R300_TX_FORMAT_##B)< 0.5, return ARG0, else return ARG1 - * - CMP: If ARG2 < 0, return ARG1, else return ARG0 - * - FLR: use FRC+MAD - * - XPD: use MAD+MAD - * - SGE, SLT: use MAD+CMP - * - RSQ: use ABS modifier for argument - * - Use OUTC_REPL_ALPHA to write results of an alpha-only operation - * (e.g. RCP) into color register - * - apparently, there's no quick DST operation - * - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2" - * - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0" - * - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1" - * - * Operand selection - * First stage selects three sources from the available registers and - * constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha). - * fglrx sorts the three source fields: Registers before constants, - * lower indices before higher indices; I do not know whether this is - * necessary. - * - * fglrx fills unused sources with "read constant 0" - * According to specs, you cannot select more than two different constants. - * - * Second stage selects the operands from the sources. This is defined in - * INSTR0 (color) and INSTR2 (alpha). You can also select the special constants - * zero and one. - * Swizzling and negation happens in this stage, as well. - * - * Important: Color and alpha seem to be mostly separate, i.e. their sources - * selection appears to be fully independent (the register storage is probably - * physically split into a color and an alpha section). - * However (because of the apparent physical split), there is some interaction - * WRT swizzling. If, for example, you want to load an R component into an - * Alpha operand, this R component is taken from a *color* source, not from - * an alpha source. The corresponding register doesn't even have to appear in - * the alpha sources list. (I hope this all makes sense to you) - * - * Destination selection - * The destination register index is in FPI1 (color) and FPI3 (alpha) - * together with enable bits. - * There are separate enable bits for writing into temporary registers - * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* - * /DSTA_OUTPUT). You can write to both at once, or not write at all (the - * same index must be used for both). - * - * Note: There is a special form for LRP - * - Argument order is the same as in ARB_fragment_program. - * - Operation is MAD - * - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP - * - Set FPI0/FPI2_SPECIAL_LRP - * Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD - */ -#define R300_PFS_INSTR1_0 0x46C0 -# define R300_FPI1_SRC0C_SHIFT 0 -# define R300_FPI1_SRC0C_MASK (31 << 0) -# define R300_FPI1_SRC0C_CONST (1 << 5) -# define R300_FPI1_SRC1C_SHIFT 6 -# define R300_FPI1_SRC1C_MASK (31 << 6) -# define R300_FPI1_SRC1C_CONST (1 << 11) -# define R300_FPI1_SRC2C_SHIFT 12 -# define R300_FPI1_SRC2C_MASK (31 << 12) -# define R300_FPI1_SRC2C_CONST (1 << 17) -# define R300_FPI1_SRC_MASK 0x0003ffff -# define R300_FPI1_DSTC_SHIFT 18 -# define R300_FPI1_DSTC_MASK (31 << 18) -# define R300_FPI1_DSTC_REG_MASK_SHIFT 23 -# define R300_FPI1_DSTC_REG_X (1 << 23) -# define R300_FPI1_DSTC_REG_Y (1 << 24) -# define R300_FPI1_DSTC_REG_Z (1 << 25) -# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26 -# define R300_FPI1_DSTC_OUTPUT_X (1 << 26) -# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) -# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) - -#define R300_PFS_INSTR3_0 0x47C0 -# define R300_FPI3_SRC0A_SHIFT 0 -# define R300_FPI3_SRC0A_MASK (31 << 0) -# define R300_FPI3_SRC0A_CONST (1 << 5) -# define R300_FPI3_SRC1A_SHIFT 6 -# define R300_FPI3_SRC1A_MASK (31 << 6) -# define R300_FPI3_SRC1A_CONST (1 << 11) -# define R300_FPI3_SRC2A_SHIFT 12 -# define R300_FPI3_SRC2A_MASK (31 << 12) -# define R300_FPI3_SRC2A_CONST (1 << 17) -# define R300_FPI3_SRC_MASK 0x0003ffff -# define R300_FPI3_DSTA_SHIFT 18 -# define R300_FPI3_DSTA_MASK (31 << 18) -# define R300_FPI3_DSTA_REG (1 << 23) -# define R300_FPI3_DSTA_OUTPUT (1 << 24) -# define R300_FPI3_DSTA_DEPTH (1 << 27) - -#define R300_PFS_INSTR0_0 0x48C0 -# define R300_FPI0_ARGC_SRC0C_XYZ 0 -# define R300_FPI0_ARGC_SRC0C_XXX 1 -# define R300_FPI0_ARGC_SRC0C_YYY 2 -# define R300_FPI0_ARGC_SRC0C_ZZZ 3 -# define R300_FPI0_ARGC_SRC1C_XYZ 4 -# define R300_FPI0_ARGC_SRC1C_XXX 5 -# define R300_FPI0_ARGC_SRC1C_YYY 6 -# define R300_FPI0_ARGC_SRC1C_ZZZ 7 -# define R300_FPI0_ARGC_SRC2C_XYZ 8 -# define R300_FPI0_ARGC_SRC2C_XXX 9 -# define R300_FPI0_ARGC_SRC2C_YYY 10 -# define R300_FPI0_ARGC_SRC2C_ZZZ 11 -# define R300_FPI0_ARGC_SRC0A 12 -# define R300_FPI0_ARGC_SRC1A 13 -# define R300_FPI0_ARGC_SRC2A 14 -# define R300_FPI0_ARGC_SRC1C_LRP 15 -# define R300_FPI0_ARGC_ZERO 20 -# define R300_FPI0_ARGC_ONE 21 - /* GUESS */ -# define R300_FPI0_ARGC_HALF 22 -# define R300_FPI0_ARGC_SRC0C_YZX 23 -# define R300_FPI0_ARGC_SRC1C_YZX 24 -# define R300_FPI0_ARGC_SRC2C_YZX 25 -# define R300_FPI0_ARGC_SRC0C_ZXY 26 -# define R300_FPI0_ARGC_SRC1C_ZXY 27 -# define R300_FPI0_ARGC_SRC2C_ZXY 28 -# define R300_FPI0_ARGC_SRC0CA_WZY 29 -# define R300_FPI0_ARGC_SRC1CA_WZY 30 -# define R300_FPI0_ARGC_SRC2CA_WZY 31 - -# define R300_FPI0_ARG0C_SHIFT 0 -# define R300_FPI0_ARG0C_MASK (31 << 0) -# define R300_FPI0_ARG0C_NEG (1 << 5) -# define R300_FPI0_ARG0C_ABS (1 << 6) -# define R300_FPI0_ARG1C_SHIFT 7 -# define R300_FPI0_ARG1C_MASK (31 << 7) -# define R300_FPI0_ARG1C_NEG (1 << 12) -# define R300_FPI0_ARG1C_ABS (1 << 13) -# define R300_FPI0_ARG2C_SHIFT 14 -# define R300_FPI0_ARG2C_MASK (31 << 14) -# define R300_FPI0_ARG2C_NEG (1 << 19) -# define R300_FPI0_ARG2C_ABS (1 << 20) -# define R300_FPI0_SPECIAL_LRP (1 << 21) -# define R300_FPI0_OUTC_MAD (0 << 23) -# define R300_FPI0_OUTC_DP3 (1 << 23) -# define R300_FPI0_OUTC_DP4 (2 << 23) -# define R300_FPI0_OUTC_MIN (4 << 23) -# define R300_FPI0_OUTC_MAX (5 << 23) -# define R300_FPI0_OUTC_CMPH (7 << 23) -# define R300_FPI0_OUTC_CMP (8 << 23) -# define R300_FPI0_OUTC_FRC (9 << 23) -# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) -# define R300_FPI0_OUTC_SAT (1 << 30) -# define R300_FPI0_INSERT_NOP (1 << 31) - -#define R300_PFS_INSTR2_0 0x49C0 -# define R300_FPI2_ARGA_SRC0C_X 0 -# define R300_FPI2_ARGA_SRC0C_Y 1 -# define R300_FPI2_ARGA_SRC0C_Z 2 -# define R300_FPI2_ARGA_SRC1C_X 3 -# define R300_FPI2_ARGA_SRC1C_Y 4 -# define R300_FPI2_ARGA_SRC1C_Z 5 -# define R300_FPI2_ARGA_SRC2C_X 6 -# define R300_FPI2_ARGA_SRC2C_Y 7 -# define R300_FPI2_ARGA_SRC2C_Z 8 -# define R300_FPI2_ARGA_SRC0A 9 -# define R300_FPI2_ARGA_SRC1A 10 -# define R300_FPI2_ARGA_SRC2A 11 -# define R300_FPI2_ARGA_SRC1A_LRP 15 -# define R300_FPI2_ARGA_ZERO 16 -# define R300_FPI2_ARGA_ONE 17 - /* GUESS */ -# define R300_FPI2_ARGA_HALF 18 -# define R300_FPI2_ARG0A_SHIFT 0 -# define R300_FPI2_ARG0A_MASK (31 << 0) -# define R300_FPI2_ARG0A_NEG (1 << 5) - /* GUESS */ -# define R300_FPI2_ARG0A_ABS (1 << 6) -# define R300_FPI2_ARG1A_SHIFT 7 -# define R300_FPI2_ARG1A_MASK (31 << 7) -# define R300_FPI2_ARG1A_NEG (1 << 12) - /* GUESS */ -# define R300_FPI2_ARG1A_ABS (1 << 13) -# define R300_FPI2_ARG2A_SHIFT 14 -# define R300_FPI2_ARG2A_MASK (31 << 14) -# define R300_FPI2_ARG2A_NEG (1 << 19) - /* GUESS */ -# define R300_FPI2_ARG2A_ABS (1 << 20) -# define R300_FPI2_SPECIAL_LRP (1 << 21) -# define R300_FPI2_OUTA_MAD (0 << 23) -# define R300_FPI2_OUTA_DP4 (1 << 23) -# define R300_FPI2_OUTA_MIN (2 << 23) -# define R300_FPI2_OUTA_MAX (3 << 23) -# define R300_FPI2_OUTA_CMP (6 << 23) -# define R300_FPI2_OUTA_FRC (7 << 23) -# define R300_FPI2_OUTA_EX2 (8 << 23) -# define R300_FPI2_OUTA_LG2 (9 << 23) -# define R300_FPI2_OUTA_RCP (10 << 23) -# define R300_FPI2_OUTA_RSQ (11 << 23) -# define R300_FPI2_OUTA_SAT (1 << 30) -# define R300_FPI2_UNKNOWN_31 (1 << 31) -/* END: Fragment program instruction set */ - -/* Fog state and color */ -#define R300_RE_FOG_STATE 0x4BC0 -# define R300_FOG_ENABLE (1 << 0) -# define R300_FOG_MODE_LINEAR (0 << 1) -# define R300_FOG_MODE_EXP (1 << 1) -# define R300_FOG_MODE_EXP2 (2 << 1) -# define R300_FOG_MODE_MASK (3 << 1) -#define R300_FOG_COLOR_R 0x4BC8 -#define R300_FOG_COLOR_G 0x4BCC -#define R300_FOG_COLOR_B 0x4BD0 - -#define R300_PP_ALPHA_TEST 0x4BD4 -# define R300_REF_ALPHA_MASK 0x000000ff -# define R300_ALPHA_TEST_FAIL (0 << 8) -# define R300_ALPHA_TEST_LESS (1 << 8) -# define R300_ALPHA_TEST_LEQUAL (3 << 8) -# define R300_ALPHA_TEST_EQUAL (2 << 8) -# define R300_ALPHA_TEST_GEQUAL (6 << 8) -# define R300_ALPHA_TEST_GREATER (4 << 8) -# define R300_ALPHA_TEST_NEQUAL (5 << 8) -# define R300_ALPHA_TEST_PASS (7 << 8) -# define R300_ALPHA_TEST_OP_MASK (7 << 8) -# define R300_ALPHA_TEST_ENABLE (1 << 11) - -/* gap */ - -/* Fragment program parameters in 7.16 floating point */ -#define R300_PFS_PARAM_0_X 0x4C00 -#define R300_PFS_PARAM_0_Y 0x4C04 -#define R300_PFS_PARAM_0_Z 0x4C08 -#define R300_PFS_PARAM_0_W 0x4C0C -/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */ -#define R300_PFS_PARAM_31_X 0x4DF0 -#define R300_PFS_PARAM_31_Y 0x4DF4 -#define R300_PFS_PARAM_31_Z 0x4DF8 -#define R300_PFS_PARAM_31_W 0x4DFC - -/* Notes: - * - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in - * the application - * - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND - * are set to the same - * function (both registers are always set up completely in any case) - * - Most blend flags are simply copied from R200 and not tested yet - */ -#define R300_RB3D_CBLEND 0x4E04 -#define R300_RB3D_ABLEND 0x4E08 -/* the following only appear in CBLEND */ -# define R300_BLEND_ENABLE (1 << 0) -# define R300_BLEND_UNKNOWN (3 << 1) -# define R300_BLEND_NO_SEPARATE (1 << 3) -/* the following are shared between CBLEND and ABLEND */ -# define R300_FCN_MASK (3 << 12) -# define R300_COMB_FCN_ADD_CLAMP (0 << 12) -# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12) -# define R300_COMB_FCN_SUB_CLAMP (2 << 12) -# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12) -# define R300_COMB_FCN_MIN (4 << 12) -# define R300_COMB_FCN_MAX (5 << 12) -# define R300_COMB_FCN_RSUB_CLAMP (6 << 12) -# define R300_COMB_FCN_RSUB_NOCLAMP (7 << 12) -# define R300_BLEND_GL_ZERO (32) -# define R300_BLEND_GL_ONE (33) -# define R300_BLEND_GL_SRC_COLOR (34) -# define R300_BLEND_GL_ONE_MINUS_SRC_COLOR (35) -# define R300_BLEND_GL_DST_COLOR (36) -# define R300_BLEND_GL_ONE_MINUS_DST_COLOR (37) -# define R300_BLEND_GL_SRC_ALPHA (38) -# define R300_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) -# define R300_BLEND_GL_DST_ALPHA (40) -# define R300_BLEND_GL_ONE_MINUS_DST_ALPHA (41) -# define R300_BLEND_GL_SRC_ALPHA_SATURATE (42) -# define R300_BLEND_GL_CONST_COLOR (43) -# define R300_BLEND_GL_ONE_MINUS_CONST_COLOR (44) -# define R300_BLEND_GL_CONST_ALPHA (45) -# define R300_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) -# define R300_BLEND_MASK (63) -# define R300_SRC_BLEND_SHIFT (16) -# define R300_DST_BLEND_SHIFT (24) -#define R300_RB3D_BLEND_COLOR 0x4E10 -#define R300_RB3D_COLORMASK 0x4E0C -# define R300_COLORMASK0_B (1<<0) -# define R300_COLORMASK0_G (1<<1) -# define R300_COLORMASK0_R (1<<2) -# define R300_COLORMASK0_A (1<<3) - -/* gap */ - -#define R300_RB3D_COLOROFFSET0 0x4E28 -# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ -#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ -#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ -#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */ - -/* gap */ - -/* Bit 16: Larger tiles - * Bit 17: 4x2 tiles - * Bit 18: Extremely weird tile like, but some pixels duplicated? - */ -#define R300_RB3D_COLORPITCH0 0x4E38 -# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ -# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ -# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ -# define R300_COLOR_MICROTILE_SQUARE_ENABLE (2 << 17) -# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ -# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ -# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ -# define R300_COLOR_FORMAT_RGB565 (2 << 22) -# define R300_COLOR_FORMAT_ARGB8888 (3 << 22) -#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */ -#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ -#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ - -#define R300_RB3D_AARESOLVE_OFFSET 0x4E80 -#define R300_RB3D_AARESOLVE_PITCH 0x4E84 -#define R300_RB3D_AARESOLVE_CTL 0x4E88 -/* gap */ - -/* Guess by Vladimir. - * Set to 0A before 3D operations, set to 02 afterwards. - */ -/*#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C*/ -# define R300_RB3D_DSTCACHE_UNKNOWN_02 0x00000002 -# define R300_RB3D_DSTCACHE_UNKNOWN_0A 0x0000000A - -/* gap */ -/* There seems to be no "write only" setting, so use Z-test = ALWAYS - * for this. - * Bit (1<<8) is the "test" bit. so plain write is 6 - vd - */ -#define R300_ZB_CNTL 0x4F00 -# define R300_STENCIL_ENABLE (1 << 0) -# define R300_Z_ENABLE (1 << 1) -# define R300_Z_WRITE_ENABLE (1 << 2) -# define R300_Z_SIGNED_COMPARE (1 << 3) -# define R300_STENCIL_FRONT_BACK (1 << 4) - -#define R300_ZB_ZSTENCILCNTL 0x4f04 - /* functions */ -# define R300_ZS_NEVER 0 -# define R300_ZS_LESS 1 -# define R300_ZS_LEQUAL 2 -# define R300_ZS_EQUAL 3 -# define R300_ZS_GEQUAL 4 -# define R300_ZS_GREATER 5 -# define R300_ZS_NOTEQUAL 6 -# define R300_ZS_ALWAYS 7 -# define R300_ZS_MASK 7 - /* operations */ -# define R300_ZS_KEEP 0 -# define R300_ZS_ZERO 1 -# define R300_ZS_REPLACE 2 -# define R300_ZS_INCR 3 -# define R300_ZS_DECR 4 -# define R300_ZS_INVERT 5 -# define R300_ZS_INCR_WRAP 6 -# define R300_ZS_DECR_WRAP 7 -# define R300_Z_FUNC_SHIFT 0 - /* front and back refer to operations done for front - and back faces, i.e. separate stencil function support */ -# define R300_S_FRONT_FUNC_SHIFT 3 -# define R300_S_FRONT_SFAIL_OP_SHIFT 6 -# define R300_S_FRONT_ZPASS_OP_SHIFT 9 -# define R300_S_FRONT_ZFAIL_OP_SHIFT 12 -# define R300_S_BACK_FUNC_SHIFT 15 -# define R300_S_BACK_SFAIL_OP_SHIFT 18 -# define R300_S_BACK_ZPASS_OP_SHIFT 21 -# define R300_S_BACK_ZFAIL_OP_SHIFT 24 - -#define R300_ZB_STENCILREFMASK 0x4f08 -# define R300_STENCILREF_SHIFT 0 -# define R300_STENCILREF_MASK 0x000000ff -# define R300_STENCILMASK_SHIFT 8 -# define R300_STENCILMASK_MASK 0x0000ff00 -# define R300_STENCILWRITEMASK_SHIFT 16 -# define R300_STENCILWRITEMASK_MASK 0x00ff0000 - -/* gap */ - -#define R300_ZB_FORMAT 0x4f10 -# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0) -# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0) -# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0) -/* reserved up to (15 << 0) */ -# define R300_INVERT_13E3_LEADING_ONES (0 << 4) -# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4) - -#define R300_ZB_ZTOP 0x4F14 -# define R300_ZTOP_DISABLE (0 << 0) -# define R300_ZTOP_ENABLE (1 << 0) - -/* gap */ - -#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) -# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) - -#define R300_ZB_BW_CNTL 0x4f1c -# define R300_HIZ_DISABLE (0 << 0) -# define R300_HIZ_ENABLE (1 << 0) -# define R300_HIZ_MIN (0 << 1) -# define R300_HIZ_MAX (1 << 1) -# define R300_FAST_FILL_DISABLE (0 << 2) -# define R300_FAST_FILL_ENABLE (1 << 2) -# define R300_RD_COMP_DISABLE (0 << 3) -# define R300_RD_COMP_ENABLE (1 << 3) -# define R300_WR_COMP_DISABLE (0 << 4) -# define R300_WR_COMP_ENABLE (1 << 4) -# define R300_ZB_CB_CLEAR_RMW (0 << 5) -# define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5) -# define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6) -# define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6) - -# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7) -# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7) -# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8) -# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8) - -# define R500_BMASK_ENABLE (0 << 10) -# define R500_BMASK_DISABLE (1 << 10) -# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11) -# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11) -# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12) -# define R500_HIZ_FP_EXP_BITS_1 (1 << 12) -# define R500_HIZ_FP_EXP_BITS_2 (2 << 12) -# define R500_HIZ_FP_EXP_BITS_3 (3 << 12) -# define R500_HIZ_FP_EXP_BITS_4 (4 << 12) -# define R500_HIZ_FP_EXP_BITS_5 (5 << 12) -# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15) -# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15) -# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16) -# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16) -# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17) -# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17) -# define R500_PEQ_PACKING_DISABLE (0 << 18) -# define R500_PEQ_PACKING_ENABLE (1 << 18) -# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18) -# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18) - - -/* gap */ - -/* Z Buffer Address Offset. - * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles. - */ -#define R300_ZB_DEPTHOFFSET 0x4f20 - -/* Z Buffer Pitch and Endian Control */ -#define R300_ZB_DEPTHPITCH 0x4f24 -# define R300_DEPTHPITCH_MASK 0x00003FFC -# define R300_DEPTHMACROTILE_DISABLE (0 << 16) -# define R300_DEPTHMACROTILE_ENABLE (1 << 16) -# define R300_DEPTHMICROTILE_LINEAR (0 << 17) -# define R300_DEPTHMICROTILE_TILED (1 << 17) -# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17) -# define R300_DEPTHENDIAN_NO_SWAP (0 << 18) -# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18) -# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18) -# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18) - -/* Z Buffer Clear Value */ -#define R300_ZB_DEPTHCLEARVALUE 0x4f28 - -#define R300_ZB_ZMASK_OFFSET 0x4f30 -#define R300_ZB_ZMASK_PITCH 0x4f34 -#define R300_ZB_ZMASK_WRINDEX 0x4f38 -#define R300_ZB_ZMASK_DWORD 0x4f3c -#define R300_ZB_ZMASK_RDINDEX 0x4f40 - -/* Hierarchical Z Memory Offset */ -#define R300_ZB_HIZ_OFFSET 0x4f44 - -/* Hierarchical Z Write Index */ -#define R300_ZB_HIZ_WRINDEX 0x4f48 - -/* Hierarchical Z Data */ -#define R300_ZB_HIZ_DWORD 0x4f4c - -/* Hierarchical Z Read Index */ -#define R300_ZB_HIZ_RDINDEX 0x4f50 - -/* Hierarchical Z Pitch */ -#define R300_ZB_HIZ_PITCH 0x4f54 - -/* Z Buffer Z Pass Counter Data */ -#define R300_ZB_ZPASS_DATA 0x4f58 - -/* Z Buffer Z Pass Counter Address */ -#define R300_ZB_ZPASS_ADDR 0x4f5c - -/* Depth buffer X and Y coordinate offset */ -#define R300_ZB_DEPTHXY_OFFSET 0x4f60 -# define R300_DEPTHX_OFFSET_SHIFT 1 -# define R300_DEPTHX_OFFSET_MASK 0x000007FE -# define R300_DEPTHY_OFFSET_SHIFT 17 -# define R300_DEPTHY_OFFSET_MASK 0x07FE0000 - -/* Sets the fifo sizes */ -#define R500_ZB_FIFO_SIZE 0x4fd0 -# define R500_OP_FIFO_SIZE_FULL (0 << 0) -# define R500_OP_FIFO_SIZE_HALF (1 << 0) -# define R500_OP_FIFO_SIZE_QUATER (2 << 0) -# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0) - -/* Stencil Reference Value and Mask for backfacing quads */ -/* R300_ZB_STENCILREFMASK handles front face */ -#define R500_ZB_STENCILREFMASK_BF 0x4fd4 -# define R500_STENCILREF_SHIFT 0 -# define R500_STENCILREF_MASK 0x000000ff -# define R500_STENCILMASK_SHIFT 8 -# define R500_STENCILMASK_MASK 0x0000ff00 -# define R500_STENCILWRITEMASK_SHIFT 16 -# define R500_STENCILWRITEMASK_MASK 0x00ff0000 - -/* BEGIN: Vertex program instruction set */ - -/* Every instruction is four dwords long: - * DWORD 0: output and opcode - * DWORD 1: first argument - * DWORD 2: second argument - * DWORD 3: third argument - * - * Notes: - * - ABS r, a is implemented as MAX r, a, -a - * - MOV is implemented as ADD to zero - * - XPD is implemented as MUL + MAD - * - FLR is implemented as FRC + ADD - * - apparently, fglrx tries to schedule instructions so that there is at - * least one instruction between the write to a temporary and the first - * read from said temporary; however, violations of this scheduling are - * allowed - * - register indices seem to be unrelated with OpenGL aliasing to - * conventional state - * - only one attribute and one parameter can be loaded at a time; however, - * the same attribute/parameter can be used for more than one argument - * - the second software argument for POW is the third hardware argument - * (no idea why) - * - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2 - * - * There is some magic surrounding LIT: - * The single argument is replicated across all three inputs, but swizzled: - * First argument: xyzy - * Second argument: xyzx - * Third argument: xyzw - * Whenever the result is used later in the fragment program, fglrx forces - * x and w to be 1.0 in the input selection; I don't know whether this is - * strictly necessary - */ -#define R300_VPI_OUT_OP_DOT (1 << 0) -#define R300_VPI_OUT_OP_MUL (2 << 0) -#define R300_VPI_OUT_OP_ADD (3 << 0) -#define R300_VPI_OUT_OP_MAD (4 << 0) -#define R300_VPI_OUT_OP_DST (5 << 0) -#define R300_VPI_OUT_OP_FRC (6 << 0) -#define R300_VPI_OUT_OP_MAX (7 << 0) -#define R300_VPI_OUT_OP_MIN (8 << 0) -#define R300_VPI_OUT_OP_SGE (9 << 0) -#define R300_VPI_OUT_OP_SLT (10 << 0) - /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */ -#define R300_VPI_OUT_OP_UNK12 (12 << 0) -#define R300_VPI_OUT_OP_ARL (13 << 0) -#define R300_VPI_OUT_OP_EXP (65 << 0) -#define R300_VPI_OUT_OP_LOG (66 << 0) - /* Used in fog computations, scalar(scalar) */ -#define R300_VPI_OUT_OP_UNK67 (67 << 0) -#define R300_VPI_OUT_OP_LIT (68 << 0) -#define R300_VPI_OUT_OP_POW (69 << 0) -#define R300_VPI_OUT_OP_RCP (70 << 0) -#define R300_VPI_OUT_OP_RSQ (72 << 0) - /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */ -#define R300_VPI_OUT_OP_UNK73 (73 << 0) -#define R300_VPI_OUT_OP_EX2 (75 << 0) -#define R300_VPI_OUT_OP_LG2 (76 << 0) -#define R300_VPI_OUT_OP_MAD_2 (128 << 0) - /* all temps, vector(scalar, vector, vector) */ -#define R300_VPI_OUT_OP_UNK129 (129 << 0) - -#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8) -#define R300_VPI_OUT_REG_CLASS_ADDR (1 << 8) -#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8) -#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8) - -#define R300_VPI_OUT_REG_INDEX_SHIFT 13 - /* GUESS based on fglrx native limits */ -#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) - -#define R300_VPI_OUT_WRITE_X (1 << 20) -#define R300_VPI_OUT_WRITE_Y (1 << 21) -#define R300_VPI_OUT_WRITE_Z (1 << 22) -#define R300_VPI_OUT_WRITE_W (1 << 23) - -#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0) -#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0) -#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0) -#define R300_VPI_IN_REG_CLASS_NONE (9 << 0) -#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) - -#define R300_VPI_IN_REG_INDEX_SHIFT 5 - /* GUESS based on fglrx native limits */ -#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) - -/* The R300 can select components from the input register arbitrarily. - * Use the following constants, shifted by the component shift you - * want to select - */ -#define R300_VPI_IN_SELECT_X 0 -#define R300_VPI_IN_SELECT_Y 1 -#define R300_VPI_IN_SELECT_Z 2 -#define R300_VPI_IN_SELECT_W 3 -#define R300_VPI_IN_SELECT_ZERO 4 -#define R300_VPI_IN_SELECT_ONE 5 -#define R300_VPI_IN_SELECT_MASK 7 - -#define R300_VPI_IN_X_SHIFT 13 -#define R300_VPI_IN_Y_SHIFT 16 -#define R300_VPI_IN_Z_SHIFT 19 -#define R300_VPI_IN_W_SHIFT 22 - -#define R300_VPI_IN_NEG_X (1 << 25) -#define R300_VPI_IN_NEG_Y (1 << 26) -#define R300_VPI_IN_NEG_Z (1 << 27) -#define R300_VPI_IN_NEG_W (1 << 28) -/* END: Vertex program instruction set */ - -/* BEGIN: Packet 3 commands */ - -/* A primitive emission dword. */ -#define R300_PRIM_TYPE_NONE (0 << 0) -#define R300_PRIM_TYPE_POINT (1 << 0) -#define R300_PRIM_TYPE_LINE (2 << 0) -#define R300_PRIM_TYPE_LINE_STRIP (3 << 0) -#define R300_PRIM_TYPE_TRI_LIST (4 << 0) -#define R300_PRIM_TYPE_TRI_FAN (5 << 0) -#define R300_PRIM_TYPE_TRI_STRIP (6 << 0) -#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0) -#define R300_PRIM_TYPE_RECT_LIST (8 << 0) -#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) -#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) - /* GUESS (based on r200) */ -#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) -#define R300_PRIM_TYPE_LINE_LOOP (12 << 0) -#define R300_PRIM_TYPE_QUADS (13 << 0) -#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0) -#define R300_PRIM_TYPE_POLYGON (15 << 0) -#define R300_PRIM_TYPE_MASK 0xF -#define R300_PRIM_WALK_IND (1 << 4) -#define R300_PRIM_WALK_LIST (2 << 4) -#define R300_PRIM_WALK_RING (3 << 4) -#define R300_PRIM_WALK_MASK (3 << 4) - /* GUESS (based on r200) */ -#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) -#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) -#define R300_PRIM_NUM_VERTICES_SHIFT 16 -#define R300_PRIM_NUM_VERTICES_MASK 0xffff - -/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. - * Two parameter dwords: - * 0. The first parameter appears to be always 0 - * 1. The second parameter is a standard primitive emission dword. - */ -#define R300_PACKET3_3D_DRAW_VBUF 0x00002800 - -/* Specify the full set of vertex arrays as (address, stride). - * The first parameter is the number of vertex arrays specified. - * The rest of the command is a variable length list of blocks, where - * each block is three dwords long and specifies two arrays. - * The first dword of a block is split into two words, the lower significant - * word refers to the first array, the more significant word to the second - * array in the block. - * The low byte of each word contains the size of an array entry in dwords, - * the high byte contains the stride of the array. - * The second dword of a block contains the pointer to the first array, - * the third dword of a block contains the pointer to the second array. - * Note that if the total number of arrays is odd, the third dword of - * the last block is omitted. - */ -#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 - -#define R300_PACKET3_INDX_BUFFER 0x00003300 -# define R300_EB_UNK1_SHIFT 24 -# define R300_EB_UNK1 (0x80<<24) -# define R300_EB_UNK2 0x0810 -#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400 -#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 - -/* END: Packet 3 commands */ - - -/* Color formats for 2d packets - */ -#define R300_CP_COLOR_FORMAT_CI8 2 -#define R300_CP_COLOR_FORMAT_ARGB1555 3 -#define R300_CP_COLOR_FORMAT_RGB565 4 -#define R300_CP_COLOR_FORMAT_ARGB8888 6 -#define R300_CP_COLOR_FORMAT_RGB332 7 -#define R300_CP_COLOR_FORMAT_RGB8 9 -#define R300_CP_COLOR_FORMAT_ARGB4444 15 - -/* - * CP type-3 packets - */ -#define R300_CP_CMD_BITBLT_MULTI 0xC0009B00 - -#define R500_VAP_INDEX_OFFSET 0x208c - -#define R500_GA_US_VECTOR_INDEX 0x4250 -#define R500_GA_US_VECTOR_DATA 0x4254 - -#define R500_RS_IP_0 0x4074 -#define R500_RS_INST_0 0x4320 - -#define R500_US_CONFIG 0x4600 - -#define R500_US_FC_CTRL 0x4624 -#define R500_US_CODE_ADDR 0x4630 - -#define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0 -#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8 - -#define R300_SU_REG_DEST 0x42c8 -#define RV530_FG_ZBREG_DEST 0x4be8 -#define R300_ZB_ZPASS_DATA 0x4f58 -#define R300_ZB_ZPASS_ADDR 0x4f5c - -#endif /* _R300_REG_H */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300d.h deleted file mode 100644 index 1f519a5f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r300d.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __R300D_H__ -#define __R300D_H__ - -#define CP_PACKET0 0x00000000 -#define PACKET0_BASE_INDEX_SHIFT 0 -#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) -#define PACKET0_COUNT_SHIFT 16 -#define PACKET0_COUNT_MASK (0x3fff << 16) -#define CP_PACKET1 0x40000000 -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) -#define CP_PACKET3 0xC0000000 -#define PACKET3_IT_OPCODE_SHIFT 8 -#define PACKET3_IT_OPCODE_MASK (0xff << 8) -#define PACKET3_COUNT_SHIFT 16 -#define PACKET3_COUNT_MASK (0x3fff << 16) -/* PACKET3 op code */ -#define PACKET3_NOP 0x10 -#define PACKET3_3D_DRAW_VBUF 0x28 -#define PACKET3_3D_DRAW_IMMD 0x29 -#define PACKET3_3D_DRAW_INDX 0x2A -#define PACKET3_3D_LOAD_VBPNTR 0x2F -#define PACKET3_3D_CLEAR_ZMASK 0x32 -#define PACKET3_INDX_BUFFER 0x33 -#define PACKET3_3D_DRAW_VBUF_2 0x34 -#define PACKET3_3D_DRAW_IMMD_2 0x35 -#define PACKET3_3D_DRAW_INDX_2 0x36 -#define PACKET3_3D_CLEAR_HIZ 0x37 -#define PACKET3_3D_CLEAR_CMASK 0x38 -#define PACKET3_BITBLT_MULTI 0x9B - -#define PACKET0(reg, n) (CP_PACKET0 | \ - REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ - REG_SET(PACKET0_COUNT, (n))) -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -#define PACKET3(op, n) (CP_PACKET3 | \ - REG_SET(PACKET3_IT_OPCODE, (op)) | \ - REG_SET(PACKET3_COUNT, (n))) - -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) - -/* Registers */ -#define R_000148_MC_FB_LOCATION 0x000148 -#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000148_MC_FB_START 0xFFFF0000 -#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000148_MC_FB_TOP 0x0000FFFF -#define R_00014C_MC_AGP_LOCATION 0x00014C -#define S_00014C_MC_AGP_START(x) (((x) & 0xFFFF) << 0) -#define G_00014C_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) -#define C_00014C_MC_AGP_START 0xFFFF0000 -#define S_00014C_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) -#define G_00014C_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_00014C_MC_AGP_TOP 0x0000FFFF -#define R_00015C_AGP_BASE_2 0x00015C -#define S_00015C_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) -#define G_00015C_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) -#define C_00015C_AGP_BASE_ADDR_2 0xFFFFFFF0 -#define R_000170_AGP_BASE 0x000170 -#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000170_AGP_BASE_ADDR 0x00000000 -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF -#define R_0000F0_RBBM_SOFT_RESET 0x0000F0 -#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) -#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) -#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE -#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) -#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) -#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD -#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2) -#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1) -#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB -#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) -#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) -#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 -#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) -#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) -#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF -#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) -#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) -#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF -#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) -#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) -#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF -#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) -#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) -#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F -#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) -#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) -#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF -#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) -#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) -#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF -#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) -#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) -#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF -#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) -#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) -#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF -#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) -#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) -#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF -#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13) -#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1) -#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF -#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14) -#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1) -#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF - -#define R_00000D_SCLK_CNTL 0x00000D -#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) -#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7) -#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8 -#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3) -#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1) -#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7 -#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4) -#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1) -#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF -#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5) -#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1) -#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF -#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6) -#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1) -#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF -#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7) -#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1) -#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F -#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8) -#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1) -#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF -#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9) -#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1) -#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF -#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10) -#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1) -#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF -#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11) -#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1) -#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF -#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12) -#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1) -#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF -#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13) -#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1) -#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF -#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14) -#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1) -#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF -#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15) -#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1) -#define C_00000D_FORCE_DISP2 0xFFFF7FFF -#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16) -#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1) -#define C_00000D_FORCE_CP 0xFFFEFFFF -#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17) -#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1) -#define C_00000D_FORCE_HDP 0xFFFDFFFF -#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18) -#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1) -#define C_00000D_FORCE_DISP1 0xFFFBFFFF -#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19) -#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1) -#define C_00000D_FORCE_TOP 0xFFF7FFFF -#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20) -#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1) -#define C_00000D_FORCE_E2 0xFFEFFFFF -#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21) -#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1) -#define C_00000D_FORCE_SE 0xFFDFFFFF -#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22) -#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1) -#define C_00000D_FORCE_IDCT 0xFFBFFFFF -#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23) -#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1) -#define C_00000D_FORCE_VIP 0xFF7FFFFF -#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24) -#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1) -#define C_00000D_FORCE_RE 0xFEFFFFFF -#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25) -#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1) -#define C_00000D_FORCE_PB 0xFDFFFFFF -#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26) -#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1) -#define C_00000D_FORCE_TAM 0xFBFFFFFF -#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27) -#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1) -#define C_00000D_FORCE_TDM 0xF7FFFFFF -#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28) -#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1) -#define C_00000D_FORCE_RB 0xEFFFFFFF -#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29) -#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1) -#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF -#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30) -#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1) -#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF -#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31) -#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1) -#define C_00000D_FORCE_OV0 0x7FFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r420.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r420.c deleted file mode 100644 index f3fcaacf..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r420.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include "drmP.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" -#include "r100d.h" -#include "r420d.h" -#include "r420_reg_safe.h" - -void r420_pm_init_profile(struct radeon_device *rdev) -{ - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; -} - -static void r420_set_reg_safe(struct radeon_device *rdev) -{ - rdev->config.r300.reg_safe_bm = r420_reg_safe_bm; - rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r420_reg_safe_bm); -} - -void r420_pipes_init(struct radeon_device *rdev) -{ - unsigned tmp; - unsigned gb_pipe_select; - unsigned num_pipes; - - /* GA_ENHANCE workaround TCL deadlock issue */ - WREG32(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL | - (1 << 2) | (1 << 3)); - /* add idle wait as per freedesktop.org bug 24041 */ - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } - /* get max number of pipes */ - gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); - num_pipes = ((gb_pipe_select >> 12) & 3) + 1; - - /* SE chips have 1 pipe */ - if ((rdev->pdev->device == 0x5e4c) || - (rdev->pdev->device == 0x5e4f)) - num_pipes = 1; - - rdev->num_gb_pipes = num_pipes; - tmp = 0; - switch (num_pipes) { - default: - /* force to 1 pipe */ - num_pipes = 1; - case 1: - tmp = (0 << 1); - break; - case 2: - tmp = (3 << 1); - break; - case 3: - tmp = (6 << 1); - break; - case 4: - tmp = (7 << 1); - break; - } - WREG32(R500_SU_REG_DEST, (1 << num_pipes) - 1); - /* Sub pixel 1/12 so we can have 4K rendering according to doc */ - tmp |= R300_TILE_SIZE_16 | R300_ENABLE_TILING; - WREG32(R300_GB_TILE_CONFIG, tmp); - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } - - tmp = RREG32(R300_DST_PIPE_CONFIG); - WREG32(R300_DST_PIPE_CONFIG, tmp | R300_PIPE_AUTO_CONFIG); - - WREG32(R300_RB2D_DSTCACHE_MODE, - RREG32(R300_RB2D_DSTCACHE_MODE) | - R300_DC_AUTOFLUSH_ENABLE | - R300_DC_DC_DISABLE_IGNORE_PE); - - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "programming pipes. Bad things might happen.\n"); - } - - if (rdev->family == CHIP_RV530) { - tmp = RREG32(RV530_GB_PIPE_SELECT2); - if ((tmp & 3) == 3) - rdev->num_z_pipes = 2; - else - rdev->num_z_pipes = 1; - } else - rdev->num_z_pipes = 1; - - DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n", - rdev->num_gb_pipes, rdev->num_z_pipes); -} - -u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg) -{ - u32 r; - - WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg)); - r = RREG32(R_0001FC_MC_IND_DATA); - return r; -} - -void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v) -{ - WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) | - S_0001F8_MC_IND_WR_EN(1)); - WREG32(R_0001FC_MC_IND_DATA, v); -} - -static void r420_debugfs(struct radeon_device *rdev) -{ - if (r100_debugfs_rbbm_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for RBBM !\n"); - } - if (r420_debugfs_pipes_info_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for pipes !\n"); - } -} - -static void r420_clock_resume(struct radeon_device *rdev) -{ - u32 sclk_cntl; - - if (radeon_dynclks != -1 && radeon_dynclks) - radeon_atom_set_clock_gating(rdev, 1); - sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL); - sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); - if (rdev->family == CHIP_R420) - sclk_cntl |= S_00000D_FORCE_PX(1) | S_00000D_FORCE_TX(1); - WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl); -} - -static void r420_cp_errata_init(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - - /* RV410 and R420 can lock up if CP DMA to host memory happens - * while the 2D engine is busy. - * - * The proper workaround is to queue a RESYNC at the beginning - * of the CP init, apparently. - */ - radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch); - radeon_ring_lock(rdev, ring, 8); - radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1)); - radeon_ring_write(ring, rdev->config.r300.resync_scratch); - radeon_ring_write(ring, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, ring); -} - -static void r420_cp_errata_fini(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - - /* Catch the RESYNC we dispatched all the way back, - * at the very beginning of the CP init. - */ - radeon_ring_lock(rdev, ring, 8); - radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, R300_RB3D_DC_FINISH); - radeon_ring_unlock_commit(rdev, ring); - radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); -} - -static int r420_startup(struct radeon_device *rdev) -{ - int r; - - /* set common regs */ - r100_set_common_regs(rdev); - /* program mc */ - r300_mc_program(rdev); - /* Resume clock */ - r420_clock_resume(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - if (rdev->flags & RADEON_IS_PCIE) { - r = rv370_pcie_gart_enable(rdev); - if (r) - return r; - } - if (rdev->flags & RADEON_IS_PCI) { - r = r100_pci_gart_enable(rdev); - if (r) - return r; - } - r420_pipes_init(rdev); - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r100_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - r420_cp_errata_init(rdev); - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int r420_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_disable(rdev); - /* Resume clock before doing reset */ - r420_clock_resume(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (rdev->is_atom_bios) { - atom_asic_init(rdev->mode_info.atom_context); - } else { - radeon_combios_asic_init(rdev->ddev); - } - /* Resume clock after posting */ - r420_clock_resume(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = r420_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int r420_suspend(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - r420_cp_errata_fini(rdev); - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - r100_irq_disable(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_disable(rdev); - return 0; -} - -void r420_fini(struct radeon_device *rdev) -{ - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_fini(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_fini(rdev); - radeon_agp_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - if (rdev->is_atom_bios) { - radeon_atombios_fini(rdev); - } else { - radeon_combios_fini(rdev); - } - kfree(rdev->bios); - rdev->bios = NULL; -} - -int r420_init(struct radeon_device *rdev) -{ - int r; - - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* TODO: disable VGA need to use VGA request */ - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - r = radeon_atombios_init(rdev); - if (r) { - return r; - } - } else { - r = radeon_combios_init(rdev); - if (r) { - return r; - } - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } - } - /* initialize memory controller */ - r300_mc_init(rdev); - r420_debugfs(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) { - return r; - } - r = radeon_irq_kms_init(rdev); - if (r) { - return r; - } - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) { - return r; - } - if (rdev->family == CHIP_R420) - r100_enable_bm(rdev); - - if (rdev->flags & RADEON_IS_PCIE) { - r = rv370_pcie_gart_init(rdev); - if (r) - return r; - } - if (rdev->flags & RADEON_IS_PCI) { - r = r100_pci_gart_init(rdev); - if (r) - return r; - } - r420_set_reg_safe(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = r420_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_fini(rdev); - if (rdev->flags & RADEON_IS_PCI) - r100_pci_gart_fini(rdev); - radeon_agp_fini(rdev); - rdev->accel_working = false; - } - return 0; -} - -/* - * Debugfs info - */ -#if defined(CONFIG_DEBUG_FS) -static int r420_debugfs_pipes_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - tmp = RREG32(R400_GB_PIPE_SELECT); - seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp); - tmp = RREG32(R300_GB_TILE_CONFIG); - seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp); - tmp = RREG32(R300_DST_PIPE_CONFIG); - seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp); - return 0; -} - -static struct drm_info_list r420_pipes_info_list[] = { - {"r420_pipes_info", r420_debugfs_pipes_info, 0, NULL}, -}; -#endif - -int r420_debugfs_pipes_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, r420_pipes_info_list, 1); -#else - return 0; -#endif -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r420d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r420d.h deleted file mode 100644 index fc78d31a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r420d.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef R420D_H -#define R420D_H - -#define R_0001F8_MC_IND_INDEX 0x0001F8 -#define S_0001F8_MC_IND_ADDR(x) (((x) & 0x7F) << 0) -#define G_0001F8_MC_IND_ADDR(x) (((x) >> 0) & 0x7F) -#define C_0001F8_MC_IND_ADDR 0xFFFFFF80 -#define S_0001F8_MC_IND_WR_EN(x) (((x) & 0x1) << 8) -#define G_0001F8_MC_IND_WR_EN(x) (((x) >> 8) & 0x1) -#define C_0001F8_MC_IND_WR_EN 0xFFFFFEFF -#define R_0001FC_MC_IND_DATA 0x0001FC -#define S_0001FC_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0) -#define G_0001FC_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_0001FC_MC_IND_DATA 0x00000000 -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF - -/* CLK registers */ -#define R_00000D_SCLK_CNTL 0x00000D -#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) -#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7) -#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8 -#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3) -#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1) -#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7 -#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4) -#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1) -#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF -#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5) -#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1) -#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF -#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6) -#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1) -#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF -#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7) -#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1) -#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F -#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8) -#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1) -#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF -#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9) -#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1) -#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF -#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10) -#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1) -#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF -#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11) -#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1) -#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF -#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12) -#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1) -#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF -#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13) -#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1) -#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF -#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14) -#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1) -#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF -#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15) -#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1) -#define C_00000D_FORCE_DISP2 0xFFFF7FFF -#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16) -#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1) -#define C_00000D_FORCE_CP 0xFFFEFFFF -#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17) -#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1) -#define C_00000D_FORCE_HDP 0xFFFDFFFF -#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18) -#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1) -#define C_00000D_FORCE_DISP1 0xFFFBFFFF -#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19) -#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1) -#define C_00000D_FORCE_TOP 0xFFF7FFFF -#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20) -#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1) -#define C_00000D_FORCE_E2 0xFFEFFFFF -#define S_00000D_FORCE_VAP(x) (((x) & 0x1) << 21) -#define G_00000D_FORCE_VAP(x) (((x) >> 21) & 0x1) -#define C_00000D_FORCE_VAP 0xFFDFFFFF -#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22) -#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1) -#define C_00000D_FORCE_IDCT 0xFFBFFFFF -#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23) -#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1) -#define C_00000D_FORCE_VIP 0xFF7FFFFF -#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24) -#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1) -#define C_00000D_FORCE_RE 0xFEFFFFFF -#define S_00000D_FORCE_SR(x) (((x) & 0x1) << 25) -#define G_00000D_FORCE_SR(x) (((x) >> 25) & 0x1) -#define C_00000D_FORCE_SR 0xFDFFFFFF -#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26) -#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1) -#define C_00000D_FORCE_PX 0xFBFFFFFF -#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27) -#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1) -#define C_00000D_FORCE_TX 0xF7FFFFFF -#define S_00000D_FORCE_US(x) (((x) & 0x1) << 28) -#define G_00000D_FORCE_US(x) (((x) >> 28) & 0x1) -#define C_00000D_FORCE_US 0xEFFFFFFF -#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29) -#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1) -#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF -#define S_00000D_FORCE_SU(x) (((x) & 0x1) << 30) -#define G_00000D_FORCE_SU(x) (((x) >> 30) & 0x1) -#define C_00000D_FORCE_SU 0xBFFFFFFF -#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31) -#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1) -#define C_00000D_FORCE_OV0 0x7FFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r500_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r500_reg.h deleted file mode 100644 index ec576aaa..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r500_reg.h +++ /dev/null @@ -1,797 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __R500_REG_H__ -#define __R500_REG_H__ - -/* pipe config regs */ -#define R300_GA_POLY_MODE 0x4288 -# define R300_FRONT_PTYPE_POINT (0 << 4) -# define R300_FRONT_PTYPE_LINE (1 << 4) -# define R300_FRONT_PTYPE_TRIANGE (2 << 4) -# define R300_BACK_PTYPE_POINT (0 << 7) -# define R300_BACK_PTYPE_LINE (1 << 7) -# define R300_BACK_PTYPE_TRIANGE (2 << 7) -#define R300_GA_ROUND_MODE 0x428c -# define R300_GEOMETRY_ROUND_TRUNC (0 << 0) -# define R300_GEOMETRY_ROUND_NEAREST (1 << 0) -# define R300_COLOR_ROUND_TRUNC (0 << 2) -# define R300_COLOR_ROUND_NEAREST (1 << 2) -#define R300_GB_MSPOS0 0x4010 -# define R300_MS_X0_SHIFT 0 -# define R300_MS_Y0_SHIFT 4 -# define R300_MS_X1_SHIFT 8 -# define R300_MS_Y1_SHIFT 12 -# define R300_MS_X2_SHIFT 16 -# define R300_MS_Y2_SHIFT 20 -# define R300_MSBD0_Y_SHIFT 24 -# define R300_MSBD0_X_SHIFT 28 -#define R300_GB_MSPOS1 0x4014 -# define R300_MS_X3_SHIFT 0 -# define R300_MS_Y3_SHIFT 4 -# define R300_MS_X4_SHIFT 8 -# define R300_MS_Y4_SHIFT 12 -# define R300_MS_X5_SHIFT 16 -# define R300_MS_Y5_SHIFT 20 -# define R300_MSBD1_SHIFT 24 - -#define R300_GA_ENHANCE 0x4274 -# define R300_GA_DEADLOCK_CNTL (1 << 0) -# define R300_GA_FASTSYNC_CNTL (1 << 1) -#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c -# define R300_RB3D_DC_FLUSH (2 << 0) -# define R300_RB3D_DC_FREE (2 << 2) -# define R300_RB3D_DC_FINISH (1 << 4) -#define R300_RB3D_ZCACHE_CTLSTAT 0x4f18 -# define R300_ZC_FLUSH (1 << 0) -# define R300_ZC_FREE (1 << 1) -# define R300_ZC_FLUSH_ALL 0x3 -#define R400_GB_PIPE_SELECT 0x402c -#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ -#define R500_SU_REG_DEST 0x42c8 -#define R300_GB_TILE_CONFIG 0x4018 -# define R300_ENABLE_TILING (1 << 0) -# define R300_PIPE_COUNT_RV350 (0 << 1) -# define R300_PIPE_COUNT_R300 (3 << 1) -# define R300_PIPE_COUNT_R420_3P (6 << 1) -# define R300_PIPE_COUNT_R420 (7 << 1) -# define R300_TILE_SIZE_8 (0 << 4) -# define R300_TILE_SIZE_16 (1 << 4) -# define R300_TILE_SIZE_32 (2 << 4) -# define R300_SUBPIXEL_1_12 (0 << 16) -# define R300_SUBPIXEL_1_16 (1 << 16) -#define R300_DST_PIPE_CONFIG 0x170c -# define R300_PIPE_AUTO_CONFIG (1 << 31) -#define R300_RB2D_DSTCACHE_MODE 0x3428 -# define R300_DC_AUTOFLUSH_ENABLE (1 << 8) -# define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17) - -#define RADEON_CP_STAT 0x7C0 -#define RADEON_RBBM_CMDFIFO_ADDR 0xE70 -#define RADEON_RBBM_CMDFIFO_DATA 0xE74 -#define RADEON_ISYNC_CNTL 0x1724 -# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) -# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) -# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) -# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) -# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) -# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) - -#define RS480_NB_MC_INDEX 0x168 -# define RS480_NB_MC_IND_WR_EN (1 << 8) -#define RS480_NB_MC_DATA 0x16c - -/* - * RS690 - */ -#define RS690_MCCFG_FB_LOCATION 0x100 -#define RS690_MC_FB_START_MASK 0x0000FFFF -#define RS690_MC_FB_START_SHIFT 0 -#define RS690_MC_FB_TOP_MASK 0xFFFF0000 -#define RS690_MC_FB_TOP_SHIFT 16 -#define RS690_MCCFG_AGP_LOCATION 0x101 -#define RS690_MC_AGP_START_MASK 0x0000FFFF -#define RS690_MC_AGP_START_SHIFT 0 -#define RS690_MC_AGP_TOP_MASK 0xFFFF0000 -#define RS690_MC_AGP_TOP_SHIFT 16 -#define RS690_MCCFG_AGP_BASE 0x102 -#define RS690_MCCFG_AGP_BASE_2 0x103 -#define RS690_MC_INIT_MISC_LAT_TIMER 0x104 -#define RS690_HDP_FB_LOCATION 0x0134 -#define RS690_MC_INDEX 0x78 -# define RS690_MC_INDEX_MASK 0x1ff -# define RS690_MC_INDEX_WR_EN (1 << 9) -# define RS690_MC_INDEX_WR_ACK 0x7f -#define RS690_MC_DATA 0x7c -#define RS690_MC_STATUS 0x90 -#define RS690_MC_STATUS_IDLE (1 << 0) -#define RS480_AGP_BASE_2 0x0164 -#define RS480_MC_MISC_CNTL 0x18 -# define RS480_DISABLE_GTW (1 << 1) -# define RS480_GART_INDEX_REG_EN (1 << 12) -# define RS690_BLOCK_GFX_D3_EN (1 << 14) -#define RS480_GART_FEATURE_ID 0x2b -# define RS480_HANG_EN (1 << 11) -# define RS480_TLB_ENABLE (1 << 18) -# define RS480_P2P_ENABLE (1 << 19) -# define RS480_GTW_LAC_EN (1 << 25) -# define RS480_2LEVEL_GART (0 << 30) -# define RS480_1LEVEL_GART (1 << 30) -# define RS480_PDC_EN (1 << 31) -#define RS480_GART_BASE 0x2c -#define RS480_GART_CACHE_CNTRL 0x2e -# define RS480_GART_CACHE_INVALIDATE (1 << 0) /* wait for it to clear */ -#define RS480_AGP_ADDRESS_SPACE_SIZE 0x38 -# define RS480_GART_EN (1 << 0) -# define RS480_VA_SIZE_32MB (0 << 1) -# define RS480_VA_SIZE_64MB (1 << 1) -# define RS480_VA_SIZE_128MB (2 << 1) -# define RS480_VA_SIZE_256MB (3 << 1) -# define RS480_VA_SIZE_512MB (4 << 1) -# define RS480_VA_SIZE_1GB (5 << 1) -# define RS480_VA_SIZE_2GB (6 << 1) -#define RS480_AGP_MODE_CNTL 0x39 -# define RS480_POST_GART_Q_SIZE (1 << 18) -# define RS480_NONGART_SNOOP (1 << 19) -# define RS480_AGP_RD_BUF_SIZE (1 << 20) -# define RS480_REQ_TYPE_SNOOP_SHIFT 22 -# define RS480_REQ_TYPE_SNOOP_MASK 0x3 -# define RS480_REQ_TYPE_SNOOP_DIS (1 << 24) - -#define RS690_AIC_CTRL_SCRATCH 0x3A -# define RS690_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) - -/* - * RS600 - */ -#define RS600_MC_STATUS 0x0 -#define RS600_MC_STATUS_IDLE (1 << 0) -#define RS600_MC_INDEX 0x70 -# define RS600_MC_ADDR_MASK 0xffff -# define RS600_MC_IND_SEQ_RBS_0 (1 << 16) -# define RS600_MC_IND_SEQ_RBS_1 (1 << 17) -# define RS600_MC_IND_SEQ_RBS_2 (1 << 18) -# define RS600_MC_IND_SEQ_RBS_3 (1 << 19) -# define RS600_MC_IND_AIC_RBS (1 << 20) -# define RS600_MC_IND_CITF_ARB0 (1 << 21) -# define RS600_MC_IND_CITF_ARB1 (1 << 22) -# define RS600_MC_IND_WR_EN (1 << 23) -#define RS600_MC_DATA 0x74 -#define RS600_MC_STATUS 0x0 -# define RS600_MC_IDLE (1 << 1) -#define RS600_MC_FB_LOCATION 0x4 -#define RS600_MC_FB_START_MASK 0x0000FFFF -#define RS600_MC_FB_START_SHIFT 0 -#define RS600_MC_FB_TOP_MASK 0xFFFF0000 -#define RS600_MC_FB_TOP_SHIFT 16 -#define RS600_MC_AGP_LOCATION 0x5 -#define RS600_MC_AGP_START_MASK 0x0000FFFF -#define RS600_MC_AGP_START_SHIFT 0 -#define RS600_MC_AGP_TOP_MASK 0xFFFF0000 -#define RS600_MC_AGP_TOP_SHIFT 16 -#define RS600_MC_AGP_BASE 0x6 -#define RS600_MC_AGP_BASE_2 0x7 -#define RS600_MC_CNTL1 0x9 -# define RS600_ENABLE_PAGE_TABLES (1 << 26) -#define RS600_MC_PT0_CNTL 0x100 -# define RS600_ENABLE_PT (1 << 0) -# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15) -# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21) -# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28) -# define RS600_INVALIDATE_L2_CACHE (1 << 29) -#define RS600_MC_PT0_CONTEXT0_CNTL 0x102 -# define RS600_ENABLE_PAGE_TABLE (1 << 0) -# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1) -#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112 -#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114 -#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c -#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c -#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c -#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c -#define RS600_MC_PT0_CLIENT0_CNTL 0x16c -# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0) -# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1) -# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8) -# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8) -# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8) -# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8) -# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8) -# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10) -# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10) -# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11) -# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14) -# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) -# define RS600_INVALIDATE_L1_TLB (1 << 20) -/* rs600/rs690/rs740 */ -# define RS600_BUS_MASTER_DIS (1 << 14) -# define RS600_MSI_REARM (1 << 20) -/* see RS400_MSI_REARM in AIC_CNTL for rs480 */ - - - -#define RV515_MC_FB_LOCATION 0x01 -#define RV515_MC_FB_START_MASK 0x0000FFFF -#define RV515_MC_FB_START_SHIFT 0 -#define RV515_MC_FB_TOP_MASK 0xFFFF0000 -#define RV515_MC_FB_TOP_SHIFT 16 -#define RV515_MC_AGP_LOCATION 0x02 -#define RV515_MC_AGP_START_MASK 0x0000FFFF -#define RV515_MC_AGP_START_SHIFT 0 -#define RV515_MC_AGP_TOP_MASK 0xFFFF0000 -#define RV515_MC_AGP_TOP_SHIFT 16 -#define RV515_MC_AGP_BASE 0x03 -#define RV515_MC_AGP_BASE_2 0x04 - -#define R520_MC_FB_LOCATION 0x04 -#define R520_MC_FB_START_MASK 0x0000FFFF -#define R520_MC_FB_START_SHIFT 0 -#define R520_MC_FB_TOP_MASK 0xFFFF0000 -#define R520_MC_FB_TOP_SHIFT 16 -#define R520_MC_AGP_LOCATION 0x05 -#define R520_MC_AGP_START_MASK 0x0000FFFF -#define R520_MC_AGP_START_SHIFT 0 -#define R520_MC_AGP_TOP_MASK 0xFFFF0000 -#define R520_MC_AGP_TOP_SHIFT 16 -#define R520_MC_AGP_BASE 0x06 -#define R520_MC_AGP_BASE_2 0x07 - - -#define AVIVO_MC_INDEX 0x0070 -#define R520_MC_STATUS 0x00 -#define R520_MC_STATUS_IDLE (1<<1) -#define RV515_MC_STATUS 0x08 -#define RV515_MC_STATUS_IDLE (1<<4) -#define RV515_MC_INIT_MISC_LAT_TIMER 0x09 -#define AVIVO_MC_DATA 0x0074 - -#define R520_MC_IND_INDEX 0x70 -#define R520_MC_IND_WR_EN (1 << 24) -#define R520_MC_IND_DATA 0x74 - -#define RV515_MC_CNTL 0x5 -# define RV515_MEM_NUM_CHANNELS_MASK 0x3 -#define R520_MC_CNTL0 0x8 -# define R520_MEM_NUM_CHANNELS_MASK (0x3 << 24) -# define R520_MEM_NUM_CHANNELS_SHIFT 24 -# define R520_MC_CHANNEL_SIZE (1 << 23) - -#define AVIVO_CP_DYN_CNTL 0x000f /* PLL */ -# define AVIVO_CP_FORCEON (1 << 0) -#define AVIVO_E2_DYN_CNTL 0x0011 /* PLL */ -# define AVIVO_E2_FORCEON (1 << 0) -#define AVIVO_IDCT_DYN_CNTL 0x0013 /* PLL */ -# define AVIVO_IDCT_FORCEON (1 << 0) - -#define AVIVO_HDP_FB_LOCATION 0x134 - -#define AVIVO_VGA_RENDER_CONTROL 0x0300 -# define AVIVO_VGA_VSTATUS_CNTL_MASK (3 << 16) -#define AVIVO_D1VGA_CONTROL 0x0330 -# define AVIVO_DVGA_CONTROL_MODE_ENABLE (1<<0) -# define AVIVO_DVGA_CONTROL_TIMING_SELECT (1<<8) -# define AVIVO_DVGA_CONTROL_SYNC_POLARITY_SELECT (1<<9) -# define AVIVO_DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1<<10) -# define AVIVO_DVGA_CONTROL_OVERSCAN_COLOR_EN (1<<16) -# define AVIVO_DVGA_CONTROL_ROTATE (1<<24) -#define AVIVO_D2VGA_CONTROL 0x0338 - -#define AVIVO_EXT1_PPLL_REF_DIV_SRC 0x400 -#define AVIVO_EXT1_PPLL_REF_DIV 0x404 -#define AVIVO_EXT1_PPLL_UPDATE_LOCK 0x408 -#define AVIVO_EXT1_PPLL_UPDATE_CNTL 0x40c - -#define AVIVO_EXT2_PPLL_REF_DIV_SRC 0x410 -#define AVIVO_EXT2_PPLL_REF_DIV 0x414 -#define AVIVO_EXT2_PPLL_UPDATE_LOCK 0x418 -#define AVIVO_EXT2_PPLL_UPDATE_CNTL 0x41c - -#define AVIVO_EXT1_PPLL_FB_DIV 0x430 -#define AVIVO_EXT2_PPLL_FB_DIV 0x434 - -#define AVIVO_EXT1_PPLL_POST_DIV_SRC 0x438 -#define AVIVO_EXT1_PPLL_POST_DIV 0x43c - -#define AVIVO_EXT2_PPLL_POST_DIV_SRC 0x440 -#define AVIVO_EXT2_PPLL_POST_DIV 0x444 - -#define AVIVO_EXT1_PPLL_CNTL 0x448 -#define AVIVO_EXT2_PPLL_CNTL 0x44c - -#define AVIVO_P1PLL_CNTL 0x450 -#define AVIVO_P2PLL_CNTL 0x454 -#define AVIVO_P1PLL_INT_SS_CNTL 0x458 -#define AVIVO_P2PLL_INT_SS_CNTL 0x45c -#define AVIVO_P1PLL_TMDSA_CNTL 0x460 -#define AVIVO_P2PLL_LVTMA_CNTL 0x464 - -#define AVIVO_PCLK_CRTC1_CNTL 0x480 -#define AVIVO_PCLK_CRTC2_CNTL 0x484 - -#define AVIVO_D1CRTC_H_TOTAL 0x6000 -#define AVIVO_D1CRTC_H_BLANK_START_END 0x6004 -#define AVIVO_D1CRTC_H_SYNC_A 0x6008 -#define AVIVO_D1CRTC_H_SYNC_A_CNTL 0x600c -#define AVIVO_D1CRTC_H_SYNC_B 0x6010 -#define AVIVO_D1CRTC_H_SYNC_B_CNTL 0x6014 - -#define AVIVO_D1CRTC_V_TOTAL 0x6020 -#define AVIVO_D1CRTC_V_BLANK_START_END 0x6024 -#define AVIVO_D1CRTC_V_SYNC_A 0x6028 -#define AVIVO_D1CRTC_V_SYNC_A_CNTL 0x602c -#define AVIVO_D1CRTC_V_SYNC_B 0x6030 -#define AVIVO_D1CRTC_V_SYNC_B_CNTL 0x6034 - -#define AVIVO_D1CRTC_CONTROL 0x6080 -# define AVIVO_CRTC_EN (1 << 0) -# define AVIVO_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) -#define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 -#define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 -#define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c -#define AVIVO_D1CRTC_STATUS 0x609c -# define AVIVO_D1CRTC_V_BLANK (1 << 0) -#define AVIVO_D1CRTC_STATUS_POSITION 0x60a0 -#define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 -#define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 - -#define AVIVO_D1MODE_MASTER_UPDATE_MODE 0x60e4 - -/* master controls */ -#define AVIVO_DC_CRTC_MASTER_EN 0x60f8 -#define AVIVO_DC_CRTC_TV_CONTROL 0x60fc - -#define AVIVO_D1GRPH_ENABLE 0x6100 -#define AVIVO_D1GRPH_CONTROL 0x6104 -# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0 << 0) -# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1 << 0) -# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2 << 0) -# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3 << 0) - -# define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED (0 << 8) - -# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555 (0 << 8) -# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1 << 8) -# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2 << 8) -# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3 << 8) -# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4 << 8) - -# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0 << 8) -# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1 << 8) -# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2 << 8) -# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3 << 8) - - -# define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616 (0 << 8) - -# define AVIVO_D1GRPH_SWAP_RB (1 << 16) -# define AVIVO_D1GRPH_TILED (1 << 20) -# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) - -# define R600_D1GRPH_ARRAY_MODE_LINEAR_GENERAL (0 << 20) -# define R600_D1GRPH_ARRAY_MODE_LINEAR_ALIGNED (1 << 20) -# define R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1 (2 << 20) -# define R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1 (4 << 20) - -/* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 - * block and vice versa. This applies to GRPH, CUR, etc. - */ -#define AVIVO_D1GRPH_LUT_SEL 0x6108 -#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 -#define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 -#define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 -#define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 -#define R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c -#define R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c -#define AVIVO_D1GRPH_PITCH 0x6120 -#define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 -#define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 -#define AVIVO_D1GRPH_X_START 0x612c -#define AVIVO_D1GRPH_Y_START 0x6130 -#define AVIVO_D1GRPH_X_END 0x6134 -#define AVIVO_D1GRPH_Y_END 0x6138 -#define AVIVO_D1GRPH_UPDATE 0x6144 -# define AVIVO_D1GRPH_SURFACE_UPDATE_PENDING (1 << 2) -# define AVIVO_D1GRPH_UPDATE_LOCK (1 << 16) -#define AVIVO_D1GRPH_FLIP_CONTROL 0x6148 -# define AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN (1 << 0) - -#define AVIVO_D1CUR_CONTROL 0x6400 -# define AVIVO_D1CURSOR_EN (1 << 0) -# define AVIVO_D1CURSOR_MODE_SHIFT 8 -# define AVIVO_D1CURSOR_MODE_MASK (3 << 8) -# define AVIVO_D1CURSOR_MODE_24BPP 2 -#define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 -#define R700_D1CUR_SURFACE_ADDRESS_HIGH 0x6c0c -#define R700_D2CUR_SURFACE_ADDRESS_HIGH 0x640c -#define AVIVO_D1CUR_SIZE 0x6410 -#define AVIVO_D1CUR_POSITION 0x6414 -#define AVIVO_D1CUR_HOT_SPOT 0x6418 -#define AVIVO_D1CUR_UPDATE 0x6424 -# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16) - -#define AVIVO_DC_LUT_RW_SELECT 0x6480 -#define AVIVO_DC_LUT_RW_MODE 0x6484 -#define AVIVO_DC_LUT_RW_INDEX 0x6488 -#define AVIVO_DC_LUT_SEQ_COLOR 0x648c -#define AVIVO_DC_LUT_PWL_DATA 0x6490 -#define AVIVO_DC_LUT_30_COLOR 0x6494 -#define AVIVO_DC_LUT_READ_PIPE_SELECT 0x6498 -#define AVIVO_DC_LUT_WRITE_EN_MASK 0x649c -#define AVIVO_DC_LUT_AUTOFILL 0x64a0 - -#define AVIVO_DC_LUTA_CONTROL 0x64c0 -#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE 0x64c4 -#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN 0x64c8 -#define AVIVO_DC_LUTA_BLACK_OFFSET_RED 0x64cc -#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE 0x64d0 -#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4 -#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8 - -#define AVIVO_DC_LB_MEMORY_SPLIT 0x6520 -# define AVIVO_DC_LB_MEMORY_SPLIT_MASK 0x3 -# define AVIVO_DC_LB_MEMORY_SPLIT_SHIFT 0 -# define AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0 -# define AVIVO_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1 -# define AVIVO_DC_LB_MEMORY_SPLIT_D1_ONLY 2 -# define AVIVO_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3 -# define AVIVO_DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2) -# define AVIVO_DC_LB_DISP1_END_ADR_SHIFT 4 -# define AVIVO_DC_LB_DISP1_END_ADR_MASK 0x7ff - -#define AVIVO_D1MODE_DATA_FORMAT 0x6528 -# define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) -#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C -#define AVIVO_D1MODE_VBLANK_STATUS 0x6534 -# define AVIVO_VBLANK_ACK (1 << 4) -#define AVIVO_D1MODE_VLINE_START_END 0x6538 -#define AVIVO_D1MODE_VLINE_STATUS 0x653c -# define AVIVO_D1MODE_VLINE_STAT (1 << 12) -#define AVIVO_DxMODE_INT_MASK 0x6540 -# define AVIVO_D1MODE_INT_MASK (1 << 0) -# define AVIVO_D2MODE_INT_MASK (1 << 8) -#define AVIVO_D1MODE_VIEWPORT_START 0x6580 -#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 -#define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588 -#define AVIVO_D1MODE_EXT_OVERSCAN_TOP_BOTTOM 0x658c - -#define AVIVO_D1SCL_SCALER_ENABLE 0x6590 -#define AVIVO_D1SCL_SCALER_TAP_CONTROL 0x6594 -#define AVIVO_D1SCL_UPDATE 0x65cc -# define AVIVO_D1SCL_UPDATE_LOCK (1 << 16) - -/* second crtc */ -#define AVIVO_D2CRTC_H_TOTAL 0x6800 -#define AVIVO_D2CRTC_H_BLANK_START_END 0x6804 -#define AVIVO_D2CRTC_H_SYNC_A 0x6808 -#define AVIVO_D2CRTC_H_SYNC_A_CNTL 0x680c -#define AVIVO_D2CRTC_H_SYNC_B 0x6810 -#define AVIVO_D2CRTC_H_SYNC_B_CNTL 0x6814 - -#define AVIVO_D2CRTC_V_TOTAL 0x6820 -#define AVIVO_D2CRTC_V_BLANK_START_END 0x6824 -#define AVIVO_D2CRTC_V_SYNC_A 0x6828 -#define AVIVO_D2CRTC_V_SYNC_A_CNTL 0x682c -#define AVIVO_D2CRTC_V_SYNC_B 0x6830 -#define AVIVO_D2CRTC_V_SYNC_B_CNTL 0x6834 - -#define AVIVO_D2CRTC_CONTROL 0x6880 -#define AVIVO_D2CRTC_BLANK_CONTROL 0x6884 -#define AVIVO_D2CRTC_INTERLACE_CONTROL 0x6888 -#define AVIVO_D2CRTC_INTERLACE_STATUS 0x688c -#define AVIVO_D2CRTC_STATUS_POSITION 0x68a0 -#define AVIVO_D2CRTC_FRAME_COUNT 0x68a4 -#define AVIVO_D2CRTC_STEREO_CONTROL 0x68c4 - -#define AVIVO_D2GRPH_ENABLE 0x6900 -#define AVIVO_D2GRPH_CONTROL 0x6904 -#define AVIVO_D2GRPH_LUT_SEL 0x6908 -#define AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910 -#define AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918 -#define AVIVO_D2GRPH_PITCH 0x6920 -#define AVIVO_D2GRPH_SURFACE_OFFSET_X 0x6924 -#define AVIVO_D2GRPH_SURFACE_OFFSET_Y 0x6928 -#define AVIVO_D2GRPH_X_START 0x692c -#define AVIVO_D2GRPH_Y_START 0x6930 -#define AVIVO_D2GRPH_X_END 0x6934 -#define AVIVO_D2GRPH_Y_END 0x6938 -#define AVIVO_D2GRPH_UPDATE 0x6944 -#define AVIVO_D2GRPH_FLIP_CONTROL 0x6948 - -#define AVIVO_D2CUR_CONTROL 0x6c00 -#define AVIVO_D2CUR_SURFACE_ADDRESS 0x6c08 -#define AVIVO_D2CUR_SIZE 0x6c10 -#define AVIVO_D2CUR_POSITION 0x6c14 - -#define AVIVO_D2MODE_VBLANK_STATUS 0x6d34 -#define AVIVO_D2MODE_VLINE_START_END 0x6d38 -#define AVIVO_D2MODE_VLINE_STATUS 0x6d3c -#define AVIVO_D2MODE_VIEWPORT_START 0x6d80 -#define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 -#define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88 -#define AVIVO_D2MODE_EXT_OVERSCAN_TOP_BOTTOM 0x6d8c - -#define AVIVO_D2SCL_SCALER_ENABLE 0x6d90 -#define AVIVO_D2SCL_SCALER_TAP_CONTROL 0x6d94 - -#define AVIVO_DDIA_BIT_DEPTH_CONTROL 0x7214 - -#define AVIVO_DACA_ENABLE 0x7800 -# define AVIVO_DAC_ENABLE (1 << 0) -#define AVIVO_DACA_SOURCE_SELECT 0x7804 -# define AVIVO_DAC_SOURCE_CRTC1 (0 << 0) -# define AVIVO_DAC_SOURCE_CRTC2 (1 << 0) -# define AVIVO_DAC_SOURCE_TV (2 << 0) - -#define AVIVO_DACA_FORCE_OUTPUT_CNTL 0x783c -# define AVIVO_DACA_FORCE_OUTPUT_CNTL_FORCE_DATA_EN (1 << 0) -# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_SHIFT (8) -# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_BLUE (1 << 0) -# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_GREEN (1 << 1) -# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_SEL_RED (1 << 2) -# define AVIVO_DACA_FORCE_OUTPUT_CNTL_DATA_ON_BLANKB_ONLY (1 << 24) -#define AVIVO_DACA_POWERDOWN 0x7850 -# define AVIVO_DACA_POWERDOWN_POWERDOWN (1 << 0) -# define AVIVO_DACA_POWERDOWN_BLUE (1 << 8) -# define AVIVO_DACA_POWERDOWN_GREEN (1 << 16) -# define AVIVO_DACA_POWERDOWN_RED (1 << 24) - -#define AVIVO_DACB_ENABLE 0x7a00 -#define AVIVO_DACB_SOURCE_SELECT 0x7a04 -#define AVIVO_DACB_FORCE_OUTPUT_CNTL 0x7a3c -# define AVIVO_DACB_FORCE_OUTPUT_CNTL_FORCE_DATA_EN (1 << 0) -# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_SHIFT (8) -# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_BLUE (1 << 0) -# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_GREEN (1 << 1) -# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_SEL_RED (1 << 2) -# define AVIVO_DACB_FORCE_OUTPUT_CNTL_DATA_ON_BLANKB_ONLY (1 << 24) -#define AVIVO_DACB_POWERDOWN 0x7a50 -# define AVIVO_DACB_POWERDOWN_POWERDOWN (1 << 0) -# define AVIVO_DACB_POWERDOWN_BLUE (1 << 8) -# define AVIVO_DACB_POWERDOWN_GREEN (1 << 16) -# define AVIVO_DACB_POWERDOWN_RED - -#define AVIVO_TMDSA_CNTL 0x7880 -# define AVIVO_TMDSA_CNTL_ENABLE (1 << 0) -# define AVIVO_TMDSA_CNTL_HDMI_EN (1 << 2) -# define AVIVO_TMDSA_CNTL_HPD_MASK (1 << 4) -# define AVIVO_TMDSA_CNTL_HPD_SELECT (1 << 8) -# define AVIVO_TMDSA_CNTL_SYNC_PHASE (1 << 12) -# define AVIVO_TMDSA_CNTL_PIXEL_ENCODING (1 << 16) -# define AVIVO_TMDSA_CNTL_DUAL_LINK_ENABLE (1 << 24) -# define AVIVO_TMDSA_CNTL_SWAP (1 << 28) -#define AVIVO_TMDSA_SOURCE_SELECT 0x7884 -/* 78a8 appears to be some kind of (reasonably tolerant) clock? - * 78d0 definitely hits the transmitter, definitely clock. */ -/* MYSTERY1 This appears to control dithering? */ -#define AVIVO_TMDSA_BIT_DEPTH_CONTROL 0x7894 -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_EN (1 << 0) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH (1 << 4) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN (1 << 8) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH (1 << 12) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_EN (1 << 16) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_DEPTH (1 << 20) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_LEVEL (1 << 24) -# define AVIVO_TMDS_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_RESET (1 << 26) -#define AVIVO_TMDSA_DCBALANCER_CONTROL 0x78d0 -# define AVIVO_TMDSA_DCBALANCER_CONTROL_EN (1 << 0) -# define AVIVO_TMDSA_DCBALANCER_CONTROL_TEST_EN (1 << 8) -# define AVIVO_TMDSA_DCBALANCER_CONTROL_TEST_IN_SHIFT (16) -# define AVIVO_TMDSA_DCBALANCER_CONTROL_FORCE (1 << 24) -#define AVIVO_TMDSA_DATA_SYNCHRONIZATION 0x78d8 -# define AVIVO_TMDSA_DATA_SYNCHRONIZATION_DSYNSEL (1 << 0) -# define AVIVO_TMDSA_DATA_SYNCHRONIZATION_PFREQCHG (1 << 8) -#define AVIVO_TMDSA_CLOCK_ENABLE 0x7900 -#define AVIVO_TMDSA_TRANSMITTER_ENABLE 0x7904 -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX0_ENABLE (1 << 0) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKC0EN (1 << 1) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD00EN (1 << 2) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD01EN (1 << 3) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD02EN (1 << 4) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX1_ENABLE (1 << 8) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD10EN (1 << 10) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD11EN (1 << 11) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKD12EN (1 << 12) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_TX_ENABLE_HPD_MASK (1 << 16) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKCEN_HPD_MASK (1 << 17) -# define AVIVO_TMDSA_TRANSMITTER_ENABLE_LNKDEN_HPD_MASK (1 << 18) - -#define AVIVO_TMDSA_TRANSMITTER_CONTROL 0x7910 -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_ENABLE (1 << 0) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_RESET (1 << 1) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_HPD_MASK_SHIFT (2) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_IDSCKSEL (1 << 4) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_BGSLEEP (1 << 5) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_PLL_PWRUP_SEQ_EN (1 << 6) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TMCLK (1 << 8) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TMCLK_FROM_PADS (1 << 13) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TDCLK (1 << 14) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_TDCLK_FROM_PADS (1 << 15) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_CLK_PATTERN_SHIFT (16) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_BYPASS_PLL (1 << 28) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_USE_CLK_DATA (1 << 29) -# define AVIVO_TMDSA_TRANSMITTER_CONTROL_INPUT_TEST_CLK_SEL (1 << 31) - -#define AVIVO_LVTMA_CNTL 0x7a80 -# define AVIVO_LVTMA_CNTL_ENABLE (1 << 0) -# define AVIVO_LVTMA_CNTL_HDMI_EN (1 << 2) -# define AVIVO_LVTMA_CNTL_HPD_MASK (1 << 4) -# define AVIVO_LVTMA_CNTL_HPD_SELECT (1 << 8) -# define AVIVO_LVTMA_CNTL_SYNC_PHASE (1 << 12) -# define AVIVO_LVTMA_CNTL_PIXEL_ENCODING (1 << 16) -# define AVIVO_LVTMA_CNTL_DUAL_LINK_ENABLE (1 << 24) -# define AVIVO_LVTMA_CNTL_SWAP (1 << 28) -#define AVIVO_LVTMA_SOURCE_SELECT 0x7a84 -#define AVIVO_LVTMA_COLOR_FORMAT 0x7a88 -#define AVIVO_LVTMA_BIT_DEPTH_CONTROL 0x7a94 -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_EN (1 << 0) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TRUNCATE_DEPTH (1 << 4) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_EN (1 << 8) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_SPATIAL_DITHER_DEPTH (1 << 12) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_EN (1 << 16) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_DEPTH (1 << 20) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_LEVEL (1 << 24) -# define AVIVO_LVTMA_BIT_DEPTH_CONTROL_TEMPORAL_DITHER_RESET (1 << 26) - - - -#define AVIVO_LVTMA_DCBALANCER_CONTROL 0x7ad0 -# define AVIVO_LVTMA_DCBALANCER_CONTROL_EN (1 << 0) -# define AVIVO_LVTMA_DCBALANCER_CONTROL_TEST_EN (1 << 8) -# define AVIVO_LVTMA_DCBALANCER_CONTROL_TEST_IN_SHIFT (16) -# define AVIVO_LVTMA_DCBALANCER_CONTROL_FORCE (1 << 24) - -#define AVIVO_LVTMA_DATA_SYNCHRONIZATION 0x78d8 -# define AVIVO_LVTMA_DATA_SYNCHRONIZATION_DSYNSEL (1 << 0) -# define AVIVO_LVTMA_DATA_SYNCHRONIZATION_PFREQCHG (1 << 8) -#define R500_LVTMA_CLOCK_ENABLE 0x7b00 -#define R600_LVTMA_CLOCK_ENABLE 0x7b04 - -#define R500_LVTMA_TRANSMITTER_ENABLE 0x7b04 -#define R600_LVTMA_TRANSMITTER_ENABLE 0x7b08 -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKC0EN (1 << 1) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD00EN (1 << 2) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD01EN (1 << 3) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD02EN (1 << 4) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD03EN (1 << 5) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKC1EN (1 << 9) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD10EN (1 << 10) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD11EN (1 << 11) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKD12EN (1 << 12) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKCEN_HPD_MASK (1 << 17) -# define AVIVO_LVTMA_TRANSMITTER_ENABLE_LNKDEN_HPD_MASK (1 << 18) - -#define R500_LVTMA_TRANSMITTER_CONTROL 0x7b10 -#define R600_LVTMA_TRANSMITTER_CONTROL 0x7b14 -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_ENABLE (1 << 0) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_RESET (1 << 1) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_HPD_MASK_SHIFT (2) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_IDSCKSEL (1 << 4) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_BGSLEEP (1 << 5) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_PLL_PWRUP_SEQ_EN (1 << 6) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TMCLK (1 << 8) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TMCLK_FROM_PADS (1 << 13) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TDCLK (1 << 14) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_TDCLK_FROM_PADS (1 << 15) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_CLK_PATTERN_SHIFT (16) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_BYPASS_PLL (1 << 28) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_USE_CLK_DATA (1 << 29) -# define AVIVO_LVTMA_TRANSMITTER_CONTROL_INPUT_TEST_CLK_SEL (1 << 31) - -#define R500_LVTMA_PWRSEQ_CNTL 0x7af0 -#define R600_LVTMA_PWRSEQ_CNTL 0x7af4 -# define AVIVO_LVTMA_PWRSEQ_EN (1 << 0) -# define AVIVO_LVTMA_PWRSEQ_PLL_ENABLE_MASK (1 << 2) -# define AVIVO_LVTMA_PWRSEQ_PLL_RESET_MASK (1 << 3) -# define AVIVO_LVTMA_PWRSEQ_TARGET_STATE (1 << 4) -# define AVIVO_LVTMA_SYNCEN (1 << 8) -# define AVIVO_LVTMA_SYNCEN_OVRD (1 << 9) -# define AVIVO_LVTMA_SYNCEN_POL (1 << 10) -# define AVIVO_LVTMA_DIGON (1 << 16) -# define AVIVO_LVTMA_DIGON_OVRD (1 << 17) -# define AVIVO_LVTMA_DIGON_POL (1 << 18) -# define AVIVO_LVTMA_BLON (1 << 24) -# define AVIVO_LVTMA_BLON_OVRD (1 << 25) -# define AVIVO_LVTMA_BLON_POL (1 << 26) - -#define R500_LVTMA_PWRSEQ_STATE 0x7af4 -#define R600_LVTMA_PWRSEQ_STATE 0x7af8 -# define AVIVO_LVTMA_PWRSEQ_STATE_TARGET_STATE_R (1 << 0) -# define AVIVO_LVTMA_PWRSEQ_STATE_DIGON (1 << 1) -# define AVIVO_LVTMA_PWRSEQ_STATE_SYNCEN (1 << 2) -# define AVIVO_LVTMA_PWRSEQ_STATE_BLON (1 << 3) -# define AVIVO_LVTMA_PWRSEQ_STATE_DONE (1 << 4) -# define AVIVO_LVTMA_PWRSEQ_STATE_STATUS_SHIFT (8) - -#define AVIVO_LVDS_BACKLIGHT_CNTL 0x7af8 -# define AVIVO_LVDS_BACKLIGHT_CNTL_EN (1 << 0) -# define AVIVO_LVDS_BACKLIGHT_LEVEL_MASK 0x0000ff00 -# define AVIVO_LVDS_BACKLIGHT_LEVEL_SHIFT 8 - -#define AVIVO_DVOA_BIT_DEPTH_CONTROL 0x7988 - -#define AVIVO_DC_GPIO_HPD_A 0x7e94 -#define AVIVO_DC_GPIO_HPD_Y 0x7e9c - -#define AVIVO_DC_I2C_STATUS1 0x7d30 -# define AVIVO_DC_I2C_DONE (1 << 0) -# define AVIVO_DC_I2C_NACK (1 << 1) -# define AVIVO_DC_I2C_HALT (1 << 2) -# define AVIVO_DC_I2C_GO (1 << 3) -#define AVIVO_DC_I2C_RESET 0x7d34 -# define AVIVO_DC_I2C_SOFT_RESET (1 << 0) -# define AVIVO_DC_I2C_ABORT (1 << 8) -#define AVIVO_DC_I2C_CONTROL1 0x7d38 -# define AVIVO_DC_I2C_START (1 << 0) -# define AVIVO_DC_I2C_STOP (1 << 1) -# define AVIVO_DC_I2C_RECEIVE (1 << 2) -# define AVIVO_DC_I2C_EN (1 << 8) -# define AVIVO_DC_I2C_PIN_SELECT(x) ((x) << 16) -# define AVIVO_SEL_DDC1 0 -# define AVIVO_SEL_DDC2 1 -# define AVIVO_SEL_DDC3 2 -#define AVIVO_DC_I2C_CONTROL2 0x7d3c -# define AVIVO_DC_I2C_ADDR_COUNT(x) ((x) << 0) -# define AVIVO_DC_I2C_DATA_COUNT(x) ((x) << 8) -#define AVIVO_DC_I2C_CONTROL3 0x7d40 -# define AVIVO_DC_I2C_DATA_DRIVE_EN (1 << 0) -# define AVIVO_DC_I2C_DATA_DRIVE_SEL (1 << 1) -# define AVIVO_DC_I2C_CLK_DRIVE_EN (1 << 7) -# define AVIVO_DC_I2C_RD_INTRA_BYTE_DELAY(x) ((x) << 8) -# define AVIVO_DC_I2C_WR_INTRA_BYTE_DELAY(x) ((x) << 16) -# define AVIVO_DC_I2C_TIME_LIMIT(x) ((x) << 24) -#define AVIVO_DC_I2C_DATA 0x7d44 -#define AVIVO_DC_I2C_INTERRUPT_CONTROL 0x7d48 -# define AVIVO_DC_I2C_INTERRUPT_STATUS (1 << 0) -# define AVIVO_DC_I2C_INTERRUPT_AK (1 << 8) -# define AVIVO_DC_I2C_INTERRUPT_ENABLE (1 << 16) -#define AVIVO_DC_I2C_ARBITRATION 0x7d50 -# define AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C (1 << 0) -# define AVIVO_DC_I2C_SW_CAN_USE_I2C (1 << 1) -# define AVIVO_DC_I2C_SW_DONE_USING_I2C (1 << 8) -# define AVIVO_DC_I2C_HW_NEEDS_I2C (1 << 9) -# define AVIVO_DC_I2C_ABORT_HDCP_I2C (1 << 16) -# define AVIVO_DC_I2C_HW_USING_I2C (1 << 17) - -#define AVIVO_DC_GPIO_DDC1_MASK 0x7e40 -#define AVIVO_DC_GPIO_DDC1_A 0x7e44 -#define AVIVO_DC_GPIO_DDC1_EN 0x7e48 -#define AVIVO_DC_GPIO_DDC1_Y 0x7e4c - -#define AVIVO_DC_GPIO_DDC2_MASK 0x7e50 -#define AVIVO_DC_GPIO_DDC2_A 0x7e54 -#define AVIVO_DC_GPIO_DDC2_EN 0x7e58 -#define AVIVO_DC_GPIO_DDC2_Y 0x7e5c - -#define AVIVO_DC_GPIO_DDC3_MASK 0x7e60 -#define AVIVO_DC_GPIO_DDC3_A 0x7e64 -#define AVIVO_DC_GPIO_DDC3_EN 0x7e68 -#define AVIVO_DC_GPIO_DDC3_Y 0x7e6c - -#define AVIVO_DISP_INTERRUPT_STATUS 0x7edc -# define AVIVO_D1_VBLANK_INTERRUPT (1 << 4) -# define AVIVO_D2_VBLANK_INTERRUPT (1 << 5) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r520.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r520.c deleted file mode 100644 index ebcc15b0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r520.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" -#include "r520d.h" - -/* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */ - -int r520_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32_MC(R520_MC_STATUS); - if (tmp & R520_MC_STATUS_IDLE) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -static void r520_gpu_init(struct radeon_device *rdev) -{ - unsigned pipe_select_current, gb_pipe_select, tmp; - - rv515_vga_render_disable(rdev); - /* - * DST_PIPE_CONFIG 0x170C - * GB_TILE_CONFIG 0x4018 - * GB_FIFO_SIZE 0x4024 - * GB_PIPE_SELECT 0x402C - * GB_PIPE_SELECT2 0x4124 - * Z_PIPE_SHIFT 0 - * Z_PIPE_MASK 0x000000003 - * GB_FIFO_SIZE2 0x4128 - * SC_SFIFO_SIZE_SHIFT 0 - * SC_SFIFO_SIZE_MASK 0x000000003 - * SC_MFIFO_SIZE_SHIFT 2 - * SC_MFIFO_SIZE_MASK 0x00000000C - * FG_SFIFO_SIZE_SHIFT 4 - * FG_SFIFO_SIZE_MASK 0x000000030 - * ZB_MFIFO_SIZE_SHIFT 6 - * ZB_MFIFO_SIZE_MASK 0x0000000C0 - * GA_ENHANCE 0x4274 - * SU_REG_DEST 0x42C8 - */ - /* workaround for RV530 */ - if (rdev->family == CHIP_RV530) { - WREG32(0x4128, 0xFF); - } - r420_pipes_init(rdev); - gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); - tmp = RREG32(R300_DST_PIPE_CONFIG); - pipe_select_current = (tmp >> 2) & 3; - tmp = (1 << pipe_select_current) | - (((gb_pipe_select >> 8) & 0xF) << 4); - WREG32_PLL(0x000D, tmp); - if (r520_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait MC idle while " - "programming pipes. Bad things might happen.\n"); - } -} - -static void r520_vram_get_type(struct radeon_device *rdev) -{ - uint32_t tmp; - - rdev->mc.vram_width = 128; - rdev->mc.vram_is_ddr = true; - tmp = RREG32_MC(R520_MC_CNTL0); - switch ((tmp & R520_MEM_NUM_CHANNELS_MASK) >> R520_MEM_NUM_CHANNELS_SHIFT) { - case 0: - rdev->mc.vram_width = 32; - break; - case 1: - rdev->mc.vram_width = 64; - break; - case 2: - rdev->mc.vram_width = 128; - break; - case 3: - rdev->mc.vram_width = 256; - break; - default: - rdev->mc.vram_width = 128; - break; - } - if (tmp & R520_MC_CHANNEL_SIZE) - rdev->mc.vram_width *= 2; -} - -void r520_mc_init(struct radeon_device *rdev) -{ - - r520_vram_get_type(rdev); - r100_vram_init_sizes(rdev); - radeon_vram_location(rdev, &rdev->mc, 0); - rdev->mc.gtt_base_align = 0; - if (!(rdev->flags & RADEON_IS_AGP)) - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - -void r520_mc_program(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - - /* Stops all mc clients */ - rv515_mc_stop(rdev, &save); - - /* Wait for mc idle */ - if (r520_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); - /* Write VRAM size in case we are limiting it */ - WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); - /* Program MC, should be a 32bits limited address space */ - WREG32_MC(R_000004_MC_FB_LOCATION, - S_000004_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16)); - WREG32(R_000134_HDP_FB_LOCATION, - S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); - if (rdev->flags & RADEON_IS_AGP) { - WREG32_MC(R_000005_MC_AGP_LOCATION, - S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) | - S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); - WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); - WREG32_MC(R_000007_AGP_BASE_2, - S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); - } else { - WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF); - WREG32_MC(R_000006_AGP_BASE, 0); - WREG32_MC(R_000007_AGP_BASE_2, 0); - } - - rv515_mc_resume(rdev, &save); -} - -static int r520_startup(struct radeon_device *rdev) -{ - int r; - - r520_mc_program(rdev); - /* Resume clock */ - rv515_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ - r520_gpu_init(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - if (rdev->flags & RADEON_IS_PCIE) { - r = rv370_pcie_gart_enable(rdev); - if (r) - return r; - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - rs600_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - return 0; -} - -int r520_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - /* Resume clock before doing reset */ - rv515_clock_startup(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - atom_asic_init(rdev->mode_info.atom_context); - /* Resume clock after posting */ - rv515_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = r520_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int r520_init(struct radeon_device *rdev) -{ - int r; - - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* TODO: disable VGA need to use VGA request */ - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - r = radeon_atombios_init(rdev); - if (r) - return r; - } else { - dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); - return -EINVAL; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - - if (!radeon_card_posted(rdev) && rdev->bios) { - DRM_INFO("GPU not posted. posting now...\n"); - atom_asic_init(rdev->mode_info.atom_context); - } - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } - } - /* initialize memory controller */ - r520_mc_init(rdev); - rv515_debugfs(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - r = rv370_pcie_gart_init(rdev); - if (r) - return r; - rv515_set_safe_registers(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = r520_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - rv370_pcie_gart_fini(rdev); - radeon_agp_fini(rdev); - rdev->accel_working = false; - } - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r520d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r520d.h deleted file mode 100644 index 61af61f6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r520d.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __R520D_H__ -#define __R520D_H__ - -/* Registers */ -#define R_0000F8_CONFIG_MEMSIZE 0x0000F8 -#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_0000F8_CONFIG_MEMSIZE 0x00000000 -#define R_000134_HDP_FB_LOCATION 0x000134 -#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000134_HDP_FB_START 0xFFFF0000 -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_RBBM_HIBUSY(x) (((x) & 0x1) << 28) -#define G_000E40_RBBM_HIBUSY(x) (((x) >> 28) & 0x1) -#define C_000E40_RBBM_HIBUSY 0xEFFFFFFF -#define S_000E40_SKID_CFBUSY(x) (((x) & 0x1) << 29) -#define G_000E40_SKID_CFBUSY(x) (((x) >> 29) & 0x1) -#define C_000E40_SKID_CFBUSY 0xDFFFFFFF -#define S_000E40_VAP_VF_BUSY(x) (((x) & 0x1) << 30) -#define G_000E40_VAP_VF_BUSY(x) (((x) >> 30) & 0x1) -#define C_000E40_VAP_VF_BUSY 0xBFFFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF - - -#define R_000004_MC_FB_LOCATION 0x000004 -#define S_000004_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000004_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000004_MC_FB_START 0xFFFF0000 -#define S_000004_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000004_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000004_MC_FB_TOP 0x0000FFFF -#define R_000005_MC_AGP_LOCATION 0x000005 -#define S_000005_MC_AGP_START(x) (((x) & 0xFFFF) << 0) -#define G_000005_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) -#define C_000005_MC_AGP_START 0xFFFF0000 -#define S_000005_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000005_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000005_MC_AGP_TOP 0x0000FFFF -#define R_000006_AGP_BASE 0x000006 -#define S_000006_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000006_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000006_AGP_BASE_ADDR 0x00000000 -#define R_000007_AGP_BASE_2 0x000007 -#define S_000007_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) -#define G_000007_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) -#define C_000007_AGP_BASE_ADDR_2 0xFFFFFFF0 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600.c deleted file mode 100644 index b1ff9ccd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600.c +++ /dev/null @@ -1,3799 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include -#include -#include -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "radeon_mode.h" -#include "r600d.h" -#include "atom.h" -#include "avivod.h" - -#define PFP_UCODE_SIZE 576 -#define PM4_UCODE_SIZE 1792 -#define RLC_UCODE_SIZE 768 -#define R700_PFP_UCODE_SIZE 848 -#define R700_PM4_UCODE_SIZE 1360 -#define R700_RLC_UCODE_SIZE 1024 -#define EVERGREEN_PFP_UCODE_SIZE 1120 -#define EVERGREEN_PM4_UCODE_SIZE 1376 -#define EVERGREEN_RLC_UCODE_SIZE 768 -#define CAYMAN_RLC_UCODE_SIZE 1024 -#define ARUBA_RLC_UCODE_SIZE 1536 - -/* Firmware Names */ -MODULE_FIRMWARE("radeon/R600_pfp.bin"); -MODULE_FIRMWARE("radeon/R600_me.bin"); -MODULE_FIRMWARE("radeon/RV610_pfp.bin"); -MODULE_FIRMWARE("radeon/RV610_me.bin"); -MODULE_FIRMWARE("radeon/RV630_pfp.bin"); -MODULE_FIRMWARE("radeon/RV630_me.bin"); -MODULE_FIRMWARE("radeon/RV620_pfp.bin"); -MODULE_FIRMWARE("radeon/RV620_me.bin"); -MODULE_FIRMWARE("radeon/RV635_pfp.bin"); -MODULE_FIRMWARE("radeon/RV635_me.bin"); -MODULE_FIRMWARE("radeon/RV670_pfp.bin"); -MODULE_FIRMWARE("radeon/RV670_me.bin"); -MODULE_FIRMWARE("radeon/RS780_pfp.bin"); -MODULE_FIRMWARE("radeon/RS780_me.bin"); -MODULE_FIRMWARE("radeon/RV770_pfp.bin"); -MODULE_FIRMWARE("radeon/RV770_me.bin"); -MODULE_FIRMWARE("radeon/RV730_pfp.bin"); -MODULE_FIRMWARE("radeon/RV730_me.bin"); -MODULE_FIRMWARE("radeon/RV710_pfp.bin"); -MODULE_FIRMWARE("radeon/RV710_me.bin"); -MODULE_FIRMWARE("radeon/R600_rlc.bin"); -MODULE_FIRMWARE("radeon/R700_rlc.bin"); -MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); -MODULE_FIRMWARE("radeon/CEDAR_me.bin"); -MODULE_FIRMWARE("radeon/CEDAR_rlc.bin"); -MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin"); -MODULE_FIRMWARE("radeon/REDWOOD_me.bin"); -MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin"); -MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin"); -MODULE_FIRMWARE("radeon/JUNIPER_me.bin"); -MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); -MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); -MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); -MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); -MODULE_FIRMWARE("radeon/PALM_pfp.bin"); -MODULE_FIRMWARE("radeon/PALM_me.bin"); -MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); -MODULE_FIRMWARE("radeon/SUMO_pfp.bin"); -MODULE_FIRMWARE("radeon/SUMO_me.bin"); -MODULE_FIRMWARE("radeon/SUMO2_pfp.bin"); -MODULE_FIRMWARE("radeon/SUMO2_me.bin"); - -int r600_debugfs_mc_info_init(struct radeon_device *rdev); - -/* r600,rv610,rv630,rv620,rv635,rv670 */ -int r600_mc_wait_for_idle(struct radeon_device *rdev); -void r600_gpu_init(struct radeon_device *rdev); -void r600_fini(struct radeon_device *rdev); -void r600_irq_disable(struct radeon_device *rdev); -static void r600_pcie_gen2_enable(struct radeon_device *rdev); - -/* get temperature in millidegrees */ -int rv6xx_get_temp(struct radeon_device *rdev) -{ - u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> - ASIC_T_SHIFT; - int actual_temp = temp & 0xff; - - if (temp & 0x100) - actual_temp -= 256; - - return actual_temp * 1000; -} - -void r600_pm_get_dynpm_state(struct radeon_device *rdev) -{ - int i; - - rdev->pm.dynpm_can_upclock = true; - rdev->pm.dynpm_can_downclock = true; - - /* power state array is low to high, default is first */ - if ((rdev->flags & RADEON_IS_IGP) || (rdev->family == CHIP_R600)) { - int min_power_state_index = 0; - - if (rdev->pm.num_power_states > 2) - min_power_state_index = 1; - - switch (rdev->pm.dynpm_planned_action) { - case DYNPM_ACTION_MINIMUM: - rdev->pm.requested_power_state_index = min_power_state_index; - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - break; - case DYNPM_ACTION_DOWNCLOCK: - if (rdev->pm.current_power_state_index == min_power_state_index) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_downclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = 0; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i >= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else { - if (rdev->pm.current_power_state_index == 0) - rdev->pm.requested_power_state_index = - rdev->pm.num_power_states - 1; - else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index - 1; - } - } - rdev->pm.requested_clock_mode_index = 0; - /* don't use the power state if crtcs are active and no display flag is set */ - if ((rdev->pm.active_crtc_count > 0) && - (rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].flags & - RADEON_PM_MODE_NO_DISPLAY)) { - rdev->pm.requested_power_state_index++; - } - break; - case DYNPM_ACTION_UPCLOCK: - if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) { - rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index; - rdev->pm.dynpm_can_upclock = false; - } else { - if (rdev->pm.active_crtc_count > 1) { - for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if (i <= rdev->pm.current_power_state_index) { - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index; - break; - } else { - rdev->pm.requested_power_state_index = i; - break; - } - } - } else - rdev->pm.requested_power_state_index = - rdev->pm.current_power_state_index + 1; - } - rdev->pm.requested_clock_mode_index = 0; - break; - case DYNPM_ACTION_DEFAULT: - rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_upclock = false; - break; - case DYNPM_ACTION_NONE: - default: - DRM_ERROR("Requested mode for not defined action\n"); - return; - } - } else { - /* XXX select a power state based on AC/DC, single/dualhead, etc. */ - /* for now just select the first power state and switch between clock modes */ - /* power state array is low to high, default is first (0) */ - if (rdev->pm.active_crtc_count > 1) { - rdev->pm.requested_power_state_index = -1; - /* start at 1 as we don't want the default mode */ - for (i = 1; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - continue; - else if ((rdev->pm.power_state[i].type == POWER_STATE_TYPE_PERFORMANCE) || - (rdev->pm.power_state[i].type == POWER_STATE_TYPE_BATTERY)) { - rdev->pm.requested_power_state_index = i; - break; - } - } - /* if nothing selected, grab the default state. */ - if (rdev->pm.requested_power_state_index == -1) - rdev->pm.requested_power_state_index = 0; - } else - rdev->pm.requested_power_state_index = 1; - - switch (rdev->pm.dynpm_planned_action) { - case DYNPM_ACTION_MINIMUM: - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - break; - case DYNPM_ACTION_DOWNCLOCK: - if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) { - if (rdev->pm.current_clock_mode_index == 0) { - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - } else - rdev->pm.requested_clock_mode_index = - rdev->pm.current_clock_mode_index - 1; - } else { - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_downclock = false; - } - /* don't use the power state if crtcs are active and no display flag is set */ - if ((rdev->pm.active_crtc_count > 0) && - (rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].flags & - RADEON_PM_MODE_NO_DISPLAY)) { - rdev->pm.requested_clock_mode_index++; - } - break; - case DYNPM_ACTION_UPCLOCK: - if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) { - if (rdev->pm.current_clock_mode_index == - (rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1)) { - rdev->pm.requested_clock_mode_index = rdev->pm.current_clock_mode_index; - rdev->pm.dynpm_can_upclock = false; - } else - rdev->pm.requested_clock_mode_index = - rdev->pm.current_clock_mode_index + 1; - } else { - rdev->pm.requested_clock_mode_index = - rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1; - rdev->pm.dynpm_can_upclock = false; - } - break; - case DYNPM_ACTION_DEFAULT: - rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.requested_clock_mode_index = 0; - rdev->pm.dynpm_can_upclock = false; - break; - case DYNPM_ACTION_NONE: - default: - DRM_ERROR("Requested mode for not defined action\n"); - return; - } - } - - DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d\n", - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].sclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].mclk, - rdev->pm.power_state[rdev->pm.requested_power_state_index]. - pcie_lanes); -} - -void rs780_pm_init_profile(struct radeon_device *rdev) -{ - if (rdev->pm.num_power_states == 2) { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } else if (rdev->pm.num_power_states == 3) { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } else { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 3; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 3; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } -} - -void r600_pm_init_profile(struct radeon_device *rdev) -{ - int idx; - - if (rdev->family == CHIP_R600) { - /* XXX */ - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0; - } else { - if (rdev->pm.num_power_states < 4) { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; - /* low sh */ - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; - /* high sh */ - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* low mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; - /* high mh */ - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; - } else { - /* default */ - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; - /* low sh */ - if (rdev->flags & RADEON_IS_MOBILITY) - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); - else - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; - /* mid sh */ - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; - /* high sh */ - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; - /* low mh */ - if (rdev->flags & RADEON_IS_MOBILITY) - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); - else - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; - /* mid mh */ - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; - /* high mh */ - idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; - rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; - } - } -} - -void r600_pm_misc(struct radeon_device *rdev) -{ - int req_ps_idx = rdev->pm.requested_power_state_index; - int req_cm_idx = rdev->pm.requested_clock_mode_index; - struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { - /* 0xff01 is a flag rather then an actual voltage */ - if (voltage->voltage == 0xff01) - return; - if (voltage->voltage != rdev->pm.current_vddc) { - radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); - } - } -} - -bool r600_gui_idle(struct radeon_device *rdev) -{ - if (RREG32(GRBM_STATUS) & GUI_ACTIVE) - return false; - else - return true; -} - -/* hpd for digital panel detect/disconnect */ -bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) -{ - bool connected = false; - - if (ASIC_IS_DCE3(rdev)) { - switch (hpd) { - case RADEON_HPD_1: - if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_2: - if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_3: - if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_4: - if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - /* DCE 3.2 */ - case RADEON_HPD_5: - if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - case RADEON_HPD_6: - if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) - connected = true; - break; - default: - break; - } - } else { - switch (hpd) { - case RADEON_HPD_1: - if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) - connected = true; - break; - case RADEON_HPD_2: - if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) - connected = true; - break; - case RADEON_HPD_3: - if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) - connected = true; - break; - default: - break; - } - } - return connected; -} - -void r600_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd) -{ - u32 tmp; - bool connected = r600_hpd_sense(rdev, hpd); - - if (ASIC_IS_DCE3(rdev)) { - switch (hpd) { - case RADEON_HPD_1: - tmp = RREG32(DC_HPD1_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD1_INT_CONTROL, tmp); - break; - case RADEON_HPD_2: - tmp = RREG32(DC_HPD2_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD2_INT_CONTROL, tmp); - break; - case RADEON_HPD_3: - tmp = RREG32(DC_HPD3_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD3_INT_CONTROL, tmp); - break; - case RADEON_HPD_4: - tmp = RREG32(DC_HPD4_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD4_INT_CONTROL, tmp); - break; - case RADEON_HPD_5: - tmp = RREG32(DC_HPD5_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, tmp); - break; - /* DCE 3.2 */ - case RADEON_HPD_6: - tmp = RREG32(DC_HPD6_INT_CONTROL); - if (connected) - tmp &= ~DC_HPDx_INT_POLARITY; - else - tmp |= DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, tmp); - break; - default: - break; - } - } else { - switch (hpd) { - case RADEON_HPD_1: - tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); - if (connected) - tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; - else - tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); - break; - case RADEON_HPD_2: - tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); - if (connected) - tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; - else - tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); - break; - case RADEON_HPD_3: - tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); - if (connected) - tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; - else - tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); - break; - default: - break; - } - } -} - -void r600_hpd_init(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - if (ASIC_IS_DCE3(rdev)) { - u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); - if (ASIC_IS_DCE32(rdev)) - tmp |= DC_HPDx_EN; - - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(DC_HPD1_CONTROL, tmp); - rdev->irq.hpd[0] = true; - break; - case RADEON_HPD_2: - WREG32(DC_HPD2_CONTROL, tmp); - rdev->irq.hpd[1] = true; - break; - case RADEON_HPD_3: - WREG32(DC_HPD3_CONTROL, tmp); - rdev->irq.hpd[2] = true; - break; - case RADEON_HPD_4: - WREG32(DC_HPD4_CONTROL, tmp); - rdev->irq.hpd[3] = true; - break; - /* DCE 3.2 */ - case RADEON_HPD_5: - WREG32(DC_HPD5_CONTROL, tmp); - rdev->irq.hpd[4] = true; - break; - case RADEON_HPD_6: - WREG32(DC_HPD6_CONTROL, tmp); - rdev->irq.hpd[5] = true; - break; - default: - break; - } - } else { - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); - rdev->irq.hpd[0] = true; - break; - case RADEON_HPD_2: - WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); - rdev->irq.hpd[1] = true; - break; - case RADEON_HPD_3: - WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); - rdev->irq.hpd[2] = true; - break; - default: - break; - } - } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - } - if (rdev->irq.installed) - r600_irq_set(rdev); -} - -void r600_hpd_fini(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - if (ASIC_IS_DCE3(rdev)) { - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(DC_HPD1_CONTROL, 0); - rdev->irq.hpd[0] = false; - break; - case RADEON_HPD_2: - WREG32(DC_HPD2_CONTROL, 0); - rdev->irq.hpd[1] = false; - break; - case RADEON_HPD_3: - WREG32(DC_HPD3_CONTROL, 0); - rdev->irq.hpd[2] = false; - break; - case RADEON_HPD_4: - WREG32(DC_HPD4_CONTROL, 0); - rdev->irq.hpd[3] = false; - break; - /* DCE 3.2 */ - case RADEON_HPD_5: - WREG32(DC_HPD5_CONTROL, 0); - rdev->irq.hpd[4] = false; - break; - case RADEON_HPD_6: - WREG32(DC_HPD6_CONTROL, 0); - rdev->irq.hpd[5] = false; - break; - default: - break; - } - } - } else { - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); - rdev->irq.hpd[0] = false; - break; - case RADEON_HPD_2: - WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); - rdev->irq.hpd[1] = false; - break; - case RADEON_HPD_3: - WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); - rdev->irq.hpd[2] = false; - break; - default: - break; - } - } - } -} - -/* - * R600 PCIE GART - */ -void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) -{ - unsigned i; - u32 tmp; - - /* flush hdp cache so updates hit vram */ - if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && - !(rdev->flags & RADEON_IS_AGP)) { - void __iomem *ptr = (void *)rdev->gart.ptr; - u32 tmp; - - /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read - * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL - * This seems to cause problems on some AGP cards. Just use the old - * method for them. - */ - WREG32(HDP_DEBUG1, 0); - tmp = readl((void __iomem *)ptr); - } else - WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - - WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); - WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE); - tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT; - if (tmp == 2) { - printk(KERN_WARNING "[drm] r600 flush TLB failed\n"); - return; - } - if (tmp) { - return; - } - udelay(1); - } -} - -int r600_pcie_gart_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.robj) { - WARN(1, "R600 PCIE GART already initialized\n"); - return 0; - } - /* Initialize common gart structure */ - r = radeon_gart_init(rdev); - if (r) - return r; - rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; - return radeon_gart_table_vram_alloc(rdev); -} - -int r600_pcie_gart_enable(struct radeon_device *rdev) -{ - u32 tmp; - int r, i; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); - /* Setup TLB control */ - tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | - ENABLE_WAIT_L2_QUERY; - WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING); - WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); - WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); - WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - for (i = 1; i < 7; i++) - WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - - r600_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void r600_pcie_gart_disable(struct radeon_device *rdev) -{ - u32 tmp; - int i; - - /* Disable all tables */ - for (i = 0; i < 7; i++) - WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - - /* Disable L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); - /* Setup L1 TLB control */ - tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | - ENABLE_WAIT_L2_QUERY; - WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); - radeon_gart_table_vram_unpin(rdev); -} - -void r600_pcie_gart_fini(struct radeon_device *rdev) -{ - radeon_gart_fini(rdev); - r600_pcie_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); -} - -void r600_agp_enable(struct radeon_device *rdev) -{ - u32 tmp; - int i; - - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); - /* Setup TLB control */ - tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | - ENABLE_WAIT_L2_QUERY; - WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING); - WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); - WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); - WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); - for (i = 0; i < 7; i++) - WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); -} - -int r600_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - u32 tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00; - if (!tmp) - return 0; - udelay(1); - } - return -1; -} - -static void r600_mc_program(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - u32 tmp; - int i, j; - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); - - rv515_mc_stop(rdev, &save); - if (r600_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Lockout access through VGA aperture (doesn't exist before R600) */ - WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); - /* Update configuration */ - if (rdev->flags & RADEON_IS_AGP) { - if (rdev->mc.vram_start < rdev->mc.gtt_start) { - /* VRAM before AGP */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.gtt_end >> 12); - } else { - /* VRAM after AGP */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.gtt_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.vram_end >> 12); - } - } else { - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); - } - WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); - tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; - tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); - WREG32(MC_VM_FB_LOCATION, tmp); - WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); - WREG32(HDP_NONSURFACE_INFO, (2 << 7)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); - if (rdev->flags & RADEON_IS_AGP) { - WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22); - WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22); - WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); - } else { - WREG32(MC_VM_AGP_BASE, 0); - WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); - WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); - } - if (r600_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - rv515_mc_resume(rdev, &save); - /* we need to own VRAM, so turn off the VGA renderer here - * to stop it overwriting our objects */ - rv515_vga_render_disable(rdev); -} - -/** - * r600_vram_gtt_location - try to find VRAM & GTT location - * @rdev: radeon device structure holding all necessary informations - * @mc: memory controller structure holding memory informations - * - * Function will place try to place VRAM at same place as in CPU (PCI) - * address space as some GPU seems to have issue when we reprogram at - * different address space. - * - * If there is not enough space to fit the unvisible VRAM after the - * aperture then we limit the VRAM size to the aperture. - * - * If we are using AGP then place VRAM adjacent to AGP aperture are we need - * them to be in one from GPU point of view so that we can program GPU to - * catch access outside them (weird GPU policy see ??). - * - * This function will never fails, worst case are limiting VRAM or GTT. - * - * Note: GTT start, end, size should be initialized before calling this - * function on AGP platform. - */ -static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) -{ - u64 size_bf, size_af; - - if (mc->mc_vram_size > 0xE0000000) { - /* leave room for at least 512M GTT */ - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = 0xE0000000; - mc->mc_vram_size = 0xE0000000; - } - if (rdev->flags & RADEON_IS_AGP) { - size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; - if (size_bf > size_af) { - if (mc->mc_vram_size > size_bf) { - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = size_bf; - mc->mc_vram_size = size_bf; - } - mc->vram_start = mc->gtt_start - mc->mc_vram_size; - } else { - if (mc->mc_vram_size > size_af) { - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = size_af; - mc->mc_vram_size = size_af; - } - mc->vram_start = mc->gtt_end + 1; - } - mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", - mc->mc_vram_size >> 20, mc->vram_start, - mc->vram_end, mc->real_vram_size >> 20); - } else { - u64 base = 0; - if (rdev->flags & RADEON_IS_IGP) { - base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; - base <<= 24; - } - radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; - radeon_gtt_location(rdev, mc); - } -} - -int r600_mc_init(struct radeon_device *rdev) -{ - u32 tmp; - int chansize, numchan; - - /* Get VRAM informations */ - rdev->mc.vram_is_ddr = true; - tmp = RREG32(RAMCFG); - if (tmp & CHANSIZE_OVERRIDE) { - chansize = 16; - } else if (tmp & CHANSIZE_MASK) { - chansize = 64; - } else { - chansize = 32; - } - tmp = RREG32(CHMAP); - switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { - case 0: - default: - numchan = 1; - break; - case 1: - numchan = 2; - break; - case 2: - numchan = 4; - break; - case 3: - numchan = 8; - break; - } - rdev->mc.vram_width = numchan * chansize; - /* Could aper size report 0 ? */ - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - /* Setup GPU memory space */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); - rdev->mc.visible_vram_size = rdev->mc.aper_size; - r600_vram_gtt_location(rdev, &rdev->mc); - - if (rdev->flags & RADEON_IS_IGP) { - rs690_pm_info(rdev); - rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - } - radeon_update_bandwidth_info(rdev); - return 0; -} - -int r600_vram_scratch_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->vram_scratch.robj == NULL) { - r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, - PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, - &rdev->vram_scratch.robj); - if (r) { - return r; - } - } - - r = radeon_bo_reserve(rdev->vram_scratch.robj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->vram_scratch.robj, - RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr); - if (r) { - radeon_bo_unreserve(rdev->vram_scratch.robj); - return r; - } - r = radeon_bo_kmap(rdev->vram_scratch.robj, - (void **)&rdev->vram_scratch.ptr); - if (r) - radeon_bo_unpin(rdev->vram_scratch.robj); - radeon_bo_unreserve(rdev->vram_scratch.robj); - - return r; -} - -void r600_vram_scratch_fini(struct radeon_device *rdev) -{ - int r; - - if (rdev->vram_scratch.robj == NULL) { - return; - } - r = radeon_bo_reserve(rdev->vram_scratch.robj, false); - if (likely(r == 0)) { - radeon_bo_kunmap(rdev->vram_scratch.robj); - radeon_bo_unpin(rdev->vram_scratch.robj); - radeon_bo_unreserve(rdev->vram_scratch.robj); - } - radeon_bo_unref(&rdev->vram_scratch.robj); -} - -/* We doesn't check that the GPU really needs a reset we simply do the - * reset, it's up to the caller to determine if the GPU needs one. We - * might add an helper function to check that. - */ -int r600_gpu_soft_reset(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | - S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | - S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | - S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) | - S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) | - S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) | - S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) | - S_008010_GUI_ACTIVE(1); - u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) | - S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) | - S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) | - S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) | - S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) | - S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | - S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | - S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); - u32 tmp; - - if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) - return 0; - - dev_info(rdev->dev, "GPU softreset \n"); - dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", - RREG32(R_008010_GRBM_STATUS)); - dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", - RREG32(R_008014_GRBM_STATUS2)); - dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", - RREG32(R_000E50_SRBM_STATUS)); - rv515_mc_stop(rdev, &save); - if (r600_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Disable CP parsing/prefetching */ - WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); - /* Check if any of the rendering block is busy and reset it */ - if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || - (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { - tmp = S_008020_SOFT_RESET_CR(1) | - S_008020_SOFT_RESET_DB(1) | - S_008020_SOFT_RESET_CB(1) | - S_008020_SOFT_RESET_PA(1) | - S_008020_SOFT_RESET_SC(1) | - S_008020_SOFT_RESET_SMX(1) | - S_008020_SOFT_RESET_SPI(1) | - S_008020_SOFT_RESET_SX(1) | - S_008020_SOFT_RESET_SH(1) | - S_008020_SOFT_RESET_TC(1) | - S_008020_SOFT_RESET_TA(1) | - S_008020_SOFT_RESET_VC(1) | - S_008020_SOFT_RESET_VGT(1); - dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(R_008020_GRBM_SOFT_RESET, tmp); - RREG32(R_008020_GRBM_SOFT_RESET); - mdelay(15); - WREG32(R_008020_GRBM_SOFT_RESET, 0); - } - /* Reset CP (we always reset CP) */ - tmp = S_008020_SOFT_RESET_CP(1); - dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(R_008020_GRBM_SOFT_RESET, tmp); - RREG32(R_008020_GRBM_SOFT_RESET); - mdelay(15); - WREG32(R_008020_GRBM_SOFT_RESET, 0); - /* Wait a little for things to settle down */ - mdelay(1); - dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", - RREG32(R_008010_GRBM_STATUS)); - dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", - RREG32(R_008014_GRBM_STATUS2)); - dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", - RREG32(R_000E50_SRBM_STATUS)); - rv515_mc_resume(rdev, &save); - return 0; -} - -bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 srbm_status; - u32 grbm_status; - u32 grbm_status2; - struct r100_gpu_lockup *lockup; - int r; - - if (rdev->family >= CHIP_RV770) - lockup = &rdev->config.rv770.lockup; - else - lockup = &rdev->config.r600.lockup; - - srbm_status = RREG32(R_000E50_SRBM_STATUS); - grbm_status = RREG32(R_008010_GRBM_STATUS); - grbm_status2 = RREG32(R_008014_GRBM_STATUS2); - if (!G_008010_GUI_ACTIVE(grbm_status)) { - r100_gpu_lockup_update(lockup, ring); - return false; - } - /* force CP activities */ - r = radeon_ring_lock(rdev, ring, 2); - if (!r) { - /* PACKET2 NOP */ - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - radeon_ring_unlock_commit(rdev, ring); - } - ring->rptr = RREG32(ring->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, lockup, ring); -} - -int r600_asic_reset(struct radeon_device *rdev) -{ - return r600_gpu_soft_reset(rdev); -} - -static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R6XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - - if (num_tile_pipes > R6XX_MAX_PIPES) - num_tile_pipes = R6XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R6XX_MAX_BACKENDS) - num_backends = R6XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - break; - case 4: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - break; - case 5: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - break; - case 6: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - break; - case 7: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - break; - case 8: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - } - - return backend_map; -} - -int r600_count_pipe_bits(uint32_t val) -{ - int i, ret = 0; - - for (i = 0; i < 32; i++) { - ret += val & 1; - val >>= 1; - } - return ret; -} - -void r600_gpu_init(struct radeon_device *rdev) -{ - u32 tiling_config; - u32 ramcfg; - u32 backend_map; - u32 cc_rb_backend_disable; - u32 cc_gc_shader_pipe_config; - u32 tmp; - int i, j; - u32 sq_config; - u32 sq_gpr_resource_mgmt_1 = 0; - u32 sq_gpr_resource_mgmt_2 = 0; - u32 sq_thread_resource_mgmt = 0; - u32 sq_stack_resource_mgmt_1 = 0; - u32 sq_stack_resource_mgmt_2 = 0; - - /* FIXME: implement */ - switch (rdev->family) { - case CHIP_R600: - rdev->config.r600.max_pipes = 4; - rdev->config.r600.max_tile_pipes = 8; - rdev->config.r600.max_simds = 4; - rdev->config.r600.max_backends = 4; - rdev->config.r600.max_gprs = 256; - rdev->config.r600.max_threads = 192; - rdev->config.r600.max_stack_entries = 256; - rdev->config.r600.max_hw_contexts = 8; - rdev->config.r600.max_gs_threads = 16; - rdev->config.r600.sx_max_export_size = 128; - rdev->config.r600.sx_max_export_pos_size = 16; - rdev->config.r600.sx_max_export_smx_size = 128; - rdev->config.r600.sq_num_cf_insts = 2; - break; - case CHIP_RV630: - case CHIP_RV635: - rdev->config.r600.max_pipes = 2; - rdev->config.r600.max_tile_pipes = 2; - rdev->config.r600.max_simds = 3; - rdev->config.r600.max_backends = 1; - rdev->config.r600.max_gprs = 128; - rdev->config.r600.max_threads = 192; - rdev->config.r600.max_stack_entries = 128; - rdev->config.r600.max_hw_contexts = 8; - rdev->config.r600.max_gs_threads = 4; - rdev->config.r600.sx_max_export_size = 128; - rdev->config.r600.sx_max_export_pos_size = 16; - rdev->config.r600.sx_max_export_smx_size = 128; - rdev->config.r600.sq_num_cf_insts = 2; - break; - case CHIP_RV610: - case CHIP_RV620: - case CHIP_RS780: - case CHIP_RS880: - rdev->config.r600.max_pipes = 1; - rdev->config.r600.max_tile_pipes = 1; - rdev->config.r600.max_simds = 2; - rdev->config.r600.max_backends = 1; - rdev->config.r600.max_gprs = 128; - rdev->config.r600.max_threads = 192; - rdev->config.r600.max_stack_entries = 128; - rdev->config.r600.max_hw_contexts = 4; - rdev->config.r600.max_gs_threads = 4; - rdev->config.r600.sx_max_export_size = 128; - rdev->config.r600.sx_max_export_pos_size = 16; - rdev->config.r600.sx_max_export_smx_size = 128; - rdev->config.r600.sq_num_cf_insts = 1; - break; - case CHIP_RV670: - rdev->config.r600.max_pipes = 4; - rdev->config.r600.max_tile_pipes = 4; - rdev->config.r600.max_simds = 4; - rdev->config.r600.max_backends = 4; - rdev->config.r600.max_gprs = 192; - rdev->config.r600.max_threads = 192; - rdev->config.r600.max_stack_entries = 256; - rdev->config.r600.max_hw_contexts = 8; - rdev->config.r600.max_gs_threads = 16; - rdev->config.r600.sx_max_export_size = 128; - rdev->config.r600.sx_max_export_pos_size = 16; - rdev->config.r600.sx_max_export_smx_size = 128; - rdev->config.r600.sq_num_cf_insts = 2; - break; - default: - break; - } - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - - WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - - /* Setup tiling */ - tiling_config = 0; - ramcfg = RREG32(RAMCFG); - switch (rdev->config.r600.max_tile_pipes) { - case 1: - tiling_config |= PIPE_TILING(0); - break; - case 2: - tiling_config |= PIPE_TILING(1); - break; - case 4: - tiling_config |= PIPE_TILING(2); - break; - case 8: - tiling_config |= PIPE_TILING(3); - break; - default: - break; - } - rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes; - rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); - tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); - tiling_config |= GROUP_SIZE((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - if ((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) - rdev->config.r600.tiling_group_size = 512; - else - rdev->config.r600.tiling_group_size = 256; - tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; - if (tmp > 3) { - tiling_config |= ROW_TILING(3); - tiling_config |= SAMPLE_SPLIT(3); - } else { - tiling_config |= ROW_TILING(tmp); - tiling_config |= SAMPLE_SPLIT(tmp); - } - tiling_config |= BANK_SWAPS(1); - - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; - cc_rb_backend_disable |= - BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); - - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; - cc_gc_shader_pipe_config |= - INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); - - backend_map = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, - (R6XX_MAX_BACKENDS - - r600_count_pipe_bits((cc_rb_backend_disable & - R6XX_MAX_BACKENDS_MASK) >> 16)), - (cc_rb_backend_disable >> 16)); - rdev->config.r600.tile_config = tiling_config; - rdev->config.r600.backend_map = backend_map; - tiling_config |= BACKEND_MAP(backend_map); - WREG32(GB_TILING_CONFIG, tiling_config); - WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); - WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); - - /* Setup pipes */ - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); - WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); - WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); - - /* Setup some CP states */ - WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b))); - WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40))); - - WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT | - SYNC_WALKER | SYNC_ALIGNER)); - /* Setup various GPU states */ - if (rdev->family == CHIP_RV670) - WREG32(ARB_GDEC_RD_CNTL, 0x00000021); - - tmp = RREG32(SX_DEBUG_1); - tmp |= SMX_EVENT_RELEASE; - if ((rdev->family > CHIP_R600)) - tmp |= ENABLE_NEW_SMX_ADDRESS; - WREG32(SX_DEBUG_1, tmp); - - if (((rdev->family) == CHIP_R600) || - ((rdev->family) == CHIP_RV630) || - ((rdev->family) == CHIP_RV610) || - ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780) || - ((rdev->family) == CHIP_RS880)) { - WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); - } else { - WREG32(DB_DEBUG, 0); - } - WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) | - DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4))); - - WREG32(PA_SC_MULTI_CHIP_CNTL, 0); - WREG32(VGT_NUM_INSTANCES, 0); - - WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0)); - - tmp = RREG32(SQ_MS_FIFO_SIZES); - if (((rdev->family) == CHIP_RV610) || - ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780) || - ((rdev->family) == CHIP_RS880)) { - tmp = (CACHE_FIFO_SIZE(0xa) | - FETCH_FIFO_HIWATER(0xa) | - DONE_FIFO_HIWATER(0xe0) | - ALU_UPDATE_FIFO_HIWATER(0x8)); - } else if (((rdev->family) == CHIP_R600) || - ((rdev->family) == CHIP_RV630)) { - tmp &= ~DONE_FIFO_HIWATER(0xff); - tmp |= DONE_FIFO_HIWATER(0x4); - } - WREG32(SQ_MS_FIFO_SIZES, tmp); - - /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT - * should be adjusted as needed by the 2D/3D drivers. This just sets default values - */ - sq_config = RREG32(SQ_CONFIG); - sq_config &= ~(PS_PRIO(3) | - VS_PRIO(3) | - GS_PRIO(3) | - ES_PRIO(3)); - sq_config |= (DX9_CONSTS | - VC_ENABLE | - PS_PRIO(0) | - VS_PRIO(1) | - GS_PRIO(2) | - ES_PRIO(3)); - - if ((rdev->family) == CHIP_R600) { - sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) | - NUM_VS_GPRS(124) | - NUM_CLAUSE_TEMP_GPRS(4)); - sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) | - NUM_ES_GPRS(0)); - sq_thread_resource_mgmt = (NUM_PS_THREADS(136) | - NUM_VS_THREADS(48) | - NUM_GS_THREADS(4) | - NUM_ES_THREADS(4)); - sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) | - NUM_VS_STACK_ENTRIES(128)); - sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) | - NUM_ES_STACK_ENTRIES(0)); - } else if (((rdev->family) == CHIP_RV610) || - ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780) || - ((rdev->family) == CHIP_RS880)) { - /* no vertex cache */ - sq_config &= ~VC_ENABLE; - - sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | - NUM_VS_GPRS(44) | - NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) | - NUM_ES_GPRS(17)); - sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | - NUM_VS_THREADS(78) | - NUM_GS_THREADS(4) | - NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) | - NUM_VS_STACK_ENTRIES(40)); - sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) | - NUM_ES_STACK_ENTRIES(16)); - } else if (((rdev->family) == CHIP_RV630) || - ((rdev->family) == CHIP_RV635)) { - sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | - NUM_VS_GPRS(44) | - NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) | - NUM_ES_GPRS(18)); - sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | - NUM_VS_THREADS(78) | - NUM_GS_THREADS(4) | - NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) | - NUM_VS_STACK_ENTRIES(40)); - sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) | - NUM_ES_STACK_ENTRIES(16)); - } else if ((rdev->family) == CHIP_RV670) { - sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | - NUM_VS_GPRS(44) | - NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) | - NUM_ES_GPRS(17)); - sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | - NUM_VS_THREADS(78) | - NUM_GS_THREADS(4) | - NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) | - NUM_VS_STACK_ENTRIES(64)); - sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) | - NUM_ES_STACK_ENTRIES(64)); - } - - WREG32(SQ_CONFIG, sq_config); - WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); - WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); - WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); - WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); - - if (((rdev->family) == CHIP_RV610) || - ((rdev->family) == CHIP_RV620) || - ((rdev->family) == CHIP_RS780) || - ((rdev->family) == CHIP_RS880)) { - WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); - } else { - WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); - } - - /* More default values. 2D/3D driver should adjust as needed */ - WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) | - S1_X(0x4) | S1_Y(0xc))); - WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) | - S1_X(0x2) | S1_Y(0x2) | - S2_X(0xa) | S2_Y(0x6) | - S3_X(0x6) | S3_Y(0xa))); - WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) | - S1_X(0x4) | S1_Y(0xc) | - S2_X(0x1) | S2_Y(0x6) | - S3_X(0xa) | S3_Y(0xe))); - WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) | - S5_X(0x0) | S5_Y(0x0) | - S6_X(0xb) | S6_Y(0x4) | - S7_X(0x7) | S7_Y(0x8))); - - WREG32(VGT_STRMOUT_EN, 0); - tmp = rdev->config.r600.max_pipes * 16; - switch (rdev->family) { - case CHIP_RV610: - case CHIP_RV620: - case CHIP_RS780: - case CHIP_RS880: - tmp += 32; - break; - case CHIP_RV670: - tmp += 128; - break; - default: - break; - } - if (tmp > 256) { - tmp = 256; - } - WREG32(VGT_ES_PER_GS, 128); - WREG32(VGT_GS_PER_ES, tmp); - WREG32(VGT_GS_PER_VS, 2); - WREG32(VGT_GS_VERTEX_REUSE, 16); - - /* more default values. 2D/3D driver should adjust as needed */ - WREG32(PA_SC_LINE_STIPPLE_STATE, 0); - WREG32(VGT_STRMOUT_EN, 0); - WREG32(SX_MISC, 0); - WREG32(PA_SC_MODE_CNTL, 0); - WREG32(PA_SC_AA_CONFIG, 0); - WREG32(PA_SC_LINE_STIPPLE, 0); - WREG32(SPI_INPUT_Z, 0); - WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2)); - WREG32(CB_COLOR7_FRAG, 0); - - /* Clear render buffer base addresses */ - WREG32(CB_COLOR0_BASE, 0); - WREG32(CB_COLOR1_BASE, 0); - WREG32(CB_COLOR2_BASE, 0); - WREG32(CB_COLOR3_BASE, 0); - WREG32(CB_COLOR4_BASE, 0); - WREG32(CB_COLOR5_BASE, 0); - WREG32(CB_COLOR6_BASE, 0); - WREG32(CB_COLOR7_BASE, 0); - WREG32(CB_COLOR7_FRAG, 0); - - switch (rdev->family) { - case CHIP_RV610: - case CHIP_RV620: - case CHIP_RS780: - case CHIP_RS880: - tmp = TC_L2_SIZE(8); - break; - case CHIP_RV630: - case CHIP_RV635: - tmp = TC_L2_SIZE(4); - break; - case CHIP_R600: - tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT; - break; - default: - tmp = TC_L2_SIZE(0); - break; - } - WREG32(TC_CNTL, tmp); - - tmp = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, tmp); - - tmp = RREG32(ARB_POP); - tmp |= ENABLE_TC128; - WREG32(ARB_POP, tmp); - - WREG32(PA_SC_MULTI_CHIP_CNTL, 0); - WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | - NUM_CLIP_SEQ(3))); - WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); - WREG32(VC_ENHANCE, 0); -} - - -/* - * Indirect registers accessor - */ -u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg) -{ - u32 r; - - WREG32(PCIE_PORT_INDEX, ((reg) & 0xff)); - (void)RREG32(PCIE_PORT_INDEX); - r = RREG32(PCIE_PORT_DATA); - return r; -} - -void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) -{ - WREG32(PCIE_PORT_INDEX, ((reg) & 0xff)); - (void)RREG32(PCIE_PORT_INDEX); - WREG32(PCIE_PORT_DATA, (v)); - (void)RREG32(PCIE_PORT_DATA); -} - -/* - * CP & Ring - */ -void r600_cp_stop(struct radeon_device *rdev) -{ - radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); - WREG32(SCRATCH_UMSK, 0); -} - -int r600_init_microcode(struct radeon_device *rdev) -{ - struct platform_device *pdev; - const char *chip_name; - const char *rlc_chip_name; - size_t pfp_req_size, me_req_size, rlc_req_size; - char fw_name[30]; - int err; - - DRM_DEBUG("\n"); - - pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); - err = IS_ERR(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); - return -EINVAL; - } - - switch (rdev->family) { - case CHIP_R600: - chip_name = "R600"; - rlc_chip_name = "R600"; - break; - case CHIP_RV610: - chip_name = "RV610"; - rlc_chip_name = "R600"; - break; - case CHIP_RV630: - chip_name = "RV630"; - rlc_chip_name = "R600"; - break; - case CHIP_RV620: - chip_name = "RV620"; - rlc_chip_name = "R600"; - break; - case CHIP_RV635: - chip_name = "RV635"; - rlc_chip_name = "R600"; - break; - case CHIP_RV670: - chip_name = "RV670"; - rlc_chip_name = "R600"; - break; - case CHIP_RS780: - case CHIP_RS880: - chip_name = "RS780"; - rlc_chip_name = "R600"; - break; - case CHIP_RV770: - chip_name = "RV770"; - rlc_chip_name = "R700"; - break; - case CHIP_RV730: - case CHIP_RV740: - chip_name = "RV730"; - rlc_chip_name = "R700"; - break; - case CHIP_RV710: - chip_name = "RV710"; - rlc_chip_name = "R700"; - break; - case CHIP_CEDAR: - chip_name = "CEDAR"; - rlc_chip_name = "CEDAR"; - break; - case CHIP_REDWOOD: - chip_name = "REDWOOD"; - rlc_chip_name = "REDWOOD"; - break; - case CHIP_JUNIPER: - chip_name = "JUNIPER"; - rlc_chip_name = "JUNIPER"; - break; - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - chip_name = "CYPRESS"; - rlc_chip_name = "CYPRESS"; - break; - case CHIP_PALM: - chip_name = "PALM"; - rlc_chip_name = "SUMO"; - break; - case CHIP_SUMO: - chip_name = "SUMO"; - rlc_chip_name = "SUMO"; - break; - case CHIP_SUMO2: - chip_name = "SUMO2"; - rlc_chip_name = "SUMO"; - break; - default: BUG(); - } - - if (rdev->family >= CHIP_CEDAR) { - pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; - me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; - rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; - } else if (rdev->family >= CHIP_RV770) { - pfp_req_size = R700_PFP_UCODE_SIZE * 4; - me_req_size = R700_PM4_UCODE_SIZE * 4; - rlc_req_size = R700_RLC_UCODE_SIZE * 4; - } else { - pfp_req_size = PFP_UCODE_SIZE * 4; - me_req_size = PM4_UCODE_SIZE * 12; - rlc_req_size = RLC_UCODE_SIZE * 4; - } - - DRM_INFO("Loading %s Microcode\n", chip_name); - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); - err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->pfp_fw->size != pfp_req_size) { - printk(KERN_ERR - "r600_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->pfp_fw->size, fw_name); - err = -EINVAL; - goto out; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); - err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->me_fw->size != me_req_size) { - printk(KERN_ERR - "r600_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->me_fw->size, fw_name); - err = -EINVAL; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); - err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->rlc_fw->size != rlc_req_size) { - printk(KERN_ERR - "r600_rlc: Bogus length %zu in firmware \"%s\"\n", - rdev->rlc_fw->size, fw_name); - err = -EINVAL; - } - -out: - platform_device_unregister(pdev); - - if (err) { - if (err != -EINVAL) - printk(KERN_ERR - "r600_cp: Failed to load firmware \"%s\"\n", - fw_name); - release_firmware(rdev->pfp_fw); - rdev->pfp_fw = NULL; - release_firmware(rdev->me_fw); - rdev->me_fw = NULL; - release_firmware(rdev->rlc_fw); - rdev->rlc_fw = NULL; - } - return err; -} - -static int r600_cp_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - int i; - - if (!rdev->me_fw || !rdev->pfp_fw) - return -EINVAL; - - r600_cp_stop(rdev); - - WREG32(CP_RB_CNTL, -#ifdef __BIG_ENDIAN - BUF_SWAP_32BIT | -#endif - RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); - - /* Reset cp */ - WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); - RREG32(GRBM_SOFT_RESET); - mdelay(15); - WREG32(GRBM_SOFT_RESET, 0); - - WREG32(CP_ME_RAM_WADDR, 0); - - fw_data = (const __be32 *)rdev->me_fw->data; - WREG32(CP_ME_RAM_WADDR, 0); - for (i = 0; i < PM4_UCODE_SIZE * 3; i++) - WREG32(CP_ME_RAM_DATA, - be32_to_cpup(fw_data++)); - - fw_data = (const __be32 *)rdev->pfp_fw->data; - WREG32(CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < PFP_UCODE_SIZE; i++) - WREG32(CP_PFP_UCODE_DATA, - be32_to_cpup(fw_data++)); - - WREG32(CP_PFP_UCODE_ADDR, 0); - WREG32(CP_ME_RAM_WADDR, 0); - WREG32(CP_ME_RAM_RADDR, 0); - return 0; -} - -int r600_cp_start(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - uint32_t cp_me; - - r = radeon_ring_lock(rdev, ring, 7); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); - radeon_ring_write(ring, 0x1); - if (rdev->family >= CHIP_RV770) { - radeon_ring_write(ring, 0x0); - radeon_ring_write(ring, rdev->config.rv770.max_hw_contexts - 1); - } else { - radeon_ring_write(ring, 0x3); - radeon_ring_write(ring, rdev->config.r600.max_hw_contexts - 1); - } - radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_unlock_commit(rdev, ring); - - cp_me = 0xff; - WREG32(R_0086D8_CP_ME_CNTL, cp_me); - return 0; -} - -int r600_cp_resume(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 tmp; - u32 rb_bufsz; - int r; - - /* Reset cp */ - WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); - RREG32(GRBM_SOFT_RESET); - mdelay(15); - WREG32(GRBM_SOFT_RESET, 0); - - /* Set ring buffer size */ - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB_CNTL, tmp); - WREG32(CP_SEM_WAIT_TIMER, 0x0); - - /* Set the write pointer delay */ - WREG32(CP_RB_WPTR_DELAY, 0); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); - WREG32(CP_RB_RPTR_WR, 0); - ring->wptr = 0; - WREG32(CP_RB_WPTR, ring->wptr); - - /* set the wb address whether it's enabled or not */ - WREG32(CP_RB_RPTR_ADDR, - ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); - WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); - WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); - - if (rdev->wb.enabled) - WREG32(SCRATCH_UMSK, 0xff); - else { - tmp |= RB_NO_UPDATE; - WREG32(SCRATCH_UMSK, 0); - } - - mdelay(1); - WREG32(CP_RB_CNTL, tmp); - - WREG32(CP_RB_BASE, ring->gpu_addr >> 8); - WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); - - ring->rptr = RREG32(CP_RB_RPTR); - - r600_cp_start(rdev); - ring->ready = true; - r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); - if (r) { - ring->ready = false; - return r; - } - return 0; -} - -void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) -{ - u32 rb_bufsz; - - /* Align ring size */ - rb_bufsz = drm_order(ring_size / 8); - ring_size = (1 << (rb_bufsz + 1)) * 4; - ring->ring_size = ring_size; - ring->align_mask = 16 - 1; -} - -void r600_cp_fini(struct radeon_device *rdev) -{ - r600_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); -} - - -/* - * GPU scratch registers helpers function. - */ -void r600_scratch_init(struct radeon_device *rdev) -{ - int i; - - rdev->scratch.num_reg = 7; - rdev->scratch.reg_base = SCRATCH_REG0; - for (i = 0; i < rdev->scratch.num_reg; i++) { - rdev->scratch.free[i] = true; - rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); - } -} - -int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) -{ - uint32_t scratch; - uint32_t tmp = 0; - unsigned i, ridx = radeon_ring_index(rdev, ring); - int r; - - r = radeon_scratch_get(rdev, &scratch); - if (r) { - DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); - return r; - } - WREG32(scratch, 0xCAFEDEAD); - r = radeon_ring_lock(rdev, ring, 3); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r); - radeon_scratch_free(rdev, scratch); - return r; - } - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); - radeon_ring_write(ring, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, ring); - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(scratch); - if (tmp == 0xDEADBEEF) - break; - DRM_UDELAY(1); - } - if (i < rdev->usec_timeout) { - DRM_INFO("ring test on %d succeeded in %d usecs\n", ridx, i); - } else { - DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n", - ridx, scratch, tmp); - r = -EINVAL; - } - radeon_scratch_free(rdev, scratch); - return r; -} - -void r600_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[fence->ring]; - - if (rdev->wb.use_event) { - u64 addr = rdev->fence_drv[fence->ring].gpu_addr; - /* flush read cache over gart */ - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); - radeon_ring_write(ring, 0xFFFFFFFF); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ - /* EVENT_WRITE_EOP - flush caches, send int */ - radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); - radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); - radeon_ring_write(ring, addr & 0xffffffff); - radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); - radeon_ring_write(ring, fence->seq); - radeon_ring_write(ring, 0); - } else { - /* flush read cache over gart */ - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); - radeon_ring_write(ring, 0xFFFFFFFF); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ - radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE, 0)); - radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); - /* wait for 3D idle clean */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(ring, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); - /* Emit fence sequence & fire IRQ */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); - radeon_ring_write(ring, fence->seq); - /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ - radeon_ring_write(ring, PACKET0(CP_INT_STATUS, 0)); - radeon_ring_write(ring, RB_INT_STAT); - } -} - -void r600_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *ring, - struct radeon_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; - - if (rdev->family < CHIP_CAYMAN) - sel |= PACKET3_SEM_WAIT_ON_SIGNAL; - - radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - radeon_ring_write(ring, addr & 0xffffffff); - radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); -} - -int r600_copy_blit(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence) -{ - int r; - - mutex_lock(&rdev->r600_blit.mutex); - rdev->r600_blit.vb_ib = NULL; - r = r600_blit_prepare_copy(rdev, num_gpu_pages); - if (r) { - if (rdev->r600_blit.vb_ib) - radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); - mutex_unlock(&rdev->r600_blit.mutex); - return r; - } - r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages); - r600_blit_done_copy(rdev, fence); - mutex_unlock(&rdev->r600_blit.mutex); - return 0; -} - -void r600_blit_suspend(struct radeon_device *rdev) -{ - int r; - - /* unpin shaders bo */ - if (rdev->r600_blit.shader_obj) { - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (!r) { - radeon_bo_unpin(rdev->r600_blit.shader_obj); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - } - } -} - -int r600_set_surface_reg(struct radeon_device *rdev, int reg, - uint32_t tiling_flags, uint32_t pitch, - uint32_t offset, uint32_t obj_size) -{ - /* FIXME: implement */ - return 0; -} - -void r600_clear_surface_reg(struct radeon_device *rdev, int reg) -{ - /* FIXME: implement */ -} - -int r600_startup(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - - /* enable pcie gen2 link */ - r600_pcie_gen2_enable(rdev); - - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = r600_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - - r = r600_vram_scratch_init(rdev); - if (r) - return r; - - r600_mc_program(rdev); - if (rdev->flags & RADEON_IS_AGP) { - r600_agp_enable(rdev); - } else { - r = r600_pcie_gart_enable(rdev); - if (r) - return r; - } - r600_gpu_init(rdev); - r = r600_blit_init(rdev); - if (r) { - r600_blit_fini(rdev); - rdev->asic->copy.copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r = r600_irq_init(rdev); - if (r) { - DRM_ERROR("radeon: IH init failed (%d).\n", r); - radeon_irq_kms_fini(rdev); - return r; - } - r600_irq_set(rdev); - - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - - if (r) - return r; - r = r600_cp_load_microcode(rdev); - if (r) - return r; - r = r600_cp_resume(rdev); - if (r) - return r; - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -void r600_vga_set_state(struct radeon_device *rdev, bool state) -{ - uint32_t temp; - - temp = RREG32(CONFIG_CNTL); - if (state == false) { - temp &= ~(1<<0); - temp |= (1<<1); - } else { - temp &= ~(1<<1); - } - WREG32(CONFIG_CNTL, temp); -} - -int r600_resume(struct radeon_device *rdev) -{ - int r; - - /* Do not reset GPU before posting, on r600 hw unlike on r500 hw, - * posting will perform necessary task to bring back GPU into good - * shape. - */ - /* post card */ - atom_asic_init(rdev->mode_info.atom_context); - - rdev->accel_working = true; - r = r600_startup(rdev); - if (r) { - DRM_ERROR("r600 startup failed on resume\n"); - rdev->accel_working = false; - return r; - } - - r = r600_audio_init(rdev); - if (r) { - DRM_ERROR("radeon: audio resume failed\n"); - return r; - } - - return r; -} - -int r600_suspend(struct radeon_device *rdev) -{ - r600_audio_fini(rdev); - radeon_ib_pool_suspend(rdev); - r600_blit_suspend(rdev); - /* FIXME: we should wait for ring to be empty */ - r600_cp_stop(rdev); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - r600_irq_suspend(rdev); - radeon_wb_disable(rdev); - r600_pcie_gart_disable(rdev); - - return 0; -} - -/* Plan is to move initialization in that function and use - * helper function so that radeon_device_init pretty much - * do nothing more than calling asic specific function. This - * should also allow to remove a bunch of callback function - * like vram_info. - */ -int r600_init(struct radeon_device *rdev) -{ - int r; - - if (r600_debugfs_mc_info_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for mc !\n"); - } - /* This don't do much */ - r = radeon_gem_init(rdev); - if (r) - return r; - /* Read BIOS */ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); - return -EINVAL; - } - r = radeon_atombios_init(rdev); - if (r) - return r; - /* Post card if necessary */ - if (!radeon_card_posted(rdev)) { - if (!rdev->bios) { - dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); - return -EINVAL; - } - DRM_INFO("GPU not posted. posting now...\n"); - atom_asic_init(rdev->mode_info.atom_context); - } - /* Initialize scratch registers */ - r600_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) - radeon_agp_disable(rdev); - } - r = r600_mc_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - - r = radeon_irq_kms_init(rdev); - if (r) - return r; - - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); - - rdev->ih.ring_obj = NULL; - r600_ih_ring_init(rdev, 64 * 1024); - - r = r600_pcie_gart_init(rdev); - if (r) - return r; - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = r600_startup(rdev); - if (r) { - dev_err(rdev->dev, "disabling GPU acceleration\n"); - r600_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - r600_pcie_gart_fini(rdev); - rdev->accel_working = false; - } - - r = r600_audio_init(rdev); - if (r) - return r; /* TODO error handling */ - return 0; -} - -void r600_fini(struct radeon_device *rdev) -{ - r600_audio_fini(rdev); - r600_blit_fini(rdev); - r600_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - r600_pcie_gart_fini(rdev); - r600_vram_scratch_fini(rdev); - radeon_agp_fini(rdev); - radeon_gem_fini(rdev); - radeon_semaphore_driver_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - - -/* - * CS stuff - */ -void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -{ - struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; - - /* FIXME: implement */ - radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (ib->gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); - radeon_ring_write(ring, ib->length_dw); -} - -int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) -{ - struct radeon_ib *ib; - uint32_t scratch; - uint32_t tmp = 0; - unsigned i; - int r; - int ring_index = radeon_ring_index(rdev, ring); - - r = radeon_scratch_get(rdev, &scratch); - if (r) { - DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); - return r; - } - WREG32(scratch, 0xCAFEDEAD); - r = radeon_ib_get(rdev, ring_index, &ib, 256); - if (r) { - DRM_ERROR("radeon: failed to get ib (%d).\n", r); - return r; - } - ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); - ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - ib->ptr[2] = 0xDEADBEEF; - ib->length_dw = 3; - r = radeon_ib_schedule(rdev, ib); - if (r) { - radeon_scratch_free(rdev, scratch); - radeon_ib_free(rdev, &ib); - DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); - return r; - } - r = radeon_fence_wait(ib->fence, false); - if (r) { - DRM_ERROR("radeon: fence wait failed (%d).\n", r); - return r; - } - for (i = 0; i < rdev->usec_timeout; i++) { - tmp = RREG32(scratch); - if (tmp == 0xDEADBEEF) - break; - DRM_UDELAY(1); - } - if (i < rdev->usec_timeout) { - DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib->fence->ring, i); - } else { - DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", - scratch, tmp); - r = -EINVAL; - } - radeon_scratch_free(rdev, scratch); - radeon_ib_free(rdev, &ib); - return r; -} - -/* - * Interrupts - * - * Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty - * the same as the CP ring buffer, but in reverse. Rather than the CPU - * writing to the ring and the GPU consuming, the GPU writes to the ring - * and host consumes. As the host irq handler processes interrupts, it - * increments the rptr. When the rptr catches up with the wptr, all the - * current interrupts have been processed. - */ - -void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) -{ - u32 rb_bufsz; - - /* Align ring size */ - rb_bufsz = drm_order(ring_size / 4); - ring_size = (1 << rb_bufsz) * 4; - rdev->ih.ring_size = ring_size; - rdev->ih.ptr_mask = rdev->ih.ring_size - 1; - rdev->ih.rptr = 0; -} - -int r600_ih_ring_alloc(struct radeon_device *rdev) -{ - int r; - - /* Allocate ring buffer */ - if (rdev->ih.ring_obj == NULL) { - r = radeon_bo_create(rdev, rdev->ih.ring_size, - PAGE_SIZE, true, - RADEON_GEM_DOMAIN_GTT, - &rdev->ih.ring_obj); - if (r) { - DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); - return r; - } - r = radeon_bo_reserve(rdev->ih.ring_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->ih.ring_obj, - RADEON_GEM_DOMAIN_GTT, - &rdev->ih.gpu_addr); - if (r) { - radeon_bo_unreserve(rdev->ih.ring_obj); - DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r); - return r; - } - r = radeon_bo_kmap(rdev->ih.ring_obj, - (void **)&rdev->ih.ring); - radeon_bo_unreserve(rdev->ih.ring_obj); - if (r) { - DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r); - return r; - } - } - return 0; -} - -void r600_ih_ring_fini(struct radeon_device *rdev) -{ - int r; - if (rdev->ih.ring_obj) { - r = radeon_bo_reserve(rdev->ih.ring_obj, false); - if (likely(r == 0)) { - radeon_bo_kunmap(rdev->ih.ring_obj); - radeon_bo_unpin(rdev->ih.ring_obj); - radeon_bo_unreserve(rdev->ih.ring_obj); - } - radeon_bo_unref(&rdev->ih.ring_obj); - rdev->ih.ring = NULL; - rdev->ih.ring_obj = NULL; - } -} - -void r600_rlc_stop(struct radeon_device *rdev) -{ - - if ((rdev->family >= CHIP_RV770) && - (rdev->family <= CHIP_RV740)) { - /* r7xx asics need to soft reset RLC before halting */ - WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); - RREG32(SRBM_SOFT_RESET); - mdelay(15); - WREG32(SRBM_SOFT_RESET, 0); - RREG32(SRBM_SOFT_RESET); - } - - WREG32(RLC_CNTL, 0); -} - -static void r600_rlc_start(struct radeon_device *rdev) -{ - WREG32(RLC_CNTL, RLC_ENABLE); -} - -static int r600_rlc_init(struct radeon_device *rdev) -{ - u32 i; - const __be32 *fw_data; - - if (!rdev->rlc_fw) - return -EINVAL; - - r600_rlc_stop(rdev); - - WREG32(RLC_HB_CNTL, 0); - - if (rdev->family == CHIP_ARUBA) { - WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); - WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); - } - if (rdev->family <= CHIP_CAYMAN) { - WREG32(RLC_HB_BASE, 0); - WREG32(RLC_HB_RPTR, 0); - WREG32(RLC_HB_WPTR, 0); - } - if (rdev->family <= CHIP_CAICOS) { - WREG32(RLC_HB_WPTR_LSB_ADDR, 0); - WREG32(RLC_HB_WPTR_MSB_ADDR, 0); - } - WREG32(RLC_MC_CNTL, 0); - WREG32(RLC_UCODE_CNTL, 0); - - fw_data = (const __be32 *)rdev->rlc_fw->data; - if (rdev->family >= CHIP_ARUBA) { - for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); - } - } else if (rdev->family >= CHIP_CAYMAN) { - for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); - } - } else if (rdev->family >= CHIP_CEDAR) { - for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); - } - } else if (rdev->family >= CHIP_RV770) { - for (i = 0; i < R700_RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); - } - } else { - for (i = 0; i < RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); - } - } - WREG32(RLC_UCODE_ADDR, 0); - - r600_rlc_start(rdev); - - return 0; -} - -static void r600_enable_interrupts(struct radeon_device *rdev) -{ - u32 ih_cntl = RREG32(IH_CNTL); - u32 ih_rb_cntl = RREG32(IH_RB_CNTL); - - ih_cntl |= ENABLE_INTR; - ih_rb_cntl |= IH_RB_ENABLE; - WREG32(IH_CNTL, ih_cntl); - WREG32(IH_RB_CNTL, ih_rb_cntl); - rdev->ih.enabled = true; -} - -void r600_disable_interrupts(struct radeon_device *rdev) -{ - u32 ih_rb_cntl = RREG32(IH_RB_CNTL); - u32 ih_cntl = RREG32(IH_CNTL); - - ih_rb_cntl &= ~IH_RB_ENABLE; - ih_cntl &= ~ENABLE_INTR; - WREG32(IH_RB_CNTL, ih_rb_cntl); - WREG32(IH_CNTL, ih_cntl); - /* set rptr, wptr to 0 */ - WREG32(IH_RB_RPTR, 0); - WREG32(IH_RB_WPTR, 0); - rdev->ih.enabled = false; - rdev->ih.wptr = 0; - rdev->ih.rptr = 0; -} - -static void r600_disable_interrupt_state(struct radeon_device *rdev) -{ - u32 tmp; - - WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); - WREG32(GRBM_INT_CNTL, 0); - WREG32(DxMODE_INT_MASK, 0); - WREG32(D1GRPH_INTERRUPT_CONTROL, 0); - WREG32(D2GRPH_INTERRUPT_CONTROL, 0); - if (ASIC_IS_DCE3(rdev)) { - WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); - WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); - tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD1_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD2_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD3_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD4_INT_CONTROL, tmp); - if (ASIC_IS_DCE32(rdev)) { - tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, tmp); - } - } else { - WREG32(DACA_AUTODETECT_INT_CONTROL, 0); - WREG32(DACB_AUTODETECT_INT_CONTROL, 0); - tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); - tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); - tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; - WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); - } -} - -int r600_irq_init(struct radeon_device *rdev) -{ - int ret = 0; - int rb_bufsz; - u32 interrupt_cntl, ih_cntl, ih_rb_cntl; - - /* allocate ring */ - ret = r600_ih_ring_alloc(rdev); - if (ret) - return ret; - - /* disable irqs */ - r600_disable_interrupts(rdev); - - /* init rlc */ - ret = r600_rlc_init(rdev); - if (ret) { - r600_ih_ring_fini(rdev); - return ret; - } - - /* setup interrupt control */ - /* set dummy read address to ring address */ - WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); - interrupt_cntl = RREG32(INTERRUPT_CNTL); - /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi - * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN - */ - interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; - /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ - interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; - WREG32(INTERRUPT_CNTL, interrupt_cntl); - - WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); - rb_bufsz = drm_order(rdev->ih.ring_size / 4); - - ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | - IH_WPTR_OVERFLOW_CLEAR | - (rb_bufsz << 1)); - - if (rdev->wb.enabled) - ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; - - /* set the writeback address whether it's enabled or not */ - WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); - WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); - - WREG32(IH_RB_CNTL, ih_rb_cntl); - - /* set rptr, wptr to 0 */ - WREG32(IH_RB_RPTR, 0); - WREG32(IH_RB_WPTR, 0); - - /* Default settings for IH_CNTL (disabled at first) */ - ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10); - /* RPTR_REARM only works if msi's are enabled */ - if (rdev->msi_enabled) - ih_cntl |= RPTR_REARM; - WREG32(IH_CNTL, ih_cntl); - - /* force the active interrupt state to all disabled */ - if (rdev->family >= CHIP_CEDAR) - evergreen_disable_interrupt_state(rdev); - else - r600_disable_interrupt_state(rdev); - - /* enable irqs */ - r600_enable_interrupts(rdev); - - return ret; -} - -void r600_irq_suspend(struct radeon_device *rdev) -{ - r600_irq_disable(rdev); - r600_rlc_stop(rdev); -} - -void r600_irq_fini(struct radeon_device *rdev) -{ - r600_irq_suspend(rdev); - r600_ih_ring_fini(rdev); -} - -int r600_irq_set(struct radeon_device *rdev) -{ - u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; - u32 mode_int = 0; - u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; - u32 grbm_int_cntl = 0; - u32 hdmi1, hdmi2; - u32 d1grph = 0, d2grph = 0; - - if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); - return -EINVAL; - } - /* don't enable anything if the ih is disabled */ - if (!rdev->ih.enabled) { - r600_disable_interrupts(rdev); - /* force the active interrupt state to all disabled */ - r600_disable_interrupt_state(rdev); - return 0; - } - - hdmi1 = RREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; - if (ASIC_IS_DCE3(rdev)) { - hdmi2 = RREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; - hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; - if (ASIC_IS_DCE32(rdev)) { - hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; - } - } else { - hdmi2 = RREG32(R600_HDMI_BLOCK2 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; - hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; - } - - if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { - DRM_DEBUG("r600_irq_set: sw int\n"); - cp_int_cntl |= RB_INT_ENABLE; - cp_int_cntl |= TIME_STAMP_INT_ENABLE; - } - if (rdev->irq.crtc_vblank_int[0] || - rdev->irq.pflip[0]) { - DRM_DEBUG("r600_irq_set: vblank 0\n"); - mode_int |= D1MODE_VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[1] || - rdev->irq.pflip[1]) { - DRM_DEBUG("r600_irq_set: vblank 1\n"); - mode_int |= D2MODE_VBLANK_INT_MASK; - } - if (rdev->irq.hpd[0]) { - DRM_DEBUG("r600_irq_set: hpd 1\n"); - hpd1 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[1]) { - DRM_DEBUG("r600_irq_set: hpd 2\n"); - hpd2 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[2]) { - DRM_DEBUG("r600_irq_set: hpd 3\n"); - hpd3 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[3]) { - DRM_DEBUG("r600_irq_set: hpd 4\n"); - hpd4 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[4]) { - DRM_DEBUG("r600_irq_set: hpd 5\n"); - hpd5 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[5]) { - DRM_DEBUG("r600_irq_set: hpd 6\n"); - hpd6 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hdmi[0]) { - DRM_DEBUG("r600_irq_set: hdmi 1\n"); - hdmi1 |= R600_HDMI_INT_EN; - } - if (rdev->irq.hdmi[1]) { - DRM_DEBUG("r600_irq_set: hdmi 2\n"); - hdmi2 |= R600_HDMI_INT_EN; - } - if (rdev->irq.gui_idle) { - DRM_DEBUG("gui idle\n"); - grbm_int_cntl |= GUI_IDLE_INT_ENABLE; - } - - WREG32(CP_INT_CNTL, cp_int_cntl); - WREG32(DxMODE_INT_MASK, mode_int); - WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); - WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); - WREG32(GRBM_INT_CNTL, grbm_int_cntl); - WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); - if (ASIC_IS_DCE3(rdev)) { - WREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, hdmi2); - WREG32(DC_HPD1_INT_CONTROL, hpd1); - WREG32(DC_HPD2_INT_CONTROL, hpd2); - WREG32(DC_HPD3_INT_CONTROL, hpd3); - WREG32(DC_HPD4_INT_CONTROL, hpd4); - if (ASIC_IS_DCE32(rdev)) { - WREG32(DC_HPD5_INT_CONTROL, hpd5); - WREG32(DC_HPD6_INT_CONTROL, hpd6); - } - } else { - WREG32(R600_HDMI_BLOCK2 + R600_HDMI_CNTL, hdmi2); - WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); - WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); - WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); - } - - return 0; -} - -static void r600_irq_ack(struct radeon_device *rdev) -{ - u32 tmp; - - if (ASIC_IS_DCE3(rdev)) { - rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); - rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); - rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); - } else { - rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); - rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); - rdev->irq.stat_regs.r600.disp_int_cont2 = 0; - } - rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); - rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); - - if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED) - WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED) - WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) - WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) - WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) - WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) - WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { - if (ASIC_IS_DCE3(rdev)) { - tmp = RREG32(DC_HPD1_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD1_INT_CONTROL, tmp); - } else { - tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); - } - } - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { - if (ASIC_IS_DCE3(rdev)) { - tmp = RREG32(DC_HPD2_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD2_INT_CONTROL, tmp); - } else { - tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); - } - } - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { - if (ASIC_IS_DCE3(rdev)) { - tmp = RREG32(DC_HPD3_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD3_INT_CONTROL, tmp); - } else { - tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); - } - } - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { - tmp = RREG32(DC_HPD4_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD4_INT_CONTROL, tmp); - } - if (ASIC_IS_DCE32(rdev)) { - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { - tmp = RREG32(DC_HPD5_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD5_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { - tmp = RREG32(DC_HPD5_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD6_INT_CONTROL, tmp); - } - } - if (RREG32(R600_HDMI_BLOCK1 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { - WREG32_P(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); - } - if (ASIC_IS_DCE3(rdev)) { - if (RREG32(R600_HDMI_BLOCK3 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { - WREG32_P(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); - } - } else { - if (RREG32(R600_HDMI_BLOCK2 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { - WREG32_P(R600_HDMI_BLOCK2 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); - } - } -} - -void r600_irq_disable(struct radeon_device *rdev) -{ - r600_disable_interrupts(rdev); - /* Wait and acknowledge irq */ - mdelay(1); - r600_irq_ack(rdev); - r600_disable_interrupt_state(rdev); -} - -static u32 r600_get_ih_wptr(struct radeon_device *rdev) -{ - u32 wptr, tmp; - - if (rdev->wb.enabled) - wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); - else - wptr = RREG32(IH_RB_WPTR); - - if (wptr & RB_OVERFLOW) { - /* When a ring buffer overflow happen start parsing interrupt - * from the last not overwritten vector (wptr + 16). Hopefully - * this should allow us to catchup. - */ - dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", - wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); - rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; - tmp = RREG32(IH_RB_CNTL); - tmp |= IH_WPTR_OVERFLOW_CLEAR; - WREG32(IH_RB_CNTL, tmp); - } - return (wptr & rdev->ih.ptr_mask); -} - -/* r600 IV Ring - * Each IV ring entry is 128 bits: - * [7:0] - interrupt source id - * [31:8] - reserved - * [59:32] - interrupt source data - * [127:60] - reserved - * - * The basic interrupt vector entries - * are decoded as follows: - * src_id src_data description - * 1 0 D1 Vblank - * 1 1 D1 Vline - * 5 0 D2 Vblank - * 5 1 D2 Vline - * 19 0 FP Hot plug detection A - * 19 1 FP Hot plug detection B - * 19 2 DAC A auto-detection - * 19 3 DAC B auto-detection - * 21 4 HDMI block A - * 21 5 HDMI block B - * 176 - CP_INT RB - * 177 - CP_INT IB1 - * 178 - CP_INT IB2 - * 181 - EOP Interrupt - * 233 - GUI Idle - * - * Note, these are based on r600 and may need to be - * adjusted or added to on newer asics - */ - -int r600_irq_process(struct radeon_device *rdev) -{ - u32 wptr; - u32 rptr; - u32 src_id, src_data; - u32 ring_index; - unsigned long flags; - bool queue_hotplug = false; - - if (!rdev->ih.enabled || rdev->shutdown) - return IRQ_NONE; - - /* No MSIs, need a dummy read to flush PCI DMAs */ - if (!rdev->msi_enabled) - RREG32(IH_RB_WPTR); - - wptr = r600_get_ih_wptr(rdev); - rptr = rdev->ih.rptr; - DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - - spin_lock_irqsave(&rdev->ih.lock, flags); - - if (rptr == wptr) { - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_NONE; - } - -restart_ih: - /* Order reading of wptr vs. reading of IH ring data */ - rmb(); - - /* display interrupts */ - r600_irq_ack(rdev); - - rdev->ih.wptr = wptr; - while (rptr != wptr) { - /* wptr/rptr are in bytes! */ - ring_index = rptr / 4; - src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; - src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; - - switch (src_id) { - case 1: /* D1 vblank/vline */ - switch (src_data) { - case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); - rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); - } - break; - case 1: /* D1 vline */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 5: /* D2 vblank/vline */ - switch (src_data) { - case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); - rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); - } - break; - case 1: /* D1 vline */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 19: /* HPD/DAC hotplug */ - switch (src_data) { - case 0: - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } - break; - case 1: - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } - break; - case 4: - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } - break; - case 5: - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } - break; - case 10: - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } - break; - case 12: - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 21: /* HDMI */ - DRM_DEBUG("IH: HDMI: 0x%x\n", src_data); - r600_audio_schedule_polling(rdev); - break; - case 176: /* CP_INT in ring buffer */ - case 177: /* CP_INT in IB1 */ - case 178: /* CP_INT in IB2 */ - DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 181: /* CP EOP event */ - DRM_DEBUG("IH: CP EOP\n"); - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 233: /* GUI IDLE */ - DRM_DEBUG("IH: GUI idle\n"); - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - - /* wptr/rptr are in bytes! */ - rptr += 16; - rptr &= rdev->ih.ptr_mask; - } - /* make sure wptr hasn't changed while processing */ - wptr = r600_get_ih_wptr(rdev); - if (wptr != rdev->ih.wptr) - goto restart_ih; - if (queue_hotplug) - schedule_work(&rdev->hotplug_work); - rdev->ih.rptr = rptr; - WREG32(IH_RB_RPTR, rdev->ih.rptr); - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_HANDLED; -} - -/* - * Debugfs info - */ -#if defined(CONFIG_DEBUG_FS) - -static int r600_debugfs_mc_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - - DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS); - DREG32_SYS(m, rdev, VM_L2_STATUS); - return 0; -} - -static struct drm_info_list r600_mc_info_list[] = { - {"r600_mc_info", r600_debugfs_mc_info, 0, NULL}, -}; -#endif - -int r600_debugfs_mc_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list)); -#else - return 0; -#endif -} - -/** - * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl - * rdev: radeon device structure - * bo: buffer object struct which userspace is waiting for idle - * - * Some R6XX/R7XX doesn't seems to take into account HDP flush performed - * through ring buffer, this leads to corruption in rendering, see - * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we - * directly perform HDP flush by writing register through MMIO. - */ -void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) -{ - /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read - * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL. - * This seems to cause problems on some AGP cards. Just use the old - * method for them. - */ - if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && - rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { - void __iomem *ptr = (void *)rdev->vram_scratch.ptr; - u32 tmp; - - WREG32(HDP_DEBUG1, 0); - tmp = readl((void __iomem *)ptr); - } else - WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); -} - -void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes) -{ - u32 link_width_cntl, mask, target_reg; - - if (rdev->flags & RADEON_IS_IGP) - return; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return; - - /* x2 cards have a special sequence */ - if (ASIC_IS_X2(rdev)) - return; - - /* FIXME wait for idle */ - - switch (lanes) { - case 0: - mask = RADEON_PCIE_LC_LINK_WIDTH_X0; - break; - case 1: - mask = RADEON_PCIE_LC_LINK_WIDTH_X1; - break; - case 2: - mask = RADEON_PCIE_LC_LINK_WIDTH_X2; - break; - case 4: - mask = RADEON_PCIE_LC_LINK_WIDTH_X4; - break; - case 8: - mask = RADEON_PCIE_LC_LINK_WIDTH_X8; - break; - case 12: - mask = RADEON_PCIE_LC_LINK_WIDTH_X12; - break; - case 16: - default: - mask = RADEON_PCIE_LC_LINK_WIDTH_X16; - break; - } - - link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); - - if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == - (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) - return; - - if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS) - return; - - link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | - RADEON_PCIE_LC_RECONFIG_NOW | - R600_PCIE_LC_RENEGOTIATE_EN | - R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE); - link_width_cntl |= mask; - - WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - - /* some northbridges can renegotiate the link rather than requiring - * a complete re-config. - * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.) - */ - if (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT) - link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT; - else - link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE; - - WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | - RADEON_PCIE_LC_RECONFIG_NOW)); - - if (rdev->family >= CHIP_RV770) - target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX; - else - target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX; - - /* wait for lane set to complete */ - link_width_cntl = RREG32(target_reg); - while (link_width_cntl == 0xffffffff) - link_width_cntl = RREG32(target_reg); - -} - -int r600_get_pcie_lanes(struct radeon_device *rdev) -{ - u32 link_width_cntl; - - if (rdev->flags & RADEON_IS_IGP) - return 0; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return 0; - - /* x2 cards have a special sequence */ - if (ASIC_IS_X2(rdev)) - return 0; - - /* FIXME wait for idle */ - - link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); - - switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { - case RADEON_PCIE_LC_LINK_WIDTH_X0: - return 0; - case RADEON_PCIE_LC_LINK_WIDTH_X1: - return 1; - case RADEON_PCIE_LC_LINK_WIDTH_X2: - return 2; - case RADEON_PCIE_LC_LINK_WIDTH_X4: - return 4; - case RADEON_PCIE_LC_LINK_WIDTH_X8: - return 8; - case RADEON_PCIE_LC_LINK_WIDTH_X16: - default: - return 16; - } -} - -static void r600_pcie_gen2_enable(struct radeon_device *rdev) -{ - u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; - u16 link_cntl2; - - if (radeon_pcie_gen2 == 0) - return; - - if (rdev->flags & RADEON_IS_IGP) - return; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return; - - /* x2 cards have a special sequence */ - if (ASIC_IS_X2(rdev)) - return; - - /* only RV6xx+ chips are supported */ - if (rdev->family <= CHIP_R600) - return; - - /* 55 nm r6xx asics */ - if ((rdev->family == CHIP_RV670) || - (rdev->family == CHIP_RV620) || - (rdev->family == CHIP_RV635)) { - /* advertise upconfig capability */ - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - link_width_cntl &= ~LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { - lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; - link_width_cntl &= ~(LC_LINK_WIDTH_MASK | - LC_RECONFIG_ARC_MISSING_ESCAPE); - link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } else { - link_width_cntl |= LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } - } - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && - (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { - - /* 55 nm r6xx asics */ - if ((rdev->family == CHIP_RV670) || - (rdev->family == CHIP_RV620) || - (rdev->family == CHIP_RV635)) { - WREG32(MM_CFGREGS_CNTL, 0x8); - link_cntl2 = RREG32(0x4088); - WREG32(MM_CFGREGS_CNTL, 0); - /* not supported yet */ - if (link_cntl2 & SELECTABLE_DEEMPHASIS) - return; - } - - speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK; - speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT); - speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK; - speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE; - speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - tmp = RREG32(0x541c); - WREG32(0x541c, tmp | 0x8); - WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); - link_cntl2 = RREG16(0x4088); - link_cntl2 &= ~TARGET_LINK_SPEED_MASK; - link_cntl2 |= 0x2; - WREG16(0x4088, link_cntl2); - WREG32(MM_CFGREGS_CNTL, 0); - - if ((rdev->family == CHIP_RV670) || - (rdev->family == CHIP_RV620) || - (rdev->family == CHIP_RV635)) { - training_cntl = RREG32_PCIE_P(PCIE_LC_TRAINING_CNTL); - training_cntl &= ~LC_POINT_7_PLUS_EN; - WREG32_PCIE_P(PCIE_LC_TRAINING_CNTL, training_cntl); - } else { - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - } - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl |= LC_GEN2_EN_STRAP; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - } else { - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ - if (1) - link_width_cntl |= LC_UPCONFIGURE_DIS; - else - link_width_cntl &= ~LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_audio.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_audio.c deleted file mode 100644 index 24e39399..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_audio.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Christian König. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Christian König - */ -#include "drmP.h" -#include "radeon.h" -#include "radeon_reg.h" -#include "radeon_asic.h" -#include "atom.h" - -#define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */ - -/* - * check if the chipset is supported - */ -static int r600_audio_chipset_supported(struct radeon_device *rdev) -{ - return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) - || rdev->family == CHIP_RS600 - || rdev->family == CHIP_RS690 - || rdev->family == CHIP_RS740; -} - -/* - * current number of channels - */ -int r600_audio_channels(struct radeon_device *rdev) -{ - return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; -} - -/* - * current bits per sample - */ -int r600_audio_bits_per_sample(struct radeon_device *rdev) -{ - uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4; - switch (value) { - case 0x0: return 8; - case 0x1: return 16; - case 0x2: return 20; - case 0x3: return 24; - case 0x4: return 32; - } - - dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n", - (int)value); - - return 16; -} - -/* - * current sampling rate in HZ - */ -int r600_audio_rate(struct radeon_device *rdev) -{ - uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); - uint32_t result; - - if (value & 0x4000) - result = 44100; - else - result = 48000; - - result *= ((value >> 11) & 0x7) + 1; - result /= ((value >> 8) & 0x7) + 1; - - return result; -} - -/* - * iec 60958 status bits - */ -uint8_t r600_audio_status_bits(struct radeon_device *rdev) -{ - return RREG32(R600_AUDIO_STATUS_BITS) & 0xff; -} - -/* - * iec 60958 category code - */ -uint8_t r600_audio_category_code(struct radeon_device *rdev) -{ - return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff; -} - -/* - * schedule next audio update event - */ -void r600_audio_schedule_polling(struct radeon_device *rdev) -{ - mod_timer(&rdev->audio_timer, - jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL)); -} - -/* - * update all hdmi interfaces with current audio parameters - */ -static void r600_audio_update_hdmi(unsigned long param) -{ - struct radeon_device *rdev = (struct radeon_device *)param; - struct drm_device *dev = rdev->ddev; - - int channels = r600_audio_channels(rdev); - int rate = r600_audio_rate(rdev); - int bps = r600_audio_bits_per_sample(rdev); - uint8_t status_bits = r600_audio_status_bits(rdev); - uint8_t category_code = r600_audio_category_code(rdev); - - struct drm_encoder *encoder; - int changes = 0, still_going = 0; - - changes |= channels != rdev->audio_channels; - changes |= rate != rdev->audio_rate; - changes |= bps != rdev->audio_bits_per_sample; - changes |= status_bits != rdev->audio_status_bits; - changes |= category_code != rdev->audio_category_code; - - if (changes) { - rdev->audio_channels = channels; - rdev->audio_rate = rate; - rdev->audio_bits_per_sample = bps; - rdev->audio_status_bits = status_bits; - rdev->audio_category_code = category_code; - } - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - still_going |= radeon_encoder->audio_polling_active; - if (changes || r600_hdmi_buffer_status_changed(encoder)) - r600_hdmi_update_audio_settings(encoder); - } - - if (still_going) - r600_audio_schedule_polling(rdev); -} - -/* - * turn on/off audio engine - */ -static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) -{ - u32 value = 0; - DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling"); - if (ASIC_IS_DCE4(rdev)) { - if (enable) { - value |= 0x81000000; /* Required to enable audio */ - value |= 0x0e1000f0; /* fglrx sets that too */ - } - WREG32(EVERGREEN_AUDIO_ENABLE, value); - } else { - WREG32_P(R600_AUDIO_ENABLE, - enable ? 0x81000000 : 0x0, ~0x81000000); - } - rdev->audio_enabled = enable; -} - -/* - * initialize the audio vars and register the update timer - */ -int r600_audio_init(struct radeon_device *rdev) -{ - if (!radeon_audio || !r600_audio_chipset_supported(rdev)) - return 0; - - r600_audio_engine_enable(rdev, true); - - rdev->audio_channels = -1; - rdev->audio_rate = -1; - rdev->audio_bits_per_sample = -1; - rdev->audio_status_bits = 0; - rdev->audio_category_code = 0; - - setup_timer( - &rdev->audio_timer, - r600_audio_update_hdmi, - (unsigned long)rdev); - - return 0; -} - -/* - * enable the polling timer, to check for status changes - */ -void r600_audio_enable_polling(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - - DRM_DEBUG("r600_audio_enable_polling: %d\n", - radeon_encoder->audio_polling_active); - if (radeon_encoder->audio_polling_active) - return; - - radeon_encoder->audio_polling_active = 1; - if (rdev->audio_enabled) - mod_timer(&rdev->audio_timer, jiffies + 1); -} - -/* - * disable the polling timer, so we get no more status updates - */ -void r600_audio_disable_polling(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DRM_DEBUG("r600_audio_disable_polling: %d\n", - radeon_encoder->audio_polling_active); - radeon_encoder->audio_polling_active = 0; -} - -/* - * atach the audio codec to the clock source of the encoder - */ -void r600_audio_set_clock(struct drm_encoder *encoder, int clock) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - int base_rate = 48000; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - WREG32_P(R600_AUDIO_TIMING, 0, ~0x301); - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301); - break; - default: - dev_err(rdev->dev, "Unsupported encoder type 0x%02X\n", - radeon_encoder->encoder_id); - return; - } - - if (ASIC_IS_DCE4(rdev)) { - /* TODO: other PLLs? */ - WREG32(EVERGREEN_AUDIO_PLL1_MUL, base_rate * 10); - WREG32(EVERGREEN_AUDIO_PLL1_DIV, clock * 10); - WREG32(EVERGREEN_AUDIO_PLL1_UNK, 0x00000071); - - /* Select DTO source */ - WREG32(0x5ac, radeon_crtc->crtc_id); - } else { - switch (dig->dig_encoder) { - case 0: - WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50); - WREG32(R600_AUDIO_PLL1_DIV, clock * 100); - WREG32(R600_AUDIO_CLK_SRCSEL, 0); - break; - - case 1: - WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50); - WREG32(R600_AUDIO_PLL2_DIV, clock * 100); - WREG32(R600_AUDIO_CLK_SRCSEL, 1); - break; - default: - dev_err(rdev->dev, - "Unsupported DIG on encoder 0x%02X\n", - radeon_encoder->encoder_id); - return; - } - } -} - -/* - * release the audio timer - * TODO: How to do this correctly on SMP systems? - */ -void r600_audio_fini(struct radeon_device *rdev) -{ - if (!rdev->audio_enabled) - return; - - del_timer(&rdev->audio_timer); - - r600_audio_engine_enable(rdev, false); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit.c deleted file mode 100644 index 3c031a48..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Alex Deucher - */ -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -#include "r600_blit_shaders.h" - -#define DI_PT_RECTLIST 0x11 -#define DI_INDEX_SIZE_16_BIT 0x0 -#define DI_SRC_SEL_AUTO_INDEX 0x2 - -#define FMT_8 0x1 -#define FMT_5_6_5 0x8 -#define FMT_8_8_8_8 0x1a -#define COLOR_8 0x1 -#define COLOR_5_6_5 0x8 -#define COLOR_8_8_8_8 0x1a - -static void -set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr) -{ - u32 cb_color_info; - int pitch, slice; - RING_LOCALS; - DRM_DEBUG("\n"); - - h = ALIGN(h, 8); - if (h < 8) - h = 8; - - cb_color_info = ((format << 2) | (1 << 27)); - pitch = (w / 8) - 1; - slice = ((w * h) / 64) - 1; - - if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) && - ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) { - BEGIN_RING(21 + 2); - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(gpu_addr >> 8); - OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); - OUT_RING(2 << 0); - } else { - BEGIN_RING(21); - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(gpu_addr >> 8); - } - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING((pitch << 0) | (slice << 10)); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(0); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(cb_color_info); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(0); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(0); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(0); - - ADVANCE_RING(); -} - -static void -cp_set_surface_sync(drm_radeon_private_t *dev_priv, - u32 sync_type, u32 size, u64 mc_addr) -{ - u32 cp_coher_size; - RING_LOCALS; - DRM_DEBUG("\n"); - - if (size == 0xffffffff) - cp_coher_size = 0xffffffff; - else - cp_coher_size = ((size + 255) >> 8); - - BEGIN_RING(5); - OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3)); - OUT_RING(sync_type); - OUT_RING(cp_coher_size); - OUT_RING((mc_addr >> 8)); - OUT_RING(10); /* poll interval */ - ADVANCE_RING(); -} - -static void -set_shaders(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u64 gpu_addr; - int i; - u32 *vs, *ps; - uint32_t sq_pgm_resources; - RING_LOCALS; - DRM_DEBUG("\n"); - - /* load shaders */ - vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset); - ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); - - for (i = 0; i < r6xx_vs_size; i++) - vs[i] = cpu_to_le32(r6xx_vs[i]); - for (i = 0; i < r6xx_ps_size; i++) - ps[i] = cpu_to_le32(r6xx_ps[i]); - - dev_priv->blit_vb->used = 512; - - gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset; - - /* setup shader regs */ - sq_pgm_resources = (1 << 0); - - BEGIN_RING(9 + 12); - /* VS */ - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(gpu_addr >> 8); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(sq_pgm_resources); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(0); - - /* PS */ - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING((gpu_addr + 256) >> 8); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(sq_pgm_resources | (1 << 28)); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(2); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); - OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING(0); - ADVANCE_RING(); - - cp_set_surface_sync(dev_priv, - R600_SH_ACTION_ENA, 512, gpu_addr); -} - -static void -set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) -{ - uint32_t sq_vtx_constant_word2; - RING_LOCALS; - DRM_DEBUG("\n"); - - sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); -#ifdef __BIG_ENDIAN - sq_vtx_constant_word2 |= (2 << 30); -#endif - - BEGIN_RING(9); - OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); - OUT_RING(0x460); - OUT_RING(gpu_addr & 0xffffffff); - OUT_RING(48 - 1); - OUT_RING(sq_vtx_constant_word2); - OUT_RING(1 << 0); - OUT_RING(0); - OUT_RING(0); - OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30); - ADVANCE_RING(); - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) - cp_set_surface_sync(dev_priv, - R600_TC_ACTION_ENA, 48, gpu_addr); - else - cp_set_surface_sync(dev_priv, - R600_VC_ACTION_ENA, 48, gpu_addr); -} - -static void -set_tex_resource(drm_radeon_private_t *dev_priv, - int format, int w, int h, int pitch, u64 gpu_addr) -{ - uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; - RING_LOCALS; - DRM_DEBUG("\n"); - - if (h < 1) - h = 1; - - sq_tex_resource_word0 = (1 << 0); - sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | - ((w - 1) << 19)); - - sq_tex_resource_word1 = (format << 26); - sq_tex_resource_word1 |= ((h - 1) << 0); - - sq_tex_resource_word4 = ((1 << 14) | - (0 << 16) | - (1 << 19) | - (2 << 22) | - (3 << 25)); - - BEGIN_RING(9); - OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); - OUT_RING(0); - OUT_RING(sq_tex_resource_word0); - OUT_RING(sq_tex_resource_word1); - OUT_RING(gpu_addr >> 8); - OUT_RING(gpu_addr >> 8); - OUT_RING(sq_tex_resource_word4); - OUT_RING(0); - OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30); - ADVANCE_RING(); - -} - -static void -set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(12); - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); - OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING((x1 << 0) | (y1 << 16)); - OUT_RING((x2 << 0) | (y2 << 16)); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); - OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); - OUT_RING((x2 << 0) | (y2 << 16)); - - OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); - OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); - OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); - OUT_RING((x2 << 0) | (y2 << 16)); - ADVANCE_RING(); -} - -static void -draw_auto(drm_radeon_private_t *dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(10); - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); - OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2); - OUT_RING(DI_PT_RECTLIST); - - OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); -#ifdef __BIG_ENDIAN - OUT_RING((2 << 2) | DI_INDEX_SIZE_16_BIT); -#else - OUT_RING(DI_INDEX_SIZE_16_BIT); -#endif - - OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); - OUT_RING(1); - - OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); - OUT_RING(3); - OUT_RING(DI_SRC_SEL_AUTO_INDEX); - - ADVANCE_RING(); - COMMIT_RING(); -} - -static void -set_default_state(drm_radeon_private_t *dev_priv) -{ - int i; - u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; - u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; - int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; - int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; - int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; - RING_LOCALS; - - switch ((dev_priv->flags & RADEON_FAMILY_MASK)) { - case CHIP_R600: - num_ps_gprs = 192; - num_vs_gprs = 56; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 136; - num_vs_threads = 48; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 128; - num_vs_stack_entries = 128; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - case CHIP_RV630: - case CHIP_RV635: - num_ps_gprs = 84; - num_vs_gprs = 36; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 144; - num_vs_threads = 40; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 40; - num_vs_stack_entries = 40; - num_gs_stack_entries = 32; - num_es_stack_entries = 16; - break; - case CHIP_RV610: - case CHIP_RV620: - case CHIP_RS780: - case CHIP_RS880: - default: - num_ps_gprs = 84; - num_vs_gprs = 36; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 136; - num_vs_threads = 48; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 40; - num_vs_stack_entries = 40; - num_gs_stack_entries = 32; - num_es_stack_entries = 16; - break; - case CHIP_RV670: - num_ps_gprs = 144; - num_vs_gprs = 40; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 136; - num_vs_threads = 48; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 40; - num_vs_stack_entries = 40; - num_gs_stack_entries = 32; - num_es_stack_entries = 16; - break; - case CHIP_RV770: - num_ps_gprs = 192; - num_vs_gprs = 56; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 188; - num_vs_threads = 60; - num_gs_threads = 0; - num_es_threads = 0; - num_ps_stack_entries = 256; - num_vs_stack_entries = 256; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - case CHIP_RV730: - case CHIP_RV740: - num_ps_gprs = 84; - num_vs_gprs = 36; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 188; - num_vs_threads = 60; - num_gs_threads = 0; - num_es_threads = 0; - num_ps_stack_entries = 128; - num_vs_stack_entries = 128; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - case CHIP_RV710: - num_ps_gprs = 192; - num_vs_gprs = 56; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 144; - num_vs_threads = 48; - num_gs_threads = 0; - num_es_threads = 0; - num_ps_stack_entries = 128; - num_vs_stack_entries = 128; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - } - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) - sq_config = 0; - else - sq_config = R600_VC_ENABLE; - - sq_config |= (R600_DX9_CONSTS | - R600_ALU_INST_PREFER_VECTOR | - R600_PS_PRIO(0) | - R600_VS_PRIO(1) | - R600_GS_PRIO(2) | - R600_ES_PRIO(3)); - - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) | - R600_NUM_VS_GPRS(num_vs_gprs) | - R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) | - R600_NUM_ES_GPRS(num_es_gprs)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) | - R600_NUM_VS_THREADS(num_vs_threads) | - R600_NUM_GS_THREADS(num_gs_threads) | - R600_NUM_ES_THREADS(num_es_threads)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | - R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | - R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries)); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { - BEGIN_RING(r7xx_default_size + 10); - for (i = 0; i < r7xx_default_size; i++) - OUT_RING(r7xx_default_state[i]); - } else { - BEGIN_RING(r6xx_default_size + 10); - for (i = 0; i < r6xx_default_size; i++) - OUT_RING(r6xx_default_state[i]); - } - OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); - OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); - /* SQ config */ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6)); - OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2); - OUT_RING(sq_config); - OUT_RING(sq_gpr_resource_mgmt_1); - OUT_RING(sq_gpr_resource_mgmt_2); - OUT_RING(sq_thread_resource_mgmt); - OUT_RING(sq_stack_resource_mgmt_1); - OUT_RING(sq_stack_resource_mgmt_2); - ADVANCE_RING(); -} - -static uint32_t i2f(uint32_t input) -{ - u32 result, i, exponent, fraction; - - if ((input & 0x3fff) == 0) - result = 0; /* 0 is a special case */ - else { - exponent = 140; /* exponent biased by 127; */ - fraction = (input & 0x3fff) << 10; /* cheat and only - handle numbers below 2^^15 */ - for (i = 0; i < 14; i++) { - if (fraction & 0x800000) - break; - else { - fraction = fraction << 1; /* keep - shifting left until top bit = 1 */ - exponent = exponent - 1; - } - } - result = exponent << 23 | (fraction & 0x7fffff); /* mask - off top bit; assumed 1 */ - } - return result; -} - - -static int r600_nomm_get_vb(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - dev_priv->blit_vb = radeon_freelist_get(dev); - if (!dev_priv->blit_vb) { - DRM_ERROR("Unable to allocate vertex buffer for blit\n"); - return -EAGAIN; - } - return 0; -} - -static void r600_nomm_put_vb(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - dev_priv->blit_vb->used = 0; - radeon_cp_discard_buffer(dev, dev_priv->blit_vb->file_priv->master, dev_priv->blit_vb); -} - -static void *r600_nomm_get_vb_ptr(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - return (((char *)dev->agp_buffer_map->handle + - dev_priv->blit_vb->offset + dev_priv->blit_vb->used)); -} - -int -r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int ret; - DRM_DEBUG("\n"); - - ret = r600_nomm_get_vb(dev); - if (ret) - return ret; - - dev_priv->blit_vb->file_priv = file_priv; - - set_default_state(dev_priv); - set_shaders(dev); - - return 0; -} - - -void -r600_done_blit_copy(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5); - OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); - OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); - /* wait for 3D idle clean */ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); - OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); - OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); - - ADVANCE_RING(); - COMMIT_RING(); - - r600_nomm_put_vb(dev); -} - -void -r600_blit_copy(struct drm_device *dev, - uint64_t src_gpu_addr, uint64_t dst_gpu_addr, - int size_bytes) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int max_bytes; - u64 vb_addr; - u32 *vb; - - vb = r600_nomm_get_vb_ptr(dev); - - if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { - max_bytes = 8192; - - while (size_bytes) { - int cur_size = size_bytes; - int src_x = src_gpu_addr & 255; - int dst_x = dst_gpu_addr & 255; - int h = 1; - src_gpu_addr = src_gpu_addr & ~255; - dst_gpu_addr = dst_gpu_addr & ~255; - - if (!src_x && !dst_x) { - h = (cur_size / max_bytes); - if (h > 8192) - h = 8192; - if (h == 0) - h = 1; - else - cur_size = max_bytes; - } else { - if (cur_size > max_bytes) - cur_size = max_bytes; - if (cur_size > (max_bytes - dst_x)) - cur_size = (max_bytes - dst_x); - if (cur_size > (max_bytes - src_x)) - cur_size = (max_bytes - src_x); - } - - if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { - - r600_nomm_put_vb(dev); - r600_nomm_get_vb(dev); - if (!dev_priv->blit_vb) - return; - set_shaders(dev); - vb = r600_nomm_get_vb_ptr(dev); - } - - vb[0] = i2f(dst_x); - vb[1] = 0; - vb[2] = i2f(src_x); - vb[3] = 0; - - vb[4] = i2f(dst_x); - vb[5] = i2f(h); - vb[6] = i2f(src_x); - vb[7] = i2f(h); - - vb[8] = i2f(dst_x + cur_size); - vb[9] = i2f(h); - vb[10] = i2f(src_x + cur_size); - vb[11] = i2f(h); - - /* src */ - set_tex_resource(dev_priv, FMT_8, - src_x + cur_size, h, src_x + cur_size, - src_gpu_addr); - - cp_set_surface_sync(dev_priv, - R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); - - /* dst */ - set_render_target(dev_priv, COLOR_8, - dst_x + cur_size, h, - dst_gpu_addr); - - /* scissors */ - set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h); - - /* Vertex buffer setup */ - vb_addr = dev_priv->gart_buffers_offset + - dev_priv->blit_vb->offset + - dev_priv->blit_vb->used; - set_vtx_resource(dev_priv, vb_addr); - - /* draw */ - draw_auto(dev_priv); - - cp_set_surface_sync(dev_priv, - R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, - cur_size * h, dst_gpu_addr); - - vb += 12; - dev_priv->blit_vb->used += 12 * 4; - - src_gpu_addr += cur_size * h; - dst_gpu_addr += cur_size * h; - size_bytes -= cur_size * h; - } - } else { - max_bytes = 8192 * 4; - - while (size_bytes) { - int cur_size = size_bytes; - int src_x = (src_gpu_addr & 255); - int dst_x = (dst_gpu_addr & 255); - int h = 1; - src_gpu_addr = src_gpu_addr & ~255; - dst_gpu_addr = dst_gpu_addr & ~255; - - if (!src_x && !dst_x) { - h = (cur_size / max_bytes); - if (h > 8192) - h = 8192; - if (h == 0) - h = 1; - else - cur_size = max_bytes; - } else { - if (cur_size > max_bytes) - cur_size = max_bytes; - if (cur_size > (max_bytes - dst_x)) - cur_size = (max_bytes - dst_x); - if (cur_size > (max_bytes - src_x)) - cur_size = (max_bytes - src_x); - } - - if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { - r600_nomm_put_vb(dev); - r600_nomm_get_vb(dev); - if (!dev_priv->blit_vb) - return; - - set_shaders(dev); - vb = r600_nomm_get_vb_ptr(dev); - } - - vb[0] = i2f(dst_x / 4); - vb[1] = 0; - vb[2] = i2f(src_x / 4); - vb[3] = 0; - - vb[4] = i2f(dst_x / 4); - vb[5] = i2f(h); - vb[6] = i2f(src_x / 4); - vb[7] = i2f(h); - - vb[8] = i2f((dst_x + cur_size) / 4); - vb[9] = i2f(h); - vb[10] = i2f((src_x + cur_size) / 4); - vb[11] = i2f(h); - - /* src */ - set_tex_resource(dev_priv, FMT_8_8_8_8, - (src_x + cur_size) / 4, - h, (src_x + cur_size) / 4, - src_gpu_addr); - - cp_set_surface_sync(dev_priv, - R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); - - /* dst */ - set_render_target(dev_priv, COLOR_8_8_8_8, - (dst_x + cur_size) / 4, h, - dst_gpu_addr); - - /* scissors */ - set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h); - - /* Vertex buffer setup */ - vb_addr = dev_priv->gart_buffers_offset + - dev_priv->blit_vb->offset + - dev_priv->blit_vb->used; - set_vtx_resource(dev_priv, vb_addr); - - /* draw */ - draw_auto(dev_priv); - - cp_set_surface_sync(dev_priv, - R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, - cur_size * h, dst_gpu_addr); - - vb += 12; - dev_priv->blit_vb->used += 12 * 4; - - src_gpu_addr += cur_size * h; - dst_gpu_addr += cur_size * h; - size_bytes -= cur_size * h; - } - } -} - -void -r600_blit_swap(struct drm_device *dev, - uint64_t src_gpu_addr, uint64_t dst_gpu_addr, - int sx, int sy, int dx, int dy, - int w, int h, int src_pitch, int dst_pitch, int cpp) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int cb_format, tex_format; - int sx2, sy2, dx2, dy2; - u64 vb_addr; - u32 *vb; - - if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { - - r600_nomm_put_vb(dev); - r600_nomm_get_vb(dev); - if (!dev_priv->blit_vb) - return; - - set_shaders(dev); - } - vb = r600_nomm_get_vb_ptr(dev); - - sx2 = sx + w; - sy2 = sy + h; - dx2 = dx + w; - dy2 = dy + h; - - vb[0] = i2f(dx); - vb[1] = i2f(dy); - vb[2] = i2f(sx); - vb[3] = i2f(sy); - - vb[4] = i2f(dx); - vb[5] = i2f(dy2); - vb[6] = i2f(sx); - vb[7] = i2f(sy2); - - vb[8] = i2f(dx2); - vb[9] = i2f(dy2); - vb[10] = i2f(sx2); - vb[11] = i2f(sy2); - - switch(cpp) { - case 4: - cb_format = COLOR_8_8_8_8; - tex_format = FMT_8_8_8_8; - break; - case 2: - cb_format = COLOR_5_6_5; - tex_format = FMT_5_6_5; - break; - default: - cb_format = COLOR_8; - tex_format = FMT_8; - break; - } - - /* src */ - set_tex_resource(dev_priv, tex_format, - src_pitch / cpp, - sy2, src_pitch / cpp, - src_gpu_addr); - - cp_set_surface_sync(dev_priv, - R600_TC_ACTION_ENA, src_pitch * sy2, src_gpu_addr); - - /* dst */ - set_render_target(dev_priv, cb_format, - dst_pitch / cpp, dy2, - dst_gpu_addr); - - /* scissors */ - set_scissors(dev_priv, dx, dy, dx2, dy2); - - /* Vertex buffer setup */ - vb_addr = dev_priv->gart_buffers_offset + - dev_priv->blit_vb->offset + - dev_priv->blit_vb->used; - set_vtx_resource(dev_priv, vb_addr); - - /* draw */ - draw_auto(dev_priv); - - cp_set_surface_sync(dev_priv, - R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, - dst_pitch * dy2, dst_gpu_addr); - - dev_priv->blit_vb->used += 12 * 4; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_kms.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_kms.c deleted file mode 100644 index db38f587..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_kms.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon.h" - -#include "r600d.h" -#include "r600_blit_shaders.h" -#include "radeon_blit_common.h" - -/* emits 21 on rv770+, 23 on r600 */ -static void -set_render_target(struct radeon_device *rdev, int format, - int w, int h, u64 gpu_addr) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 cb_color_info; - int pitch, slice; - - h = ALIGN(h, 8); - if (h < 8) - h = 8; - - cb_color_info = CB_FORMAT(format) | - CB_SOURCE_FORMAT(CB_SF_EXPORT_NORM) | - CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - pitch = (w / 8) - 1; - slice = ((w * h) / 64) - 1; - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, gpu_addr >> 8); - - if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) { - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); - radeon_ring_write(ring, 2 << 0); - } - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, (pitch << 0) | (slice << 10)); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 0); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, cb_color_info); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 0); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 0); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 0); -} - -/* emits 5dw */ -static void -cp_set_surface_sync(struct radeon_device *rdev, - u32 sync_type, u32 size, - u64 mc_addr) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 cp_coher_size; - - if (size == 0xffffffff) - cp_coher_size = 0xffffffff; - else - cp_coher_size = ((size + 255) >> 8); - - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, sync_type); - radeon_ring_write(ring, cp_coher_size); - radeon_ring_write(ring, mc_addr >> 8); - radeon_ring_write(ring, 10); /* poll interval */ -} - -/* emits 21dw + 1 surface sync = 26dw */ -static void -set_shaders(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u64 gpu_addr; - u32 sq_pgm_resources; - - /* setup shader regs */ - sq_pgm_resources = (1 << 0); - - /* VS */ - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, gpu_addr >> 8); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, sq_pgm_resources); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 0); - - /* PS */ - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, gpu_addr >> 8); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, sq_pgm_resources | (1 << 28)); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 2); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(ring, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, 0); - - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); -} - -/* emits 9 + 1 sync (5) = 14*/ -static void -set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 sq_vtx_constant_word2; - - sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) | - SQ_VTXC_STRIDE(16); -#ifdef __BIG_ENDIAN - sq_vtx_constant_word2 |= SQ_VTXC_ENDIAN_SWAP(SQ_ENDIAN_8IN32); -#endif - - radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 7)); - radeon_ring_write(ring, 0x460); - radeon_ring_write(ring, gpu_addr & 0xffffffff); - radeon_ring_write(ring, 48 - 1); - radeon_ring_write(ring, sq_vtx_constant_word2); - radeon_ring_write(ring, 1 << 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, SQ_TEX_VTX_VALID_BUFFER << 30); - - if ((rdev->family == CHIP_RV610) || - (rdev->family == CHIP_RV620) || - (rdev->family == CHIP_RS780) || - (rdev->family == CHIP_RS880) || - (rdev->family == CHIP_RV710)) - cp_set_surface_sync(rdev, - PACKET3_TC_ACTION_ENA, 48, gpu_addr); - else - cp_set_surface_sync(rdev, - PACKET3_VC_ACTION_ENA, 48, gpu_addr); -} - -/* emits 9 */ -static void -set_tex_resource(struct radeon_device *rdev, - int format, int w, int h, int pitch, - u64 gpu_addr, u32 size) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; - - if (h < 1) - h = 1; - - sq_tex_resource_word0 = S_038000_DIM(V_038000_SQ_TEX_DIM_2D) | - S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); - sq_tex_resource_word0 |= S_038000_PITCH((pitch >> 3) - 1) | - S_038000_TEX_WIDTH(w - 1); - - sq_tex_resource_word1 = S_038004_DATA_FORMAT(format); - sq_tex_resource_word1 |= S_038004_TEX_HEIGHT(h - 1); - - sq_tex_resource_word4 = S_038010_REQUEST_SIZE(1) | - S_038010_DST_SEL_X(SQ_SEL_X) | - S_038010_DST_SEL_Y(SQ_SEL_Y) | - S_038010_DST_SEL_Z(SQ_SEL_Z) | - S_038010_DST_SEL_W(SQ_SEL_W); - - cp_set_surface_sync(rdev, - PACKET3_TC_ACTION_ENA, size, gpu_addr); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 7)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, sq_tex_resource_word0); - radeon_ring_write(ring, sq_tex_resource_word1); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(ring, sq_tex_resource_word4); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, SQ_TEX_VTX_VALID_TEXTURE << 30); -} - -/* emits 12 */ -static void -set_scissors(struct radeon_device *rdev, int x1, int y1, - int x2, int y2) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, (x1 << 0) | (y1 << 16)); - radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); -} - -/* emits 10 */ -static void -draw_auto(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(ring, DI_PT_RECTLIST); - - radeon_ring_write(ring, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 2) | -#endif - DI_INDEX_SIZE_16_BIT); - - radeon_ring_write(ring, PACKET3(PACKET3_NUM_INSTANCES, 0)); - radeon_ring_write(ring, 1); - - radeon_ring_write(ring, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); - radeon_ring_write(ring, 3); - radeon_ring_write(ring, DI_SRC_SEL_AUTO_INDEX); - -} - -/* emits 14 */ -static void -set_default_state(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; - u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; - int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; - int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; - int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; - u64 gpu_addr; - int dwords; - - switch (rdev->family) { - case CHIP_R600: - num_ps_gprs = 192; - num_vs_gprs = 56; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 136; - num_vs_threads = 48; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 128; - num_vs_stack_entries = 128; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - case CHIP_RV630: - case CHIP_RV635: - num_ps_gprs = 84; - num_vs_gprs = 36; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 144; - num_vs_threads = 40; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 40; - num_vs_stack_entries = 40; - num_gs_stack_entries = 32; - num_es_stack_entries = 16; - break; - case CHIP_RV610: - case CHIP_RV620: - case CHIP_RS780: - case CHIP_RS880: - default: - num_ps_gprs = 84; - num_vs_gprs = 36; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 136; - num_vs_threads = 48; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 40; - num_vs_stack_entries = 40; - num_gs_stack_entries = 32; - num_es_stack_entries = 16; - break; - case CHIP_RV670: - num_ps_gprs = 144; - num_vs_gprs = 40; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 136; - num_vs_threads = 48; - num_gs_threads = 4; - num_es_threads = 4; - num_ps_stack_entries = 40; - num_vs_stack_entries = 40; - num_gs_stack_entries = 32; - num_es_stack_entries = 16; - break; - case CHIP_RV770: - num_ps_gprs = 192; - num_vs_gprs = 56; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 188; - num_vs_threads = 60; - num_gs_threads = 0; - num_es_threads = 0; - num_ps_stack_entries = 256; - num_vs_stack_entries = 256; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - case CHIP_RV730: - case CHIP_RV740: - num_ps_gprs = 84; - num_vs_gprs = 36; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 188; - num_vs_threads = 60; - num_gs_threads = 0; - num_es_threads = 0; - num_ps_stack_entries = 128; - num_vs_stack_entries = 128; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - case CHIP_RV710: - num_ps_gprs = 192; - num_vs_gprs = 56; - num_temp_gprs = 4; - num_gs_gprs = 0; - num_es_gprs = 0; - num_ps_threads = 144; - num_vs_threads = 48; - num_gs_threads = 0; - num_es_threads = 0; - num_ps_stack_entries = 128; - num_vs_stack_entries = 128; - num_gs_stack_entries = 0; - num_es_stack_entries = 0; - break; - } - - if ((rdev->family == CHIP_RV610) || - (rdev->family == CHIP_RV620) || - (rdev->family == CHIP_RS780) || - (rdev->family == CHIP_RS880) || - (rdev->family == CHIP_RV710)) - sq_config = 0; - else - sq_config = VC_ENABLE; - - sq_config |= (DX9_CONSTS | - ALU_INST_PREFER_VECTOR | - PS_PRIO(0) | - VS_PRIO(1) | - GS_PRIO(2) | - ES_PRIO(3)); - - sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | - NUM_VS_GPRS(num_vs_gprs) | - NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); - sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | - NUM_ES_GPRS(num_es_gprs)); - sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | - NUM_VS_THREADS(num_vs_threads) | - NUM_GS_THREADS(num_gs_threads) | - NUM_ES_THREADS(num_es_threads)); - sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | - NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); - sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | - NUM_ES_STACK_ENTRIES(num_es_stack_entries)); - - /* emit an IB pointing at default state */ - dwords = ALIGN(rdev->r600_blit.state_len, 0x10); - gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; - radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xFF); - radeon_ring_write(ring, dwords); - - /* SQ config */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 6)); - radeon_ring_write(ring, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(ring, sq_config); - radeon_ring_write(ring, sq_gpr_resource_mgmt_1); - radeon_ring_write(ring, sq_gpr_resource_mgmt_2); - radeon_ring_write(ring, sq_thread_resource_mgmt); - radeon_ring_write(ring, sq_stack_resource_mgmt_1); - radeon_ring_write(ring, sq_stack_resource_mgmt_2); -} - -#define I2F_MAX_BITS 15 -#define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1) -#define I2F_SHIFT (24 - I2F_MAX_BITS) - -/* - * Converts unsigned integer into 32-bit IEEE floating point representation. - * Conversion is not universal and only works for the range from 0 - * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between - * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary, - * I2F_MAX_BITS can be increased, but that will add to the loop iterations - * and slow us down. Conversion is done by shifting the input and counting - * down until the first 1 reaches bit position 23. The resulting counter - * and the shifted input are, respectively, the exponent and the fraction. - * The sign is always zero. - */ -static uint32_t i2f(uint32_t input) -{ - u32 result, i, exponent, fraction; - - WARN_ON_ONCE(input > I2F_MAX_INPUT); - - if ((input & I2F_MAX_INPUT) == 0) - result = 0; - else { - exponent = 126 + I2F_MAX_BITS; - fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT; - - for (i = 0; i < I2F_MAX_BITS; i++) { - if (fraction & 0x800000) - break; - else { - fraction = fraction << 1; - exponent = exponent - 1; - } - } - result = exponent << 23 | (fraction & 0x7fffff); - } - return result; -} - -int r600_blit_init(struct radeon_device *rdev) -{ - u32 obj_size; - int i, r, dwords; - void *ptr; - u32 packet2s[16]; - int num_packet2s = 0; - - rdev->r600_blit.primitives.set_render_target = set_render_target; - rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync; - rdev->r600_blit.primitives.set_shaders = set_shaders; - rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource; - rdev->r600_blit.primitives.set_tex_resource = set_tex_resource; - rdev->r600_blit.primitives.set_scissors = set_scissors; - rdev->r600_blit.primitives.draw_auto = draw_auto; - rdev->r600_blit.primitives.set_default_state = set_default_state; - - rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ - rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ - rdev->r600_blit.ring_size_common += 5; /* done copy */ - rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ - - rdev->r600_blit.ring_size_per_loop = 76; - /* set_render_target emits 2 extra dwords on rv6xx */ - if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) - rdev->r600_blit.ring_size_per_loop += 2; - - rdev->r600_blit.max_dim = 8192; - - /* pin copy shader into vram if already initialized */ - if (rdev->r600_blit.shader_obj) - goto done; - - mutex_init(&rdev->r600_blit.mutex); - rdev->r600_blit.state_offset = 0; - - if (rdev->family >= CHIP_RV770) - rdev->r600_blit.state_len = r7xx_default_size; - else - rdev->r600_blit.state_len = r6xx_default_size; - - dwords = rdev->r600_blit.state_len; - while (dwords & 0xf) { - packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); - dwords++; - } - - obj_size = dwords * 4; - obj_size = ALIGN(obj_size, 256); - - rdev->r600_blit.vs_offset = obj_size; - obj_size += r6xx_vs_size * 4; - obj_size = ALIGN(obj_size, 256); - - rdev->r600_blit.ps_offset = obj_size; - obj_size += r6xx_ps_size * 4; - obj_size = ALIGN(obj_size, 256); - - r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, - &rdev->r600_blit.shader_obj); - if (r) { - DRM_ERROR("r600 failed to allocate shader\n"); - return r; - } - - DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n", - obj_size, - rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); - - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr); - if (r) { - DRM_ERROR("failed to map blit object %d\n", r); - return r; - } - if (rdev->family >= CHIP_RV770) - memcpy_toio(ptr + rdev->r600_blit.state_offset, - r7xx_default_state, rdev->r600_blit.state_len * 4); - else - memcpy_toio(ptr + rdev->r600_blit.state_offset, - r6xx_default_state, rdev->r600_blit.state_len * 4); - if (num_packet2s) - memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), - packet2s, num_packet2s * 4); - for (i = 0; i < r6xx_vs_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(r6xx_vs[i]); - for (i = 0; i < r6xx_ps_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(r6xx_ps[i]); - radeon_bo_kunmap(rdev->r600_blit.shader_obj); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - -done: - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, - &rdev->r600_blit.shader_gpu_addr); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - if (r) { - dev_err(rdev->dev, "(%d) pin blit object failed\n", r); - return r; - } - radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); - return 0; -} - -void r600_blit_fini(struct radeon_device *rdev) -{ - int r; - - radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - if (rdev->r600_blit.shader_obj == NULL) - return; - /* If we can't reserve the bo, unref should be enough to destroy - * it when it becomes idle. - */ - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (!r) { - radeon_bo_unpin(rdev->r600_blit.shader_obj); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - } - radeon_bo_unref(&rdev->r600_blit.shader_obj); -} - -static int r600_vb_ib_get(struct radeon_device *rdev, unsigned size) -{ - int r; - r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, - &rdev->r600_blit.vb_ib, size); - if (r) { - DRM_ERROR("failed to get IB for vertex buffer\n"); - return r; - } - - rdev->r600_blit.vb_total = size; - rdev->r600_blit.vb_used = 0; - return 0; -} - -static void r600_vb_ib_put(struct radeon_device *rdev) -{ - radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); - radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); -} - -static unsigned r600_blit_create_rect(unsigned num_gpu_pages, - int *width, int *height, int max_dim) -{ - unsigned max_pages; - unsigned pages = num_gpu_pages; - int w, h; - - if (num_gpu_pages == 0) { - /* not supposed to be called with no pages, but just in case */ - h = 0; - w = 0; - pages = 0; - WARN_ON(1); - } else { - int rect_order = 2; - h = RECT_UNIT_H; - while (num_gpu_pages / rect_order) { - h *= 2; - rect_order *= 4; - if (h >= max_dim) { - h = max_dim; - break; - } - } - max_pages = (max_dim * h) / (RECT_UNIT_W * RECT_UNIT_H); - if (pages > max_pages) - pages = max_pages; - w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h; - w = (w / RECT_UNIT_W) * RECT_UNIT_W; - pages = (w * h) / (RECT_UNIT_W * RECT_UNIT_H); - BUG_ON(pages == 0); - } - - - DRM_DEBUG("blit_rectangle: h=%d, w=%d, pages=%d\n", h, w, pages); - - /* return width and height only of the caller wants it */ - if (height) - *height = h; - if (width) - *width = w; - - return pages; -} - - -int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - int ring_size; - int num_loops = 0; - int dwords_per_loop = rdev->r600_blit.ring_size_per_loop; - - /* num loops */ - while (num_gpu_pages) { - num_gpu_pages -= - r600_blit_create_rect(num_gpu_pages, NULL, NULL, - rdev->r600_blit.max_dim); - num_loops++; - } - - /* 48 bytes for vertex per loop */ - r = r600_vb_ib_get(rdev, (num_loops*48)+256); - if (r) - return r; - - /* calculate number of loops correctly */ - ring_size = num_loops * dwords_per_loop; - ring_size += rdev->r600_blit.ring_size_common; - r = radeon_ring_lock(rdev, ring, ring_size); - if (r) - return r; - - rdev->r600_blit.primitives.set_default_state(rdev); - rdev->r600_blit.primitives.set_shaders(rdev); - return 0; -} - -void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) -{ - int r; - - if (rdev->r600_blit.vb_ib) - r600_vb_ib_put(rdev); - - if (fence) - r = radeon_fence_emit(rdev, fence); - - radeon_ring_unlock_commit(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); -} - -void r600_kms_blit_copy(struct radeon_device *rdev, - u64 src_gpu_addr, u64 dst_gpu_addr, - unsigned num_gpu_pages) -{ - u64 vb_gpu_addr; - u32 *vb; - - DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", - src_gpu_addr, dst_gpu_addr, - num_gpu_pages, rdev->r600_blit.vb_used); - vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); - - while (num_gpu_pages) { - int w, h; - unsigned size_in_bytes; - unsigned pages_per_loop = - r600_blit_create_rect(num_gpu_pages, &w, &h, - rdev->r600_blit.max_dim); - - size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE; - DRM_DEBUG("rectangle w=%d h=%d\n", w, h); - - if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { - WARN_ON(1); - } - - vb[0] = 0; - vb[1] = 0; - vb[2] = 0; - vb[3] = 0; - - vb[4] = 0; - vb[5] = i2f(h); - vb[6] = 0; - vb[7] = i2f(h); - - vb[8] = i2f(w); - vb[9] = i2f(h); - vb[10] = i2f(w); - vb[11] = i2f(h); - - rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, - w, h, w, src_gpu_addr, size_in_bytes); - rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8, - w, h, dst_gpu_addr); - rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h); - vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; - rdev->r600_blit.primitives.set_vtx_resource(rdev, vb_gpu_addr); - rdev->r600_blit.primitives.draw_auto(rdev); - rdev->r600_blit.primitives.cp_set_surface_sync(rdev, - PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, - size_in_bytes, dst_gpu_addr); - - vb += 12; - rdev->r600_blit.vb_used += 4*12; - src_gpu_addr += size_in_bytes; - dst_gpu_addr += size_in_bytes; - num_gpu_pages -= pages_per_loop; - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.c deleted file mode 100644 index 34c8b234..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ /dev/null @@ -1,719 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Alex Deucher - */ - -#include -#include -#include - -/* - * R6xx+ cards need to use the 3D engine to blit data which requires - * quite a bit of hw state setup. Rather than pull the whole 3D driver - * (which normally generates the 3D state) into the DRM, we opt to use - * statically generated state tables. The regsiter state and shaders - * were hand generated to support blitting functionality. See the 3D - * driver or documentation for descriptions of the registers and - * shader instructions. - */ - -const u32 r6xx_default_state[] = -{ - 0xc0002400, /* START_3D_CMDBUF */ - 0x00000000, - - 0xc0012800, /* CONTEXT_CONTROL */ - 0x80000000, - 0x80000000, - - 0xc0016800, - 0x00000010, - 0x00008000, /* WAIT_UNTIL */ - - 0xc0016800, - 0x00000542, - 0x07000003, /* TA_CNTL_AUX */ - - 0xc0016800, - 0x000005c5, - 0x00000000, /* VC_ENHANCE */ - - 0xc0016800, - 0x00000363, - 0x00000000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */ - - 0xc0016800, - 0x0000060c, - 0x82000000, /* DB_DEBUG */ - - 0xc0016800, - 0x0000060e, - 0x01020204, /* DB_WATERMARKS */ - - 0xc0026f00, - 0x00000000, - 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ - 0x00000000, /* SQ_VTX_START_INST_LOC */ - - 0xc0096900, - 0x0000022a, - 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0016900, - 0x00000004, - 0x00000000, /* DB_DEPTH_INFO */ - - 0xc0026900, - 0x0000000a, - 0x00000000, /* DB_STENCIL_CLEAR */ - 0x00000000, /* DB_DEPTH_CLEAR */ - - 0xc0016900, - 0x00000200, - 0x00000000, /* DB_DEPTH_CONTROL */ - - 0xc0026900, - 0x00000343, - 0x00000060, /* DB_RENDER_CONTROL */ - 0x00000040, /* DB_RENDER_OVERRIDE */ - - 0xc0016900, - 0x00000351, - 0x0000aa00, /* DB_ALPHA_TO_MASK */ - - 0xc00f6900, - 0x00000100, - 0x00000800, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* VGT_MIN_VTX_INDX */ - 0x00000000, /* VGT_INDX_OFFSET */ - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ - 0x00000000, /* SX_ALPHA_TEST_CONTROL */ - 0x00000000, /* CB_BLEND_RED */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, /* CB_FOG_RED */ - 0x00000000, - 0x00000000, - 0x00000000, /* DB_STENCILREFMASK */ - 0x00000000, /* DB_STENCILREFMASK_BF */ - 0x00000000, /* SX_ALPHA_REF */ - - 0xc0046900, - 0x0000030c, - 0x01000000, /* CB_CLRCMP_CNTL */ - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0046900, - 0x00000048, - 0x3f800000, /* CB_CLEAR_RED */ - 0x00000000, - 0x3f800000, - 0x3f800000, - - 0xc0016900, - 0x00000080, - 0x00000000, /* PA_SC_WINDOW_OFFSET */ - - 0xc00a6900, - 0x00000083, - 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ - 0x00000000, /* PA_SC_CLIPRECT_0_TL */ - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, /* PA_SC_EDGERULE */ - - 0xc0406900, - 0x00000094, - 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x00000292, - 0x00000000, /* PA_SC_MPASS_PS_CNTL */ - 0x00004010, /* PA_SC_MODE_CNTL */ - - 0xc0096900, - 0x00000300, - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - 0x0000002d, /* PA_SU_VTX_CNTL */ - 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ - 0x3f800000, - 0x3f800000, - 0x3f800000, - 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ - 0x00000000, - - 0xc0016900, - 0x00000312, - 0xffffffff, /* PA_SC_AA_MASK */ - - 0xc0066900, - 0x0000037e, - 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ - 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ - 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ - - 0xc0046900, - 0x000001b6, - 0x00000000, /* SPI_INPUT_Z */ - 0x00000000, /* SPI_FOG_CNTL */ - 0x00000000, /* SPI_FOG_FUNC_SCALE */ - 0x00000000, /* SPI_FOG_FUNC_BIAS */ - - 0xc0016900, - 0x00000225, - 0x00000000, /* SQ_PGM_START_FS */ - - 0xc0016900, - 0x00000229, - 0x00000000, /* SQ_PGM_RESOURCES_FS */ - - 0xc0016900, - 0x00000237, - 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ - - 0xc0026900, - 0x000002a8, - 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ - - 0xc0116900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ - 0x00000008, /* PA_SU_LINE_CNTL */ - 0x00000000, /* PA_SC_LINE_STIPPLE */ - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - 0x00000000, /* VGT_HOS_CNTL */ - 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ - 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ - 0x00000000, /* VGT_HOS_REUSE_DEPTH */ - 0x00000000, /* VGT_GROUP_PRIM_TYPE */ - 0x00000000, /* VGT_GROUP_FIRST_DECR */ - 0x00000000, /* VGT_GROUP_DECR */ - 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ - 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ - 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ - 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ - 0x00000000, /* VGT_GS_MODE */ - - 0xc0016900, - 0x000002a1, - 0x00000000, /* VGT_PRIMITIVEID_EN */ - - 0xc0016900, - 0x000002a5, - 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ - - 0xc0036900, - 0x000002ac, - 0x00000000, /* VGT_STRMOUT_EN */ - 0x00000000, /* VGT_REUSE_OFF */ - 0x00000000, /* VGT_VTX_CNT_EN */ - - 0xc0016900, - 0x000000d4, - 0x00000000, /* SX_MISC */ - - 0xc0016900, - 0x000002c8, - 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ - - 0xc0076900, - 0x00000202, - 0x00cc0000, /* CB_COLOR_CONTROL */ - 0x00000210, /* DB_SHADER_CNTL */ - 0x00010000, /* PA_CL_CLIP_CNTL */ - 0x00000244, /* PA_SU_SC_MODE_CNTL */ - 0x00000100, /* PA_CL_VTE_CNTL */ - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ - - 0xc0026900, - 0x0000008e, - 0x0000000f, /* CB_TARGET_MASK */ - 0x0000000f, /* CB_SHADER_MASK */ - - 0xc0016900, - 0x000001e8, - 0x00000001, /* CB_SHADER_CONTROL */ - - 0xc0016900, - 0x00000185, - 0x00000000, /* SPI_VS_OUT_ID_0 */ - - 0xc0016900, - 0x00000191, - 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ - - 0xc0056900, - 0x000001b1, - 0x00000000, /* SPI_VS_OUT_CONFIG */ - 0x00000000, /* SPI_THREAD_GROUPING */ - 0x00000001, /* SPI_PS_IN_CONTROL_0 */ - 0x00000000, /* SPI_PS_IN_CONTROL_1 */ - 0x00000000, /* SPI_INTERP_CONTROL_0 */ - - 0xc0036e00, /* SET_SAMPLER */ - 0x00000000, - 0x00000012, - 0x00000000, - 0x00000000, -}; - -const u32 r7xx_default_state[] = -{ - 0xc0012800, /* CONTEXT_CONTROL */ - 0x80000000, - 0x80000000, - - 0xc0016800, - 0x00000010, - 0x00008000, /* WAIT_UNTIL */ - - 0xc0016800, - 0x00000542, - 0x07000002, /* TA_CNTL_AUX */ - - 0xc0016800, - 0x000005c5, - 0x00000000, /* VC_ENHANCE */ - - 0xc0016800, - 0x00000363, - 0x00004000, /* SQ_DYN_GPR_CNTL_PS_FLUSH_REQ */ - - 0xc0016800, - 0x0000060c, - 0x00000000, /* DB_DEBUG */ - - 0xc0016800, - 0x0000060e, - 0x00420204, /* DB_WATERMARKS */ - - 0xc0026f00, - 0x00000000, - 0x00000000, /* SQ_VTX_BASE_VTX_LOC */ - 0x00000000, /* SQ_VTX_START_INST_LOC */ - - 0xc0096900, - 0x0000022a, - 0x00000000, /* SQ_ESGS_RING_ITEMSIZE */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0016900, - 0x00000004, - 0x00000000, /* DB_DEPTH_INFO */ - - 0xc0026900, - 0x0000000a, - 0x00000000, /* DB_STENCIL_CLEAR */ - 0x00000000, /* DB_DEPTH_CLEAR */ - - 0xc0016900, - 0x00000200, - 0x00000000, /* DB_DEPTH_CONTROL */ - - 0xc0026900, - 0x00000343, - 0x00000060, /* DB_RENDER_CONTROL */ - 0x00000000, /* DB_RENDER_OVERRIDE */ - - 0xc0016900, - 0x00000351, - 0x0000aa00, /* DB_ALPHA_TO_MASK */ - - 0xc0096900, - 0x00000100, - 0x00000800, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* VGT_MIN_VTX_INDX */ - 0x00000000, /* VGT_INDX_OFFSET */ - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ - 0x00000000, /* SX_ALPHA_TEST_CONTROL */ - 0x00000000, /* CB_BLEND_RED */ - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0036900, - 0x0000010c, - 0x00000000, /* DB_STENCILREFMASK */ - 0x00000000, /* DB_STENCILREFMASK_BF */ - 0x00000000, /* SX_ALPHA_REF */ - - 0xc0046900, - 0x0000030c, /* CB_CLRCMP_CNTL */ - 0x01000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0016900, - 0x00000080, - 0x00000000, /* PA_SC_WINDOW_OFFSET */ - - 0xc00a6900, - 0x00000083, - 0x0000ffff, /* PA_SC_CLIP_RECT_RULE */ - 0x00000000, /* PA_SC_CLIPRECT_0_TL */ - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0xaaaaaaaa, /* PA_SC_EDGERULE */ - - 0xc0406900, - 0x00000094, - 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - 0x80000000, /* PA_SC_VPORT_SCISSOR_1_TL */ - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - 0x00000000, - 0x3f800000, - - 0xc0026900, - 0x00000292, - 0x00000000, /* PA_SC_MPASS_PS_CNTL */ - 0x00514000, /* PA_SC_MODE_CNTL */ - - 0xc0096900, - 0x00000300, - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - 0x0000002d, /* PA_SU_VTX_CNTL */ - 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ - 0x3f800000, - 0x3f800000, - 0x3f800000, - 0x00000000, /* PA_SC_SAMPLE_LOCS_MCTX */ - 0x00000000, - - 0xc0016900, - 0x00000312, - 0xffffffff, /* PA_SC_AA_MASK */ - - 0xc0066900, - 0x0000037e, - 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - 0x00000000, /* PA_SU_POLY_OFFSET_CLAMP */ - 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_SCALE */ - 0x00000000, /* PA_SU_POLY_OFFSET_FRONT_OFFSET */ - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_SCALE */ - 0x00000000, /* PA_SU_POLY_OFFSET_BACK_OFFSET */ - - 0xc0046900, - 0x000001b6, - 0x00000000, /* SPI_INPUT_Z */ - 0x00000000, /* SPI_FOG_CNTL */ - 0x00000000, /* SPI_FOG_FUNC_SCALE */ - 0x00000000, /* SPI_FOG_FUNC_BIAS */ - - 0xc0016900, - 0x00000225, - 0x00000000, /* SQ_PGM_START_FS */ - - 0xc0016900, - 0x00000229, - 0x00000000, /* SQ_PGM_RESOURCES_FS */ - - 0xc0016900, - 0x00000237, - 0x00000000, /* SQ_PGM_CF_OFFSET_FS */ - - 0xc0026900, - 0x000002a8, - 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - 0x00000000, /* VGT_INSTANCE_STEP_RATE_1 */ - - 0xc0116900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ - 0x00000008, /* PA_SU_LINE_CNTL */ - 0x00000000, /* PA_SC_LINE_STIPPLE */ - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - 0x00000000, /* VGT_HOS_CNTL */ - 0x00000000, /* VGT_HOS_MAX_TESS_LEVEL */ - 0x00000000, /* VGT_HOS_MIN_TESS_LEVEL */ - 0x00000000, /* VGT_HOS_REUSE_DEPTH */ - 0x00000000, /* VGT_GROUP_PRIM_TYPE */ - 0x00000000, /* VGT_GROUP_FIRST_DECR */ - 0x00000000, /* VGT_GROUP_DECR */ - 0x00000000, /* VGT_GROUP_VECT_0_CNTL */ - 0x00000000, /* VGT_GROUP_VECT_1_CNTL */ - 0x00000000, /* VGT_GROUP_VECT_0_FMT_CNTL */ - 0x00000000, /* VGT_GROUP_VECT_1_FMT_CNTL */ - 0x00000000, /* VGT_GS_MODE */ - - 0xc0016900, - 0x000002a1, - 0x00000000, /* VGT_PRIMITIVEID_EN */ - - 0xc0016900, - 0x000002a5, - 0x00000000, /* VGT_MULTI_PRIM_ID_RESET_EN */ - - 0xc0036900, - 0x000002ac, - 0x00000000, /* VGT_STRMOUT_EN */ - 0x00000000, /* VGT_REUSE_OFF */ - 0x00000000, /* VGT_VTX_CNT_EN */ - - 0xc0016900, - 0x000000d4, - 0x00000000, /* SX_MISC */ - - 0xc0016900, - 0x000002c8, - 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ - - 0xc0076900, - 0x00000202, - 0x00cc0000, /* CB_COLOR_CONTROL */ - 0x00000210, /* DB_SHADER_CNTL */ - 0x00010000, /* PA_CL_CLIP_CNTL */ - 0x00000244, /* PA_SU_SC_MODE_CNTL */ - 0x00000100, /* PA_CL_VTE_CNTL */ - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ - - 0xc0026900, - 0x0000008e, - 0x0000000f, /* CB_TARGET_MASK */ - 0x0000000f, /* CB_SHADER_MASK */ - - 0xc0016900, - 0x000001e8, - 0x00000001, /* CB_SHADER_CONTROL */ - - 0xc0016900, - 0x00000185, - 0x00000000, /* SPI_VS_OUT_ID_0 */ - - 0xc0016900, - 0x00000191, - 0x00000b00, /* SPI_PS_INPUT_CNTL_0 */ - - 0xc0056900, - 0x000001b1, - 0x00000000, /* SPI_VS_OUT_CONFIG */ - 0x00000001, /* SPI_THREAD_GROUPING */ - 0x00000001, /* SPI_PS_IN_CONTROL_0 */ - 0x00000000, /* SPI_PS_IN_CONTROL_1 */ - 0x00000000, /* SPI_INTERP_CONTROL_0 */ - - 0xc0036e00, /* SET_SAMPLER */ - 0x00000000, - 0x00000012, - 0x00000000, - 0x00000000, -}; - -/* same for r6xx/r7xx */ -const u32 r6xx_vs[] = -{ - 0x00000004, - 0x81000000, - 0x0000203c, - 0x94000b08, - 0x00004000, - 0x14200b1a, - 0x00000000, - 0x00000000, - 0x3c000000, - 0x68cd1000, -#ifdef __BIG_ENDIAN - 0x000a0000, -#else - 0x00080000, -#endif - 0x00000000, -}; - -const u32 r6xx_ps[] = -{ - 0x00000002, - 0x80800000, - 0x00000000, - 0x94200688, - 0x00000010, - 0x000d1000, - 0xb0800000, - 0x00000000, -}; - -const u32 r6xx_ps_size = ARRAY_SIZE(r6xx_ps); -const u32 r6xx_vs_size = ARRAY_SIZE(r6xx_vs); -const u32 r6xx_default_size = ARRAY_SIZE(r6xx_default_state); -const u32 r7xx_default_size = ARRAY_SIZE(r7xx_default_state); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.h deleted file mode 100644 index f437d36d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_blit_shaders.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef R600_BLIT_SHADERS_H -#define R600_BLIT_SHADERS_H - -extern const u32 r6xx_ps[]; -extern const u32 r6xx_vs[]; -extern const u32 r7xx_default_state[]; -extern const u32 r6xx_default_state[]; - - -extern const u32 r6xx_ps_size, r6xx_vs_size; -extern const u32 r6xx_default_size, r7xx_default_size; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cp.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cp.c deleted file mode 100644 index 75ed17c9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cp.c +++ /dev/null @@ -1,2664 +0,0 @@ -/* - * Copyright 2008-2009 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Dave Airlie - * Alex Deucher - */ - -#include - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -#define PFP_UCODE_SIZE 576 -#define PM4_UCODE_SIZE 1792 -#define R700_PFP_UCODE_SIZE 848 -#define R700_PM4_UCODE_SIZE 1360 - -/* Firmware Names */ -MODULE_FIRMWARE("radeon/R600_pfp.bin"); -MODULE_FIRMWARE("radeon/R600_me.bin"); -MODULE_FIRMWARE("radeon/RV610_pfp.bin"); -MODULE_FIRMWARE("radeon/RV610_me.bin"); -MODULE_FIRMWARE("radeon/RV630_pfp.bin"); -MODULE_FIRMWARE("radeon/RV630_me.bin"); -MODULE_FIRMWARE("radeon/RV620_pfp.bin"); -MODULE_FIRMWARE("radeon/RV620_me.bin"); -MODULE_FIRMWARE("radeon/RV635_pfp.bin"); -MODULE_FIRMWARE("radeon/RV635_me.bin"); -MODULE_FIRMWARE("radeon/RV670_pfp.bin"); -MODULE_FIRMWARE("radeon/RV670_me.bin"); -MODULE_FIRMWARE("radeon/RS780_pfp.bin"); -MODULE_FIRMWARE("radeon/RS780_me.bin"); -MODULE_FIRMWARE("radeon/RV770_pfp.bin"); -MODULE_FIRMWARE("radeon/RV770_me.bin"); -MODULE_FIRMWARE("radeon/RV730_pfp.bin"); -MODULE_FIRMWARE("radeon/RV730_me.bin"); -MODULE_FIRMWARE("radeon/RV710_pfp.bin"); -MODULE_FIRMWARE("radeon/RV710_me.bin"); - - -int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, - unsigned family, u32 *ib, int *l); -void r600_cs_legacy_init(void); - - -# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ -# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) - -#define R600_PTE_VALID (1 << 0) -#define R600_PTE_SYSTEM (1 << 1) -#define R600_PTE_SNOOPED (1 << 2) -#define R600_PTE_READABLE (1 << 5) -#define R600_PTE_WRITEABLE (1 << 6) - -/* MAX values used for gfx init */ -#define R6XX_MAX_SH_GPRS 256 -#define R6XX_MAX_TEMP_GPRS 16 -#define R6XX_MAX_SH_THREADS 256 -#define R6XX_MAX_SH_STACK_ENTRIES 4096 -#define R6XX_MAX_BACKENDS 8 -#define R6XX_MAX_BACKENDS_MASK 0xff -#define R6XX_MAX_SIMDS 8 -#define R6XX_MAX_SIMDS_MASK 0xff -#define R6XX_MAX_PIPES 8 -#define R6XX_MAX_PIPES_MASK 0xff - -#define R7XX_MAX_SH_GPRS 256 -#define R7XX_MAX_TEMP_GPRS 16 -#define R7XX_MAX_SH_THREADS 256 -#define R7XX_MAX_SH_STACK_ENTRIES 4096 -#define R7XX_MAX_BACKENDS 8 -#define R7XX_MAX_BACKENDS_MASK 0xff -#define R7XX_MAX_SIMDS 16 -#define R7XX_MAX_SIMDS_MASK 0xffff -#define R7XX_MAX_PIPES 8 -#define R7XX_MAX_PIPES_MASK 0xff - -static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries) -{ - int i; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - int slots; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - slots = (RADEON_READ(R600_GRBM_STATUS) - & R700_CMDFIFO_AVAIL_MASK); - else - slots = (RADEON_READ(R600_GRBM_STATUS) - & R600_CMDFIFO_AVAIL_MASK); - if (slots >= entries) - return 0; - DRM_UDELAY(1); - } - DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n", - RADEON_READ(R600_GRBM_STATUS), - RADEON_READ(R600_GRBM_STATUS2)); - - return -EBUSY; -} - -static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv) -{ - int i, ret; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - ret = r600_do_wait_for_fifo(dev_priv, 8); - else - ret = r600_do_wait_for_fifo(dev_priv, 16); - if (ret) - return ret; - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE)) - return 0; - DRM_UDELAY(1); - } - DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n", - RADEON_READ(R600_GRBM_STATUS), - RADEON_READ(R600_GRBM_STATUS2)); - - return -EBUSY; -} - -void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) -{ - struct drm_sg_mem *entry = dev->sg; - int max_pages; - int pages; - int i; - - if (!entry) - return; - - if (gart_info->bus_addr) { - max_pages = (gart_info->table_size / sizeof(u64)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; - - for (i = 0; i < pages; i++) { - if (!entry->busaddr[i]) - break; - pci_unmap_page(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - } - if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) - gart_info->bus_addr = 0; - } -} - -/* R600 has page table setup */ -int r600_page_table_init(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; - struct drm_local_map *map = &gart_info->mapping; - struct drm_sg_mem *entry = dev->sg; - int ret = 0; - int i, j; - int pages; - u64 page_base; - dma_addr_t entry_addr; - int max_ati_pages, max_real_pages, gart_idx; - - /* okay page table is available - lets rock */ - max_ati_pages = (gart_info->table_size / sizeof(u64)); - max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); - - pages = (entry->pages <= max_real_pages) ? - entry->pages : max_real_pages; - - memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u64)); - - gart_idx = 0; - for (i = 0; i < pages; i++) { - entry->busaddr[i] = pci_map_page(dev->pdev, - entry->pagelist[i], 0, - PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, entry->busaddr[i])) { - DRM_ERROR("unable to map PCIGART pages!\n"); - r600_page_table_cleanup(dev, gart_info); - goto done; - } - entry_addr = entry->busaddr[i]; - for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK; - page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; - page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; - - DRM_WRITE64(map, gart_idx * sizeof(u64), page_base); - - gart_idx++; - - if ((i % 128) == 0) - DRM_DEBUG("page entry %d: 0x%016llx\n", - i, (unsigned long long)page_base); - entry_addr += ATI_PCIGART_PAGE_SIZE; - } - } - ret = 1; -done: - return ret; -} - -static void r600_vm_flush_gart_range(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 resp, countdown = 1000; - RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2); - - do { - resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE); - countdown--; - DRM_UDELAY(1); - } while (((resp & 0xf0) == 0) && countdown); -} - -static void r600_vm_init(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - /* initialise the VM to use the page table we constructed up there */ - u32 vm_c0, i; - u32 mc_rd_a; - u32 vm_l2_cntl, vm_l2_cntl3; - /* okay set up the PCIE aperture type thingo */ - RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); - - /* setup MC RD a */ - mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS | - R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) | - R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY; - - RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING); - RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/); - - RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a); - RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a); - - RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE); - RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a); - - vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; - vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7); - RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); - - RADEON_WRITE(R600_VM_L2_CNTL2, 0); - vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) | - R600_VM_L2_CNTL3_BANK_SELECT_1(1) | - R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2)); - RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); - - vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; - - RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); - - vm_c0 &= ~R600_VM_ENABLE_CONTEXT; - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); - - RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - - r600_vm_flush_gart_range(dev); -} - -static int r600_cp_init_microcode(drm_radeon_private_t *dev_priv) -{ - struct platform_device *pdev; - const char *chip_name; - size_t pfp_req_size, me_req_size; - char fw_name[30]; - int err; - - pdev = platform_device_register_simple("r600_cp", 0, NULL, 0); - err = IS_ERR(pdev); - if (err) { - printk(KERN_ERR "r600_cp: Failed to register firmware\n"); - return -EINVAL; - } - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_R600: chip_name = "R600"; break; - case CHIP_RV610: chip_name = "RV610"; break; - case CHIP_RV630: chip_name = "RV630"; break; - case CHIP_RV620: chip_name = "RV620"; break; - case CHIP_RV635: chip_name = "RV635"; break; - case CHIP_RV670: chip_name = "RV670"; break; - case CHIP_RS780: - case CHIP_RS880: chip_name = "RS780"; break; - case CHIP_RV770: chip_name = "RV770"; break; - case CHIP_RV730: - case CHIP_RV740: chip_name = "RV730"; break; - case CHIP_RV710: chip_name = "RV710"; break; - default: BUG(); - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { - pfp_req_size = R700_PFP_UCODE_SIZE * 4; - me_req_size = R700_PM4_UCODE_SIZE * 4; - } else { - pfp_req_size = PFP_UCODE_SIZE * 4; - me_req_size = PM4_UCODE_SIZE * 12; - } - - DRM_INFO("Loading %s CP Microcode\n", chip_name); - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); - err = request_firmware(&dev_priv->pfp_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (dev_priv->pfp_fw->size != pfp_req_size) { - printk(KERN_ERR - "r600_cp: Bogus length %zu in firmware \"%s\"\n", - dev_priv->pfp_fw->size, fw_name); - err = -EINVAL; - goto out; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); - err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (dev_priv->me_fw->size != me_req_size) { - printk(KERN_ERR - "r600_cp: Bogus length %zu in firmware \"%s\"\n", - dev_priv->me_fw->size, fw_name); - err = -EINVAL; - } -out: - platform_device_unregister(pdev); - - if (err) { - if (err != -EINVAL) - printk(KERN_ERR - "r600_cp: Failed to load firmware \"%s\"\n", - fw_name); - release_firmware(dev_priv->pfp_fw); - dev_priv->pfp_fw = NULL; - release_firmware(dev_priv->me_fw); - dev_priv->me_fw = NULL; - } - return err; -} - -static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) -{ - const __be32 *fw_data; - int i; - - if (!dev_priv->me_fw || !dev_priv->pfp_fw) - return; - - r600_do_cp_stop(dev_priv); - - RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif - R600_RB_NO_UPDATE | - R600_RB_BLKSZ(15) | - R600_RB_BUFSZ(3)); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); - RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - - fw_data = (const __be32 *)dev_priv->me_fw->data; - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - for (i = 0; i < PM4_UCODE_SIZE * 3; i++) - RADEON_WRITE(R600_CP_ME_RAM_DATA, - be32_to_cpup(fw_data++)); - - fw_data = (const __be32 *)dev_priv->pfp_fw->data; - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, - be32_to_cpup(fw_data++)); - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); - -} - -static void r700_vm_init(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - /* initialise the VM to use the page table we constructed up there */ - u32 vm_c0, i; - u32 mc_vm_md_l1; - u32 vm_l2_cntl, vm_l2_cntl3; - /* okay set up the PCIE aperture type thingo */ - RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); - - mc_vm_md_l1 = R700_ENABLE_L1_TLB | - R700_ENABLE_L1_FRAGMENT_PROCESSING | - R700_SYSTEM_ACCESS_MODE_IN_SYS | - R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - R700_EFFECTIVE_L1_TLB_SIZE(5) | - R700_EFFECTIVE_L1_QUEUE_SIZE(5); - - RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1); - RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1); - - vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; - vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7); - RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); - - RADEON_WRITE(R600_VM_L2_CNTL2, 0); - vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); - RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); - - vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; - - RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); - - vm_c0 &= ~R600_VM_ENABLE_CONTEXT; - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); - - RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); - RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); - RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); - - r600_vm_flush_gart_range(dev); -} - -static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) -{ - const __be32 *fw_data; - int i; - - if (!dev_priv->me_fw || !dev_priv->pfp_fw) - return; - - r600_do_cp_stop(dev_priv); - - RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif - R600_RB_NO_UPDATE | - R600_RB_BLKSZ(15) | - R600_RB_BUFSZ(3)); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); - RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - - fw_data = (const __be32 *)dev_priv->pfp_fw->data; - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < R700_PFP_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - - fw_data = (const __be32 *)dev_priv->me_fw->data; - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - for (i = 0; i < R700_PM4_UCODE_SIZE; i++) - RADEON_WRITE(R600_CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); - -} - -static void r600_test_writeback(drm_radeon_private_t *dev_priv) -{ - u32 tmp; - - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - - /* Writeback doesn't seem to work everywhere, test it here and possibly - * enable it if it appears to work - */ - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); - - RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef); - - for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - u32 val; - - val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1)); - if (val == 0xdeadbeef) - break; - DRM_UDELAY(1); - } - - if (tmp < dev_priv->usec_timeout) { - dev_priv->writeback_works = 1; - DRM_INFO("writeback test succeeded in %d usecs\n", tmp); - } else { - dev_priv->writeback_works = 0; - DRM_INFO("writeback test failed\n"); - } - if (radeon_no_wb == 1) { - dev_priv->writeback_works = 0; - DRM_INFO("writeback forced off\n"); - } - - if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif - RADEON_READ(R600_CP_RB_CNTL) | - R600_RB_NO_UPDATE); - RADEON_WRITE(R600_SCRATCH_UMSK, 0); - } -} - -int r600_do_engine_reset(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 cp_ptr, cp_me_cntl, cp_rb_cntl; - - DRM_INFO("Resetting GPU\n"); - - cp_ptr = RADEON_READ(R600_CP_RB_WPTR); - cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL); - RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff); - RADEON_READ(R600_GRBM_SOFT_RESET); - DRM_UDELAY(50); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - RADEON_READ(R600_GRBM_SOFT_RESET); - - RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); - cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); - RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif - R600_RB_RPTR_WR_ENA); - - RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); - RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); - RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl); - RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl); - - /* Reset the CP ring */ - r600_do_cp_reset(dev_priv); - - /* The CP is no longer running after an engine reset */ - dev_priv->cp_running = 0; - - /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset(dev); - - return 0; - -} - -static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R6XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - - if (num_tile_pipes > R6XX_MAX_PIPES) - num_tile_pipes = R6XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R6XX_MAX_BACKENDS) - num_backends = R6XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - break; - case 4: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - break; - case 5: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - break; - case 6: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - break; - case 7: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - break; - case 8: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; - } - - return backend_map; -} - -static int r600_count_pipe_bits(uint32_t val) -{ - int i, ret = 0; - for (i = 0; i < 32; i++) { - ret += val & 1; - val >>= 1; - } - return ret; -} - -static void r600_gfx_init(struct drm_device *dev, - drm_radeon_private_t *dev_priv) -{ - int i, j, num_qd_pipes; - u32 sx_debug_1; - u32 tc_cntl; - u32 arb_pop; - u32 num_gs_verts_per_thread; - u32 vgt_gs_per_es; - u32 gs_prim_buffer_depth = 0; - u32 sq_ms_fifo_sizes; - u32 sq_config; - u32 sq_gpr_resource_mgmt_1 = 0; - u32 sq_gpr_resource_mgmt_2 = 0; - u32 sq_thread_resource_mgmt = 0; - u32 sq_stack_resource_mgmt_1 = 0; - u32 sq_stack_resource_mgmt_2 = 0; - u32 hdp_host_path_cntl; - u32 backend_map; - u32 gb_tiling_config = 0; - u32 cc_rb_backend_disable; - u32 cc_gc_shader_pipe_config; - u32 ramcfg; - - /* setup chip specs */ - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_R600: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 8; - dev_priv->r600_max_simds = 4; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 2; - break; - case CHIP_RV630: - case CHIP_RV635: - dev_priv->r600_max_pipes = 2; - dev_priv->r600_max_tile_pipes = 2; - dev_priv->r600_max_simds = 3; - dev_priv->r600_max_backends = 1; - dev_priv->r600_max_gprs = 128; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 128; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 4; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 2; - break; - case CHIP_RV610: - case CHIP_RS780: - case CHIP_RS880: - case CHIP_RV620: - dev_priv->r600_max_pipes = 1; - dev_priv->r600_max_tile_pipes = 1; - dev_priv->r600_max_simds = 2; - dev_priv->r600_max_backends = 1; - dev_priv->r600_max_gprs = 128; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 128; - dev_priv->r600_max_hw_contexts = 4; - dev_priv->r600_max_gs_threads = 4; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 1; - break; - case CHIP_RV670: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 4; - dev_priv->r600_max_simds = 4; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 192; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 128; - dev_priv->r600_sq_num_cf_insts = 2; - break; - default: - break; - } - - /* Initialize HDP */ - j = 0; - for (i = 0; i < 32; i++) { - RADEON_WRITE((0x2c14 + j), 0x00000000); - RADEON_WRITE((0x2c18 + j), 0x00000000); - RADEON_WRITE((0x2c1c + j), 0x00000000); - RADEON_WRITE((0x2c20 + j), 0x00000000); - RADEON_WRITE((0x2c24 + j), 0x00000000); - j += 0x18; - } - - RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); - - /* setup tiling, simd, pipe config */ - ramcfg = RADEON_READ(R600_RAMCFG); - - switch (dev_priv->r600_max_tile_pipes) { - case 1: - gb_tiling_config |= R600_PIPE_TILING(0); - break; - case 2: - gb_tiling_config |= R600_PIPE_TILING(1); - break; - case 4: - gb_tiling_config |= R600_PIPE_TILING(2); - break; - case 8: - gb_tiling_config |= R600_PIPE_TILING(3); - break; - default: - break; - } - - gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK); - - gb_tiling_config |= R600_GROUP_SIZE(0); - - if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) { - gb_tiling_config |= R600_ROW_TILING(3); - gb_tiling_config |= R600_SAMPLE_SPLIT(3); - } else { - gb_tiling_config |= - R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); - gb_tiling_config |= - R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); - } - - gb_tiling_config |= R600_BANK_SWAPS(1); - - cc_rb_backend_disable = RADEON_READ(R600_CC_RB_BACKEND_DISABLE) & 0x00ff0000; - cc_rb_backend_disable |= - R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK); - - cc_gc_shader_pipe_config = RADEON_READ(R600_CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; - cc_gc_shader_pipe_config |= - R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK); - - backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, - (R6XX_MAX_BACKENDS - - r600_count_pipe_bits((cc_rb_backend_disable & - R6XX_MAX_BACKENDS_MASK) >> 16)), - (cc_rb_backend_disable >> 16)); - gb_tiling_config |= R600_BACKEND_MAP(backend_map); - - RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); - RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - if (gb_tiling_config & 0xc0) { - dev_priv->r600_group_size = 512; - } else { - dev_priv->r600_group_size = 256; - } - dev_priv->r600_npipes = 1 << ((gb_tiling_config >> 1) & 0x7); - if (gb_tiling_config & 0x30) { - dev_priv->r600_nbanks = 8; - } else { - dev_priv->r600_nbanks = 4; - } - - RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - num_qd_pipes = - R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8); - RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); - RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); - - /* set HW defaults for 3D engine */ - RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | - R600_ROQ_IB2_START(0x2b))); - - RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) | - R600_ROQ_END(0x40))); - - RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | - R600_SYNC_GRADIENT | - R600_SYNC_WALKER | - R600_SYNC_ALIGNER)); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) - RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021); - - sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1); - sx_debug_1 |= R600_SMX_EVENT_RELEASE; - if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600)) - sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS; - RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1); - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) - RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); - else - RADEON_WRITE(R600_DB_DEBUG, 0); - - RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) | - R600_DEPTH_FLUSH(16) | - R600_DEPTH_PENDING_FREE(4) | - R600_DEPTH_CACHELINE_FREE(16))); - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0); - - RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); - RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0)); - - sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { - sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | - R600_FETCH_FIFO_HIWATER(0xa) | - R600_DONE_FIFO_HIWATER(0xe0) | - R600_ALU_UPDATE_FIFO_HIWATER(0x8)); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { - sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff); - sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4); - } - RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); - - /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT - * should be adjusted as needed by the 2D/3D drivers. This just sets default values - */ - sq_config = RADEON_READ(R600_SQ_CONFIG); - sq_config &= ~(R600_PS_PRIO(3) | - R600_VS_PRIO(3) | - R600_GS_PRIO(3) | - R600_ES_PRIO(3)); - sq_config |= (R600_DX9_CONSTS | - R600_VC_ENABLE | - R600_PS_PRIO(0) | - R600_VS_PRIO(1) | - R600_GS_PRIO(2) | - R600_ES_PRIO(3)); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) { - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) | - R600_NUM_VS_GPRS(124) | - R600_NUM_CLAUSE_TEMP_GPRS(4)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) | - R600_NUM_ES_GPRS(0)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) | - R600_NUM_VS_THREADS(48) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(4)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) | - R600_NUM_VS_STACK_ENTRIES(128)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) | - R600_NUM_ES_STACK_ENTRIES(0)); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { - /* no vertex cache */ - sq_config &= ~R600_VC_ENABLE; - - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | - R600_NUM_VS_GPRS(44) | - R600_NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | - R600_NUM_ES_GPRS(17)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | - R600_NUM_VS_THREADS(78) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | - R600_NUM_VS_STACK_ENTRIES(40)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | - R600_NUM_ES_STACK_ENTRIES(16)); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | - R600_NUM_VS_GPRS(44) | - R600_NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) | - R600_NUM_ES_GPRS(18)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | - R600_NUM_VS_THREADS(78) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | - R600_NUM_VS_STACK_ENTRIES(40)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | - R600_NUM_ES_STACK_ENTRIES(16)); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) { - sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | - R600_NUM_VS_GPRS(44) | - R600_NUM_CLAUSE_TEMP_GPRS(2)); - sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | - R600_NUM_ES_GPRS(17)); - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | - R600_NUM_VS_THREADS(78) | - R600_NUM_GS_THREADS(4) | - R600_NUM_ES_THREADS(31)); - sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) | - R600_NUM_VS_STACK_ENTRIES(64)); - sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) | - R600_NUM_ES_STACK_ENTRIES(64)); - } - - RADEON_WRITE(R600_SQ_CONFIG, sq_config); - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); - RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); - else - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); - - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) | - R600_S0_Y(0x4) | - R600_S1_X(0x4) | - R600_S1_Y(0xc))); - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) | - R600_S0_Y(0xe) | - R600_S1_X(0x2) | - R600_S1_Y(0x2) | - R600_S2_X(0xa) | - R600_S2_Y(0x6) | - R600_S3_X(0x6) | - R600_S3_Y(0xa))); - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) | - R600_S0_Y(0xb) | - R600_S1_X(0x4) | - R600_S1_Y(0xc) | - R600_S2_X(0x1) | - R600_S2_Y(0x6) | - R600_S3_X(0xa) | - R600_S3_Y(0xe))); - RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) | - R600_S4_Y(0x1) | - R600_S5_X(0x0) | - R600_S5_Y(0x0) | - R600_S6_X(0xb) | - R600_S6_Y(0x4) | - R600_S7_X(0x7) | - R600_S7_Y(0x8))); - - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_R600: - case CHIP_RV630: - case CHIP_RV635: - gs_prim_buffer_depth = 0; - break; - case CHIP_RV610: - case CHIP_RS780: - case CHIP_RS880: - case CHIP_RV620: - gs_prim_buffer_depth = 32; - break; - case CHIP_RV670: - gs_prim_buffer_depth = 128; - break; - default: - break; - } - - num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; - vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; - /* Max value for this is 256 */ - if (vgt_gs_per_es > 256) - vgt_gs_per_es = 256; - - RADEON_WRITE(R600_VGT_ES_PER_GS, 128); - RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); - RADEON_WRITE(R600_VGT_GS_PER_VS, 2); - RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); - - /* more default values. 2D/3D driver should adjust as needed */ - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); - RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); - RADEON_WRITE(R600_SX_MISC, 0); - RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); - RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); - RADEON_WRITE(R600_SPI_INPUT_Z, 0); - RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); - RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); - - /* clear render buffer base addresses */ - RADEON_WRITE(R600_CB_COLOR0_BASE, 0); - RADEON_WRITE(R600_CB_COLOR1_BASE, 0); - RADEON_WRITE(R600_CB_COLOR2_BASE, 0); - RADEON_WRITE(R600_CB_COLOR3_BASE, 0); - RADEON_WRITE(R600_CB_COLOR4_BASE, 0); - RADEON_WRITE(R600_CB_COLOR5_BASE, 0); - RADEON_WRITE(R600_CB_COLOR6_BASE, 0); - RADEON_WRITE(R600_CB_COLOR7_BASE, 0); - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV610: - case CHIP_RS780: - case CHIP_RS880: - case CHIP_RV620: - tc_cntl = R600_TC_L2_SIZE(8); - break; - case CHIP_RV630: - case CHIP_RV635: - tc_cntl = R600_TC_L2_SIZE(4); - break; - case CHIP_R600: - tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT; - break; - default: - tc_cntl = R600_TC_L2_SIZE(0); - break; - } - - RADEON_WRITE(R600_TC_CNTL, tc_cntl); - - hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); - RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - arb_pop = RADEON_READ(R600_ARB_POP); - arb_pop |= R600_ENABLE_TC128; - RADEON_WRITE(R600_ARB_POP, arb_pop); - - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | - R600_NUM_CLIP_SEQ(3))); - RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095)); - -} - -static u32 r700_get_tile_pipe_to_backend_map(drm_radeon_private_t *dev_priv, - u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R7XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - bool force_no_swizzle; - - if (num_tile_pipes > R7XX_MAX_PIPES) - num_tile_pipes = R7XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R7XX_MAX_BACKENDS) - num_backends = R7XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - case CHIP_RV730: - force_no_swizzle = false; - break; - case CHIP_RV710: - case CHIP_RV740: - default: - force_no_swizzle = true; - break; - } - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - } - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 3; - swizzle_pipe[3] = 1; - } - break; - case 5: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - } - break; - case 7: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 7; - swizzle_pipe[7] = 5; - } - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - } - - return backend_map; -} - -static void r700_gfx_init(struct drm_device *dev, - drm_radeon_private_t *dev_priv) -{ - int i, j, num_qd_pipes; - u32 ta_aux_cntl; - u32 sx_debug_1; - u32 smx_dc_ctl0; - u32 db_debug3; - u32 num_gs_verts_per_thread; - u32 vgt_gs_per_es; - u32 gs_prim_buffer_depth = 0; - u32 sq_ms_fifo_sizes; - u32 sq_config; - u32 sq_thread_resource_mgmt; - u32 hdp_host_path_cntl; - u32 sq_dyn_gpr_size_simd_ab_0; - u32 backend_map; - u32 gb_tiling_config = 0; - u32 cc_rb_backend_disable; - u32 cc_gc_shader_pipe_config; - u32 mc_arb_ramcfg; - u32 db_debug4; - - /* setup chip specs */ - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 8; - dev_priv->r600_max_simds = 10; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 248; - dev_priv->r600_max_stack_entries = 512; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16 * 2; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 112; - dev_priv->r600_sq_num_cf_insts = 2; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0xF9; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - break; - case CHIP_RV730: - dev_priv->r600_max_pipes = 2; - dev_priv->r600_max_tile_pipes = 4; - dev_priv->r600_max_simds = 8; - dev_priv->r600_max_backends = 2; - dev_priv->r600_max_gprs = 128; - dev_priv->r600_max_threads = 248; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16 * 2; - dev_priv->r600_sx_max_export_size = 256; - dev_priv->r600_sx_max_export_pos_size = 32; - dev_priv->r600_sx_max_export_smx_size = 224; - dev_priv->r600_sq_num_cf_insts = 2; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0xf9; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - if (dev_priv->r600_sx_max_export_pos_size > 16) { - dev_priv->r600_sx_max_export_pos_size -= 16; - dev_priv->r600_sx_max_export_smx_size += 16; - } - break; - case CHIP_RV710: - dev_priv->r600_max_pipes = 2; - dev_priv->r600_max_tile_pipes = 2; - dev_priv->r600_max_simds = 2; - dev_priv->r600_max_backends = 1; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 192; - dev_priv->r600_max_stack_entries = 256; - dev_priv->r600_max_hw_contexts = 4; - dev_priv->r600_max_gs_threads = 8 * 2; - dev_priv->r600_sx_max_export_size = 128; - dev_priv->r600_sx_max_export_pos_size = 16; - dev_priv->r600_sx_max_export_smx_size = 112; - dev_priv->r600_sq_num_cf_insts = 1; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0x40; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - break; - case CHIP_RV740: - dev_priv->r600_max_pipes = 4; - dev_priv->r600_max_tile_pipes = 4; - dev_priv->r600_max_simds = 8; - dev_priv->r600_max_backends = 4; - dev_priv->r600_max_gprs = 256; - dev_priv->r600_max_threads = 248; - dev_priv->r600_max_stack_entries = 512; - dev_priv->r600_max_hw_contexts = 8; - dev_priv->r600_max_gs_threads = 16 * 2; - dev_priv->r600_sx_max_export_size = 256; - dev_priv->r600_sx_max_export_pos_size = 32; - dev_priv->r600_sx_max_export_smx_size = 224; - dev_priv->r600_sq_num_cf_insts = 2; - - dev_priv->r700_sx_num_of_sets = 7; - dev_priv->r700_sc_prim_fifo_size = 0x100; - dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; - dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; - - if (dev_priv->r600_sx_max_export_pos_size > 16) { - dev_priv->r600_sx_max_export_pos_size -= 16; - dev_priv->r600_sx_max_export_smx_size += 16; - } - break; - default: - break; - } - - /* Initialize HDP */ - j = 0; - for (i = 0; i < 32; i++) { - RADEON_WRITE((0x2c14 + j), 0x00000000); - RADEON_WRITE((0x2c18 + j), 0x00000000); - RADEON_WRITE((0x2c1c + j), 0x00000000); - RADEON_WRITE((0x2c20 + j), 0x00000000); - RADEON_WRITE((0x2c24 + j), 0x00000000); - j += 0x18; - } - - RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); - - /* setup tiling, simd, pipe config */ - mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG); - - switch (dev_priv->r600_max_tile_pipes) { - case 1: - gb_tiling_config |= R600_PIPE_TILING(0); - break; - case 2: - gb_tiling_config |= R600_PIPE_TILING(1); - break; - case 4: - gb_tiling_config |= R600_PIPE_TILING(2); - break; - case 8: - gb_tiling_config |= R600_PIPE_TILING(3); - break; - default: - break; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) - gb_tiling_config |= R600_BANK_TILING(1); - else - gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK); - - gb_tiling_config |= R600_GROUP_SIZE(0); - - if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) { - gb_tiling_config |= R600_ROW_TILING(3); - gb_tiling_config |= R600_SAMPLE_SPLIT(3); - } else { - gb_tiling_config |= - R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); - gb_tiling_config |= - R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); - } - - gb_tiling_config |= R600_BANK_SWAPS(1); - - cc_rb_backend_disable = RADEON_READ(R600_CC_RB_BACKEND_DISABLE) & 0x00ff0000; - cc_rb_backend_disable |= - R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK); - - cc_gc_shader_pipe_config = RADEON_READ(R600_CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; - cc_gc_shader_pipe_config |= - R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740) - backend_map = 0x28; - else - backend_map = r700_get_tile_pipe_to_backend_map(dev_priv, - dev_priv->r600_max_tile_pipes, - (R7XX_MAX_BACKENDS - - r600_count_pipe_bits((cc_rb_backend_disable & - R7XX_MAX_BACKENDS_MASK) >> 16)), - (cc_rb_backend_disable >> 16)); - gb_tiling_config |= R600_BACKEND_MAP(backend_map); - - RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); - RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - if (gb_tiling_config & 0xc0) { - dev_priv->r600_group_size = 512; - } else { - dev_priv->r600_group_size = 256; - } - dev_priv->r600_npipes = 1 << ((gb_tiling_config >> 1) & 0x7); - if (gb_tiling_config & 0x30) { - dev_priv->r600_nbanks = 8; - } else { - dev_priv->r600_nbanks = 4; - } - - RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - - RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); - RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); - RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); - RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0); - - num_qd_pipes = - R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8); - RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); - RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); - - /* set HW defaults for 3D engine */ - RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | - R600_ROQ_IB2_START(0x2b))); - - RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30)); - - ta_aux_cntl = RADEON_READ(R600_TA_CNTL_AUX); - RADEON_WRITE(R600_TA_CNTL_AUX, ta_aux_cntl | R600_DISABLE_CUBE_ANISO); - - sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1); - sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS; - RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1); - - smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0); - smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff); - smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1); - RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) != CHIP_RV740) - RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) | - R700_GS_FLUSH_CTL(4) | - R700_ACK_FLUSH_CTL(3) | - R700_SYNC_FLUSH_CTL)); - - db_debug3 = RADEON_READ(R700_DB_DEBUG3); - db_debug3 &= ~R700_DB_CLK_OFF_DELAY(0x1f); - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - case CHIP_RV740: - db_debug3 |= R700_DB_CLK_OFF_DELAY(0x1f); - break; - case CHIP_RV710: - case CHIP_RV730: - default: - db_debug3 |= R700_DB_CLK_OFF_DELAY(2); - break; - } - RADEON_WRITE(R700_DB_DEBUG3, db_debug3); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) != CHIP_RV770) { - db_debug4 = RADEON_READ(RV700_DB_DEBUG4); - db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER; - RADEON_WRITE(RV700_DB_DEBUG4, db_debug4); - } - - RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) | - R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) | - R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1))); - - RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) | - R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) | - R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize))); - - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - - RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1); - - RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); - - RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4)); - - RADEON_WRITE(R600_CP_PERFMON_CNTL, 0); - - sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) | - R600_DONE_FIFO_HIWATER(0xe0) | - R600_ALU_UPDATE_FIFO_HIWATER(0x8)); - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1); - break; - case CHIP_RV740: - default: - sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4); - break; - } - RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); - - /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT - * should be adjusted as needed by the 2D/3D drivers. This just sets default values - */ - sq_config = RADEON_READ(R600_SQ_CONFIG); - sq_config &= ~(R600_PS_PRIO(3) | - R600_VS_PRIO(3) | - R600_GS_PRIO(3) | - R600_ES_PRIO(3)); - sq_config |= (R600_DX9_CONSTS | - R600_VC_ENABLE | - R600_EXPORT_SRC_C | - R600_PS_PRIO(0) | - R600_VS_PRIO(1) | - R600_GS_PRIO(2) | - R600_ES_PRIO(3)); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) - /* no vertex cache */ - sq_config &= ~R600_VC_ENABLE; - - RADEON_WRITE(R600_SQ_CONFIG, sq_config); - - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) | - R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) | - R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2))); - - RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) | - R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64))); - - sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) | - R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) | - R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8)); - if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads) - sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads); - else - sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8); - RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | - R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); - - RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | - R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); - - sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) | - R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) | - R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) | - R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64)); - - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); - RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); - - RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) | - R700_FORCE_EOV_MAX_REZ_CNT(255))); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) | - R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); - else - RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) | - R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); - - switch (dev_priv->flags & RADEON_FAMILY_MASK) { - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV740: - gs_prim_buffer_depth = 384; - break; - case CHIP_RV710: - gs_prim_buffer_depth = 128; - break; - default: - break; - } - - num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; - vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; - /* Max value for this is 256 */ - if (vgt_gs_per_es > 256) - vgt_gs_per_es = 256; - - RADEON_WRITE(R600_VGT_ES_PER_GS, 128); - RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); - RADEON_WRITE(R600_VGT_GS_PER_VS, 2); - - /* more default values. 2D/3D driver should adjust as needed */ - RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); - RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); - RADEON_WRITE(R600_SX_MISC, 0); - RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); - RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa); - RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); - RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff); - RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); - RADEON_WRITE(R600_SPI_INPUT_Z, 0); - RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); - RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); - - /* clear render buffer base addresses */ - RADEON_WRITE(R600_CB_COLOR0_BASE, 0); - RADEON_WRITE(R600_CB_COLOR1_BASE, 0); - RADEON_WRITE(R600_CB_COLOR2_BASE, 0); - RADEON_WRITE(R600_CB_COLOR3_BASE, 0); - RADEON_WRITE(R600_CB_COLOR4_BASE, 0); - RADEON_WRITE(R600_CB_COLOR5_BASE, 0); - RADEON_WRITE(R600_CB_COLOR6_BASE, 0); - RADEON_WRITE(R600_CB_COLOR7_BASE, 0); - - RADEON_WRITE(R700_TCP_CNTL, 0); - - hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); - RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); - - RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | - R600_NUM_CLIP_SEQ(3))); - -} - -static void r600_cp_init_ring_buffer(struct drm_device *dev, - drm_radeon_private_t *dev_priv, - struct drm_file *file_priv) -{ - struct drm_radeon_master_private *master_priv; - u32 ring_start; - u64 rptr_addr; - - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_gfx_init(dev, dev_priv); - else - r600_gfx_init(dev, dev_priv); - - RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); - RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - - - /* Set ring buffer size */ -#ifdef __BIG_ENDIAN - RADEON_WRITE(R600_CP_RB_CNTL, - R600_BUF_SWAP_32BIT | - R600_RB_NO_UPDATE | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_RB_NO_UPDATE | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - - RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x0); - - /* Set the write pointer delay */ - RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); - -#ifdef __BIG_ENDIAN - RADEON_WRITE(R600_CP_RB_CNTL, - R600_BUF_SWAP_32BIT | - R600_RB_NO_UPDATE | - R600_RB_RPTR_WR_ENA | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(R600_CP_RB_CNTL, - R600_RB_NO_UPDATE | - R600_RB_RPTR_WR_ENA | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - - /* Initialize the ring buffer's read and write pointers */ - RADEON_WRITE(R600_CP_RB_RPTR_WR, 0); - RADEON_WRITE(R600_CP_RB_WPTR, 0); - SET_RING_HEAD(dev_priv, 0); - dev_priv->ring.tail = 0; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - rptr_addr = dev_priv->ring_rptr->offset - - dev->agp->base + - dev_priv->gart_vm_start; - } else -#endif - { - rptr_addr = dev_priv->ring_rptr->offset - - ((unsigned long) dev->sg->virtual) - + dev_priv->gart_vm_start; - } - RADEON_WRITE(R600_CP_RB_RPTR_ADDR, (rptr_addr & 0xfffffffc)); - RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, upper_32_bits(rptr_addr)); - -#ifdef __BIG_ENDIAN - RADEON_WRITE(R600_CP_RB_CNTL, - RADEON_BUF_SWAP_32BIT | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(R600_CP_RB_CNTL, - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* XXX */ - radeon_write_agp_base(dev_priv, dev->agp->base); - - /* XXX */ - radeon_write_agp_location(dev_priv, - (((dev_priv->gart_vm_start - 1 + - dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); - - ring_start = (dev_priv->cp_ring->offset - - dev->agp->base - + dev_priv->gart_vm_start); - } else -#endif - ring_start = (dev_priv->cp_ring->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8); - - RADEON_WRITE(R600_CP_ME_CNTL, 0xff); - - RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28)); - - /* Initialize the scratch register pointer. This will cause - * the scratch register values to be written out to memory - * whenever they are updated. - * - * We simply put this behind the ring read pointer, this works - * with PCI GART as well as (whatever kind of) AGP GART - */ - { - u64 scratch_addr; - - scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR) & 0xFFFFFFFC; - scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; - scratch_addr += R600_SCRATCH_REG_OFFSET; - scratch_addr >>= 8; - scratch_addr &= 0xffffffff; - - RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); - } - - RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); - - /* Turn on bus mastering */ - radeon_enable_bm(dev_priv); - - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0); - RADEON_WRITE(R600_LAST_FRAME_REG, 0); - - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); - RADEON_WRITE(R600_LAST_DISPATCH_REG, 0); - - radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0); - RADEON_WRITE(R600_LAST_CLEAR_REG, 0); - - /* reset sarea copies of these */ - master_priv = file_priv->master->driver_priv; - if (master_priv->sarea_priv) { - master_priv->sarea_priv->last_frame = 0; - master_priv->sarea_priv->last_dispatch = 0; - master_priv->sarea_priv->last_clear = 0; - } - - r600_do_wait_for_idle(dev_priv); - -} - -int r600_do_cleanup_cp(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - if (dev_priv->cp_ring != NULL) { - drm_core_ioremapfree(dev_priv->cp_ring, dev); - dev_priv->cp_ring = NULL; - } - if (dev_priv->ring_rptr != NULL) { - drm_core_ioremapfree(dev_priv->ring_rptr, dev); - dev_priv->ring_rptr = NULL; - } - if (dev->agp_buffer_map != NULL) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } - } else -#endif - { - - if (dev_priv->gart_info.bus_addr) - r600_page_table_cleanup(dev, &dev_priv->gart_info); - - if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = NULL; - } - } - /* only clear to the start of flags */ - memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); - - return 0; -} - -int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - - DRM_DEBUG("\n"); - - mutex_init(&dev_priv->cs_mutex); - r600_cs_legacy_init(); - /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { - DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; - /* The writeback test succeeds, but when writeback is enabled, - * the ring buffer read ptr update fails after first 128 bytes. - */ - radeon_no_wb = 1; - } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) { - DRM_DEBUG("Restoring AGP flag\n"); - dev_priv->flags |= RADEON_IS_AGP; - } - - dev_priv->usec_timeout = init->usec_timeout; - if (dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { - DRM_DEBUG("TIMEOUT problem!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - /* Enable vblank on CRTC1 for older X servers - */ - dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; - dev_priv->do_boxes = 0; - dev_priv->cp_mode = init->cp_mode; - - /* We don't support anything other than bus-mastering ring mode, - * but the ring can be in either AGP or PCI space for the ring - * read pointer. - */ - if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && - (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { - DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - switch (init->fb_bpp) { - case 16: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; - break; - case 32: - default: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; - break; - } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - dev_priv->ring_offset = init->ring_offset; - dev_priv->ring_rptr_offset = init->ring_rptr_offset; - dev_priv->buffers_offset = init->buffers_offset; - dev_priv->gart_textures_offset = init->gart_textures_offset; - - master_priv->sarea = drm_getsarea(dev); - if (!master_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->cp_ring) { - DRM_ERROR("could not find cp ring region!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if (!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find dma buffer region!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->gart_textures_offset) { - dev_priv->gart_textures = - drm_core_findmap(dev, init->gart_textures_offset); - if (!dev_priv->gart_textures) { - DRM_ERROR("could not find GART texture region!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - } - -#if __OS_HAS_AGP - /* XXX */ - if (dev_priv->flags & RADEON_IS_AGP) { - drm_core_ioremap_wc(dev_priv->cp_ring, dev); - drm_core_ioremap_wc(dev_priv->ring_rptr, dev); - drm_core_ioremap_wc(dev->agp_buffer_map, dev); - if (!dev_priv->cp_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { - DRM_ERROR("could not find ioremap agp regions!\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - } else -#endif - { - dev_priv->cp_ring->handle = (void *)(unsigned long)dev_priv->cp_ring->offset; - dev_priv->ring_rptr->handle = - (void *)(unsigned long)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = - (void *)(unsigned long)dev->agp_buffer_map->offset; - - DRM_DEBUG("dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle); - DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle); - DRM_DEBUG("dev->agp_buffer_map->handle %p\n", - dev->agp_buffer_map->handle); - } - - dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24; - dev_priv->fb_size = - (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000) - - dev_priv->fb_location; - - dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | - ((dev_priv->front_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | - ((dev_priv->back_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | - ((dev_priv->depth_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->gart_size = init->gart_size; - - /* New let's set the memory map ... */ - if (dev_priv->new_memmap) { - u32 base = 0; - - DRM_INFO("Setting GART location based on new memory map\n"); - - /* If using AGP, try to locate the AGP aperture at the same - * location in the card and on the bus, though we have to - * align it down. - */ -#if __OS_HAS_AGP - /* XXX */ - if (dev_priv->flags & RADEON_IS_AGP) { - base = dev->agp->base; - /* Check if valid */ - if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && - base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { - DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", - dev->agp->base); - base = 0; - } - } -#endif - /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ - if (base == 0) { - base = dev_priv->fb_location + dev_priv->fb_size; - if (base < dev_priv->fb_location || - ((base + dev_priv->gart_size) & 0xfffffffful) < base) - base = dev_priv->fb_location - - dev_priv->gart_size; - } - dev_priv->gart_vm_start = base & 0xffc00000u; - if (dev_priv->gart_vm_start != base) - DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", - base, dev_priv->gart_vm_start); - } - -#if __OS_HAS_AGP - /* XXX */ - if (dev_priv->flags & RADEON_IS_AGP) - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->agp->base - + dev_priv->gart_vm_start); - else -#endif - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - DRM_DEBUG("fb 0x%08x size %d\n", - (unsigned int) dev_priv->fb_location, - (unsigned int) dev_priv->fb_size); - DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); - DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n", - (unsigned int) dev_priv->gart_vm_start); - DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n", - dev_priv->gart_buffers_offset); - - dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; - dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle - + init->ring_size / sizeof(u32)); - dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - - dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; - dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8); - - dev_priv->ring.fetch_size = /* init->fetch_size */ 32; - dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16); - - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; - - dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* XXX turn off pcie gart */ - } else -#endif - { - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); - /* if we have an offset set from userspace */ - if (!dev_priv->pcigart_offset_set) { - DRM_ERROR("Need gart offset from userspace\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset); - - dev_priv->gart_info.bus_addr = - dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->pcigart_offset + dev_priv->fb_aper_offset; - dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; - - drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); - if (!dev_priv->gart_info.mapping.handle) { - DRM_ERROR("ioremap failed.\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; - - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", - dev_priv->gart_info.addr, - dev_priv->pcigart_offset); - - if (!r600_page_table_init(dev)) { - DRM_ERROR("Failed to init GART table\n"); - r600_do_cleanup_cp(dev); - return -EINVAL; - } - - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_vm_init(dev); - else - r600_vm_init(dev); - } - - if (!dev_priv->me_fw || !dev_priv->pfp_fw) { - int err = r600_cp_init_microcode(dev_priv); - if (err) { - DRM_ERROR("Failed to load firmware!\n"); - r600_do_cleanup_cp(dev); - return err; - } - } - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_cp_load_microcode(dev_priv); - else - r600_cp_load_microcode(dev_priv); - - r600_cp_init_ring_buffer(dev, dev_priv, file_priv); - - dev_priv->last_buf = 0; - - r600_do_engine_reset(dev); - r600_test_writeback(dev_priv); - - return 0; -} - -int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) { - r700_vm_init(dev); - r700_cp_load_microcode(dev_priv); - } else { - r600_vm_init(dev); - r600_cp_load_microcode(dev_priv); - } - r600_cp_init_ring_buffer(dev, dev_priv, file_priv); - r600_do_engine_reset(dev); - - return 0; -} - -/* Wait for the CP to go idle. - */ -int r600_do_cp_idle(drm_radeon_private_t *dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(5); - OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); - OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); - /* wait for 3D idle clean */ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); - OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); - OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); - - ADVANCE_RING(); - COMMIT_RING(); - - return r600_do_wait_for_idle(dev_priv); -} - -/* Start the Command Processor. - */ -void r600_do_cp_start(drm_radeon_private_t *dev_priv) -{ - u32 cp_me; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(7); - OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); - OUT_RING(0x00000001); - if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) - OUT_RING(0x00000003); - else - OUT_RING(0x00000000); - OUT_RING((dev_priv->r600_max_hw_contexts - 1)); - OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); - OUT_RING(0x00000000); - OUT_RING(0x00000000); - ADVANCE_RING(); - COMMIT_RING(); - - /* set the mux and reset the halt bit */ - cp_me = 0xff; - RADEON_WRITE(R600_CP_ME_CNTL, cp_me); - - dev_priv->cp_running = 1; - -} - -void r600_do_cp_reset(drm_radeon_private_t *dev_priv) -{ - u32 cur_read_ptr; - DRM_DEBUG("\n"); - - cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); - RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); - SET_RING_HEAD(dev_priv, cur_read_ptr); - dev_priv->ring.tail = cur_read_ptr; -} - -void r600_do_cp_stop(drm_radeon_private_t *dev_priv) -{ - uint32_t cp_me; - - DRM_DEBUG("\n"); - - cp_me = 0xff | R600_CP_ME_HALT; - - RADEON_WRITE(R600_CP_ME_CNTL, cp_me); - - dev_priv->cp_running = 0; -} - -int r600_cp_dispatch_indirect(struct drm_device *dev, - struct drm_buf *buf, int start, int end) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - if (start != end) { - unsigned long offset = (dev_priv->gart_buffers_offset - + buf->offset + start); - int dwords = (end - start + 3) / sizeof(u32); - - DRM_DEBUG("dwords:%d\n", dwords); - DRM_DEBUG("offset 0x%lx\n", offset); - - - /* Indirect buffer data must be a multiple of 16 dwords. - * pad the data with a Type-2 CP packet. - */ - while (dwords & 0xf) { - u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = RADEON_CP_PACKET2; - } - - /* Fire off the indirect buffer */ - BEGIN_RING(4); - OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); - OUT_RING((offset & 0xfffffffc)); - OUT_RING((upper_32_bits(offset) & 0xff)); - OUT_RING(dwords); - ADVANCE_RING(); - } - - return 0; -} - -void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_master *master = file_priv->master; - struct drm_radeon_master_private *master_priv = master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int i, cpp, src_pitch, dst_pitch; - uint64_t src, dst; - RING_LOCALS; - DRM_DEBUG("\n"); - - if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888) - cpp = 4; - else - cpp = 2; - - if (sarea_priv->pfCurrentPage == 0) { - src_pitch = dev_priv->back_pitch; - dst_pitch = dev_priv->front_pitch; - src = dev_priv->back_offset + dev_priv->fb_location; - dst = dev_priv->front_offset + dev_priv->fb_location; - } else { - src_pitch = dev_priv->front_pitch; - dst_pitch = dev_priv->back_pitch; - src = dev_priv->front_offset + dev_priv->fb_location; - dst = dev_priv->back_offset + dev_priv->fb_location; - } - - if (r600_prepare_blit_copy(dev, file_priv)) { - DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); - return; - } - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h); - - r600_blit_swap(dev, - src, dst, - x, y, x, y, w, h, - src_pitch, dst_pitch, cpp); - } - r600_done_blit_copy(dev); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - sarea_priv->last_frame++; - - BEGIN_RING(3); - R600_FRAME_AGE(sarea_priv->last_frame); - ADVANCE_RING(); -} - -int r600_cp_dispatch_texture(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_texture_t *tex, - drm_radeon_tex_image_t *image) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - u32 *buffer; - const u8 __user *data; - int size, pass_size; - u64 src_offset, dst_offset; - - if (!radeon_check_offset(dev_priv, tex->offset)) { - DRM_ERROR("Invalid destination offset\n"); - return -EINVAL; - } - - /* this might fail for zero-sized uploads - are those illegal? */ - if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) { - DRM_ERROR("Invalid final destination offset\n"); - return -EINVAL; - } - - size = tex->height * tex->pitch; - - if (size == 0) - return 0; - - dst_offset = tex->offset; - - if (r600_prepare_blit_copy(dev, file_priv)) { - DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); - return -EAGAIN; - } - do { - data = (const u8 __user *)image->data; - pass_size = size; - - buf = radeon_freelist_get(dev); - if (!buf) { - DRM_DEBUG("EAGAIN\n"); - if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) - return -EFAULT; - return -EAGAIN; - } - - if (pass_size > buf->total) - pass_size = buf->total; - - /* Dispatch the indirect buffer. - */ - buffer = - (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); - - if (DRM_COPY_FROM_USER(buffer, data, pass_size)) { - DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size); - return -EFAULT; - } - - buf->file_priv = file_priv; - buf->used = pass_size; - src_offset = dev_priv->gart_buffers_offset + buf->offset; - - r600_blit_copy(dev, src_offset, dst_offset, pass_size); - - radeon_cp_discard_buffer(dev, file_priv->master, buf); - - /* Update the input parameters for next time */ - image->data = (const u8 __user *)image->data + pass_size; - dst_offset += pass_size; - size -= pass_size; - } while (size > 0); - r600_done_blit_copy(dev); - - return 0; -} - -/* - * Legacy cs ioctl - */ -static u32 radeon_cs_id_get(struct drm_radeon_private *radeon) -{ - /* FIXME: check if wrap affect last reported wrap & sequence */ - radeon->cs_id_scnt = (radeon->cs_id_scnt + 1) & 0x00FFFFFF; - if (!radeon->cs_id_scnt) { - /* increment wrap counter */ - radeon->cs_id_wcnt += 0x01000000; - /* valid sequence counter start at 1 */ - radeon->cs_id_scnt = 1; - } - return (radeon->cs_id_scnt | radeon->cs_id_wcnt); -} - -static void r600_cs_id_emit(drm_radeon_private_t *dev_priv, u32 *id) -{ - RING_LOCALS; - - *id = radeon_cs_id_get(dev_priv); - - /* SCRATCH 2 */ - BEGIN_RING(3); - R600_CLEAR_AGE(*id); - ADVANCE_RING(); - COMMIT_RING(); -} - -static int r600_ib_get(struct drm_device *dev, - struct drm_file *fpriv, - struct drm_buf **buffer) -{ - struct drm_buf *buf; - - *buffer = NULL; - buf = radeon_freelist_get(dev); - if (!buf) { - return -EBUSY; - } - buf->file_priv = fpriv; - *buffer = buf; - return 0; -} - -static void r600_ib_free(struct drm_device *dev, struct drm_buf *buf, - struct drm_file *fpriv, int l, int r) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (buf) { - if (!r) - r600_cp_dispatch_indirect(dev, buf, 0, l * 4); - radeon_cp_discard_buffer(dev, fpriv->master, buf); - COMMIT_RING(); - } -} - -int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) -{ - struct drm_radeon_private *dev_priv = dev->dev_private; - struct drm_radeon_cs *cs = data; - struct drm_buf *buf; - unsigned family; - int l, r = 0; - u32 *ib, cs_id = 0; - - if (dev_priv == NULL) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - family = dev_priv->flags & RADEON_FAMILY_MASK; - if (family < CHIP_R600) { - DRM_ERROR("cs ioctl valid only for R6XX & R7XX in legacy mode\n"); - return -EINVAL; - } - mutex_lock(&dev_priv->cs_mutex); - /* get ib */ - r = r600_ib_get(dev, fpriv, &buf); - if (r) { - DRM_ERROR("ib_get failed\n"); - goto out; - } - ib = dev->agp_buffer_map->handle + buf->offset; - /* now parse command stream */ - r = r600_cs_legacy(dev, data, fpriv, family, ib, &l); - if (r) { - goto out; - } - -out: - r600_ib_free(dev, buf, fpriv, l, r); - /* emit cs id sequence */ - r600_cs_id_emit(dev_priv, &cs_id); - cs->cs_id = cs_id; - mutex_unlock(&dev_priv->cs_mutex); - return r; -} - -void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size) -{ - struct drm_radeon_private *dev_priv = dev->dev_private; - - *npipes = dev_priv->r600_npipes; - *nbanks = dev_priv->r600_nbanks; - *group_size = dev_priv->r600_group_size; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cs.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cs.c deleted file mode 100644 index b8e12af3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_cs.c +++ /dev/null @@ -1,2357 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include "drmP.h" -#include "radeon.h" -#include "r600d.h" -#include "r600_reg_safe.h" - -static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); -static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc); -typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); -static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; -extern void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size); - - -struct r600_cs_track { - /* configuration we miror so that we use same code btw kms/ums */ - u32 group_size; - u32 nbanks; - u32 npipes; - /* value we track */ - u32 sq_config; - u32 nsamples; - u32 cb_color_base_last[8]; - struct radeon_bo *cb_color_bo[8]; - u64 cb_color_bo_mc[8]; - u32 cb_color_bo_offset[8]; - struct radeon_bo *cb_color_frag_bo[8]; /* unused */ - struct radeon_bo *cb_color_tile_bo[8]; /* unused */ - u32 cb_color_info[8]; - u32 cb_color_view[8]; - u32 cb_color_size_idx[8]; /* unused */ - u32 cb_target_mask; - u32 cb_shader_mask; /* unused */ - u32 cb_color_size[8]; - u32 vgt_strmout_en; - u32 vgt_strmout_buffer_en; - struct radeon_bo *vgt_strmout_bo[4]; - u64 vgt_strmout_bo_mc[4]; /* unused */ - u32 vgt_strmout_bo_offset[4]; - u32 vgt_strmout_size[4]; - u32 db_depth_control; - u32 db_depth_info; - u32 db_depth_size_idx; - u32 db_depth_view; - u32 db_depth_size; - u32 db_offset; - struct radeon_bo *db_bo; - u64 db_bo_mc; - bool sx_misc_kill_all_prims; - bool cb_dirty; - bool db_dirty; - bool streamout_dirty; - struct radeon_bo *htile_bo; - u64 htile_offset; - u32 htile_surface; -}; - -#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } -#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 } -#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 4, 0, CHIP_R600 } -#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 } -#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 8, 0, CHIP_R600 } -#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 } -#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 } -#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 } - -struct gpu_formats { - unsigned blockwidth; - unsigned blockheight; - unsigned blocksize; - unsigned valid_color; - enum radeon_family min_family; -}; - -static const struct gpu_formats color_formats_table[] = { - /* 8 bit */ - FMT_8_BIT(V_038004_COLOR_8, 1), - FMT_8_BIT(V_038004_COLOR_4_4, 1), - FMT_8_BIT(V_038004_COLOR_3_3_2, 1), - FMT_8_BIT(V_038004_FMT_1, 0), - - /* 16-bit */ - FMT_16_BIT(V_038004_COLOR_16, 1), - FMT_16_BIT(V_038004_COLOR_16_FLOAT, 1), - FMT_16_BIT(V_038004_COLOR_8_8, 1), - FMT_16_BIT(V_038004_COLOR_5_6_5, 1), - FMT_16_BIT(V_038004_COLOR_6_5_5, 1), - FMT_16_BIT(V_038004_COLOR_1_5_5_5, 1), - FMT_16_BIT(V_038004_COLOR_4_4_4_4, 1), - FMT_16_BIT(V_038004_COLOR_5_5_5_1, 1), - - /* 24-bit */ - FMT_24_BIT(V_038004_FMT_8_8_8), - - /* 32-bit */ - FMT_32_BIT(V_038004_COLOR_32, 1), - FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1), - FMT_32_BIT(V_038004_COLOR_16_16, 1), - FMT_32_BIT(V_038004_COLOR_16_16_FLOAT, 1), - FMT_32_BIT(V_038004_COLOR_8_24, 1), - FMT_32_BIT(V_038004_COLOR_8_24_FLOAT, 1), - FMT_32_BIT(V_038004_COLOR_24_8, 1), - FMT_32_BIT(V_038004_COLOR_24_8_FLOAT, 1), - FMT_32_BIT(V_038004_COLOR_10_11_11, 1), - FMT_32_BIT(V_038004_COLOR_10_11_11_FLOAT, 1), - FMT_32_BIT(V_038004_COLOR_11_11_10, 1), - FMT_32_BIT(V_038004_COLOR_11_11_10_FLOAT, 1), - FMT_32_BIT(V_038004_COLOR_2_10_10_10, 1), - FMT_32_BIT(V_038004_COLOR_8_8_8_8, 1), - FMT_32_BIT(V_038004_COLOR_10_10_10_2, 1), - FMT_32_BIT(V_038004_FMT_5_9_9_9_SHAREDEXP, 0), - FMT_32_BIT(V_038004_FMT_32_AS_8, 0), - FMT_32_BIT(V_038004_FMT_32_AS_8_8, 0), - - /* 48-bit */ - FMT_48_BIT(V_038004_FMT_16_16_16), - FMT_48_BIT(V_038004_FMT_16_16_16_FLOAT), - - /* 64-bit */ - FMT_64_BIT(V_038004_COLOR_X24_8_32_FLOAT, 1), - FMT_64_BIT(V_038004_COLOR_32_32, 1), - FMT_64_BIT(V_038004_COLOR_32_32_FLOAT, 1), - FMT_64_BIT(V_038004_COLOR_16_16_16_16, 1), - FMT_64_BIT(V_038004_COLOR_16_16_16_16_FLOAT, 1), - - FMT_96_BIT(V_038004_FMT_32_32_32), - FMT_96_BIT(V_038004_FMT_32_32_32_FLOAT), - - /* 128-bit */ - FMT_128_BIT(V_038004_COLOR_32_32_32_32, 1), - FMT_128_BIT(V_038004_COLOR_32_32_32_32_FLOAT, 1), - - [V_038004_FMT_GB_GR] = { 2, 1, 4, 0 }, - [V_038004_FMT_BG_RG] = { 2, 1, 4, 0 }, - - /* block compressed formats */ - [V_038004_FMT_BC1] = { 4, 4, 8, 0 }, - [V_038004_FMT_BC2] = { 4, 4, 16, 0 }, - [V_038004_FMT_BC3] = { 4, 4, 16, 0 }, - [V_038004_FMT_BC4] = { 4, 4, 8, 0 }, - [V_038004_FMT_BC5] = { 4, 4, 16, 0}, - [V_038004_FMT_BC6] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */ - [V_038004_FMT_BC7] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */ - - /* The other Evergreen formats */ - [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR}, -}; - -bool r600_fmt_is_valid_color(u32 format) -{ - if (format >= ARRAY_SIZE(color_formats_table)) - return false; - - if (color_formats_table[format].valid_color) - return true; - - return false; -} - -bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family) -{ - if (format >= ARRAY_SIZE(color_formats_table)) - return false; - - if (family < color_formats_table[format].min_family) - return false; - - if (color_formats_table[format].blockwidth > 0) - return true; - - return false; -} - -int r600_fmt_get_blocksize(u32 format) -{ - if (format >= ARRAY_SIZE(color_formats_table)) - return 0; - - return color_formats_table[format].blocksize; -} - -int r600_fmt_get_nblocksx(u32 format, u32 w) -{ - unsigned bw; - - if (format >= ARRAY_SIZE(color_formats_table)) - return 0; - - bw = color_formats_table[format].blockwidth; - if (bw == 0) - return 0; - - return (w + bw - 1) / bw; -} - -int r600_fmt_get_nblocksy(u32 format, u32 h) -{ - unsigned bh; - - if (format >= ARRAY_SIZE(color_formats_table)) - return 0; - - bh = color_formats_table[format].blockheight; - if (bh == 0) - return 0; - - return (h + bh - 1) / bh; -} - -struct array_mode_checker { - int array_mode; - u32 group_size; - u32 nbanks; - u32 npipes; - u32 nsamples; - u32 blocksize; -}; - -/* returns alignment in pixels for pitch/height/depth and bytes for base */ -static int r600_get_array_mode_alignment(struct array_mode_checker *values, - u32 *pitch_align, - u32 *height_align, - u32 *depth_align, - u64 *base_align) -{ - u32 tile_width = 8; - u32 tile_height = 8; - u32 macro_tile_width = values->nbanks; - u32 macro_tile_height = values->npipes; - u32 tile_bytes = tile_width * tile_height * values->blocksize * values->nsamples; - u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; - - switch (values->array_mode) { - case ARRAY_LINEAR_GENERAL: - /* technically tile_width/_height for pitch/height */ - *pitch_align = 1; /* tile_width */ - *height_align = 1; /* tile_height */ - *depth_align = 1; - *base_align = 1; - break; - case ARRAY_LINEAR_ALIGNED: - *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize)); - *height_align = 1; - *depth_align = 1; - *base_align = values->group_size; - break; - case ARRAY_1D_TILED_THIN1: - *pitch_align = max((u32)tile_width, - (u32)(values->group_size / - (tile_height * values->blocksize * values->nsamples))); - *height_align = tile_height; - *depth_align = 1; - *base_align = values->group_size; - break; - case ARRAY_2D_TILED_THIN1: - *pitch_align = max((u32)macro_tile_width * tile_width, - (u32)((values->group_size * values->nbanks) / - (values->blocksize * values->nsamples * tile_width))); - *height_align = macro_tile_height * tile_height; - *depth_align = 1; - *base_align = max(macro_tile_bytes, - (*pitch_align) * values->blocksize * (*height_align) * values->nsamples); - break; - default: - return -EINVAL; - } - - return 0; -} - -static void r600_cs_track_init(struct r600_cs_track *track) -{ - int i; - - /* assume DX9 mode */ - track->sq_config = DX9_CONSTS; - for (i = 0; i < 8; i++) { - track->cb_color_base_last[i] = 0; - track->cb_color_size[i] = 0; - track->cb_color_size_idx[i] = 0; - track->cb_color_info[i] = 0; - track->cb_color_view[i] = 0xFFFFFFFF; - track->cb_color_bo[i] = NULL; - track->cb_color_bo_offset[i] = 0xFFFFFFFF; - track->cb_color_bo_mc[i] = 0xFFFFFFFF; - } - track->cb_target_mask = 0xFFFFFFFF; - track->cb_shader_mask = 0xFFFFFFFF; - track->cb_dirty = true; - track->db_bo = NULL; - track->db_bo_mc = 0xFFFFFFFF; - /* assume the biggest format and that htile is enabled */ - track->db_depth_info = 7 | (1 << 25); - track->db_depth_view = 0xFFFFC000; - track->db_depth_size = 0xFFFFFFFF; - track->db_depth_size_idx = 0; - track->db_depth_control = 0xFFFFFFFF; - track->db_dirty = true; - track->htile_bo = NULL; - track->htile_offset = 0xFFFFFFFF; - track->htile_surface = 0; - - for (i = 0; i < 4; i++) { - track->vgt_strmout_size[i] = 0; - track->vgt_strmout_bo[i] = NULL; - track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF; - track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF; - } - track->streamout_dirty = true; - track->sx_misc_kill_all_prims = false; -} - -static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) -{ - struct r600_cs_track *track = p->track; - u32 slice_tile_max, size, tmp; - u32 height, height_align, pitch, pitch_align, depth_align; - u64 base_offset, base_align; - struct array_mode_checker array_check; - volatile u32 *ib = p->ib->ptr; - unsigned array_mode; - u32 format; - - if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { - dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); - return -EINVAL; - } - size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; - format = G_0280A0_FORMAT(track->cb_color_info[i]); - if (!r600_fmt_is_valid_color(format)) { - dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", - __func__, __LINE__, format, - i, track->cb_color_info[i]); - return -EINVAL; - } - /* pitch in pixels */ - pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8; - slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; - slice_tile_max *= 64; - height = slice_tile_max / pitch; - if (height > 8192) - height = 8192; - array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); - - base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i]; - array_check.array_mode = array_mode; - array_check.group_size = track->group_size; - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = track->nsamples; - array_check.blocksize = r600_fmt_get_blocksize(format); - if (r600_get_array_mode_alignment(&array_check, - &pitch_align, &height_align, &depth_align, &base_align)) { - dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, - G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, - track->cb_color_info[i]); - return -EINVAL; - } - switch (array_mode) { - case V_0280A0_ARRAY_LINEAR_GENERAL: - break; - case V_0280A0_ARRAY_LINEAR_ALIGNED: - break; - case V_0280A0_ARRAY_1D_TILED_THIN1: - /* avoid breaking userspace */ - if (height > 7) - height &= ~0x7; - break; - case V_0280A0_ARRAY_2D_TILED_THIN1: - break; - default: - dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, - G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, - track->cb_color_info[i]); - return -EINVAL; - } - - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, pitch, pitch_align, array_mode); - return -EINVAL; - } - if (!IS_ALIGNED(height, height_align)) { - dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, height, height_align, array_mode); - return -EINVAL; - } - if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s offset[%d] 0x%llx 0x%llx, %d not aligned\n", __func__, i, - base_offset, base_align, array_mode); - return -EINVAL; - } - - /* check offset */ - tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); - switch (array_mode) { - default: - case V_0280A0_ARRAY_LINEAR_GENERAL: - case V_0280A0_ARRAY_LINEAR_ALIGNED: - tmp += track->cb_color_view[i] & 0xFF; - break; - case V_0280A0_ARRAY_1D_TILED_THIN1: - case V_0280A0_ARRAY_2D_TILED_THIN1: - tmp += G_028080_SLICE_MAX(track->cb_color_view[i]) * tmp; - break; - } - if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { - if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { - /* the initial DDX does bad things with the CB size occasionally */ - /* it rounds up height too far for slice tile max but the BO is smaller */ - /* r600c,g also seem to flush at bad times in some apps resulting in - * bogus values here. So for linear just allow anything to avoid breaking - * broken userspace. - */ - } else { - dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", - __func__, i, array_mode, - track->cb_color_bo_offset[i], tmp, - radeon_bo_size(track->cb_color_bo[i]), - pitch, height, r600_fmt_get_nblocksx(format, pitch), - r600_fmt_get_nblocksy(format, height), - r600_fmt_get_blocksize(format)); - return -EINVAL; - } - } - /* limit max tile */ - tmp = (height * pitch) >> 6; - if (tmp < slice_tile_max) - slice_tile_max = tmp; - tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | - S_028060_SLICE_TILE_MAX(slice_tile_max - 1); - ib[track->cb_color_size_idx[i]] = tmp; - return 0; -} - -static int r600_cs_track_validate_db(struct radeon_cs_parser *p) -{ - struct r600_cs_track *track = p->track; - u32 nviews, bpe, ntiles, size, slice_tile_max, tmp; - u32 height_align, pitch_align, depth_align; - u32 pitch = 8192; - u32 height = 8192; - u64 base_offset, base_align; - struct array_mode_checker array_check; - int array_mode; - volatile u32 *ib = p->ib->ptr; - - - if (track->db_bo == NULL) { - dev_warn(p->dev, "z/stencil with no depth buffer\n"); - return -EINVAL; - } - switch (G_028010_FORMAT(track->db_depth_info)) { - case V_028010_DEPTH_16: - bpe = 2; - break; - case V_028010_DEPTH_X8_24: - case V_028010_DEPTH_8_24: - case V_028010_DEPTH_X8_24_FLOAT: - case V_028010_DEPTH_8_24_FLOAT: - case V_028010_DEPTH_32_FLOAT: - bpe = 4; - break; - case V_028010_DEPTH_X24_8_32_FLOAT: - bpe = 8; - break; - default: - dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info)); - return -EINVAL; - } - if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { - if (!track->db_depth_size_idx) { - dev_warn(p->dev, "z/stencil buffer size not set\n"); - return -EINVAL; - } - tmp = radeon_bo_size(track->db_bo) - track->db_offset; - tmp = (tmp / bpe) >> 6; - if (!tmp) { - dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n", - track->db_depth_size, bpe, track->db_offset, - radeon_bo_size(track->db_bo)); - return -EINVAL; - } - ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); - } else { - size = radeon_bo_size(track->db_bo); - /* pitch in pixels */ - pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; - slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; - slice_tile_max *= 64; - height = slice_tile_max / pitch; - if (height > 8192) - height = 8192; - base_offset = track->db_bo_mc + track->db_offset; - array_mode = G_028010_ARRAY_MODE(track->db_depth_info); - array_check.array_mode = array_mode; - array_check.group_size = track->group_size; - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = track->nsamples; - array_check.blocksize = bpe; - if (r600_get_array_mode_alignment(&array_check, - &pitch_align, &height_align, &depth_align, &base_align)) { - dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, - G_028010_ARRAY_MODE(track->db_depth_info), - track->db_depth_info); - return -EINVAL; - } - switch (array_mode) { - case V_028010_ARRAY_1D_TILED_THIN1: - /* don't break userspace */ - height &= ~0x7; - break; - case V_028010_ARRAY_2D_TILED_THIN1: - break; - default: - dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, - G_028010_ARRAY_MODE(track->db_depth_info), - track->db_depth_info); - return -EINVAL; - } - - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, pitch, pitch_align, array_mode); - return -EINVAL; - } - if (!IS_ALIGNED(height, height_align)) { - dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, height, height_align, array_mode); - return -EINVAL; - } - if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s offset 0x%llx, 0x%llx, %d not aligned\n", __func__, - base_offset, base_align, array_mode); - return -EINVAL; - } - - ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; - nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; - tmp = ntiles * bpe * 64 * nviews; - if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { - dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", - array_mode, - track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, - radeon_bo_size(track->db_bo)); - return -EINVAL; - } - } - - /* hyperz */ - if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) { - unsigned long size; - unsigned nbx, nby; - - if (track->htile_bo == NULL) { - dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n", - __func__, __LINE__, track->db_depth_info); - return -EINVAL; - } - if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { - dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n", - __func__, __LINE__, track->db_depth_size); - return -EINVAL; - } - - nbx = pitch; - nby = height; - if (G_028D24_LINEAR(track->htile_surface)) { - /* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */ - nbx = round_up(nbx, 16 * 8); - /* nby is npipes htiles aligned == npipes * 8 pixel aligned */ - nby = round_up(nby, track->npipes * 8); - } else { - /* htile widht & nby (8 or 4) make 2 bits number */ - tmp = track->htile_surface & 3; - /* align is htile align * 8, htile align vary according to - * number of pipe and tile width and nby - */ - switch (track->npipes) { - case 8: - switch (tmp) { - case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ - nbx = round_up(nbx, 64 * 8); - nby = round_up(nby, 64 * 8); - break; - case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ - case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 64 * 8); - nby = round_up(nby, 32 * 8); - break; - case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 32 * 8); - break; - default: - return -EINVAL; - } - break; - case 4: - switch (tmp) { - case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ - nbx = round_up(nbx, 64 * 8); - nby = round_up(nby, 32 * 8); - break; - case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ - case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 32 * 8); - break; - case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 16 * 8); - break; - default: - return -EINVAL; - } - break; - case 2: - switch (tmp) { - case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 32 * 8); - break; - case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ - case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 16 * 8); - break; - case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 16 * 8); - nby = round_up(nby, 16 * 8); - break; - default: - return -EINVAL; - } - break; - case 1: - switch (tmp) { - case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ - nbx = round_up(nbx, 32 * 8); - nby = round_up(nby, 16 * 8); - break; - case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/ - case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 16 * 8); - nby = round_up(nby, 16 * 8); - break; - case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/ - nbx = round_up(nbx, 16 * 8); - nby = round_up(nby, 8 * 8); - break; - default: - return -EINVAL; - } - break; - default: - dev_warn(p->dev, "%s:%d invalid num pipes %d\n", - __func__, __LINE__, track->npipes); - return -EINVAL; - } - } - /* compute number of htile */ - nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4; - nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4; - size = nbx * nby * 4; - size += track->htile_offset; - - if (size > radeon_bo_size(track->htile_bo)) { - dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n", - __func__, __LINE__, radeon_bo_size(track->htile_bo), - size, nbx, nby); - return -EINVAL; - } - } - - track->db_dirty = false; - return 0; -} - -static int r600_cs_track_check(struct radeon_cs_parser *p) -{ - struct r600_cs_track *track = p->track; - u32 tmp; - int r, i; - - /* on legacy kernel we don't perform advanced check */ - if (p->rdev == NULL) - return 0; - - /* check streamout */ - if (track->streamout_dirty && track->vgt_strmout_en) { - for (i = 0; i < 4; i++) { - if (track->vgt_strmout_buffer_en & (1 << i)) { - if (track->vgt_strmout_bo[i]) { - u64 offset = (u64)track->vgt_strmout_bo_offset[i] + - (u64)track->vgt_strmout_size[i]; - if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) { - DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n", - i, offset, - radeon_bo_size(track->vgt_strmout_bo[i])); - return -EINVAL; - } - } else { - dev_warn(p->dev, "No buffer for streamout %d\n", i); - return -EINVAL; - } - } - } - track->streamout_dirty = false; - } - - if (track->sx_misc_kill_all_prims) - return 0; - - /* check that we have a cb for each enabled target, we don't check - * shader_mask because it seems mesa isn't always setting it :( - */ - if (track->cb_dirty) { - tmp = track->cb_target_mask; - for (i = 0; i < 8; i++) { - if ((tmp >> (i * 4)) & 0xF) { - /* at least one component is enabled */ - if (track->cb_color_bo[i] == NULL) { - dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n", - __func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i); - return -EINVAL; - } - /* perform rewrite of CB_COLOR[0-7]_SIZE */ - r = r600_cs_track_validate_cb(p, i); - if (r) - return r; - } - } - track->cb_dirty = false; - } - - /* Check depth buffer */ - if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || - G_028800_Z_ENABLE(track->db_depth_control))) { - r = r600_cs_track_validate_db(p); - if (r) - return r; - } - - return 0; -} - -/** - * r600_cs_packet_parse() - parse cp packet and point ib index to next packet - * @parser: parser structure holding parsing context. - * @pkt: where to store packet informations - * - * Assume that chunk_ib_index is properly set. Will return -EINVAL - * if packet is bigger than remaining ib size. or if packets is unknown. - **/ -int r600_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx) -{ - struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; - uint32_t header; - - if (idx >= ib_chunk->length_dw) { - DRM_ERROR("Can not parse packet at %d after CS end %d !\n", - idx, ib_chunk->length_dw); - return -EINVAL; - } - header = radeon_get_ib_value(p, idx); - pkt->idx = idx; - pkt->type = CP_PACKET_GET_TYPE(header); - pkt->count = CP_PACKET_GET_COUNT(header); - pkt->one_reg_wr = 0; - switch (pkt->type) { - case PACKET_TYPE0: - pkt->reg = CP_PACKET0_GET_REG(header); - break; - case PACKET_TYPE3: - pkt->opcode = CP_PACKET3_GET_OPCODE(header); - break; - case PACKET_TYPE2: - pkt->count = -1; - break; - default: - DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); - return -EINVAL; - } - if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { - DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", - pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); - return -EINVAL; - } - return 0; -} - -/** - * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3 - * @parser: parser structure holding parsing context. - * @data: pointer to relocation data - * @offset_start: starting offset - * @offset_mask: offset mask (to align start offset on) - * @reloc: reloc informations - * - * Check next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_packet p3reloc; - unsigned idx; - int r; - - if (p->chunk_relocs_idx == -1) { - DRM_ERROR("No relocation chunk !\n"); - return -EINVAL; - } - *cs_reloc = NULL; - relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = r600_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return r; - } - p->idx += p3reloc.count + 2; - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - return -EINVAL; - } - idx = radeon_get_ib_value(p, p3reloc.idx + 1); - if (idx >= relocs_chunk->length_dw) { - DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", - idx, relocs_chunk->length_dw); - return -EINVAL; - } - /* FIXME: we assume reloc size is 4 dwords */ - *cs_reloc = p->relocs_ptr[(idx / 4)]; - return 0; -} - -/** - * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3 - * @parser: parser structure holding parsing context. - * @data: pointer to relocation data - * @offset_start: starting offset - * @offset_mask: offset mask (to align start offset on) - * @reloc: reloc informations - * - * Check next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, - struct radeon_cs_reloc **cs_reloc) -{ - struct radeon_cs_chunk *relocs_chunk; - struct radeon_cs_packet p3reloc; - unsigned idx; - int r; - - if (p->chunk_relocs_idx == -1) { - DRM_ERROR("No relocation chunk !\n"); - return -EINVAL; - } - *cs_reloc = NULL; - relocs_chunk = &p->chunks[p->chunk_relocs_idx]; - r = r600_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return r; - } - p->idx += p3reloc.count + 2; - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - DRM_ERROR("No packet3 for relocation for packet at %d.\n", - p3reloc.idx); - return -EINVAL; - } - idx = radeon_get_ib_value(p, p3reloc.idx + 1); - if (idx >= relocs_chunk->length_dw) { - DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", - idx, relocs_chunk->length_dw); - return -EINVAL; - } - *cs_reloc = p->relocs; - (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32; - (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; - return 0; -} - -/** - * r600_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc - * @parser: parser structure holding parsing context. - * - * Check next packet is relocation packet3, do bo validation and compute - * GPU offset using the provided start. - **/ -static int r600_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet p3reloc; - int r; - - r = r600_cs_packet_parse(p, &p3reloc, p->idx); - if (r) { - return 0; - } - if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { - return 0; - } - return 1; -} - -/** - * r600_cs_packet_next_vline() - parse userspace VLINE packet - * @parser: parser structure holding parsing context. - * - * Userspace sends a special sequence for VLINE waits. - * PACKET0 - VLINE_START_END + value - * PACKET3 - WAIT_REG_MEM poll vline status reg - * RELOC (P3) - crtc_id in reloc. - * - * This function parses this and relocates the VLINE START END - * and WAIT_REG_MEM packets to the correct crtc. - * It also detects a switched off crtc and nulls out the - * wait in that case. - */ -static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) -{ - struct drm_mode_object *obj; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - struct radeon_cs_packet p3reloc, wait_reg_mem; - int crtc_id; - int r; - uint32_t header, h_idx, reg, wait_reg_mem_info; - volatile uint32_t *ib; - - ib = p->ib->ptr; - - /* parse the WAIT_REG_MEM */ - r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx); - if (r) - return r; - - /* check its a WAIT_REG_MEM */ - if (wait_reg_mem.type != PACKET_TYPE3 || - wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { - DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); - return -EINVAL; - } - - wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); - /* bit 4 is reg (0) or mem (1) */ - if (wait_reg_mem_info & 0x10) { - DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); - return -EINVAL; - } - /* waiting for value to be equal */ - if ((wait_reg_mem_info & 0x7) != 0x3) { - DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); - return -EINVAL; - } - if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != AVIVO_D1MODE_VLINE_STATUS) { - DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); - return -EINVAL; - } - - if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != AVIVO_D1MODE_VLINE_STAT) { - DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); - return -EINVAL; - } - - /* jump over the NOP */ - r = r600_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); - if (r) - return r; - - h_idx = p->idx - 2; - p->idx += wait_reg_mem.count + 2; - p->idx += p3reloc.count + 2; - - header = radeon_get_ib_value(p, h_idx); - crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); - reg = CP_PACKET0_GET_REG(header); - - obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { - DRM_ERROR("cannot find crtc %d\n", crtc_id); - return -EINVAL; - } - crtc = obj_to_crtc(obj); - radeon_crtc = to_radeon_crtc(crtc); - crtc_id = radeon_crtc->crtc_id; - - if (!crtc->enabled) { - /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ - ib[h_idx + 2] = PACKET2(0); - ib[h_idx + 3] = PACKET2(0); - ib[h_idx + 4] = PACKET2(0); - ib[h_idx + 5] = PACKET2(0); - ib[h_idx + 6] = PACKET2(0); - ib[h_idx + 7] = PACKET2(0); - ib[h_idx + 8] = PACKET2(0); - } else if (crtc_id == 1) { - switch (reg) { - case AVIVO_D1MODE_VLINE_START_END: - header &= ~R600_CP_PACKET0_REG_MASK; - header |= AVIVO_D2MODE_VLINE_START_END >> 2; - break; - default: - DRM_ERROR("unknown crtc reloc\n"); - return -EINVAL; - } - ib[h_idx] = header; - ib[h_idx + 4] = AVIVO_D2MODE_VLINE_STATUS >> 2; - } - - return 0; -} - -static int r600_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg) -{ - int r; - - switch (reg) { - case AVIVO_D1MODE_VLINE_START_END: - r = r600_cs_packet_parse_vline(p); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - return r; - } - break; - default: - printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", - reg, idx); - return -EINVAL; - } - return 0; -} - -static int r600_cs_parse_packet0(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - unsigned reg, i; - unsigned idx; - int r; - - idx = pkt->idx + 1; - reg = pkt->reg; - for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { - r = r600_packet0_check(p, pkt, idx, reg); - if (r) { - return r; - } - } - return 0; -} - -/** - * r600_cs_check_reg() - check if register is authorized or not - * @parser: parser structure holding parsing context - * @reg: register we are testing - * @idx: index into the cs buffer - * - * This function will test against r600_reg_safe_bm and return 0 - * if register is safe. If register is not flag as safe this function - * will test it against a list of register needind special handling. - */ -static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) -{ - struct r600_cs_track *track = (struct r600_cs_track *)p->track; - struct radeon_cs_reloc *reloc; - u32 m, i, tmp, *ib; - int r; - - i = (reg >> 7); - if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return -EINVAL; - } - m = 1 << ((reg >> 2) & 31); - if (!(r600_reg_safe_bm[i] & m)) - return 0; - ib = p->ib->ptr; - switch (reg) { - /* force following reg to 0 in an attempt to disable out buffer - * which will need us to better understand how it works to perform - * security check on it (Jerome) - */ - case R_0288A8_SQ_ESGS_RING_ITEMSIZE: - case R_008C44_SQ_ESGS_RING_SIZE: - case R_0288B0_SQ_ESTMP_RING_ITEMSIZE: - case R_008C54_SQ_ESTMP_RING_SIZE: - case R_0288C0_SQ_FBUF_RING_ITEMSIZE: - case R_008C74_SQ_FBUF_RING_SIZE: - case R_0288B4_SQ_GSTMP_RING_ITEMSIZE: - case R_008C5C_SQ_GSTMP_RING_SIZE: - case R_0288AC_SQ_GSVS_RING_ITEMSIZE: - case R_008C4C_SQ_GSVS_RING_SIZE: - case R_0288BC_SQ_PSTMP_RING_ITEMSIZE: - case R_008C6C_SQ_PSTMP_RING_SIZE: - case R_0288C4_SQ_REDUC_RING_ITEMSIZE: - case R_008C7C_SQ_REDUC_RING_SIZE: - case R_0288B8_SQ_VSTMP_RING_ITEMSIZE: - case R_008C64_SQ_VSTMP_RING_SIZE: - case R_0288C8_SQ_GS_VERT_ITEMSIZE: - /* get value to populate the IB don't remove */ - tmp =radeon_get_ib_value(p, idx); - ib[idx] = 0; - break; - case SQ_CONFIG: - track->sq_config = radeon_get_ib_value(p, idx); - break; - case R_028800_DB_DEPTH_CONTROL: - track->db_depth_control = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case R_028010_DB_DEPTH_INFO: - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && - r600_cs_packet_next_is_pkt3_nop(p)) { - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->db_depth_info = radeon_get_ib_value(p, idx); - ib[idx] &= C_028010_ARRAY_MODE; - track->db_depth_info &= C_028010_ARRAY_MODE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); - track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); - } else { - ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); - track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); - } - } else { - track->db_depth_info = radeon_get_ib_value(p, idx); - } - track->db_dirty = true; - break; - case R_028004_DB_DEPTH_VIEW: - track->db_depth_view = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case R_028000_DB_DEPTH_SIZE: - track->db_depth_size = radeon_get_ib_value(p, idx); - track->db_depth_size_idx = idx; - track->db_dirty = true; - break; - case R_028AB0_VGT_STRMOUT_EN: - track->vgt_strmout_en = radeon_get_ib_value(p, idx); - track->streamout_dirty = true; - break; - case R_028B20_VGT_STRMOUT_BUFFER_EN: - track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx); - track->streamout_dirty = true; - break; - case VGT_STRMOUT_BUFFER_BASE_0: - case VGT_STRMOUT_BUFFER_BASE_1: - case VGT_STRMOUT_BUFFER_BASE_2: - case VGT_STRMOUT_BUFFER_BASE_3: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16; - track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->vgt_strmout_bo[tmp] = reloc->robj; - track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset; - track->streamout_dirty = true; - break; - case VGT_STRMOUT_BUFFER_SIZE_0: - case VGT_STRMOUT_BUFFER_SIZE_1: - case VGT_STRMOUT_BUFFER_SIZE_2: - case VGT_STRMOUT_BUFFER_SIZE_3: - tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16; - /* size in register is DWs, convert to bytes */ - track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4; - track->streamout_dirty = true; - break; - case CP_COHER_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "missing reloc for CP_COHER_BASE " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case R_028238_CB_TARGET_MASK: - track->cb_target_mask = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case R_02823C_CB_SHADER_MASK: - track->cb_shader_mask = radeon_get_ib_value(p, idx); - break; - case R_028C04_PA_SC_AA_CONFIG: - tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); - track->nsamples = 1 << tmp; - track->cb_dirty = true; - break; - case R_0280A0_CB_COLOR0_INFO: - case R_0280A4_CB_COLOR1_INFO: - case R_0280A8_CB_COLOR2_INFO: - case R_0280AC_CB_COLOR3_INFO: - case R_0280B0_CB_COLOR4_INFO: - case R_0280B4_CB_COLOR5_INFO: - case R_0280B8_CB_COLOR6_INFO: - case R_0280BC_CB_COLOR7_INFO: - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && - r600_cs_packet_next_is_pkt3_nop(p)) { - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); - return -EINVAL; - } - tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; - track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); - track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); - } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { - ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); - track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); - } - } else { - tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; - track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - } - track->cb_dirty = true; - break; - case R_028080_CB_COLOR0_VIEW: - case R_028084_CB_COLOR1_VIEW: - case R_028088_CB_COLOR2_VIEW: - case R_02808C_CB_COLOR3_VIEW: - case R_028090_CB_COLOR4_VIEW: - case R_028094_CB_COLOR5_VIEW: - case R_028098_CB_COLOR6_VIEW: - case R_02809C_CB_COLOR7_VIEW: - tmp = (reg - R_028080_CB_COLOR0_VIEW) / 4; - track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); - track->cb_dirty = true; - break; - case R_028060_CB_COLOR0_SIZE: - case R_028064_CB_COLOR1_SIZE: - case R_028068_CB_COLOR2_SIZE: - case R_02806C_CB_COLOR3_SIZE: - case R_028070_CB_COLOR4_SIZE: - case R_028074_CB_COLOR5_SIZE: - case R_028078_CB_COLOR6_SIZE: - case R_02807C_CB_COLOR7_SIZE: - tmp = (reg - R_028060_CB_COLOR0_SIZE) / 4; - track->cb_color_size[tmp] = radeon_get_ib_value(p, idx); - track->cb_color_size_idx[tmp] = idx; - track->cb_dirty = true; - break; - /* This register were added late, there is userspace - * which does provide relocation for those but set - * 0 offset. In order to avoid breaking old userspace - * we detect this and set address to point to last - * CB_COLOR0_BASE, note that if userspace doesn't set - * CB_COLOR0_BASE before this register we will report - * error. Old userspace always set CB_COLOR0_BASE - * before any of this. - */ - case R_0280E0_CB_COLOR0_FRAG: - case R_0280E4_CB_COLOR1_FRAG: - case R_0280E8_CB_COLOR2_FRAG: - case R_0280EC_CB_COLOR3_FRAG: - case R_0280F0_CB_COLOR4_FRAG: - case R_0280F4_CB_COLOR5_FRAG: - case R_0280F8_CB_COLOR6_FRAG: - case R_0280FC_CB_COLOR7_FRAG: - tmp = (reg - R_0280E0_CB_COLOR0_FRAG) / 4; - if (!r600_cs_packet_next_is_pkt3_nop(p)) { - if (!track->cb_color_base_last[tmp]) { - dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); - return -EINVAL; - } - ib[idx] = track->cb_color_base_last[tmp]; - track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; - } else { - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_frag_bo[tmp] = reloc->robj; - } - break; - case R_0280C0_CB_COLOR0_TILE: - case R_0280C4_CB_COLOR1_TILE: - case R_0280C8_CB_COLOR2_TILE: - case R_0280CC_CB_COLOR3_TILE: - case R_0280D0_CB_COLOR4_TILE: - case R_0280D4_CB_COLOR5_TILE: - case R_0280D8_CB_COLOR6_TILE: - case R_0280DC_CB_COLOR7_TILE: - tmp = (reg - R_0280C0_CB_COLOR0_TILE) / 4; - if (!r600_cs_packet_next_is_pkt3_nop(p)) { - if (!track->cb_color_base_last[tmp]) { - dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); - return -EINVAL; - } - ib[idx] = track->cb_color_base_last[tmp]; - track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; - } else { - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_tile_bo[tmp] = reloc->robj; - } - break; - case CB_COLOR0_BASE: - case CB_COLOR1_BASE: - case CB_COLOR2_BASE: - case CB_COLOR3_BASE: - case CB_COLOR4_BASE: - case CB_COLOR5_BASE: - case CB_COLOR6_BASE: - case CB_COLOR7_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - tmp = (reg - CB_COLOR0_BASE) / 4; - track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->cb_color_base_last[tmp] = ib[idx]; - track->cb_color_bo[tmp] = reloc->robj; - track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset; - track->cb_dirty = true; - break; - case DB_DEPTH_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->db_offset = radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->db_bo = reloc->robj; - track->db_bo_mc = reloc->lobj.gpu_offset; - track->db_dirty = true; - break; - case DB_HTILE_DATA_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - track->htile_offset = radeon_get_ib_value(p, idx) << 8; - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - track->htile_bo = reloc->robj; - track->db_dirty = true; - break; - case DB_HTILE_SURFACE: - track->htile_surface = radeon_get_ib_value(p, idx); - track->db_dirty = true; - break; - case SQ_PGM_START_FS: - case SQ_PGM_START_ES: - case SQ_PGM_START_VS: - case SQ_PGM_START_GS: - case SQ_PGM_START_PS: - case SQ_ALU_CONST_CACHE_GS_0: - case SQ_ALU_CONST_CACHE_GS_1: - case SQ_ALU_CONST_CACHE_GS_2: - case SQ_ALU_CONST_CACHE_GS_3: - case SQ_ALU_CONST_CACHE_GS_4: - case SQ_ALU_CONST_CACHE_GS_5: - case SQ_ALU_CONST_CACHE_GS_6: - case SQ_ALU_CONST_CACHE_GS_7: - case SQ_ALU_CONST_CACHE_GS_8: - case SQ_ALU_CONST_CACHE_GS_9: - case SQ_ALU_CONST_CACHE_GS_10: - case SQ_ALU_CONST_CACHE_GS_11: - case SQ_ALU_CONST_CACHE_GS_12: - case SQ_ALU_CONST_CACHE_GS_13: - case SQ_ALU_CONST_CACHE_GS_14: - case SQ_ALU_CONST_CACHE_GS_15: - case SQ_ALU_CONST_CACHE_PS_0: - case SQ_ALU_CONST_CACHE_PS_1: - case SQ_ALU_CONST_CACHE_PS_2: - case SQ_ALU_CONST_CACHE_PS_3: - case SQ_ALU_CONST_CACHE_PS_4: - case SQ_ALU_CONST_CACHE_PS_5: - case SQ_ALU_CONST_CACHE_PS_6: - case SQ_ALU_CONST_CACHE_PS_7: - case SQ_ALU_CONST_CACHE_PS_8: - case SQ_ALU_CONST_CACHE_PS_9: - case SQ_ALU_CONST_CACHE_PS_10: - case SQ_ALU_CONST_CACHE_PS_11: - case SQ_ALU_CONST_CACHE_PS_12: - case SQ_ALU_CONST_CACHE_PS_13: - case SQ_ALU_CONST_CACHE_PS_14: - case SQ_ALU_CONST_CACHE_PS_15: - case SQ_ALU_CONST_CACHE_VS_0: - case SQ_ALU_CONST_CACHE_VS_1: - case SQ_ALU_CONST_CACHE_VS_2: - case SQ_ALU_CONST_CACHE_VS_3: - case SQ_ALU_CONST_CACHE_VS_4: - case SQ_ALU_CONST_CACHE_VS_5: - case SQ_ALU_CONST_CACHE_VS_6: - case SQ_ALU_CONST_CACHE_VS_7: - case SQ_ALU_CONST_CACHE_VS_8: - case SQ_ALU_CONST_CACHE_VS_9: - case SQ_ALU_CONST_CACHE_VS_10: - case SQ_ALU_CONST_CACHE_VS_11: - case SQ_ALU_CONST_CACHE_VS_12: - case SQ_ALU_CONST_CACHE_VS_13: - case SQ_ALU_CONST_CACHE_VS_14: - case SQ_ALU_CONST_CACHE_VS_15: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case SX_MEMORY_EXPORT_BASE: - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONFIG_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - break; - case SX_MISC: - track->sx_misc_kill_all_prims = (radeon_get_ib_value(p, idx) & 0x1) != 0; - break; - default: - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return -EINVAL; - } - return 0; -} - -unsigned r600_mip_minify(unsigned size, unsigned level) -{ - unsigned val; - - val = max(1U, size >> level); - if (level > 0) - val = roundup_pow_of_two(val); - return val; -} - -static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, - unsigned w0, unsigned h0, unsigned d0, unsigned format, - unsigned block_align, unsigned height_align, unsigned base_align, - unsigned *l0_size, unsigned *mipmap_size) -{ - unsigned offset, i, level; - unsigned width, height, depth, size; - unsigned blocksize; - unsigned nbx, nby; - unsigned nlevels = llevel - blevel + 1; - - *l0_size = -1; - blocksize = r600_fmt_get_blocksize(format); - - w0 = r600_mip_minify(w0, 0); - h0 = r600_mip_minify(h0, 0); - d0 = r600_mip_minify(d0, 0); - for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { - width = r600_mip_minify(w0, i); - nbx = r600_fmt_get_nblocksx(format, width); - - nbx = round_up(nbx, block_align); - - height = r600_mip_minify(h0, i); - nby = r600_fmt_get_nblocksy(format, height); - nby = round_up(nby, height_align); - - depth = r600_mip_minify(d0, i); - - size = nbx * nby * blocksize; - if (nfaces) - size *= nfaces; - else - size *= depth; - - if (i == 0) - *l0_size = size; - - if (i == 0 || i == 1) - offset = round_up(offset, base_align); - - offset += size; - } - *mipmap_size = offset; - if (llevel == 0) - *mipmap_size = *l0_size; - if (!blevel) - *mipmap_size -= *l0_size; -} - -/** - * r600_check_texture_resource() - check if register is authorized or not - * @p: parser structure holding parsing context - * @idx: index into the cs buffer - * @texture: texture's bo structure - * @mipmap: mipmap's bo structure - * - * This function will check that the resource has valid field and that - * the texture and mipmap bo object are big enough to cover this resource. - */ -static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, - struct radeon_bo *texture, - struct radeon_bo *mipmap, - u64 base_offset, - u64 mip_offset, - u32 tiling_flags) -{ - struct r600_cs_track *track = p->track; - u32 nfaces, llevel, blevel, w0, h0, d0; - u32 word0, word1, l0_size, mipmap_size, word2, word3; - u32 height_align, pitch, pitch_align, depth_align; - u32 array, barray, larray; - u64 base_align; - struct array_mode_checker array_check; - u32 format; - - /* on legacy kernel we don't perform advanced check */ - if (p->rdev == NULL) - return 0; - - /* convert to bytes */ - base_offset <<= 8; - mip_offset <<= 8; - - word0 = radeon_get_ib_value(p, idx + 0); - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (tiling_flags & RADEON_TILING_MACRO) - word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); - else if (tiling_flags & RADEON_TILING_MICRO) - word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); - } - word1 = radeon_get_ib_value(p, idx + 1); - w0 = G_038000_TEX_WIDTH(word0) + 1; - h0 = G_038004_TEX_HEIGHT(word1) + 1; - d0 = G_038004_TEX_DEPTH(word1); - nfaces = 1; - array = 0; - switch (G_038000_DIM(word0)) { - case V_038000_SQ_TEX_DIM_1D: - case V_038000_SQ_TEX_DIM_2D: - case V_038000_SQ_TEX_DIM_3D: - break; - case V_038000_SQ_TEX_DIM_CUBEMAP: - if (p->family >= CHIP_RV770) - nfaces = 8; - else - nfaces = 6; - break; - case V_038000_SQ_TEX_DIM_1D_ARRAY: - case V_038000_SQ_TEX_DIM_2D_ARRAY: - array = 1; - break; - case V_038000_SQ_TEX_DIM_2D_MSAA: - case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: - default: - dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); - return -EINVAL; - } - format = G_038004_DATA_FORMAT(word1); - if (!r600_fmt_is_valid_texture(format, p->family)) { - dev_warn(p->dev, "%s:%d texture invalid format %d\n", - __func__, __LINE__, format); - return -EINVAL; - } - - /* pitch in texels */ - pitch = (G_038000_PITCH(word0) + 1) * 8; - array_check.array_mode = G_038000_TILE_MODE(word0); - array_check.group_size = track->group_size; - array_check.nbanks = track->nbanks; - array_check.npipes = track->npipes; - array_check.nsamples = 1; - array_check.blocksize = r600_fmt_get_blocksize(format); - if (r600_get_array_mode_alignment(&array_check, - &pitch_align, &height_align, &depth_align, &base_align)) { - dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", - __func__, __LINE__, G_038000_TILE_MODE(word0)); - return -EINVAL; - } - - /* XXX check height as well... */ - - if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0)); - return -EINVAL; - } - if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s:%d tex base offset (0x%llx, 0x%llx, %d) invalid\n", - __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0)); - return -EINVAL; - } - if (!IS_ALIGNED(mip_offset, base_align)) { - dev_warn(p->dev, "%s:%d tex mip offset (0x%llx, 0x%llx, %d) invalid\n", - __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0)); - return -EINVAL; - } - - word2 = radeon_get_ib_value(p, idx + 2) << 8; - word3 = radeon_get_ib_value(p, idx + 3) << 8; - - word0 = radeon_get_ib_value(p, idx + 4); - word1 = radeon_get_ib_value(p, idx + 5); - blevel = G_038010_BASE_LEVEL(word0); - llevel = G_038014_LAST_LEVEL(word1); - if (blevel > llevel) { - dev_warn(p->dev, "texture blevel %d > llevel %d\n", - blevel, llevel); - } - if (array == 1) { - barray = G_038014_BASE_ARRAY(word1); - larray = G_038014_LAST_ARRAY(word1); - - nfaces = larray - barray + 1; - } - r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, - pitch_align, height_align, base_align, - &l0_size, &mipmap_size); - /* using get ib will give us the offset into the texture bo */ - if ((l0_size + word2) > radeon_bo_size(texture)) { - dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n", - w0, h0, pitch_align, height_align, - array_check.array_mode, format, word2, - l0_size, radeon_bo_size(texture)); - dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align); - return -EINVAL; - } - /* using get ib will give us the offset into the mipmap bo */ - word3 = radeon_get_ib_value(p, idx + 3) << 8; - if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { - /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", - w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ - } - return 0; -} - -static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) -{ - u32 m, i; - - i = (reg >> 7); - if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return false; - } - m = 1 << ((reg >> 2) & 31); - if (!(r600_reg_safe_bm[i] & m)) - return true; - dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); - return false; -} - -static int r600_packet3_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) -{ - struct radeon_cs_reloc *reloc; - struct r600_cs_track *track; - volatile u32 *ib; - unsigned idx; - unsigned i; - unsigned start_reg, end_reg, reg; - int r; - u32 idx_value; - - track = (struct r600_cs_track *)p->track; - ib = p->ib->ptr; - idx = pkt->idx + 1; - idx_value = radeon_get_ib_value(p, idx); - - switch (pkt->opcode) { - case PACKET3_SET_PREDICATION: - { - int pred_op; - int tmp; - uint64_t offset; - - if (pkt->count != 1) { - DRM_ERROR("bad SET PREDICATION\n"); - return -EINVAL; - } - - tmp = radeon_get_ib_value(p, idx + 1); - pred_op = (tmp >> 16) & 0x7; - - /* for the clear predicate operation */ - if (pred_op == 0) - return 0; - - if (pred_op > 2) { - DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op); - return -EINVAL; - } - - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET PREDICATION\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (idx_value & 0xfffffff0) + - ((u64)(tmp & 0xff) << 32); - - ib[idx + 0] = offset; - ib[idx + 1] = (tmp & 0xffffff00) | (upper_32_bits(offset) & 0xff); - } - break; - - case PACKET3_START_3D_CMDBUF: - if (p->family >= CHIP_RV770 || pkt->count) { - DRM_ERROR("bad START_3D\n"); - return -EINVAL; - } - break; - case PACKET3_CONTEXT_CONTROL: - if (pkt->count != 1) { - DRM_ERROR("bad CONTEXT_CONTROL\n"); - return -EINVAL; - } - break; - case PACKET3_INDEX_TYPE: - case PACKET3_NUM_INSTANCES: - if (pkt->count) { - DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n"); - return -EINVAL; - } - break; - case PACKET3_DRAW_INDEX: - { - uint64_t offset; - if (pkt->count != 3) { - DRM_ERROR("bad DRAW_INDEX\n"); - return -EINVAL; - } - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad DRAW_INDEX\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - idx_value + - ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); - - ib[idx+0] = offset; - ib[idx+1] = upper_32_bits(offset) & 0xff; - - r = r600_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - } - case PACKET3_DRAW_INDEX_AUTO: - if (pkt->count != 1) { - DRM_ERROR("bad DRAW_INDEX_AUTO\n"); - return -EINVAL; - } - r = r600_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); - return r; - } - break; - case PACKET3_DRAW_INDEX_IMMD_BE: - case PACKET3_DRAW_INDEX_IMMD: - if (pkt->count < 2) { - DRM_ERROR("bad DRAW_INDEX_IMMD\n"); - return -EINVAL; - } - r = r600_cs_track_check(p); - if (r) { - dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); - return r; - } - break; - case PACKET3_WAIT_REG_MEM: - if (pkt->count != 5) { - DRM_ERROR("bad WAIT_REG_MEM\n"); - return -EINVAL; - } - /* bit 4 is reg (0) or mem (1) */ - if (idx_value & 0x10) { - uint64_t offset; - - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad WAIT_REG_MEM\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffff0) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffff0); - ib[idx+2] = upper_32_bits(offset) & 0xff; - } - break; - case PACKET3_SURFACE_SYNC: - if (pkt->count != 3) { - DRM_ERROR("bad SURFACE_SYNC\n"); - return -EINVAL; - } - /* 0xffffffff/0x0 is flush all cache flag */ - if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || - radeon_get_ib_value(p, idx + 2) != 0) { - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SURFACE_SYNC\n"); - return -EINVAL; - } - ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - } - break; - case PACKET3_EVENT_WRITE: - if (pkt->count != 2 && pkt->count != 0) { - DRM_ERROR("bad EVENT_WRITE\n"); - return -EINVAL; - } - if (pkt->count) { - uint64_t offset; - - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad EVENT_WRITE\n"); - return -EINVAL; - } - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffff8) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = offset & 0xfffffff8; - ib[idx+2] = upper_32_bits(offset) & 0xff; - } - break; - case PACKET3_EVENT_WRITE_EOP: - { - uint64_t offset; - - if (pkt->count != 4) { - DRM_ERROR("bad EVENT_WRITE_EOP\n"); - return -EINVAL; - } - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad EVENT_WRITE\n"); - return -EINVAL; - } - - offset = reloc->lobj.gpu_offset + - (radeon_get_ib_value(p, idx+1) & 0xfffffffc) + - ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); - - ib[idx+1] = offset & 0xfffffffc; - ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff); - break; - } - case PACKET3_SET_CONFIG_REG: - start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) || - (start_reg >= PACKET3_SET_CONFIG_REG_END) || - (end_reg >= PACKET3_SET_CONFIG_REG_END)) { - DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); - return -EINVAL; - } - for (i = 0; i < pkt->count; i++) { - reg = start_reg + (4 * i); - r = r600_cs_check_reg(p, reg, idx+1+i); - if (r) - return r; - } - break; - case PACKET3_SET_CONTEXT_REG: - start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) || - (start_reg >= PACKET3_SET_CONTEXT_REG_END) || - (end_reg >= PACKET3_SET_CONTEXT_REG_END)) { - DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n"); - return -EINVAL; - } - for (i = 0; i < pkt->count; i++) { - reg = start_reg + (4 * i); - r = r600_cs_check_reg(p, reg, idx+1+i); - if (r) - return r; - } - break; - case PACKET3_SET_RESOURCE: - if (pkt->count % 7) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) || - (start_reg >= PACKET3_SET_RESOURCE_END) || - (end_reg >= PACKET3_SET_RESOURCE_END)) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - for (i = 0; i < (pkt->count / 7); i++) { - struct radeon_bo *texture, *mipmap; - u32 size, offset, base_offset, mip_offset; - - switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { - case SQ_TEX_VTX_VALID_TEXTURE: - /* tex base */ - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); - } - texture = reloc->robj; - /* tex mip base */ - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - mipmap = reloc->robj; - r = r600_check_texture_resource(p, idx+(i*7)+1, - texture, mipmap, - base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2), - mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3), - reloc->lobj.tiling_flags); - if (r) - return r; - ib[idx+1+(i*7)+2] += base_offset; - ib[idx+1+(i*7)+3] += mip_offset; - break; - case SQ_TEX_VTX_VALID_BUFFER: - { - uint64_t offset64; - /* vtx base */ - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+1+(i*7)+0); - size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1; - if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { - /* force size to size of the buffer */ - dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n", - size + offset, radeon_bo_size(reloc->robj)); - ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj) - offset; - } - - offset64 = reloc->lobj.gpu_offset + offset; - ib[idx+1+(i*8)+0] = offset64; - ib[idx+1+(i*8)+2] = (ib[idx+1+(i*8)+2] & 0xffffff00) | - (upper_32_bits(offset64) & 0xff); - break; - } - case SQ_TEX_VTX_INVALID_TEXTURE: - case SQ_TEX_VTX_INVALID_BUFFER: - default: - DRM_ERROR("bad SET_RESOURCE\n"); - return -EINVAL; - } - } - break; - case PACKET3_SET_ALU_CONST: - if (track->sq_config & DX9_CONSTS) { - start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || - (start_reg >= PACKET3_SET_ALU_CONST_END) || - (end_reg >= PACKET3_SET_ALU_CONST_END)) { - DRM_ERROR("bad SET_ALU_CONST\n"); - return -EINVAL; - } - } - break; - case PACKET3_SET_BOOL_CONST: - start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) || - (start_reg >= PACKET3_SET_BOOL_CONST_END) || - (end_reg >= PACKET3_SET_BOOL_CONST_END)) { - DRM_ERROR("bad SET_BOOL_CONST\n"); - return -EINVAL; - } - break; - case PACKET3_SET_LOOP_CONST: - start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) || - (start_reg >= PACKET3_SET_LOOP_CONST_END) || - (end_reg >= PACKET3_SET_LOOP_CONST_END)) { - DRM_ERROR("bad SET_LOOP_CONST\n"); - return -EINVAL; - } - break; - case PACKET3_SET_CTL_CONST: - start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) || - (start_reg >= PACKET3_SET_CTL_CONST_END) || - (end_reg >= PACKET3_SET_CTL_CONST_END)) { - DRM_ERROR("bad SET_CTL_CONST\n"); - return -EINVAL; - } - break; - case PACKET3_SET_SAMPLER: - if (pkt->count % 3) { - DRM_ERROR("bad SET_SAMPLER\n"); - return -EINVAL; - } - start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_OFFSET; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) || - (start_reg >= PACKET3_SET_SAMPLER_END) || - (end_reg >= PACKET3_SET_SAMPLER_END)) { - DRM_ERROR("bad SET_SAMPLER\n"); - return -EINVAL; - } - break; - case PACKET3_SURFACE_BASE_UPDATE: - if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { - DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); - return -EINVAL; - } - if (pkt->count) { - DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); - return -EINVAL; - } - break; - case PACKET3_STRMOUT_BUFFER_UPDATE: - if (pkt->count != 4) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n"); - return -EINVAL; - } - /* Updating memory at DST_ADDRESS. */ - if (idx_value & 0x1) { - u64 offset; - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+1); - offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+1] = offset; - ib[idx+2] = upper_32_bits(offset) & 0xff; - } - /* Reading data from SRC_ADDRESS. */ - if (((idx_value >> 1) & 0x3) == 2) { - u64 offset; - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+3); - offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+3] = offset; - ib[idx+4] = upper_32_bits(offset) & 0xff; - } - break; - case PACKET3_COPY_DW: - if (pkt->count != 4) { - DRM_ERROR("bad COPY_DW (invalid count)\n"); - return -EINVAL; - } - if (idx_value & 0x1) { - u64 offset; - /* SRC is memory. */ - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad COPY_DW (missing src reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+1); - offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+1] = offset; - ib[idx+2] = upper_32_bits(offset) & 0xff; - } else { - /* SRC is a reg. */ - reg = radeon_get_ib_value(p, idx+1) << 2; - if (!r600_is_safe_reg(p, reg, idx+1)) - return -EINVAL; - } - if (idx_value & 0x2) { - u64 offset; - /* DST is memory. */ - r = r600_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); - return -EINVAL; - } - offset = radeon_get_ib_value(p, idx+3); - offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; - if ((offset + 4) > radeon_bo_size(reloc->robj)) { - DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n", - offset + 4, radeon_bo_size(reloc->robj)); - return -EINVAL; - } - offset += reloc->lobj.gpu_offset; - ib[idx+3] = offset; - ib[idx+4] = upper_32_bits(offset) & 0xff; - } else { - /* DST is a reg. */ - reg = radeon_get_ib_value(p, idx+3) << 2; - if (!r600_is_safe_reg(p, reg, idx+3)) - return -EINVAL; - } - break; - case PACKET3_NOP: - break; - default: - DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -int r600_cs_parse(struct radeon_cs_parser *p) -{ - struct radeon_cs_packet pkt; - struct r600_cs_track *track; - int r; - - if (p->track == NULL) { - /* initialize tracker, we are in kms */ - track = kzalloc(sizeof(*track), GFP_KERNEL); - if (track == NULL) - return -ENOMEM; - r600_cs_track_init(track); - if (p->rdev->family < CHIP_RV770) { - track->npipes = p->rdev->config.r600.tiling_npipes; - track->nbanks = p->rdev->config.r600.tiling_nbanks; - track->group_size = p->rdev->config.r600.tiling_group_size; - } else if (p->rdev->family <= CHIP_RV740) { - track->npipes = p->rdev->config.rv770.tiling_npipes; - track->nbanks = p->rdev->config.rv770.tiling_nbanks; - track->group_size = p->rdev->config.rv770.tiling_group_size; - } - p->track = track; - } - do { - r = r600_cs_packet_parse(p, &pkt, p->idx); - if (r) { - kfree(p->track); - p->track = NULL; - return r; - } - p->idx += pkt.count + 2; - switch (pkt.type) { - case PACKET_TYPE0: - r = r600_cs_parse_packet0(p, &pkt); - break; - case PACKET_TYPE2: - break; - case PACKET_TYPE3: - r = r600_packet3_check(p, &pkt); - break; - default: - DRM_ERROR("Unknown packet type %d !\n", pkt.type); - kfree(p->track); - p->track = NULL; - return -EINVAL; - } - if (r) { - kfree(p->track); - p->track = NULL; - return r; - } - } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); -#if 0 - for (r = 0; r < p->ib->length_dw; r++) { - printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); - mdelay(1); - } -#endif - kfree(p->track); - p->track = NULL; - return 0; -} - -static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) -{ - if (p->chunk_relocs_idx == -1) { - return 0; - } - p->relocs = kzalloc(sizeof(struct radeon_cs_reloc), GFP_KERNEL); - if (p->relocs == NULL) { - return -ENOMEM; - } - return 0; -} - -/** - * cs_parser_fini() - clean parser states - * @parser: parser structure holding parsing context. - * @error: error number - * - * If error is set than unvalidate buffer, otherwise just free memory - * used by parsing context. - **/ -static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) -{ - unsigned i; - - kfree(parser->relocs); - for (i = 0; i < parser->nchunks; i++) { - kfree(parser->chunks[i].kdata); - kfree(parser->chunks[i].kpage[0]); - kfree(parser->chunks[i].kpage[1]); - } - kfree(parser->chunks); - kfree(parser->chunks_array); -} - -int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, - unsigned family, u32 *ib, int *l) -{ - struct radeon_cs_parser parser; - struct radeon_cs_chunk *ib_chunk; - struct radeon_ib fake_ib; - struct r600_cs_track *track; - int r; - - /* initialize tracker */ - track = kzalloc(sizeof(*track), GFP_KERNEL); - if (track == NULL) - return -ENOMEM; - r600_cs_track_init(track); - r600_cs_legacy_get_tiling_conf(dev, &track->npipes, &track->nbanks, &track->group_size); - /* initialize parser */ - memset(&parser, 0, sizeof(struct radeon_cs_parser)); - parser.filp = filp; - parser.dev = &dev->pdev->dev; - parser.rdev = NULL; - parser.family = family; - parser.ib = &fake_ib; - parser.track = track; - fake_ib.ptr = ib; - r = radeon_cs_parser_init(&parser, data); - if (r) { - DRM_ERROR("Failed to initialize parser !\n"); - r600_cs_parser_fini(&parser, r); - return r; - } - r = r600_cs_parser_relocs_legacy(&parser); - if (r) { - DRM_ERROR("Failed to parse relocation !\n"); - r600_cs_parser_fini(&parser, r); - return r; - } - /* Copy the packet into the IB, the parser will read from the - * input memory (cached) and write to the IB (which can be - * uncached). */ - ib_chunk = &parser.chunks[parser.chunk_ib_idx]; - parser.ib->length_dw = ib_chunk->length_dw; - *l = parser.ib->length_dw; - r = r600_cs_parse(&parser); - if (r) { - DRM_ERROR("Invalid command stream !\n"); - r600_cs_parser_fini(&parser, r); - return r; - } - r = radeon_cs_finish_pages(&parser); - if (r) { - DRM_ERROR("Invalid command stream !\n"); - r600_cs_parser_fini(&parser, r); - return r; - } - r600_cs_parser_fini(&parser, r); - return r; -} - -void r600_cs_legacy_init(void) -{ - r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_hdmi.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_hdmi.c deleted file mode 100644 index 0b592067..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_hdmi.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Christian König. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Christian König - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" - -/* - * HDMI color format - */ -enum r600_hdmi_color_format { - RGB = 0, - YCC_422 = 1, - YCC_444 = 2 -}; - -/* - * IEC60958 status bits - */ -enum r600_hdmi_iec_status_bits { - AUDIO_STATUS_DIG_ENABLE = 0x01, - AUDIO_STATUS_V = 0x02, - AUDIO_STATUS_VCFG = 0x04, - AUDIO_STATUS_EMPHASIS = 0x08, - AUDIO_STATUS_COPYRIGHT = 0x10, - AUDIO_STATUS_NONAUDIO = 0x20, - AUDIO_STATUS_PROFESSIONAL = 0x40, - AUDIO_STATUS_LEVEL = 0x80 -}; - -struct { - uint32_t Clock; - - int N_32kHz; - int CTS_32kHz; - - int N_44_1kHz; - int CTS_44_1kHz; - - int N_48kHz; - int CTS_48kHz; - -} r600_hdmi_ACR[] = { - /* 32kHz 44.1kHz 48kHz */ - /* Clock N CTS N CTS N CTS */ - { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ - { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ - { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ - { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ - { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ - { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ - { 74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */ - { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ - { 148351, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */ - { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ - { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */ -}; - -/* - * calculate CTS value if it's not found in the table - */ -static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq) -{ - if (*CTS == 0) - *CTS = clock * N / (128 * freq) * 1000; - DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n", - N, *CTS, freq); -} - -/* - * update the N and CTS parameters for a given pixel clock rate - */ -static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - int CTS; - int N; - int i; - - for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++); - - CTS = r600_hdmi_ACR[i].CTS_32kHz; - N = r600_hdmi_ACR[i].N_32kHz; - r600_hdmi_calc_CTS(clock, &CTS, N, 32000); - WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12); - WREG32(offset+R600_HDMI_32kHz_N, N); - - CTS = r600_hdmi_ACR[i].CTS_44_1kHz; - N = r600_hdmi_ACR[i].N_44_1kHz; - r600_hdmi_calc_CTS(clock, &CTS, N, 44100); - WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12); - WREG32(offset+R600_HDMI_44_1kHz_N, N); - - CTS = r600_hdmi_ACR[i].CTS_48kHz; - N = r600_hdmi_ACR[i].N_48kHz; - r600_hdmi_calc_CTS(clock, &CTS, N, 48000); - WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12); - WREG32(offset+R600_HDMI_48kHz_N, N); -} - -/* - * calculate the crc for a given info frame - */ -static void r600_hdmi_infoframe_checksum(uint8_t packetType, - uint8_t versionNumber, - uint8_t length, - uint8_t *frame) -{ - int i; - frame[0] = packetType + versionNumber + length; - for (i = 1; i <= length; i++) - frame[0] += frame[i]; - frame[0] = 0x100 - frame[0]; -} - -/* - * build a HDMI Video Info Frame - */ -static void r600_hdmi_videoinfoframe( - struct drm_encoder *encoder, - enum r600_hdmi_color_format color_format, - int active_information_present, - uint8_t active_format_aspect_ratio, - uint8_t scan_information, - uint8_t colorimetry, - uint8_t ex_colorimetry, - uint8_t quantization, - int ITC, - uint8_t picture_aspect_ratio, - uint8_t video_format_identification, - uint8_t pixel_repetition, - uint8_t non_uniform_picture_scaling, - uint8_t bar_info_data_valid, - uint16_t top_bar, - uint16_t bottom_bar, - uint16_t left_bar, - uint16_t right_bar -) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - - uint8_t frame[14]; - - frame[0x0] = 0; - frame[0x1] = - (scan_information & 0x3) | - ((bar_info_data_valid & 0x3) << 2) | - ((active_information_present & 0x1) << 4) | - ((color_format & 0x3) << 5); - frame[0x2] = - (active_format_aspect_ratio & 0xF) | - ((picture_aspect_ratio & 0x3) << 4) | - ((colorimetry & 0x3) << 6); - frame[0x3] = - (non_uniform_picture_scaling & 0x3) | - ((quantization & 0x3) << 2) | - ((ex_colorimetry & 0x7) << 4) | - ((ITC & 0x1) << 7); - frame[0x4] = (video_format_identification & 0x7F); - frame[0x5] = (pixel_repetition & 0xF); - frame[0x6] = (top_bar & 0xFF); - frame[0x7] = (top_bar >> 8); - frame[0x8] = (bottom_bar & 0xFF); - frame[0x9] = (bottom_bar >> 8); - frame[0xA] = (left_bar & 0xFF); - frame[0xB] = (left_bar >> 8); - frame[0xC] = (right_bar & 0xFF); - frame[0xD] = (right_bar >> 8); - - r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); - /* Our header values (type, version, length) should be alright, Intel - * is using the same. Checksum function also seems to be OK, it works - * fine for audio infoframe. However calculated value is always lower - * by 2 in comparison to fglrx. It breaks displaying anything in case - * of TVs that strictly check the checksum. Hack it manually here to - * workaround this issue. */ - frame[0x0] += 2; - - WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0, - frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); - WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1, - frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24)); - WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2, - frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); - WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3, - frame[0xC] | (frame[0xD] << 8)); -} - -/* - * build a Audio Info Frame - */ -static void r600_hdmi_audioinfoframe( - struct drm_encoder *encoder, - uint8_t channel_count, - uint8_t coding_type, - uint8_t sample_size, - uint8_t sample_frequency, - uint8_t format, - uint8_t channel_allocation, - uint8_t level_shift, - int downmix_inhibit -) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - - uint8_t frame[11]; - - frame[0x0] = 0; - frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4); - frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2); - frame[0x3] = format; - frame[0x4] = channel_allocation; - frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7); - frame[0x6] = 0; - frame[0x7] = 0; - frame[0x8] = 0; - frame[0x9] = 0; - frame[0xA] = 0; - - r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame); - - WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0, - frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); - WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1, - frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24)); -} - -/* - * test if audio buffer is filled enough to start playing - */ -static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - - return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0; -} - -/* - * have buffer status changed since last call? - */ -int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - int status, result; - - if (!radeon_encoder->hdmi_offset) - return 0; - - status = r600_hdmi_is_audio_buffer_filled(encoder); - result = radeon_encoder->hdmi_buffer_status != status; - radeon_encoder->hdmi_buffer_status = status; - - return result; -} - -/* - * write the audio workaround status to the hardware - */ -void r600_hdmi_audio_workaround(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t offset = radeon_encoder->hdmi_offset; - - if (!offset) - return; - - if (!radeon_encoder->hdmi_audio_workaround || - r600_hdmi_is_audio_buffer_filled(encoder)) { - - /* disable audio workaround */ - WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001); - - } else { - /* enable audio workaround */ - WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001); - } -} - - -/* - * update the info frames with the data from the current display mode - */ -void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - - if (ASIC_IS_DCE5(rdev)) - return; - - if (!offset) - return; - - r600_audio_set_clock(encoder, mode->clock); - - WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000); - WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0); - WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000); - - r600_hdmi_update_ACR(encoder, mode->clock); - - WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13); - - WREG32(offset+R600_HDMI_VERSION, 0x202); - - r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ - WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF); - WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF); - WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001); - WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001); - - r600_hdmi_audio_workaround(encoder); - - /* audio packets per line, does anyone know how to calc this ? */ - WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000); -} - -/* - * update settings with current parameters from audio engine - */ -void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - - int channels = r600_audio_channels(rdev); - int rate = r600_audio_rate(rdev); - int bps = r600_audio_bits_per_sample(rdev); - uint8_t status_bits = r600_audio_status_bits(rdev); - uint8_t category_code = r600_audio_category_code(rdev); - - uint32_t iec; - - if (!offset) - return; - - DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", - r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped", - channels, rate, bps); - DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n", - (int)status_bits, (int)category_code); - - iec = 0; - if (status_bits & AUDIO_STATUS_PROFESSIONAL) - iec |= 1 << 0; - if (status_bits & AUDIO_STATUS_NONAUDIO) - iec |= 1 << 1; - if (status_bits & AUDIO_STATUS_COPYRIGHT) - iec |= 1 << 2; - if (status_bits & AUDIO_STATUS_EMPHASIS) - iec |= 1 << 3; - - iec |= category_code << 8; - - switch (rate) { - case 32000: iec |= 0x3 << 24; break; - case 44100: iec |= 0x0 << 24; break; - case 88200: iec |= 0x8 << 24; break; - case 176400: iec |= 0xc << 24; break; - case 48000: iec |= 0x2 << 24; break; - case 96000: iec |= 0xa << 24; break; - case 192000: iec |= 0xe << 24; break; - } - - WREG32(offset+R600_HDMI_IEC60958_1, iec); - - iec = 0; - switch (bps) { - case 16: iec |= 0x2; break; - case 20: iec |= 0x3; break; - case 24: iec |= 0xb; break; - } - if (status_bits & AUDIO_STATUS_V) - iec |= 0x5 << 16; - - WREG32_P(offset+R600_HDMI_IEC60958_2, iec, ~0x5000f); - - /* 0x021 or 0x031 sets the audio frame length */ - WREG32(offset+R600_HDMI_AUDIOCNTL, 0x31); - r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0); - - r600_hdmi_audio_workaround(encoder); -} - -static int r600_hdmi_find_free_block(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - bool free_blocks[3] = { true, true, true }; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); - switch (radeon_encoder->hdmi_offset) { - case R600_HDMI_BLOCK1: - free_blocks[0] = false; - break; - case R600_HDMI_BLOCK2: - free_blocks[1] = false; - break; - case R600_HDMI_BLOCK3: - free_blocks[2] = false; - break; - } - } - - if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || - rdev->family == CHIP_RS740) { - return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; - } else if (rdev->family >= CHIP_R600) { - if (free_blocks[0]) - return R600_HDMI_BLOCK1; - else if (free_blocks[1]) - return R600_HDMI_BLOCK2; - } - return 0; -} - -static void r600_hdmi_assign_block(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - - u16 eg_offsets[] = { - EVERGREEN_CRTC0_REGISTER_OFFSET, - EVERGREEN_CRTC1_REGISTER_OFFSET, - EVERGREEN_CRTC2_REGISTER_OFFSET, - EVERGREEN_CRTC3_REGISTER_OFFSET, - EVERGREEN_CRTC4_REGISTER_OFFSET, - EVERGREEN_CRTC5_REGISTER_OFFSET, - }; - - if (!dig) { - dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); - return; - } - - if (ASIC_IS_DCE5(rdev)) { - /* TODO */ - } else if (ASIC_IS_DCE4(rdev)) { - if (dig->dig_encoder >= ARRAY_SIZE(eg_offsets)) { - dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); - return; - } - radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BASE + - eg_offsets[dig->dig_encoder]; - radeon_encoder->hdmi_config_offset = radeon_encoder->hdmi_offset - + EVERGREEN_HDMI_CONFIG_OFFSET; - } else if (ASIC_IS_DCE3(rdev)) { - radeon_encoder->hdmi_offset = dig->dig_encoder ? - R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; - if (ASIC_IS_DCE32(rdev)) - radeon_encoder->hdmi_config_offset = dig->dig_encoder ? - R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; - } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 || - rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { - radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); - } -} - -/* - * enable the HDMI engine - */ -void r600_hdmi_enable(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t offset; - - if (ASIC_IS_DCE5(rdev)) - return; - - if (!radeon_encoder->hdmi_offset) { - r600_hdmi_assign_block(encoder); - if (!radeon_encoder->hdmi_offset) { - dev_warn(rdev->dev, "Could not find HDMI block for " - "0x%x encoder\n", radeon_encoder->encoder_id); - return; - } - } - - offset = radeon_encoder->hdmi_offset; - if (ASIC_IS_DCE5(rdev)) { - /* TODO */ - } else if (ASIC_IS_DCE4(rdev)) { - WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0x1, ~0x1); - } else if (ASIC_IS_DCE32(rdev)) { - WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); - } else if (ASIC_IS_DCE3(rdev)) { - /* TODO */ - } else if (rdev->family >= CHIP_R600) { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN, - ~AVIVO_TMDSA_CNTL_HDMI_EN); - WREG32(offset + R600_HDMI_ENABLE, 0x101); - break; - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN, - ~AVIVO_LVTMA_CNTL_HDMI_EN); - WREG32(offset + R600_HDMI_ENABLE, 0x105); - break; - default: - dev_err(rdev->dev, "Unknown HDMI output type\n"); - break; - } - } - - if (rdev->irq.installed - && rdev->family != CHIP_RS600 - && rdev->family != CHIP_RS690 - && rdev->family != CHIP_RS740 - && !ASIC_IS_DCE4(rdev)) { - /* if irq is available use it */ - rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true; - radeon_irq_set(rdev); - - r600_audio_disable_polling(encoder); - } else { - /* if not fallback to polling */ - r600_audio_enable_polling(encoder); - } - - DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", - radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); -} - -/* - * disable the HDMI engine - */ -void r600_hdmi_disable(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t offset; - - if (ASIC_IS_DCE5(rdev)) - return; - - offset = radeon_encoder->hdmi_offset; - if (!offset) { - dev_err(rdev->dev, "Disabling not enabled HDMI\n"); - return; - } - - DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", - offset, radeon_encoder->encoder_id); - - /* disable irq */ - rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = false; - radeon_irq_set(rdev); - - /* disable polling */ - r600_audio_disable_polling(encoder); - - if (ASIC_IS_DCE5(rdev)) { - /* TODO */ - } else if (ASIC_IS_DCE4(rdev)) { - WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0, ~0x1); - } else if (ASIC_IS_DCE32(rdev)) { - WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); - } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - WREG32_P(AVIVO_TMDSA_CNTL, 0, - ~AVIVO_TMDSA_CNTL_HDMI_EN); - WREG32(offset + R600_HDMI_ENABLE, 0); - break; - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - WREG32_P(AVIVO_LVTMA_CNTL, 0, - ~AVIVO_LVTMA_CNTL_HDMI_EN); - WREG32(offset + R600_HDMI_ENABLE, 0); - break; - default: - dev_err(rdev->dev, "Unknown HDMI output type\n"); - break; - } - } - - radeon_encoder->hdmi_offset = 0; - radeon_encoder->hdmi_config_offset = 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_reg.h deleted file mode 100644 index f869897c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600_reg.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __R600_REG_H__ -#define __R600_REG_H__ - -#define R600_PCIE_PORT_INDEX 0x0038 -#define R600_PCIE_PORT_DATA 0x003c - -#define R600_MC_VM_FB_LOCATION 0x2180 -#define R600_MC_FB_BASE_MASK 0x0000FFFF -#define R600_MC_FB_BASE_SHIFT 0 -#define R600_MC_FB_TOP_MASK 0xFFFF0000 -#define R600_MC_FB_TOP_SHIFT 16 -#define R600_MC_VM_AGP_TOP 0x2184 -#define R600_MC_AGP_TOP_MASK 0x0003FFFF -#define R600_MC_AGP_TOP_SHIFT 0 -#define R600_MC_VM_AGP_BOT 0x2188 -#define R600_MC_AGP_BOT_MASK 0x0003FFFF -#define R600_MC_AGP_BOT_SHIFT 0 -#define R600_MC_VM_AGP_BASE 0x218c -#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 -#define R600_LOGICAL_PAGE_NUMBER_MASK 0x000FFFFF -#define R600_LOGICAL_PAGE_NUMBER_SHIFT 0 -#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 -#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 - -#define R700_MC_VM_FB_LOCATION 0x2024 -#define R700_MC_FB_BASE_MASK 0x0000FFFF -#define R700_MC_FB_BASE_SHIFT 0 -#define R700_MC_FB_TOP_MASK 0xFFFF0000 -#define R700_MC_FB_TOP_SHIFT 16 -#define R700_MC_VM_AGP_TOP 0x2028 -#define R700_MC_AGP_TOP_MASK 0x0003FFFF -#define R700_MC_AGP_TOP_SHIFT 0 -#define R700_MC_VM_AGP_BOT 0x202c -#define R700_MC_AGP_BOT_MASK 0x0003FFFF -#define R700_MC_AGP_BOT_SHIFT 0 -#define R700_MC_VM_AGP_BASE 0x2030 -#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -#define R700_LOGICAL_PAGE_NUMBER_MASK 0x000FFFFF -#define R700_LOGICAL_PAGE_NUMBER_SHIFT 0 -#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c - -#define R600_RAMCFG 0x2408 -# define R600_CHANSIZE (1 << 7) -# define R600_CHANSIZE_OVERRIDE (1 << 10) - - -#define R600_GENERAL_PWRMGT 0x618 -# define R600_OPEN_DRAIN_PADS (1 << 11) - -#define R600_LOWER_GPIO_ENABLE 0x710 -#define R600_CTXSW_VID_LOWER_GPIO_CNTL 0x718 -#define R600_HIGH_VID_LOWER_GPIO_CNTL 0x71c -#define R600_MEDIUM_VID_LOWER_GPIO_CNTL 0x720 -#define R600_LOW_VID_LOWER_GPIO_CNTL 0x724 - -#define R600_D1GRPH_SWAP_CONTROL 0x610C -# define R600_D1GRPH_SWAP_ENDIAN_NONE (0 << 0) -# define R600_D1GRPH_SWAP_ENDIAN_16BIT (1 << 0) -# define R600_D1GRPH_SWAP_ENDIAN_32BIT (2 << 0) -# define R600_D1GRPH_SWAP_ENDIAN_64BIT (3 << 0) - -#define R600_HDP_NONSURFACE_BASE 0x2c04 - -#define R600_BUS_CNTL 0x5420 -# define R600_BIOS_ROM_DIS (1 << 1) -#define R600_CONFIG_CNTL 0x5424 -#define R600_CONFIG_MEMSIZE 0x5428 -#define R600_CONFIG_F0_BASE 0x542C -#define R600_CONFIG_APER_SIZE 0x5430 - -#define R600_ROM_CNTL 0x1600 -# define R600_SCK_OVERWRITE (1 << 1) -# define R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT 28 -# define R600_SCK_PRESCALE_CRYSTAL_CLK_MASK (0xf << 28) - -#define R600_CG_SPLL_FUNC_CNTL 0x600 -# define R600_SPLL_BYPASS_EN (1 << 3) -#define R600_CG_SPLL_STATUS 0x60c -# define R600_SPLL_CHG_STATUS (1 << 1) - -#define R600_BIOS_0_SCRATCH 0x1724 -#define R600_BIOS_1_SCRATCH 0x1728 -#define R600_BIOS_2_SCRATCH 0x172c -#define R600_BIOS_3_SCRATCH 0x1730 -#define R600_BIOS_4_SCRATCH 0x1734 -#define R600_BIOS_5_SCRATCH 0x1738 -#define R600_BIOS_6_SCRATCH 0x173c -#define R600_BIOS_7_SCRATCH 0x1740 - -/* Audio, these regs were reverse enginered, - * so the chance is high that the naming is wrong - * R6xx+ ??? */ - -/* Audio clocks */ -#define R600_AUDIO_PLL1_MUL 0x0514 -#define R600_AUDIO_PLL1_DIV 0x0518 -#define R600_AUDIO_PLL2_MUL 0x0524 -#define R600_AUDIO_PLL2_DIV 0x0528 -#define R600_AUDIO_CLK_SRCSEL 0x0534 - -/* Audio general */ -#define R600_AUDIO_ENABLE 0x7300 -#define R600_AUDIO_TIMING 0x7344 - -/* Audio params */ -#define R600_AUDIO_VENDOR_ID 0x7380 -#define R600_AUDIO_REVISION_ID 0x7384 -#define R600_AUDIO_ROOT_NODE_COUNT 0x7388 -#define R600_AUDIO_NID1_NODE_COUNT 0x738c -#define R600_AUDIO_NID1_TYPE 0x7390 -#define R600_AUDIO_SUPPORTED_SIZE_RATE 0x7394 -#define R600_AUDIO_SUPPORTED_CODEC 0x7398 -#define R600_AUDIO_SUPPORTED_POWER_STATES 0x739c -#define R600_AUDIO_NID2_CAPS 0x73a0 -#define R600_AUDIO_NID3_CAPS 0x73a4 -#define R600_AUDIO_NID3_PIN_CAPS 0x73a8 - -/* Audio conn list */ -#define R600_AUDIO_CONN_LIST_LEN 0x73ac -#define R600_AUDIO_CONN_LIST 0x73b0 - -/* Audio verbs */ -#define R600_AUDIO_RATE_BPS_CHANNEL 0x73c0 -#define R600_AUDIO_PLAYING 0x73c4 -#define R600_AUDIO_IMPLEMENTATION_ID 0x73c8 -#define R600_AUDIO_CONFIG_DEFAULT 0x73cc -#define R600_AUDIO_PIN_SENSE 0x73d0 -#define R600_AUDIO_PIN_WIDGET_CNTL 0x73d4 -#define R600_AUDIO_STATUS_BITS 0x73d8 - -/* HDMI base register addresses */ -#define R600_HDMI_BLOCK1 0x7400 -#define R600_HDMI_BLOCK2 0x7700 -#define R600_HDMI_BLOCK3 0x7800 - -/* HDMI registers */ -#define R600_HDMI_ENABLE 0x00 -#define R600_HDMI_STATUS 0x04 -# define R600_HDMI_INT_PENDING (1 << 29) -#define R600_HDMI_CNTL 0x08 -# define R600_HDMI_INT_EN (1 << 28) -# define R600_HDMI_INT_ACK (1 << 29) -#define R600_HDMI_UNKNOWN_0 0x0C -#define R600_HDMI_AUDIOCNTL 0x10 -#define R600_HDMI_VIDEOCNTL 0x14 -#define R600_HDMI_VERSION 0x18 -#define R600_HDMI_UNKNOWN_1 0x28 -#define R600_HDMI_VIDEOINFOFRAME_0 0x54 -#define R600_HDMI_VIDEOINFOFRAME_1 0x58 -#define R600_HDMI_VIDEOINFOFRAME_2 0x5c -#define R600_HDMI_VIDEOINFOFRAME_3 0x60 -#define R600_HDMI_32kHz_CTS 0xac -#define R600_HDMI_32kHz_N 0xb0 -#define R600_HDMI_44_1kHz_CTS 0xb4 -#define R600_HDMI_44_1kHz_N 0xb8 -#define R600_HDMI_48kHz_CTS 0xbc -#define R600_HDMI_48kHz_N 0xc0 -#define R600_HDMI_AUDIOINFOFRAME_0 0xcc -#define R600_HDMI_AUDIOINFOFRAME_1 0xd0 -#define R600_HDMI_IEC60958_1 0xd4 -#define R600_HDMI_IEC60958_2 0xd8 -#define R600_HDMI_UNKNOWN_2 0xdc -#define R600_HDMI_AUDIO_DEBUG_0 0xe0 -#define R600_HDMI_AUDIO_DEBUG_1 0xe4 -#define R600_HDMI_AUDIO_DEBUG_2 0xe8 -#define R600_HDMI_AUDIO_DEBUG_3 0xec - -/* HDMI additional config base register addresses */ -#define R600_HDMI_CONFIG1 0x7600 -#define R600_HDMI_CONFIG2 0x7a00 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600d.h deleted file mode 100644 index 12ceb829..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/r600d.h +++ /dev/null @@ -1,1578 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef R600D_H -#define R600D_H - -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) - -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) - -#define R6XX_MAX_SH_GPRS 256 -#define R6XX_MAX_TEMP_GPRS 16 -#define R6XX_MAX_SH_THREADS 256 -#define R6XX_MAX_SH_STACK_ENTRIES 4096 -#define R6XX_MAX_BACKENDS 8 -#define R6XX_MAX_BACKENDS_MASK 0xff -#define R6XX_MAX_SIMDS 8 -#define R6XX_MAX_SIMDS_MASK 0xff -#define R6XX_MAX_PIPES 8 -#define R6XX_MAX_PIPES_MASK 0xff - -/* PTE flags */ -#define PTE_VALID (1 << 0) -#define PTE_SYSTEM (1 << 1) -#define PTE_SNOOPED (1 << 2) -#define PTE_READABLE (1 << 5) -#define PTE_WRITEABLE (1 << 6) - -/* tiling bits */ -#define ARRAY_LINEAR_GENERAL 0x00000000 -#define ARRAY_LINEAR_ALIGNED 0x00000001 -#define ARRAY_1D_TILED_THIN1 0x00000002 -#define ARRAY_2D_TILED_THIN1 0x00000004 - -/* Registers */ -#define ARB_POP 0x2418 -#define ENABLE_TC128 (1 << 30) -#define ARB_GDEC_RD_CNTL 0x246C - -#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -#define CC_RB_BACKEND_DISABLE 0x98F4 -#define BACKEND_DISABLE(x) ((x) << 16) - -#define CB_COLOR0_BASE 0x28040 -#define CB_COLOR1_BASE 0x28044 -#define CB_COLOR2_BASE 0x28048 -#define CB_COLOR3_BASE 0x2804C -#define CB_COLOR4_BASE 0x28050 -#define CB_COLOR5_BASE 0x28054 -#define CB_COLOR6_BASE 0x28058 -#define CB_COLOR7_BASE 0x2805C -#define CB_COLOR7_FRAG 0x280FC - -#define CB_COLOR0_SIZE 0x28060 -#define CB_COLOR0_VIEW 0x28080 -#define R_028080_CB_COLOR0_VIEW 0x028080 -#define S_028080_SLICE_START(x) (((x) & 0x7FF) << 0) -#define G_028080_SLICE_START(x) (((x) >> 0) & 0x7FF) -#define C_028080_SLICE_START 0xFFFFF800 -#define S_028080_SLICE_MAX(x) (((x) & 0x7FF) << 13) -#define G_028080_SLICE_MAX(x) (((x) >> 13) & 0x7FF) -#define C_028080_SLICE_MAX 0xFF001FFF -#define R_028084_CB_COLOR1_VIEW 0x028084 -#define R_028088_CB_COLOR2_VIEW 0x028088 -#define R_02808C_CB_COLOR3_VIEW 0x02808C -#define R_028090_CB_COLOR4_VIEW 0x028090 -#define R_028094_CB_COLOR5_VIEW 0x028094 -#define R_028098_CB_COLOR6_VIEW 0x028098 -#define R_02809C_CB_COLOR7_VIEW 0x02809C -#define CB_COLOR0_INFO 0x280a0 -# define CB_FORMAT(x) ((x) << 2) -# define CB_ARRAY_MODE(x) ((x) << 8) -# define CB_SOURCE_FORMAT(x) ((x) << 27) -# define CB_SF_EXPORT_FULL 0 -# define CB_SF_EXPORT_NORM 1 -#define CB_COLOR0_TILE 0x280c0 -#define CB_COLOR0_FRAG 0x280e0 -#define CB_COLOR0_MASK 0x28100 - -#define SQ_ALU_CONST_CACHE_PS_0 0x28940 -#define SQ_ALU_CONST_CACHE_PS_1 0x28944 -#define SQ_ALU_CONST_CACHE_PS_2 0x28948 -#define SQ_ALU_CONST_CACHE_PS_3 0x2894c -#define SQ_ALU_CONST_CACHE_PS_4 0x28950 -#define SQ_ALU_CONST_CACHE_PS_5 0x28954 -#define SQ_ALU_CONST_CACHE_PS_6 0x28958 -#define SQ_ALU_CONST_CACHE_PS_7 0x2895c -#define SQ_ALU_CONST_CACHE_PS_8 0x28960 -#define SQ_ALU_CONST_CACHE_PS_9 0x28964 -#define SQ_ALU_CONST_CACHE_PS_10 0x28968 -#define SQ_ALU_CONST_CACHE_PS_11 0x2896c -#define SQ_ALU_CONST_CACHE_PS_12 0x28970 -#define SQ_ALU_CONST_CACHE_PS_13 0x28974 -#define SQ_ALU_CONST_CACHE_PS_14 0x28978 -#define SQ_ALU_CONST_CACHE_PS_15 0x2897c -#define SQ_ALU_CONST_CACHE_VS_0 0x28980 -#define SQ_ALU_CONST_CACHE_VS_1 0x28984 -#define SQ_ALU_CONST_CACHE_VS_2 0x28988 -#define SQ_ALU_CONST_CACHE_VS_3 0x2898c -#define SQ_ALU_CONST_CACHE_VS_4 0x28990 -#define SQ_ALU_CONST_CACHE_VS_5 0x28994 -#define SQ_ALU_CONST_CACHE_VS_6 0x28998 -#define SQ_ALU_CONST_CACHE_VS_7 0x2899c -#define SQ_ALU_CONST_CACHE_VS_8 0x289a0 -#define SQ_ALU_CONST_CACHE_VS_9 0x289a4 -#define SQ_ALU_CONST_CACHE_VS_10 0x289a8 -#define SQ_ALU_CONST_CACHE_VS_11 0x289ac -#define SQ_ALU_CONST_CACHE_VS_12 0x289b0 -#define SQ_ALU_CONST_CACHE_VS_13 0x289b4 -#define SQ_ALU_CONST_CACHE_VS_14 0x289b8 -#define SQ_ALU_CONST_CACHE_VS_15 0x289bc -#define SQ_ALU_CONST_CACHE_GS_0 0x289c0 -#define SQ_ALU_CONST_CACHE_GS_1 0x289c4 -#define SQ_ALU_CONST_CACHE_GS_2 0x289c8 -#define SQ_ALU_CONST_CACHE_GS_3 0x289cc -#define SQ_ALU_CONST_CACHE_GS_4 0x289d0 -#define SQ_ALU_CONST_CACHE_GS_5 0x289d4 -#define SQ_ALU_CONST_CACHE_GS_6 0x289d8 -#define SQ_ALU_CONST_CACHE_GS_7 0x289dc -#define SQ_ALU_CONST_CACHE_GS_8 0x289e0 -#define SQ_ALU_CONST_CACHE_GS_9 0x289e4 -#define SQ_ALU_CONST_CACHE_GS_10 0x289e8 -#define SQ_ALU_CONST_CACHE_GS_11 0x289ec -#define SQ_ALU_CONST_CACHE_GS_12 0x289f0 -#define SQ_ALU_CONST_CACHE_GS_13 0x289f4 -#define SQ_ALU_CONST_CACHE_GS_14 0x289f8 -#define SQ_ALU_CONST_CACHE_GS_15 0x289fc - -#define CONFIG_MEMSIZE 0x5428 -#define CONFIG_CNTL 0x5424 -#define CP_STAT 0x8680 -#define CP_COHER_BASE 0x85F8 -#define CP_DEBUG 0xC1FC -#define R_0086D8_CP_ME_CNTL 0x86D8 -#define S_0086D8_CP_ME_HALT(x) (((x) & 1)<<28) -#define C_0086D8_CP_ME_HALT(x) ((x) & 0xEFFFFFFF) -#define CP_ME_RAM_DATA 0xC160 -#define CP_ME_RAM_RADDR 0xC158 -#define CP_ME_RAM_WADDR 0xC15C -#define CP_MEQ_THRESHOLDS 0x8764 -#define MEQ_END(x) ((x) << 16) -#define ROQ_END(x) ((x) << 24) -#define CP_PERFMON_CNTL 0x87FC -#define CP_PFP_UCODE_ADDR 0xC150 -#define CP_PFP_UCODE_DATA 0xC154 -#define CP_QUEUE_THRESHOLDS 0x8760 -#define ROQ_IB1_START(x) ((x) << 0) -#define ROQ_IB2_START(x) ((x) << 8) -#define CP_RB_BASE 0xC100 -#define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) -#define BUF_SWAP_32BIT (2 << 16) -#define CP_RB_RPTR 0x8700 -#define CP_RB_RPTR_ADDR 0xC10C -#define RB_RPTR_SWAP(x) ((x) << 0) -#define CP_RB_RPTR_ADDR_HI 0xC110 -#define CP_RB_RPTR_WR 0xC108 -#define CP_RB_WPTR 0xC114 -#define CP_RB_WPTR_ADDR 0xC118 -#define CP_RB_WPTR_ADDR_HI 0xC11C -#define CP_RB_WPTR_DELAY 0x8704 -#define CP_ROQ_IB1_STAT 0x8784 -#define CP_ROQ_IB2_STAT 0x8788 -#define CP_SEM_WAIT_TIMER 0x85BC - -#define DB_DEBUG 0x9830 -#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) -#define DB_DEPTH_BASE 0x2800C -#define DB_HTILE_DATA_BASE 0x28014 -#define DB_HTILE_SURFACE 0x28D24 -#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0) -#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1) -#define C_028D24_HTILE_WIDTH 0xFFFFFFFE -#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1) -#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1) -#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD -#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1) -#define DB_WATERMARKS 0x9838 -#define DEPTH_FREE(x) ((x) << 0) -#define DEPTH_FLUSH(x) ((x) << 5) -#define DEPTH_PENDING_FREE(x) ((x) << 15) -#define DEPTH_CACHELINE_FREE(x) ((x) << 20) - -#define DCP_TILING_CONFIG 0x6CA0 -#define PIPE_TILING(x) ((x) << 1) -#define BANK_TILING(x) ((x) << 4) -#define GROUP_SIZE(x) ((x) << 6) -#define ROW_TILING(x) ((x) << 8) -#define BANK_SWAPS(x) ((x) << 11) -#define SAMPLE_SPLIT(x) ((x) << 14) -#define BACKEND_MAP(x) ((x) << 16) - -#define GB_TILING_CONFIG 0x98F0 - -#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -#define INACTIVE_QD_PIPES(x) ((x) << 8) -#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -#define INACTIVE_SIMDS(x) ((x) << 16) -#define INACTIVE_SIMDS_MASK 0x00FF0000 - -#define SQ_CONFIG 0x8c00 -# define VC_ENABLE (1 << 0) -# define EXPORT_SRC_C (1 << 1) -# define DX9_CONSTS (1 << 2) -# define ALU_INST_PREFER_VECTOR (1 << 3) -# define DX10_CLAMP (1 << 4) -# define CLAUSE_SEQ_PRIO(x) ((x) << 8) -# define PS_PRIO(x) ((x) << 24) -# define VS_PRIO(x) ((x) << 26) -# define GS_PRIO(x) ((x) << 28) -# define ES_PRIO(x) ((x) << 30) -#define SQ_GPR_RESOURCE_MGMT_1 0x8c04 -# define NUM_PS_GPRS(x) ((x) << 0) -# define NUM_VS_GPRS(x) ((x) << 16) -# define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -#define SQ_GPR_RESOURCE_MGMT_2 0x8c08 -# define NUM_GS_GPRS(x) ((x) << 0) -# define NUM_ES_GPRS(x) ((x) << 16) -#define SQ_THREAD_RESOURCE_MGMT 0x8c0c -# define NUM_PS_THREADS(x) ((x) << 0) -# define NUM_VS_THREADS(x) ((x) << 8) -# define NUM_GS_THREADS(x) ((x) << 16) -# define NUM_ES_THREADS(x) ((x) << 24) -#define SQ_STACK_RESOURCE_MGMT_1 0x8c10 -# define NUM_PS_STACK_ENTRIES(x) ((x) << 0) -# define NUM_VS_STACK_ENTRIES(x) ((x) << 16) -#define SQ_STACK_RESOURCE_MGMT_2 0x8c14 -# define NUM_GS_STACK_ENTRIES(x) ((x) << 0) -# define NUM_ES_STACK_ENTRIES(x) ((x) << 16) -#define SQ_ESGS_RING_BASE 0x8c40 -#define SQ_GSVS_RING_BASE 0x8c48 -#define SQ_ESTMP_RING_BASE 0x8c50 -#define SQ_GSTMP_RING_BASE 0x8c58 -#define SQ_VSTMP_RING_BASE 0x8c60 -#define SQ_PSTMP_RING_BASE 0x8c68 -#define SQ_FBUF_RING_BASE 0x8c70 -#define SQ_REDUC_RING_BASE 0x8c78 - -#define GRBM_CNTL 0x8000 -# define GRBM_READ_TIMEOUT(x) ((x) << 0) -#define GRBM_STATUS 0x8010 -#define CMDFIFO_AVAIL_MASK 0x0000001F -#define GUI_ACTIVE (1<<31) -#define GRBM_STATUS2 0x8014 -#define GRBM_SOFT_RESET 0x8020 -#define SOFT_RESET_CP (1<<0) - -#define CG_THERMAL_STATUS 0x7F4 -#define ASIC_T(x) ((x) << 0) -#define ASIC_T_MASK 0x1FF -#define ASIC_T_SHIFT 0 - -#define HDP_HOST_PATH_CNTL 0x2C00 -#define HDP_NONSURFACE_BASE 0x2C04 -#define HDP_NONSURFACE_INFO 0x2C08 -#define HDP_NONSURFACE_SIZE 0x2C0C -#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 -#define HDP_TILING_CONFIG 0x2F3C -#define HDP_DEBUG1 0x2F34 - -#define MC_VM_AGP_TOP 0x2184 -#define MC_VM_AGP_BOT 0x2188 -#define MC_VM_AGP_BASE 0x218C -#define MC_VM_FB_LOCATION 0x2180 -#define MC_VM_L1_TLB_MCD_RD_A_CNTL 0x219C -#define ENABLE_L1_TLB (1 << 0) -#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -#define ENABLE_L1_STRICT_ORDERING (1 << 2) -#define SYSTEM_ACCESS_MODE_MASK 0x000000C0 -#define SYSTEM_ACCESS_MODE_SHIFT 6 -#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) -#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) -#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) -#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) -#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) -#define SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) -#define ENABLE_SEMAPHORE_MODE (1 << 10) -#define ENABLE_WAIT_L2_QUERY (1 << 11) -#define EFFECTIVE_L1_TLB_SIZE(x) (((x) & 7) << 12) -#define EFFECTIVE_L1_TLB_SIZE_MASK 0x00007000 -#define EFFECTIVE_L1_TLB_SIZE_SHIFT 12 -#define EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 7) << 15) -#define EFFECTIVE_L1_QUEUE_SIZE_MASK 0x00038000 -#define EFFECTIVE_L1_QUEUE_SIZE_SHIFT 15 -#define MC_VM_L1_TLB_MCD_RD_B_CNTL 0x21A0 -#define MC_VM_L1_TLB_MCB_RD_GFX_CNTL 0x21FC -#define MC_VM_L1_TLB_MCB_RD_HDP_CNTL 0x2204 -#define MC_VM_L1_TLB_MCB_RD_PDMA_CNTL 0x2208 -#define MC_VM_L1_TLB_MCB_RD_SEM_CNTL 0x220C -#define MC_VM_L1_TLB_MCB_RD_SYS_CNTL 0x2200 -#define MC_VM_L1_TLB_MCD_WR_A_CNTL 0x21A4 -#define MC_VM_L1_TLB_MCD_WR_B_CNTL 0x21A8 -#define MC_VM_L1_TLB_MCB_WR_GFX_CNTL 0x2210 -#define MC_VM_L1_TLB_MCB_WR_HDP_CNTL 0x2218 -#define MC_VM_L1_TLB_MCB_WR_PDMA_CNTL 0x221C -#define MC_VM_L1_TLB_MCB_WR_SEM_CNTL 0x2220 -#define MC_VM_L1_TLB_MCB_WR_SYS_CNTL 0x2214 -#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 -#define LOGICAL_PAGE_NUMBER_MASK 0x000FFFFF -#define LOGICAL_PAGE_NUMBER_SHIFT 0 -#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 -#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 - -#define PA_CL_ENHANCE 0x8A14 -#define CLIP_VTX_REORDER_ENA (1 << 0) -#define NUM_CLIP_SEQ(x) ((x) << 1) -#define PA_SC_AA_CONFIG 0x28C04 -#define PA_SC_AA_SAMPLE_LOCS_2S 0x8B40 -#define PA_SC_AA_SAMPLE_LOCS_4S 0x8B44 -#define PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8B48 -#define PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8B4C -#define S0_X(x) ((x) << 0) -#define S0_Y(x) ((x) << 4) -#define S1_X(x) ((x) << 8) -#define S1_Y(x) ((x) << 12) -#define S2_X(x) ((x) << 16) -#define S2_Y(x) ((x) << 20) -#define S3_X(x) ((x) << 24) -#define S3_Y(x) ((x) << 28) -#define S4_X(x) ((x) << 0) -#define S4_Y(x) ((x) << 4) -#define S5_X(x) ((x) << 8) -#define S5_Y(x) ((x) << 12) -#define S6_X(x) ((x) << 16) -#define S6_Y(x) ((x) << 20) -#define S7_X(x) ((x) << 24) -#define S7_Y(x) ((x) << 28) -#define PA_SC_CLIPRECT_RULE 0x2820c -#define PA_SC_ENHANCE 0x8BF0 -#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -#define FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) -#define PA_SC_LINE_STIPPLE 0x28A0C -#define PA_SC_LINE_STIPPLE_STATE 0x8B10 -#define PA_SC_MODE_CNTL 0x28A4C -#define PA_SC_MULTI_CHIP_CNTL 0x8B20 - -#define PA_SC_SCREEN_SCISSOR_TL 0x28030 -#define PA_SC_GENERIC_SCISSOR_TL 0x28240 -#define PA_SC_WINDOW_SCISSOR_TL 0x28204 - -#define PCIE_PORT_INDEX 0x0038 -#define PCIE_PORT_DATA 0x003C - -#define CHMAP 0x2004 -#define NOOFCHAN_SHIFT 12 -#define NOOFCHAN_MASK 0x00003000 - -#define RAMCFG 0x2408 -#define NOOFBANK_SHIFT 0 -#define NOOFBANK_MASK 0x00000001 -#define NOOFRANK_SHIFT 1 -#define NOOFRANK_MASK 0x00000002 -#define NOOFROWS_SHIFT 2 -#define NOOFROWS_MASK 0x0000001C -#define NOOFCOLS_SHIFT 5 -#define NOOFCOLS_MASK 0x00000060 -#define CHANSIZE_SHIFT 7 -#define CHANSIZE_MASK 0x00000080 -#define BURSTLENGTH_SHIFT 8 -#define BURSTLENGTH_MASK 0x00000100 -#define CHANSIZE_OVERRIDE (1 << 10) - -#define SCRATCH_REG0 0x8500 -#define SCRATCH_REG1 0x8504 -#define SCRATCH_REG2 0x8508 -#define SCRATCH_REG3 0x850C -#define SCRATCH_REG4 0x8510 -#define SCRATCH_REG5 0x8514 -#define SCRATCH_REG6 0x8518 -#define SCRATCH_REG7 0x851C -#define SCRATCH_UMSK 0x8540 -#define SCRATCH_ADDR 0x8544 - -#define SPI_CONFIG_CNTL 0x9100 -#define GPR_WRITE_PRIORITY(x) ((x) << 0) -#define DISABLE_INTERP_1 (1 << 5) -#define SPI_CONFIG_CNTL_1 0x913C -#define VTX_DONE_DELAY(x) ((x) << 0) -#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -#define SPI_INPUT_Z 0x286D8 -#define SPI_PS_IN_CONTROL_0 0x286CC -#define NUM_INTERP(x) ((x)<<0) -#define POSITION_ENA (1<<8) -#define POSITION_CENTROID (1<<9) -#define POSITION_ADDR(x) ((x)<<10) -#define PARAM_GEN(x) ((x)<<15) -#define PARAM_GEN_ADDR(x) ((x)<<19) -#define BARYC_SAMPLE_CNTL(x) ((x)<<26) -#define PERSP_GRADIENT_ENA (1<<28) -#define LINEAR_GRADIENT_ENA (1<<29) -#define POSITION_SAMPLE (1<<30) -#define BARYC_AT_SAMPLE_ENA (1<<31) -#define SPI_PS_IN_CONTROL_1 0x286D0 -#define GEN_INDEX_PIX (1<<0) -#define GEN_INDEX_PIX_ADDR(x) ((x)<<1) -#define FRONT_FACE_ENA (1<<8) -#define FRONT_FACE_CHAN(x) ((x)<<9) -#define FRONT_FACE_ALL_BITS (1<<11) -#define FRONT_FACE_ADDR(x) ((x)<<12) -#define FOG_ADDR(x) ((x)<<17) -#define FIXED_PT_POSITION_ENA (1<<24) -#define FIXED_PT_POSITION_ADDR(x) ((x)<<25) - -#define SQ_MS_FIFO_SIZES 0x8CF0 -#define CACHE_FIFO_SIZE(x) ((x) << 0) -#define FETCH_FIFO_HIWATER(x) ((x) << 8) -#define DONE_FIFO_HIWATER(x) ((x) << 16) -#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -#define SQ_PGM_START_ES 0x28880 -#define SQ_PGM_START_FS 0x28894 -#define SQ_PGM_START_GS 0x2886C -#define SQ_PGM_START_PS 0x28840 -#define SQ_PGM_RESOURCES_PS 0x28850 -#define SQ_PGM_EXPORTS_PS 0x28854 -#define SQ_PGM_CF_OFFSET_PS 0x288cc -#define SQ_PGM_START_VS 0x28858 -#define SQ_PGM_RESOURCES_VS 0x28868 -#define SQ_PGM_CF_OFFSET_VS 0x288d0 - -#define SQ_VTX_CONSTANT_WORD0_0 0x30000 -#define SQ_VTX_CONSTANT_WORD1_0 0x30004 -#define SQ_VTX_CONSTANT_WORD2_0 0x30008 -# define SQ_VTXC_BASE_ADDR_HI(x) ((x) << 0) -# define SQ_VTXC_STRIDE(x) ((x) << 8) -# define SQ_VTXC_ENDIAN_SWAP(x) ((x) << 30) -# define SQ_ENDIAN_NONE 0 -# define SQ_ENDIAN_8IN16 1 -# define SQ_ENDIAN_8IN32 2 -#define SQ_VTX_CONSTANT_WORD3_0 0x3000c -#define SQ_VTX_CONSTANT_WORD6_0 0x38018 -#define S__SQ_VTX_CONSTANT_TYPE(x) (((x) & 3) << 30) -#define G__SQ_VTX_CONSTANT_TYPE(x) (((x) >> 30) & 3) -#define SQ_TEX_VTX_INVALID_TEXTURE 0x0 -#define SQ_TEX_VTX_INVALID_BUFFER 0x1 -#define SQ_TEX_VTX_VALID_TEXTURE 0x2 -#define SQ_TEX_VTX_VALID_BUFFER 0x3 - - -#define SX_MISC 0x28350 -#define SX_MEMORY_EXPORT_BASE 0x9010 -#define SX_DEBUG_1 0x9054 -#define SMX_EVENT_RELEASE (1 << 0) -#define ENABLE_NEW_SMX_ADDRESS (1 << 16) - -#define TA_CNTL_AUX 0x9508 -#define DISABLE_CUBE_WRAP (1 << 0) -#define DISABLE_CUBE_ANISO (1 << 1) -#define SYNC_GRADIENT (1 << 24) -#define SYNC_WALKER (1 << 25) -#define SYNC_ALIGNER (1 << 26) -#define BILINEAR_PRECISION_6_BIT (0 << 31) -#define BILINEAR_PRECISION_8_BIT (1 << 31) - -#define TC_CNTL 0x9608 -#define TC_L2_SIZE(x) ((x)<<5) -#define L2_DISABLE_LATE_HIT (1<<9) - -#define VC_ENHANCE 0x9714 - -#define VGT_CACHE_INVALIDATION 0x88C4 -#define CACHE_INVALIDATION(x) ((x)<<0) -#define VC_ONLY 0 -#define TC_ONLY 1 -#define VC_AND_TC 2 -#define VGT_DMA_BASE 0x287E8 -#define VGT_DMA_BASE_HI 0x287E4 -#define VGT_ES_PER_GS 0x88CC -#define VGT_GS_PER_ES 0x88C8 -#define VGT_GS_PER_VS 0x88E8 -#define VGT_GS_VERTEX_REUSE 0x88D4 -#define VGT_PRIMITIVE_TYPE 0x8958 -#define VGT_NUM_INSTANCES 0x8974 -#define VGT_OUT_DEALLOC_CNTL 0x28C5C -#define DEALLOC_DIST_MASK 0x0000007F -#define VGT_STRMOUT_BASE_OFFSET_0 0x28B10 -#define VGT_STRMOUT_BASE_OFFSET_1 0x28B14 -#define VGT_STRMOUT_BASE_OFFSET_2 0x28B18 -#define VGT_STRMOUT_BASE_OFFSET_3 0x28B1c -#define VGT_STRMOUT_BASE_OFFSET_HI_0 0x28B44 -#define VGT_STRMOUT_BASE_OFFSET_HI_1 0x28B48 -#define VGT_STRMOUT_BASE_OFFSET_HI_2 0x28B4c -#define VGT_STRMOUT_BASE_OFFSET_HI_3 0x28B50 -#define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8 -#define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8 -#define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8 -#define VGT_STRMOUT_BUFFER_BASE_3 0x28B08 -#define VGT_STRMOUT_BUFFER_OFFSET_0 0x28ADC -#define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC -#define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC -#define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C -#define VGT_STRMOUT_BUFFER_SIZE_0 0x28AD0 -#define VGT_STRMOUT_BUFFER_SIZE_1 0x28AE0 -#define VGT_STRMOUT_BUFFER_SIZE_2 0x28AF0 -#define VGT_STRMOUT_BUFFER_SIZE_3 0x28B00 - -#define VGT_STRMOUT_EN 0x28AB0 -#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 -#define VTX_REUSE_DEPTH_MASK 0x000000FF -#define VGT_EVENT_INITIATOR 0x28a90 -# define CACHE_FLUSH_AND_INV_EVENT_TS (0x14 << 0) -# define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) - -#define VM_CONTEXT0_CNTL 0x1410 -#define ENABLE_CONTEXT (1 << 0) -#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -#define VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 -#define VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14B0 -#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 -#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 -#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15B4 -#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1554 -#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -#define REQUEST_TYPE(x) (((x) & 0xf) << 0) -#define RESPONSE_TYPE_MASK 0x000000F0 -#define RESPONSE_TYPE_SHIFT 4 -#define VM_L2_CNTL 0x1400 -#define ENABLE_L2_CACHE (1 << 0) -#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 13) -#define VM_L2_CNTL2 0x1404 -#define INVALIDATE_ALL_L1_TLBS (1 << 0) -#define INVALIDATE_L2_CACHE (1 << 1) -#define VM_L2_CNTL3 0x1408 -#define BANK_SELECT_0(x) (((x) & 0x1f) << 0) -#define BANK_SELECT_1(x) (((x) & 0x1f) << 5) -#define L2_CACHE_UPDATE_MODE(x) (((x) & 3) << 10) -#define VM_L2_STATUS 0x140C -#define L2_BUSY (1 << 0) - -#define WAIT_UNTIL 0x8040 -#define WAIT_2D_IDLE_bit (1 << 14) -#define WAIT_3D_IDLE_bit (1 << 15) -#define WAIT_2D_IDLECLEAN_bit (1 << 16) -#define WAIT_3D_IDLECLEAN_bit (1 << 17) - -#define IH_RB_CNTL 0x3e00 -# define IH_RB_ENABLE (1 << 0) -# define IH_IB_SIZE(x) ((x) << 1) /* log2 */ -# define IH_RB_FULL_DRAIN_ENABLE (1 << 6) -# define IH_WPTR_WRITEBACK_ENABLE (1 << 8) -# define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */ -# define IH_WPTR_OVERFLOW_ENABLE (1 << 16) -# define IH_WPTR_OVERFLOW_CLEAR (1 << 31) -#define IH_RB_BASE 0x3e04 -#define IH_RB_RPTR 0x3e08 -#define IH_RB_WPTR 0x3e0c -# define RB_OVERFLOW (1 << 0) -# define WPTR_OFFSET_MASK 0x3fffc -#define IH_RB_WPTR_ADDR_HI 0x3e10 -#define IH_RB_WPTR_ADDR_LO 0x3e14 -#define IH_CNTL 0x3e18 -# define ENABLE_INTR (1 << 0) -# define IH_MC_SWAP(x) ((x) << 1) -# define IH_MC_SWAP_NONE 0 -# define IH_MC_SWAP_16BIT 1 -# define IH_MC_SWAP_32BIT 2 -# define IH_MC_SWAP_64BIT 3 -# define RPTR_REARM (1 << 4) -# define MC_WRREQ_CREDIT(x) ((x) << 15) -# define MC_WR_CLEAN_CNT(x) ((x) << 20) - -#define RLC_CNTL 0x3f00 -# define RLC_ENABLE (1 << 0) -#define RLC_HB_BASE 0x3f10 -#define RLC_HB_CNTL 0x3f0c -#define RLC_HB_RPTR 0x3f20 -#define RLC_HB_WPTR 0x3f1c -#define RLC_HB_WPTR_LSB_ADDR 0x3f14 -#define RLC_HB_WPTR_MSB_ADDR 0x3f18 -#define RLC_MC_CNTL 0x3f44 -#define RLC_UCODE_CNTL 0x3f48 -#define RLC_UCODE_ADDR 0x3f2c -#define RLC_UCODE_DATA 0x3f30 - -/* new for TN */ -#define TN_RLC_SAVE_AND_RESTORE_BASE 0x3f10 -#define TN_RLC_CLEAR_STATE_RESTORE_BASE 0x3f20 - -#define SRBM_SOFT_RESET 0xe60 -# define SOFT_RESET_RLC (1 << 13) - -#define CP_INT_CNTL 0xc124 -# define CNTX_BUSY_INT_ENABLE (1 << 19) -# define CNTX_EMPTY_INT_ENABLE (1 << 20) -# define SCRATCH_INT_ENABLE (1 << 25) -# define TIME_STAMP_INT_ENABLE (1 << 26) -# define IB2_INT_ENABLE (1 << 29) -# define IB1_INT_ENABLE (1 << 30) -# define RB_INT_ENABLE (1 << 31) -#define CP_INT_STATUS 0xc128 -# define SCRATCH_INT_STAT (1 << 25) -# define TIME_STAMP_INT_STAT (1 << 26) -# define IB2_INT_STAT (1 << 29) -# define IB1_INT_STAT (1 << 30) -# define RB_INT_STAT (1 << 31) - -#define GRBM_INT_CNTL 0x8060 -# define RDERR_INT_ENABLE (1 << 0) -# define WAIT_COUNT_TIMEOUT_INT_ENABLE (1 << 1) -# define GUI_IDLE_INT_ENABLE (1 << 19) - -#define INTERRUPT_CNTL 0x5468 -# define IH_DUMMY_RD_OVERRIDE (1 << 0) -# define IH_DUMMY_RD_EN (1 << 1) -# define IH_REQ_NONSNOOP_EN (1 << 3) -# define GEN_IH_INT_EN (1 << 8) -#define INTERRUPT_CNTL2 0x546c - -#define D1MODE_VBLANK_STATUS 0x6534 -#define D2MODE_VBLANK_STATUS 0x6d34 -# define DxMODE_VBLANK_OCCURRED (1 << 0) -# define DxMODE_VBLANK_ACK (1 << 4) -# define DxMODE_VBLANK_STAT (1 << 12) -# define DxMODE_VBLANK_INTERRUPT (1 << 16) -# define DxMODE_VBLANK_INTERRUPT_TYPE (1 << 17) -#define D1MODE_VLINE_STATUS 0x653c -#define D2MODE_VLINE_STATUS 0x6d3c -# define DxMODE_VLINE_OCCURRED (1 << 0) -# define DxMODE_VLINE_ACK (1 << 4) -# define DxMODE_VLINE_STAT (1 << 12) -# define DxMODE_VLINE_INTERRUPT (1 << 16) -# define DxMODE_VLINE_INTERRUPT_TYPE (1 << 17) -#define DxMODE_INT_MASK 0x6540 -# define D1MODE_VBLANK_INT_MASK (1 << 0) -# define D1MODE_VLINE_INT_MASK (1 << 4) -# define D2MODE_VBLANK_INT_MASK (1 << 8) -# define D2MODE_VLINE_INT_MASK (1 << 12) -#define DCE3_DISP_INTERRUPT_STATUS 0x7ddc -# define DC_HPD1_INTERRUPT (1 << 18) -# define DC_HPD2_INTERRUPT (1 << 19) -#define DISP_INTERRUPT_STATUS 0x7edc -# define LB_D1_VLINE_INTERRUPT (1 << 2) -# define LB_D2_VLINE_INTERRUPT (1 << 3) -# define LB_D1_VBLANK_INTERRUPT (1 << 4) -# define LB_D2_VBLANK_INTERRUPT (1 << 5) -# define DACA_AUTODETECT_INTERRUPT (1 << 16) -# define DACB_AUTODETECT_INTERRUPT (1 << 17) -# define DC_HOT_PLUG_DETECT1_INTERRUPT (1 << 18) -# define DC_HOT_PLUG_DETECT2_INTERRUPT (1 << 19) -# define DC_I2C_SW_DONE_INTERRUPT (1 << 20) -# define DC_I2C_HW_DONE_INTERRUPT (1 << 21) -#define DISP_INTERRUPT_STATUS_CONTINUE 0x7ee8 -#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE 0x7de8 -# define DC_HPD4_INTERRUPT (1 << 14) -# define DC_HPD4_RX_INTERRUPT (1 << 15) -# define DC_HPD3_INTERRUPT (1 << 28) -# define DC_HPD1_RX_INTERRUPT (1 << 29) -# define DC_HPD2_RX_INTERRUPT (1 << 30) -#define DCE3_DISP_INTERRUPT_STATUS_CONTINUE2 0x7dec -# define DC_HPD3_RX_INTERRUPT (1 << 0) -# define DIGA_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 1) -# define DIGA_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 2) -# define DIGB_DP_VID_STREAM_DISABLE_INTERRUPT (1 << 3) -# define DIGB_DP_STEER_FIFO_OVERFLOW_INTERRUPT (1 << 4) -# define AUX1_SW_DONE_INTERRUPT (1 << 5) -# define AUX1_LS_DONE_INTERRUPT (1 << 6) -# define AUX2_SW_DONE_INTERRUPT (1 << 7) -# define AUX2_LS_DONE_INTERRUPT (1 << 8) -# define AUX3_SW_DONE_INTERRUPT (1 << 9) -# define AUX3_LS_DONE_INTERRUPT (1 << 10) -# define AUX4_SW_DONE_INTERRUPT (1 << 11) -# define AUX4_LS_DONE_INTERRUPT (1 << 12) -# define DIGA_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 13) -# define DIGB_DP_FAST_TRAINING_COMPLETE_INTERRUPT (1 << 14) -/* DCE 3.2 */ -# define AUX5_SW_DONE_INTERRUPT (1 << 15) -# define AUX5_LS_DONE_INTERRUPT (1 << 16) -# define AUX6_SW_DONE_INTERRUPT (1 << 17) -# define AUX6_LS_DONE_INTERRUPT (1 << 18) -# define DC_HPD5_INTERRUPT (1 << 19) -# define DC_HPD5_RX_INTERRUPT (1 << 20) -# define DC_HPD6_INTERRUPT (1 << 21) -# define DC_HPD6_RX_INTERRUPT (1 << 22) - -#define DACA_AUTO_DETECT_CONTROL 0x7828 -#define DACB_AUTO_DETECT_CONTROL 0x7a28 -#define DCE3_DACA_AUTO_DETECT_CONTROL 0x7028 -#define DCE3_DACB_AUTO_DETECT_CONTROL 0x7128 -# define DACx_AUTODETECT_MODE(x) ((x) << 0) -# define DACx_AUTODETECT_MODE_NONE 0 -# define DACx_AUTODETECT_MODE_CONNECT 1 -# define DACx_AUTODETECT_MODE_DISCONNECT 2 -# define DACx_AUTODETECT_FRAME_TIME_COUNTER(x) ((x) << 8) -/* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */ -# define DACx_AUTODETECT_CHECK_MASK(x) ((x) << 16) - -#define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 -#define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 -#define DACA_AUTODETECT_INT_CONTROL 0x7838 -#define DACB_AUTODETECT_INT_CONTROL 0x7a38 -# define DACx_AUTODETECT_ACK (1 << 0) -# define DACx_AUTODETECT_INT_ENABLE (1 << 16) - -#define DC_HOT_PLUG_DETECT1_CONTROL 0x7d00 -#define DC_HOT_PLUG_DETECT2_CONTROL 0x7d10 -#define DC_HOT_PLUG_DETECT3_CONTROL 0x7d24 -# define DC_HOT_PLUG_DETECTx_EN (1 << 0) - -#define DC_HOT_PLUG_DETECT1_INT_STATUS 0x7d04 -#define DC_HOT_PLUG_DETECT2_INT_STATUS 0x7d14 -#define DC_HOT_PLUG_DETECT3_INT_STATUS 0x7d28 -# define DC_HOT_PLUG_DETECTx_INT_STATUS (1 << 0) -# define DC_HOT_PLUG_DETECTx_SENSE (1 << 1) - -/* DCE 3.0 */ -#define DC_HPD1_INT_STATUS 0x7d00 -#define DC_HPD2_INT_STATUS 0x7d0c -#define DC_HPD3_INT_STATUS 0x7d18 -#define DC_HPD4_INT_STATUS 0x7d24 -/* DCE 3.2 */ -#define DC_HPD5_INT_STATUS 0x7dc0 -#define DC_HPD6_INT_STATUS 0x7df4 -# define DC_HPDx_INT_STATUS (1 << 0) -# define DC_HPDx_SENSE (1 << 1) -# define DC_HPDx_RX_INT_STATUS (1 << 8) - -#define DC_HOT_PLUG_DETECT1_INT_CONTROL 0x7d08 -#define DC_HOT_PLUG_DETECT2_INT_CONTROL 0x7d18 -#define DC_HOT_PLUG_DETECT3_INT_CONTROL 0x7d2c -# define DC_HOT_PLUG_DETECTx_INT_ACK (1 << 0) -# define DC_HOT_PLUG_DETECTx_INT_POLARITY (1 << 8) -# define DC_HOT_PLUG_DETECTx_INT_EN (1 << 16) -/* DCE 3.0 */ -#define DC_HPD1_INT_CONTROL 0x7d04 -#define DC_HPD2_INT_CONTROL 0x7d10 -#define DC_HPD3_INT_CONTROL 0x7d1c -#define DC_HPD4_INT_CONTROL 0x7d28 -/* DCE 3.2 */ -#define DC_HPD5_INT_CONTROL 0x7dc4 -#define DC_HPD6_INT_CONTROL 0x7df8 -# define DC_HPDx_INT_ACK (1 << 0) -# define DC_HPDx_INT_POLARITY (1 << 8) -# define DC_HPDx_INT_EN (1 << 16) -# define DC_HPDx_RX_INT_ACK (1 << 20) -# define DC_HPDx_RX_INT_EN (1 << 24) - -/* DCE 3.0 */ -#define DC_HPD1_CONTROL 0x7d08 -#define DC_HPD2_CONTROL 0x7d14 -#define DC_HPD3_CONTROL 0x7d20 -#define DC_HPD4_CONTROL 0x7d2c -/* DCE 3.2 */ -#define DC_HPD5_CONTROL 0x7dc8 -#define DC_HPD6_CONTROL 0x7dfc -# define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) -# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) -/* DCE 3.2 */ -# define DC_HPDx_EN (1 << 28) - -#define D1GRPH_INTERRUPT_STATUS 0x6158 -#define D2GRPH_INTERRUPT_STATUS 0x6958 -# define DxGRPH_PFLIP_INT_OCCURRED (1 << 0) -# define DxGRPH_PFLIP_INT_CLEAR (1 << 8) -#define D1GRPH_INTERRUPT_CONTROL 0x615c -#define D2GRPH_INTERRUPT_CONTROL 0x695c -# define DxGRPH_PFLIP_INT_MASK (1 << 0) -# define DxGRPH_PFLIP_INT_TYPE (1 << 8) - -/* PCIE link stuff */ -#define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ -# define LC_POINT_7_PLUS_EN (1 << 6) -#define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ -# define LC_LINK_WIDTH_SHIFT 0 -# define LC_LINK_WIDTH_MASK 0x7 -# define LC_LINK_WIDTH_X0 0 -# define LC_LINK_WIDTH_X1 1 -# define LC_LINK_WIDTH_X2 2 -# define LC_LINK_WIDTH_X4 3 -# define LC_LINK_WIDTH_X8 4 -# define LC_LINK_WIDTH_X16 6 -# define LC_LINK_WIDTH_RD_SHIFT 4 -# define LC_LINK_WIDTH_RD_MASK 0x70 -# define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) -# define LC_RECONFIG_NOW (1 << 8) -# define LC_RENEGOTIATION_SUPPORT (1 << 9) -# define LC_RENEGOTIATE_EN (1 << 10) -# define LC_SHORT_RECONFIG_EN (1 << 11) -# define LC_UPCONFIGURE_SUPPORT (1 << 12) -# define LC_UPCONFIGURE_DIS (1 << 13) -#define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ -# define LC_GEN2_EN_STRAP (1 << 0) -# define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) -# define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) -# define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) -# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) -# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 -# define LC_CURRENT_DATA_RATE (1 << 11) -# define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) -# define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) -# define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) -# define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) -#define MM_CFGREGS_CNTL 0x544c -# define MM_WR_TO_CFG_EN (1 << 3) -#define LINK_CNTL2 0x88 /* F0 */ -# define TARGET_LINK_SPEED_MASK (0xf << 0) -# define SELECTABLE_DEEMPHASIS (1 << 6) - -/* - * PM4 - */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ - (((reg) >> 2) & 0xFFFF) | \ - ((n) & 0x3FFF) << 16) -#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ - (((op) & 0xFF) << 8) | \ - ((n) & 0x3FFF) << 16) - -/* Packet 3 types */ -#define PACKET3_NOP 0x10 -#define PACKET3_INDIRECT_BUFFER_END 0x17 -#define PACKET3_SET_PREDICATION 0x20 -#define PACKET3_REG_RMW 0x21 -#define PACKET3_COND_EXEC 0x22 -#define PACKET3_PRED_EXEC 0x23 -#define PACKET3_START_3D_CMDBUF 0x24 -#define PACKET3_DRAW_INDEX_2 0x27 -#define PACKET3_CONTEXT_CONTROL 0x28 -#define PACKET3_DRAW_INDEX_IMMD_BE 0x29 -#define PACKET3_INDEX_TYPE 0x2A -#define PACKET3_DRAW_INDEX 0x2B -#define PACKET3_DRAW_INDEX_AUTO 0x2D -#define PACKET3_DRAW_INDEX_IMMD 0x2E -#define PACKET3_NUM_INSTANCES 0x2F -#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 -#define PACKET3_INDIRECT_BUFFER_MP 0x38 -#define PACKET3_MEM_SEMAPHORE 0x39 -# define PACKET3_SEM_WAIT_ON_SIGNAL (0x1 << 12) -# define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) -# define PACKET3_SEM_SEL_WAIT (0x7 << 29) -#define PACKET3_MPEG_INDEX 0x3A -#define PACKET3_COPY_DW 0x3B -#define PACKET3_WAIT_REG_MEM 0x3C -#define PACKET3_MEM_WRITE 0x3D -#define PACKET3_INDIRECT_BUFFER 0x32 -#define PACKET3_SURFACE_SYNC 0x43 -# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) -# define PACKET3_TC_ACTION_ENA (1 << 23) -# define PACKET3_VC_ACTION_ENA (1 << 24) -# define PACKET3_CB_ACTION_ENA (1 << 25) -# define PACKET3_DB_ACTION_ENA (1 << 26) -# define PACKET3_SH_ACTION_ENA (1 << 27) -# define PACKET3_SMX_ACTION_ENA (1 << 28) -#define PACKET3_ME_INITIALIZE 0x44 -#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -#define PACKET3_COND_WRITE 0x45 -#define PACKET3_EVENT_WRITE 0x46 -#define EVENT_TYPE(x) ((x) << 0) -#define EVENT_INDEX(x) ((x) << 8) - /* 0 - any non-TS event - * 1 - ZPASS_DONE - * 2 - SAMPLE_PIPELINESTAT - * 3 - SAMPLE_STREAMOUTSTAT* - * 4 - *S_PARTIAL_FLUSH - * 5 - TS events - */ -#define PACKET3_EVENT_WRITE_EOP 0x47 -#define DATA_SEL(x) ((x) << 29) - /* 0 - discard - * 1 - send low 32bit data - * 2 - send 64bit data - * 3 - send 64bit counter value - */ -#define INT_SEL(x) ((x) << 24) - /* 0 - none - * 1 - interrupt only (DATA_SEL = 0) - * 2 - interrupt when data write is confirmed - */ -#define PACKET3_ONE_REG_WRITE 0x57 -#define PACKET3_SET_CONFIG_REG 0x68 -#define PACKET3_SET_CONFIG_REG_OFFSET 0x00008000 -#define PACKET3_SET_CONFIG_REG_END 0x0000ac00 -#define PACKET3_SET_CONTEXT_REG 0x69 -#define PACKET3_SET_CONTEXT_REG_OFFSET 0x00028000 -#define PACKET3_SET_CONTEXT_REG_END 0x00029000 -#define PACKET3_SET_ALU_CONST 0x6A -#define PACKET3_SET_ALU_CONST_OFFSET 0x00030000 -#define PACKET3_SET_ALU_CONST_END 0x00032000 -#define PACKET3_SET_BOOL_CONST 0x6B -#define PACKET3_SET_BOOL_CONST_OFFSET 0x0003e380 -#define PACKET3_SET_BOOL_CONST_END 0x00040000 -#define PACKET3_SET_LOOP_CONST 0x6C -#define PACKET3_SET_LOOP_CONST_OFFSET 0x0003e200 -#define PACKET3_SET_LOOP_CONST_END 0x0003e380 -#define PACKET3_SET_RESOURCE 0x6D -#define PACKET3_SET_RESOURCE_OFFSET 0x00038000 -#define PACKET3_SET_RESOURCE_END 0x0003c000 -#define PACKET3_SET_SAMPLER 0x6E -#define PACKET3_SET_SAMPLER_OFFSET 0x0003c000 -#define PACKET3_SET_SAMPLER_END 0x0003cff0 -#define PACKET3_SET_CTL_CONST 0x6F -#define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 -#define PACKET3_SET_CTL_CONST_END 0x0003e200 -#define PACKET3_SURFACE_BASE_UPDATE 0x73 - - -#define R_008020_GRBM_SOFT_RESET 0x8020 -#define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0) -#define S_008020_SOFT_RESET_CB(x) (((x) & 1) << 1) -#define S_008020_SOFT_RESET_CR(x) (((x) & 1) << 2) -#define S_008020_SOFT_RESET_DB(x) (((x) & 1) << 3) -#define S_008020_SOFT_RESET_PA(x) (((x) & 1) << 5) -#define S_008020_SOFT_RESET_SC(x) (((x) & 1) << 6) -#define S_008020_SOFT_RESET_SMX(x) (((x) & 1) << 7) -#define S_008020_SOFT_RESET_SPI(x) (((x) & 1) << 8) -#define S_008020_SOFT_RESET_SH(x) (((x) & 1) << 9) -#define S_008020_SOFT_RESET_SX(x) (((x) & 1) << 10) -#define S_008020_SOFT_RESET_TC(x) (((x) & 1) << 11) -#define S_008020_SOFT_RESET_TA(x) (((x) & 1) << 12) -#define S_008020_SOFT_RESET_VC(x) (((x) & 1) << 13) -#define S_008020_SOFT_RESET_VGT(x) (((x) & 1) << 14) -#define R_008010_GRBM_STATUS 0x8010 -#define S_008010_CMDFIFO_AVAIL(x) (((x) & 0x1F) << 0) -#define S_008010_CP_RQ_PENDING(x) (((x) & 1) << 6) -#define S_008010_CF_RQ_PENDING(x) (((x) & 1) << 7) -#define S_008010_PF_RQ_PENDING(x) (((x) & 1) << 8) -#define S_008010_GRBM_EE_BUSY(x) (((x) & 1) << 10) -#define S_008010_VC_BUSY(x) (((x) & 1) << 11) -#define S_008010_DB03_CLEAN(x) (((x) & 1) << 12) -#define S_008010_CB03_CLEAN(x) (((x) & 1) << 13) -#define S_008010_VGT_BUSY_NO_DMA(x) (((x) & 1) << 16) -#define S_008010_VGT_BUSY(x) (((x) & 1) << 17) -#define S_008010_TA03_BUSY(x) (((x) & 1) << 18) -#define S_008010_TC_BUSY(x) (((x) & 1) << 19) -#define S_008010_SX_BUSY(x) (((x) & 1) << 20) -#define S_008010_SH_BUSY(x) (((x) & 1) << 21) -#define S_008010_SPI03_BUSY(x) (((x) & 1) << 22) -#define S_008010_SMX_BUSY(x) (((x) & 1) << 23) -#define S_008010_SC_BUSY(x) (((x) & 1) << 24) -#define S_008010_PA_BUSY(x) (((x) & 1) << 25) -#define S_008010_DB03_BUSY(x) (((x) & 1) << 26) -#define S_008010_CR_BUSY(x) (((x) & 1) << 27) -#define S_008010_CP_COHERENCY_BUSY(x) (((x) & 1) << 28) -#define S_008010_CP_BUSY(x) (((x) & 1) << 29) -#define S_008010_CB03_BUSY(x) (((x) & 1) << 30) -#define S_008010_GUI_ACTIVE(x) (((x) & 1) << 31) -#define G_008010_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x1F) -#define G_008010_CP_RQ_PENDING(x) (((x) >> 6) & 1) -#define G_008010_CF_RQ_PENDING(x) (((x) >> 7) & 1) -#define G_008010_PF_RQ_PENDING(x) (((x) >> 8) & 1) -#define G_008010_GRBM_EE_BUSY(x) (((x) >> 10) & 1) -#define G_008010_VC_BUSY(x) (((x) >> 11) & 1) -#define G_008010_DB03_CLEAN(x) (((x) >> 12) & 1) -#define G_008010_CB03_CLEAN(x) (((x) >> 13) & 1) -#define G_008010_VGT_BUSY_NO_DMA(x) (((x) >> 16) & 1) -#define G_008010_VGT_BUSY(x) (((x) >> 17) & 1) -#define G_008010_TA03_BUSY(x) (((x) >> 18) & 1) -#define G_008010_TC_BUSY(x) (((x) >> 19) & 1) -#define G_008010_SX_BUSY(x) (((x) >> 20) & 1) -#define G_008010_SH_BUSY(x) (((x) >> 21) & 1) -#define G_008010_SPI03_BUSY(x) (((x) >> 22) & 1) -#define G_008010_SMX_BUSY(x) (((x) >> 23) & 1) -#define G_008010_SC_BUSY(x) (((x) >> 24) & 1) -#define G_008010_PA_BUSY(x) (((x) >> 25) & 1) -#define G_008010_DB03_BUSY(x) (((x) >> 26) & 1) -#define G_008010_CR_BUSY(x) (((x) >> 27) & 1) -#define G_008010_CP_COHERENCY_BUSY(x) (((x) >> 28) & 1) -#define G_008010_CP_BUSY(x) (((x) >> 29) & 1) -#define G_008010_CB03_BUSY(x) (((x) >> 30) & 1) -#define G_008010_GUI_ACTIVE(x) (((x) >> 31) & 1) -#define R_008014_GRBM_STATUS2 0x8014 -#define S_008014_CR_CLEAN(x) (((x) & 1) << 0) -#define S_008014_SMX_CLEAN(x) (((x) & 1) << 1) -#define S_008014_SPI0_BUSY(x) (((x) & 1) << 8) -#define S_008014_SPI1_BUSY(x) (((x) & 1) << 9) -#define S_008014_SPI2_BUSY(x) (((x) & 1) << 10) -#define S_008014_SPI3_BUSY(x) (((x) & 1) << 11) -#define S_008014_TA0_BUSY(x) (((x) & 1) << 12) -#define S_008014_TA1_BUSY(x) (((x) & 1) << 13) -#define S_008014_TA2_BUSY(x) (((x) & 1) << 14) -#define S_008014_TA3_BUSY(x) (((x) & 1) << 15) -#define S_008014_DB0_BUSY(x) (((x) & 1) << 16) -#define S_008014_DB1_BUSY(x) (((x) & 1) << 17) -#define S_008014_DB2_BUSY(x) (((x) & 1) << 18) -#define S_008014_DB3_BUSY(x) (((x) & 1) << 19) -#define S_008014_CB0_BUSY(x) (((x) & 1) << 20) -#define S_008014_CB1_BUSY(x) (((x) & 1) << 21) -#define S_008014_CB2_BUSY(x) (((x) & 1) << 22) -#define S_008014_CB3_BUSY(x) (((x) & 1) << 23) -#define G_008014_CR_CLEAN(x) (((x) >> 0) & 1) -#define G_008014_SMX_CLEAN(x) (((x) >> 1) & 1) -#define G_008014_SPI0_BUSY(x) (((x) >> 8) & 1) -#define G_008014_SPI1_BUSY(x) (((x) >> 9) & 1) -#define G_008014_SPI2_BUSY(x) (((x) >> 10) & 1) -#define G_008014_SPI3_BUSY(x) (((x) >> 11) & 1) -#define G_008014_TA0_BUSY(x) (((x) >> 12) & 1) -#define G_008014_TA1_BUSY(x) (((x) >> 13) & 1) -#define G_008014_TA2_BUSY(x) (((x) >> 14) & 1) -#define G_008014_TA3_BUSY(x) (((x) >> 15) & 1) -#define G_008014_DB0_BUSY(x) (((x) >> 16) & 1) -#define G_008014_DB1_BUSY(x) (((x) >> 17) & 1) -#define G_008014_DB2_BUSY(x) (((x) >> 18) & 1) -#define G_008014_DB3_BUSY(x) (((x) >> 19) & 1) -#define G_008014_CB0_BUSY(x) (((x) >> 20) & 1) -#define G_008014_CB1_BUSY(x) (((x) >> 21) & 1) -#define G_008014_CB2_BUSY(x) (((x) >> 22) & 1) -#define G_008014_CB3_BUSY(x) (((x) >> 23) & 1) -#define R_000E50_SRBM_STATUS 0x0E50 -#define G_000E50_RLC_RQ_PENDING(x) (((x) >> 3) & 1) -#define G_000E50_RCU_RQ_PENDING(x) (((x) >> 4) & 1) -#define G_000E50_GRBM_RQ_PENDING(x) (((x) >> 5) & 1) -#define G_000E50_HI_RQ_PENDING(x) (((x) >> 6) & 1) -#define G_000E50_IO_EXTERN_SIGNAL(x) (((x) >> 7) & 1) -#define G_000E50_VMC_BUSY(x) (((x) >> 8) & 1) -#define G_000E50_MCB_BUSY(x) (((x) >> 9) & 1) -#define G_000E50_MCDZ_BUSY(x) (((x) >> 10) & 1) -#define G_000E50_MCDY_BUSY(x) (((x) >> 11) & 1) -#define G_000E50_MCDX_BUSY(x) (((x) >> 12) & 1) -#define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1) -#define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1) -#define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1) -#define G_000E50_BIF_BUSY(x) (((x) >> 29) & 1) -#define R_000E60_SRBM_SOFT_RESET 0x0E60 -#define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1) -#define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2) -#define S_000E60_SOFT_RESET_CMC(x) (((x) & 1) << 3) -#define S_000E60_SOFT_RESET_CSC(x) (((x) & 1) << 4) -#define S_000E60_SOFT_RESET_DC(x) (((x) & 1) << 5) -#define S_000E60_SOFT_RESET_GRBM(x) (((x) & 1) << 8) -#define S_000E60_SOFT_RESET_HDP(x) (((x) & 1) << 9) -#define S_000E60_SOFT_RESET_IH(x) (((x) & 1) << 10) -#define S_000E60_SOFT_RESET_MC(x) (((x) & 1) << 11) -#define S_000E60_SOFT_RESET_RLC(x) (((x) & 1) << 13) -#define S_000E60_SOFT_RESET_ROM(x) (((x) & 1) << 14) -#define S_000E60_SOFT_RESET_SEM(x) (((x) & 1) << 15) -#define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) -#define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) - -#define R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 - -#define R_028C04_PA_SC_AA_CONFIG 0x028C04 -#define S_028C04_MSAA_NUM_SAMPLES(x) (((x) & 0x3) << 0) -#define G_028C04_MSAA_NUM_SAMPLES(x) (((x) >> 0) & 0x3) -#define C_028C04_MSAA_NUM_SAMPLES 0xFFFFFFFC -#define S_028C04_AA_MASK_CENTROID_DTMN(x) (((x) & 0x1) << 4) -#define G_028C04_AA_MASK_CENTROID_DTMN(x) (((x) >> 4) & 0x1) -#define C_028C04_AA_MASK_CENTROID_DTMN 0xFFFFFFEF -#define S_028C04_MAX_SAMPLE_DIST(x) (((x) & 0xF) << 13) -#define G_028C04_MAX_SAMPLE_DIST(x) (((x) >> 13) & 0xF) -#define C_028C04_MAX_SAMPLE_DIST 0xFFFE1FFF -#define R_0280E0_CB_COLOR0_FRAG 0x0280E0 -#define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) -#define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_0280E0_BASE_256B 0x00000000 -#define R_0280E4_CB_COLOR1_FRAG 0x0280E4 -#define R_0280E8_CB_COLOR2_FRAG 0x0280E8 -#define R_0280EC_CB_COLOR3_FRAG 0x0280EC -#define R_0280F0_CB_COLOR4_FRAG 0x0280F0 -#define R_0280F4_CB_COLOR5_FRAG 0x0280F4 -#define R_0280F8_CB_COLOR6_FRAG 0x0280F8 -#define R_0280FC_CB_COLOR7_FRAG 0x0280FC -#define R_0280C0_CB_COLOR0_TILE 0x0280C0 -#define S_0280C0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0) -#define G_0280C0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_0280C0_BASE_256B 0x00000000 -#define R_0280C4_CB_COLOR1_TILE 0x0280C4 -#define R_0280C8_CB_COLOR2_TILE 0x0280C8 -#define R_0280CC_CB_COLOR3_TILE 0x0280CC -#define R_0280D0_CB_COLOR4_TILE 0x0280D0 -#define R_0280D4_CB_COLOR5_TILE 0x0280D4 -#define R_0280D8_CB_COLOR6_TILE 0x0280D8 -#define R_0280DC_CB_COLOR7_TILE 0x0280DC -#define R_0280A0_CB_COLOR0_INFO 0x0280A0 -#define S_0280A0_ENDIAN(x) (((x) & 0x3) << 0) -#define G_0280A0_ENDIAN(x) (((x) >> 0) & 0x3) -#define C_0280A0_ENDIAN 0xFFFFFFFC -#define S_0280A0_FORMAT(x) (((x) & 0x3F) << 2) -#define G_0280A0_FORMAT(x) (((x) >> 2) & 0x3F) -#define C_0280A0_FORMAT 0xFFFFFF03 -#define V_0280A0_COLOR_INVALID 0x00000000 -#define V_0280A0_COLOR_8 0x00000001 -#define V_0280A0_COLOR_4_4 0x00000002 -#define V_0280A0_COLOR_3_3_2 0x00000003 -#define V_0280A0_COLOR_16 0x00000005 -#define V_0280A0_COLOR_16_FLOAT 0x00000006 -#define V_0280A0_COLOR_8_8 0x00000007 -#define V_0280A0_COLOR_5_6_5 0x00000008 -#define V_0280A0_COLOR_6_5_5 0x00000009 -#define V_0280A0_COLOR_1_5_5_5 0x0000000A -#define V_0280A0_COLOR_4_4_4_4 0x0000000B -#define V_0280A0_COLOR_5_5_5_1 0x0000000C -#define V_0280A0_COLOR_32 0x0000000D -#define V_0280A0_COLOR_32_FLOAT 0x0000000E -#define V_0280A0_COLOR_16_16 0x0000000F -#define V_0280A0_COLOR_16_16_FLOAT 0x00000010 -#define V_0280A0_COLOR_8_24 0x00000011 -#define V_0280A0_COLOR_8_24_FLOAT 0x00000012 -#define V_0280A0_COLOR_24_8 0x00000013 -#define V_0280A0_COLOR_24_8_FLOAT 0x00000014 -#define V_0280A0_COLOR_10_11_11 0x00000015 -#define V_0280A0_COLOR_10_11_11_FLOAT 0x00000016 -#define V_0280A0_COLOR_11_11_10 0x00000017 -#define V_0280A0_COLOR_11_11_10_FLOAT 0x00000018 -#define V_0280A0_COLOR_2_10_10_10 0x00000019 -#define V_0280A0_COLOR_8_8_8_8 0x0000001A -#define V_0280A0_COLOR_10_10_10_2 0x0000001B -#define V_0280A0_COLOR_X24_8_32_FLOAT 0x0000001C -#define V_0280A0_COLOR_32_32 0x0000001D -#define V_0280A0_COLOR_32_32_FLOAT 0x0000001E -#define V_0280A0_COLOR_16_16_16_16 0x0000001F -#define V_0280A0_COLOR_16_16_16_16_FLOAT 0x00000020 -#define V_0280A0_COLOR_32_32_32_32 0x00000022 -#define V_0280A0_COLOR_32_32_32_32_FLOAT 0x00000023 -#define S_0280A0_ARRAY_MODE(x) (((x) & 0xF) << 8) -#define G_0280A0_ARRAY_MODE(x) (((x) >> 8) & 0xF) -#define C_0280A0_ARRAY_MODE 0xFFFFF0FF -#define V_0280A0_ARRAY_LINEAR_GENERAL 0x00000000 -#define V_0280A0_ARRAY_LINEAR_ALIGNED 0x00000001 -#define V_0280A0_ARRAY_1D_TILED_THIN1 0x00000002 -#define V_0280A0_ARRAY_2D_TILED_THIN1 0x00000004 -#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12) -#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7) -#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF -#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15) -#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1) -#define C_0280A0_READ_SIZE 0xFFFF7FFF -#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16) -#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3) -#define C_0280A0_COMP_SWAP 0xFFFCFFFF -#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) -#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) -#define C_0280A0_TILE_MODE 0xFFF3FFFF -#define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) -#define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) -#define C_0280A0_BLEND_CLAMP 0xFFEFFFFF -#define S_0280A0_CLEAR_COLOR(x) (((x) & 0x1) << 21) -#define G_0280A0_CLEAR_COLOR(x) (((x) >> 21) & 0x1) -#define C_0280A0_CLEAR_COLOR 0xFFDFFFFF -#define S_0280A0_BLEND_BYPASS(x) (((x) & 0x1) << 22) -#define G_0280A0_BLEND_BYPASS(x) (((x) >> 22) & 0x1) -#define C_0280A0_BLEND_BYPASS 0xFFBFFFFF -#define S_0280A0_BLEND_FLOAT32(x) (((x) & 0x1) << 23) -#define G_0280A0_BLEND_FLOAT32(x) (((x) >> 23) & 0x1) -#define C_0280A0_BLEND_FLOAT32 0xFF7FFFFF -#define S_0280A0_SIMPLE_FLOAT(x) (((x) & 0x1) << 24) -#define G_0280A0_SIMPLE_FLOAT(x) (((x) >> 24) & 0x1) -#define C_0280A0_SIMPLE_FLOAT 0xFEFFFFFF -#define S_0280A0_ROUND_MODE(x) (((x) & 0x1) << 25) -#define G_0280A0_ROUND_MODE(x) (((x) >> 25) & 0x1) -#define C_0280A0_ROUND_MODE 0xFDFFFFFF -#define S_0280A0_TILE_COMPACT(x) (((x) & 0x1) << 26) -#define G_0280A0_TILE_COMPACT(x) (((x) >> 26) & 0x1) -#define C_0280A0_TILE_COMPACT 0xFBFFFFFF -#define S_0280A0_SOURCE_FORMAT(x) (((x) & 0x1) << 27) -#define G_0280A0_SOURCE_FORMAT(x) (((x) >> 27) & 0x1) -#define C_0280A0_SOURCE_FORMAT 0xF7FFFFFF -#define R_0280A4_CB_COLOR1_INFO 0x0280A4 -#define R_0280A8_CB_COLOR2_INFO 0x0280A8 -#define R_0280AC_CB_COLOR3_INFO 0x0280AC -#define R_0280B0_CB_COLOR4_INFO 0x0280B0 -#define R_0280B4_CB_COLOR5_INFO 0x0280B4 -#define R_0280B8_CB_COLOR6_INFO 0x0280B8 -#define R_0280BC_CB_COLOR7_INFO 0x0280BC -#define R_028060_CB_COLOR0_SIZE 0x028060 -#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0) -#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF) -#define C_028060_PITCH_TILE_MAX 0xFFFFFC00 -#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10) -#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF) -#define C_028060_SLICE_TILE_MAX 0xC00003FF -#define R_028064_CB_COLOR1_SIZE 0x028064 -#define R_028068_CB_COLOR2_SIZE 0x028068 -#define R_02806C_CB_COLOR3_SIZE 0x02806C -#define R_028070_CB_COLOR4_SIZE 0x028070 -#define R_028074_CB_COLOR5_SIZE 0x028074 -#define R_028078_CB_COLOR6_SIZE 0x028078 -#define R_02807C_CB_COLOR7_SIZE 0x02807C -#define R_028238_CB_TARGET_MASK 0x028238 -#define S_028238_TARGET0_ENABLE(x) (((x) & 0xF) << 0) -#define G_028238_TARGET0_ENABLE(x) (((x) >> 0) & 0xF) -#define C_028238_TARGET0_ENABLE 0xFFFFFFF0 -#define S_028238_TARGET1_ENABLE(x) (((x) & 0xF) << 4) -#define G_028238_TARGET1_ENABLE(x) (((x) >> 4) & 0xF) -#define C_028238_TARGET1_ENABLE 0xFFFFFF0F -#define S_028238_TARGET2_ENABLE(x) (((x) & 0xF) << 8) -#define G_028238_TARGET2_ENABLE(x) (((x) >> 8) & 0xF) -#define C_028238_TARGET2_ENABLE 0xFFFFF0FF -#define S_028238_TARGET3_ENABLE(x) (((x) & 0xF) << 12) -#define G_028238_TARGET3_ENABLE(x) (((x) >> 12) & 0xF) -#define C_028238_TARGET3_ENABLE 0xFFFF0FFF -#define S_028238_TARGET4_ENABLE(x) (((x) & 0xF) << 16) -#define G_028238_TARGET4_ENABLE(x) (((x) >> 16) & 0xF) -#define C_028238_TARGET4_ENABLE 0xFFF0FFFF -#define S_028238_TARGET5_ENABLE(x) (((x) & 0xF) << 20) -#define G_028238_TARGET5_ENABLE(x) (((x) >> 20) & 0xF) -#define C_028238_TARGET5_ENABLE 0xFF0FFFFF -#define S_028238_TARGET6_ENABLE(x) (((x) & 0xF) << 24) -#define G_028238_TARGET6_ENABLE(x) (((x) >> 24) & 0xF) -#define C_028238_TARGET6_ENABLE 0xF0FFFFFF -#define S_028238_TARGET7_ENABLE(x) (((x) & 0xF) << 28) -#define G_028238_TARGET7_ENABLE(x) (((x) >> 28) & 0xF) -#define C_028238_TARGET7_ENABLE 0x0FFFFFFF -#define R_02823C_CB_SHADER_MASK 0x02823C -#define S_02823C_OUTPUT0_ENABLE(x) (((x) & 0xF) << 0) -#define G_02823C_OUTPUT0_ENABLE(x) (((x) >> 0) & 0xF) -#define C_02823C_OUTPUT0_ENABLE 0xFFFFFFF0 -#define S_02823C_OUTPUT1_ENABLE(x) (((x) & 0xF) << 4) -#define G_02823C_OUTPUT1_ENABLE(x) (((x) >> 4) & 0xF) -#define C_02823C_OUTPUT1_ENABLE 0xFFFFFF0F -#define S_02823C_OUTPUT2_ENABLE(x) (((x) & 0xF) << 8) -#define G_02823C_OUTPUT2_ENABLE(x) (((x) >> 8) & 0xF) -#define C_02823C_OUTPUT2_ENABLE 0xFFFFF0FF -#define S_02823C_OUTPUT3_ENABLE(x) (((x) & 0xF) << 12) -#define G_02823C_OUTPUT3_ENABLE(x) (((x) >> 12) & 0xF) -#define C_02823C_OUTPUT3_ENABLE 0xFFFF0FFF -#define S_02823C_OUTPUT4_ENABLE(x) (((x) & 0xF) << 16) -#define G_02823C_OUTPUT4_ENABLE(x) (((x) >> 16) & 0xF) -#define C_02823C_OUTPUT4_ENABLE 0xFFF0FFFF -#define S_02823C_OUTPUT5_ENABLE(x) (((x) & 0xF) << 20) -#define G_02823C_OUTPUT5_ENABLE(x) (((x) >> 20) & 0xF) -#define C_02823C_OUTPUT5_ENABLE 0xFF0FFFFF -#define S_02823C_OUTPUT6_ENABLE(x) (((x) & 0xF) << 24) -#define G_02823C_OUTPUT6_ENABLE(x) (((x) >> 24) & 0xF) -#define C_02823C_OUTPUT6_ENABLE 0xF0FFFFFF -#define S_02823C_OUTPUT7_ENABLE(x) (((x) & 0xF) << 28) -#define G_02823C_OUTPUT7_ENABLE(x) (((x) >> 28) & 0xF) -#define C_02823C_OUTPUT7_ENABLE 0x0FFFFFFF -#define R_028AB0_VGT_STRMOUT_EN 0x028AB0 -#define S_028AB0_STREAMOUT(x) (((x) & 0x1) << 0) -#define G_028AB0_STREAMOUT(x) (((x) >> 0) & 0x1) -#define C_028AB0_STREAMOUT 0xFFFFFFFE -#define R_028B20_VGT_STRMOUT_BUFFER_EN 0x028B20 -#define S_028B20_BUFFER_0_EN(x) (((x) & 0x1) << 0) -#define G_028B20_BUFFER_0_EN(x) (((x) >> 0) & 0x1) -#define C_028B20_BUFFER_0_EN 0xFFFFFFFE -#define S_028B20_BUFFER_1_EN(x) (((x) & 0x1) << 1) -#define G_028B20_BUFFER_1_EN(x) (((x) >> 1) & 0x1) -#define C_028B20_BUFFER_1_EN 0xFFFFFFFD -#define S_028B20_BUFFER_2_EN(x) (((x) & 0x1) << 2) -#define G_028B20_BUFFER_2_EN(x) (((x) >> 2) & 0x1) -#define C_028B20_BUFFER_2_EN 0xFFFFFFFB -#define S_028B20_BUFFER_3_EN(x) (((x) & 0x1) << 3) -#define G_028B20_BUFFER_3_EN(x) (((x) >> 3) & 0x1) -#define C_028B20_BUFFER_3_EN 0xFFFFFFF7 -#define S_028B20_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_028B20_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_028B20_SIZE 0x00000000 -#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000 -#define S_038000_DIM(x) (((x) & 0x7) << 0) -#define G_038000_DIM(x) (((x) >> 0) & 0x7) -#define C_038000_DIM 0xFFFFFFF8 -#define V_038000_SQ_TEX_DIM_1D 0x00000000 -#define V_038000_SQ_TEX_DIM_2D 0x00000001 -#define V_038000_SQ_TEX_DIM_3D 0x00000002 -#define V_038000_SQ_TEX_DIM_CUBEMAP 0x00000003 -#define V_038000_SQ_TEX_DIM_1D_ARRAY 0x00000004 -#define V_038000_SQ_TEX_DIM_2D_ARRAY 0x00000005 -#define V_038000_SQ_TEX_DIM_2D_MSAA 0x00000006 -#define V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 -#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) -#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) -#define C_038000_TILE_MODE 0xFFFFFF87 -#define V_038000_ARRAY_LINEAR_GENERAL 0x00000000 -#define V_038000_ARRAY_LINEAR_ALIGNED 0x00000001 -#define V_038000_ARRAY_1D_TILED_THIN1 0x00000002 -#define V_038000_ARRAY_2D_TILED_THIN1 0x00000004 -#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) -#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) -#define C_038000_TILE_TYPE 0xFFFFFF7F -#define S_038000_PITCH(x) (((x) & 0x7FF) << 8) -#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF) -#define C_038000_PITCH 0xFFF800FF -#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19) -#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF) -#define C_038000_TEX_WIDTH 0x0007FFFF -#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004 -#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0) -#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF) -#define C_038004_TEX_HEIGHT 0xFFFFE000 -#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13) -#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF) -#define C_038004_TEX_DEPTH 0xFC001FFF -#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26) -#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F) -#define C_038004_DATA_FORMAT 0x03FFFFFF -#define V_038004_COLOR_INVALID 0x00000000 -#define V_038004_COLOR_8 0x00000001 -#define V_038004_COLOR_4_4 0x00000002 -#define V_038004_COLOR_3_3_2 0x00000003 -#define V_038004_COLOR_16 0x00000005 -#define V_038004_COLOR_16_FLOAT 0x00000006 -#define V_038004_COLOR_8_8 0x00000007 -#define V_038004_COLOR_5_6_5 0x00000008 -#define V_038004_COLOR_6_5_5 0x00000009 -#define V_038004_COLOR_1_5_5_5 0x0000000A -#define V_038004_COLOR_4_4_4_4 0x0000000B -#define V_038004_COLOR_5_5_5_1 0x0000000C -#define V_038004_COLOR_32 0x0000000D -#define V_038004_COLOR_32_FLOAT 0x0000000E -#define V_038004_COLOR_16_16 0x0000000F -#define V_038004_COLOR_16_16_FLOAT 0x00000010 -#define V_038004_COLOR_8_24 0x00000011 -#define V_038004_COLOR_8_24_FLOAT 0x00000012 -#define V_038004_COLOR_24_8 0x00000013 -#define V_038004_COLOR_24_8_FLOAT 0x00000014 -#define V_038004_COLOR_10_11_11 0x00000015 -#define V_038004_COLOR_10_11_11_FLOAT 0x00000016 -#define V_038004_COLOR_11_11_10 0x00000017 -#define V_038004_COLOR_11_11_10_FLOAT 0x00000018 -#define V_038004_COLOR_2_10_10_10 0x00000019 -#define V_038004_COLOR_8_8_8_8 0x0000001A -#define V_038004_COLOR_10_10_10_2 0x0000001B -#define V_038004_COLOR_X24_8_32_FLOAT 0x0000001C -#define V_038004_COLOR_32_32 0x0000001D -#define V_038004_COLOR_32_32_FLOAT 0x0000001E -#define V_038004_COLOR_16_16_16_16 0x0000001F -#define V_038004_COLOR_16_16_16_16_FLOAT 0x00000020 -#define V_038004_COLOR_32_32_32_32 0x00000022 -#define V_038004_COLOR_32_32_32_32_FLOAT 0x00000023 -#define V_038004_FMT_1 0x00000025 -#define V_038004_FMT_GB_GR 0x00000027 -#define V_038004_FMT_BG_RG 0x00000028 -#define V_038004_FMT_32_AS_8 0x00000029 -#define V_038004_FMT_32_AS_8_8 0x0000002A -#define V_038004_FMT_5_9_9_9_SHAREDEXP 0x0000002B -#define V_038004_FMT_8_8_8 0x0000002C -#define V_038004_FMT_16_16_16 0x0000002D -#define V_038004_FMT_16_16_16_FLOAT 0x0000002E -#define V_038004_FMT_32_32_32 0x0000002F -#define V_038004_FMT_32_32_32_FLOAT 0x00000030 -#define V_038004_FMT_BC1 0x00000031 -#define V_038004_FMT_BC2 0x00000032 -#define V_038004_FMT_BC3 0x00000033 -#define V_038004_FMT_BC4 0x00000034 -#define V_038004_FMT_BC5 0x00000035 -#define V_038004_FMT_BC6 0x00000036 -#define V_038004_FMT_BC7 0x00000037 -#define V_038004_FMT_32_AS_32_32_32_32 0x00000038 -#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010 -#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) -#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) -#define C_038010_FORMAT_COMP_X 0xFFFFFFFC -#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) -#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) -#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3 -#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) -#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) -#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF -#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) -#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) -#define C_038010_FORMAT_COMP_W 0xFFFFFF3F -#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) -#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) -#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF -#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) -#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) -#define C_038010_SRF_MODE_ALL 0xFFFFFBFF -#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) -#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) -#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF -#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) -#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) -#define C_038010_ENDIAN_SWAP 0xFFFFCFFF -#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14) -#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3) -#define C_038010_REQUEST_SIZE 0xFFFF3FFF -#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16) -#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7) -#define C_038010_DST_SEL_X 0xFFF8FFFF -#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19) -#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7) -#define C_038010_DST_SEL_Y 0xFFC7FFFF -#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22) -#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7) -#define C_038010_DST_SEL_Z 0xFE3FFFFF -#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25) -#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7) -#define C_038010_DST_SEL_W 0xF1FFFFFF -# define SQ_SEL_X 0 -# define SQ_SEL_Y 1 -# define SQ_SEL_Z 2 -# define SQ_SEL_W 3 -# define SQ_SEL_0 4 -# define SQ_SEL_1 5 -#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28) -#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF) -#define C_038010_BASE_LEVEL 0x0FFFFFFF -#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014 -#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0) -#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF) -#define C_038014_LAST_LEVEL 0xFFFFFFF0 -#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) -#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) -#define C_038014_BASE_ARRAY 0xFFFE000F -#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) -#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) -#define C_038014_LAST_ARRAY 0xC001FFFF -#define R_0288A8_SQ_ESGS_RING_ITEMSIZE 0x0288A8 -#define S_0288A8_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288A8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288A8_ITEMSIZE 0xFFFF8000 -#define R_008C44_SQ_ESGS_RING_SIZE 0x008C44 -#define S_008C44_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C44_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C44_MEM_SIZE 0x00000000 -#define R_0288B0_SQ_ESTMP_RING_ITEMSIZE 0x0288B0 -#define S_0288B0_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288B0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288B0_ITEMSIZE 0xFFFF8000 -#define R_008C54_SQ_ESTMP_RING_SIZE 0x008C54 -#define S_008C54_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C54_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C54_MEM_SIZE 0x00000000 -#define R_0288C0_SQ_FBUF_RING_ITEMSIZE 0x0288C0 -#define S_0288C0_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288C0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288C0_ITEMSIZE 0xFFFF8000 -#define R_008C74_SQ_FBUF_RING_SIZE 0x008C74 -#define S_008C74_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C74_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C74_MEM_SIZE 0x00000000 -#define R_0288B4_SQ_GSTMP_RING_ITEMSIZE 0x0288B4 -#define S_0288B4_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288B4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288B4_ITEMSIZE 0xFFFF8000 -#define R_008C5C_SQ_GSTMP_RING_SIZE 0x008C5C -#define S_008C5C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C5C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C5C_MEM_SIZE 0x00000000 -#define R_0288AC_SQ_GSVS_RING_ITEMSIZE 0x0288AC -#define S_0288AC_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288AC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288AC_ITEMSIZE 0xFFFF8000 -#define R_008C4C_SQ_GSVS_RING_SIZE 0x008C4C -#define S_008C4C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C4C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C4C_MEM_SIZE 0x00000000 -#define R_0288BC_SQ_PSTMP_RING_ITEMSIZE 0x0288BC -#define S_0288BC_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288BC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288BC_ITEMSIZE 0xFFFF8000 -#define R_008C6C_SQ_PSTMP_RING_SIZE 0x008C6C -#define S_008C6C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C6C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C6C_MEM_SIZE 0x00000000 -#define R_0288C4_SQ_REDUC_RING_ITEMSIZE 0x0288C4 -#define S_0288C4_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288C4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288C4_ITEMSIZE 0xFFFF8000 -#define R_008C7C_SQ_REDUC_RING_SIZE 0x008C7C -#define S_008C7C_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C7C_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C7C_MEM_SIZE 0x00000000 -#define R_0288B8_SQ_VSTMP_RING_ITEMSIZE 0x0288B8 -#define S_0288B8_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288B8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288B8_ITEMSIZE 0xFFFF8000 -#define R_008C64_SQ_VSTMP_RING_SIZE 0x008C64 -#define S_008C64_MEM_SIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_008C64_MEM_SIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_008C64_MEM_SIZE 0x00000000 -#define R_0288C8_SQ_GS_VERT_ITEMSIZE 0x0288C8 -#define S_0288C8_ITEMSIZE(x) (((x) & 0x7FFF) << 0) -#define G_0288C8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF) -#define C_0288C8_ITEMSIZE 0xFFFF8000 -#define R_028010_DB_DEPTH_INFO 0x028010 -#define S_028010_FORMAT(x) (((x) & 0x7) << 0) -#define G_028010_FORMAT(x) (((x) >> 0) & 0x7) -#define C_028010_FORMAT 0xFFFFFFF8 -#define V_028010_DEPTH_INVALID 0x00000000 -#define V_028010_DEPTH_16 0x00000001 -#define V_028010_DEPTH_X8_24 0x00000002 -#define V_028010_DEPTH_8_24 0x00000003 -#define V_028010_DEPTH_X8_24_FLOAT 0x00000004 -#define V_028010_DEPTH_8_24_FLOAT 0x00000005 -#define V_028010_DEPTH_32_FLOAT 0x00000006 -#define V_028010_DEPTH_X24_8_32_FLOAT 0x00000007 -#define S_028010_READ_SIZE(x) (((x) & 0x1) << 3) -#define G_028010_READ_SIZE(x) (((x) >> 3) & 0x1) -#define C_028010_READ_SIZE 0xFFFFFFF7 -#define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15) -#define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF) -#define C_028010_ARRAY_MODE 0xFFF87FFF -#define V_028010_ARRAY_1D_TILED_THIN1 0x00000002 -#define V_028010_ARRAY_2D_TILED_THIN1 0x00000004 -#define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25) -#define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1) -#define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF -#define S_028010_TILE_COMPACT(x) (((x) & 0x1) << 26) -#define G_028010_TILE_COMPACT(x) (((x) >> 26) & 0x1) -#define C_028010_TILE_COMPACT 0xFBFFFFFF -#define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31) -#define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1) -#define C_028010_ZRANGE_PRECISION 0x7FFFFFFF -#define R_028000_DB_DEPTH_SIZE 0x028000 -#define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0) -#define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF) -#define C_028000_PITCH_TILE_MAX 0xFFFFFC00 -#define S_028000_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10) -#define G_028000_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF) -#define C_028000_SLICE_TILE_MAX 0xC00003FF -#define R_028004_DB_DEPTH_VIEW 0x028004 -#define S_028004_SLICE_START(x) (((x) & 0x7FF) << 0) -#define G_028004_SLICE_START(x) (((x) >> 0) & 0x7FF) -#define C_028004_SLICE_START 0xFFFFF800 -#define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13) -#define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF) -#define C_028004_SLICE_MAX 0xFF001FFF -#define R_028800_DB_DEPTH_CONTROL 0x028800 -#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0) -#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1) -#define C_028800_STENCIL_ENABLE 0xFFFFFFFE -#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1) -#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1) -#define C_028800_Z_ENABLE 0xFFFFFFFD -#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2) -#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1) -#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB -#define S_028800_ZFUNC(x) (((x) & 0x7) << 4) -#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7) -#define C_028800_ZFUNC 0xFFFFFF8F -#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7) -#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1) -#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F -#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8) -#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7) -#define C_028800_STENCILFUNC 0xFFFFF8FF -#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11) -#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7) -#define C_028800_STENCILFAIL 0xFFFFC7FF -#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14) -#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7) -#define C_028800_STENCILZPASS 0xFFFE3FFF -#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17) -#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7) -#define C_028800_STENCILZFAIL 0xFFF1FFFF -#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20) -#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7) -#define C_028800_STENCILFUNC_BF 0xFF8FFFFF -#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23) -#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7) -#define C_028800_STENCILFAIL_BF 0xFC7FFFFF -#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26) -#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7) -#define C_028800_STENCILZPASS_BF 0xE3FFFFFF -#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29) -#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7) -#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon.h deleted file mode 100644 index 138b9521..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon.h +++ /dev/null @@ -1,1867 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RADEON_H__ -#define __RADEON_H__ - -/* TODO: Here are things that needs to be done : - * - surface allocator & initializer : (bit like scratch reg) should - * initialize HDP_ stuff on RS600, R600, R700 hw, well anythings - * related to surface - * - WB : write back stuff (do it bit like scratch reg things) - * - Vblank : look at Jesse's rework and what we should do - * - r600/r700: gart & cp - * - cs : clean cs ioctl use bitmap & things like that. - * - power management stuff - * - Barrier in gart code - * - Unmappabled vram ? - * - TESTING, TESTING, TESTING - */ - -/* Initialization path: - * We expect that acceleration initialization might fail for various - * reasons even thought we work hard to make it works on most - * configurations. In order to still have a working userspace in such - * situation the init path must succeed up to the memory controller - * initialization point. Failure before this point are considered as - * fatal error. Here is the init callchain : - * radeon_device_init perform common structure, mutex initialization - * asic_init setup the GPU memory layout and perform all - * one time initialization (failure in this - * function are considered fatal) - * asic_startup setup the GPU acceleration, in order to - * follow guideline the first thing this - * function should do is setting the GPU - * memory controller (only MC setup failure - * are considered as fatal) - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "radeon_family.h" -#include "radeon_mode.h" -#include "radeon_reg.h" - -/* - * Modules parameters. - */ -extern int radeon_no_wb; -extern int radeon_modeset; -extern int radeon_dynclks; -extern int radeon_r4xx_atom; -extern int radeon_agpmode; -extern int radeon_vram_limit; -extern int radeon_gart_size; -extern int radeon_benchmarking; -extern int radeon_testing; -extern int radeon_connector_table; -extern int radeon_tv; -extern int radeon_audio; -extern int radeon_disp_priority; -extern int radeon_hw_i2c; -extern int radeon_pcie_gen2; -extern int radeon_msi; - -/* - * Copy from radeon_drv.h so we don't have to include both and have conflicting - * symbol; - */ -#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ -#define RADEON_FENCE_JIFFIES_TIMEOUT (HZ / 2) -/* RADEON_IB_POOL_SIZE must be a power of 2 */ -#define RADEON_IB_POOL_SIZE 16 -#define RADEON_DEBUGFS_MAX_COMPONENTS 32 -#define RADEONFB_CONN_LIMIT 4 -#define RADEON_BIOS_NUM_SCRATCH 8 - -/* max number of rings */ -#define RADEON_NUM_RINGS 3 - -/* internal ring indices */ -/* r1xx+ has gfx CP ring */ -#define RADEON_RING_TYPE_GFX_INDEX 0 - -/* cayman has 2 compute CP rings */ -#define CAYMAN_RING_TYPE_CP1_INDEX 1 -#define CAYMAN_RING_TYPE_CP2_INDEX 2 - -/* hardcode those limit for now */ -#define RADEON_VA_RESERVED_SIZE (8 << 20) -#define RADEON_IB_VM_MAX_SIZE (64 << 10) - -/* - * Errata workarounds. - */ -enum radeon_pll_errata { - CHIP_ERRATA_R300_CG = 0x00000001, - CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002, - CHIP_ERRATA_PLL_DELAY = 0x00000004 -}; - - -struct radeon_device; - - -/* - * BIOS. - */ -#define ATRM_BIOS_PAGE 4096 - -#if defined(CONFIG_VGA_SWITCHEROO) -bool radeon_atrm_supported(struct pci_dev *pdev); -int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); -#else -static inline bool radeon_atrm_supported(struct pci_dev *pdev) -{ - return false; -} - -static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ - return -EINVAL; -} -#endif -bool radeon_get_bios(struct radeon_device *rdev); - - -/* - * Mutex which allows recursive locking from the same process. - */ -struct radeon_mutex { - struct mutex mutex; - struct task_struct *owner; - int level; -}; - -static inline void radeon_mutex_init(struct radeon_mutex *mutex) -{ - mutex_init(&mutex->mutex); - mutex->owner = NULL; - mutex->level = 0; -} - -static inline void radeon_mutex_lock(struct radeon_mutex *mutex) -{ - if (mutex_trylock(&mutex->mutex)) { - /* The mutex was unlocked before, so it's ours now */ - mutex->owner = current; - } else if (mutex->owner != current) { - /* Another process locked the mutex, take it */ - mutex_lock(&mutex->mutex); - mutex->owner = current; - } - /* Otherwise the mutex was already locked by this process */ - - mutex->level++; -} - -static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) -{ - if (--mutex->level > 0) - return; - - mutex->owner = NULL; - mutex_unlock(&mutex->mutex); -} - - -/* - * Dummy page - */ -struct radeon_dummy_page { - struct page *page; - dma_addr_t addr; -}; -int radeon_dummy_page_init(struct radeon_device *rdev); -void radeon_dummy_page_fini(struct radeon_device *rdev); - - -/* - * Clocks - */ -struct radeon_clock { - struct radeon_pll p1pll; - struct radeon_pll p2pll; - struct radeon_pll dcpll; - struct radeon_pll spll; - struct radeon_pll mpll; - /* 10 Khz units */ - uint32_t default_mclk; - uint32_t default_sclk; - uint32_t default_dispclk; - uint32_t dp_extclk; - uint32_t max_pixel_clock; -}; - -/* - * Power management - */ -int radeon_pm_init(struct radeon_device *rdev); -void radeon_pm_fini(struct radeon_device *rdev); -void radeon_pm_compute_clocks(struct radeon_device *rdev); -void radeon_pm_suspend(struct radeon_device *rdev); -void radeon_pm_resume(struct radeon_device *rdev); -void radeon_combios_get_power_modes(struct radeon_device *rdev); -void radeon_atombios_get_power_modes(struct radeon_device *rdev); -void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); -void rs690_pm_info(struct radeon_device *rdev); -extern int rv6xx_get_temp(struct radeon_device *rdev); -extern int rv770_get_temp(struct radeon_device *rdev); -extern int evergreen_get_temp(struct radeon_device *rdev); -extern int sumo_get_temp(struct radeon_device *rdev); -extern int si_get_temp(struct radeon_device *rdev); -extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, - unsigned *bankh, unsigned *mtaspect, - unsigned *tile_split); - -/* - * Fences. - */ -struct radeon_fence_driver { - uint32_t scratch_reg; - uint64_t gpu_addr; - volatile uint32_t *cpu_addr; - atomic_t seq; - uint32_t last_seq; - unsigned long last_jiffies; - unsigned long last_timeout; - wait_queue_head_t queue; - struct list_head created; - struct list_head emitted; - struct list_head signaled; - bool initialized; -}; - -struct radeon_fence { - struct radeon_device *rdev; - struct kref kref; - struct list_head list; - /* protected by radeon_fence.lock */ - uint32_t seq; - bool emitted; - bool signaled; - /* RB, DMA, etc. */ - int ring; - struct radeon_semaphore *semaphore; -}; - -int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); -int radeon_fence_driver_init(struct radeon_device *rdev); -void radeon_fence_driver_fini(struct radeon_device *rdev); -int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence, int ring); -int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence); -void radeon_fence_process(struct radeon_device *rdev, int ring); -bool radeon_fence_signaled(struct radeon_fence *fence); -int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); -int radeon_fence_wait_next(struct radeon_device *rdev, int ring); -int radeon_fence_wait_last(struct radeon_device *rdev, int ring); -struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); -void radeon_fence_unref(struct radeon_fence **fence); -int radeon_fence_count_emitted(struct radeon_device *rdev, int ring); - -/* - * Tiling registers - */ -struct radeon_surface_reg { - struct radeon_bo *bo; -}; - -#define RADEON_GEM_MAX_SURFACES 8 - -/* - * TTM. - */ -struct radeon_mman { - struct ttm_bo_global_ref bo_global_ref; - struct drm_global_reference mem_global_ref; - struct ttm_bo_device bdev; - bool mem_global_referenced; - bool initialized; -}; - -/* bo virtual address in a specific vm */ -struct radeon_bo_va { - /* bo list is protected by bo being reserved */ - struct list_head bo_list; - /* vm list is protected by vm mutex */ - struct list_head vm_list; - /* constant after initialization */ - struct radeon_vm *vm; - struct radeon_bo *bo; - uint64_t soffset; - uint64_t eoffset; - uint32_t flags; - bool valid; -}; - -struct radeon_bo { - /* Protected by gem.mutex */ - struct list_head list; - /* Protected by tbo.reserved */ - u32 placements[3]; - struct ttm_placement placement; - struct ttm_buffer_object tbo; - struct ttm_bo_kmap_obj kmap; - unsigned pin_count; - void *kptr; - u32 tiling_flags; - u32 pitch; - int surface_reg; - /* list of all virtual address to which this bo - * is associated to - */ - struct list_head va; - /* Constant after initialization */ - struct radeon_device *rdev; - struct drm_gem_object gem_base; -}; -#define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, gem_base) - -struct radeon_bo_list { - struct ttm_validate_buffer tv; - struct radeon_bo *bo; - uint64_t gpu_offset; - unsigned rdomain; - unsigned wdomain; - u32 tiling_flags; -}; - -/* sub-allocation manager, it has to be protected by another lock. - * By conception this is an helper for other part of the driver - * like the indirect buffer or semaphore, which both have their - * locking. - * - * Principe is simple, we keep a list of sub allocation in offset - * order (first entry has offset == 0, last entry has the highest - * offset). - * - * When allocating new object we first check if there is room at - * the end total_size - (last_object_offset + last_object_size) >= - * alloc_size. If so we allocate new object there. - * - * When there is not enough room at the end, we start waiting for - * each sub object until we reach object_offset+object_size >= - * alloc_size, this object then become the sub object we return. - * - * Alignment can't be bigger than page size. - * - * Hole are not considered for allocation to keep things simple. - * Assumption is that there won't be hole (all object on same - * alignment). - */ -struct radeon_sa_manager { - struct radeon_bo *bo; - struct list_head sa_bo; - unsigned size; - uint64_t gpu_addr; - void *cpu_ptr; - uint32_t domain; -}; - -struct radeon_sa_bo; - -/* sub-allocation buffer */ -struct radeon_sa_bo { - struct list_head list; - struct radeon_sa_manager *manager; - unsigned offset; - unsigned size; -}; - -/* - * GEM objects. - */ -struct radeon_gem { - struct mutex mutex; - struct list_head objects; -}; - -int radeon_gem_init(struct radeon_device *rdev); -void radeon_gem_fini(struct radeon_device *rdev); -int radeon_gem_object_create(struct radeon_device *rdev, int size, - int alignment, int initial_domain, - bool discardable, bool kernel, - struct drm_gem_object **obj); - -int radeon_mode_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); -int radeon_mode_dumb_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p); -int radeon_mode_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle); - -/* - * Semaphores. - */ -struct radeon_ring; - -#define RADEON_SEMAPHORE_BO_SIZE 256 - -struct radeon_semaphore_driver { - rwlock_t lock; - struct list_head bo; -}; - -struct radeon_semaphore_bo; - -/* everything here is constant */ -struct radeon_semaphore { - struct list_head list; - uint64_t gpu_addr; - uint32_t *cpu_ptr; - struct radeon_semaphore_bo *bo; -}; - -struct radeon_semaphore_bo { - struct list_head list; - struct radeon_ib *ib; - struct list_head free; - struct radeon_semaphore semaphores[RADEON_SEMAPHORE_BO_SIZE/8]; - unsigned nused; -}; - -void radeon_semaphore_driver_fini(struct radeon_device *rdev); -int radeon_semaphore_create(struct radeon_device *rdev, - struct radeon_semaphore **semaphore); -void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore); -void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore); -void radeon_semaphore_free(struct radeon_device *rdev, - struct radeon_semaphore *semaphore); - -/* - * GART structures, functions & helpers - */ -struct radeon_mc; - -#define RADEON_GPU_PAGE_SIZE 4096 -#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) -#define RADEON_GPU_PAGE_SHIFT 12 -#define RADEON_GPU_PAGE_ALIGN(a) (((a) + RADEON_GPU_PAGE_MASK) & ~RADEON_GPU_PAGE_MASK) - -struct radeon_gart { - dma_addr_t table_addr; - struct radeon_bo *robj; - void *ptr; - unsigned num_gpu_pages; - unsigned num_cpu_pages; - unsigned table_size; - struct page **pages; - dma_addr_t *pages_addr; - bool ready; -}; - -int radeon_gart_table_ram_alloc(struct radeon_device *rdev); -void radeon_gart_table_ram_free(struct radeon_device *rdev); -int radeon_gart_table_vram_alloc(struct radeon_device *rdev); -void radeon_gart_table_vram_free(struct radeon_device *rdev); -int radeon_gart_table_vram_pin(struct radeon_device *rdev); -void radeon_gart_table_vram_unpin(struct radeon_device *rdev); -int radeon_gart_init(struct radeon_device *rdev); -void radeon_gart_fini(struct radeon_device *rdev); -void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, - int pages); -int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, - int pages, struct page **pagelist, - dma_addr_t *dma_addr); -void radeon_gart_restore(struct radeon_device *rdev); - - -/* - * GPU MC structures, functions & helpers - */ -struct radeon_mc { - resource_size_t aper_size; - resource_size_t aper_base; - resource_size_t agp_base; - /* for some chips with <= 32MB we need to lie - * about vram size near mc fb location */ - u64 mc_vram_size; - u64 visible_vram_size; - u64 gtt_size; - u64 gtt_start; - u64 gtt_end; - u64 vram_start; - u64 vram_end; - unsigned vram_width; - u64 real_vram_size; - int vram_mtrr; - bool vram_is_ddr; - bool igp_sideport_enabled; - u64 gtt_base_align; -}; - -bool radeon_combios_sideport_present(struct radeon_device *rdev); -bool radeon_atombios_sideport_present(struct radeon_device *rdev); - -/* - * GPU scratch registers structures, functions & helpers - */ -struct radeon_scratch { - unsigned num_reg; - uint32_t reg_base; - bool free[32]; - uint32_t reg[32]; -}; - -int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg); -void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg); - - -/* - * IRQS. - */ - -struct radeon_unpin_work { - struct work_struct work; - struct radeon_device *rdev; - int crtc_id; - struct radeon_fence *fence; - struct drm_pending_vblank_event *event; - struct radeon_bo *old_rbo; - u64 new_crtc_base; -}; - -struct r500_irq_stat_regs { - u32 disp_int; -}; - -struct r600_irq_stat_regs { - u32 disp_int; - u32 disp_int_cont; - u32 disp_int_cont2; - u32 d1grph_int; - u32 d2grph_int; -}; - -struct evergreen_irq_stat_regs { - u32 disp_int; - u32 disp_int_cont; - u32 disp_int_cont2; - u32 disp_int_cont3; - u32 disp_int_cont4; - u32 disp_int_cont5; - u32 d1grph_int; - u32 d2grph_int; - u32 d3grph_int; - u32 d4grph_int; - u32 d5grph_int; - u32 d6grph_int; -}; - -union radeon_irq_stat_regs { - struct r500_irq_stat_regs r500; - struct r600_irq_stat_regs r600; - struct evergreen_irq_stat_regs evergreen; -}; - -#define RADEON_MAX_HPD_PINS 6 -#define RADEON_MAX_CRTCS 6 -#define RADEON_MAX_HDMI_BLOCKS 2 - -struct radeon_irq { - bool installed; - bool sw_int[RADEON_NUM_RINGS]; - bool crtc_vblank_int[RADEON_MAX_CRTCS]; - bool pflip[RADEON_MAX_CRTCS]; - wait_queue_head_t vblank_queue; - bool hpd[RADEON_MAX_HPD_PINS]; - bool gui_idle; - bool gui_idle_acked; - wait_queue_head_t idle_queue; - bool hdmi[RADEON_MAX_HDMI_BLOCKS]; - spinlock_t sw_lock; - int sw_refcount[RADEON_NUM_RINGS]; - union radeon_irq_stat_regs stat_regs; - spinlock_t pflip_lock[RADEON_MAX_CRTCS]; - int pflip_refcount[RADEON_MAX_CRTCS]; -}; - -int radeon_irq_kms_init(struct radeon_device *rdev); -void radeon_irq_kms_fini(struct radeon_device *rdev); -void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring); -void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring); -void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); -void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); - -/* - * CP & rings. - */ - -struct radeon_ib { - struct radeon_sa_bo sa_bo; - unsigned idx; - uint32_t length_dw; - uint64_t gpu_addr; - uint32_t *ptr; - struct radeon_fence *fence; - unsigned vm_id; - bool is_const_ib; -}; - -/* - * locking - - * mutex protects scheduled_ibs, ready, alloc_bm - */ -struct radeon_ib_pool { - struct radeon_mutex mutex; - struct radeon_sa_manager sa_manager; - struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; - bool ready; - unsigned head_id; -}; - -struct radeon_ring { - struct radeon_bo *ring_obj; - volatile uint32_t *ring; - unsigned rptr; - unsigned rptr_offs; - unsigned rptr_reg; - unsigned wptr; - unsigned wptr_old; - unsigned wptr_reg; - unsigned ring_size; - unsigned ring_free_dw; - int count_dw; - uint64_t gpu_addr; - uint32_t align_mask; - uint32_t ptr_mask; - struct mutex mutex; - bool ready; - u32 ptr_reg_shift; - u32 ptr_reg_mask; - u32 nop; -}; - -/* - * VM - */ -struct radeon_vm { - struct list_head list; - struct list_head va; - int id; - unsigned last_pfn; - u64 pt_gpu_addr; - u64 *pt; - struct radeon_sa_bo sa_bo; - struct mutex mutex; - /* last fence for cs using this vm */ - struct radeon_fence *fence; -}; - -struct radeon_vm_funcs { - int (*init)(struct radeon_device *rdev); - void (*fini)(struct radeon_device *rdev); - /* cs mutex must be lock for schedule_ib */ - int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id); - void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm); - void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm); - uint32_t (*page_flags)(struct radeon_device *rdev, - struct radeon_vm *vm, - uint32_t flags); - void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm, - unsigned pfn, uint64_t addr, uint32_t flags); -}; - -struct radeon_vm_manager { - struct list_head lru_vm; - uint32_t use_bitmap; - struct radeon_sa_manager sa_manager; - uint32_t max_pfn; - /* fields constant after init */ - const struct radeon_vm_funcs *funcs; - /* number of VMIDs */ - unsigned nvm; - /* vram base address for page table entry */ - u64 vram_base_offset; - /* is vm enabled? */ - bool enabled; -}; - -/* - * file private structure - */ -struct radeon_fpriv { - struct radeon_vm vm; -}; - -/* - * R6xx+ IH ring - */ -struct r600_ih { - struct radeon_bo *ring_obj; - volatile uint32_t *ring; - unsigned rptr; - unsigned rptr_offs; - unsigned wptr; - unsigned wptr_old; - unsigned ring_size; - uint64_t gpu_addr; - uint32_t ptr_mask; - spinlock_t lock; - bool enabled; -}; - -struct r600_blit_cp_primitives { - void (*set_render_target)(struct radeon_device *rdev, int format, - int w, int h, u64 gpu_addr); - void (*cp_set_surface_sync)(struct radeon_device *rdev, - u32 sync_type, u32 size, - u64 mc_addr); - void (*set_shaders)(struct radeon_device *rdev); - void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr); - void (*set_tex_resource)(struct radeon_device *rdev, - int format, int w, int h, int pitch, - u64 gpu_addr, u32 size); - void (*set_scissors)(struct radeon_device *rdev, int x1, int y1, - int x2, int y2); - void (*draw_auto)(struct radeon_device *rdev); - void (*set_default_state)(struct radeon_device *rdev); -}; - -struct r600_blit { - struct mutex mutex; - struct radeon_bo *shader_obj; - struct r600_blit_cp_primitives primitives; - int max_dim; - int ring_size_common; - int ring_size_per_loop; - u64 shader_gpu_addr; - u32 vs_offset, ps_offset; - u32 state_offset; - u32 state_len; - u32 vb_used, vb_total; - struct radeon_ib *vb_ib; -}; - -void r600_blit_suspend(struct radeon_device *rdev); - -/* - * SI RLC stuff - */ -struct si_rlc { - /* for power gating */ - struct radeon_bo *save_restore_obj; - uint64_t save_restore_gpu_addr; - /* for clear state */ - struct radeon_bo *clear_state_obj; - uint64_t clear_state_gpu_addr; -}; - -int radeon_ib_get(struct radeon_device *rdev, int ring, - struct radeon_ib **ib, unsigned size); -void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); -bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib); -int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); -int radeon_ib_pool_init(struct radeon_device *rdev); -void radeon_ib_pool_fini(struct radeon_device *rdev); -int radeon_ib_pool_start(struct radeon_device *rdev); -int radeon_ib_pool_suspend(struct radeon_device *rdev); -/* Ring access between begin & end cannot sleep */ -int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *cp); -void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); -int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); -int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); -void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); -void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); -void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); -int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); -int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, - unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, - u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); -void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp); - - -/* - * CS. - */ -struct radeon_cs_reloc { - struct drm_gem_object *gobj; - struct radeon_bo *robj; - struct radeon_bo_list lobj; - uint32_t handle; - uint32_t flags; -}; - -struct radeon_cs_chunk { - uint32_t chunk_id; - uint32_t length_dw; - int kpage_idx[2]; - uint32_t *kpage[2]; - uint32_t *kdata; - void __user *user_ptr; - int last_copied_page; - int last_page_index; -}; - -struct radeon_cs_parser { - struct device *dev; - struct radeon_device *rdev; - struct drm_file *filp; - /* chunks */ - unsigned nchunks; - struct radeon_cs_chunk *chunks; - uint64_t *chunks_array; - /* IB */ - unsigned idx; - /* relocations */ - unsigned nrelocs; - struct radeon_cs_reloc *relocs; - struct radeon_cs_reloc **relocs_ptr; - struct list_head validated; - /* indices of various chunks */ - int chunk_ib_idx; - int chunk_relocs_idx; - int chunk_flags_idx; - int chunk_const_ib_idx; - struct radeon_ib *ib; - struct radeon_ib *const_ib; - void *track; - unsigned family; - int parser_error; - u32 cs_flags; - u32 ring; - s32 priority; -}; - -extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); -extern int radeon_cs_finish_pages(struct radeon_cs_parser *p); -extern u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx); - -struct radeon_cs_packet { - unsigned idx; - unsigned type; - unsigned reg; - unsigned opcode; - int count; - unsigned one_reg_wr; -}; - -typedef int (*radeon_packet0_check_t)(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg); -typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt); - - -/* - * AGP - */ -int radeon_agp_init(struct radeon_device *rdev); -void radeon_agp_resume(struct radeon_device *rdev); -void radeon_agp_suspend(struct radeon_device *rdev); -void radeon_agp_fini(struct radeon_device *rdev); - - -/* - * Writeback - */ -struct radeon_wb { - struct radeon_bo *wb_obj; - volatile uint32_t *wb; - uint64_t gpu_addr; - bool enabled; - bool use_event; -}; - -#define RADEON_WB_SCRATCH_OFFSET 0 -#define RADEON_WB_CP_RPTR_OFFSET 1024 -#define RADEON_WB_CP1_RPTR_OFFSET 1280 -#define RADEON_WB_CP2_RPTR_OFFSET 1536 -#define R600_WB_IH_WPTR_OFFSET 2048 -#define R600_WB_EVENT_OFFSET 3072 - -/** - * struct radeon_pm - power management datas - * @max_bandwidth: maximum bandwidth the gpu has (MByte/s) - * @igp_sideport_mclk: sideport memory clock Mhz (rs690,rs740,rs780,rs880) - * @igp_system_mclk: system clock Mhz (rs690,rs740,rs780,rs880) - * @igp_ht_link_clk: ht link clock Mhz (rs690,rs740,rs780,rs880) - * @igp_ht_link_width: ht link width in bits (rs690,rs740,rs780,rs880) - * @k8_bandwidth: k8 bandwidth the gpu has (MByte/s) (IGP) - * @sideport_bandwidth: sideport bandwidth the gpu has (MByte/s) (IGP) - * @ht_bandwidth: ht bandwidth the gpu has (MByte/s) (IGP) - * @core_bandwidth: core GPU bandwidth the gpu has (MByte/s) (IGP) - * @sclk: GPU clock Mhz (core bandwidth depends of this clock) - * @needed_bandwidth: current bandwidth needs - * - * It keeps track of various data needed to take powermanagement decision. - * Bandwidth need is used to determine minimun clock of the GPU and memory. - * Equation between gpu/memory clock and available bandwidth is hw dependent - * (type of memory, bus size, efficiency, ...) - */ - -enum radeon_pm_method { - PM_METHOD_PROFILE, - PM_METHOD_DYNPM, -}; - -enum radeon_dynpm_state { - DYNPM_STATE_DISABLED, - DYNPM_STATE_MINIMUM, - DYNPM_STATE_PAUSED, - DYNPM_STATE_ACTIVE, - DYNPM_STATE_SUSPENDED, -}; -enum radeon_dynpm_action { - DYNPM_ACTION_NONE, - DYNPM_ACTION_MINIMUM, - DYNPM_ACTION_DOWNCLOCK, - DYNPM_ACTION_UPCLOCK, - DYNPM_ACTION_DEFAULT -}; - -enum radeon_voltage_type { - VOLTAGE_NONE = 0, - VOLTAGE_GPIO, - VOLTAGE_VDDC, - VOLTAGE_SW -}; - -enum radeon_pm_state_type { - POWER_STATE_TYPE_DEFAULT, - POWER_STATE_TYPE_POWERSAVE, - POWER_STATE_TYPE_BATTERY, - POWER_STATE_TYPE_BALANCED, - POWER_STATE_TYPE_PERFORMANCE, -}; - -enum radeon_pm_profile_type { - PM_PROFILE_DEFAULT, - PM_PROFILE_AUTO, - PM_PROFILE_LOW, - PM_PROFILE_MID, - PM_PROFILE_HIGH, -}; - -#define PM_PROFILE_DEFAULT_IDX 0 -#define PM_PROFILE_LOW_SH_IDX 1 -#define PM_PROFILE_MID_SH_IDX 2 -#define PM_PROFILE_HIGH_SH_IDX 3 -#define PM_PROFILE_LOW_MH_IDX 4 -#define PM_PROFILE_MID_MH_IDX 5 -#define PM_PROFILE_HIGH_MH_IDX 6 -#define PM_PROFILE_MAX 7 - -struct radeon_pm_profile { - int dpms_off_ps_idx; - int dpms_on_ps_idx; - int dpms_off_cm_idx; - int dpms_on_cm_idx; -}; - -enum radeon_int_thermal_type { - THERMAL_TYPE_NONE, - THERMAL_TYPE_RV6XX, - THERMAL_TYPE_RV770, - THERMAL_TYPE_EVERGREEN, - THERMAL_TYPE_SUMO, - THERMAL_TYPE_NI, - THERMAL_TYPE_SI, -}; - -struct radeon_voltage { - enum radeon_voltage_type type; - /* gpio voltage */ - struct radeon_gpio_rec gpio; - u32 delay; /* delay in usec from voltage drop to sclk change */ - bool active_high; /* voltage drop is active when bit is high */ - /* VDDC voltage */ - u8 vddc_id; /* index into vddc voltage table */ - u8 vddci_id; /* index into vddci voltage table */ - bool vddci_enabled; - /* r6xx+ sw */ - u16 voltage; - /* evergreen+ vddci */ - u16 vddci; -}; - -/* clock mode flags */ -#define RADEON_PM_MODE_NO_DISPLAY (1 << 0) - -struct radeon_pm_clock_info { - /* memory clock */ - u32 mclk; - /* engine clock */ - u32 sclk; - /* voltage info */ - struct radeon_voltage voltage; - /* standardized clock flags */ - u32 flags; -}; - -/* state flags */ -#define RADEON_PM_STATE_SINGLE_DISPLAY_ONLY (1 << 0) - -struct radeon_power_state { - enum radeon_pm_state_type type; - struct radeon_pm_clock_info *clock_info; - /* number of valid clock modes in this power state */ - int num_clock_modes; - struct radeon_pm_clock_info *default_clock_mode; - /* standardized state flags */ - u32 flags; - u32 misc; /* vbios specific flags */ - u32 misc2; /* vbios specific flags */ - int pcie_lanes; /* pcie lanes */ -}; - -/* - * Some modes are overclocked by very low value, accept them - */ -#define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */ - -struct radeon_pm { - struct mutex mutex; - u32 active_crtcs; - int active_crtc_count; - int req_vblank; - bool vblank_sync; - bool gui_idle; - fixed20_12 max_bandwidth; - fixed20_12 igp_sideport_mclk; - fixed20_12 igp_system_mclk; - fixed20_12 igp_ht_link_clk; - fixed20_12 igp_ht_link_width; - fixed20_12 k8_bandwidth; - fixed20_12 sideport_bandwidth; - fixed20_12 ht_bandwidth; - fixed20_12 core_bandwidth; - fixed20_12 sclk; - fixed20_12 mclk; - fixed20_12 needed_bandwidth; - struct radeon_power_state *power_state; - /* number of valid power states */ - int num_power_states; - int current_power_state_index; - int current_clock_mode_index; - int requested_power_state_index; - int requested_clock_mode_index; - int default_power_state_index; - u32 current_sclk; - u32 current_mclk; - u16 current_vddc; - u16 current_vddci; - u32 default_sclk; - u32 default_mclk; - u16 default_vddc; - u16 default_vddci; - struct radeon_i2c_chan *i2c_bus; - /* selected pm method */ - enum radeon_pm_method pm_method; - /* dynpm power management */ - struct delayed_work dynpm_idle_work; - enum radeon_dynpm_state dynpm_state; - enum radeon_dynpm_action dynpm_planned_action; - unsigned long dynpm_action_timeout; - bool dynpm_can_upclock; - bool dynpm_can_downclock; - /* profile-based power management */ - enum radeon_pm_profile_type profile; - int profile_index; - struct radeon_pm_profile profiles[PM_PROFILE_MAX]; - /* internal thermal controller on rv6xx+ */ - enum radeon_int_thermal_type int_thermal_type; - struct device *int_hwmon_dev; -}; - -int radeon_pm_get_type_index(struct radeon_device *rdev, - enum radeon_pm_state_type ps_type, - int instance); - -/* - * Benchmarking - */ -void radeon_benchmark(struct radeon_device *rdev, int test_number); - - -/* - * Testing - */ -void radeon_test_moves(struct radeon_device *rdev); -void radeon_test_ring_sync(struct radeon_device *rdev, - struct radeon_ring *cpA, - struct radeon_ring *cpB); -void radeon_test_syncing(struct radeon_device *rdev); - - -/* - * Debugfs - */ -struct radeon_debugfs { - struct drm_info_list *files; - unsigned num_files; -}; - -int radeon_debugfs_add_files(struct radeon_device *rdev, - struct drm_info_list *files, - unsigned nfiles); -int radeon_debugfs_fence_init(struct radeon_device *rdev); - - -/* - * ASIC specific functions. - */ -struct radeon_asic { - int (*init)(struct radeon_device *rdev); - void (*fini)(struct radeon_device *rdev); - int (*resume)(struct radeon_device *rdev); - int (*suspend)(struct radeon_device *rdev); - void (*vga_set_state)(struct radeon_device *rdev, bool state); - bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); - int (*asic_reset)(struct radeon_device *rdev); - /* ioctl hw specific callback. Some hw might want to perform special - * operation on specific ioctl. For instance on wait idle some hw - * might want to perform and HDP flush through MMIO as it seems that - * some R6XX/R7XX hw doesn't take HDP flush into account if programmed - * through ring. - */ - void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); - /* check if 3D engine is idle */ - bool (*gui_idle)(struct radeon_device *rdev); - /* wait for mc_idle */ - int (*mc_wait_for_idle)(struct radeon_device *rdev); - /* gart */ - struct { - void (*tlb_flush)(struct radeon_device *rdev); - int (*set_page)(struct radeon_device *rdev, int i, uint64_t addr); - } gart; - /* ring specific callbacks */ - struct { - void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); - int (*ib_parse)(struct radeon_device *rdev, struct radeon_ib *ib); - void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence); - void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, - struct radeon_semaphore *semaphore, bool emit_wait); - int (*cs_parse)(struct radeon_cs_parser *p); - void (*ring_start)(struct radeon_device *rdev, struct radeon_ring *cp); - int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); - int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp); - } ring[RADEON_NUM_RINGS]; - /* irqs */ - struct { - int (*set)(struct radeon_device *rdev); - int (*process)(struct radeon_device *rdev); - } irq; - /* displays */ - struct { - /* display watermarks */ - void (*bandwidth_update)(struct radeon_device *rdev); - /* get frame count */ - u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); - /* wait for vblank */ - void (*wait_for_vblank)(struct radeon_device *rdev, int crtc); - } display; - /* copy functions for bo handling */ - struct { - int (*blit)(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence); - u32 blit_ring_index; - int (*dma)(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence); - u32 dma_ring_index; - /* method used for bo copy */ - int (*copy)(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence); - /* ring used for bo copies */ - u32 copy_ring_index; - } copy; - /* surfaces */ - struct { - int (*set_reg)(struct radeon_device *rdev, int reg, - uint32_t tiling_flags, uint32_t pitch, - uint32_t offset, uint32_t obj_size); - void (*clear_reg)(struct radeon_device *rdev, int reg); - } surface; - /* hotplug detect */ - struct { - void (*init)(struct radeon_device *rdev); - void (*fini)(struct radeon_device *rdev); - bool (*sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); - void (*set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); - } hpd; - /* power management */ - struct { - void (*misc)(struct radeon_device *rdev); - void (*prepare)(struct radeon_device *rdev); - void (*finish)(struct radeon_device *rdev); - void (*init_profile)(struct radeon_device *rdev); - void (*get_dynpm_state)(struct radeon_device *rdev); - uint32_t (*get_engine_clock)(struct radeon_device *rdev); - void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); - uint32_t (*get_memory_clock)(struct radeon_device *rdev); - void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); - int (*get_pcie_lanes)(struct radeon_device *rdev); - void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); - void (*set_clock_gating)(struct radeon_device *rdev, int enable); - } pm; - /* pageflipping */ - struct { - void (*pre_page_flip)(struct radeon_device *rdev, int crtc); - u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base); - void (*post_page_flip)(struct radeon_device *rdev, int crtc); - } pflip; -}; - -/* - * Asic structures - */ -struct r100_gpu_lockup { - unsigned long last_jiffies; - u32 last_cp_rptr; -}; - -struct r100_asic { - const unsigned *reg_safe_bm; - unsigned reg_safe_bm_size; - u32 hdp_cntl; - struct r100_gpu_lockup lockup; -}; - -struct r300_asic { - const unsigned *reg_safe_bm; - unsigned reg_safe_bm_size; - u32 resync_scratch; - u32 hdp_cntl; - struct r100_gpu_lockup lockup; -}; - -struct r600_asic { - unsigned max_pipes; - unsigned max_tile_pipes; - unsigned max_simds; - unsigned max_backends; - unsigned max_gprs; - unsigned max_threads; - unsigned max_stack_entries; - unsigned max_hw_contexts; - unsigned max_gs_threads; - unsigned sx_max_export_size; - unsigned sx_max_export_pos_size; - unsigned sx_max_export_smx_size; - unsigned sq_num_cf_insts; - unsigned tiling_nbanks; - unsigned tiling_npipes; - unsigned tiling_group_size; - unsigned tile_config; - unsigned backend_map; - struct r100_gpu_lockup lockup; -}; - -struct rv770_asic { - unsigned max_pipes; - unsigned max_tile_pipes; - unsigned max_simds; - unsigned max_backends; - unsigned max_gprs; - unsigned max_threads; - unsigned max_stack_entries; - unsigned max_hw_contexts; - unsigned max_gs_threads; - unsigned sx_max_export_size; - unsigned sx_max_export_pos_size; - unsigned sx_max_export_smx_size; - unsigned sq_num_cf_insts; - unsigned sx_num_of_sets; - unsigned sc_prim_fifo_size; - unsigned sc_hiz_tile_fifo_size; - unsigned sc_earlyz_tile_fifo_fize; - unsigned tiling_nbanks; - unsigned tiling_npipes; - unsigned tiling_group_size; - unsigned tile_config; - unsigned backend_map; - struct r100_gpu_lockup lockup; -}; - -struct evergreen_asic { - unsigned num_ses; - unsigned max_pipes; - unsigned max_tile_pipes; - unsigned max_simds; - unsigned max_backends; - unsigned max_gprs; - unsigned max_threads; - unsigned max_stack_entries; - unsigned max_hw_contexts; - unsigned max_gs_threads; - unsigned sx_max_export_size; - unsigned sx_max_export_pos_size; - unsigned sx_max_export_smx_size; - unsigned sq_num_cf_insts; - unsigned sx_num_of_sets; - unsigned sc_prim_fifo_size; - unsigned sc_hiz_tile_fifo_size; - unsigned sc_earlyz_tile_fifo_size; - unsigned tiling_nbanks; - unsigned tiling_npipes; - unsigned tiling_group_size; - unsigned tile_config; - unsigned backend_map; - struct r100_gpu_lockup lockup; -}; - -struct cayman_asic { - unsigned max_shader_engines; - unsigned max_pipes_per_simd; - unsigned max_tile_pipes; - unsigned max_simds_per_se; - unsigned max_backends_per_se; - unsigned max_texture_channel_caches; - unsigned max_gprs; - unsigned max_threads; - unsigned max_gs_threads; - unsigned max_stack_entries; - unsigned sx_num_of_sets; - unsigned sx_max_export_size; - unsigned sx_max_export_pos_size; - unsigned sx_max_export_smx_size; - unsigned max_hw_contexts; - unsigned sq_num_cf_insts; - unsigned sc_prim_fifo_size; - unsigned sc_hiz_tile_fifo_size; - unsigned sc_earlyz_tile_fifo_size; - - unsigned num_shader_engines; - unsigned num_shader_pipes_per_simd; - unsigned num_tile_pipes; - unsigned num_simds_per_se; - unsigned num_backends_per_se; - unsigned backend_disable_mask_per_asic; - unsigned backend_map; - unsigned num_texture_channel_caches; - unsigned mem_max_burst_length_bytes; - unsigned mem_row_size_in_kb; - unsigned shader_engine_tile_size; - unsigned num_gpus; - unsigned multi_gpu_tile_size; - - unsigned tile_config; - struct r100_gpu_lockup lockup; -}; - -struct si_asic { - unsigned max_shader_engines; - unsigned max_pipes_per_simd; - unsigned max_tile_pipes; - unsigned max_simds_per_se; - unsigned max_backends_per_se; - unsigned max_texture_channel_caches; - unsigned max_gprs; - unsigned max_gs_threads; - unsigned max_hw_contexts; - unsigned sc_prim_fifo_size_frontend; - unsigned sc_prim_fifo_size_backend; - unsigned sc_hiz_tile_fifo_size; - unsigned sc_earlyz_tile_fifo_size; - - unsigned num_shader_engines; - unsigned num_tile_pipes; - unsigned num_backends_per_se; - unsigned backend_disable_mask_per_asic; - unsigned backend_map; - unsigned num_texture_channel_caches; - unsigned mem_max_burst_length_bytes; - unsigned mem_row_size_in_kb; - unsigned shader_engine_tile_size; - unsigned num_gpus; - unsigned multi_gpu_tile_size; - - unsigned tile_config; - struct r100_gpu_lockup lockup; -}; - -union radeon_asic_config { - struct r300_asic r300; - struct r100_asic r100; - struct r600_asic r600; - struct rv770_asic rv770; - struct evergreen_asic evergreen; - struct cayman_asic cayman; - struct si_asic si; -}; - -/* - * asic initizalization from radeon_asic.c - */ -void radeon_agp_disable(struct radeon_device *rdev); -int radeon_asic_init(struct radeon_device *rdev); - - -/* - * IOCTL. - */ -int radeon_gem_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_va_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); -int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); -int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp); - -/* VRAM scratch page for HDP bug, default vram page */ -struct r600_vram_scratch { - struct radeon_bo *robj; - volatile uint32_t *ptr; - u64 gpu_addr; -}; - - -/* - * Core structure, functions and helpers. - */ -typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t); -typedef void (*radeon_wreg_t)(struct radeon_device*, uint32_t, uint32_t); - -struct radeon_device { - struct device *dev; - struct drm_device *ddev; - struct pci_dev *pdev; - /* ASIC */ - union radeon_asic_config config; - enum radeon_family family; - unsigned long flags; - int usec_timeout; - enum radeon_pll_errata pll_errata; - int num_gb_pipes; - int num_z_pipes; - int disp_priority; - /* BIOS */ - uint8_t *bios; - bool is_atom_bios; - uint16_t bios_header_start; - struct radeon_bo *stollen_vga_memory; - /* Register mmio */ - resource_size_t rmmio_base; - resource_size_t rmmio_size; - void __iomem *rmmio; - radeon_rreg_t mc_rreg; - radeon_wreg_t mc_wreg; - radeon_rreg_t pll_rreg; - radeon_wreg_t pll_wreg; - uint32_t pcie_reg_mask; - radeon_rreg_t pciep_rreg; - radeon_wreg_t pciep_wreg; - /* io port */ - void __iomem *rio_mem; - resource_size_t rio_mem_size; - struct radeon_clock clock; - struct radeon_mc mc; - struct radeon_gart gart; - struct radeon_mode_info mode_info; - struct radeon_scratch scratch; - struct radeon_mman mman; - rwlock_t fence_lock; - struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; - struct radeon_semaphore_driver semaphore_drv; - struct radeon_ring ring[RADEON_NUM_RINGS]; - struct radeon_ib_pool ib_pool; - struct radeon_irq irq; - struct radeon_asic *asic; - struct radeon_gem gem; - struct radeon_pm pm; - uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; - struct radeon_mutex cs_mutex; - struct radeon_wb wb; - struct radeon_dummy_page dummy_page; - bool gpu_lockup; - bool shutdown; - bool suspend; - bool need_dma32; - bool accel_working; - struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; - const struct firmware *me_fw; /* all family ME firmware */ - const struct firmware *pfp_fw; /* r6/700 PFP firmware */ - const struct firmware *rlc_fw; /* r6/700 RLC firmware */ - const struct firmware *mc_fw; /* NI MC firmware */ - const struct firmware *ce_fw; /* SI CE firmware */ - struct r600_blit r600_blit; - struct r600_vram_scratch vram_scratch; - int msi_enabled; /* msi enabled */ - struct r600_ih ih; /* r6/700 interrupt ring */ - struct si_rlc rlc; - struct work_struct hotplug_work; - int num_crtc; /* number of crtcs */ - struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ - struct mutex vram_mutex; - - /* audio stuff */ - bool audio_enabled; - struct timer_list audio_timer; - int audio_channels; - int audio_rate; - int audio_bits_per_sample; - uint8_t audio_status_bits; - uint8_t audio_category_code; - - struct notifier_block acpi_nb; - /* only one userspace can use Hyperz features or CMASK at a time */ - struct drm_file *hyperz_filp; - struct drm_file *cmask_filp; - /* i2c buses */ - struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS]; - /* debugfs */ - struct radeon_debugfs debugfs[RADEON_DEBUGFS_MAX_COMPONENTS]; - unsigned debugfs_count; - /* virtual memory */ - struct radeon_vm_manager vm_manager; -}; - -int radeon_device_init(struct radeon_device *rdev, - struct drm_device *ddev, - struct pci_dev *pdev, - uint32_t flags); -void radeon_device_fini(struct radeon_device *rdev); -int radeon_gpu_wait_for_idle(struct radeon_device *rdev); - -uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); -void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -u32 r100_io_rreg(struct radeon_device *rdev, u32 reg); -void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v); - -/* - * Cast helper - */ -#define to_radeon_fence(p) ((struct radeon_fence *)(p)) - -/* - * Registers read & write functions. - */ -#define RREG8(reg) readb((rdev->rmmio) + (reg)) -#define WREG8(reg, v) writeb(v, (rdev->rmmio) + (reg)) -#define RREG16(reg) readw((rdev->rmmio) + (reg)) -#define WREG16(reg, v) writew(v, (rdev->rmmio) + (reg)) -#define RREG32(reg) r100_mm_rreg(rdev, (reg)) -#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) -#define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) -#define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) -#define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) -#define RREG32_PLL(reg) rdev->pll_rreg(rdev, (reg)) -#define WREG32_PLL(reg, v) rdev->pll_wreg(rdev, (reg), (v)) -#define RREG32_MC(reg) rdev->mc_rreg(rdev, (reg)) -#define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) -#define RREG32_PCIE(reg) rv370_pcie_rreg(rdev, (reg)) -#define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v)) -#define RREG32_PCIE_P(reg) rdev->pciep_rreg(rdev, (reg)) -#define WREG32_PCIE_P(reg, v) rdev->pciep_wreg(rdev, (reg), (v)) -#define WREG32_P(reg, val, mask) \ - do { \ - uint32_t tmp_ = RREG32(reg); \ - tmp_ &= (mask); \ - tmp_ |= ((val) & ~(mask)); \ - WREG32(reg, tmp_); \ - } while (0) -#define WREG32_PLL_P(reg, val, mask) \ - do { \ - uint32_t tmp_ = RREG32_PLL(reg); \ - tmp_ &= (mask); \ - tmp_ |= ((val) & ~(mask)); \ - WREG32_PLL(reg, tmp_); \ - } while (0) -#define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) -#define RREG32_IO(reg) r100_io_rreg(rdev, (reg)) -#define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v)) - -/* - * Indirect registers accessor - */ -static inline uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg) -{ - uint32_t r; - - WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); - r = RREG32(RADEON_PCIE_DATA); - return r; -} - -static inline void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); - WREG32(RADEON_PCIE_DATA, (v)); -} - -void r100_pll_errata_after_index(struct radeon_device *rdev); - - -/* - * ASICs helpers. - */ -#define ASIC_IS_RN50(rdev) ((rdev->pdev->device == 0x515e) || \ - (rdev->pdev->device == 0x5969)) -#define ASIC_IS_RV100(rdev) ((rdev->family == CHIP_RV100) || \ - (rdev->family == CHIP_RV200) || \ - (rdev->family == CHIP_RS100) || \ - (rdev->family == CHIP_RS200) || \ - (rdev->family == CHIP_RV250) || \ - (rdev->family == CHIP_RV280) || \ - (rdev->family == CHIP_RS300)) -#define ASIC_IS_R300(rdev) ((rdev->family == CHIP_R300) || \ - (rdev->family == CHIP_RV350) || \ - (rdev->family == CHIP_R350) || \ - (rdev->family == CHIP_RV380) || \ - (rdev->family == CHIP_R420) || \ - (rdev->family == CHIP_R423) || \ - (rdev->family == CHIP_RV410) || \ - (rdev->family == CHIP_RS400) || \ - (rdev->family == CHIP_RS480)) -#define ASIC_IS_X2(rdev) ((rdev->ddev->pdev->device == 0x9441) || \ - (rdev->ddev->pdev->device == 0x9443) || \ - (rdev->ddev->pdev->device == 0x944B) || \ - (rdev->ddev->pdev->device == 0x9506) || \ - (rdev->ddev->pdev->device == 0x9509) || \ - (rdev->ddev->pdev->device == 0x950F) || \ - (rdev->ddev->pdev->device == 0x689C) || \ - (rdev->ddev->pdev->device == 0x689D)) -#define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600)) -#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \ - (rdev->family == CHIP_RS690) || \ - (rdev->family == CHIP_RS740) || \ - (rdev->family >= CHIP_R600)) -#define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) -#define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) -#define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) -#define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM) && \ - (rdev->flags & RADEON_IS_IGP)) -#define ASIC_IS_DCE5(rdev) ((rdev->family >= CHIP_BARTS)) -#define ASIC_IS_DCE6(rdev) ((rdev->family >= CHIP_ARUBA)) -#define ASIC_IS_DCE61(rdev) ((rdev->family >= CHIP_ARUBA) && \ - (rdev->flags & RADEON_IS_IGP)) - -/* - * BIOS helpers. - */ -#define RBIOS8(i) (rdev->bios[i]) -#define RBIOS16(i) (RBIOS8(i) | (RBIOS8((i)+1) << 8)) -#define RBIOS32(i) ((RBIOS16(i)) | (RBIOS16((i)+2) << 16)) - -int radeon_combios_init(struct radeon_device *rdev); -void radeon_combios_fini(struct radeon_device *rdev); -int radeon_atombios_init(struct radeon_device *rdev); -void radeon_atombios_fini(struct radeon_device *rdev); - - -/* - * RING helpers. - */ -#if DRM_DEBUG_CODE == 0 -static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) -{ - ring->ring[ring->wptr++] = v; - ring->wptr &= ring->ptr_mask; - ring->count_dw--; - ring->ring_free_dw--; -} -#else -/* With debugging this is just too big to inline */ -void radeon_ring_write(struct radeon_ring *ring, uint32_t v); -#endif - -/* - * ASICs macro. - */ -#define radeon_init(rdev) (rdev)->asic->init((rdev)) -#define radeon_fini(rdev) (rdev)->asic->fini((rdev)) -#define radeon_resume(rdev) (rdev)->asic->resume((rdev)) -#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) -#define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)].cs_parse((p)) -#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) -#define radeon_gpu_is_lockup(rdev, cp) (rdev)->asic->gpu_is_lockup((rdev), (cp)) -#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) -#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) -#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) -#define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp)) -#define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp)) -#define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) -#define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib)) -#define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib)) -#define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev)) -#define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev)) -#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc)) -#define radeon_fence_ring_emit(rdev, r, fence) (rdev)->asic->ring[(r)].emit_fence((rdev), (fence)) -#define radeon_semaphore_ring_emit(rdev, r, cp, semaphore, emit_wait) (rdev)->asic->ring[(r)].emit_semaphore((rdev), (cp), (semaphore), (emit_wait)) -#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy.blit((rdev), (s), (d), (np), (f)) -#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy.dma((rdev), (s), (d), (np), (f)) -#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy.copy((rdev), (s), (d), (np), (f)) -#define radeon_copy_blit_ring_index(rdev) (rdev)->asic->copy.blit_ring_index -#define radeon_copy_dma_ring_index(rdev) (rdev)->asic->copy.dma_ring_index -#define radeon_copy_ring_index(rdev) (rdev)->asic->copy.copy_ring_index -#define radeon_get_engine_clock(rdev) (rdev)->asic->pm.get_engine_clock((rdev)) -#define radeon_set_engine_clock(rdev, e) (rdev)->asic->pm.set_engine_clock((rdev), (e)) -#define radeon_get_memory_clock(rdev) (rdev)->asic->pm.get_memory_clock((rdev)) -#define radeon_set_memory_clock(rdev, e) (rdev)->asic->pm.set_memory_clock((rdev), (e)) -#define radeon_get_pcie_lanes(rdev) (rdev)->asic->pm.get_pcie_lanes((rdev)) -#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), (l)) -#define radeon_set_clock_gating(rdev, e) (rdev)->asic->pm.set_clock_gating((rdev), (e)) -#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s))) -#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->surface.clear_reg((rdev), (r))) -#define radeon_bandwidth_update(rdev) (rdev)->asic->display.bandwidth_update((rdev)) -#define radeon_hpd_init(rdev) (rdev)->asic->hpd.init((rdev)) -#define radeon_hpd_fini(rdev) (rdev)->asic->hpd.fini((rdev)) -#define radeon_hpd_sense(rdev, h) (rdev)->asic->hpd.sense((rdev), (h)) -#define radeon_hpd_set_polarity(rdev, h) (rdev)->asic->hpd.set_polarity((rdev), (h)) -#define radeon_gui_idle(rdev) (rdev)->asic->gui_idle((rdev)) -#define radeon_pm_misc(rdev) (rdev)->asic->pm.misc((rdev)) -#define radeon_pm_prepare(rdev) (rdev)->asic->pm.prepare((rdev)) -#define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) -#define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) -#define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) -#define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) -#define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) -#define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) -#define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) -#define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) - -/* Common functions */ -/* AGP */ -extern int radeon_gpu_reset(struct radeon_device *rdev); -extern void radeon_agp_disable(struct radeon_device *rdev); -extern int radeon_modeset_init(struct radeon_device *rdev); -extern void radeon_modeset_fini(struct radeon_device *rdev); -extern bool radeon_card_posted(struct radeon_device *rdev); -extern void radeon_update_bandwidth_info(struct radeon_device *rdev); -extern void radeon_update_display_priority(struct radeon_device *rdev); -extern bool radeon_boot_test_post_card(struct radeon_device *rdev); -extern void radeon_scratch_init(struct radeon_device *rdev); -extern void radeon_wb_fini(struct radeon_device *rdev); -extern int radeon_wb_init(struct radeon_device *rdev); -extern void radeon_wb_disable(struct radeon_device *rdev); -extern void radeon_surface_init(struct radeon_device *rdev); -extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); -extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); -extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); -extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); -extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); -extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); -extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); -extern int radeon_resume_kms(struct drm_device *dev); -extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); -extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); - -/* - * vm - */ -int radeon_vm_manager_init(struct radeon_device *rdev); -void radeon_vm_manager_fini(struct radeon_device *rdev); -int radeon_vm_manager_start(struct radeon_device *rdev); -int radeon_vm_manager_suspend(struct radeon_device *rdev); -int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); -void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); -int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); -void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); -int radeon_vm_bo_update_pte(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_bo *bo, - struct ttm_mem_reg *mem); -void radeon_vm_bo_invalidate(struct radeon_device *rdev, - struct radeon_bo *bo); -int radeon_vm_bo_add(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_bo *bo, - uint64_t offset, - uint32_t flags); -int radeon_vm_bo_rmv(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_bo *bo); - - -/* - * R600 vram scratch functions - */ -int r600_vram_scratch_init(struct radeon_device *rdev); -void r600_vram_scratch_fini(struct radeon_device *rdev); - -/* - * r600 cs checking helper - */ -unsigned r600_mip_minify(unsigned size, unsigned level); -bool r600_fmt_is_valid_color(u32 format); -bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family); -int r600_fmt_get_blocksize(u32 format); -int r600_fmt_get_nblocksx(u32 format, u32 w); -int r600_fmt_get_nblocksy(u32 format, u32 h); - -/* - * r600 functions used by radeon_encoder.c - */ -extern void r600_hdmi_enable(struct drm_encoder *encoder); -extern void r600_hdmi_disable(struct drm_encoder *encoder); -extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); - -extern int ni_init_microcode(struct radeon_device *rdev); -extern int ni_mc_load_microcode(struct radeon_device *rdev); - -/* radeon_acpi.c */ -#if defined(CONFIG_ACPI) -extern int radeon_acpi_init(struct radeon_device *rdev); -#else -static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } -#endif - -#include "radeon_object.h" - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_acpi.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_acpi.c deleted file mode 100644 index 3516a608..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_acpi.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "drm_crtc_helper.h" -#include "radeon.h" - -#include - -/* Call the ATIF method - * - * Note: currently we discard the output - */ -static int radeon_atif_call(acpi_handle handle) -{ - acpi_status status; - union acpi_object atif_arg_elements[2]; - struct acpi_object_list atif_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - - atif_arg.count = 2; - atif_arg.pointer = &atif_arg_elements[0]; - - atif_arg_elements[0].type = ACPI_TYPE_INTEGER; - atif_arg_elements[0].integer.value = 0; - atif_arg_elements[1].type = ACPI_TYPE_INTEGER; - atif_arg_elements[1].integer.value = 0; - - status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); - - /* Fail only if calling the method fails and ATIF is supported */ - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", - acpi_format_exception(status)); - kfree(buffer.pointer); - return 1; - } - - kfree(buffer.pointer); - return 0; -} - -/* Call all ACPI methods here */ -int radeon_acpi_init(struct radeon_device *rdev) -{ - acpi_handle handle; - int ret; - - /* Get the device handle */ - handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); - - /* No need to proceed if we're sure that ATIF is not supported */ - if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) - return 0; - - /* Call the ATIF method */ - ret = radeon_atif_call(handle); - if (ret) - return ret; - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_agp.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_agp.c deleted file mode 100644 index bd2f33e5..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_agp.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Dave Airlie - * Jerome Glisse - */ -#include "drmP.h" -#include "drm.h" -#include "radeon.h" -#include "radeon_drm.h" - -#if __OS_HAS_AGP - -struct radeon_agpmode_quirk { - u32 hostbridge_vendor; - u32 hostbridge_device; - u32 chip_vendor; - u32 chip_device; - u32 subsys_vendor; - u32 subsys_device; - u32 default_mode; -}; - -static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { - /* Intel E7505 Memory Controller Hub / RV350 AR [Radeon 9600XT] Needs AGPMode 4 (deb #515326) */ - { PCI_VENDOR_ID_INTEL, 0x2550, PCI_VENDOR_ID_ATI, 0x4152, 0x1458, 0x4038, 4}, - /* Intel 82865G/PE/P DRAM Controller/Host-Hub / Mobility 9800 Needs AGPMode 4 (deb #462590) */ - { PCI_VENDOR_ID_INTEL, 0x2570, PCI_VENDOR_ID_ATI, 0x4a4e, PCI_VENDOR_ID_DELL, 0x5106, 4}, - /* Intel 82865G/PE/P DRAM Controller/Host-Hub / RV280 [Radeon 9200 SE] Needs AGPMode 4 (lp #300304) */ - { PCI_VENDOR_ID_INTEL, 0x2570, PCI_VENDOR_ID_ATI, 0x5964, - 0x148c, 0x2073, 4}, - /* Intel 82855PM Processor to I/O Controller / Mobility M6 LY Needs AGPMode 1 (deb #467235) */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c59, - PCI_VENDOR_ID_IBM, 0x052f, 1}, - /* Intel 82855PM host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #195051) */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e50, - PCI_VENDOR_ID_IBM, 0x0550, 1}, - /* Intel 82855PM host bridge / Mobility M7 needs AGPMode 1 */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c57, - PCI_VENDOR_ID_IBM, 0x0530, 1}, - /* Intel 82855PM host bridge / FireGL Mobility T2 RV350 Needs AGPMode 2 (fdo #20647) */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4e54, - PCI_VENDOR_ID_IBM, 0x054f, 2}, - /* Intel 82855PM host bridge / Mobility M9+ / VaioPCG-V505DX Needs AGPMode 2 (fdo #17928) */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x5c61, - PCI_VENDOR_ID_SONY, 0x816b, 2}, - /* Intel 82855PM Processor to I/O Controller / Mobility M9+ Needs AGPMode 8 (phoronix forum) */ - { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x5c61, - PCI_VENDOR_ID_SONY, 0x8195, 8}, - /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ - { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, - PCI_VENDOR_ID_DELL, 0x00e3, 2}, - /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ - { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, - PCI_VENDOR_ID_DELL, 0x0149, 1}, - /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ - { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, - 0x1025, 0x0061, 1}, - /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #203007) */ - { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, - 0x1025, 0x0064, 1}, - /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (lp #141551) */ - { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, - PCI_VENDOR_ID_ASUSTEK, 0x1942, 1}, - /* Intel 82852/82855 host bridge / Mobility 9600/9700 Needs AGPMode 1 (deb #510208) */ - { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, - 0x10cf, 0x127f, 1}, - /* ASRock K7VT4A+ AGP 8x / ATI Radeon 9250 AGP Needs AGPMode 4 (lp #133192) */ - { 0x1849, 0x3189, PCI_VENDOR_ID_ATI, 0x5960, - 0x1787, 0x5960, 4}, - /* VIA K8M800 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (fdo #12544) */ - { PCI_VENDOR_ID_VIA, 0x0204, PCI_VENDOR_ID_ATI, 0x5960, - 0x17af, 0x2020, 4}, - /* VIA KT880 Host Bridge / RV350 [Radeon 9550] Needs AGPMode 4 (fdo #19981) */ - { PCI_VENDOR_ID_VIA, 0x0269, PCI_VENDOR_ID_ATI, 0x4153, - PCI_VENDOR_ID_ASUSTEK, 0x003c, 4}, - /* VIA VT8363 Host Bridge / R200 QL [Radeon 8500] Needs AGPMode 2 (lp #141551) */ - { PCI_VENDOR_ID_VIA, 0x0305, PCI_VENDOR_ID_ATI, 0x514c, - PCI_VENDOR_ID_ATI, 0x013a, 2}, - /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 (deb #515512) */ - { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_ATI, 0x5960, - PCI_VENDOR_ID_ASUSTEK, 0x004c, 2}, - /* VIA VT82C693A Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 2 */ - { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_ATI, 0x5960, - PCI_VENDOR_ID_ASUSTEK, 0x0054, 2}, - /* VIA VT8377 Host Bridge / R200 QM [Radeon 9100] Needs AGPMode 4 (deb #461144) */ - { PCI_VENDOR_ID_VIA, 0x3189, PCI_VENDOR_ID_ATI, 0x514d, - 0x174b, 0x7149, 4}, - /* VIA VT8377 Host Bridge / RV280 [Radeon 9200 PRO] Needs AGPMode 4 (lp #312693) */ - { PCI_VENDOR_ID_VIA, 0x3189, PCI_VENDOR_ID_ATI, 0x5960, - 0x1462, 0x0380, 4}, - /* VIA VT8377 Host Bridge / RV280 Needs AGPMode 4 (ati ML) */ - { PCI_VENDOR_ID_VIA, 0x3189, PCI_VENDOR_ID_ATI, 0x5964, - 0x148c, 0x2073, 4}, - /* ATI Host Bridge / RV280 [M9+] Needs AGPMode 1 (phoronix forum) */ - { PCI_VENDOR_ID_ATI, 0xcbb2, PCI_VENDOR_ID_ATI, 0x5c61, - PCI_VENDOR_ID_SONY, 0x8175, 1}, - /* HP Host Bridge / R300 [FireGL X1] Needs AGPMode 2 (fdo #7770) */ - { PCI_VENDOR_ID_HP, 0x122e, PCI_VENDOR_ID_ATI, 0x4e47, - PCI_VENDOR_ID_ATI, 0x0152, 2}, - { 0, 0, 0, 0, 0, 0, 0 }, -}; -#endif - -int radeon_agp_init(struct radeon_device *rdev) -{ -#if __OS_HAS_AGP - struct radeon_agpmode_quirk *p = radeon_agpmode_quirk_list; - struct drm_agp_mode mode; - struct drm_agp_info info; - uint32_t agp_status; - int default_mode; - bool is_v3; - int ret; - - /* Acquire AGP. */ - ret = drm_agp_acquire(rdev->ddev); - if (ret) { - DRM_ERROR("Unable to acquire AGP: %d\n", ret); - return ret; - } - - ret = drm_agp_info(rdev->ddev, &info); - if (ret) { - drm_agp_release(rdev->ddev); - DRM_ERROR("Unable to get AGP info: %d\n", ret); - return ret; - } - - if (rdev->ddev->agp->agp_info.aper_size < 32) { - drm_agp_release(rdev->ddev); - dev_warn(rdev->dev, "AGP aperture too small (%zuM) " - "need at least 32M, disabling AGP\n", - rdev->ddev->agp->agp_info.aper_size); - return -EINVAL; - } - - mode.mode = info.mode; - /* chips with the agp to pcie bridge don't have the AGP_STATUS register - * Just use the whatever mode the host sets up. - */ - if (rdev->family <= CHIP_RV350) - agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; - else - agp_status = mode.mode; - is_v3 = !!(agp_status & RADEON_AGPv3_MODE); - - if (is_v3) { - default_mode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; - } else { - if (agp_status & RADEON_AGP_4X_MODE) { - default_mode = 4; - } else if (agp_status & RADEON_AGP_2X_MODE) { - default_mode = 2; - } else { - default_mode = 1; - } - } - - /* Apply AGPMode Quirks */ - while (p && p->chip_device != 0) { - if (info.id_vendor == p->hostbridge_vendor && - info.id_device == p->hostbridge_device && - rdev->pdev->vendor == p->chip_vendor && - rdev->pdev->device == p->chip_device && - rdev->pdev->subsystem_vendor == p->subsys_vendor && - rdev->pdev->subsystem_device == p->subsys_device) { - default_mode = p->default_mode; - } - ++p; - } - - if (radeon_agpmode > 0) { - if ((radeon_agpmode < (is_v3 ? 4 : 1)) || - (radeon_agpmode > (is_v3 ? 8 : 4)) || - (radeon_agpmode & (radeon_agpmode - 1))) { - DRM_ERROR("Illegal AGP Mode: %d (valid %s), leaving at %d\n", - radeon_agpmode, is_v3 ? "4, 8" : "1, 2, 4", - default_mode); - radeon_agpmode = default_mode; - } else { - DRM_INFO("AGP mode requested: %d\n", radeon_agpmode); - } - } else { - radeon_agpmode = default_mode; - } - - mode.mode &= ~RADEON_AGP_MODE_MASK; - if (is_v3) { - switch (radeon_agpmode) { - case 8: - mode.mode |= RADEON_AGPv3_8X_MODE; - break; - case 4: - default: - mode.mode |= RADEON_AGPv3_4X_MODE; - break; - } - } else { - switch (radeon_agpmode) { - case 4: - mode.mode |= RADEON_AGP_4X_MODE; - break; - case 2: - mode.mode |= RADEON_AGP_2X_MODE; - break; - case 1: - default: - mode.mode |= RADEON_AGP_1X_MODE; - break; - } - } - - mode.mode &= ~RADEON_AGP_FW_MODE; /* disable fw */ - ret = drm_agp_enable(rdev->ddev, mode); - if (ret) { - DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode); - drm_agp_release(rdev->ddev); - return ret; - } - - rdev->mc.agp_base = rdev->ddev->agp->agp_info.aper_base; - rdev->mc.gtt_size = rdev->ddev->agp->agp_info.aper_size << 20; - rdev->mc.gtt_start = rdev->mc.agp_base; - rdev->mc.gtt_end = rdev->mc.gtt_start + rdev->mc.gtt_size - 1; - dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", - rdev->mc.gtt_size >> 20, rdev->mc.gtt_start, rdev->mc.gtt_end); - - /* workaround some hw issues */ - if (rdev->family < CHIP_R200) { - WREG32(RADEON_AGP_CNTL, RREG32(RADEON_AGP_CNTL) | 0x000e0000); - } - return 0; -#else - return 0; -#endif -} - -void radeon_agp_resume(struct radeon_device *rdev) -{ -#if __OS_HAS_AGP - int r; - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) - dev_warn(rdev->dev, "radeon AGP reinit failed\n"); - } -#endif -} - -void radeon_agp_fini(struct radeon_device *rdev) -{ -#if __OS_HAS_AGP - if (rdev->ddev->agp && rdev->ddev->agp->acquired) { - drm_agp_release(rdev->ddev); - } -#endif -} - -void radeon_agp_suspend(struct radeon_device *rdev) -{ - radeon_agp_fini(rdev); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.c deleted file mode 100644 index be4dc2ff..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.c +++ /dev/null @@ -1,1748 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ - -#include -#include -#include -#include -#include -#include -#include "radeon_reg.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" - -/* - * Registers accessors functions. - */ -static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) -{ - DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); - BUG_ON(1); - return 0; -} - -static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", - reg, v); - BUG_ON(1); -} - -static void radeon_register_accessor_init(struct radeon_device *rdev) -{ - rdev->mc_rreg = &radeon_invalid_rreg; - rdev->mc_wreg = &radeon_invalid_wreg; - rdev->pll_rreg = &radeon_invalid_rreg; - rdev->pll_wreg = &radeon_invalid_wreg; - rdev->pciep_rreg = &radeon_invalid_rreg; - rdev->pciep_wreg = &radeon_invalid_wreg; - - /* Don't change order as we are overridding accessor. */ - if (rdev->family < CHIP_RV515) { - rdev->pcie_reg_mask = 0xff; - } else { - rdev->pcie_reg_mask = 0x7ff; - } - /* FIXME: not sure here */ - if (rdev->family <= CHIP_R580) { - rdev->pll_rreg = &r100_pll_rreg; - rdev->pll_wreg = &r100_pll_wreg; - } - if (rdev->family >= CHIP_R420) { - rdev->mc_rreg = &r420_mc_rreg; - rdev->mc_wreg = &r420_mc_wreg; - } - if (rdev->family >= CHIP_RV515) { - rdev->mc_rreg = &rv515_mc_rreg; - rdev->mc_wreg = &rv515_mc_wreg; - } - if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { - rdev->mc_rreg = &rs400_mc_rreg; - rdev->mc_wreg = &rs400_mc_wreg; - } - if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { - rdev->mc_rreg = &rs690_mc_rreg; - rdev->mc_wreg = &rs690_mc_wreg; - } - if (rdev->family == CHIP_RS600) { - rdev->mc_rreg = &rs600_mc_rreg; - rdev->mc_wreg = &rs600_mc_wreg; - } - if (rdev->family >= CHIP_R600) { - rdev->pciep_rreg = &r600_pciep_rreg; - rdev->pciep_wreg = &r600_pciep_wreg; - } -} - - -/* helper to disable agp */ -void radeon_agp_disable(struct radeon_device *rdev) -{ - rdev->flags &= ~RADEON_IS_AGP; - if (rdev->family >= CHIP_R600) { - DRM_INFO("Forcing AGP to PCIE mode\n"); - rdev->flags |= RADEON_IS_PCIE; - } else if (rdev->family >= CHIP_RV515 || - rdev->family == CHIP_RV380 || - rdev->family == CHIP_RV410 || - rdev->family == CHIP_R423) { - DRM_INFO("Forcing AGP to PCIE mode\n"); - rdev->flags |= RADEON_IS_PCIE; - rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; - rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; - } else { - DRM_INFO("Forcing AGP to PCI mode\n"); - rdev->flags |= RADEON_IS_PCI; - rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; - rdev->asic->gart.set_page = &r100_pci_gart_set_page; - } - rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; -} - -/* - * ASIC - */ -static struct radeon_asic r100_asic = { - .init = &r100_init, - .fini = &r100_fini, - .suspend = &r100_suspend, - .resume = &r100_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r100_gpu_is_lockup, - .asic_reset = &r100_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &r100_mc_wait_for_idle, - .gart = { - .tlb_flush = &r100_pci_gart_tlb_flush, - .set_page = &r100_pci_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r100_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r100_cs_parse, - .ring_start = &r100_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &r100_irq_set, - .process = &r100_irq_process, - }, - .display = { - .bandwidth_update = &r100_bandwidth_update, - .get_vblank_counter = &r100_get_vblank_counter, - .wait_for_vblank = &r100_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &r100_hpd_init, - .fini = &r100_hpd_fini, - .sense = &r100_hpd_sense, - .set_polarity = &r100_hpd_set_polarity, - }, - .pm = { - .misc = &r100_pm_misc, - .prepare = &r100_pm_prepare, - .finish = &r100_pm_finish, - .init_profile = &r100_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_legacy_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &r100_pre_page_flip, - .page_flip = &r100_page_flip, - .post_page_flip = &r100_post_page_flip, - }, -}; - -static struct radeon_asic r200_asic = { - .init = &r100_init, - .fini = &r100_fini, - .suspend = &r100_suspend, - .resume = &r100_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r100_gpu_is_lockup, - .asic_reset = &r100_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &r100_mc_wait_for_idle, - .gart = { - .tlb_flush = &r100_pci_gart_tlb_flush, - .set_page = &r100_pci_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r100_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r100_cs_parse, - .ring_start = &r100_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &r100_irq_set, - .process = &r100_irq_process, - }, - .display = { - .bandwidth_update = &r100_bandwidth_update, - .get_vblank_counter = &r100_get_vblank_counter, - .wait_for_vblank = &r100_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &r100_hpd_init, - .fini = &r100_hpd_fini, - .sense = &r100_hpd_sense, - .set_polarity = &r100_hpd_set_polarity, - }, - .pm = { - .misc = &r100_pm_misc, - .prepare = &r100_pm_prepare, - .finish = &r100_pm_finish, - .init_profile = &r100_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_legacy_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &r100_pre_page_flip, - .page_flip = &r100_page_flip, - .post_page_flip = &r100_post_page_flip, - }, -}; - -static struct radeon_asic r300_asic = { - .init = &r300_init, - .fini = &r300_fini, - .suspend = &r300_suspend, - .resume = &r300_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &r300_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &r300_mc_wait_for_idle, - .gart = { - .tlb_flush = &r100_pci_gart_tlb_flush, - .set_page = &r100_pci_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &r100_irq_set, - .process = &r100_irq_process, - }, - .display = { - .bandwidth_update = &r100_bandwidth_update, - .get_vblank_counter = &r100_get_vblank_counter, - .wait_for_vblank = &r100_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &r100_hpd_init, - .fini = &r100_hpd_fini, - .sense = &r100_hpd_sense, - .set_polarity = &r100_hpd_set_polarity, - }, - .pm = { - .misc = &r100_pm_misc, - .prepare = &r100_pm_prepare, - .finish = &r100_pm_finish, - .init_profile = &r100_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_legacy_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &r100_pre_page_flip, - .page_flip = &r100_page_flip, - .post_page_flip = &r100_post_page_flip, - }, -}; - -static struct radeon_asic r300_asic_pcie = { - .init = &r300_init, - .fini = &r300_fini, - .suspend = &r300_suspend, - .resume = &r300_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &r300_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &r300_mc_wait_for_idle, - .gart = { - .tlb_flush = &rv370_pcie_gart_tlb_flush, - .set_page = &rv370_pcie_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &r100_irq_set, - .process = &r100_irq_process, - }, - .display = { - .bandwidth_update = &r100_bandwidth_update, - .get_vblank_counter = &r100_get_vblank_counter, - .wait_for_vblank = &r100_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &r100_hpd_init, - .fini = &r100_hpd_fini, - .sense = &r100_hpd_sense, - .set_polarity = &r100_hpd_set_polarity, - }, - .pm = { - .misc = &r100_pm_misc, - .prepare = &r100_pm_prepare, - .finish = &r100_pm_finish, - .init_profile = &r100_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_legacy_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &r100_pre_page_flip, - .page_flip = &r100_page_flip, - .post_page_flip = &r100_post_page_flip, - }, -}; - -static struct radeon_asic r420_asic = { - .init = &r420_init, - .fini = &r420_fini, - .suspend = &r420_suspend, - .resume = &r420_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &r300_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &r300_mc_wait_for_idle, - .gart = { - .tlb_flush = &rv370_pcie_gart_tlb_flush, - .set_page = &rv370_pcie_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &r100_irq_set, - .process = &r100_irq_process, - }, - .display = { - .bandwidth_update = &r100_bandwidth_update, - .get_vblank_counter = &r100_get_vblank_counter, - .wait_for_vblank = &r100_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &r100_hpd_init, - .fini = &r100_hpd_fini, - .sense = &r100_hpd_sense, - .set_polarity = &r100_hpd_set_polarity, - }, - .pm = { - .misc = &r100_pm_misc, - .prepare = &r100_pm_prepare, - .finish = &r100_pm_finish, - .init_profile = &r420_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &r100_pre_page_flip, - .page_flip = &r100_page_flip, - .post_page_flip = &r100_post_page_flip, - }, -}; - -static struct radeon_asic rs400_asic = { - .init = &rs400_init, - .fini = &rs400_fini, - .suspend = &rs400_suspend, - .resume = &rs400_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &r300_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &rs400_mc_wait_for_idle, - .gart = { - .tlb_flush = &rs400_gart_tlb_flush, - .set_page = &rs400_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &r100_irq_set, - .process = &r100_irq_process, - }, - .display = { - .bandwidth_update = &r100_bandwidth_update, - .get_vblank_counter = &r100_get_vblank_counter, - .wait_for_vblank = &r100_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &r100_hpd_init, - .fini = &r100_hpd_fini, - .sense = &r100_hpd_sense, - .set_polarity = &r100_hpd_set_polarity, - }, - .pm = { - .misc = &r100_pm_misc, - .prepare = &r100_pm_prepare, - .finish = &r100_pm_finish, - .init_profile = &r100_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_legacy_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &r100_pre_page_flip, - .page_flip = &r100_page_flip, - .post_page_flip = &r100_post_page_flip, - }, -}; - -static struct radeon_asic rs600_asic = { - .init = &rs600_init, - .fini = &rs600_fini, - .suspend = &rs600_suspend, - .resume = &rs600_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &rs600_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &rs600_mc_wait_for_idle, - .gart = { - .tlb_flush = &rs600_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &rs600_irq_set, - .process = &rs600_irq_process, - }, - .display = { - .bandwidth_update = &rs600_bandwidth_update, - .get_vblank_counter = &rs600_get_vblank_counter, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &rs600_hpd_init, - .fini = &rs600_hpd_fini, - .sense = &rs600_hpd_sense, - .set_polarity = &rs600_hpd_set_polarity, - }, - .pm = { - .misc = &rs600_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &r420_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_atom_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rs600_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic rs690_asic = { - .init = &rs690_init, - .fini = &rs690_fini, - .suspend = &rs690_suspend, - .resume = &rs690_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &rs600_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &rs690_mc_wait_for_idle, - .gart = { - .tlb_flush = &rs400_gart_tlb_flush, - .set_page = &rs400_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &rs600_irq_set, - .process = &rs600_irq_process, - }, - .display = { - .get_vblank_counter = &rs600_get_vblank_counter, - .bandwidth_update = &rs690_bandwidth_update, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r200_copy_dma, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &rs600_hpd_init, - .fini = &rs600_hpd_fini, - .sense = &rs600_hpd_sense, - .set_polarity = &rs600_hpd_set_polarity, - }, - .pm = { - .misc = &rs600_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &r420_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_atom_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rs600_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic rv515_asic = { - .init = &rv515_init, - .fini = &rv515_fini, - .suspend = &rv515_suspend, - .resume = &rv515_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &rs600_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &rv515_mc_wait_for_idle, - .gart = { - .tlb_flush = &rv370_pcie_gart_tlb_flush, - .set_page = &rv370_pcie_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &rv515_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &rs600_irq_set, - .process = &rs600_irq_process, - }, - .display = { - .get_vblank_counter = &rs600_get_vblank_counter, - .bandwidth_update = &rv515_bandwidth_update, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &rs600_hpd_init, - .fini = &rs600_hpd_fini, - .sense = &rs600_hpd_sense, - .set_polarity = &rs600_hpd_set_polarity, - }, - .pm = { - .misc = &rs600_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &r420_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rs600_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic r520_asic = { - .init = &r520_init, - .fini = &rv515_fini, - .suspend = &rv515_suspend, - .resume = &r520_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_is_lockup = &r300_gpu_is_lockup, - .asic_reset = &rs600_asic_reset, - .ioctl_wait_idle = NULL, - .gui_idle = &r100_gui_idle, - .mc_wait_for_idle = &r520_mc_wait_for_idle, - .gart = { - .tlb_flush = &rv370_pcie_gart_tlb_flush, - .set_page = &rv370_pcie_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r100_ring_ib_execute, - .emit_fence = &r300_fence_ring_emit, - .emit_semaphore = &r100_semaphore_ring_emit, - .cs_parse = &r300_cs_parse, - .ring_start = &rv515_ring_start, - .ring_test = &r100_ring_test, - .ib_test = &r100_ib_test, - } - }, - .irq = { - .set = &rs600_irq_set, - .process = &rs600_irq_process, - }, - .display = { - .bandwidth_update = &rv515_bandwidth_update, - .get_vblank_counter = &rs600_get_vblank_counter, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r100_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = &r200_copy_dma, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r100_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r100_set_surface_reg, - .clear_reg = r100_clear_surface_reg, - }, - .hpd = { - .init = &rs600_hpd_init, - .fini = &rs600_hpd_fini, - .sense = &rs600_hpd_sense, - .set_polarity = &rs600_hpd_set_polarity, - }, - .pm = { - .misc = &rs600_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &r420_pm_init_profile, - .get_dynpm_state = &r100_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rs600_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic r600_asic = { - .init = &r600_init, - .fini = &r600_fini, - .suspend = &r600_suspend, - .resume = &r600_resume, - .vga_set_state = &r600_vga_set_state, - .gpu_is_lockup = &r600_gpu_is_lockup, - .asic_reset = &r600_asic_reset, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &r600_mc_wait_for_idle, - .gart = { - .tlb_flush = &r600_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r600_ring_ib_execute, - .emit_fence = &r600_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &r600_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &r600_irq_set, - .process = &r600_irq_process, - }, - .display = { - .bandwidth_update = &rv515_bandwidth_update, - .get_vblank_counter = &rs600_get_vblank_counter, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &r600_hpd_init, - .fini = &r600_hpd_fini, - .sense = &r600_hpd_sense, - .set_polarity = &r600_hpd_set_polarity, - }, - .pm = { - .misc = &r600_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &r600_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &r600_get_pcie_lanes, - .set_pcie_lanes = &r600_set_pcie_lanes, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rs600_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic rs780_asic = { - .init = &r600_init, - .fini = &r600_fini, - .suspend = &r600_suspend, - .resume = &r600_resume, - .gpu_is_lockup = &r600_gpu_is_lockup, - .vga_set_state = &r600_vga_set_state, - .asic_reset = &r600_asic_reset, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &r600_mc_wait_for_idle, - .gart = { - .tlb_flush = &r600_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r600_ring_ib_execute, - .emit_fence = &r600_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &r600_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &r600_irq_set, - .process = &r600_irq_process, - }, - .display = { - .bandwidth_update = &rs690_bandwidth_update, - .get_vblank_counter = &rs600_get_vblank_counter, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &r600_hpd_init, - .fini = &r600_hpd_fini, - .sense = &r600_hpd_sense, - .set_polarity = &r600_hpd_set_polarity, - }, - .pm = { - .misc = &r600_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &rs780_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = NULL, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rs600_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic rv770_asic = { - .init = &rv770_init, - .fini = &rv770_fini, - .suspend = &rv770_suspend, - .resume = &rv770_resume, - .asic_reset = &r600_asic_reset, - .gpu_is_lockup = &r600_gpu_is_lockup, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &r600_mc_wait_for_idle, - .gart = { - .tlb_flush = &r600_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &r600_ring_ib_execute, - .emit_fence = &r600_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &r600_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &r600_irq_set, - .process = &r600_irq_process, - }, - .display = { - .bandwidth_update = &rv515_bandwidth_update, - .get_vblank_counter = &rs600_get_vblank_counter, - .wait_for_vblank = &avivo_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &r600_hpd_init, - .fini = &r600_hpd_fini, - .sense = &r600_hpd_sense, - .set_polarity = &r600_hpd_set_polarity, - }, - .pm = { - .misc = &rv770_pm_misc, - .prepare = &rs600_pm_prepare, - .finish = &rs600_pm_finish, - .init_profile = &r600_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &r600_get_pcie_lanes, - .set_pcie_lanes = &r600_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - }, - .pflip = { - .pre_page_flip = &rs600_pre_page_flip, - .page_flip = &rv770_page_flip, - .post_page_flip = &rs600_post_page_flip, - }, -}; - -static struct radeon_asic evergreen_asic = { - .init = &evergreen_init, - .fini = &evergreen_fini, - .suspend = &evergreen_suspend, - .resume = &evergreen_resume, - .gpu_is_lockup = &evergreen_gpu_is_lockup, - .asic_reset = &evergreen_asic_reset, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .gart = { - .tlb_flush = &evergreen_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &evergreen_ring_ib_execute, - .emit_fence = &r600_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &evergreen_irq_set, - .process = &evergreen_irq_process, - }, - .display = { - .bandwidth_update = &evergreen_bandwidth_update, - .get_vblank_counter = &evergreen_get_vblank_counter, - .wait_for_vblank = &dce4_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &evergreen_hpd_init, - .fini = &evergreen_hpd_fini, - .sense = &evergreen_hpd_sense, - .set_polarity = &evergreen_hpd_set_polarity, - }, - .pm = { - .misc = &evergreen_pm_misc, - .prepare = &evergreen_pm_prepare, - .finish = &evergreen_pm_finish, - .init_profile = &r600_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &r600_get_pcie_lanes, - .set_pcie_lanes = &r600_set_pcie_lanes, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &evergreen_pre_page_flip, - .page_flip = &evergreen_page_flip, - .post_page_flip = &evergreen_post_page_flip, - }, -}; - -static struct radeon_asic sumo_asic = { - .init = &evergreen_init, - .fini = &evergreen_fini, - .suspend = &evergreen_suspend, - .resume = &evergreen_resume, - .gpu_is_lockup = &evergreen_gpu_is_lockup, - .asic_reset = &evergreen_asic_reset, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .gart = { - .tlb_flush = &evergreen_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &evergreen_ring_ib_execute, - .emit_fence = &r600_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - }, - .irq = { - .set = &evergreen_irq_set, - .process = &evergreen_irq_process, - }, - .display = { - .bandwidth_update = &evergreen_bandwidth_update, - .get_vblank_counter = &evergreen_get_vblank_counter, - .wait_for_vblank = &dce4_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &evergreen_hpd_init, - .fini = &evergreen_hpd_fini, - .sense = &evergreen_hpd_sense, - .set_polarity = &evergreen_hpd_set_polarity, - }, - .pm = { - .misc = &evergreen_pm_misc, - .prepare = &evergreen_pm_prepare, - .finish = &evergreen_pm_finish, - .init_profile = &sumo_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = NULL, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &evergreen_pre_page_flip, - .page_flip = &evergreen_page_flip, - .post_page_flip = &evergreen_post_page_flip, - }, -}; - -static struct radeon_asic btc_asic = { - .init = &evergreen_init, - .fini = &evergreen_fini, - .suspend = &evergreen_suspend, - .resume = &evergreen_resume, - .gpu_is_lockup = &evergreen_gpu_is_lockup, - .asic_reset = &evergreen_asic_reset, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .gart = { - .tlb_flush = &evergreen_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &evergreen_ring_ib_execute, - .emit_fence = &r600_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &evergreen_irq_set, - .process = &evergreen_irq_process, - }, - .display = { - .bandwidth_update = &evergreen_bandwidth_update, - .get_vblank_counter = &evergreen_get_vblank_counter, - .wait_for_vblank = &dce4_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &evergreen_hpd_init, - .fini = &evergreen_hpd_fini, - .sense = &evergreen_hpd_sense, - .set_polarity = &evergreen_hpd_set_polarity, - }, - .pm = { - .misc = &evergreen_pm_misc, - .prepare = &evergreen_pm_prepare, - .finish = &evergreen_pm_finish, - .init_profile = &r600_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &evergreen_pre_page_flip, - .page_flip = &evergreen_page_flip, - .post_page_flip = &evergreen_post_page_flip, - }, -}; - -static const struct radeon_vm_funcs cayman_vm_funcs = { - .init = &cayman_vm_init, - .fini = &cayman_vm_fini, - .bind = &cayman_vm_bind, - .unbind = &cayman_vm_unbind, - .tlb_flush = &cayman_vm_tlb_flush, - .page_flags = &cayman_vm_page_flags, - .set_page = &cayman_vm_set_page, -}; - -static struct radeon_asic cayman_asic = { - .init = &cayman_init, - .fini = &cayman_fini, - .suspend = &cayman_suspend, - .resume = &cayman_resume, - .gpu_is_lockup = &cayman_gpu_is_lockup, - .asic_reset = &cayman_asic_reset, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .gart = { - .tlb_flush = &cayman_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &cayman_ring_ib_execute, - .ib_parse = &evergreen_ib_parse, - .emit_fence = &cayman_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - [CAYMAN_RING_TYPE_CP1_INDEX] = { - .ib_execute = &cayman_ring_ib_execute, - .ib_parse = &evergreen_ib_parse, - .emit_fence = &cayman_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - [CAYMAN_RING_TYPE_CP2_INDEX] = { - .ib_execute = &cayman_ring_ib_execute, - .ib_parse = &evergreen_ib_parse, - .emit_fence = &cayman_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &evergreen_irq_set, - .process = &evergreen_irq_process, - }, - .display = { - .bandwidth_update = &evergreen_bandwidth_update, - .get_vblank_counter = &evergreen_get_vblank_counter, - .wait_for_vblank = &dce4_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &evergreen_hpd_init, - .fini = &evergreen_hpd_fini, - .sense = &evergreen_hpd_sense, - .set_polarity = &evergreen_hpd_set_polarity, - }, - .pm = { - .misc = &evergreen_pm_misc, - .prepare = &evergreen_pm_prepare, - .finish = &evergreen_pm_finish, - .init_profile = &r600_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &evergreen_pre_page_flip, - .page_flip = &evergreen_page_flip, - .post_page_flip = &evergreen_post_page_flip, - }, -}; - -static struct radeon_asic trinity_asic = { - .init = &cayman_init, - .fini = &cayman_fini, - .suspend = &cayman_suspend, - .resume = &cayman_resume, - .gpu_is_lockup = &cayman_gpu_is_lockup, - .asic_reset = &cayman_asic_reset, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .gart = { - .tlb_flush = &cayman_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &cayman_ring_ib_execute, - .ib_parse = &evergreen_ib_parse, - .emit_fence = &cayman_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - [CAYMAN_RING_TYPE_CP1_INDEX] = { - .ib_execute = &cayman_ring_ib_execute, - .ib_parse = &evergreen_ib_parse, - .emit_fence = &cayman_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - [CAYMAN_RING_TYPE_CP2_INDEX] = { - .ib_execute = &cayman_ring_ib_execute, - .ib_parse = &evergreen_ib_parse, - .emit_fence = &cayman_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = &evergreen_cs_parse, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &evergreen_irq_set, - .process = &evergreen_irq_process, - }, - .display = { - .bandwidth_update = &dce6_bandwidth_update, - .get_vblank_counter = &evergreen_get_vblank_counter, - .wait_for_vblank = &dce4_wait_for_vblank, - }, - .copy = { - .blit = &r600_copy_blit, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = &r600_copy_blit, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &evergreen_hpd_init, - .fini = &evergreen_hpd_fini, - .sense = &evergreen_hpd_sense, - .set_polarity = &evergreen_hpd_set_polarity, - }, - .pm = { - .misc = &evergreen_pm_misc, - .prepare = &evergreen_pm_prepare, - .finish = &evergreen_pm_finish, - .init_profile = &sumo_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = NULL, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &evergreen_pre_page_flip, - .page_flip = &evergreen_page_flip, - .post_page_flip = &evergreen_post_page_flip, - }, -}; - -static const struct radeon_vm_funcs si_vm_funcs = { - .init = &si_vm_init, - .fini = &si_vm_fini, - .bind = &si_vm_bind, - .unbind = &si_vm_unbind, - .tlb_flush = &si_vm_tlb_flush, - .page_flags = &cayman_vm_page_flags, - .set_page = &cayman_vm_set_page, -}; - -static struct radeon_asic si_asic = { - .init = &si_init, - .fini = &si_fini, - .suspend = &si_suspend, - .resume = &si_resume, - .gpu_is_lockup = &si_gpu_is_lockup, - .asic_reset = &si_asic_reset, - .vga_set_state = &r600_vga_set_state, - .ioctl_wait_idle = r600_ioctl_wait_idle, - .gui_idle = &r600_gui_idle, - .mc_wait_for_idle = &evergreen_mc_wait_for_idle, - .gart = { - .tlb_flush = &si_pcie_gart_tlb_flush, - .set_page = &rs600_gart_set_page, - }, - .ring = { - [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &si_ring_ib_execute, - .ib_parse = &si_ib_parse, - .emit_fence = &si_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = NULL, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - [CAYMAN_RING_TYPE_CP1_INDEX] = { - .ib_execute = &si_ring_ib_execute, - .ib_parse = &si_ib_parse, - .emit_fence = &si_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = NULL, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - }, - [CAYMAN_RING_TYPE_CP2_INDEX] = { - .ib_execute = &si_ring_ib_execute, - .ib_parse = &si_ib_parse, - .emit_fence = &si_fence_ring_emit, - .emit_semaphore = &r600_semaphore_ring_emit, - .cs_parse = NULL, - .ring_test = &r600_ring_test, - .ib_test = &r600_ib_test, - } - }, - .irq = { - .set = &si_irq_set, - .process = &si_irq_process, - }, - .display = { - .bandwidth_update = &dce6_bandwidth_update, - .get_vblank_counter = &evergreen_get_vblank_counter, - .wait_for_vblank = &dce4_wait_for_vblank, - }, - .copy = { - .blit = NULL, - .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .dma = NULL, - .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, - .copy = NULL, - .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, - }, - .surface = { - .set_reg = r600_set_surface_reg, - .clear_reg = r600_clear_surface_reg, - }, - .hpd = { - .init = &evergreen_hpd_init, - .fini = &evergreen_hpd_fini, - .sense = &evergreen_hpd_sense, - .set_polarity = &evergreen_hpd_set_polarity, - }, - .pm = { - .misc = &evergreen_pm_misc, - .prepare = &evergreen_pm_prepare, - .finish = &evergreen_pm_finish, - .init_profile = &sumo_pm_init_profile, - .get_dynpm_state = &r600_pm_get_dynpm_state, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - }, - .pflip = { - .pre_page_flip = &evergreen_pre_page_flip, - .page_flip = &evergreen_page_flip, - .post_page_flip = &evergreen_post_page_flip, - }, -}; - -int radeon_asic_init(struct radeon_device *rdev) -{ - radeon_register_accessor_init(rdev); - - /* set the number of crtcs */ - if (rdev->flags & RADEON_SINGLE_CRTC) - rdev->num_crtc = 1; - else - rdev->num_crtc = 2; - - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - rdev->asic = &r100_asic; - break; - case CHIP_R200: - case CHIP_RV250: - case CHIP_RS300: - case CHIP_RV280: - rdev->asic = &r200_asic; - break; - case CHIP_R300: - case CHIP_R350: - case CHIP_RV350: - case CHIP_RV380: - if (rdev->flags & RADEON_IS_PCIE) - rdev->asic = &r300_asic_pcie; - else - rdev->asic = &r300_asic; - break; - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - rdev->asic = &r420_asic; - /* handle macs */ - if (rdev->bios == NULL) { - rdev->asic->pm.get_engine_clock = &radeon_legacy_get_engine_clock; - rdev->asic->pm.set_engine_clock = &radeon_legacy_set_engine_clock; - rdev->asic->pm.get_memory_clock = &radeon_legacy_get_memory_clock; - rdev->asic->pm.set_memory_clock = NULL; - } - break; - case CHIP_RS400: - case CHIP_RS480: - rdev->asic = &rs400_asic; - break; - case CHIP_RS600: - rdev->asic = &rs600_asic; - break; - case CHIP_RS690: - case CHIP_RS740: - rdev->asic = &rs690_asic; - break; - case CHIP_RV515: - rdev->asic = &rv515_asic; - break; - case CHIP_R520: - case CHIP_RV530: - case CHIP_RV560: - case CHIP_RV570: - case CHIP_R580: - rdev->asic = &r520_asic; - break; - case CHIP_R600: - case CHIP_RV610: - case CHIP_RV630: - case CHIP_RV620: - case CHIP_RV635: - case CHIP_RV670: - rdev->asic = &r600_asic; - break; - case CHIP_RS780: - case CHIP_RS880: - rdev->asic = &rs780_asic; - break; - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - case CHIP_RV740: - rdev->asic = &rv770_asic; - break; - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_JUNIPER: - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - /* set num crtcs */ - if (rdev->family == CHIP_CEDAR) - rdev->num_crtc = 4; - else - rdev->num_crtc = 6; - rdev->asic = &evergreen_asic; - break; - case CHIP_PALM: - case CHIP_SUMO: - case CHIP_SUMO2: - rdev->asic = &sumo_asic; - break; - case CHIP_BARTS: - case CHIP_TURKS: - case CHIP_CAICOS: - /* set num crtcs */ - if (rdev->family == CHIP_CAICOS) - rdev->num_crtc = 4; - else - rdev->num_crtc = 6; - rdev->asic = &btc_asic; - break; - case CHIP_CAYMAN: - rdev->asic = &cayman_asic; - /* set num crtcs */ - rdev->num_crtc = 6; - rdev->vm_manager.funcs = &cayman_vm_funcs; - break; - case CHIP_ARUBA: - rdev->asic = &trinity_asic; - /* set num crtcs */ - rdev->num_crtc = 4; - rdev->vm_manager.funcs = &cayman_vm_funcs; - break; - case CHIP_TAHITI: - case CHIP_PITCAIRN: - case CHIP_VERDE: - rdev->asic = &si_asic; - /* set num crtcs */ - rdev->num_crtc = 6; - rdev->vm_manager.funcs = &si_vm_funcs; - break; - default: - /* FIXME: not supported yet */ - return -EINVAL; - } - - if (rdev->flags & RADEON_IS_IGP) { - rdev->asic->pm.get_memory_clock = NULL; - rdev->asic->pm.set_memory_clock = NULL; - } - - return 0; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.h deleted file mode 100644 index 3d9f9f1d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_asic.h +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RADEON_ASIC_H__ -#define __RADEON_ASIC_H__ - -/* - * common functions - */ -uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); -void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); -uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev); -void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); - -uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); -void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); -uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev); -void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); -void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); - -/* - * r100,rv100,rs100,rv200,rs200 - */ -struct r100_mc_save { - u32 GENMO_WT; - u32 CRTC_EXT_CNTL; - u32 CRTC_GEN_CNTL; - u32 CRTC2_GEN_CNTL; - u32 CUR_OFFSET; - u32 CUR2_OFFSET; -}; -int r100_init(struct radeon_device *rdev); -void r100_fini(struct radeon_device *rdev); -int r100_suspend(struct radeon_device *rdev); -int r100_resume(struct radeon_device *rdev); -void r100_vga_set_state(struct radeon_device *rdev, bool state); -bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int r100_asic_reset(struct radeon_device *rdev); -u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); -void r100_pci_gart_tlb_flush(struct radeon_device *rdev); -int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); -int r100_irq_set(struct radeon_device *rdev); -int r100_irq_process(struct radeon_device *rdev); -void r100_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); -void r100_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *cp, - struct radeon_semaphore *semaphore, - bool emit_wait); -int r100_cs_parse(struct radeon_cs_parser *p); -void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); -int r100_copy_blit(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence); -int r100_set_surface_reg(struct radeon_device *rdev, int reg, - uint32_t tiling_flags, uint32_t pitch, - uint32_t offset, uint32_t obj_size); -void r100_clear_surface_reg(struct radeon_device *rdev, int reg); -void r100_bandwidth_update(struct radeon_device *rdev); -void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); -void r100_hpd_init(struct radeon_device *rdev); -void r100_hpd_fini(struct radeon_device *rdev); -bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); -void r100_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd); -int r100_debugfs_rbbm_init(struct radeon_device *rdev); -int r100_debugfs_cp_init(struct radeon_device *rdev); -void r100_cp_disable(struct radeon_device *rdev); -int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); -void r100_cp_fini(struct radeon_device *rdev); -int r100_pci_gart_init(struct radeon_device *rdev); -void r100_pci_gart_fini(struct radeon_device *rdev); -int r100_pci_gart_enable(struct radeon_device *rdev); -void r100_pci_gart_disable(struct radeon_device *rdev); -int r100_debugfs_mc_info_init(struct radeon_device *rdev); -int r100_gui_wait_for_idle(struct radeon_device *rdev); -void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, - struct radeon_ring *cp); -bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, - struct r100_gpu_lockup *lockup, - struct radeon_ring *cp); -void r100_ib_fini(struct radeon_device *rdev); -int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); -void r100_irq_disable(struct radeon_device *rdev); -void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); -void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save); -void r100_vram_init_sizes(struct radeon_device *rdev); -int r100_cp_reset(struct radeon_device *rdev); -void r100_vga_render_disable(struct radeon_device *rdev); -void r100_restore_sanity(struct radeon_device *rdev); -int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - struct radeon_bo *robj); -int r100_cs_parse_packet0(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - const unsigned *auth, unsigned n, - radeon_packet0_check_t check); -int r100_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx); -void r100_enable_bm(struct radeon_device *rdev); -void r100_set_common_regs(struct radeon_device *rdev); -void r100_bm_disable(struct radeon_device *rdev); -extern bool r100_gui_idle(struct radeon_device *rdev); -extern void r100_pm_misc(struct radeon_device *rdev); -extern void r100_pm_prepare(struct radeon_device *rdev); -extern void r100_pm_finish(struct radeon_device *rdev); -extern void r100_pm_init_profile(struct radeon_device *rdev); -extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); -extern void r100_pre_page_flip(struct radeon_device *rdev, int crtc); -extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); -extern void r100_post_page_flip(struct radeon_device *rdev, int crtc); -extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc); -extern int r100_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * r200,rv250,rs300,rv280 - */ -extern int r200_copy_dma(struct radeon_device *rdev, - uint64_t src_offset, - uint64_t dst_offset, - unsigned num_gpu_pages, - struct radeon_fence *fence); -void r200_set_safe_registers(struct radeon_device *rdev); - -/* - * r300,r350,rv350,rv380 - */ -extern int r300_init(struct radeon_device *rdev); -extern void r300_fini(struct radeon_device *rdev); -extern int r300_suspend(struct radeon_device *rdev); -extern int r300_resume(struct radeon_device *rdev); -extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -extern int r300_asic_reset(struct radeon_device *rdev); -extern void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); -extern void r300_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); -extern int r300_cs_parse(struct radeon_cs_parser *p); -extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); -extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); -extern int rv370_get_pcie_lanes(struct radeon_device *rdev); -extern void r300_set_reg_safe(struct radeon_device *rdev); -extern void r300_mc_program(struct radeon_device *rdev); -extern void r300_mc_init(struct radeon_device *rdev); -extern void r300_clock_startup(struct radeon_device *rdev); -extern int r300_mc_wait_for_idle(struct radeon_device *rdev); -extern int rv370_pcie_gart_init(struct radeon_device *rdev); -extern void rv370_pcie_gart_fini(struct radeon_device *rdev); -extern int rv370_pcie_gart_enable(struct radeon_device *rdev); -extern void rv370_pcie_gart_disable(struct radeon_device *rdev); -extern int r300_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * r420,r423,rv410 - */ -extern int r420_init(struct radeon_device *rdev); -extern void r420_fini(struct radeon_device *rdev); -extern int r420_suspend(struct radeon_device *rdev); -extern int r420_resume(struct radeon_device *rdev); -extern void r420_pm_init_profile(struct radeon_device *rdev); -extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg); -extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v); -extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev); -extern void r420_pipes_init(struct radeon_device *rdev); - -/* - * rs400,rs480 - */ -extern int rs400_init(struct radeon_device *rdev); -extern void rs400_fini(struct radeon_device *rdev); -extern int rs400_suspend(struct radeon_device *rdev); -extern int rs400_resume(struct radeon_device *rdev); -void rs400_gart_tlb_flush(struct radeon_device *rdev); -int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); -void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -int rs400_gart_init(struct radeon_device *rdev); -int rs400_gart_enable(struct radeon_device *rdev); -void rs400_gart_adjust_size(struct radeon_device *rdev); -void rs400_gart_disable(struct radeon_device *rdev); -void rs400_gart_fini(struct radeon_device *rdev); -extern int rs400_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * rs600. - */ -extern int rs600_asic_reset(struct radeon_device *rdev); -extern int rs600_init(struct radeon_device *rdev); -extern void rs600_fini(struct radeon_device *rdev); -extern int rs600_suspend(struct radeon_device *rdev); -extern int rs600_resume(struct radeon_device *rdev); -int rs600_irq_set(struct radeon_device *rdev); -int rs600_irq_process(struct radeon_device *rdev); -void rs600_irq_disable(struct radeon_device *rdev); -u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); -void rs600_gart_tlb_flush(struct radeon_device *rdev); -int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); -void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -void rs600_bandwidth_update(struct radeon_device *rdev); -void rs600_hpd_init(struct radeon_device *rdev); -void rs600_hpd_fini(struct radeon_device *rdev); -bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); -void rs600_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd); -extern void rs600_pm_misc(struct radeon_device *rdev); -extern void rs600_pm_prepare(struct radeon_device *rdev); -extern void rs600_pm_finish(struct radeon_device *rdev); -extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc); -extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); -extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc); -void rs600_set_safe_registers(struct radeon_device *rdev); -extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc); -extern int rs600_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * rs690,rs740 - */ -int rs690_init(struct radeon_device *rdev); -void rs690_fini(struct radeon_device *rdev); -int rs690_resume(struct radeon_device *rdev); -int rs690_suspend(struct radeon_device *rdev); -uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); -void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -void rs690_bandwidth_update(struct radeon_device *rdev); -void rs690_line_buffer_adjust(struct radeon_device *rdev, - struct drm_display_mode *mode1, - struct drm_display_mode *mode2); -extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * rv515 - */ -struct rv515_mc_save { - u32 d1vga_control; - u32 d2vga_control; - u32 vga_render_control; - u32 vga_hdp_control; - u32 d1crtc_control; - u32 d2crtc_control; -}; -int rv515_init(struct radeon_device *rdev); -void rv515_fini(struct radeon_device *rdev); -uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); -void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -void rv515_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); -void rv515_bandwidth_update(struct radeon_device *rdev); -int rv515_resume(struct radeon_device *rdev); -int rv515_suspend(struct radeon_device *rdev); -void rv515_bandwidth_avivo_update(struct radeon_device *rdev); -void rv515_vga_render_disable(struct radeon_device *rdev); -void rv515_set_safe_registers(struct radeon_device *rdev); -void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save); -void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save); -void rv515_clock_startup(struct radeon_device *rdev); -void rv515_debugfs(struct radeon_device *rdev); -int rv515_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * r520,rv530,rv560,rv570,r580 - */ -int r520_init(struct radeon_device *rdev); -int r520_resume(struct radeon_device *rdev); -int r520_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880 - */ -int r600_init(struct radeon_device *rdev); -void r600_fini(struct radeon_device *rdev); -int r600_suspend(struct radeon_device *rdev); -int r600_resume(struct radeon_device *rdev); -void r600_vga_set_state(struct radeon_device *rdev, bool state); -int r600_wb_init(struct radeon_device *rdev); -void r600_wb_fini(struct radeon_device *rdev); -void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); -uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); -void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -int r600_cs_parse(struct radeon_cs_parser *p); -void r600_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); -void r600_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_ring *cp, - struct radeon_semaphore *semaphore, - bool emit_wait); -bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int r600_asic_reset(struct radeon_device *rdev); -int r600_set_surface_reg(struct radeon_device *rdev, int reg, - uint32_t tiling_flags, uint32_t pitch, - uint32_t offset, uint32_t obj_size); -void r600_clear_surface_reg(struct radeon_device *rdev, int reg); -int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); -void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); -int r600_copy_blit(struct radeon_device *rdev, - uint64_t src_offset, uint64_t dst_offset, - unsigned num_gpu_pages, struct radeon_fence *fence); -void r600_hpd_init(struct radeon_device *rdev); -void r600_hpd_fini(struct radeon_device *rdev); -bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); -void r600_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd); -extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); -extern bool r600_gui_idle(struct radeon_device *rdev); -extern void r600_pm_misc(struct radeon_device *rdev); -extern void r600_pm_init_profile(struct radeon_device *rdev); -extern void rs780_pm_init_profile(struct radeon_device *rdev); -extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); -extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes); -extern int r600_get_pcie_lanes(struct radeon_device *rdev); -bool r600_card_posted(struct radeon_device *rdev); -void r600_cp_stop(struct radeon_device *rdev); -int r600_cp_start(struct radeon_device *rdev); -void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size); -int r600_cp_resume(struct radeon_device *rdev); -void r600_cp_fini(struct radeon_device *rdev); -int r600_count_pipe_bits(uint32_t val); -int r600_mc_wait_for_idle(struct radeon_device *rdev); -int r600_pcie_gart_init(struct radeon_device *rdev); -void r600_scratch_init(struct radeon_device *rdev); -int r600_blit_init(struct radeon_device *rdev); -void r600_blit_fini(struct radeon_device *rdev); -int r600_init_microcode(struct radeon_device *rdev); -/* r600 irq */ -int r600_irq_process(struct radeon_device *rdev); -int r600_irq_init(struct radeon_device *rdev); -void r600_irq_fini(struct radeon_device *rdev); -void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); -int r600_irq_set(struct radeon_device *rdev); -void r600_irq_suspend(struct radeon_device *rdev); -void r600_disable_interrupts(struct radeon_device *rdev); -void r600_rlc_stop(struct radeon_device *rdev); -/* r600 audio */ -int r600_audio_init(struct radeon_device *rdev); -int r600_audio_tmds_index(struct drm_encoder *encoder); -void r600_audio_set_clock(struct drm_encoder *encoder, int clock); -int r600_audio_channels(struct radeon_device *rdev); -int r600_audio_bits_per_sample(struct radeon_device *rdev); -int r600_audio_rate(struct radeon_device *rdev); -uint8_t r600_audio_status_bits(struct radeon_device *rdev); -uint8_t r600_audio_category_code(struct radeon_device *rdev); -void r600_audio_schedule_polling(struct radeon_device *rdev); -void r600_audio_enable_polling(struct drm_encoder *encoder); -void r600_audio_disable_polling(struct drm_encoder *encoder); -void r600_audio_fini(struct radeon_device *rdev); -void r600_hdmi_init(struct drm_encoder *encoder); -int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); -void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); -/* r600 blit */ -int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages); -void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence); -void r600_kms_blit_copy(struct radeon_device *rdev, - u64 src_gpu_addr, u64 dst_gpu_addr, - unsigned num_gpu_pages); -int r600_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * rv770,rv730,rv710,rv740 - */ -int rv770_init(struct radeon_device *rdev); -void rv770_fini(struct radeon_device *rdev); -int rv770_suspend(struct radeon_device *rdev); -int rv770_resume(struct radeon_device *rdev); -void rv770_pm_misc(struct radeon_device *rdev); -u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); -void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); -void r700_cp_stop(struct radeon_device *rdev); -void r700_cp_fini(struct radeon_device *rdev); - -/* - * evergreen - */ -struct evergreen_mc_save { - u32 vga_control[6]; - u32 vga_render_control; - u32 vga_hdp_control; - u32 crtc_control[6]; -}; -void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); -int evergreen_init(struct radeon_device *rdev); -void evergreen_fini(struct radeon_device *rdev); -int evergreen_suspend(struct radeon_device *rdev); -int evergreen_resume(struct radeon_device *rdev); -bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int evergreen_asic_reset(struct radeon_device *rdev); -void evergreen_bandwidth_update(struct radeon_device *rdev); -void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -void evergreen_hpd_init(struct radeon_device *rdev); -void evergreen_hpd_fini(struct radeon_device *rdev); -bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); -void evergreen_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd); -u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc); -int evergreen_irq_set(struct radeon_device *rdev); -int evergreen_irq_process(struct radeon_device *rdev); -extern int evergreen_cs_parse(struct radeon_cs_parser *p); -extern void evergreen_pm_misc(struct radeon_device *rdev); -extern void evergreen_pm_prepare(struct radeon_device *rdev); -extern void evergreen_pm_finish(struct radeon_device *rdev); -extern void sumo_pm_init_profile(struct radeon_device *rdev); -extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); -extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); -extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); -extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc); -void evergreen_disable_interrupt_state(struct radeon_device *rdev); -int evergreen_blit_init(struct radeon_device *rdev); -int evergreen_mc_wait_for_idle(struct radeon_device *rdev); - -/* - * cayman - */ -void cayman_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); -void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev); -int cayman_init(struct radeon_device *rdev); -void cayman_fini(struct radeon_device *rdev); -int cayman_suspend(struct radeon_device *rdev); -int cayman_resume(struct radeon_device *rdev); -bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int cayman_asic_reset(struct radeon_device *rdev); -void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int cayman_vm_init(struct radeon_device *rdev); -void cayman_vm_fini(struct radeon_device *rdev); -int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); -void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); -void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); -uint32_t cayman_vm_page_flags(struct radeon_device *rdev, - struct radeon_vm *vm, - uint32_t flags); -void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, - unsigned pfn, uint64_t addr, uint32_t flags); -int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); - -/* DCE6 - SI */ -void dce6_bandwidth_update(struct radeon_device *rdev); - -/* - * si - */ -void si_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence); -void si_pcie_gart_tlb_flush(struct radeon_device *rdev); -int si_init(struct radeon_device *rdev); -void si_fini(struct radeon_device *rdev); -int si_suspend(struct radeon_device *rdev); -int si_resume(struct radeon_device *rdev); -bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); -int si_asic_reset(struct radeon_device *rdev); -void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int si_irq_set(struct radeon_device *rdev); -int si_irq_process(struct radeon_device *rdev); -int si_vm_init(struct radeon_device *rdev); -void si_vm_fini(struct radeon_device *rdev); -int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); -void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); -void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); -int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atombios.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atombios.c deleted file mode 100644 index b1e3820d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atombios.c +++ /dev/null @@ -1,3162 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" - -#include "atom.h" -#include "atom-bits.h" - -/* from radeon_encoder.c */ -extern uint32_t -radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, - uint8_t dac); -extern void radeon_link_encoder_connector(struct drm_device *dev); -extern void -radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, - uint32_t supported_device, u16 caps); - -/* from radeon_connector.c */ -extern void -radeon_add_atom_connector(struct drm_device *dev, - uint32_t connector_id, - uint32_t supported_device, - int connector_type, - struct radeon_i2c_bus_rec *i2c_bus, - uint32_t igp_lane_info, - uint16_t connector_object_id, - struct radeon_hpd *hpd, - struct radeon_router *router); - -/* from radeon_legacy_encoder.c */ -extern void -radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, - uint32_t supported_device); - -/* local */ -static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, - u16 voltage_id, u16 *voltage); - -union atom_supported_devices { - struct _ATOM_SUPPORTED_DEVICES_INFO info; - struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2; - struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; -}; - -static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev, - ATOM_GPIO_I2C_ASSIGMENT *gpio, - u8 index) -{ - /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ - if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { - if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { - gpio->ucClkMaskShift = 0x19; - gpio->ucDataMaskShift = 0x18; - } - } - - /* some evergreen boards have bad data for this entry */ - if (ASIC_IS_DCE4(rdev)) { - if ((index == 7) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && - (gpio->sucI2cId.ucAccess == 0)) { - gpio->sucI2cId.ucAccess = 0x97; - gpio->ucDataMaskShift = 8; - gpio->ucDataEnShift = 8; - gpio->ucDataY_Shift = 8; - gpio->ucDataA_Shift = 8; - } - } - - /* some DCE3 boards have bad data for this entry */ - if (ASIC_IS_DCE3(rdev)) { - if ((index == 4) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && - (gpio->sucI2cId.ucAccess == 0x94)) - gpio->sucI2cId.ucAccess = 0x14; - } -} - -static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio) -{ - struct radeon_i2c_bus_rec i2c; - - memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); - - i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; - i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; - i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; - i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; - i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; - i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; - i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; - i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; - i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); - i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); - i2c.en_clk_mask = (1 << gpio->ucClkEnShift); - i2c.en_data_mask = (1 << gpio->ucDataEnShift); - i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); - i2c.y_data_mask = (1 << gpio->ucDataY_Shift); - i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); - i2c.a_data_mask = (1 << gpio->ucDataA_Shift); - - if (gpio->sucI2cId.sbfAccess.bfHW_Capable) - i2c.hw_capable = true; - else - i2c.hw_capable = false; - - if (gpio->sucI2cId.ucAccess == 0xa0) - i2c.mm_i2c = true; - else - i2c.mm_i2c = false; - - i2c.i2c_id = gpio->sucI2cId.ucAccess; - - if (i2c.mask_clk_reg) - i2c.valid = true; - else - i2c.valid = false; - - return i2c; -} - -static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, - uint8_t id) -{ - struct atom_context *ctx = rdev->mode_info.atom_context; - ATOM_GPIO_I2C_ASSIGMENT *gpio; - struct radeon_i2c_bus_rec i2c; - int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); - struct _ATOM_GPIO_I2C_INFO *i2c_info; - uint16_t data_offset, size; - int i, num_indices; - - memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); - i2c.valid = false; - - if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { - i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); - - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_GPIO_I2C_ASSIGMENT); - - for (i = 0; i < num_indices; i++) { - gpio = &i2c_info->asGPIO_Info[i]; - - radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); - - if (gpio->sucI2cId.ucAccess == id) { - i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); - break; - } - } - } - - return i2c; -} - -void radeon_atombios_i2c_init(struct radeon_device *rdev) -{ - struct atom_context *ctx = rdev->mode_info.atom_context; - ATOM_GPIO_I2C_ASSIGMENT *gpio; - struct radeon_i2c_bus_rec i2c; - int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); - struct _ATOM_GPIO_I2C_INFO *i2c_info; - uint16_t data_offset, size; - int i, num_indices; - char stmp[32]; - - if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { - i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); - - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_GPIO_I2C_ASSIGMENT); - - for (i = 0; i < num_indices; i++) { - gpio = &i2c_info->asGPIO_Info[i]; - - radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); - - i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); - - if (i2c.valid) { - sprintf(stmp, "0x%x", i2c.i2c_id); - rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); - } - } - } -} - -static struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rdev, - u8 id) -{ - struct atom_context *ctx = rdev->mode_info.atom_context; - struct radeon_gpio_rec gpio; - int index = GetIndexIntoMasterTable(DATA, GPIO_Pin_LUT); - struct _ATOM_GPIO_PIN_LUT *gpio_info; - ATOM_GPIO_PIN_ASSIGNMENT *pin; - u16 data_offset, size; - int i, num_indices; - - memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); - gpio.valid = false; - - if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { - gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); - - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_GPIO_PIN_ASSIGNMENT); - - for (i = 0; i < num_indices; i++) { - pin = &gpio_info->asGPIO_Pin[i]; - if (id == pin->ucGPIO_ID) { - gpio.id = pin->ucGPIO_ID; - gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; - gpio.mask = (1 << pin->ucGpioPinBitShift); - gpio.valid = true; - break; - } - } - } - - return gpio; -} - -static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device *rdev, - struct radeon_gpio_rec *gpio) -{ - struct radeon_hpd hpd; - u32 reg; - - memset(&hpd, 0, sizeof(struct radeon_hpd)); - - if (ASIC_IS_DCE6(rdev)) - reg = SI_DC_GPIO_HPD_A; - else if (ASIC_IS_DCE4(rdev)) - reg = EVERGREEN_DC_GPIO_HPD_A; - else - reg = AVIVO_DC_GPIO_HPD_A; - - hpd.gpio = *gpio; - if (gpio->reg == reg) { - switch(gpio->mask) { - case (1 << 0): - hpd.hpd = RADEON_HPD_1; - break; - case (1 << 8): - hpd.hpd = RADEON_HPD_2; - break; - case (1 << 16): - hpd.hpd = RADEON_HPD_3; - break; - case (1 << 24): - hpd.hpd = RADEON_HPD_4; - break; - case (1 << 26): - hpd.hpd = RADEON_HPD_5; - break; - case (1 << 28): - hpd.hpd = RADEON_HPD_6; - break; - default: - hpd.hpd = RADEON_HPD_NONE; - break; - } - } else - hpd.hpd = RADEON_HPD_NONE; - return hpd; -} - -static bool radeon_atom_apply_quirks(struct drm_device *dev, - uint32_t supported_device, - int *connector_type, - struct radeon_i2c_bus_rec *i2c_bus, - uint16_t *line_mux, - struct radeon_hpd *hpd) -{ - - /* Asus M2A-VM HDMI board lists the DVI port as HDMI */ - if ((dev->pdev->device == 0x791e) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0x826d)) { - if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && - (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) - *connector_type = DRM_MODE_CONNECTOR_DVID; - } - - /* Asrock RS600 board lists the DVI port as HDMI */ - if ((dev->pdev->device == 0x7941) && - (dev->pdev->subsystem_vendor == 0x1849) && - (dev->pdev->subsystem_device == 0x7941)) { - if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && - (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) - *connector_type = DRM_MODE_CONNECTOR_DVID; - } - - /* MSI K9A2GM V2/V3 board has no HDMI or DVI */ - if ((dev->pdev->device == 0x796e) && - (dev->pdev->subsystem_vendor == 0x1462) && - (dev->pdev->subsystem_device == 0x7302)) { - if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) || - (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) - return false; - } - - /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ - if ((dev->pdev->device == 0x7941) && - (dev->pdev->subsystem_vendor == 0x147b) && - (dev->pdev->subsystem_device == 0x2412)) { - if (*connector_type == DRM_MODE_CONNECTOR_DVII) - return false; - } - - /* Falcon NW laptop lists vga ddc line for LVDS */ - if ((dev->pdev->device == 0x5653) && - (dev->pdev->subsystem_vendor == 0x1462) && - (dev->pdev->subsystem_device == 0x0291)) { - if (*connector_type == DRM_MODE_CONNECTOR_LVDS) { - i2c_bus->valid = false; - *line_mux = 53; - } - } - - /* HIS X1300 is DVI+VGA, not DVI+DVI */ - if ((dev->pdev->device == 0x7146) && - (dev->pdev->subsystem_vendor == 0x17af) && - (dev->pdev->subsystem_device == 0x2058)) { - if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) - return false; - } - - /* Gigabyte X1300 is DVI+VGA, not DVI+DVI */ - if ((dev->pdev->device == 0x7142) && - (dev->pdev->subsystem_vendor == 0x1458) && - (dev->pdev->subsystem_device == 0x2134)) { - if (supported_device == ATOM_DEVICE_DFP1_SUPPORT) - return false; - } - - - /* Funky macbooks */ - if ((dev->pdev->device == 0x71C5) && - (dev->pdev->subsystem_vendor == 0x106b) && - (dev->pdev->subsystem_device == 0x0080)) { - if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) || - (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) - return false; - if (supported_device == ATOM_DEVICE_CRT2_SUPPORT) - *line_mux = 0x90; - } - - /* mac rv630, rv730, others */ - if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) && - (*connector_type == DRM_MODE_CONNECTOR_DVII)) { - *connector_type = DRM_MODE_CONNECTOR_9PinDIN; - *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1; - } - - /* ASUS HD 3600 XT board lists the DVI port as HDMI */ - if ((dev->pdev->device == 0x9598) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0x01da)) { - if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - } - } - - /* ASUS HD 3600 board lists the DVI port as HDMI */ - if ((dev->pdev->device == 0x9598) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0x01e4)) { - if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - } - } - - /* ASUS HD 3450 board lists the DVI port as HDMI */ - if ((dev->pdev->device == 0x95C5) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0x01e2)) { - if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - } - } - - /* some BIOSes seem to report DAC on HDMI - usually this is a board with - * HDMI + VGA reporting as HDMI - */ - if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) { - if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) { - *connector_type = DRM_MODE_CONNECTOR_VGA; - *line_mux = 0; - } - } - - /* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port - * on the laptop and a DVI port on the docking station and - * both share the same encoder, hpd pin, and ddc line. - * So while the bios table is technically correct, - * we drop the DVI port here since xrandr has no concept of - * encoders and will try and drive both connectors - * with different crtcs which isn't possible on the hardware - * side and leaves no crtcs for LVDS or VGA. - */ - if (((dev->pdev->device == 0x95c4) || (dev->pdev->device == 0x9591)) && - (dev->pdev->subsystem_vendor == 0x1025) && - (dev->pdev->subsystem_device == 0x013c)) { - if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && - (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) { - /* actually it's a DVI-D port not DVI-I */ - *connector_type = DRM_MODE_CONNECTOR_DVID; - return false; - } - } - - /* XFX Pine Group device rv730 reports no VGA DDC lines - * even though they are wired up to record 0x93 - */ - if ((dev->pdev->device == 0x9498) && - (dev->pdev->subsystem_vendor == 0x1682) && - (dev->pdev->subsystem_device == 0x2452) && - (i2c_bus->valid == false) && - !(supported_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))) { - struct radeon_device *rdev = dev->dev_private; - *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93); - } - - /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ - if ((dev->pdev->device == 0x9802) && - (dev->pdev->subsystem_vendor == 0x1734) && - (dev->pdev->subsystem_device == 0x11bd)) { - if (*connector_type == DRM_MODE_CONNECTOR_VGA) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - *line_mux = 0x3103; - } else if (*connector_type == DRM_MODE_CONNECTOR_DVID) { - *connector_type = DRM_MODE_CONNECTOR_DVII; - } - } - - - return true; -} - -const int supported_devices_connector_convert[] = { - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_VGA, - DRM_MODE_CONNECTOR_DVII, - DRM_MODE_CONNECTOR_DVID, - DRM_MODE_CONNECTOR_DVIA, - DRM_MODE_CONNECTOR_SVIDEO, - DRM_MODE_CONNECTOR_Composite, - DRM_MODE_CONNECTOR_LVDS, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_HDMIA, - DRM_MODE_CONNECTOR_HDMIB, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_9PinDIN, - DRM_MODE_CONNECTOR_DisplayPort -}; - -const uint16_t supported_devices_connector_object_id_convert[] = { - CONNECTOR_OBJECT_ID_NONE, - CONNECTOR_OBJECT_ID_VGA, - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */ - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */ - CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */ - CONNECTOR_OBJECT_ID_COMPOSITE, - CONNECTOR_OBJECT_ID_SVIDEO, - CONNECTOR_OBJECT_ID_LVDS, - CONNECTOR_OBJECT_ID_9PIN_DIN, - CONNECTOR_OBJECT_ID_9PIN_DIN, - CONNECTOR_OBJECT_ID_DISPLAYPORT, - CONNECTOR_OBJECT_ID_HDMI_TYPE_A, - CONNECTOR_OBJECT_ID_HDMI_TYPE_B, - CONNECTOR_OBJECT_ID_SVIDEO -}; - -const int object_connector_convert[] = { - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_DVII, - DRM_MODE_CONNECTOR_DVII, - DRM_MODE_CONNECTOR_DVID, - DRM_MODE_CONNECTOR_DVID, - DRM_MODE_CONNECTOR_VGA, - DRM_MODE_CONNECTOR_Composite, - DRM_MODE_CONNECTOR_SVIDEO, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_9PinDIN, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_HDMIA, - DRM_MODE_CONNECTOR_HDMIB, - DRM_MODE_CONNECTOR_LVDS, - DRM_MODE_CONNECTOR_9PinDIN, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_DisplayPort, - DRM_MODE_CONNECTOR_eDP, - DRM_MODE_CONNECTOR_Unknown -}; - -bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - struct atom_context *ctx = mode_info->atom_context; - int index = GetIndexIntoMasterTable(DATA, Object_Header); - u16 size, data_offset; - u8 frev, crev; - ATOM_CONNECTOR_OBJECT_TABLE *con_obj; - ATOM_ENCODER_OBJECT_TABLE *enc_obj; - ATOM_OBJECT_TABLE *router_obj; - ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj; - ATOM_OBJECT_HEADER *obj_header; - int i, j, k, path_size, device_support; - int connector_type; - u16 igp_lane_info, conn_id, connector_object_id; - struct radeon_i2c_bus_rec ddc_bus; - struct radeon_router router; - struct radeon_gpio_rec gpio; - struct radeon_hpd hpd; - - if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) - return false; - - if (crev < 2) - return false; - - obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset); - path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) - (ctx->bios + data_offset + - le16_to_cpu(obj_header->usDisplayPathTableOffset)); - con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *) - (ctx->bios + data_offset + - le16_to_cpu(obj_header->usConnectorObjectTableOffset)); - enc_obj = (ATOM_ENCODER_OBJECT_TABLE *) - (ctx->bios + data_offset + - le16_to_cpu(obj_header->usEncoderObjectTableOffset)); - router_obj = (ATOM_OBJECT_TABLE *) - (ctx->bios + data_offset + - le16_to_cpu(obj_header->usRouterObjectTableOffset)); - device_support = le16_to_cpu(obj_header->usDeviceSupport); - - path_size = 0; - for (i = 0; i < path_obj->ucNumOfDispPath; i++) { - uint8_t *addr = (uint8_t *) path_obj->asDispPath; - ATOM_DISPLAY_OBJECT_PATH *path; - addr += path_size; - path = (ATOM_DISPLAY_OBJECT_PATH *) addr; - path_size += le16_to_cpu(path->usSize); - - if (device_support & le16_to_cpu(path->usDeviceTag)) { - uint8_t con_obj_id, con_obj_num, con_obj_type; - - con_obj_id = - (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK) - >> OBJECT_ID_SHIFT; - con_obj_num = - (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK) - >> ENUM_ID_SHIFT; - con_obj_type = - (le16_to_cpu(path->usConnObjectId) & - OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; - - /* TODO CV support */ - if (le16_to_cpu(path->usDeviceTag) == - ATOM_DEVICE_CV_SUPPORT) - continue; - - /* IGP chips */ - if ((rdev->flags & RADEON_IS_IGP) && - (con_obj_id == - CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { - uint16_t igp_offset = 0; - ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj; - - index = - GetIndexIntoMasterTable(DATA, - IntegratedSystemInfo); - - if (atom_parse_data_header(ctx, index, &size, &frev, - &crev, &igp_offset)) { - - if (crev >= 2) { - igp_obj = - (ATOM_INTEGRATED_SYSTEM_INFO_V2 - *) (ctx->bios + igp_offset); - - if (igp_obj) { - uint32_t slot_config, ct; - - if (con_obj_num == 1) - slot_config = - igp_obj-> - ulDDISlot1Config; - else - slot_config = - igp_obj-> - ulDDISlot2Config; - - ct = (slot_config >> 16) & 0xff; - connector_type = - object_connector_convert - [ct]; - connector_object_id = ct; - igp_lane_info = - slot_config & 0xffff; - } else - continue; - } else - continue; - } else { - igp_lane_info = 0; - connector_type = - object_connector_convert[con_obj_id]; - connector_object_id = con_obj_id; - } - } else { - igp_lane_info = 0; - connector_type = - object_connector_convert[con_obj_id]; - connector_object_id = con_obj_id; - } - - if (connector_type == DRM_MODE_CONNECTOR_Unknown) - continue; - - router.ddc_valid = false; - router.cd_valid = false; - for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { - uint8_t grph_obj_id, grph_obj_num, grph_obj_type; - - grph_obj_id = - (le16_to_cpu(path->usGraphicObjIds[j]) & - OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - grph_obj_num = - (le16_to_cpu(path->usGraphicObjIds[j]) & - ENUM_ID_MASK) >> ENUM_ID_SHIFT; - grph_obj_type = - (le16_to_cpu(path->usGraphicObjIds[j]) & - OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; - - if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { - for (k = 0; k < enc_obj->ucNumberOfObjects; k++) { - u16 encoder_obj = le16_to_cpu(enc_obj->asObjects[k].usObjectID); - if (le16_to_cpu(path->usGraphicObjIds[j]) == encoder_obj) { - ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) - (ctx->bios + data_offset + - le16_to_cpu(enc_obj->asObjects[k].usRecordOffset)); - ATOM_ENCODER_CAP_RECORD *cap_record; - u16 caps = 0; - - while (record->ucRecordSize > 0 && - record->ucRecordType > 0 && - record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { - switch (record->ucRecordType) { - case ATOM_ENCODER_CAP_RECORD_TYPE: - cap_record =(ATOM_ENCODER_CAP_RECORD *) - record; - caps = le16_to_cpu(cap_record->usEncoderCap); - break; - } - record = (ATOM_COMMON_RECORD_HEADER *) - ((char *)record + record->ucRecordSize); - } - radeon_add_atom_encoder(dev, - encoder_obj, - le16_to_cpu - (path-> - usDeviceTag), - caps); - } - } - } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { - for (k = 0; k < router_obj->ucNumberOfObjects; k++) { - u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); - if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) { - ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) - (ctx->bios + data_offset + - le16_to_cpu(router_obj->asObjects[k].usRecordOffset)); - ATOM_I2C_RECORD *i2c_record; - ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; - ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path; - ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path; - ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = - (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) - (ctx->bios + data_offset + - le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); - int enum_id; - - router.router_id = router_obj_id; - for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst; - enum_id++) { - if (le16_to_cpu(path->usConnObjectId) == - le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id])) - break; - } - - while (record->ucRecordSize > 0 && - record->ucRecordType > 0 && - record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { - switch (record->ucRecordType) { - case ATOM_I2C_RECORD_TYPE: - i2c_record = - (ATOM_I2C_RECORD *) - record; - i2c_config = - (ATOM_I2C_ID_CONFIG_ACCESS *) - &i2c_record->sucI2cId; - router.i2c_info = - radeon_lookup_i2c_gpio(rdev, - i2c_config-> - ucAccess); - router.i2c_addr = i2c_record->ucI2CAddr >> 1; - break; - case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: - ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *) - record; - router.ddc_valid = true; - router.ddc_mux_type = ddc_path->ucMuxType; - router.ddc_mux_control_pin = ddc_path->ucMuxControlPin; - router.ddc_mux_state = ddc_path->ucMuxState[enum_id]; - break; - case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE: - cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *) - record; - router.cd_valid = true; - router.cd_mux_type = cd_path->ucMuxType; - router.cd_mux_control_pin = cd_path->ucMuxControlPin; - router.cd_mux_state = cd_path->ucMuxState[enum_id]; - break; - } - record = (ATOM_COMMON_RECORD_HEADER *) - ((char *)record + record->ucRecordSize); - } - } - } - } - } - - /* look up gpio for ddc, hpd */ - ddc_bus.valid = false; - hpd.hpd = RADEON_HPD_NONE; - if ((le16_to_cpu(path->usDeviceTag) & - (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) { - for (j = 0; j < con_obj->ucNumberOfObjects; j++) { - if (le16_to_cpu(path->usConnObjectId) == - le16_to_cpu(con_obj->asObjects[j]. - usObjectID)) { - ATOM_COMMON_RECORD_HEADER - *record = - (ATOM_COMMON_RECORD_HEADER - *) - (ctx->bios + data_offset + - le16_to_cpu(con_obj-> - asObjects[j]. - usRecordOffset)); - ATOM_I2C_RECORD *i2c_record; - ATOM_HPD_INT_RECORD *hpd_record; - ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; - - while (record->ucRecordSize > 0 && - record->ucRecordType > 0 && - record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { - switch (record->ucRecordType) { - case ATOM_I2C_RECORD_TYPE: - i2c_record = - (ATOM_I2C_RECORD *) - record; - i2c_config = - (ATOM_I2C_ID_CONFIG_ACCESS *) - &i2c_record->sucI2cId; - ddc_bus = radeon_lookup_i2c_gpio(rdev, - i2c_config-> - ucAccess); - break; - case ATOM_HPD_INT_RECORD_TYPE: - hpd_record = - (ATOM_HPD_INT_RECORD *) - record; - gpio = radeon_lookup_gpio(rdev, - hpd_record->ucHPDIntGPIOID); - hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio); - hpd.plugged_state = hpd_record->ucPlugged_PinState; - break; - } - record = - (ATOM_COMMON_RECORD_HEADER - *) ((char *)record - + - record-> - ucRecordSize); - } - break; - } - } - } - - /* needed for aux chan transactions */ - ddc_bus.hpd = hpd.hpd; - - conn_id = le16_to_cpu(path->usConnObjectId); - - if (!radeon_atom_apply_quirks - (dev, le16_to_cpu(path->usDeviceTag), &connector_type, - &ddc_bus, &conn_id, &hpd)) - continue; - - radeon_add_atom_connector(dev, - conn_id, - le16_to_cpu(path-> - usDeviceTag), - connector_type, &ddc_bus, - igp_lane_info, - connector_object_id, - &hpd, - &router); - - } - } - - radeon_link_encoder_connector(dev); - - return true; -} - -static uint16_t atombios_get_connector_object_id(struct drm_device *dev, - int connector_type, - uint16_t devices) -{ - struct radeon_device *rdev = dev->dev_private; - - if (rdev->flags & RADEON_IS_IGP) { - return supported_devices_connector_object_id_convert - [connector_type]; - } else if (((connector_type == DRM_MODE_CONNECTOR_DVII) || - (connector_type == DRM_MODE_CONNECTOR_DVID)) && - (devices & ATOM_DEVICE_DFP2_SUPPORT)) { - struct radeon_mode_info *mode_info = &rdev->mode_info; - struct atom_context *ctx = mode_info->atom_context; - int index = GetIndexIntoMasterTable(DATA, XTMDS_Info); - uint16_t size, data_offset; - uint8_t frev, crev; - ATOM_XTMDS_INFO *xtmds; - - if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) { - xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); - - if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { - if (connector_type == DRM_MODE_CONNECTOR_DVII) - return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; - else - return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; - } else { - if (connector_type == DRM_MODE_CONNECTOR_DVII) - return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; - else - return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; - } - } else - return supported_devices_connector_object_id_convert - [connector_type]; - } else { - return supported_devices_connector_object_id_convert - [connector_type]; - } -} - -struct bios_connector { - bool valid; - uint16_t line_mux; - uint16_t devices; - int connector_type; - struct radeon_i2c_bus_rec ddc_bus; - struct radeon_hpd hpd; -}; - -bool radeon_get_atom_connector_info_from_supported_devices_table(struct - drm_device - *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - struct atom_context *ctx = mode_info->atom_context; - int index = GetIndexIntoMasterTable(DATA, SupportedDevicesInfo); - uint16_t size, data_offset; - uint8_t frev, crev; - uint16_t device_support; - uint8_t dac; - union atom_supported_devices *supported_devices; - int i, j, max_device; - struct bios_connector *bios_connectors; - size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; - struct radeon_router router; - - router.ddc_valid = false; - router.cd_valid = false; - - bios_connectors = kzalloc(bc_size, GFP_KERNEL); - if (!bios_connectors) - return false; - - if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, - &data_offset)) { - kfree(bios_connectors); - return false; - } - - supported_devices = - (union atom_supported_devices *)(ctx->bios + data_offset); - - device_support = le16_to_cpu(supported_devices->info.usDeviceSupport); - - if (frev > 1) - max_device = ATOM_MAX_SUPPORTED_DEVICE; - else - max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; - - for (i = 0; i < max_device; i++) { - ATOM_CONNECTOR_INFO_I2C ci = - supported_devices->info.asConnInfo[i]; - - bios_connectors[i].valid = false; - - if (!(device_support & (1 << i))) { - continue; - } - - if (i == ATOM_DEVICE_CV_INDEX) { - DRM_DEBUG_KMS("Skipping Component Video\n"); - continue; - } - - bios_connectors[i].connector_type = - supported_devices_connector_convert[ci.sucConnectorInfo. - sbfAccess. - bfConnectorType]; - - if (bios_connectors[i].connector_type == - DRM_MODE_CONNECTOR_Unknown) - continue; - - dac = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC; - - bios_connectors[i].line_mux = - ci.sucI2cId.ucAccess; - - /* give tv unique connector ids */ - if (i == ATOM_DEVICE_TV1_INDEX) { - bios_connectors[i].ddc_bus.valid = false; - bios_connectors[i].line_mux = 50; - } else if (i == ATOM_DEVICE_TV2_INDEX) { - bios_connectors[i].ddc_bus.valid = false; - bios_connectors[i].line_mux = 51; - } else if (i == ATOM_DEVICE_CV_INDEX) { - bios_connectors[i].ddc_bus.valid = false; - bios_connectors[i].line_mux = 52; - } else - bios_connectors[i].ddc_bus = - radeon_lookup_i2c_gpio(rdev, - bios_connectors[i].line_mux); - - if ((crev > 1) && (frev > 1)) { - u8 isb = supported_devices->info_2d1.asIntSrcInfo[i].ucIntSrcBitmap; - switch (isb) { - case 0x4: - bios_connectors[i].hpd.hpd = RADEON_HPD_1; - break; - case 0xa: - bios_connectors[i].hpd.hpd = RADEON_HPD_2; - break; - default: - bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; - break; - } - } else { - if (i == ATOM_DEVICE_DFP1_INDEX) - bios_connectors[i].hpd.hpd = RADEON_HPD_1; - else if (i == ATOM_DEVICE_DFP2_INDEX) - bios_connectors[i].hpd.hpd = RADEON_HPD_2; - else - bios_connectors[i].hpd.hpd = RADEON_HPD_NONE; - } - - /* Always set the connector type to VGA for CRT1/CRT2. if they are - * shared with a DVI port, we'll pick up the DVI connector when we - * merge the outputs. Some bioses incorrectly list VGA ports as DVI. - */ - if (i == ATOM_DEVICE_CRT1_INDEX || i == ATOM_DEVICE_CRT2_INDEX) - bios_connectors[i].connector_type = - DRM_MODE_CONNECTOR_VGA; - - if (!radeon_atom_apply_quirks - (dev, (1 << i), &bios_connectors[i].connector_type, - &bios_connectors[i].ddc_bus, &bios_connectors[i].line_mux, - &bios_connectors[i].hpd)) - continue; - - bios_connectors[i].valid = true; - bios_connectors[i].devices = (1 << i); - - if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) - radeon_add_atom_encoder(dev, - radeon_get_encoder_enum(dev, - (1 << i), - dac), - (1 << i), - 0); - else - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - (1 << i), - dac), - (1 << i)); - } - - /* combine shared connectors */ - for (i = 0; i < max_device; i++) { - if (bios_connectors[i].valid) { - for (j = 0; j < max_device; j++) { - if (bios_connectors[j].valid && (i != j)) { - if (bios_connectors[i].line_mux == - bios_connectors[j].line_mux) { - /* make sure not to combine LVDS */ - if (bios_connectors[i].devices & (ATOM_DEVICE_LCD_SUPPORT)) { - bios_connectors[i].line_mux = 53; - bios_connectors[i].ddc_bus.valid = false; - continue; - } - if (bios_connectors[j].devices & (ATOM_DEVICE_LCD_SUPPORT)) { - bios_connectors[j].line_mux = 53; - bios_connectors[j].ddc_bus.valid = false; - continue; - } - /* combine analog and digital for DVI-I */ - if (((bios_connectors[i].devices & (ATOM_DEVICE_DFP_SUPPORT)) && - (bios_connectors[j].devices & (ATOM_DEVICE_CRT_SUPPORT))) || - ((bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) && - (bios_connectors[i].devices & (ATOM_DEVICE_CRT_SUPPORT)))) { - bios_connectors[i].devices |= - bios_connectors[j].devices; - bios_connectors[i].connector_type = - DRM_MODE_CONNECTOR_DVII; - if (bios_connectors[j].devices & (ATOM_DEVICE_DFP_SUPPORT)) - bios_connectors[i].hpd = - bios_connectors[j].hpd; - bios_connectors[j].valid = false; - } - } - } - } - } - } - - /* add the connectors */ - for (i = 0; i < max_device; i++) { - if (bios_connectors[i].valid) { - uint16_t connector_object_id = - atombios_get_connector_object_id(dev, - bios_connectors[i].connector_type, - bios_connectors[i].devices); - radeon_add_atom_connector(dev, - bios_connectors[i].line_mux, - bios_connectors[i].devices, - bios_connectors[i]. - connector_type, - &bios_connectors[i].ddc_bus, - 0, - connector_object_id, - &bios_connectors[i].hpd, - &router); - } - } - - radeon_link_encoder_connector(dev); - - kfree(bios_connectors); - return true; -} - -union firmware_info { - ATOM_FIRMWARE_INFO info; - ATOM_FIRMWARE_INFO_V1_2 info_12; - ATOM_FIRMWARE_INFO_V1_3 info_13; - ATOM_FIRMWARE_INFO_V1_4 info_14; - ATOM_FIRMWARE_INFO_V2_1 info_21; - ATOM_FIRMWARE_INFO_V2_2 info_22; -}; - -bool radeon_atom_get_clock_info(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); - union firmware_info *firmware_info; - uint8_t frev, crev; - struct radeon_pll *p1pll = &rdev->clock.p1pll; - struct radeon_pll *p2pll = &rdev->clock.p2pll; - struct radeon_pll *dcpll = &rdev->clock.dcpll; - struct radeon_pll *spll = &rdev->clock.spll; - struct radeon_pll *mpll = &rdev->clock.mpll; - uint16_t data_offset; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - firmware_info = - (union firmware_info *)(mode_info->atom_context->bios + - data_offset); - /* pixel clocks */ - p1pll->reference_freq = - le16_to_cpu(firmware_info->info.usReferenceClock); - p1pll->reference_div = 0; - - if (crev < 2) - p1pll->pll_out_min = - le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); - else - p1pll->pll_out_min = - le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output); - p1pll->pll_out_max = - le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); - - if (crev >= 4) { - p1pll->lcd_pll_out_min = - le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100; - if (p1pll->lcd_pll_out_min == 0) - p1pll->lcd_pll_out_min = p1pll->pll_out_min; - p1pll->lcd_pll_out_max = - le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100; - if (p1pll->lcd_pll_out_max == 0) - p1pll->lcd_pll_out_max = p1pll->pll_out_max; - } else { - p1pll->lcd_pll_out_min = p1pll->pll_out_min; - p1pll->lcd_pll_out_max = p1pll->pll_out_max; - } - - if (p1pll->pll_out_min == 0) { - if (ASIC_IS_AVIVO(rdev)) - p1pll->pll_out_min = 64800; - else - p1pll->pll_out_min = 20000; - } - - p1pll->pll_in_min = - le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input); - p1pll->pll_in_max = - le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input); - - *p2pll = *p1pll; - - /* system clock */ - if (ASIC_IS_DCE4(rdev)) - spll->reference_freq = - le16_to_cpu(firmware_info->info_21.usCoreReferenceClock); - else - spll->reference_freq = - le16_to_cpu(firmware_info->info.usReferenceClock); - spll->reference_div = 0; - - spll->pll_out_min = - le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output); - spll->pll_out_max = - le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output); - - /* ??? */ - if (spll->pll_out_min == 0) { - if (ASIC_IS_AVIVO(rdev)) - spll->pll_out_min = 64800; - else - spll->pll_out_min = 20000; - } - - spll->pll_in_min = - le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input); - spll->pll_in_max = - le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input); - - /* memory clock */ - if (ASIC_IS_DCE4(rdev)) - mpll->reference_freq = - le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock); - else - mpll->reference_freq = - le16_to_cpu(firmware_info->info.usReferenceClock); - mpll->reference_div = 0; - - mpll->pll_out_min = - le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output); - mpll->pll_out_max = - le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output); - - /* ??? */ - if (mpll->pll_out_min == 0) { - if (ASIC_IS_AVIVO(rdev)) - mpll->pll_out_min = 64800; - else - mpll->pll_out_min = 20000; - } - - mpll->pll_in_min = - le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input); - mpll->pll_in_max = - le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input); - - rdev->clock.default_sclk = - le32_to_cpu(firmware_info->info.ulDefaultEngineClock); - rdev->clock.default_mclk = - le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); - - if (ASIC_IS_DCE4(rdev)) { - rdev->clock.default_dispclk = - le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq); - if (rdev->clock.default_dispclk == 0) { - if (ASIC_IS_DCE5(rdev)) - rdev->clock.default_dispclk = 54000; /* 540 Mhz */ - else - rdev->clock.default_dispclk = 60000; /* 600 Mhz */ - } - rdev->clock.dp_extclk = - le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq); - } - *dcpll = *p1pll; - - rdev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock); - if (rdev->clock.max_pixel_clock == 0) - rdev->clock.max_pixel_clock = 40000; - - return true; - } - - return false; -} - -union igp_info { - struct _ATOM_INTEGRATED_SYSTEM_INFO info; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; -}; - -bool radeon_atombios_sideport_present(struct radeon_device *rdev) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); - union igp_info *igp_info; - u8 frev, crev; - u16 data_offset; - - /* sideport is AMD only */ - if (rdev->family == CHIP_RS600) - return false; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - igp_info = (union igp_info *)(mode_info->atom_context->bios + - data_offset); - switch (crev) { - case 1: - if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock)) - return true; - break; - case 2: - if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock)) - return true; - break; - default: - DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); - break; - } - } - return false; -} - -bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, - struct radeon_encoder_int_tmds *tmds) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, TMDS_Info); - uint16_t data_offset; - struct _ATOM_TMDS_INFO *tmds_info; - uint8_t frev, crev; - uint16_t maxfreq; - int i; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - tmds_info = - (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + - data_offset); - - maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); - for (i = 0; i < 4; i++) { - tmds->tmds_pll[i].freq = - le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency); - tmds->tmds_pll[i].value = - tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f; - tmds->tmds_pll[i].value |= - (tmds_info->asMiscInfo[i]. - ucPLL_VCO_Gain & 0x3f) << 6; - tmds->tmds_pll[i].value |= - (tmds_info->asMiscInfo[i]. - ucPLL_DutyCycle & 0xf) << 12; - tmds->tmds_pll[i].value |= - (tmds_info->asMiscInfo[i]. - ucPLL_VoltageSwing & 0xf) << 16; - - DRM_DEBUG_KMS("TMDS PLL From ATOMBIOS %u %x\n", - tmds->tmds_pll[i].freq, - tmds->tmds_pll[i].value); - - if (maxfreq == tmds->tmds_pll[i].freq) { - tmds->tmds_pll[i].freq = 0xffffffff; - break; - } - } - return true; - } - return false; -} - -bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, - struct radeon_atom_ss *ss, - int id) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); - uint16_t data_offset, size; - struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; - uint8_t frev, crev; - int i, num_indices; - - memset(ss, 0, sizeof(struct radeon_atom_ss)); - if (atom_parse_data_header(mode_info->atom_context, index, &size, - &frev, &crev, &data_offset)) { - ss_info = - (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); - - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT); - - for (i = 0; i < num_indices; i++) { - if (ss_info->asSS_Info[i].ucSS_Id == id) { - ss->percentage = - le16_to_cpu(ss_info->asSS_Info[i].usSpreadSpectrumPercentage); - ss->type = ss_info->asSS_Info[i].ucSpreadSpectrumType; - ss->step = ss_info->asSS_Info[i].ucSS_Step; - ss->delay = ss_info->asSS_Info[i].ucSS_Delay; - ss->range = ss_info->asSS_Info[i].ucSS_Range; - ss->refdiv = ss_info->asSS_Info[i].ucRecommendedRef_Div; - return true; - } - } - } - return false; -} - -static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, - struct radeon_atom_ss *ss, - int id) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); - u16 data_offset, size; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; - u8 frev, crev; - u16 percentage = 0, rate = 0; - - /* get any igp specific overrides */ - if (atom_parse_data_header(mode_info->atom_context, index, &size, - &frev, &crev, &data_offset)) { - igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) - (mode_info->atom_context->bios + data_offset); - switch (id) { - case ASIC_INTERNAL_SS_ON_TMDS: - percentage = le16_to_cpu(igp_info->usDVISSPercentage); - rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); - break; - case ASIC_INTERNAL_SS_ON_HDMI: - percentage = le16_to_cpu(igp_info->usHDMISSPercentage); - rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); - break; - case ASIC_INTERNAL_SS_ON_LVDS: - percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); - rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); - break; - } - if (percentage) - ss->percentage = percentage; - if (rate) - ss->rate = rate; - } -} - -union asic_ss_info { - struct _ATOM_ASIC_INTERNAL_SS_INFO info; - struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; - struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 info_3; -}; - -bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, - struct radeon_atom_ss *ss, - int id, u32 clock) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); - uint16_t data_offset, size; - union asic_ss_info *ss_info; - uint8_t frev, crev; - int i, num_indices; - - memset(ss, 0, sizeof(struct radeon_atom_ss)); - if (atom_parse_data_header(mode_info->atom_context, index, &size, - &frev, &crev, &data_offset)) { - - ss_info = - (union asic_ss_info *)(mode_info->atom_context->bios + data_offset); - - switch (frev) { - case 1: - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_ASIC_SS_ASSIGNMENT); - - for (i = 0; i < num_indices; i++) { - if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { - ss->percentage = - le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); - ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; - ss->rate = le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadRateInKhz); - return true; - } - } - break; - case 2: - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); - for (i = 0; i < num_indices; i++) { - if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { - ss->percentage = - le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); - ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; - ss->rate = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadRateIn10Hz); - return true; - } - } - break; - case 3: - num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / - sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); - for (i = 0; i < num_indices; i++) { - if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { - ss->percentage = - le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); - ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; - ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); - if (rdev->flags & RADEON_IS_IGP) - radeon_atombios_get_igp_ss_overrides(rdev, ss, id); - return true; - } - } - break; - default: - DRM_ERROR("Unsupported ASIC_InternalSS_Info table: %d %d\n", frev, crev); - break; - } - - } - return false; -} - -union lvds_info { - struct _ATOM_LVDS_INFO info; - struct _ATOM_LVDS_INFO_V12 info_12; -}; - -struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct - radeon_encoder - *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, LVDS_Info); - uint16_t data_offset, misc; - union lvds_info *lvds_info; - uint8_t frev, crev; - struct radeon_encoder_atom_dig *lvds = NULL; - int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - lvds_info = - (union lvds_info *)(mode_info->atom_context->bios + data_offset); - lvds = - kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); - - if (!lvds) - return NULL; - - lvds->native_mode.clock = - le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; - lvds->native_mode.hdisplay = - le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); - lvds->native_mode.vdisplay = - le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); - lvds->native_mode.htotal = lvds->native_mode.hdisplay + - le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); - lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + - le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); - lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + - le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); - lvds->native_mode.vtotal = lvds->native_mode.vdisplay + - le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); - lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + - le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); - lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + - le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); - lvds->panel_pwr_delay = - le16_to_cpu(lvds_info->info.usOffDelayInMs); - lvds->lcd_misc = lvds_info->info.ucLVDS_Misc; - - misc = le16_to_cpu(lvds_info->info.sLCDTiming.susModeMiscInfo.usAccess); - if (misc & ATOM_VSYNC_POLARITY) - lvds->native_mode.flags |= DRM_MODE_FLAG_NVSYNC; - if (misc & ATOM_HSYNC_POLARITY) - lvds->native_mode.flags |= DRM_MODE_FLAG_NHSYNC; - if (misc & ATOM_COMPOSITESYNC) - lvds->native_mode.flags |= DRM_MODE_FLAG_CSYNC; - if (misc & ATOM_INTERLACE) - lvds->native_mode.flags |= DRM_MODE_FLAG_INTERLACE; - if (misc & ATOM_DOUBLE_CLOCK_MODE) - lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; - - lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize); - lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize); - - /* set crtc values */ - drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); - - lvds->lcd_ss_id = lvds_info->info.ucSS_Id; - - encoder->native_mode = lvds->native_mode; - - if (encoder_enum == 2) - lvds->linkb = true; - else - lvds->linkb = false; - - /* parse the lcd record table */ - if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) { - ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; - ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; - bool bad_record = false; - u8 *record; - - if ((frev == 1) && (crev < 2)) - /* absolute */ - record = (u8 *)(mode_info->atom_context->bios + - le16_to_cpu(lvds_info->info.usModePatchTableOffset)); - else - /* relative */ - record = (u8 *)(mode_info->atom_context->bios + - data_offset + - le16_to_cpu(lvds_info->info.usModePatchTableOffset)); - while (*record != ATOM_RECORD_END_TYPE) { - switch (*record) { - case LCD_MODE_PATCH_RECORD_MODE_TYPE: - record += sizeof(ATOM_PATCH_RECORD_MODE); - break; - case LCD_RTS_RECORD_TYPE: - record += sizeof(ATOM_LCD_RTS_RECORD); - break; - case LCD_CAP_RECORD_TYPE: - record += sizeof(ATOM_LCD_MODE_CONTROL_CAP); - break; - case LCD_FAKE_EDID_PATCH_RECORD_TYPE: - fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; - if (fake_edid_record->ucFakeEDIDLength) { - struct edid *edid; - int edid_size = - max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength); - edid = kmalloc(edid_size, GFP_KERNEL); - if (edid) { - memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], - fake_edid_record->ucFakeEDIDLength); - - if (drm_edid_is_valid(edid)) { - rdev->mode_info.bios_hardcoded_edid = edid; - rdev->mode_info.bios_hardcoded_edid_size = edid_size; - } else - kfree(edid); - } - } - record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); - break; - case LCD_PANEL_RESOLUTION_RECORD_TYPE: - panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; - lvds->native_mode.width_mm = panel_res_record->usHSize; - lvds->native_mode.height_mm = panel_res_record->usVSize; - record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); - break; - default: - DRM_ERROR("Bad LCD record %d\n", *record); - bad_record = true; - break; - } - if (bad_record) - break; - } - } - } - return lvds; -} - -struct radeon_encoder_primary_dac * -radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, CompassionateData); - uint16_t data_offset; - struct _COMPASSIONATE_DATA *dac_info; - uint8_t frev, crev; - uint8_t bg, dac; - struct radeon_encoder_primary_dac *p_dac = NULL; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - dac_info = (struct _COMPASSIONATE_DATA *) - (mode_info->atom_context->bios + data_offset); - - p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); - - if (!p_dac) - return NULL; - - bg = dac_info->ucDAC1_BG_Adjustment; - dac = dac_info->ucDAC1_DAC_Adjustment; - p_dac->ps2_pdac_adj = (bg << 8) | (dac); - - } - return p_dac; -} - -bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, - struct drm_display_mode *mode) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - ATOM_ANALOG_TV_INFO *tv_info; - ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2; - ATOM_DTD_FORMAT *dtd_timings; - int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); - u8 frev, crev; - u16 data_offset, misc; - - if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL, - &frev, &crev, &data_offset)) - return false; - - switch (crev) { - case 1: - tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); - if (index >= MAX_SUPPORTED_TV_TIMING) - return false; - - mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); - mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); - mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); - mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) + - le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); - - mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); - mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); - mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); - mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) + - le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); - - mode->flags = 0; - misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess); - if (misc & ATOM_VSYNC_POLARITY) - mode->flags |= DRM_MODE_FLAG_NVSYNC; - if (misc & ATOM_HSYNC_POLARITY) - mode->flags |= DRM_MODE_FLAG_NHSYNC; - if (misc & ATOM_COMPOSITESYNC) - mode->flags |= DRM_MODE_FLAG_CSYNC; - if (misc & ATOM_INTERLACE) - mode->flags |= DRM_MODE_FLAG_INTERLACE; - if (misc & ATOM_DOUBLE_CLOCK_MODE) - mode->flags |= DRM_MODE_FLAG_DBLSCAN; - - mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; - - if (index == 1) { - /* PAL timings appear to have wrong values for totals */ - mode->crtc_htotal -= 1; - mode->crtc_vtotal -= 1; - } - break; - case 2: - tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); - if (index >= MAX_SUPPORTED_TV_TIMING_V1_2) - return false; - - dtd_timings = &tv_info_v1_2->aModeTimings[index]; - mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) + - le16_to_cpu(dtd_timings->usHBlanking_Time); - mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive); - mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) + - le16_to_cpu(dtd_timings->usHSyncOffset); - mode->crtc_hsync_end = mode->crtc_hsync_start + - le16_to_cpu(dtd_timings->usHSyncWidth); - - mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) + - le16_to_cpu(dtd_timings->usVBlanking_Time); - mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive); - mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) + - le16_to_cpu(dtd_timings->usVSyncOffset); - mode->crtc_vsync_end = mode->crtc_vsync_start + - le16_to_cpu(dtd_timings->usVSyncWidth); - - mode->flags = 0; - misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); - if (misc & ATOM_VSYNC_POLARITY) - mode->flags |= DRM_MODE_FLAG_NVSYNC; - if (misc & ATOM_HSYNC_POLARITY) - mode->flags |= DRM_MODE_FLAG_NHSYNC; - if (misc & ATOM_COMPOSITESYNC) - mode->flags |= DRM_MODE_FLAG_CSYNC; - if (misc & ATOM_INTERLACE) - mode->flags |= DRM_MODE_FLAG_INTERLACE; - if (misc & ATOM_DOUBLE_CLOCK_MODE) - mode->flags |= DRM_MODE_FLAG_DBLSCAN; - - mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; - break; - } - return true; -} - -enum radeon_tv_std -radeon_atombios_get_tv_info(struct radeon_device *rdev) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); - uint16_t data_offset; - uint8_t frev, crev; - struct _ATOM_ANALOG_TV_INFO *tv_info; - enum radeon_tv_std tv_std = TV_STD_NTSC; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - - tv_info = (struct _ATOM_ANALOG_TV_INFO *) - (mode_info->atom_context->bios + data_offset); - - switch (tv_info->ucTV_BootUpDefaultStandard) { - case ATOM_TV_NTSC: - tv_std = TV_STD_NTSC; - DRM_DEBUG_KMS("Default TV standard: NTSC\n"); - break; - case ATOM_TV_NTSCJ: - tv_std = TV_STD_NTSC_J; - DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); - break; - case ATOM_TV_PAL: - tv_std = TV_STD_PAL; - DRM_DEBUG_KMS("Default TV standard: PAL\n"); - break; - case ATOM_TV_PALM: - tv_std = TV_STD_PAL_M; - DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); - break; - case ATOM_TV_PALN: - tv_std = TV_STD_PAL_N; - DRM_DEBUG_KMS("Default TV standard: PAL-N\n"); - break; - case ATOM_TV_PALCN: - tv_std = TV_STD_PAL_CN; - DRM_DEBUG_KMS("Default TV standard: PAL-CN\n"); - break; - case ATOM_TV_PAL60: - tv_std = TV_STD_PAL_60; - DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); - break; - case ATOM_TV_SECAM: - tv_std = TV_STD_SECAM; - DRM_DEBUG_KMS("Default TV standard: SECAM\n"); - break; - default: - tv_std = TV_STD_NTSC; - DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n"); - break; - } - } - return tv_std; -} - -struct radeon_encoder_tv_dac * -radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, CompassionateData); - uint16_t data_offset; - struct _COMPASSIONATE_DATA *dac_info; - uint8_t frev, crev; - uint8_t bg, dac; - struct radeon_encoder_tv_dac *tv_dac = NULL; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - - dac_info = (struct _COMPASSIONATE_DATA *) - (mode_info->atom_context->bios + data_offset); - - tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); - - if (!tv_dac) - return NULL; - - bg = dac_info->ucDAC2_CRT2_BG_Adjustment; - dac = dac_info->ucDAC2_CRT2_DAC_Adjustment; - tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); - - bg = dac_info->ucDAC2_PAL_BG_Adjustment; - dac = dac_info->ucDAC2_PAL_DAC_Adjustment; - tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); - - bg = dac_info->ucDAC2_NTSC_BG_Adjustment; - dac = dac_info->ucDAC2_NTSC_DAC_Adjustment; - tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); - - tv_dac->tv_std = radeon_atombios_get_tv_info(rdev); - } - return tv_dac; -} - -static const char *thermal_controller_names[] = { - "NONE", - "lm63", - "adm1032", - "adm1030", - "max6649", - "lm64", - "f75375", - "asc7xxx", -}; - -static const char *pp_lib_thermal_controller_names[] = { - "NONE", - "lm63", - "adm1032", - "adm1030", - "max6649", - "lm64", - "f75375", - "RV6xx", - "RV770", - "adt7473", - "NONE", - "External GPIO", - "Evergreen", - "emc2103", - "Sumo", - "Northern Islands", - "Southern Islands", - "lm96163", -}; - -union power_info { - struct _ATOM_POWERPLAY_INFO info; - struct _ATOM_POWERPLAY_INFO_V2 info_2; - struct _ATOM_POWERPLAY_INFO_V3 info_3; - struct _ATOM_PPLIB_POWERPLAYTABLE pplib; - struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2; - struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3; -}; - -union pplib_clock_info { - struct _ATOM_PPLIB_R600_CLOCK_INFO r600; - struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; - struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; - struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; - struct _ATOM_PPLIB_SI_CLOCK_INFO si; -}; - -union pplib_power_state { - struct _ATOM_PPLIB_STATE v1; - struct _ATOM_PPLIB_STATE_V2 v2; -}; - -static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev, - int state_index, - u32 misc, u32 misc2) -{ - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - /* order matters! */ - if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_POWERSAVE; - if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } - if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[0]; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } -} - -static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - u32 misc, misc2 = 0; - int num_modes = 0, i; - int state_index = 0; - struct radeon_i2c_bus_rec i2c_bus; - union power_info *power_info; - int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); - u16 data_offset; - u8 frev, crev; - - if (!atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) - return state_index; - power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - - /* add the i2c bus for thermal/fan chip */ - if (power_info->info.ucOverdriveThermalController > 0) { - DRM_INFO("Possible %s thermal controller at 0x%02x\n", - thermal_controller_names[power_info->info.ucOverdriveThermalController], - power_info->info.ucOverdriveControllerAddress >> 1); - i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = thermal_controller_names[power_info->info. - ucOverdriveThermalController]; - info.addr = power_info->info.ucOverdriveControllerAddress >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } - } - num_modes = power_info->info.ucNumOfPowerModeEntries; - if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) - num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); - if (!rdev->pm.power_state) - return state_index; - /* last mode is usually default, array is low to high */ - for (i = 0; i < num_modes; i++) { - rdev->pm.power_state[state_index].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); - if (!rdev->pm.power_state[state_index].clock_info) - return state_index; - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - switch (frev) { - case 1: - rdev->pm.power_state[state_index].clock_info[0].mclk = - le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); - rdev->pm.power_state[state_index].clock_info[0].sclk = - le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - continue; - rdev->pm.power_state[state_index].pcie_lanes = - power_info->info.asPowerPlayInfo[i].ucNumPciELanes; - misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); - if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || - (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_GPIO; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = - radeon_lookup_gpio(rdev, - power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_VDDC; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = - power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; - } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0); - state_index++; - break; - case 2: - rdev->pm.power_state[state_index].clock_info[0].mclk = - le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); - rdev->pm.power_state[state_index].clock_info[0].sclk = - le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - continue; - rdev->pm.power_state[state_index].pcie_lanes = - power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; - misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); - misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); - if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || - (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_GPIO; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = - radeon_lookup_gpio(rdev, - power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_VDDC; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = - power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; - } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); - state_index++; - break; - case 3: - rdev->pm.power_state[state_index].clock_info[0].mclk = - le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); - rdev->pm.power_state[state_index].clock_info[0].sclk = - le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - continue; - rdev->pm.power_state[state_index].pcie_lanes = - power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; - misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); - misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); - if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || - (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_GPIO; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = - radeon_lookup_gpio(rdev, - power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_VDDC; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = - power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; - if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { - rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = - true; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = - power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; - } - } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); - state_index++; - break; - } - } - /* last mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[state_index - 1].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index - 1; - rdev->pm.power_state[state_index - 1].default_clock_mode = - &rdev->pm.power_state[state_index - 1].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = 0; - rdev->pm.power_state[state_index].misc2 = 0; - } - return state_index; -} - -static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev, - ATOM_PPLIB_THERMALCONTROLLER *controller) -{ - struct radeon_i2c_bus_rec i2c_bus; - - /* add the i2c bus for thermal/fan chip */ - if (controller->ucType > 0) { - if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_NI; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_SI; - } else if ((controller->ucType == - ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || - (controller->ucType == - ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || - (controller->ucType == - ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { - DRM_INFO("Special thermal controller config\n"); - } else { - DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", - pp_lib_thermal_controller_names[controller->ucType], - controller->ucI2cAddress >> 1, - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = pp_lib_thermal_controller_names[controller->ucType]; - info.addr = controller->ucI2cAddress >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } - } - } -} - -static void radeon_atombios_get_default_voltages(struct radeon_device *rdev, - u16 *vddc, u16 *vddci) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); - u8 frev, crev; - u16 data_offset; - union firmware_info *firmware_info; - - *vddc = 0; - *vddci = 0; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - firmware_info = - (union firmware_info *)(mode_info->atom_context->bios + - data_offset); - *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); - if ((frev == 2) && (crev >= 2)) - *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage); - } -} - -static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, - int state_index, int mode_index, - struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) -{ - int j; - u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); - u32 misc2 = le16_to_cpu(non_clock_info->usClassification); - u16 vddc, vddci; - - radeon_atombios_get_default_voltages(rdev, &vddc, &vddci); - - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - rdev->pm.power_state[state_index].pcie_lanes = - ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> - ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; - switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { - case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - break; - case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - break; - case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - break; - case ATOM_PPLIB_CLASSIFICATION_UI_NONE: - if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - break; - } - rdev->pm.power_state[state_index].flags = 0; - if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) - rdev->pm.power_state[state_index].flags |= - RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; - if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) { - /* NI chips post without MC ucode, so default clocks are strobe mode only */ - rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; - rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; - rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; - rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci; - } else { - /* patch the table values with the default slck/mclk from firmware info */ - for (j = 0; j < mode_index; j++) { - rdev->pm.power_state[state_index].clock_info[j].mclk = - rdev->clock.default_mclk; - rdev->pm.power_state[state_index].clock_info[j].sclk = - rdev->clock.default_sclk; - if (vddc) - rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = - vddc; - } - } - } -} - -static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, - int state_index, int mode_index, - union pplib_clock_info *clock_info) -{ - u32 sclk, mclk; - u16 vddc; - - if (rdev->flags & RADEON_IS_IGP) { - if (rdev->family >= CHIP_PALM) { - sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); - sclk |= clock_info->sumo.ucEngineClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - } else { - sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); - sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - } - } else if (ASIC_IS_DCE6(rdev)) { - sclk = le16_to_cpu(clock_info->si.usEngineClockLow); - sclk |= clock_info->si.ucEngineClockHigh << 16; - mclk = le16_to_cpu(clock_info->si.usMemoryClockLow); - mclk |= clock_info->si.ucMemoryClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - le16_to_cpu(clock_info->si.usVDDC); - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci = - le16_to_cpu(clock_info->si.usVDDCI); - } else if (ASIC_IS_DCE4(rdev)) { - sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); - sclk |= clock_info->evergreen.ucEngineClockHigh << 16; - mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow); - mclk |= clock_info->evergreen.ucMemoryClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - le16_to_cpu(clock_info->evergreen.usVDDC); - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci = - le16_to_cpu(clock_info->evergreen.usVDDCI); - } else { - sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); - sclk |= clock_info->r600.ucEngineClockHigh << 16; - mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); - mclk |= clock_info->r600.ucMemoryClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - le16_to_cpu(clock_info->r600.usVDDC); - } - - /* patch up vddc if necessary */ - switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) { - case ATOM_VIRTUAL_VOLTAGE_ID0: - case ATOM_VIRTUAL_VOLTAGE_ID1: - case ATOM_VIRTUAL_VOLTAGE_ID2: - case ATOM_VIRTUAL_VOLTAGE_ID3: - if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage, - &vddc) == 0) - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; - break; - default: - break; - } - - if (rdev->flags & RADEON_IS_IGP) { - /* skip invalid modes */ - if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) - return false; - } else { - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) - return false; - } - return true; -} - -static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; - union pplib_power_state *power_state; - int i, j; - int state_index = 0, mode_index = 0; - union pplib_clock_info *clock_info; - bool valid; - union power_info *power_info; - int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); - u16 data_offset; - u8 frev, crev; - - if (!atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) - return state_index; - power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - - radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * - power_info->pplib.ucNumStates, GFP_KERNEL); - if (!rdev->pm.power_state) - return state_index; - /* first mode is usually default, followed by low to high */ - for (i = 0; i < power_info->pplib.ucNumStates; i++) { - mode_index = 0; - power_state = (union pplib_power_state *) - (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usStateArrayOffset) + - i * power_info->pplib.ucStateEntrySize); - non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) - (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + - (power_state->v1.ucNonClockStateIndex * - power_info->pplib.ucNonClockSize)); - rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * - ((power_info->pplib.ucStateEntrySize - 1) ? - (power_info->pplib.ucStateEntrySize - 1) : 1), - GFP_KERNEL); - if (!rdev->pm.power_state[i].clock_info) - return state_index; - if (power_info->pplib.ucStateEntrySize - 1) { - for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { - clock_info = (union pplib_clock_info *) - (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + - (power_state->v1.ucClockStateIndices[j] * - power_info->pplib.ucClockInfoSize)); - valid = radeon_atombios_parse_pplib_clock_info(rdev, - state_index, mode_index, - clock_info); - if (valid) - mode_index++; - } - } else { - rdev->pm.power_state[state_index].clock_info[0].mclk = - rdev->clock.default_mclk; - rdev->pm.power_state[state_index].clock_info[0].sclk = - rdev->clock.default_sclk; - mode_index++; - } - rdev->pm.power_state[state_index].num_clock_modes = mode_index; - if (mode_index) { - radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, - non_clock_info); - state_index++; - } - } - /* if multiple clock modes, mark the lowest as no display */ - for (i = 0; i < state_index; i++) { - if (rdev->pm.power_state[i].num_clock_modes > 1) - rdev->pm.power_state[i].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - /* first mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[0].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = 0; - rdev->pm.power_state[0].default_clock_mode = - &rdev->pm.power_state[0].clock_info[0]; - } - return state_index; -} - -static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; - union pplib_power_state *power_state; - int i, j, non_clock_array_index, clock_array_index; - int state_index = 0, mode_index = 0; - union pplib_clock_info *clock_info; - struct _StateArray *state_array; - struct _ClockInfoArray *clock_info_array; - struct _NonClockInfoArray *non_clock_info_array; - bool valid; - union power_info *power_info; - int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); - u16 data_offset; - u8 frev, crev; - - if (!atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) - return state_index; - power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - - radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); - state_array = (struct _StateArray *) - (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usStateArrayOffset)); - clock_info_array = (struct _ClockInfoArray *) - (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usClockInfoArrayOffset)); - non_clock_info_array = (struct _NonClockInfoArray *) - (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * - state_array->ucNumEntries, GFP_KERNEL); - if (!rdev->pm.power_state) - return state_index; - for (i = 0; i < state_array->ucNumEntries; i++) { - mode_index = 0; - power_state = (union pplib_power_state *)&state_array->states[i]; - /* XXX this might be an inagua bug... */ - non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ - non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) - &non_clock_info_array->nonClockInfo[non_clock_array_index]; - rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * - (power_state->v2.ucNumDPMLevels ? - power_state->v2.ucNumDPMLevels : 1), - GFP_KERNEL); - if (!rdev->pm.power_state[i].clock_info) - return state_index; - if (power_state->v2.ucNumDPMLevels) { - for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { - clock_array_index = power_state->v2.clockInfoIndex[j]; - /* XXX this might be an inagua bug... */ - if (clock_array_index >= clock_info_array->ucNumEntries) - continue; - clock_info = (union pplib_clock_info *) - &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; - valid = radeon_atombios_parse_pplib_clock_info(rdev, - state_index, mode_index, - clock_info); - if (valid) - mode_index++; - } - } else { - rdev->pm.power_state[state_index].clock_info[0].mclk = - rdev->clock.default_mclk; - rdev->pm.power_state[state_index].clock_info[0].sclk = - rdev->clock.default_sclk; - mode_index++; - } - rdev->pm.power_state[state_index].num_clock_modes = mode_index; - if (mode_index) { - radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, - non_clock_info); - state_index++; - } - } - /* if multiple clock modes, mark the lowest as no display */ - for (i = 0; i < state_index; i++) { - if (rdev->pm.power_state[i].num_clock_modes > 1) - rdev->pm.power_state[i].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - /* first mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[0].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = 0; - rdev->pm.power_state[0].default_clock_mode = - &rdev->pm.power_state[0].clock_info[0]; - } - return state_index; -} - -void radeon_atombios_get_power_modes(struct radeon_device *rdev) -{ - struct radeon_mode_info *mode_info = &rdev->mode_info; - int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); - u16 data_offset; - u8 frev, crev; - int state_index = 0; - - rdev->pm.default_power_state_index = -1; - - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - switch (frev) { - case 1: - case 2: - case 3: - state_index = radeon_atombios_parse_power_table_1_3(rdev); - break; - case 4: - case 5: - state_index = radeon_atombios_parse_power_table_4_5(rdev); - break; - case 6: - state_index = radeon_atombios_parse_power_table_6(rdev); - break; - default: - break; - } - } else { - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); - if (rdev->pm.power_state) { - rdev->pm.power_state[0].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); - if (rdev->pm.power_state[0].clock_info) { - /* add the default mode */ - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; - rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - rdev->pm.power_state[state_index].pcie_lanes = 16; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].flags = 0; - state_index++; - } - } - } - - rdev->pm.num_power_states = state_index; - - rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.current_clock_mode_index = 0; - if (rdev->pm.default_power_state_index >= 0) - rdev->pm.current_vddc = - rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; - else - rdev->pm.current_vddc = 0; -} - -void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) -{ - DYNAMIC_CLOCK_GATING_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, DynamicClockGating); - - args.ucEnable = enable; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) -{ - GET_ENGINE_CLOCK_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return le32_to_cpu(args.ulReturnEngineClock); -} - -uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) -{ - GET_MEMORY_CLOCK_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return le32_to_cpu(args.ulReturnMemoryClock); -} - -void radeon_atom_set_engine_clock(struct radeon_device *rdev, - uint32_t eng_clock) -{ - SET_ENGINE_CLOCK_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); - - args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */ - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -void radeon_atom_set_memory_clock(struct radeon_device *rdev, - uint32_t mem_clock) -{ - SET_MEMORY_CLOCK_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock); - - if (rdev->flags & RADEON_IS_IGP) - return; - - args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */ - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -union set_voltage { - struct _SET_VOLTAGE_PS_ALLOCATION alloc; - struct _SET_VOLTAGE_PARAMETERS v1; - struct _SET_VOLTAGE_PARAMETERS_V2 v2; - struct _SET_VOLTAGE_PARAMETERS_V1_3 v3; -}; - -void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type) -{ - union set_voltage args; - int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); - u8 frev, crev, volt_index = voltage_level; - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return; - - /* 0xff01 is a flag rather then an actual voltage */ - if (voltage_level == 0xff01) - return; - - switch (crev) { - case 1: - args.v1.ucVoltageType = voltage_type; - args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; - args.v1.ucVoltageIndex = volt_index; - break; - case 2: - args.v2.ucVoltageType = voltage_type; - args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; - args.v2.usVoltageLevel = cpu_to_le16(voltage_level); - break; - case 3: - args.v3.ucVoltageType = voltage_type; - args.v3.ucVoltageMode = ATOM_SET_VOLTAGE; - args.v3.usVoltageLevel = cpu_to_le16(voltage_level); - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - return; - } - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -} - -static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, - u16 voltage_id, u16 *voltage) -{ - union set_voltage args; - int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); - u8 frev, crev; - - if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) - return -EINVAL; - - switch (crev) { - case 1: - return -EINVAL; - case 2: - args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; - args.v2.ucVoltageMode = 0; - args.v2.usVoltageLevel = 0; - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - *voltage = le16_to_cpu(args.v2.usVoltageLevel); - break; - case 3: - args.v3.ucVoltageType = voltage_type; - args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL; - args.v3.usVoltageLevel = cpu_to_le16(voltage_id); - - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - - *voltage = le16_to_cpu(args.v3.usVoltageLevel); - break; - default: - DRM_ERROR("Unknown table version %d, %d\n", frev, crev); - return -EINVAL; - } - - return 0; -} - -void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t bios_2_scratch, bios_6_scratch; - - if (rdev->family >= CHIP_R600) { - bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); - bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); - } else { - bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); - bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - } - - /* let the bios control the backlight */ - bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; - - /* tell the bios not to handle mode switching */ - bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH; - - if (rdev->family >= CHIP_R600) { - WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); - WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); - } else { - WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch); - WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); - } - -} - -void radeon_save_bios_scratch_regs(struct radeon_device *rdev) -{ - uint32_t scratch_reg; - int i; - - if (rdev->family >= CHIP_R600) - scratch_reg = R600_BIOS_0_SCRATCH; - else - scratch_reg = RADEON_BIOS_0_SCRATCH; - - for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) - rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4)); -} - -void radeon_restore_bios_scratch_regs(struct radeon_device *rdev) -{ - uint32_t scratch_reg; - int i; - - if (rdev->family >= CHIP_R600) - scratch_reg = R600_BIOS_0_SCRATCH; - else - scratch_reg = RADEON_BIOS_0_SCRATCH; - - for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) - WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]); -} - -void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t bios_6_scratch; - - if (rdev->family >= CHIP_R600) - bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); - else - bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - - if (lock) { - bios_6_scratch |= ATOM_S6_CRITICAL_STATE; - bios_6_scratch &= ~ATOM_S6_ACC_MODE; - } else { - bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; - bios_6_scratch |= ATOM_S6_ACC_MODE; - } - - if (rdev->family >= CHIP_R600) - WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); - else - WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); -} - -/* at some point we may want to break this out into individual functions */ -void -radeon_atombios_connected_scratch_regs(struct drm_connector *connector, - struct drm_encoder *encoder, - bool connected) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = - to_radeon_connector(connector); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t bios_0_scratch, bios_3_scratch, bios_6_scratch; - - if (rdev->family >= CHIP_R600) { - bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH); - bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); - bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); - } else { - bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); - bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH); - bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - } - - if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("TV1 connected\n"); - bios_3_scratch |= ATOM_S3_TV1_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_TV1; - } else { - DRM_DEBUG_KMS("TV1 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_TV1_MASK; - bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_TV1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("CV connected\n"); - bios_3_scratch |= ATOM_S3_CV_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_CV; - } else { - DRM_DEBUG_KMS("CV disconnected\n"); - bios_0_scratch &= ~ATOM_S0_CV_MASK; - bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_CV; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("LCD1 connected\n"); - bios_0_scratch |= ATOM_S0_LCD1; - bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_LCD1; - } else { - DRM_DEBUG_KMS("LCD1 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_LCD1; - bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_LCD1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("CRT1 connected\n"); - bios_0_scratch |= ATOM_S0_CRT1_COLOR; - bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_CRT1; - } else { - DRM_DEBUG_KMS("CRT1 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_CRT1_MASK; - bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("CRT2 connected\n"); - bios_0_scratch |= ATOM_S0_CRT2_COLOR; - bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_CRT2; - } else { - DRM_DEBUG_KMS("CRT2 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_CRT2_MASK; - bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_CRT2; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP1 connected\n"); - bios_0_scratch |= ATOM_S0_DFP1; - bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_DFP1; - } else { - DRM_DEBUG_KMS("DFP1 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_DFP1; - bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP2 connected\n"); - bios_0_scratch |= ATOM_S0_DFP2; - bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_DFP2; - } else { - DRM_DEBUG_KMS("DFP2 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_DFP2; - bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP2; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP3_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP3 connected\n"); - bios_0_scratch |= ATOM_S0_DFP3; - bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_DFP3; - } else { - DRM_DEBUG_KMS("DFP3 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_DFP3; - bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP3; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP4_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP4 connected\n"); - bios_0_scratch |= ATOM_S0_DFP4; - bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_DFP4; - } else { - DRM_DEBUG_KMS("DFP4 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_DFP4; - bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP4; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP5_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP5 connected\n"); - bios_0_scratch |= ATOM_S0_DFP5; - bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_DFP5; - } else { - DRM_DEBUG_KMS("DFP5 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_DFP5; - bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP6 connected\n"); - bios_0_scratch |= ATOM_S0_DFP6; - bios_3_scratch |= ATOM_S3_DFP6_ACTIVE; - bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6; - } else { - DRM_DEBUG_KMS("DFP6 disconnected\n"); - bios_0_scratch &= ~ATOM_S0_DFP6; - bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE; - bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6; - } - } - - if (rdev->family >= CHIP_R600) { - WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); - WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch); - WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch); - } else { - WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch); - WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch); - WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); - } -} - -void -radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t bios_3_scratch; - - if (ASIC_IS_DCE4(rdev)) - return; - - if (rdev->family >= CHIP_R600) - bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); - else - bios_3_scratch = RREG32(RADEON_BIOS_3_SCRATCH); - - if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 18); - } - if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 24); - } - if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 16); - } - if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 20); - } - if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 17); - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 19); - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 23); - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) { - bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; - bios_3_scratch |= (crtc << 25); - } - - if (rdev->family >= CHIP_R600) - WREG32(R600_BIOS_3_SCRATCH, bios_3_scratch); - else - WREG32(RADEON_BIOS_3_SCRATCH, bios_3_scratch); -} - -void -radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t bios_2_scratch; - - if (ASIC_IS_DCE4(rdev)) - return; - - if (rdev->family >= CHIP_R600) - bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); - else - bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); - - if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP3_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP4_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE; - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP5_SUPPORT) { - if (on) - bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE; - else - bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE; - } - - if (rdev->family >= CHIP_R600) - WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch); - else - WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atpx_handler.c deleted file mode 100644 index 98724fcb..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2010 Red Hat Inc. - * Author : Dave Airlie - * - * Licensed under GPLv2 - * - * ATPX support for both Intel/ATI - */ -#include -#include -#include -#include -#include - -#define ATPX_VERSION 0 -#define ATPX_GPU_PWR 2 -#define ATPX_MUX_SELECT 3 -#define ATPX_I2C_MUX_SELECT 4 -#define ATPX_SWITCH_START 5 -#define ATPX_SWITCH_END 6 - -#define ATPX_INTEGRATED 0 -#define ATPX_DISCRETE 1 - -#define ATPX_MUX_IGD 0 -#define ATPX_MUX_DISCRETE 1 - -static struct radeon_atpx_priv { - bool atpx_detected; - /* handle for device - and atpx */ - acpi_handle dhandle; - acpi_handle atpx_handle; - acpi_handle atrm_handle; -} radeon_atpx_priv; - -/* retrieve the ROM in 4k blocks */ -static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, - int offset, int len) -{ - acpi_status status; - union acpi_object atrm_arg_elements[2], *obj; - struct acpi_object_list atrm_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - - atrm_arg.count = 2; - atrm_arg.pointer = &atrm_arg_elements[0]; - - atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; - atrm_arg_elements[0].integer.value = offset; - - atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; - atrm_arg_elements[1].integer.value = len; - - status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); - if (ACPI_FAILURE(status)) { - printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); - return -ENODEV; - } - - obj = (union acpi_object *)buffer.pointer; - memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); - len = obj->buffer.length; - kfree(buffer.pointer); - return len; -} - -bool radeon_atrm_supported(struct pci_dev *pdev) -{ - /* get the discrete ROM only via ATRM */ - if (!radeon_atpx_priv.atpx_detected) - return false; - - if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) - return false; - return true; -} - - -int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) -{ - return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); -} - -static int radeon_atpx_get_version(acpi_handle handle) -{ - acpi_status status; - union acpi_object atpx_arg_elements[2], *obj; - struct acpi_object_list atpx_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - - atpx_arg.count = 2; - atpx_arg.pointer = &atpx_arg_elements[0]; - - atpx_arg_elements[0].type = ACPI_TYPE_INTEGER; - atpx_arg_elements[0].integer.value = ATPX_VERSION; - - atpx_arg_elements[1].type = ACPI_TYPE_INTEGER; - atpx_arg_elements[1].integer.value = ATPX_VERSION; - - status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); - if (ACPI_FAILURE(status)) { - printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status)); - return -ENOSYS; - } - obj = (union acpi_object *)buffer.pointer; - if (obj && (obj->type == ACPI_TYPE_BUFFER)) - printk(KERN_INFO "radeon atpx: version is %d\n", *((u8 *)(obj->buffer.pointer) + 2)); - kfree(buffer.pointer); - return 0; -} - -static int radeon_atpx_execute(acpi_handle handle, int cmd_id, u16 value) -{ - acpi_status status; - union acpi_object atpx_arg_elements[2]; - struct acpi_object_list atpx_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - uint8_t buf[4] = {0}; - - if (!handle) - return -EINVAL; - - atpx_arg.count = 2; - atpx_arg.pointer = &atpx_arg_elements[0]; - - atpx_arg_elements[0].type = ACPI_TYPE_INTEGER; - atpx_arg_elements[0].integer.value = cmd_id; - - buf[2] = value & 0xff; - buf[3] = (value >> 8) & 0xff; - - atpx_arg_elements[1].type = ACPI_TYPE_BUFFER; - atpx_arg_elements[1].buffer.length = 4; - atpx_arg_elements[1].buffer.pointer = buf; - - status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); - if (ACPI_FAILURE(status)) { - printk("%s: failed to call ATPX: %s\n", __func__, acpi_format_exception(status)); - return -ENOSYS; - } - kfree(buffer.pointer); - - return 0; -} - -static int radeon_atpx_set_discrete_state(acpi_handle handle, int state) -{ - return radeon_atpx_execute(handle, ATPX_GPU_PWR, state); -} - -static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) -{ - return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); -} - -static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) -{ - return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); -} - -static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) -{ - return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); -} - -static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) -{ - return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); -} - -static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) -{ - int gpu_id; - - if (id == VGA_SWITCHEROO_IGD) - gpu_id = ATPX_INTEGRATED; - else - gpu_id = ATPX_DISCRETE; - - radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); - radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); - radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); - radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); - - return 0; -} - -static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, - enum vga_switcheroo_state state) -{ - /* on w500 ACPI can't change intel gpu state */ - if (id == VGA_SWITCHEROO_IGD) - return 0; - - radeon_atpx_set_discrete_state(radeon_atpx_priv.atpx_handle, state); - return 0; -} - -static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) -{ - acpi_handle dhandle, atpx_handle, atrm_handle; - acpi_status status; - - dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); - if (!dhandle) - return false; - - status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); - if (ACPI_FAILURE(status)) - return false; - - status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); - if (ACPI_FAILURE(status)) - return false; - - radeon_atpx_priv.dhandle = dhandle; - radeon_atpx_priv.atpx_handle = atpx_handle; - radeon_atpx_priv.atrm_handle = atrm_handle; - return true; -} - -static int radeon_atpx_init(void) -{ - /* set up the ATPX handle */ - - radeon_atpx_get_version(radeon_atpx_priv.atpx_handle); - return 0; -} - -static int radeon_atpx_get_client_id(struct pci_dev *pdev) -{ - if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) - return VGA_SWITCHEROO_IGD; - else - return VGA_SWITCHEROO_DIS; -} - -static struct vga_switcheroo_handler radeon_atpx_handler = { - .switchto = radeon_atpx_switchto, - .power_state = radeon_atpx_power_state, - .init = radeon_atpx_init, - .get_client_id = radeon_atpx_get_client_id, -}; - -static bool radeon_atpx_detect(void) -{ - char acpi_method_name[255] = { 0 }; - struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; - struct pci_dev *pdev = NULL; - bool has_atpx = false; - int vga_count = 0; - - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { - vga_count++; - - has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); - } - - if (has_atpx && vga_count == 2) { - acpi_get_name(radeon_atpx_priv.atpx_handle, ACPI_FULL_PATHNAME, &buffer); - printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", - acpi_method_name); - radeon_atpx_priv.atpx_detected = true; - return true; - } - return false; -} - -void radeon_register_atpx_handler(void) -{ - bool r; - - /* detect if we have any ATPX + 2 VGA in the system */ - r = radeon_atpx_detect(); - if (!r) - return; - - vga_switcheroo_register_handler(&radeon_atpx_handler); -} - -void radeon_unregister_atpx_handler(void) -{ - vga_switcheroo_unregister_handler(); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_benchmark.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_benchmark.c deleted file mode 100644 index fef7b722..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_benchmark.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Jerome Glisse - */ -#include -#include -#include "radeon_reg.h" -#include "radeon.h" - -#define RADEON_BENCHMARK_COPY_BLIT 1 -#define RADEON_BENCHMARK_COPY_DMA 0 - -#define RADEON_BENCHMARK_ITERATIONS 1024 -#define RADEON_BENCHMARK_COMMON_MODES_N 17 - -static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size, - uint64_t saddr, uint64_t daddr, - int flag, int n) -{ - unsigned long start_jiffies; - unsigned long end_jiffies; - struct radeon_fence *fence = NULL; - int i, r; - - start_jiffies = jiffies; - for (i = 0; i < n; i++) { - switch (flag) { - case RADEON_BENCHMARK_COPY_DMA: - r = radeon_fence_create(rdev, &fence, radeon_copy_dma_ring_index(rdev)); - if (r) - return r; - r = radeon_copy_dma(rdev, saddr, daddr, - size / RADEON_GPU_PAGE_SIZE, - fence); - break; - case RADEON_BENCHMARK_COPY_BLIT: - r = radeon_fence_create(rdev, &fence, radeon_copy_blit_ring_index(rdev)); - if (r) - return r; - r = radeon_copy_blit(rdev, saddr, daddr, - size / RADEON_GPU_PAGE_SIZE, - fence); - break; - default: - DRM_ERROR("Unknown copy method\n"); - r = -EINVAL; - } - if (r) - goto exit_do_move; - r = radeon_fence_wait(fence, false); - if (r) - goto exit_do_move; - radeon_fence_unref(&fence); - } - end_jiffies = jiffies; - r = jiffies_to_msecs(end_jiffies - start_jiffies); - -exit_do_move: - if (fence) - radeon_fence_unref(&fence); - return r; -} - - -static void radeon_benchmark_log_results(int n, unsigned size, - unsigned int time, - unsigned sdomain, unsigned ddomain, - char *kind) -{ - unsigned int throughput = (n * (size >> 10)) / time; - DRM_INFO("radeon: %s %u bo moves of %u kB from" - " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n", - kind, n, size >> 10, sdomain, ddomain, time, - throughput * 8, throughput); -} - -static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, - unsigned sdomain, unsigned ddomain) -{ - struct radeon_bo *dobj = NULL; - struct radeon_bo *sobj = NULL; - uint64_t saddr, daddr; - int r, n; - int time; - - n = RADEON_BENCHMARK_ITERATIONS; - r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); - if (r) { - goto out_cleanup; - } - r = radeon_bo_reserve(sobj, false); - if (unlikely(r != 0)) - goto out_cleanup; - r = radeon_bo_pin(sobj, sdomain, &saddr); - radeon_bo_unreserve(sobj); - if (r) { - goto out_cleanup; - } - r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, &dobj); - if (r) { - goto out_cleanup; - } - r = radeon_bo_reserve(dobj, false); - if (unlikely(r != 0)) - goto out_cleanup; - r = radeon_bo_pin(dobj, ddomain, &daddr); - radeon_bo_unreserve(dobj); - if (r) { - goto out_cleanup; - } - - /* r100 doesn't have dma engine so skip the test */ - /* also, VRAM-to-VRAM test doesn't make much sense for DMA */ - /* skip it as well if domains are the same */ - if ((rdev->asic->copy.dma) && (sdomain != ddomain)) { - time = radeon_benchmark_do_move(rdev, size, saddr, daddr, - RADEON_BENCHMARK_COPY_DMA, n); - if (time < 0) - goto out_cleanup; - if (time > 0) - radeon_benchmark_log_results(n, size, time, - sdomain, ddomain, "dma"); - } - - time = radeon_benchmark_do_move(rdev, size, saddr, daddr, - RADEON_BENCHMARK_COPY_BLIT, n); - if (time < 0) - goto out_cleanup; - if (time > 0) - radeon_benchmark_log_results(n, size, time, - sdomain, ddomain, "blit"); - -out_cleanup: - if (sobj) { - r = radeon_bo_reserve(sobj, false); - if (likely(r == 0)) { - radeon_bo_unpin(sobj); - radeon_bo_unreserve(sobj); - } - radeon_bo_unref(&sobj); - } - if (dobj) { - r = radeon_bo_reserve(dobj, false); - if (likely(r == 0)) { - radeon_bo_unpin(dobj); - radeon_bo_unreserve(dobj); - } - radeon_bo_unref(&dobj); - } - - if (r) { - DRM_ERROR("Error while benchmarking BO move.\n"); - } -} - -void radeon_benchmark(struct radeon_device *rdev, int test_number) -{ - int i; - int common_modes[RADEON_BENCHMARK_COMMON_MODES_N] = { - 640 * 480 * 4, - 720 * 480 * 4, - 800 * 600 * 4, - 848 * 480 * 4, - 1024 * 768 * 4, - 1152 * 768 * 4, - 1280 * 720 * 4, - 1280 * 800 * 4, - 1280 * 854 * 4, - 1280 * 960 * 4, - 1280 * 1024 * 4, - 1440 * 900 * 4, - 1400 * 1050 * 4, - 1680 * 1050 * 4, - 1600 * 1200 * 4, - 1920 * 1080 * 4, - 1920 * 1200 * 4 - }; - - switch (test_number) { - case 1: - /* simple test, VRAM to GTT and GTT to VRAM */ - radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_GTT, - RADEON_GEM_DOMAIN_VRAM); - radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, - RADEON_GEM_DOMAIN_GTT); - break; - case 2: - /* simple test, VRAM to VRAM */ - radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, - RADEON_GEM_DOMAIN_VRAM); - break; - case 3: - /* GTT to VRAM, buffer size sweep, powers of 2 */ - for (i = 1; i <= 16384; i <<= 1) - radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, - RADEON_GEM_DOMAIN_GTT, - RADEON_GEM_DOMAIN_VRAM); - break; - case 4: - /* VRAM to GTT, buffer size sweep, powers of 2 */ - for (i = 1; i <= 16384; i <<= 1) - radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, - RADEON_GEM_DOMAIN_VRAM, - RADEON_GEM_DOMAIN_GTT); - break; - case 5: - /* VRAM to VRAM, buffer size sweep, powers of 2 */ - for (i = 1; i <= 16384; i <<= 1) - radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, - RADEON_GEM_DOMAIN_VRAM, - RADEON_GEM_DOMAIN_VRAM); - break; - case 6: - /* GTT to VRAM, buffer size sweep, common modes */ - for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) - radeon_benchmark_move(rdev, common_modes[i], - RADEON_GEM_DOMAIN_GTT, - RADEON_GEM_DOMAIN_VRAM); - break; - case 7: - /* VRAM to GTT, buffer size sweep, common modes */ - for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) - radeon_benchmark_move(rdev, common_modes[i], - RADEON_GEM_DOMAIN_VRAM, - RADEON_GEM_DOMAIN_GTT); - break; - case 8: - /* VRAM to VRAM, buffer size sweep, common modes */ - for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) - radeon_benchmark_move(rdev, common_modes[i], - RADEON_GEM_DOMAIN_VRAM, - RADEON_GEM_DOMAIN_VRAM); - break; - - default: - DRM_ERROR("Unknown benchmark\n"); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_bios.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_bios.c deleted file mode 100644 index 501f4881..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_bios.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "atom.h" - -#include -#include -/* - * BIOS. - */ - -/* If you boot an IGP board with a discrete card as the primary, - * the IGP rom is not accessible via the rom bar as the IGP rom is - * part of the system bios. On boot, the system bios puts a - * copy of the igp rom at the start of vram if a discrete card is - * present. - */ -static bool igp_read_bios_from_vram(struct radeon_device *rdev) -{ - uint8_t __iomem *bios; - resource_size_t vram_base; - resource_size_t size = 256 * 1024; /* ??? */ - - if (!(rdev->flags & RADEON_IS_IGP)) - if (!radeon_card_posted(rdev)) - return false; - - rdev->bios = NULL; - vram_base = pci_resource_start(rdev->pdev, 0); - bios = ioremap(vram_base, size); - if (!bios) { - return false; - } - - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { - iounmap(bios); - return false; - } - rdev->bios = kmalloc(size, GFP_KERNEL); - if (rdev->bios == NULL) { - iounmap(bios); - return false; - } - memcpy_fromio(rdev->bios, bios, size); - iounmap(bios); - return true; -} - -static bool radeon_read_bios(struct radeon_device *rdev) -{ - uint8_t __iomem *bios; - size_t size; - - rdev->bios = NULL; - /* XXX: some cards may return 0 for rom size? ddx has a workaround */ - bios = pci_map_rom(rdev->pdev, &size); - if (!bios) { - return false; - } - - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { - pci_unmap_rom(rdev->pdev, bios); - return false; - } - rdev->bios = kmemdup(bios, size, GFP_KERNEL); - if (rdev->bios == NULL) { - pci_unmap_rom(rdev->pdev, bios); - return false; - } - pci_unmap_rom(rdev->pdev, bios); - return true; -} - -/* ATRM is used to get the BIOS on the discrete cards in - * dual-gpu systems. - */ -static bool radeon_atrm_get_bios(struct radeon_device *rdev) -{ - int ret; - int size = 256 * 1024; - int i; - - if (!radeon_atrm_supported(rdev->pdev)) - return false; - - rdev->bios = kmalloc(size, GFP_KERNEL); - if (!rdev->bios) { - DRM_ERROR("Unable to allocate bios\n"); - return false; - } - - for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { - ret = radeon_atrm_get_bios_chunk(rdev->bios, - (i * ATRM_BIOS_PAGE), - ATRM_BIOS_PAGE); - if (ret < ATRM_BIOS_PAGE) - break; - } - - if (i == 0 || rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { - kfree(rdev->bios); - return false; - } - return true; -} - -static bool ni_read_disabled_bios(struct radeon_device *rdev) -{ - u32 bus_cntl; - u32 d1vga_control; - u32 d2vga_control; - u32 vga_render_control; - u32 rom_cntl; - bool r; - - bus_cntl = RREG32(R600_BUS_CNTL); - d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); - d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); - vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); - rom_cntl = RREG32(R600_ROM_CNTL); - - /* enable the rom */ - WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); - /* Disable VGA mode */ - WREG32(AVIVO_D1VGA_CONTROL, - (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_D2VGA_CONTROL, - (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_VGA_RENDER_CONTROL, - (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); - WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE); - - r = radeon_read_bios(rdev); - - /* restore regs */ - WREG32(R600_BUS_CNTL, bus_cntl); - WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); - WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); - WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); - WREG32(R600_ROM_CNTL, rom_cntl); - return r; -} - -static bool r700_read_disabled_bios(struct radeon_device *rdev) -{ - uint32_t viph_control; - uint32_t bus_cntl; - uint32_t d1vga_control; - uint32_t d2vga_control; - uint32_t vga_render_control; - uint32_t rom_cntl; - uint32_t cg_spll_func_cntl = 0; - uint32_t cg_spll_status; - bool r; - - viph_control = RREG32(RADEON_VIPH_CONTROL); - bus_cntl = RREG32(R600_BUS_CNTL); - d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); - d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); - vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); - rom_cntl = RREG32(R600_ROM_CNTL); - - /* disable VIP */ - WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); - /* enable the rom */ - WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); - /* Disable VGA mode */ - WREG32(AVIVO_D1VGA_CONTROL, - (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_D2VGA_CONTROL, - (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_VGA_RENDER_CONTROL, - (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); - - if (rdev->family == CHIP_RV730) { - cg_spll_func_cntl = RREG32(R600_CG_SPLL_FUNC_CNTL); - - /* enable bypass mode */ - WREG32(R600_CG_SPLL_FUNC_CNTL, (cg_spll_func_cntl | - R600_SPLL_BYPASS_EN)); - - /* wait for SPLL_CHG_STATUS to change to 1 */ - cg_spll_status = 0; - while (!(cg_spll_status & R600_SPLL_CHG_STATUS)) - cg_spll_status = RREG32(R600_CG_SPLL_STATUS); - - WREG32(R600_ROM_CNTL, (rom_cntl & ~R600_SCK_OVERWRITE)); - } else - WREG32(R600_ROM_CNTL, (rom_cntl | R600_SCK_OVERWRITE)); - - r = radeon_read_bios(rdev); - - /* restore regs */ - if (rdev->family == CHIP_RV730) { - WREG32(R600_CG_SPLL_FUNC_CNTL, cg_spll_func_cntl); - - /* wait for SPLL_CHG_STATUS to change to 1 */ - cg_spll_status = 0; - while (!(cg_spll_status & R600_SPLL_CHG_STATUS)) - cg_spll_status = RREG32(R600_CG_SPLL_STATUS); - } - WREG32(RADEON_VIPH_CONTROL, viph_control); - WREG32(R600_BUS_CNTL, bus_cntl); - WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); - WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); - WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); - WREG32(R600_ROM_CNTL, rom_cntl); - return r; -} - -static bool r600_read_disabled_bios(struct radeon_device *rdev) -{ - uint32_t viph_control; - uint32_t bus_cntl; - uint32_t d1vga_control; - uint32_t d2vga_control; - uint32_t vga_render_control; - uint32_t rom_cntl; - uint32_t general_pwrmgt; - uint32_t low_vid_lower_gpio_cntl; - uint32_t medium_vid_lower_gpio_cntl; - uint32_t high_vid_lower_gpio_cntl; - uint32_t ctxsw_vid_lower_gpio_cntl; - uint32_t lower_gpio_enable; - bool r; - - viph_control = RREG32(RADEON_VIPH_CONTROL); - bus_cntl = RREG32(R600_BUS_CNTL); - d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); - d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); - vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); - rom_cntl = RREG32(R600_ROM_CNTL); - general_pwrmgt = RREG32(R600_GENERAL_PWRMGT); - low_vid_lower_gpio_cntl = RREG32(R600_LOW_VID_LOWER_GPIO_CNTL); - medium_vid_lower_gpio_cntl = RREG32(R600_MEDIUM_VID_LOWER_GPIO_CNTL); - high_vid_lower_gpio_cntl = RREG32(R600_HIGH_VID_LOWER_GPIO_CNTL); - ctxsw_vid_lower_gpio_cntl = RREG32(R600_CTXSW_VID_LOWER_GPIO_CNTL); - lower_gpio_enable = RREG32(R600_LOWER_GPIO_ENABLE); - - /* disable VIP */ - WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); - /* enable the rom */ - WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); - /* Disable VGA mode */ - WREG32(AVIVO_D1VGA_CONTROL, - (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_D2VGA_CONTROL, - (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_VGA_RENDER_CONTROL, - (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); - - WREG32(R600_ROM_CNTL, - ((rom_cntl & ~R600_SCK_PRESCALE_CRYSTAL_CLK_MASK) | - (1 << R600_SCK_PRESCALE_CRYSTAL_CLK_SHIFT) | - R600_SCK_OVERWRITE)); - - WREG32(R600_GENERAL_PWRMGT, (general_pwrmgt & ~R600_OPEN_DRAIN_PADS)); - WREG32(R600_LOW_VID_LOWER_GPIO_CNTL, - (low_vid_lower_gpio_cntl & ~0x400)); - WREG32(R600_MEDIUM_VID_LOWER_GPIO_CNTL, - (medium_vid_lower_gpio_cntl & ~0x400)); - WREG32(R600_HIGH_VID_LOWER_GPIO_CNTL, - (high_vid_lower_gpio_cntl & ~0x400)); - WREG32(R600_CTXSW_VID_LOWER_GPIO_CNTL, - (ctxsw_vid_lower_gpio_cntl & ~0x400)); - WREG32(R600_LOWER_GPIO_ENABLE, (lower_gpio_enable | 0x400)); - - r = radeon_read_bios(rdev); - - /* restore regs */ - WREG32(RADEON_VIPH_CONTROL, viph_control); - WREG32(R600_BUS_CNTL, bus_cntl); - WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); - WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); - WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); - WREG32(R600_ROM_CNTL, rom_cntl); - WREG32(R600_GENERAL_PWRMGT, general_pwrmgt); - WREG32(R600_LOW_VID_LOWER_GPIO_CNTL, low_vid_lower_gpio_cntl); - WREG32(R600_MEDIUM_VID_LOWER_GPIO_CNTL, medium_vid_lower_gpio_cntl); - WREG32(R600_HIGH_VID_LOWER_GPIO_CNTL, high_vid_lower_gpio_cntl); - WREG32(R600_CTXSW_VID_LOWER_GPIO_CNTL, ctxsw_vid_lower_gpio_cntl); - WREG32(R600_LOWER_GPIO_ENABLE, lower_gpio_enable); - return r; -} - -static bool avivo_read_disabled_bios(struct radeon_device *rdev) -{ - uint32_t seprom_cntl1; - uint32_t viph_control; - uint32_t bus_cntl; - uint32_t d1vga_control; - uint32_t d2vga_control; - uint32_t vga_render_control; - uint32_t gpiopad_a; - uint32_t gpiopad_en; - uint32_t gpiopad_mask; - bool r; - - seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); - viph_control = RREG32(RADEON_VIPH_CONTROL); - bus_cntl = RREG32(RV370_BUS_CNTL); - d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); - d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); - vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); - gpiopad_a = RREG32(RADEON_GPIOPAD_A); - gpiopad_en = RREG32(RADEON_GPIOPAD_EN); - gpiopad_mask = RREG32(RADEON_GPIOPAD_MASK); - - WREG32(RADEON_SEPROM_CNTL1, - ((seprom_cntl1 & ~RADEON_SCK_PRESCALE_MASK) | - (0xc << RADEON_SCK_PRESCALE_SHIFT))); - WREG32(RADEON_GPIOPAD_A, 0); - WREG32(RADEON_GPIOPAD_EN, 0); - WREG32(RADEON_GPIOPAD_MASK, 0); - - /* disable VIP */ - WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); - - /* enable the rom */ - WREG32(RV370_BUS_CNTL, (bus_cntl & ~RV370_BUS_BIOS_DIS_ROM)); - - /* Disable VGA mode */ - WREG32(AVIVO_D1VGA_CONTROL, - (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_D2VGA_CONTROL, - (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_VGA_RENDER_CONTROL, - (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); - - r = radeon_read_bios(rdev); - - /* restore regs */ - WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); - WREG32(RADEON_VIPH_CONTROL, viph_control); - WREG32(RV370_BUS_CNTL, bus_cntl); - WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); - WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); - WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); - WREG32(RADEON_GPIOPAD_A, gpiopad_a); - WREG32(RADEON_GPIOPAD_EN, gpiopad_en); - WREG32(RADEON_GPIOPAD_MASK, gpiopad_mask); - return r; -} - -static bool legacy_read_disabled_bios(struct radeon_device *rdev) -{ - uint32_t seprom_cntl1; - uint32_t viph_control; - uint32_t bus_cntl; - uint32_t crtc_gen_cntl; - uint32_t crtc2_gen_cntl; - uint32_t crtc_ext_cntl; - uint32_t fp2_gen_cntl; - bool r; - - seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); - viph_control = RREG32(RADEON_VIPH_CONTROL); - if (rdev->flags & RADEON_IS_PCIE) - bus_cntl = RREG32(RV370_BUS_CNTL); - else - bus_cntl = RREG32(RADEON_BUS_CNTL); - crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); - crtc2_gen_cntl = 0; - crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - fp2_gen_cntl = 0; - - if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) { - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - } - - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - } - - WREG32(RADEON_SEPROM_CNTL1, - ((seprom_cntl1 & ~RADEON_SCK_PRESCALE_MASK) | - (0xc << RADEON_SCK_PRESCALE_SHIFT))); - - /* disable VIP */ - WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); - - /* enable the rom */ - if (rdev->flags & RADEON_IS_PCIE) - WREG32(RV370_BUS_CNTL, (bus_cntl & ~RV370_BUS_BIOS_DIS_ROM)); - else - WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); - - /* Turn off mem requests and CRTC for both controllers */ - WREG32(RADEON_CRTC_GEN_CNTL, - ((crtc_gen_cntl & ~RADEON_CRTC_EN) | - (RADEON_CRTC_DISP_REQ_EN_B | - RADEON_CRTC_EXT_DISP_EN))); - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - WREG32(RADEON_CRTC2_GEN_CNTL, - ((crtc2_gen_cntl & ~RADEON_CRTC2_EN) | - RADEON_CRTC2_DISP_REQ_EN_B)); - } - /* Turn off CRTC */ - WREG32(RADEON_CRTC_EXT_CNTL, - ((crtc_ext_cntl & ~RADEON_CRTC_CRT_ON) | - (RADEON_CRTC_SYNC_TRISTAT | - RADEON_CRTC_DISPLAY_DIS))); - - if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) { - WREG32(RADEON_FP2_GEN_CNTL, (fp2_gen_cntl & ~RADEON_FP2_ON)); - } - - r = radeon_read_bios(rdev); - - /* restore regs */ - WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); - WREG32(RADEON_VIPH_CONTROL, viph_control); - if (rdev->flags & RADEON_IS_PCIE) - WREG32(RV370_BUS_CNTL, bus_cntl); - else - WREG32(RADEON_BUS_CNTL, bus_cntl); - WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); - if (!(rdev->flags & RADEON_SINGLE_CRTC)) { - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - } - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); - if (rdev->ddev->pci_device == PCI_DEVICE_ID_ATI_RADEON_QY) { - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - } - return r; -} - -static bool radeon_read_disabled_bios(struct radeon_device *rdev) -{ - if (rdev->flags & RADEON_IS_IGP) - return igp_read_bios_from_vram(rdev); - else if (rdev->family >= CHIP_BARTS) - return ni_read_disabled_bios(rdev); - else if (rdev->family >= CHIP_RV770) - return r700_read_disabled_bios(rdev); - else if (rdev->family >= CHIP_R600) - return r600_read_disabled_bios(rdev); - else if (rdev->family >= CHIP_RS600) - return avivo_read_disabled_bios(rdev); - else - return legacy_read_disabled_bios(rdev); -} - - -bool radeon_get_bios(struct radeon_device *rdev) -{ - bool r; - uint16_t tmp; - - r = radeon_atrm_get_bios(rdev); - if (r == false) - r = igp_read_bios_from_vram(rdev); - if (r == false) - r = radeon_read_bios(rdev); - if (r == false) { - r = radeon_read_disabled_bios(rdev); - } - if (r == false || rdev->bios == NULL) { - DRM_ERROR("Unable to locate a BIOS ROM\n"); - rdev->bios = NULL; - return false; - } - if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { - printk("BIOS signature incorrect %x %x\n", rdev->bios[0], rdev->bios[1]); - goto free_bios; - } - - tmp = RBIOS16(0x18); - if (RBIOS8(tmp + 0x14) != 0x0) { - DRM_INFO("Not an x86 BIOS ROM, not using.\n"); - goto free_bios; - } - - rdev->bios_header_start = RBIOS16(0x48); - if (!rdev->bios_header_start) { - goto free_bios; - } - tmp = rdev->bios_header_start + 4; - if (!memcmp(rdev->bios + tmp, "ATOM", 4) || - !memcmp(rdev->bios + tmp, "MOTA", 4)) { - rdev->is_atom_bios = true; - } else { - rdev->is_atom_bios = false; - } - - DRM_DEBUG("%sBIOS detected\n", rdev->is_atom_bios ? "ATOM" : "COM"); - return true; -free_bios: - kfree(rdev->bios); - rdev->bios = NULL; - return false; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_blit_common.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_blit_common.h deleted file mode 100644 index 4ecbe72c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_blit_common.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * Copyright 2009 Red Hat Inc. - * Copyright 2012 Alcatel-Lucent, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __RADEON_BLIT_COMMON_H__ - -#define DI_PT_RECTLIST 0x11 -#define DI_INDEX_SIZE_16_BIT 0x0 -#define DI_SRC_SEL_AUTO_INDEX 0x2 - -#define FMT_8 0x1 -#define FMT_5_6_5 0x8 -#define FMT_8_8_8_8 0x1a -#define COLOR_8 0x1 -#define COLOR_5_6_5 0x8 -#define COLOR_8_8_8_8 0x1a - -#define RECT_UNIT_H 32 -#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) - -#define __RADEON_BLIT_COMMON_H__ -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_clocks.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_clocks.c deleted file mode 100644 index 9c6b29a4..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_clocks.c +++ /dev/null @@ -1,912 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "atom.h" - -/* 10 khz */ -uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) -{ - struct radeon_pll *spll = &rdev->clock.spll; - uint32_t fb_div, ref_div, post_div, sclk; - - fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV); - fb_div = (fb_div >> RADEON_SPLL_FB_DIV_SHIFT) & RADEON_SPLL_FB_DIV_MASK; - fb_div <<= 1; - fb_div *= spll->reference_freq; - - ref_div = - RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; - - if (ref_div == 0) - return 0; - - sclk = fb_div / ref_div; - - post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; - if (post_div == 2) - sclk >>= 1; - else if (post_div == 3) - sclk >>= 2; - else if (post_div == 4) - sclk >>= 3; - - return sclk; -} - -/* 10 khz */ -uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) -{ - struct radeon_pll *mpll = &rdev->clock.mpll; - uint32_t fb_div, ref_div, post_div, mclk; - - fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV); - fb_div = (fb_div >> RADEON_MPLL_FB_DIV_SHIFT) & RADEON_MPLL_FB_DIV_MASK; - fb_div <<= 1; - fb_div *= mpll->reference_freq; - - ref_div = - RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; - - if (ref_div == 0) - return 0; - - mclk = fb_div / ref_div; - - post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; - if (post_div == 2) - mclk >>= 1; - else if (post_div == 3) - mclk >>= 2; - else if (post_div == 4) - mclk >>= 3; - - return mclk; -} - -#ifdef CONFIG_OF -/* - * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device - * tree. Hopefully, ATI OF driver is kind enough to fill these - */ -static bool radeon_read_clocks_OF(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct device_node *dp = rdev->pdev->dev.of_node; - const u32 *val; - struct radeon_pll *p1pll = &rdev->clock.p1pll; - struct radeon_pll *p2pll = &rdev->clock.p2pll; - struct radeon_pll *spll = &rdev->clock.spll; - struct radeon_pll *mpll = &rdev->clock.mpll; - - if (dp == NULL) - return false; - val = of_get_property(dp, "ATY,RefCLK", NULL); - if (!val || !*val) { - printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n"); - return false; - } - p1pll->reference_freq = p2pll->reference_freq = (*val) / 10; - p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; - if (p1pll->reference_div < 2) - p1pll->reference_div = 12; - p2pll->reference_div = p1pll->reference_div; - - /* These aren't in the device-tree */ - if (rdev->family >= CHIP_R420) { - p1pll->pll_in_min = 100; - p1pll->pll_in_max = 1350; - p1pll->pll_out_min = 20000; - p1pll->pll_out_max = 50000; - p2pll->pll_in_min = 100; - p2pll->pll_in_max = 1350; - p2pll->pll_out_min = 20000; - p2pll->pll_out_max = 50000; - } else { - p1pll->pll_in_min = 40; - p1pll->pll_in_max = 500; - p1pll->pll_out_min = 12500; - p1pll->pll_out_max = 35000; - p2pll->pll_in_min = 40; - p2pll->pll_in_max = 500; - p2pll->pll_out_min = 12500; - p2pll->pll_out_max = 35000; - } - /* not sure what the max should be in all cases */ - rdev->clock.max_pixel_clock = 35000; - - spll->reference_freq = mpll->reference_freq = p1pll->reference_freq; - spll->reference_div = mpll->reference_div = - RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & - RADEON_M_SPLL_REF_DIV_MASK; - - val = of_get_property(dp, "ATY,SCLK", NULL); - if (val && *val) - rdev->clock.default_sclk = (*val) / 10; - else - rdev->clock.default_sclk = - radeon_legacy_get_engine_clock(rdev); - - val = of_get_property(dp, "ATY,MCLK", NULL); - if (val && *val) - rdev->clock.default_mclk = (*val) / 10; - else - rdev->clock.default_mclk = - radeon_legacy_get_memory_clock(rdev); - - DRM_INFO("Using device-tree clock info\n"); - - return true; -} -#else -static bool radeon_read_clocks_OF(struct drm_device *dev) -{ - return false; -} -#endif /* CONFIG_OF */ - -void radeon_get_clock_info(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_pll *p1pll = &rdev->clock.p1pll; - struct radeon_pll *p2pll = &rdev->clock.p2pll; - struct radeon_pll *dcpll = &rdev->clock.dcpll; - struct radeon_pll *spll = &rdev->clock.spll; - struct radeon_pll *mpll = &rdev->clock.mpll; - int ret; - - if (rdev->is_atom_bios) - ret = radeon_atom_get_clock_info(dev); - else - ret = radeon_combios_get_clock_info(dev); - if (!ret) - ret = radeon_read_clocks_OF(dev); - - if (ret) { - if (p1pll->reference_div < 2) { - if (!ASIC_IS_AVIVO(rdev)) { - u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV); - if (ASIC_IS_R300(rdev)) - p1pll->reference_div = - (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT; - else - p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK; - if (p1pll->reference_div < 2) - p1pll->reference_div = 12; - } else - p1pll->reference_div = 12; - } - if (p2pll->reference_div < 2) - p2pll->reference_div = 12; - if (rdev->family < CHIP_RS600) { - if (spll->reference_div < 2) - spll->reference_div = - RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & - RADEON_M_SPLL_REF_DIV_MASK; - } - if (mpll->reference_div < 2) - mpll->reference_div = spll->reference_div; - } else { - if (ASIC_IS_AVIVO(rdev)) { - /* TODO FALLBACK */ - } else { - DRM_INFO("Using generic clock info\n"); - - /* may need to be per card */ - rdev->clock.max_pixel_clock = 35000; - - if (rdev->flags & RADEON_IS_IGP) { - p1pll->reference_freq = 1432; - p2pll->reference_freq = 1432; - spll->reference_freq = 1432; - mpll->reference_freq = 1432; - } else { - p1pll->reference_freq = 2700; - p2pll->reference_freq = 2700; - spll->reference_freq = 2700; - mpll->reference_freq = 2700; - } - p1pll->reference_div = - RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; - if (p1pll->reference_div < 2) - p1pll->reference_div = 12; - p2pll->reference_div = p1pll->reference_div; - - if (rdev->family >= CHIP_R420) { - p1pll->pll_in_min = 100; - p1pll->pll_in_max = 1350; - p1pll->pll_out_min = 20000; - p1pll->pll_out_max = 50000; - p2pll->pll_in_min = 100; - p2pll->pll_in_max = 1350; - p2pll->pll_out_min = 20000; - p2pll->pll_out_max = 50000; - } else { - p1pll->pll_in_min = 40; - p1pll->pll_in_max = 500; - p1pll->pll_out_min = 12500; - p1pll->pll_out_max = 35000; - p2pll->pll_in_min = 40; - p2pll->pll_in_max = 500; - p2pll->pll_out_min = 12500; - p2pll->pll_out_max = 35000; - } - - spll->reference_div = - RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & - RADEON_M_SPLL_REF_DIV_MASK; - mpll->reference_div = spll->reference_div; - rdev->clock.default_sclk = - radeon_legacy_get_engine_clock(rdev); - rdev->clock.default_mclk = - radeon_legacy_get_memory_clock(rdev); - } - } - - /* pixel clocks */ - if (ASIC_IS_AVIVO(rdev)) { - p1pll->min_post_div = 2; - p1pll->max_post_div = 0x7f; - p1pll->min_frac_feedback_div = 0; - p1pll->max_frac_feedback_div = 9; - p2pll->min_post_div = 2; - p2pll->max_post_div = 0x7f; - p2pll->min_frac_feedback_div = 0; - p2pll->max_frac_feedback_div = 9; - } else { - p1pll->min_post_div = 1; - p1pll->max_post_div = 16; - p1pll->min_frac_feedback_div = 0; - p1pll->max_frac_feedback_div = 0; - p2pll->min_post_div = 1; - p2pll->max_post_div = 12; - p2pll->min_frac_feedback_div = 0; - p2pll->max_frac_feedback_div = 0; - } - - /* dcpll is DCE4 only */ - dcpll->min_post_div = 2; - dcpll->max_post_div = 0x7f; - dcpll->min_frac_feedback_div = 0; - dcpll->max_frac_feedback_div = 9; - dcpll->min_ref_div = 2; - dcpll->max_ref_div = 0x3ff; - dcpll->min_feedback_div = 4; - dcpll->max_feedback_div = 0xfff; - dcpll->best_vco = 0; - - p1pll->min_ref_div = 2; - p1pll->max_ref_div = 0x3ff; - p1pll->min_feedback_div = 4; - p1pll->max_feedback_div = 0x7ff; - p1pll->best_vco = 0; - - p2pll->min_ref_div = 2; - p2pll->max_ref_div = 0x3ff; - p2pll->min_feedback_div = 4; - p2pll->max_feedback_div = 0x7ff; - p2pll->best_vco = 0; - - /* system clock */ - spll->min_post_div = 1; - spll->max_post_div = 1; - spll->min_ref_div = 2; - spll->max_ref_div = 0xff; - spll->min_feedback_div = 4; - spll->max_feedback_div = 0xff; - spll->best_vco = 0; - - /* memory clock */ - mpll->min_post_div = 1; - mpll->max_post_div = 1; - mpll->min_ref_div = 2; - mpll->max_ref_div = 0xff; - mpll->min_feedback_div = 4; - mpll->max_feedback_div = 0xff; - mpll->best_vco = 0; - - if (!rdev->clock.default_sclk) - rdev->clock.default_sclk = radeon_get_engine_clock(rdev); - if ((!rdev->clock.default_mclk) && rdev->asic->pm.get_memory_clock) - rdev->clock.default_mclk = radeon_get_memory_clock(rdev); - - rdev->pm.current_sclk = rdev->clock.default_sclk; - rdev->pm.current_mclk = rdev->clock.default_mclk; - -} - -/* 10 khz */ -static uint32_t calc_eng_mem_clock(struct radeon_device *rdev, - uint32_t req_clock, - int *fb_div, int *post_div) -{ - struct radeon_pll *spll = &rdev->clock.spll; - int ref_div = spll->reference_div; - - if (!ref_div) - ref_div = - RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & - RADEON_M_SPLL_REF_DIV_MASK; - - if (req_clock < 15000) { - *post_div = 8; - req_clock *= 8; - } else if (req_clock < 30000) { - *post_div = 4; - req_clock *= 4; - } else if (req_clock < 60000) { - *post_div = 2; - req_clock *= 2; - } else - *post_div = 1; - - req_clock *= ref_div; - req_clock += spll->reference_freq; - req_clock /= (2 * spll->reference_freq); - - *fb_div = req_clock & 0xff; - - req_clock = (req_clock & 0xffff) << 1; - req_clock *= spll->reference_freq; - req_clock /= ref_div; - req_clock /= *post_div; - - return req_clock; -} - -/* 10 khz */ -void radeon_legacy_set_engine_clock(struct radeon_device *rdev, - uint32_t eng_clock) -{ - uint32_t tmp; - int fb_div, post_div; - - /* XXX: wait for idle */ - - eng_clock = calc_eng_mem_clock(rdev, eng_clock, &fb_div, &post_div); - - tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); - tmp &= ~RADEON_DONT_USE_XTALIN; - WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp &= ~RADEON_SCLK_SRC_SEL_MASK; - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - udelay(10); - - tmp = RREG32_PLL(RADEON_SPLL_CNTL); - tmp |= RADEON_SPLL_SLEEP; - WREG32_PLL(RADEON_SPLL_CNTL, tmp); - - udelay(2); - - tmp = RREG32_PLL(RADEON_SPLL_CNTL); - tmp |= RADEON_SPLL_RESET; - WREG32_PLL(RADEON_SPLL_CNTL, tmp); - - udelay(200); - - tmp = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV); - tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT); - tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT; - WREG32_PLL(RADEON_M_SPLL_REF_FB_DIV, tmp); - - /* XXX: verify on different asics */ - tmp = RREG32_PLL(RADEON_SPLL_CNTL); - tmp &= ~RADEON_SPLL_PVG_MASK; - if ((eng_clock * post_div) >= 90000) - tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT); - else - tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT); - WREG32_PLL(RADEON_SPLL_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_SPLL_CNTL); - tmp &= ~RADEON_SPLL_SLEEP; - WREG32_PLL(RADEON_SPLL_CNTL, tmp); - - udelay(2); - - tmp = RREG32_PLL(RADEON_SPLL_CNTL); - tmp &= ~RADEON_SPLL_RESET; - WREG32_PLL(RADEON_SPLL_CNTL, tmp); - - udelay(200); - - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp &= ~RADEON_SCLK_SRC_SEL_MASK; - switch (post_div) { - case 1: - default: - tmp |= 1; - break; - case 2: - tmp |= 2; - break; - case 4: - tmp |= 3; - break; - case 8: - tmp |= 4; - break; - } - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - udelay(20); - - tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); - tmp |= RADEON_DONT_USE_XTALIN; - WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); - - udelay(10); -} - -void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) -{ - uint32_t tmp; - - if (enable) { - if (rdev->flags & RADEON_SINGLE_CRTC) { - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - if ((RREG32(RADEON_CONFIG_CNTL) & - RADEON_CFG_ATI_REV_ID_MASK) > - RADEON_CFG_ATI_REV_A13) { - tmp &= - ~(RADEON_SCLK_FORCE_CP | - RADEON_SCLK_FORCE_RB); - } - tmp &= - ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | - RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | - RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | - RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | - RADEON_SCLK_FORCE_TDM); - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - } else if (ASIC_IS_R300(rdev)) { - if ((rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp &= - ~(RADEON_SCLK_FORCE_DISP2 | - RADEON_SCLK_FORCE_CP | - RADEON_SCLK_FORCE_HDP | - RADEON_SCLK_FORCE_DISP1 | - RADEON_SCLK_FORCE_TOP | - RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP - | RADEON_SCLK_FORCE_IDCT | - RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR - | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX - | R300_SCLK_FORCE_US | - RADEON_SCLK_FORCE_TV_SCLK | - R300_SCLK_FORCE_SU | - RADEON_SCLK_FORCE_OV0); - tmp |= RADEON_DYN_STOP_LAT_MASK; - tmp |= - RADEON_SCLK_FORCE_TOP | - RADEON_SCLK_FORCE_VIP; - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); - tmp &= ~RADEON_SCLK_MORE_FORCEON; - tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; - WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - tmp |= (RADEON_PIXCLK_ALWAYS_ONb | - RADEON_PIXCLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); - tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | - RADEON_PIX2CLK_DAC_ALWAYS_ONb | - RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | - R300_DVOCLK_ALWAYS_ONb | - RADEON_PIXCLK_BLEND_ALWAYS_ONb | - RADEON_PIXCLK_GV_ALWAYS_ONb | - R300_PIXCLK_DVO_ALWAYS_ONb | - RADEON_PIXCLK_LVDS_ALWAYS_ONb | - RADEON_PIXCLK_TMDS_ALWAYS_ONb | - R300_PIXCLK_TRANS_ALWAYS_ONb | - R300_PIXCLK_TVO_ALWAYS_ONb | - R300_P2G2CLK_ALWAYS_ONb | - R300_P2G2CLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - } else if (rdev->family >= CHIP_RV350) { - tmp = RREG32_PLL(R300_SCLK_CNTL2); - tmp &= ~(R300_SCLK_FORCE_TCL | - R300_SCLK_FORCE_GA | - R300_SCLK_FORCE_CBA); - tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | - R300_SCLK_GA_MAX_DYN_STOP_LAT | - R300_SCLK_CBA_MAX_DYN_STOP_LAT); - WREG32_PLL(R300_SCLK_CNTL2, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp &= - ~(RADEON_SCLK_FORCE_DISP2 | - RADEON_SCLK_FORCE_CP | - RADEON_SCLK_FORCE_HDP | - RADEON_SCLK_FORCE_DISP1 | - RADEON_SCLK_FORCE_TOP | - RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP - | RADEON_SCLK_FORCE_IDCT | - RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR - | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX - | R300_SCLK_FORCE_US | - RADEON_SCLK_FORCE_TV_SCLK | - R300_SCLK_FORCE_SU | - RADEON_SCLK_FORCE_OV0); - tmp |= RADEON_DYN_STOP_LAT_MASK; - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); - tmp &= ~RADEON_SCLK_MORE_FORCEON; - tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; - WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - tmp |= (RADEON_PIXCLK_ALWAYS_ONb | - RADEON_PIXCLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); - tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | - RADEON_PIX2CLK_DAC_ALWAYS_ONb | - RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | - R300_DVOCLK_ALWAYS_ONb | - RADEON_PIXCLK_BLEND_ALWAYS_ONb | - RADEON_PIXCLK_GV_ALWAYS_ONb | - R300_PIXCLK_DVO_ALWAYS_ONb | - RADEON_PIXCLK_LVDS_ALWAYS_ONb | - RADEON_PIXCLK_TMDS_ALWAYS_ONb | - R300_PIXCLK_TRANS_ALWAYS_ONb | - R300_PIXCLK_TVO_ALWAYS_ONb | - R300_P2G2CLK_ALWAYS_ONb | - R300_P2G2CLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_MCLK_MISC); - tmp |= (RADEON_MC_MCLK_DYN_ENABLE | - RADEON_IO_MCLK_DYN_ENABLE); - WREG32_PLL(RADEON_MCLK_MISC, tmp); - - tmp = RREG32_PLL(RADEON_MCLK_CNTL); - tmp |= (RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB); - - tmp &= ~(RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC); - - /* Some releases of vbios have set DISABLE_MC_MCLKA - and DISABLE_MC_MCLKB bits in the vbios table. Setting these - bits will cause H/W hang when reading video memory with dynamic clocking - enabled. */ - if ((tmp & R300_DISABLE_MC_MCLKA) && - (tmp & R300_DISABLE_MC_MCLKB)) { - /* If both bits are set, then check the active channels */ - tmp = RREG32_PLL(RADEON_MCLK_CNTL); - if (rdev->mc.vram_width == 64) { - if (RREG32(RADEON_MEM_CNTL) & - R300_MEM_USE_CD_CH_ONLY) - tmp &= - ~R300_DISABLE_MC_MCLKB; - else - tmp &= - ~R300_DISABLE_MC_MCLKA; - } else { - tmp &= ~(R300_DISABLE_MC_MCLKA | - R300_DISABLE_MC_MCLKB); - } - } - - WREG32_PLL(RADEON_MCLK_CNTL, tmp); - } else { - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp &= ~(R300_SCLK_FORCE_VAP); - tmp |= RADEON_SCLK_FORCE_CP; - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - mdelay(15); - - tmp = RREG32_PLL(R300_SCLK_CNTL2); - tmp &= ~(R300_SCLK_FORCE_TCL | - R300_SCLK_FORCE_GA | - R300_SCLK_FORCE_CBA); - WREG32_PLL(R300_SCLK_CNTL2, tmp); - } - } else { - tmp = RREG32_PLL(RADEON_CLK_PWRMGT_CNTL); - - tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | - RADEON_DISP_DYN_STOP_LAT_MASK | - RADEON_DYN_STOP_MODE_MASK); - - tmp |= (RADEON_ENGIN_DYNCLK_MODE | - (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); - WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); - mdelay(15); - - tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); - tmp |= RADEON_SCLK_DYN_START_CNTL; - WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); - mdelay(15); - - /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 - to lockup randomly, leave them as set by BIOS. - */ - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - /*tmp &= RADEON_SCLK_SRC_SEL_MASK; */ - tmp &= ~RADEON_SCLK_FORCEON_MASK; - - /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300 */ - if (((rdev->family == CHIP_RV250) && - ((RREG32(RADEON_CONFIG_CNTL) & - RADEON_CFG_ATI_REV_ID_MASK) < - RADEON_CFG_ATI_REV_A13)) - || ((rdev->family == CHIP_RV100) - && - ((RREG32(RADEON_CONFIG_CNTL) & - RADEON_CFG_ATI_REV_ID_MASK) <= - RADEON_CFG_ATI_REV_A13))) { - tmp |= RADEON_SCLK_FORCE_CP; - tmp |= RADEON_SCLK_FORCE_VIP; - } - - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - if ((rdev->family == CHIP_RV200) || - (rdev->family == CHIP_RV250) || - (rdev->family == CHIP_RV280)) { - tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); - tmp &= ~RADEON_SCLK_MORE_FORCEON; - - /* RV200::A11 A12 RV250::A11 A12 */ - if (((rdev->family == CHIP_RV200) || - (rdev->family == CHIP_RV250)) && - ((RREG32(RADEON_CONFIG_CNTL) & - RADEON_CFG_ATI_REV_ID_MASK) < - RADEON_CFG_ATI_REV_A13)) { - tmp |= RADEON_SCLK_MORE_FORCEON; - } - WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - mdelay(15); - } - - /* RV200::A11 A12, RV250::A11 A12 */ - if (((rdev->family == CHIP_RV200) || - (rdev->family == CHIP_RV250)) && - ((RREG32(RADEON_CONFIG_CNTL) & - RADEON_CFG_ATI_REV_ID_MASK) < - RADEON_CFG_ATI_REV_A13)) { - tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL); - tmp |= RADEON_TCL_BYPASS_DISABLE; - WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); - } - mdelay(15); - - /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ - tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); - tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | - RADEON_PIX2CLK_DAC_ALWAYS_ONb | - RADEON_PIXCLK_BLEND_ALWAYS_ONb | - RADEON_PIXCLK_GV_ALWAYS_ONb | - RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | - RADEON_PIXCLK_LVDS_ALWAYS_ONb | - RADEON_PIXCLK_TMDS_ALWAYS_ONb); - - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - mdelay(15); - - tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - tmp |= (RADEON_PIXCLK_ALWAYS_ONb | - RADEON_PIXCLK_DAC_ALWAYS_ONb); - - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - mdelay(15); - } - } else { - /* Turn everything OFF (ForceON to everything) */ - if (rdev->flags & RADEON_SINGLE_CRTC) { - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | - RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP - | RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | - RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | - RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | - RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | - RADEON_SCLK_FORCE_RB); - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - } else if ((rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | - RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 - | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | - R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | - RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | - R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | - R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | - R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); - tmp |= RADEON_SCLK_MORE_FORCEON; - WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | - RADEON_PIXCLK_DAC_ALWAYS_ONb | - R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); - tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | - RADEON_PIX2CLK_DAC_ALWAYS_ONb | - RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | - R300_DVOCLK_ALWAYS_ONb | - RADEON_PIXCLK_BLEND_ALWAYS_ONb | - RADEON_PIXCLK_GV_ALWAYS_ONb | - R300_PIXCLK_DVO_ALWAYS_ONb | - RADEON_PIXCLK_LVDS_ALWAYS_ONb | - RADEON_PIXCLK_TMDS_ALWAYS_ONb | - R300_PIXCLK_TRANS_ALWAYS_ONb | - R300_PIXCLK_TVO_ALWAYS_ONb | - R300_P2G2CLK_ALWAYS_ONb | - R300_P2G2CLK_DAC_ALWAYS_ONb | - R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - } else if (rdev->family >= CHIP_RV350) { - /* for RV350/M10, no delays are required. */ - tmp = RREG32_PLL(R300_SCLK_CNTL2); - tmp |= (R300_SCLK_FORCE_TCL | - R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA); - WREG32_PLL(R300_SCLK_CNTL2, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | - RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 - | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | - R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | - RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | - R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | - R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | - R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); - tmp |= RADEON_SCLK_MORE_FORCEON; - WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_MCLK_CNTL); - tmp |= (RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC); - WREG32_PLL(RADEON_MCLK_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | - RADEON_PIXCLK_DAC_ALWAYS_ONb | - R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - - tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); - tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | - RADEON_PIX2CLK_DAC_ALWAYS_ONb | - RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | - R300_DVOCLK_ALWAYS_ONb | - RADEON_PIXCLK_BLEND_ALWAYS_ONb | - RADEON_PIXCLK_GV_ALWAYS_ONb | - R300_PIXCLK_DVO_ALWAYS_ONb | - RADEON_PIXCLK_LVDS_ALWAYS_ONb | - RADEON_PIXCLK_TMDS_ALWAYS_ONb | - R300_PIXCLK_TRANS_ALWAYS_ONb | - R300_PIXCLK_TVO_ALWAYS_ONb | - R300_P2G2CLK_ALWAYS_ONb | - R300_P2G2CLK_DAC_ALWAYS_ONb | - R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - } else { - tmp = RREG32_PLL(RADEON_SCLK_CNTL); - tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); - tmp |= RADEON_SCLK_FORCE_SE; - - if (rdev->flags & RADEON_SINGLE_CRTC) { - tmp |= (RADEON_SCLK_FORCE_RB | - RADEON_SCLK_FORCE_TDM | - RADEON_SCLK_FORCE_TAM | - RADEON_SCLK_FORCE_PB | - RADEON_SCLK_FORCE_RE | - RADEON_SCLK_FORCE_VIP | - RADEON_SCLK_FORCE_IDCT | - RADEON_SCLK_FORCE_TOP | - RADEON_SCLK_FORCE_DISP1 | - RADEON_SCLK_FORCE_DISP2 | - RADEON_SCLK_FORCE_HDP); - } else if ((rdev->family == CHIP_R300) || - (rdev->family == CHIP_R350)) { - tmp |= (RADEON_SCLK_FORCE_HDP | - RADEON_SCLK_FORCE_DISP1 | - RADEON_SCLK_FORCE_DISP2 | - RADEON_SCLK_FORCE_TOP | - RADEON_SCLK_FORCE_IDCT | - RADEON_SCLK_FORCE_VIP); - } - WREG32_PLL(RADEON_SCLK_CNTL, tmp); - - mdelay(16); - - if ((rdev->family == CHIP_R300) || - (rdev->family == CHIP_R350)) { - tmp = RREG32_PLL(R300_SCLK_CNTL2); - tmp |= (R300_SCLK_FORCE_TCL | - R300_SCLK_FORCE_GA | - R300_SCLK_FORCE_CBA); - WREG32_PLL(R300_SCLK_CNTL2, tmp); - mdelay(16); - } - - if (rdev->flags & RADEON_IS_IGP) { - tmp = RREG32_PLL(RADEON_MCLK_CNTL); - tmp &= ~(RADEON_FORCEON_MCLKA | - RADEON_FORCEON_YCLKA); - WREG32_PLL(RADEON_MCLK_CNTL, tmp); - mdelay(16); - } - - if ((rdev->family == CHIP_RV200) || - (rdev->family == CHIP_RV250) || - (rdev->family == CHIP_RV280)) { - tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); - tmp |= RADEON_SCLK_MORE_FORCEON; - WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - mdelay(16); - } - - tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); - tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | - RADEON_PIX2CLK_DAC_ALWAYS_ONb | - RADEON_PIXCLK_BLEND_ALWAYS_ONb | - RADEON_PIXCLK_GV_ALWAYS_ONb | - RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | - RADEON_PIXCLK_LVDS_ALWAYS_ONb | - RADEON_PIXCLK_TMDS_ALWAYS_ONb); - - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - mdelay(16); - - tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | - RADEON_PIXCLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - } - } -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_combios.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_combios.c deleted file mode 100644 index 2cad9fde..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_combios.c +++ /dev/null @@ -1,3538 +0,0 @@ -/* - * Copyright 2004 ATI Technologies Inc., Markham, Ontario - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" - -#ifdef CONFIG_PPC_PMAC -/* not sure which of these are needed */ -#include -#include -#include -#include -#endif /* CONFIG_PPC_PMAC */ - -/* from radeon_encoder.c */ -extern uint32_t -radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, - uint8_t dac); -extern void radeon_link_encoder_connector(struct drm_device *dev); - -/* from radeon_connector.c */ -extern void -radeon_add_legacy_connector(struct drm_device *dev, - uint32_t connector_id, - uint32_t supported_device, - int connector_type, - struct radeon_i2c_bus_rec *i2c_bus, - uint16_t connector_object_id, - struct radeon_hpd *hpd); - -/* from radeon_legacy_encoder.c */ -extern void -radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, - uint32_t supported_device); - -/* old legacy ATI BIOS routines */ - -/* COMBIOS table offsets */ -enum radeon_combios_table_offset { - /* absolute offset tables */ - COMBIOS_ASIC_INIT_1_TABLE, - COMBIOS_BIOS_SUPPORT_TABLE, - COMBIOS_DAC_PROGRAMMING_TABLE, - COMBIOS_MAX_COLOR_DEPTH_TABLE, - COMBIOS_CRTC_INFO_TABLE, - COMBIOS_PLL_INFO_TABLE, - COMBIOS_TV_INFO_TABLE, - COMBIOS_DFP_INFO_TABLE, - COMBIOS_HW_CONFIG_INFO_TABLE, - COMBIOS_MULTIMEDIA_INFO_TABLE, - COMBIOS_TV_STD_PATCH_TABLE, - COMBIOS_LCD_INFO_TABLE, - COMBIOS_MOBILE_INFO_TABLE, - COMBIOS_PLL_INIT_TABLE, - COMBIOS_MEM_CONFIG_TABLE, - COMBIOS_SAVE_MASK_TABLE, - COMBIOS_HARDCODED_EDID_TABLE, - COMBIOS_ASIC_INIT_2_TABLE, - COMBIOS_CONNECTOR_INFO_TABLE, - COMBIOS_DYN_CLK_1_TABLE, - COMBIOS_RESERVED_MEM_TABLE, - COMBIOS_EXT_TMDS_INFO_TABLE, - COMBIOS_MEM_CLK_INFO_TABLE, - COMBIOS_EXT_DAC_INFO_TABLE, - COMBIOS_MISC_INFO_TABLE, - COMBIOS_CRT_INFO_TABLE, - COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE, - COMBIOS_COMPONENT_VIDEO_INFO_TABLE, - COMBIOS_FAN_SPEED_INFO_TABLE, - COMBIOS_OVERDRIVE_INFO_TABLE, - COMBIOS_OEM_INFO_TABLE, - COMBIOS_DYN_CLK_2_TABLE, - COMBIOS_POWER_CONNECTOR_INFO_TABLE, - COMBIOS_I2C_INFO_TABLE, - /* relative offset tables */ - COMBIOS_ASIC_INIT_3_TABLE, /* offset from misc info */ - COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */ - COMBIOS_DETECTED_MEM_TABLE, /* offset from misc info */ - COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */ - COMBIOS_RAM_RESET_TABLE, /* offset from mem config */ - COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */ - COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */ - COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */ - COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */ - COMBIOS_TMDS_POWER_ON_TABLE, /* offset from tmds power */ - COMBIOS_TMDS_POWER_OFF_TABLE, /* offset from tmds power */ -}; - -enum radeon_combios_ddc { - DDC_NONE_DETECTED, - DDC_MONID, - DDC_DVI, - DDC_VGA, - DDC_CRT2, - DDC_LCD, - DDC_GPIO, -}; - -enum radeon_combios_connector { - CONNECTOR_NONE_LEGACY, - CONNECTOR_PROPRIETARY_LEGACY, - CONNECTOR_CRT_LEGACY, - CONNECTOR_DVI_I_LEGACY, - CONNECTOR_DVI_D_LEGACY, - CONNECTOR_CTV_LEGACY, - CONNECTOR_STV_LEGACY, - CONNECTOR_UNSUPPORTED_LEGACY -}; - -const int legacy_connector_convert[] = { - DRM_MODE_CONNECTOR_Unknown, - DRM_MODE_CONNECTOR_DVID, - DRM_MODE_CONNECTOR_VGA, - DRM_MODE_CONNECTOR_DVII, - DRM_MODE_CONNECTOR_DVID, - DRM_MODE_CONNECTOR_Composite, - DRM_MODE_CONNECTOR_SVIDEO, - DRM_MODE_CONNECTOR_Unknown, -}; - -static uint16_t combios_get_table_offset(struct drm_device *dev, - enum radeon_combios_table_offset table) -{ - struct radeon_device *rdev = dev->dev_private; - int rev; - uint16_t offset = 0, check_offset; - - if (!rdev->bios) - return 0; - - switch (table) { - /* absolute offset tables */ - case COMBIOS_ASIC_INIT_1_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0xc); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_BIOS_SUPPORT_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x14); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_DAC_PROGRAMMING_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x2a); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_MAX_COLOR_DEPTH_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x2c); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_CRTC_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x2e); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_PLL_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x30); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_TV_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x32); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_DFP_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x34); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_HW_CONFIG_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x36); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_MULTIMEDIA_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x38); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_TV_STD_PATCH_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x3e); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_LCD_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x40); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_MOBILE_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x42); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_PLL_INIT_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x46); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_MEM_CONFIG_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x48); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_SAVE_MASK_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x4a); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_HARDCODED_EDID_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x4c); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_ASIC_INIT_2_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x4e); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_CONNECTOR_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x50); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_DYN_CLK_1_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x52); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_RESERVED_MEM_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x54); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_EXT_TMDS_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x58); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_MEM_CLK_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x5a); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_EXT_DAC_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x5c); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_MISC_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x5e); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_CRT_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x60); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x62); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x64); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_FAN_SPEED_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x66); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_OVERDRIVE_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x68); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_OEM_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x6a); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_DYN_CLK_2_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x6c); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_POWER_CONNECTOR_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x6e); - if (check_offset) - offset = check_offset; - break; - case COMBIOS_I2C_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x70); - if (check_offset) - offset = check_offset; - break; - /* relative offset tables */ - case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); - if (check_offset) { - rev = RBIOS8(check_offset); - if (rev > 0) { - check_offset = RBIOS16(check_offset + 0x3); - if (check_offset) - offset = check_offset; - } - } - break; - case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); - if (check_offset) { - rev = RBIOS8(check_offset); - if (rev > 0) { - check_offset = RBIOS16(check_offset + 0x5); - if (check_offset) - offset = check_offset; - } - } - break; - case COMBIOS_DETECTED_MEM_TABLE: /* offset from misc info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); - if (check_offset) { - rev = RBIOS8(check_offset); - if (rev > 0) { - check_offset = RBIOS16(check_offset + 0x7); - if (check_offset) - offset = check_offset; - } - } - break; - case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE); - if (check_offset) { - rev = RBIOS8(check_offset); - if (rev == 2) { - check_offset = RBIOS16(check_offset + 0x9); - if (check_offset) - offset = check_offset; - } - } - break; - case COMBIOS_RAM_RESET_TABLE: /* offset from mem config */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE); - if (check_offset) { - while (RBIOS8(check_offset++)); - check_offset += 2; - if (check_offset) - offset = check_offset; - } - break; - case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); - if (check_offset) { - check_offset = RBIOS16(check_offset + 0x11); - if (check_offset) - offset = check_offset; - } - break; - case COMBIOS_GPIO_INFO_TABLE: /* offset from mobile info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); - if (check_offset) { - check_offset = RBIOS16(check_offset + 0x13); - if (check_offset) - offset = check_offset; - } - break; - case COMBIOS_LCD_DDC_INFO_TABLE: /* offset from mobile info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); - if (check_offset) { - check_offset = RBIOS16(check_offset + 0x15); - if (check_offset) - offset = check_offset; - } - break; - case COMBIOS_TMDS_POWER_TABLE: /* offset from mobile info */ - check_offset = - combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); - if (check_offset) { - check_offset = RBIOS16(check_offset + 0x17); - if (check_offset) - offset = check_offset; - } - break; - case COMBIOS_TMDS_POWER_ON_TABLE: /* offset from tmds power */ - check_offset = - combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE); - if (check_offset) { - check_offset = RBIOS16(check_offset + 0x2); - if (check_offset) - offset = check_offset; - } - break; - case COMBIOS_TMDS_POWER_OFF_TABLE: /* offset from tmds power */ - check_offset = - combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE); - if (check_offset) { - check_offset = RBIOS16(check_offset + 0x4); - if (check_offset) - offset = check_offset; - } - break; - default: - break; - } - - return offset; - -} - -bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) -{ - int edid_info, size; - struct edid *edid; - unsigned char *raw; - edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE); - if (!edid_info) - return false; - - raw = rdev->bios + edid_info; - size = EDID_LENGTH * (raw[0x7e] + 1); - edid = kmalloc(size, GFP_KERNEL); - if (edid == NULL) - return false; - - memcpy((unsigned char *)edid, raw, size); - - if (!drm_edid_is_valid(edid)) { - kfree(edid); - return false; - } - - rdev->mode_info.bios_hardcoded_edid = edid; - rdev->mode_info.bios_hardcoded_edid_size = size; - return true; -} - -/* this is used for atom LCDs as well */ -struct edid * -radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) -{ - struct edid *edid; - - if (rdev->mode_info.bios_hardcoded_edid) { - edid = kmalloc(rdev->mode_info.bios_hardcoded_edid_size, GFP_KERNEL); - if (edid) { - memcpy((unsigned char *)edid, - (unsigned char *)rdev->mode_info.bios_hardcoded_edid, - rdev->mode_info.bios_hardcoded_edid_size); - return edid; - } - } - return NULL; -} - -static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rdev, - enum radeon_combios_ddc ddc, - u32 clk_mask, - u32 data_mask) -{ - struct radeon_i2c_bus_rec i2c; - int ddc_line = 0; - - /* ddc id = mask reg - * DDC_NONE_DETECTED = none - * DDC_DVI = RADEON_GPIO_DVI_DDC - * DDC_VGA = RADEON_GPIO_VGA_DDC - * DDC_LCD = RADEON_GPIOPAD_MASK - * DDC_GPIO = RADEON_MDGPIO_MASK - * r1xx - * DDC_MONID = RADEON_GPIO_MONID - * DDC_CRT2 = RADEON_GPIO_CRT2_DDC - * r200 - * DDC_MONID = RADEON_GPIO_MONID - * DDC_CRT2 = RADEON_GPIO_DVI_DDC - * r300/r350 - * DDC_MONID = RADEON_GPIO_DVI_DDC - * DDC_CRT2 = RADEON_GPIO_DVI_DDC - * rv2xx/rv3xx - * DDC_MONID = RADEON_GPIO_MONID - * DDC_CRT2 = RADEON_GPIO_MONID - * rs3xx/rs4xx - * DDC_MONID = RADEON_GPIOPAD_MASK - * DDC_CRT2 = RADEON_GPIO_MONID - */ - switch (ddc) { - case DDC_NONE_DETECTED: - default: - ddc_line = 0; - break; - case DDC_DVI: - ddc_line = RADEON_GPIO_DVI_DDC; - break; - case DDC_VGA: - ddc_line = RADEON_GPIO_VGA_DDC; - break; - case DDC_LCD: - ddc_line = RADEON_GPIOPAD_MASK; - break; - case DDC_GPIO: - ddc_line = RADEON_MDGPIO_MASK; - break; - case DDC_MONID: - if (rdev->family == CHIP_RS300 || - rdev->family == CHIP_RS400 || - rdev->family == CHIP_RS480) - ddc_line = RADEON_GPIOPAD_MASK; - else if (rdev->family == CHIP_R300 || - rdev->family == CHIP_R350) { - ddc_line = RADEON_GPIO_DVI_DDC; - ddc = DDC_DVI; - } else - ddc_line = RADEON_GPIO_MONID; - break; - case DDC_CRT2: - if (rdev->family == CHIP_R200 || - rdev->family == CHIP_R300 || - rdev->family == CHIP_R350) { - ddc_line = RADEON_GPIO_DVI_DDC; - ddc = DDC_DVI; - } else if (rdev->family == CHIP_RS300 || - rdev->family == CHIP_RS400 || - rdev->family == CHIP_RS480) - ddc_line = RADEON_GPIO_MONID; - else if (rdev->family >= CHIP_RV350) { - ddc_line = RADEON_GPIO_MONID; - ddc = DDC_MONID; - } else - ddc_line = RADEON_GPIO_CRT2_DDC; - break; - } - - if (ddc_line == RADEON_GPIOPAD_MASK) { - i2c.mask_clk_reg = RADEON_GPIOPAD_MASK; - i2c.mask_data_reg = RADEON_GPIOPAD_MASK; - i2c.a_clk_reg = RADEON_GPIOPAD_A; - i2c.a_data_reg = RADEON_GPIOPAD_A; - i2c.en_clk_reg = RADEON_GPIOPAD_EN; - i2c.en_data_reg = RADEON_GPIOPAD_EN; - i2c.y_clk_reg = RADEON_GPIOPAD_Y; - i2c.y_data_reg = RADEON_GPIOPAD_Y; - } else if (ddc_line == RADEON_MDGPIO_MASK) { - i2c.mask_clk_reg = RADEON_MDGPIO_MASK; - i2c.mask_data_reg = RADEON_MDGPIO_MASK; - i2c.a_clk_reg = RADEON_MDGPIO_A; - i2c.a_data_reg = RADEON_MDGPIO_A; - i2c.en_clk_reg = RADEON_MDGPIO_EN; - i2c.en_data_reg = RADEON_MDGPIO_EN; - i2c.y_clk_reg = RADEON_MDGPIO_Y; - i2c.y_data_reg = RADEON_MDGPIO_Y; - } else { - i2c.mask_clk_reg = ddc_line; - i2c.mask_data_reg = ddc_line; - i2c.a_clk_reg = ddc_line; - i2c.a_data_reg = ddc_line; - i2c.en_clk_reg = ddc_line; - i2c.en_data_reg = ddc_line; - i2c.y_clk_reg = ddc_line; - i2c.y_data_reg = ddc_line; - } - - if (clk_mask && data_mask) { - /* system specific masks */ - i2c.mask_clk_mask = clk_mask; - i2c.mask_data_mask = data_mask; - i2c.a_clk_mask = clk_mask; - i2c.a_data_mask = data_mask; - i2c.en_clk_mask = clk_mask; - i2c.en_data_mask = data_mask; - i2c.y_clk_mask = clk_mask; - i2c.y_data_mask = data_mask; - } else if ((ddc_line == RADEON_GPIOPAD_MASK) || - (ddc_line == RADEON_MDGPIO_MASK)) { - /* default gpiopad masks */ - i2c.mask_clk_mask = (0x20 << 8); - i2c.mask_data_mask = 0x80; - i2c.a_clk_mask = (0x20 << 8); - i2c.a_data_mask = 0x80; - i2c.en_clk_mask = (0x20 << 8); - i2c.en_data_mask = 0x80; - i2c.y_clk_mask = (0x20 << 8); - i2c.y_data_mask = 0x80; - } else { - /* default masks for ddc pads */ - i2c.mask_clk_mask = RADEON_GPIO_MASK_1; - i2c.mask_data_mask = RADEON_GPIO_MASK_0; - i2c.a_clk_mask = RADEON_GPIO_A_1; - i2c.a_data_mask = RADEON_GPIO_A_0; - i2c.en_clk_mask = RADEON_GPIO_EN_1; - i2c.en_data_mask = RADEON_GPIO_EN_0; - i2c.y_clk_mask = RADEON_GPIO_Y_1; - i2c.y_data_mask = RADEON_GPIO_Y_0; - } - - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - case CHIP_RS300: - switch (ddc_line) { - case RADEON_GPIO_DVI_DDC: - i2c.hw_capable = true; - break; - default: - i2c.hw_capable = false; - break; - } - break; - case CHIP_R200: - switch (ddc_line) { - case RADEON_GPIO_DVI_DDC: - case RADEON_GPIO_MONID: - i2c.hw_capable = true; - break; - default: - i2c.hw_capable = false; - break; - } - break; - case CHIP_RV250: - case CHIP_RV280: - switch (ddc_line) { - case RADEON_GPIO_VGA_DDC: - case RADEON_GPIO_DVI_DDC: - case RADEON_GPIO_CRT2_DDC: - i2c.hw_capable = true; - break; - default: - i2c.hw_capable = false; - break; - } - break; - case CHIP_R300: - case CHIP_R350: - switch (ddc_line) { - case RADEON_GPIO_VGA_DDC: - case RADEON_GPIO_DVI_DDC: - i2c.hw_capable = true; - break; - default: - i2c.hw_capable = false; - break; - } - break; - case CHIP_RV350: - case CHIP_RV380: - case CHIP_RS400: - case CHIP_RS480: - switch (ddc_line) { - case RADEON_GPIO_VGA_DDC: - case RADEON_GPIO_DVI_DDC: - i2c.hw_capable = true; - break; - case RADEON_GPIO_MONID: - /* hw i2c on RADEON_GPIO_MONID doesn't seem to work - * reliably on some pre-r4xx hardware; not sure why. - */ - i2c.hw_capable = false; - break; - default: - i2c.hw_capable = false; - break; - } - break; - default: - i2c.hw_capable = false; - break; - } - i2c.mm_i2c = false; - - i2c.i2c_id = ddc; - i2c.hpd = RADEON_HPD_NONE; - - if (ddc_line) - i2c.valid = true; - else - i2c.valid = false; - - return i2c; -} - -void radeon_combios_i2c_init(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct radeon_i2c_bus_rec i2c; - - /* actual hw pads - * r1xx/rs2xx/rs3xx - * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm - * r200 - * 0x60, 0x64, 0x68, mm - * r300/r350 - * 0x60, 0x64, mm - * rv2xx/rv3xx/rs4xx - * 0x60, 0x64, 0x68, gpiopads, mm - */ - - /* 0x60 */ - i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC"); - /* 0x64 */ - i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC"); - - /* mm i2c */ - i2c.valid = true; - i2c.hw_capable = true; - i2c.mm_i2c = true; - i2c.i2c_id = 0xa0; - rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C"); - - if (rdev->family == CHIP_R300 || - rdev->family == CHIP_R350) { - /* only 2 sw i2c pads */ - } else if (rdev->family == CHIP_RS300 || - rdev->family == CHIP_RS400 || - rdev->family == CHIP_RS480) { - u16 offset; - u8 id, blocks, clk, data; - int i; - - /* 0x68 */ - i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); - rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); - - offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); - if (offset) { - blocks = RBIOS8(offset + 2); - for (i = 0; i < blocks; i++) { - id = RBIOS8(offset + 3 + (i * 5) + 0); - if (id == 136) { - clk = RBIOS8(offset + 3 + (i * 5) + 3); - data = RBIOS8(offset + 3 + (i * 5) + 4); - /* gpiopad */ - i2c = combios_setup_i2c_bus(rdev, DDC_MONID, - (1 << clk), (1 << data)); - rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); - break; - } - } - } - } else if ((rdev->family == CHIP_R200) || - (rdev->family >= CHIP_R300)) { - /* 0x68 */ - i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); - } else { - /* 0x68 */ - i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); - /* 0x6c */ - i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); - rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC"); - } -} - -bool radeon_combios_get_clock_info(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - uint16_t pll_info; - struct radeon_pll *p1pll = &rdev->clock.p1pll; - struct radeon_pll *p2pll = &rdev->clock.p2pll; - struct radeon_pll *spll = &rdev->clock.spll; - struct radeon_pll *mpll = &rdev->clock.mpll; - int8_t rev; - uint16_t sclk, mclk; - - pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); - if (pll_info) { - rev = RBIOS8(pll_info); - - /* pixel clocks */ - p1pll->reference_freq = RBIOS16(pll_info + 0xe); - p1pll->reference_div = RBIOS16(pll_info + 0x10); - p1pll->pll_out_min = RBIOS32(pll_info + 0x12); - p1pll->pll_out_max = RBIOS32(pll_info + 0x16); - p1pll->lcd_pll_out_min = p1pll->pll_out_min; - p1pll->lcd_pll_out_max = p1pll->pll_out_max; - - if (rev > 9) { - p1pll->pll_in_min = RBIOS32(pll_info + 0x36); - p1pll->pll_in_max = RBIOS32(pll_info + 0x3a); - } else { - p1pll->pll_in_min = 40; - p1pll->pll_in_max = 500; - } - *p2pll = *p1pll; - - /* system clock */ - spll->reference_freq = RBIOS16(pll_info + 0x1a); - spll->reference_div = RBIOS16(pll_info + 0x1c); - spll->pll_out_min = RBIOS32(pll_info + 0x1e); - spll->pll_out_max = RBIOS32(pll_info + 0x22); - - if (rev > 10) { - spll->pll_in_min = RBIOS32(pll_info + 0x48); - spll->pll_in_max = RBIOS32(pll_info + 0x4c); - } else { - /* ??? */ - spll->pll_in_min = 40; - spll->pll_in_max = 500; - } - - /* memory clock */ - mpll->reference_freq = RBIOS16(pll_info + 0x26); - mpll->reference_div = RBIOS16(pll_info + 0x28); - mpll->pll_out_min = RBIOS32(pll_info + 0x2a); - mpll->pll_out_max = RBIOS32(pll_info + 0x2e); - - if (rev > 10) { - mpll->pll_in_min = RBIOS32(pll_info + 0x5a); - mpll->pll_in_max = RBIOS32(pll_info + 0x5e); - } else { - /* ??? */ - mpll->pll_in_min = 40; - mpll->pll_in_max = 500; - } - - /* default sclk/mclk */ - sclk = RBIOS16(pll_info + 0xa); - mclk = RBIOS16(pll_info + 0x8); - if (sclk == 0) - sclk = 200 * 100; - if (mclk == 0) - mclk = 200 * 100; - - rdev->clock.default_sclk = sclk; - rdev->clock.default_mclk = mclk; - - if (RBIOS32(pll_info + 0x16)) - rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16); - else - rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */ - - return true; - } - return false; -} - -bool radeon_combios_sideport_present(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - u16 igp_info; - - /* sideport is AMD only */ - if (rdev->family == CHIP_RS400) - return false; - - igp_info = combios_get_table_offset(dev, COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE); - - if (igp_info) { - if (RBIOS16(igp_info + 0x4)) - return true; - } - return false; -} - -static const uint32_t default_primarydac_adj[CHIP_LAST] = { - 0x00000808, /* r100 */ - 0x00000808, /* rv100 */ - 0x00000808, /* rs100 */ - 0x00000808, /* rv200 */ - 0x00000808, /* rs200 */ - 0x00000808, /* r200 */ - 0x00000808, /* rv250 */ - 0x00000000, /* rs300 */ - 0x00000808, /* rv280 */ - 0x00000808, /* r300 */ - 0x00000808, /* r350 */ - 0x00000808, /* rv350 */ - 0x00000808, /* rv380 */ - 0x00000808, /* r420 */ - 0x00000808, /* r423 */ - 0x00000808, /* rv410 */ - 0x00000000, /* rs400 */ - 0x00000000, /* rs480 */ -}; - -static void radeon_legacy_get_primary_dac_info_from_table(struct radeon_device *rdev, - struct radeon_encoder_primary_dac *p_dac) -{ - p_dac->ps2_pdac_adj = default_primarydac_adj[rdev->family]; - return; -} - -struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct - radeon_encoder - *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint16_t dac_info; - uint8_t rev, bg, dac; - struct radeon_encoder_primary_dac *p_dac = NULL; - int found = 0; - - p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), - GFP_KERNEL); - - if (!p_dac) - return NULL; - - /* check CRT table */ - dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); - if (dac_info) { - rev = RBIOS8(dac_info) & 0x3; - if (rev < 2) { - bg = RBIOS8(dac_info + 0x2) & 0xf; - dac = (RBIOS8(dac_info + 0x2) >> 4) & 0xf; - p_dac->ps2_pdac_adj = (bg << 8) | (dac); - } else { - bg = RBIOS8(dac_info + 0x2) & 0xf; - dac = RBIOS8(dac_info + 0x3) & 0xf; - p_dac->ps2_pdac_adj = (bg << 8) | (dac); - } - /* if the values are all zeros, use the table */ - if (p_dac->ps2_pdac_adj) - found = 1; - } - - if (!found) /* fallback to defaults */ - radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); - - return p_dac; -} - -enum radeon_tv_std -radeon_combios_get_tv_info(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - uint16_t tv_info; - enum radeon_tv_std tv_std = TV_STD_NTSC; - - tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); - if (tv_info) { - if (RBIOS8(tv_info + 6) == 'T') { - switch (RBIOS8(tv_info + 7) & 0xf) { - case 1: - tv_std = TV_STD_NTSC; - DRM_DEBUG_KMS("Default TV standard: NTSC\n"); - break; - case 2: - tv_std = TV_STD_PAL; - DRM_DEBUG_KMS("Default TV standard: PAL\n"); - break; - case 3: - tv_std = TV_STD_PAL_M; - DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); - break; - case 4: - tv_std = TV_STD_PAL_60; - DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); - break; - case 5: - tv_std = TV_STD_NTSC_J; - DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); - break; - case 6: - tv_std = TV_STD_SCART_PAL; - DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n"); - break; - default: - tv_std = TV_STD_NTSC; - DRM_DEBUG_KMS - ("Unknown TV standard; defaulting to NTSC\n"); - break; - } - - switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) { - case 0: - DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n"); - break; - case 1: - DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n"); - break; - case 2: - DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n"); - break; - case 3: - DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n"); - break; - default: - break; - } - } - } - return tv_std; -} - -static const uint32_t default_tvdac_adj[CHIP_LAST] = { - 0x00000000, /* r100 */ - 0x00280000, /* rv100 */ - 0x00000000, /* rs100 */ - 0x00880000, /* rv200 */ - 0x00000000, /* rs200 */ - 0x00000000, /* r200 */ - 0x00770000, /* rv250 */ - 0x00290000, /* rs300 */ - 0x00560000, /* rv280 */ - 0x00780000, /* r300 */ - 0x00770000, /* r350 */ - 0x00780000, /* rv350 */ - 0x00780000, /* rv380 */ - 0x01080000, /* r420 */ - 0x01080000, /* r423 */ - 0x01080000, /* rv410 */ - 0x00780000, /* rs400 */ - 0x00780000, /* rs480 */ -}; - -static void radeon_legacy_get_tv_dac_info_from_table(struct radeon_device *rdev, - struct radeon_encoder_tv_dac *tv_dac) -{ - tv_dac->ps2_tvdac_adj = default_tvdac_adj[rdev->family]; - if ((rdev->flags & RADEON_IS_MOBILITY) && (rdev->family == CHIP_RV250)) - tv_dac->ps2_tvdac_adj = 0x00880000; - tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; - tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; - return; -} - -struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct - radeon_encoder - *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint16_t dac_info; - uint8_t rev, bg, dac; - struct radeon_encoder_tv_dac *tv_dac = NULL; - int found = 0; - - tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); - if (!tv_dac) - return NULL; - - /* first check TV table */ - dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); - if (dac_info) { - rev = RBIOS8(dac_info + 0x3); - if (rev > 4) { - bg = RBIOS8(dac_info + 0xc) & 0xf; - dac = RBIOS8(dac_info + 0xd) & 0xf; - tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); - - bg = RBIOS8(dac_info + 0xe) & 0xf; - dac = RBIOS8(dac_info + 0xf) & 0xf; - tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); - - bg = RBIOS8(dac_info + 0x10) & 0xf; - dac = RBIOS8(dac_info + 0x11) & 0xf; - tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); - /* if the values are all zeros, use the table */ - if (tv_dac->ps2_tvdac_adj) - found = 1; - } else if (rev > 1) { - bg = RBIOS8(dac_info + 0xc) & 0xf; - dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; - tv_dac->ps2_tvdac_adj = (bg << 16) | (dac << 20); - - bg = RBIOS8(dac_info + 0xd) & 0xf; - dac = (RBIOS8(dac_info + 0xd) >> 4) & 0xf; - tv_dac->pal_tvdac_adj = (bg << 16) | (dac << 20); - - bg = RBIOS8(dac_info + 0xe) & 0xf; - dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; - tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); - /* if the values are all zeros, use the table */ - if (tv_dac->ps2_tvdac_adj) - found = 1; - } - tv_dac->tv_std = radeon_combios_get_tv_info(rdev); - } - if (!found) { - /* then check CRT table */ - dac_info = - combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); - if (dac_info) { - rev = RBIOS8(dac_info) & 0x3; - if (rev < 2) { - bg = RBIOS8(dac_info + 0x3) & 0xf; - dac = (RBIOS8(dac_info + 0x3) >> 4) & 0xf; - tv_dac->ps2_tvdac_adj = - (bg << 16) | (dac << 20); - tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; - tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; - /* if the values are all zeros, use the table */ - if (tv_dac->ps2_tvdac_adj) - found = 1; - } else { - bg = RBIOS8(dac_info + 0x4) & 0xf; - dac = RBIOS8(dac_info + 0x5) & 0xf; - tv_dac->ps2_tvdac_adj = - (bg << 16) | (dac << 20); - tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; - tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; - /* if the values are all zeros, use the table */ - if (tv_dac->ps2_tvdac_adj) - found = 1; - } - } else { - DRM_INFO("No TV DAC info found in BIOS\n"); - } - } - - if (!found) /* fallback to defaults */ - radeon_legacy_get_tv_dac_info_from_table(rdev, tv_dac); - - return tv_dac; -} - -static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct - radeon_device - *rdev) -{ - struct radeon_encoder_lvds *lvds = NULL; - uint32_t fp_vert_stretch, fp_horz_stretch; - uint32_t ppll_div_sel, ppll_val; - uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); - - lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); - - if (!lvds) - return NULL; - - fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH); - fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH); - - /* These should be fail-safe defaults, fingers crossed */ - lvds->panel_pwr_delay = 200; - lvds->panel_vcc_delay = 2000; - - lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); - lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf; - lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; - - if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) - lvds->native_mode.vdisplay = - ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> - RADEON_VERT_PANEL_SHIFT) + 1; - else - lvds->native_mode.vdisplay = - (RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; - - if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) - lvds->native_mode.hdisplay = - (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> - RADEON_HORZ_PANEL_SHIFT) + 1) * 8; - else - lvds->native_mode.hdisplay = - ((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; - - if ((lvds->native_mode.hdisplay < 640) || - (lvds->native_mode.vdisplay < 480)) { - lvds->native_mode.hdisplay = 640; - lvds->native_mode.vdisplay = 480; - } - - ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; - ppll_val = RREG32_PLL(RADEON_PPLL_DIV_0 + ppll_div_sel); - if ((ppll_val & 0x000707ff) == 0x1bb) - lvds->use_bios_dividers = false; - else { - lvds->panel_ref_divider = - RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; - lvds->panel_post_divider = (ppll_val >> 16) & 0x7; - lvds->panel_fb_divider = ppll_val & 0x7ff; - - if ((lvds->panel_ref_divider != 0) && - (lvds->panel_fb_divider > 3)) - lvds->use_bios_dividers = true; - } - lvds->panel_vcc_delay = 200; - - DRM_INFO("Panel info derived from registers\n"); - DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, - lvds->native_mode.vdisplay); - - return lvds; -} - -struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder - *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint16_t lcd_info; - uint32_t panel_setup; - char stmp[30]; - int tmp, i; - struct radeon_encoder_lvds *lvds = NULL; - - lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); - - if (lcd_info) { - lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); - - if (!lvds) - return NULL; - - for (i = 0; i < 24; i++) - stmp[i] = RBIOS8(lcd_info + i + 1); - stmp[24] = 0; - - DRM_INFO("Panel ID String: %s\n", stmp); - - lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19); - lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b); - - DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, - lvds->native_mode.vdisplay); - - lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); - lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000); - - lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24); - lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf; - lvds->panel_blon_delay = (RBIOS16(lcd_info + 0x38) >> 4) & 0xf; - - lvds->panel_ref_divider = RBIOS16(lcd_info + 0x2e); - lvds->panel_post_divider = RBIOS8(lcd_info + 0x30); - lvds->panel_fb_divider = RBIOS16(lcd_info + 0x31); - if ((lvds->panel_ref_divider != 0) && - (lvds->panel_fb_divider > 3)) - lvds->use_bios_dividers = true; - - panel_setup = RBIOS32(lcd_info + 0x39); - lvds->lvds_gen_cntl = 0xff00; - if (panel_setup & 0x1) - lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT; - - if ((panel_setup >> 4) & 0x1) - lvds->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE; - - switch ((panel_setup >> 8) & 0x7) { - case 0: - lvds->lvds_gen_cntl |= RADEON_LVDS_NO_FM; - break; - case 1: - lvds->lvds_gen_cntl |= RADEON_LVDS_2_GREY; - break; - case 2: - lvds->lvds_gen_cntl |= RADEON_LVDS_4_GREY; - break; - default: - break; - } - - if ((panel_setup >> 16) & 0x1) - lvds->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW; - - if ((panel_setup >> 17) & 0x1) - lvds->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW; - - if ((panel_setup >> 18) & 0x1) - lvds->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW; - - if ((panel_setup >> 23) & 0x1) - lvds->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL; - - lvds->lvds_gen_cntl |= (panel_setup & 0xf0000000); - - for (i = 0; i < 32; i++) { - tmp = RBIOS16(lcd_info + 64 + i * 2); - if (tmp == 0) - break; - - if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && - (RBIOS16(tmp + 2) == lvds->native_mode.vdisplay)) { - lvds->native_mode.htotal = lvds->native_mode.hdisplay + - (RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; - lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + - (RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - 1) * 8; - lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + - (RBIOS8(tmp + 23) * 8); - - lvds->native_mode.vtotal = lvds->native_mode.vdisplay + - (RBIOS16(tmp + 24) - RBIOS16(tmp + 26)); - lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + - ((RBIOS16(tmp + 28) & 0x7ff) - RBIOS16(tmp + 26)); - lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + - ((RBIOS16(tmp + 28) & 0xf800) >> 11); - - lvds->native_mode.clock = RBIOS16(tmp + 9) * 10; - lvds->native_mode.flags = 0; - /* set crtc values */ - drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); - - } - } - } else { - DRM_INFO("No panel info found in BIOS\n"); - lvds = radeon_legacy_get_lvds_info_from_regs(rdev); - } - - if (lvds) - encoder->native_mode = lvds->native_mode; - return lvds; -} - -static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = { - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R100 */ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV100 */ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS100 */ - {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RV200 */ - {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_RS200 */ - {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /* CHIP_R200 */ - {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /* CHIP_RV250 */ - {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RS300 */ - {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /* CHIP_RV280 */ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R300 */ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R350 */ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV350 */ - {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RV380 */ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */ - {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */ - { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */ - { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */ -}; - -bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, - struct radeon_encoder_int_tmds *tmds) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - int i; - - for (i = 0; i < 4; i++) { - tmds->tmds_pll[i].value = - default_tmds_pll[rdev->family][i].value; - tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq; - } - - return true; -} - -bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, - struct radeon_encoder_int_tmds *tmds) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint16_t tmds_info; - int i, n; - uint8_t ver; - - tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); - - if (tmds_info) { - ver = RBIOS8(tmds_info); - DRM_DEBUG_KMS("DFP table revision: %d\n", ver); - if (ver == 3) { - n = RBIOS8(tmds_info + 5) + 1; - if (n > 4) - n = 4; - for (i = 0; i < n; i++) { - tmds->tmds_pll[i].value = - RBIOS32(tmds_info + i * 10 + 0x08); - tmds->tmds_pll[i].freq = - RBIOS16(tmds_info + i * 10 + 0x10); - DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", - tmds->tmds_pll[i].freq, - tmds->tmds_pll[i].value); - } - } else if (ver == 4) { - int stride = 0; - n = RBIOS8(tmds_info + 5) + 1; - if (n > 4) - n = 4; - for (i = 0; i < n; i++) { - tmds->tmds_pll[i].value = - RBIOS32(tmds_info + stride + 0x08); - tmds->tmds_pll[i].freq = - RBIOS16(tmds_info + stride + 0x10); - if (i == 0) - stride += 10; - else - stride += 6; - DRM_DEBUG_KMS("TMDS PLL From COMBIOS %u %x\n", - tmds->tmds_pll[i].freq, - tmds->tmds_pll[i].value); - } - } - } else { - DRM_INFO("No TMDS info found in BIOS\n"); - return false; - } - return true; -} - -bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, - struct radeon_encoder_ext_tmds *tmds) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_i2c_bus_rec i2c_bus; - - /* default for macs */ - i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - - /* XXX some macs have duallink chips */ - switch (rdev->mode_info.connector_table) { - case CT_POWERBOOK_EXTERNAL: - case CT_MINI_EXTERNAL: - default: - tmds->dvo_chip = DVO_SIL164; - tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */ - break; - } - - return true; -} - -bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder, - struct radeon_encoder_ext_tmds *tmds) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint16_t offset; - uint8_t ver; - enum radeon_combios_ddc gpio; - struct radeon_i2c_bus_rec i2c_bus; - - tmds->i2c_bus = NULL; - if (rdev->flags & RADEON_IS_IGP) { - i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - tmds->dvo_chip = DVO_SIL164; - tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */ - } else { - offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); - if (offset) { - ver = RBIOS8(offset); - DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver); - tmds->slave_addr = RBIOS8(offset + 4 + 2); - tmds->slave_addr >>= 1; /* 7 bit addressing */ - gpio = RBIOS8(offset + 4 + 3); - if (gpio == DDC_LCD) { - /* MM i2c */ - i2c_bus.valid = true; - i2c_bus.hw_capable = true; - i2c_bus.mm_i2c = true; - i2c_bus.i2c_id = 0xa0; - } else - i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); - tmds->i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - } - } - - if (!tmds->i2c_bus) { - DRM_INFO("No valid Ext TMDS info found in BIOS\n"); - return false; - } - - return true; -} - -bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_i2c_bus_rec ddc_i2c; - struct radeon_hpd hpd; - - rdev->mode_info.connector_table = radeon_connector_table; - if (rdev->mode_info.connector_table == CT_NONE) { -#ifdef CONFIG_PPC_PMAC - if (of_machine_is_compatible("PowerBook3,3")) { - /* powerbook with VGA */ - rdev->mode_info.connector_table = CT_POWERBOOK_VGA; - } else if (of_machine_is_compatible("PowerBook3,4") || - of_machine_is_compatible("PowerBook3,5")) { - /* powerbook with internal tmds */ - rdev->mode_info.connector_table = CT_POWERBOOK_INTERNAL; - } else if (of_machine_is_compatible("PowerBook5,1") || - of_machine_is_compatible("PowerBook5,2") || - of_machine_is_compatible("PowerBook5,3") || - of_machine_is_compatible("PowerBook5,4") || - of_machine_is_compatible("PowerBook5,5")) { - /* powerbook with external single link tmds (sil164) */ - rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (of_machine_is_compatible("PowerBook5,6")) { - /* powerbook with external dual or single link tmds */ - rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (of_machine_is_compatible("PowerBook5,7") || - of_machine_is_compatible("PowerBook5,8") || - of_machine_is_compatible("PowerBook5,9")) { - /* PowerBook6,2 ? */ - /* powerbook with external dual link tmds (sil1178?) */ - rdev->mode_info.connector_table = CT_POWERBOOK_EXTERNAL; - } else if (of_machine_is_compatible("PowerBook4,1") || - of_machine_is_compatible("PowerBook4,2") || - of_machine_is_compatible("PowerBook4,3") || - of_machine_is_compatible("PowerBook6,3") || - of_machine_is_compatible("PowerBook6,5") || - of_machine_is_compatible("PowerBook6,7")) { - /* ibook */ - rdev->mode_info.connector_table = CT_IBOOK; - } else if (of_machine_is_compatible("PowerMac4,4")) { - /* emac */ - rdev->mode_info.connector_table = CT_EMAC; - } else if (of_machine_is_compatible("PowerMac10,1")) { - /* mini with internal tmds */ - rdev->mode_info.connector_table = CT_MINI_INTERNAL; - } else if (of_machine_is_compatible("PowerMac10,2")) { - /* mini with external tmds */ - rdev->mode_info.connector_table = CT_MINI_EXTERNAL; - } else if (of_machine_is_compatible("PowerMac12,1")) { - /* PowerMac8,1 ? */ - /* imac g5 isight */ - rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; - } else if ((rdev->pdev->device == 0x4a48) && - (rdev->pdev->subsystem_vendor == 0x1002) && - (rdev->pdev->subsystem_device == 0x4a48)) { - /* Mac X800 */ - rdev->mode_info.connector_table = CT_MAC_X800; - } else if ((of_machine_is_compatible("PowerMac7,2") || - of_machine_is_compatible("PowerMac7,3")) && - (rdev->pdev->device == 0x4150) && - (rdev->pdev->subsystem_vendor == 0x1002) && - (rdev->pdev->subsystem_device == 0x4150)) { - /* Mac G5 tower 9600 */ - rdev->mode_info.connector_table = CT_MAC_G5_9600; - } else -#endif /* CONFIG_PPC_PMAC */ -#ifdef CONFIG_PPC64 - if (ASIC_IS_RN50(rdev)) - rdev->mode_info.connector_table = CT_RN50_POWER; - else -#endif - rdev->mode_info.connector_table = CT_GENERIC; - } - - switch (rdev->mode_info.connector_table) { - case CT_GENERIC: - DRM_INFO("Connector Table: %d (generic)\n", - rdev->mode_info.connector_table); - /* these are the most common settings */ - if (rdev->flags & RADEON_SINGLE_CRTC) { - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, - &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - } else if (rdev->flags & RADEON_IS_MOBILITY) { - /* LVDS */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, - &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, - &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - } else { - /* DVI-I - tv dac, int tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_1; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, - &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - } - - if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { - /* TV - tv dac */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, - ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - } - break; - case CT_IBOOK: - DRM_INFO("Connector Table: %d (ibook)\n", - rdev->mode_info.connector_table); - /* LVDS */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - /* VGA - TV DAC */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_POWERBOOK_EXTERNAL: - DRM_INFO("Connector Table: %d (powerbook external tmds)\n", - rdev->mode_info.connector_table); - /* LVDS */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - /* DVI-I - primary dac, ext tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_2; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP2_SUPPORT, - 0), - ATOM_DEVICE_DFP2_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - /* XXX some are SL */ - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_DFP2_SUPPORT | - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_POWERBOOK_INTERNAL: - DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", - rdev->mode_info.connector_table); - /* LVDS */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - /* DVI-I - primary dac, int tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_POWERBOOK_VGA: - DRM_INFO("Connector Table: %d (powerbook vga)\n", - rdev->mode_info.connector_table); - /* LVDS */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_MINI_EXTERNAL: - DRM_INFO("Connector Table: %d (mini external tmds)\n", - rdev->mode_info.connector_table); - /* DVI-I - tv dac, ext tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); - hpd.hpd = RADEON_HPD_2; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP2_SUPPORT, - 0), - ATOM_DEVICE_DFP2_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - /* XXX are any DL? */ - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_DFP2_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_MINI_INTERNAL: - DRM_INFO("Connector Table: %d (mini internal tmds)\n", - rdev->mode_info.connector_table); - /* DVI-I - tv dac, int tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_IMAC_G5_ISIGHT: - DRM_INFO("Connector Table: %d (imac g5 isight)\n", - rdev->mode_info.connector_table); - /* DVI-D - int tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, - DRM_MODE_CONNECTOR_DVID, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, - &hpd); - /* VGA - tv dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_EMAC: - DRM_INFO("Connector Table: %d (emac)\n", - rdev->mode_info.connector_table); - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - /* VGA - tv dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - case CT_RN50_POWER: - DRM_INFO("Connector Table: %d (rn50-power)\n", - rdev->mode_info.connector_table); - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - break; - case CT_MAC_X800: - DRM_INFO("Connector Table: %d (mac x800)\n", - rdev->mode_info.connector_table); - /* DVI - primary dac, internal tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* DVI - tv dac, dvo */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - hpd.hpd = RADEON_HPD_2; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP2_SUPPORT, - 0), - ATOM_DEVICE_DFP2_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_DFP2_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, - &hpd); - break; - case CT_MAC_G5_9600: - DRM_INFO("Connector Table: %d (mac g5 9600)\n", - rdev->mode_info.connector_table); - /* DVI - tv dac, dvo */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP2_SUPPORT, - 0), - ATOM_DEVICE_DFP2_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_DFP2_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* ADC - primary dac, internal tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_2; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - default: - DRM_INFO("Connector table: %d (invalid)\n", - rdev->mode_info.connector_table); - return false; - } - - radeon_link_encoder_connector(dev); - - return true; -} - -static bool radeon_apply_legacy_quirks(struct drm_device *dev, - int bios_index, - enum radeon_combios_connector - *legacy_connector, - struct radeon_i2c_bus_rec *ddc_i2c, - struct radeon_hpd *hpd) -{ - - /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, - one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ - if (dev->pdev->device == 0x515e && - dev->pdev->subsystem_vendor == 0x1014) { - if (*legacy_connector == CONNECTOR_CRT_LEGACY && - ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC) - return false; - } - - /* X300 card with extra non-existent DVI port */ - if (dev->pdev->device == 0x5B60 && - dev->pdev->subsystem_vendor == 0x17af && - dev->pdev->subsystem_device == 0x201e && bios_index == 2) { - if (*legacy_connector == CONNECTOR_DVI_I_LEGACY) - return false; - } - - return true; -} - -static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev) -{ - /* Acer 5102 has non-existent TV port */ - if (dev->pdev->device == 0x5975 && - dev->pdev->subsystem_vendor == 0x1025 && - dev->pdev->subsystem_device == 0x009f) - return false; - - /* HP dc5750 has non-existent TV port */ - if (dev->pdev->device == 0x5974 && - dev->pdev->subsystem_vendor == 0x103c && - dev->pdev->subsystem_device == 0x280a) - return false; - - /* MSI S270 has non-existent TV port */ - if (dev->pdev->device == 0x5955 && - dev->pdev->subsystem_vendor == 0x1462 && - dev->pdev->subsystem_device == 0x0131) - return false; - - return true; -} - -static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t ext_tmds_info; - - if (rdev->flags & RADEON_IS_IGP) { - if (is_dvi_d) - return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; - else - return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; - } - ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); - if (ext_tmds_info) { - uint8_t rev = RBIOS8(ext_tmds_info); - uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5); - if (rev >= 3) { - if (is_dvi_d) - return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; - else - return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; - } else { - if (flags & 1) { - if (is_dvi_d) - return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; - else - return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; - } - } - } - if (is_dvi_d) - return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; - else - return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; -} - -bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t conn_info, entry, devices; - uint16_t tmp, connector_object_id; - enum radeon_combios_ddc ddc_type; - enum radeon_combios_connector connector; - int i = 0; - struct radeon_i2c_bus_rec ddc_i2c; - struct radeon_hpd hpd; - - conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE); - if (conn_info) { - for (i = 0; i < 4; i++) { - entry = conn_info + 2 + i * 2; - - if (!RBIOS16(entry)) - break; - - tmp = RBIOS16(entry); - - connector = (tmp >> 12) & 0xf; - - ddc_type = (tmp >> 8) & 0xf; - ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); - - switch (connector) { - case CONNECTOR_PROPRIETARY_LEGACY: - case CONNECTOR_DVI_I_LEGACY: - case CONNECTOR_DVI_D_LEGACY: - if ((tmp >> 4) & 0x1) - hpd.hpd = RADEON_HPD_2; - else - hpd.hpd = RADEON_HPD_1; - break; - default: - hpd.hpd = RADEON_HPD_NONE; - break; - } - - if (!radeon_apply_legacy_quirks(dev, i, &connector, - &ddc_i2c, &hpd)) - continue; - - switch (connector) { - case CONNECTOR_PROPRIETARY_LEGACY: - if ((tmp >> 4) & 0x1) - devices = ATOM_DEVICE_DFP2_SUPPORT; - else - devices = ATOM_DEVICE_DFP1_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, devices, 0), - devices); - radeon_add_legacy_connector(dev, i, devices, - legacy_connector_convert - [connector], - &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D, - &hpd); - break; - case CONNECTOR_CRT_LEGACY: - if (tmp & 0x1) { - devices = ATOM_DEVICE_CRT2_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - } else { - devices = ATOM_DEVICE_CRT1_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - } - radeon_add_legacy_connector(dev, - i, - devices, - legacy_connector_convert - [connector], - &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - break; - case CONNECTOR_DVI_I_LEGACY: - devices = 0; - if (tmp & 0x1) { - devices |= ATOM_DEVICE_CRT2_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - } else { - devices |= ATOM_DEVICE_CRT1_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - } - if ((tmp >> 4) & 0x1) { - devices |= ATOM_DEVICE_DFP2_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_DFP2_SUPPORT, - 0), - ATOM_DEVICE_DFP2_SUPPORT); - connector_object_id = combios_check_dl_dvi(dev, 0); - } else { - devices |= ATOM_DEVICE_DFP1_SUPPORT; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; - } - radeon_add_legacy_connector(dev, - i, - devices, - legacy_connector_convert - [connector], - &ddc_i2c, - connector_object_id, - &hpd); - break; - case CONNECTOR_DVI_D_LEGACY: - if ((tmp >> 4) & 0x1) { - devices = ATOM_DEVICE_DFP2_SUPPORT; - connector_object_id = combios_check_dl_dvi(dev, 1); - } else { - devices = ATOM_DEVICE_DFP1_SUPPORT; - connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; - } - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, devices, 0), - devices); - radeon_add_legacy_connector(dev, i, devices, - legacy_connector_convert - [connector], - &ddc_i2c, - connector_object_id, - &hpd); - break; - case CONNECTOR_CTV_LEGACY: - case CONNECTOR_STV_LEGACY: - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, i, - ATOM_DEVICE_TV1_SUPPORT, - legacy_connector_convert - [connector], - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; - default: - DRM_ERROR("Unknown connector type: %d\n", - connector); - continue; - } - - } - } else { - uint16_t tmds_info = - combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); - if (tmds_info) { - DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); - - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_1; - radeon_add_legacy_connector(dev, - 0, - ATOM_DEVICE_CRT1_SUPPORT | - ATOM_DEVICE_DFP1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - } else { - uint16_t crt_info = - combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); - DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); - if (crt_info) { - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_connector(dev, - 0, - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, - &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - } else { - DRM_DEBUG_KMS("No connector info found\n"); - return false; - } - } - } - - if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) { - uint16_t lcd_info = - combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); - if (lcd_info) { - uint16_t lcd_ddc_info = - combios_get_table_offset(dev, - COMBIOS_LCD_DDC_INFO_TABLE); - - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - - if (lcd_ddc_info) { - ddc_type = RBIOS8(lcd_ddc_info + 2); - switch (ddc_type) { - case DDC_LCD: - ddc_i2c = - combios_setup_i2c_bus(rdev, - DDC_LCD, - RBIOS32(lcd_ddc_info + 3), - RBIOS32(lcd_ddc_info + 7)); - radeon_i2c_add(rdev, &ddc_i2c, "LCD"); - break; - case DDC_GPIO: - ddc_i2c = - combios_setup_i2c_bus(rdev, - DDC_GPIO, - RBIOS32(lcd_ddc_info + 3), - RBIOS32(lcd_ddc_info + 7)); - radeon_i2c_add(rdev, &ddc_i2c, "LCD"); - break; - default: - ddc_i2c = - combios_setup_i2c_bus(rdev, ddc_type, 0, 0); - break; - } - DRM_DEBUG_KMS("LCD DDC Info Table found!\n"); - } else - ddc_i2c.valid = false; - - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_connector(dev, - 5, - ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, - &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - } - } - - /* check TV table */ - if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { - uint32_t tv_info = - combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); - if (tv_info) { - if (RBIOS8(tv_info + 6) == 'T') { - if (radeon_apply_legacy_tv_quirks(dev)) { - hpd.hpd = RADEON_HPD_NONE; - ddc_i2c.valid = false; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum - (dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 6, - ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - } - } - } - } - - radeon_link_encoder_connector(dev); - - return true; -} - -static const char *thermal_controller_names[] = { - "NONE", - "lm63", - "adm1032", -}; - -void radeon_combios_get_power_modes(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - u16 offset, misc, misc2 = 0; - u8 rev, blocks, tmp; - int state_index = 0; - struct radeon_i2c_bus_rec i2c_bus; - - rdev->pm.default_power_state_index = -1; - - /* allocate 2 power states */ - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL); - if (rdev->pm.power_state) { - /* allocate 1 clock mode per state */ - rdev->pm.power_state[0].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); - rdev->pm.power_state[1].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); - if (!rdev->pm.power_state[0].clock_info || - !rdev->pm.power_state[1].clock_info) - goto pm_failed; - } else - goto pm_failed; - - /* check for a thermal chip */ - offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); - if (offset) { - u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; - - rev = RBIOS8(offset); - - if (rev == 0) { - thermal_controller = RBIOS8(offset + 3); - gpio = RBIOS8(offset + 4) & 0x3f; - i2c_addr = RBIOS8(offset + 5); - } else if (rev == 1) { - thermal_controller = RBIOS8(offset + 4); - gpio = RBIOS8(offset + 5) & 0x3f; - i2c_addr = RBIOS8(offset + 6); - } else if (rev == 2) { - thermal_controller = RBIOS8(offset + 4); - gpio = RBIOS8(offset + 5) & 0x3f; - i2c_addr = RBIOS8(offset + 6); - clk_bit = RBIOS8(offset + 0xa); - data_bit = RBIOS8(offset + 0xb); - } - if ((thermal_controller > 0) && (thermal_controller < 3)) { - DRM_INFO("Possible %s thermal controller at 0x%02x\n", - thermal_controller_names[thermal_controller], - i2c_addr >> 1); - if (gpio == DDC_LCD) { - /* MM i2c */ - i2c_bus.valid = true; - i2c_bus.hw_capable = true; - i2c_bus.mm_i2c = true; - i2c_bus.i2c_id = 0xa0; - } else if (gpio == DDC_GPIO) - i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit); - else - i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = thermal_controller_names[thermal_controller]; - info.addr = i2c_addr >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } - } - } else { - /* boards with a thermal chip, but no overdrive table */ - - /* Asus 9600xt has an f75375 on the monid bus */ - if ((dev->pdev->device == 0x4152) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0xc002)) { - i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = "f75375"; - info.addr = 0x28; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - DRM_INFO("Possible %s thermal controller at 0x%02x\n", - name, info.addr); - } - } - } - - if (rdev->flags & RADEON_IS_MOBILITY) { - offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); - if (offset) { - rev = RBIOS8(offset); - blocks = RBIOS8(offset + 0x2); - /* power mode 0 tends to be the only valid one */ - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].mclk = RBIOS32(offset + 0x5 + 0x2); - rdev->pm.power_state[state_index].clock_info[0].sclk = RBIOS32(offset + 0x5 + 0x6); - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - goto default_mode; - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - misc = RBIOS16(offset + 0x5 + 0x0); - if (rev > 4) - misc2 = RBIOS16(offset + 0x5 + 0xe); - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - if (misc & 0x4) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; - if (misc & 0x8) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = true; - if (rev < 6) { - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg = - RBIOS16(offset + 0x5 + 0xb) * 4; - tmp = RBIOS8(offset + 0x5 + 0xd); - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp); - } else { - u8 entries = RBIOS8(offset + 0x5 + 0xb); - u16 voltage_table_offset = RBIOS16(offset + 0x5 + 0xc); - if (entries && voltage_table_offset) { - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.reg = - RBIOS16(voltage_table_offset) * 4; - tmp = RBIOS8(voltage_table_offset + 0x2); - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.mask = (1 << tmp); - } else - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio.valid = false; - } - switch ((misc2 & 0x700) >> 8) { - case 0: - default: - rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 0; - break; - case 1: - rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 33; - break; - case 2: - rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 66; - break; - case 3: - rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 99; - break; - case 4: - rdev->pm.power_state[state_index].clock_info[0].voltage.delay = 132; - break; - } - } else - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - if (rev > 6) - rdev->pm.power_state[state_index].pcie_lanes = - RBIOS8(offset + 0x5 + 0x10); - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - state_index++; - } else { - /* XXX figure out some good default low power mode for mobility cards w/out power tables */ - } - } else { - /* XXX figure out some good default low power mode for desktop cards */ - } - -default_mode: - /* add the default mode */ - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; - rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; - rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; - if ((state_index > 0) && - (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO)) - rdev->pm.power_state[state_index].clock_info[0].voltage = - rdev->pm.power_state[0].clock_info[0].voltage; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - rdev->pm.power_state[state_index].pcie_lanes = 16; - rdev->pm.power_state[state_index].flags = 0; - rdev->pm.default_power_state_index = state_index; - rdev->pm.num_power_states = state_index + 1; - - rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.current_clock_mode_index = 0; - return; - -pm_failed: - rdev->pm.default_power_state_index = state_index; - rdev->pm.num_power_states = 0; - - rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.current_clock_mode_index = 0; -} - -void radeon_external_tmds_setup(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; - - if (!tmds) - return; - - switch (tmds->dvo_chip) { - case DVO_SIL164: - /* sil 164 */ - radeon_i2c_put_byte(tmds->i2c_bus, - tmds->slave_addr, - 0x08, 0x30); - radeon_i2c_put_byte(tmds->i2c_bus, - tmds->slave_addr, - 0x09, 0x00); - radeon_i2c_put_byte(tmds->i2c_bus, - tmds->slave_addr, - 0x0a, 0x90); - radeon_i2c_put_byte(tmds->i2c_bus, - tmds->slave_addr, - 0x0c, 0x89); - radeon_i2c_put_byte(tmds->i2c_bus, - tmds->slave_addr, - 0x08, 0x3b); - break; - case DVO_SIL1178: - /* sil 1178 - untested */ - /* - * 0x0f, 0x44 - * 0x0f, 0x4c - * 0x0e, 0x01 - * 0x0a, 0x80 - * 0x09, 0x30 - * 0x0c, 0xc9 - * 0x0d, 0x70 - * 0x08, 0x32 - * 0x08, 0x33 - */ - break; - default: - break; - } - -} - -bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint16_t offset; - uint8_t blocks, slave_addr, rev; - uint32_t index, id; - uint32_t reg, val, and_mask, or_mask; - struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; - - if (!tmds) - return false; - - if (rdev->flags & RADEON_IS_IGP) { - offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE); - rev = RBIOS8(offset); - if (offset) { - rev = RBIOS8(offset); - if (rev > 1) { - blocks = RBIOS8(offset + 3); - index = offset + 4; - while (blocks > 0) { - id = RBIOS16(index); - index += 2; - switch (id >> 13) { - case 0: - reg = (id & 0x1fff) * 4; - val = RBIOS32(index); - index += 4; - WREG32(reg, val); - break; - case 2: - reg = (id & 0x1fff) * 4; - and_mask = RBIOS32(index); - index += 4; - or_mask = RBIOS32(index); - index += 4; - val = RREG32(reg); - val = (val & and_mask) | or_mask; - WREG32(reg, val); - break; - case 3: - val = RBIOS16(index); - index += 2; - udelay(val); - break; - case 4: - val = RBIOS16(index); - index += 2; - mdelay(val); - break; - case 6: - slave_addr = id & 0xff; - slave_addr >>= 1; /* 7 bit addressing */ - index++; - reg = RBIOS8(index); - index++; - val = RBIOS8(index); - index++; - radeon_i2c_put_byte(tmds->i2c_bus, - slave_addr, - reg, val); - break; - default: - DRM_ERROR("Unknown id %d\n", id >> 13); - break; - } - blocks--; - } - return true; - } - } - } else { - offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); - if (offset) { - index = offset + 10; - id = RBIOS16(index); - while (id != 0xffff) { - index += 2; - switch (id >> 13) { - case 0: - reg = (id & 0x1fff) * 4; - val = RBIOS32(index); - WREG32(reg, val); - break; - case 2: - reg = (id & 0x1fff) * 4; - and_mask = RBIOS32(index); - index += 4; - or_mask = RBIOS32(index); - index += 4; - val = RREG32(reg); - val = (val & and_mask) | or_mask; - WREG32(reg, val); - break; - case 4: - val = RBIOS16(index); - index += 2; - udelay(val); - break; - case 5: - reg = id & 0x1fff; - and_mask = RBIOS32(index); - index += 4; - or_mask = RBIOS32(index); - index += 4; - val = RREG32_PLL(reg); - val = (val & and_mask) | or_mask; - WREG32_PLL(reg, val); - break; - case 6: - reg = id & 0x1fff; - val = RBIOS8(index); - index += 1; - radeon_i2c_put_byte(tmds->i2c_bus, - tmds->slave_addr, - reg, val); - break; - default: - DRM_ERROR("Unknown id %d\n", id >> 13); - break; - } - id = RBIOS16(index); - } - return true; - } - } - return false; -} - -static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) -{ - struct radeon_device *rdev = dev->dev_private; - - if (offset) { - while (RBIOS16(offset)) { - uint16_t cmd = ((RBIOS16(offset) & 0xe000) >> 13); - uint32_t addr = (RBIOS16(offset) & 0x1fff); - uint32_t val, and_mask, or_mask; - uint32_t tmp; - - offset += 2; - switch (cmd) { - case 0: - val = RBIOS32(offset); - offset += 4; - WREG32(addr, val); - break; - case 1: - val = RBIOS32(offset); - offset += 4; - WREG32(addr, val); - break; - case 2: - and_mask = RBIOS32(offset); - offset += 4; - or_mask = RBIOS32(offset); - offset += 4; - tmp = RREG32(addr); - tmp &= and_mask; - tmp |= or_mask; - WREG32(addr, tmp); - break; - case 3: - and_mask = RBIOS32(offset); - offset += 4; - or_mask = RBIOS32(offset); - offset += 4; - tmp = RREG32(addr); - tmp &= and_mask; - tmp |= or_mask; - WREG32(addr, tmp); - break; - case 4: - val = RBIOS16(offset); - offset += 2; - udelay(val); - break; - case 5: - val = RBIOS16(offset); - offset += 2; - switch (addr) { - case 8: - while (val--) { - if (! - (RREG32_PLL - (RADEON_CLK_PWRMGT_CNTL) & - RADEON_MC_BUSY)) - break; - } - break; - case 9: - while (val--) { - if ((RREG32(RADEON_MC_STATUS) & - RADEON_MC_IDLE)) - break; - } - break; - default: - break; - } - break; - default: - break; - } - } - } -} - -static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) -{ - struct radeon_device *rdev = dev->dev_private; - - if (offset) { - while (RBIOS8(offset)) { - uint8_t cmd = ((RBIOS8(offset) & 0xc0) >> 6); - uint8_t addr = (RBIOS8(offset) & 0x3f); - uint32_t val, shift, tmp; - uint32_t and_mask, or_mask; - - offset++; - switch (cmd) { - case 0: - val = RBIOS32(offset); - offset += 4; - WREG32_PLL(addr, val); - break; - case 1: - shift = RBIOS8(offset) * 8; - offset++; - and_mask = RBIOS8(offset) << shift; - and_mask |= ~(0xff << shift); - offset++; - or_mask = RBIOS8(offset) << shift; - offset++; - tmp = RREG32_PLL(addr); - tmp &= and_mask; - tmp |= or_mask; - WREG32_PLL(addr, tmp); - break; - case 2: - case 3: - tmp = 1000; - switch (addr) { - case 1: - udelay(150); - break; - case 2: - mdelay(1); - break; - case 3: - while (tmp--) { - if (! - (RREG32_PLL - (RADEON_CLK_PWRMGT_CNTL) & - RADEON_MC_BUSY)) - break; - } - break; - case 4: - while (tmp--) { - if (RREG32_PLL - (RADEON_CLK_PWRMGT_CNTL) & - RADEON_DLL_READY) - break; - } - break; - case 5: - tmp = - RREG32_PLL(RADEON_CLK_PWRMGT_CNTL); - if (tmp & RADEON_CG_NO1_DEBUG_0) { -#if 0 - uint32_t mclk_cntl = - RREG32_PLL - (RADEON_MCLK_CNTL); - mclk_cntl &= 0xffff0000; - /*mclk_cntl |= 0x00001111;*//* ??? */ - WREG32_PLL(RADEON_MCLK_CNTL, - mclk_cntl); - mdelay(10); -#endif - WREG32_PLL - (RADEON_CLK_PWRMGT_CNTL, - tmp & - ~RADEON_CG_NO1_DEBUG_0); - mdelay(10); - } - break; - default: - break; - } - break; - default: - break; - } - } - } -} - -static void combios_parse_ram_reset_table(struct drm_device *dev, - uint16_t offset) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - if (offset) { - uint8_t val = RBIOS8(offset); - while (val != 0xff) { - offset++; - - if (val == 0x0f) { - uint32_t channel_complete_mask; - - if (ASIC_IS_R300(rdev)) - channel_complete_mask = - R300_MEM_PWRUP_COMPLETE; - else - channel_complete_mask = - RADEON_MEM_PWRUP_COMPLETE; - tmp = 20000; - while (tmp--) { - if ((RREG32(RADEON_MEM_STR_CNTL) & - channel_complete_mask) == - channel_complete_mask) - break; - } - } else { - uint32_t or_mask = RBIOS16(offset); - offset += 2; - - tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG); - tmp &= RADEON_SDRAM_MODE_MASK; - tmp |= or_mask; - WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp); - - or_mask = val << 24; - tmp = RREG32(RADEON_MEM_SDRAM_MODE_REG); - tmp &= RADEON_B3MEM_RESET_MASK; - tmp |= or_mask; - WREG32(RADEON_MEM_SDRAM_MODE_REG, tmp); - } - val = RBIOS8(offset); - } - } -} - -static uint32_t combios_detect_ram(struct drm_device *dev, int ram, - int mem_addr_mapping) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t mem_cntl; - uint32_t mem_size; - uint32_t addr = 0; - - mem_cntl = RREG32(RADEON_MEM_CNTL); - if (mem_cntl & RV100_HALF_MODE) - ram /= 2; - mem_size = ram; - mem_cntl &= ~(0xff << 8); - mem_cntl |= (mem_addr_mapping & 0xff) << 8; - WREG32(RADEON_MEM_CNTL, mem_cntl); - RREG32(RADEON_MEM_CNTL); - - /* sdram reset ? */ - - /* something like this???? */ - while (ram--) { - addr = ram * 1024 * 1024; - /* write to each page */ - WREG32(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); - WREG32(RADEON_MM_DATA, 0xdeadbeef); - /* read back and verify */ - WREG32(RADEON_MM_INDEX, (addr) | RADEON_MM_APER); - if (RREG32(RADEON_MM_DATA) != 0xdeadbeef) - return 0; - } - - return mem_size; -} - -static void combios_write_ram_size(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - uint8_t rev; - uint16_t offset; - uint32_t mem_size = 0; - uint32_t mem_cntl = 0; - - /* should do something smarter here I guess... */ - if (rdev->flags & RADEON_IS_IGP) - return; - - /* first check detected mem table */ - offset = combios_get_table_offset(dev, COMBIOS_DETECTED_MEM_TABLE); - if (offset) { - rev = RBIOS8(offset); - if (rev < 3) { - mem_cntl = RBIOS32(offset + 1); - mem_size = RBIOS16(offset + 5); - if ((rdev->family < CHIP_R200) && - !ASIC_IS_RN50(rdev)) - WREG32(RADEON_MEM_CNTL, mem_cntl); - } - } - - if (!mem_size) { - offset = - combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE); - if (offset) { - rev = RBIOS8(offset - 1); - if (rev < 1) { - if ((rdev->family < CHIP_R200) - && !ASIC_IS_RN50(rdev)) { - int ram = 0; - int mem_addr_mapping = 0; - - while (RBIOS8(offset)) { - ram = RBIOS8(offset); - mem_addr_mapping = - RBIOS8(offset + 1); - if (mem_addr_mapping != 0x25) - ram *= 2; - mem_size = - combios_detect_ram(dev, ram, - mem_addr_mapping); - if (mem_size) - break; - offset += 2; - } - } else - mem_size = RBIOS8(offset); - } else { - mem_size = RBIOS8(offset); - mem_size *= 2; /* convert to MB */ - } - } - } - - mem_size *= (1024 * 1024); /* convert to bytes */ - WREG32(RADEON_CONFIG_MEMSIZE, mem_size); -} - -void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable) -{ - uint16_t dyn_clk_info = - combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); - - if (dyn_clk_info) - combios_parse_pll_table(dev, dyn_clk_info); -} - -void radeon_combios_asic_init(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - uint16_t table; - - /* port hardcoded mac stuff from radeonfb */ - if (rdev->bios == NULL) - return; - - /* ASIC INIT 1 */ - table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_1_TABLE); - if (table) - combios_parse_mmio_table(dev, table); - - /* PLL INIT */ - table = combios_get_table_offset(dev, COMBIOS_PLL_INIT_TABLE); - if (table) - combios_parse_pll_table(dev, table); - - /* ASIC INIT 2 */ - table = combios_get_table_offset(dev, COMBIOS_ASIC_INIT_2_TABLE); - if (table) - combios_parse_mmio_table(dev, table); - - if (!(rdev->flags & RADEON_IS_IGP)) { - /* ASIC INIT 4 */ - table = - combios_get_table_offset(dev, COMBIOS_ASIC_INIT_4_TABLE); - if (table) - combios_parse_mmio_table(dev, table); - - /* RAM RESET */ - table = combios_get_table_offset(dev, COMBIOS_RAM_RESET_TABLE); - if (table) - combios_parse_ram_reset_table(dev, table); - - /* ASIC INIT 3 */ - table = - combios_get_table_offset(dev, COMBIOS_ASIC_INIT_3_TABLE); - if (table) - combios_parse_mmio_table(dev, table); - - /* write CONFIG_MEMSIZE */ - combios_write_ram_size(dev); - } - - /* quirk for rs4xx HP nx6125 laptop to make it resume - * - it hangs on resume inside the dynclk 1 table. - */ - if (rdev->family == CHIP_RS480 && - rdev->pdev->subsystem_vendor == 0x103c && - rdev->pdev->subsystem_device == 0x308b) - return; - - /* quirk for rs4xx HP dv5000 laptop to make it resume - * - it hangs on resume inside the dynclk 1 table. - */ - if (rdev->family == CHIP_RS480 && - rdev->pdev->subsystem_vendor == 0x103c && - rdev->pdev->subsystem_device == 0x30a4) - return; - - /* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume - * - it hangs on resume inside the dynclk 1 table. - */ - if (rdev->family == CHIP_RS480 && - rdev->pdev->subsystem_vendor == 0x103c && - rdev->pdev->subsystem_device == 0x30ae) - return; - - /* DYN CLK 1 */ - table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE); - if (table) - combios_parse_pll_table(dev, table); - -} - -void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch; - - bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); - bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - bios_7_scratch = RREG32(RADEON_BIOS_7_SCRATCH); - - /* let the bios control the backlight */ - bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN; - - /* tell the bios not to handle mode switching */ - bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS | - RADEON_ACC_MODE_CHANGE); - - /* tell the bios a driver is loaded */ - bios_7_scratch |= RADEON_DRV_LOADED; - - WREG32(RADEON_BIOS_0_SCRATCH, bios_0_scratch); - WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); - WREG32(RADEON_BIOS_7_SCRATCH, bios_7_scratch); -} - -void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t bios_6_scratch; - - bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - - if (lock) - bios_6_scratch |= RADEON_DRIVER_CRITICAL; - else - bios_6_scratch &= ~RADEON_DRIVER_CRITICAL; - - WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); -} - -void -radeon_combios_connected_scratch_regs(struct drm_connector *connector, - struct drm_encoder *encoder, - bool connected) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = - to_radeon_connector(connector); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t bios_4_scratch = RREG32(RADEON_BIOS_4_SCRATCH); - uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH); - - if ((radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("TV1 connected\n"); - /* fix me */ - bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; - /*save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; */ - bios_5_scratch |= RADEON_TV1_ON; - bios_5_scratch |= RADEON_ACC_REQ_TV1; - } else { - DRM_DEBUG_KMS("TV1 disconnected\n"); - bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; - bios_5_scratch &= ~RADEON_TV1_ON; - bios_5_scratch &= ~RADEON_ACC_REQ_TV1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_LCD1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("LCD1 connected\n"); - bios_4_scratch |= RADEON_LCD1_ATTACHED; - bios_5_scratch |= RADEON_LCD1_ON; - bios_5_scratch |= RADEON_ACC_REQ_LCD1; - } else { - DRM_DEBUG_KMS("LCD1 disconnected\n"); - bios_4_scratch &= ~RADEON_LCD1_ATTACHED; - bios_5_scratch &= ~RADEON_LCD1_ON; - bios_5_scratch &= ~RADEON_ACC_REQ_LCD1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("CRT1 connected\n"); - bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; - bios_5_scratch |= RADEON_CRT1_ON; - bios_5_scratch |= RADEON_ACC_REQ_CRT1; - } else { - DRM_DEBUG_KMS("CRT1 disconnected\n"); - bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; - bios_5_scratch &= ~RADEON_CRT1_ON; - bios_5_scratch &= ~RADEON_ACC_REQ_CRT1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("CRT2 connected\n"); - bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; - bios_5_scratch |= RADEON_CRT2_ON; - bios_5_scratch |= RADEON_ACC_REQ_CRT2; - } else { - DRM_DEBUG_KMS("CRT2 disconnected\n"); - bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; - bios_5_scratch &= ~RADEON_CRT2_ON; - bios_5_scratch &= ~RADEON_ACC_REQ_CRT2; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP1_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP1 connected\n"); - bios_4_scratch |= RADEON_DFP1_ATTACHED; - bios_5_scratch |= RADEON_DFP1_ON; - bios_5_scratch |= RADEON_ACC_REQ_DFP1; - } else { - DRM_DEBUG_KMS("DFP1 disconnected\n"); - bios_4_scratch &= ~RADEON_DFP1_ATTACHED; - bios_5_scratch &= ~RADEON_DFP1_ON; - bios_5_scratch &= ~RADEON_ACC_REQ_DFP1; - } - } - if ((radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) && - (radeon_connector->devices & ATOM_DEVICE_DFP2_SUPPORT)) { - if (connected) { - DRM_DEBUG_KMS("DFP2 connected\n"); - bios_4_scratch |= RADEON_DFP2_ATTACHED; - bios_5_scratch |= RADEON_DFP2_ON; - bios_5_scratch |= RADEON_ACC_REQ_DFP2; - } else { - DRM_DEBUG_KMS("DFP2 disconnected\n"); - bios_4_scratch &= ~RADEON_DFP2_ATTACHED; - bios_5_scratch &= ~RADEON_DFP2_ON; - bios_5_scratch &= ~RADEON_ACC_REQ_DFP2; - } - } - WREG32(RADEON_BIOS_4_SCRATCH, bios_4_scratch); - WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch); -} - -void -radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t bios_5_scratch = RREG32(RADEON_BIOS_5_SCRATCH); - - if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { - bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; - bios_5_scratch |= (crtc << RADEON_TV1_CRTC_SHIFT); - } - if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { - bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; - bios_5_scratch |= (crtc << RADEON_CRT1_CRTC_SHIFT); - } - if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { - bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; - bios_5_scratch |= (crtc << RADEON_CRT2_CRTC_SHIFT); - } - if (radeon_encoder->devices & ATOM_DEVICE_LCD1_SUPPORT) { - bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; - bios_5_scratch |= (crtc << RADEON_LCD1_CRTC_SHIFT); - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP1_SUPPORT) { - bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; - bios_5_scratch |= (crtc << RADEON_DFP1_CRTC_SHIFT); - } - if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) { - bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; - bios_5_scratch |= (crtc << RADEON_DFP2_CRTC_SHIFT); - } - WREG32(RADEON_BIOS_5_SCRATCH, bios_5_scratch); -} - -void -radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { - if (on) - bios_6_scratch |= RADEON_TV_DPMS_ON; - else - bios_6_scratch &= ~RADEON_TV_DPMS_ON; - } - if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { - if (on) - bios_6_scratch |= RADEON_CRT_DPMS_ON; - else - bios_6_scratch &= ~RADEON_CRT_DPMS_ON; - } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (on) - bios_6_scratch |= RADEON_LCD_DPMS_ON; - else - bios_6_scratch &= ~RADEON_LCD_DPMS_ON; - } - if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { - if (on) - bios_6_scratch |= RADEON_DFP_DPMS_ON; - else - bios_6_scratch &= ~RADEON_DFP_DPMS_ON; - } - WREG32(RADEON_BIOS_6_SCRATCH, bios_6_scratch); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_connectors.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_connectors.c deleted file mode 100644 index 3c2e7a00..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_connectors.c +++ /dev/null @@ -1,1947 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "drm_edid.h" -#include "drm_crtc_helper.h" -#include "drm_fb_helper.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" - -extern void -radeon_combios_connected_scratch_regs(struct drm_connector *connector, - struct drm_encoder *encoder, - bool connected); -extern void -radeon_atombios_connected_scratch_regs(struct drm_connector *connector, - struct drm_encoder *encoder, - bool connected); - -extern void -radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, - struct drm_connector *drm_connector); - -void radeon_connector_hotplug(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - /* bail if the connector does not have hpd pin, e.g., - * VGA, TV, etc. - */ - if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) - return; - - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - - /* if the connector is already off, don't turn it back on */ - if (connector->dpms != DRM_MODE_DPMS_ON) - return; - - /* just deal with DP (not eDP) here. */ - if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { - int saved_dpms = connector->dpms; - - /* Only turn off the display it it's physically disconnected */ - if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - else if (radeon_dp_needs_link_train(radeon_connector)) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - connector->dpms = saved_dpms; - } -} - -static void radeon_property_change_mode(struct drm_encoder *encoder) -{ - struct drm_crtc *crtc = encoder->crtc; - - if (crtc && crtc->enabled) { - drm_crtc_helper_set_mode(crtc, &crtc->mode, - crtc->x, crtc->y, crtc->fb); - } -} -static void -radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *best_encoder = NULL; - struct drm_encoder *encoder = NULL; - struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - struct drm_mode_object *obj; - bool connected; - int i; - - best_encoder = connector_funcs->best_encoder(connector); - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) - break; - - obj = drm_mode_object_find(connector->dev, - connector->encoder_ids[i], - DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - - encoder = obj_to_encoder(obj); - - if ((encoder == best_encoder) && (status == connector_status_connected)) - connected = true; - else - connected = false; - - if (rdev->is_atom_bios) - radeon_atombios_connected_scratch_regs(connector, encoder, connected); - else - radeon_combios_connected_scratch_regs(connector, encoder, connected); - - } -} - -struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type) -{ - struct drm_mode_object *obj; - struct drm_encoder *encoder; - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) - break; - - obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - - encoder = obj_to_encoder(obj); - if (encoder->encoder_type == encoder_type) - return encoder; - } - return NULL; -} - -struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) -{ - int enc_id = connector->encoder_ids[0]; - struct drm_mode_object *obj; - struct drm_encoder *encoder; - - /* pick the encoder ids */ - if (enc_id) { - obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); - if (!obj) - return NULL; - encoder = obj_to_encoder(obj); - return encoder; - } - return NULL; -} - -/* - * radeon_connector_analog_encoder_conflict_solve - * - search for other connectors sharing this encoder - * if priority is true, then set them disconnected if this is connected - * if priority is false, set us disconnected if they are connected - */ -static enum drm_connector_status -radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, - struct drm_encoder *encoder, - enum drm_connector_status current_status, - bool priority) -{ - struct drm_device *dev = connector->dev; - struct drm_connector *conflict; - struct radeon_connector *radeon_conflict; - int i; - - list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { - if (conflict == connector) - continue; - - radeon_conflict = to_radeon_connector(conflict); - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (conflict->encoder_ids[i] == 0) - break; - - /* if the IDs match */ - if (conflict->encoder_ids[i] == encoder->base.id) { - if (conflict->status != connector_status_connected) - continue; - - if (radeon_conflict->use_digital) - continue; - - if (priority == true) { - DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector)); - conflict->status = connector_status_disconnected; - radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); - } else { - DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict)); - current_status = connector_status_disconnected; - } - break; - } - } - } - return current_status; - -} - -static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *mode = NULL; - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - - if (native_mode->hdisplay != 0 && - native_mode->vdisplay != 0 && - native_mode->clock != 0) { - mode = drm_mode_duplicate(dev, native_mode); - mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; - drm_mode_set_name(mode); - - DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name); - } else if (native_mode->hdisplay != 0 && - native_mode->vdisplay != 0) { - /* mac laptops without an edid */ - /* Note that this is not necessarily the exact panel mode, - * but an approximation based on the cvt formula. For these - * systems we should ideally read the mode info out of the - * registers or add a mode table, but this works and is much - * simpler. - */ - mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); - mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; - DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); - } - return mode; -} - -static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *mode = NULL; - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - int i; - struct mode_size { - int w; - int h; - } common_modes[17] = { - { 640, 480}, - { 720, 480}, - { 800, 600}, - { 848, 480}, - {1024, 768}, - {1152, 768}, - {1280, 720}, - {1280, 800}, - {1280, 854}, - {1280, 960}, - {1280, 1024}, - {1440, 900}, - {1400, 1050}, - {1680, 1050}, - {1600, 1200}, - {1920, 1080}, - {1920, 1200} - }; - - for (i = 0; i < 17; i++) { - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { - if (common_modes[i].w > 1024 || - common_modes[i].h > 768) - continue; - } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - if (common_modes[i].w > native_mode->hdisplay || - common_modes[i].h > native_mode->vdisplay || - (common_modes[i].w == native_mode->hdisplay && - common_modes[i].h == native_mode->vdisplay)) - continue; - } - if (common_modes[i].w < 320 || common_modes[i].h < 200) - continue; - - mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); - drm_mode_probed_add(connector, mode); - } -} - -int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, - uint64_t val) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - - if (property == rdev->mode_info.coherent_mode_property) { - struct radeon_encoder_atom_dig *dig; - bool new_coherent_mode; - - /* need to find digital encoder on connector */ - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); - if (!encoder) - return 0; - - radeon_encoder = to_radeon_encoder(encoder); - - if (!radeon_encoder->enc_priv) - return 0; - - dig = radeon_encoder->enc_priv; - new_coherent_mode = val ? true : false; - if (dig->coherent_mode != new_coherent_mode) { - dig->coherent_mode = new_coherent_mode; - radeon_property_change_mode(&radeon_encoder->base); - } - } - - if (property == rdev->mode_info.underscan_property) { - /* need to find digital encoder on connector */ - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); - if (!encoder) - return 0; - - radeon_encoder = to_radeon_encoder(encoder); - - if (radeon_encoder->underscan_type != val) { - radeon_encoder->underscan_type = val; - radeon_property_change_mode(&radeon_encoder->base); - } - } - - if (property == rdev->mode_info.underscan_hborder_property) { - /* need to find digital encoder on connector */ - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); - if (!encoder) - return 0; - - radeon_encoder = to_radeon_encoder(encoder); - - if (radeon_encoder->underscan_hborder != val) { - radeon_encoder->underscan_hborder = val; - radeon_property_change_mode(&radeon_encoder->base); - } - } - - if (property == rdev->mode_info.underscan_vborder_property) { - /* need to find digital encoder on connector */ - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); - if (!encoder) - return 0; - - radeon_encoder = to_radeon_encoder(encoder); - - if (radeon_encoder->underscan_vborder != val) { - radeon_encoder->underscan_vborder = val; - radeon_property_change_mode(&radeon_encoder->base); - } - } - - if (property == rdev->mode_info.tv_std_property) { - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC); - if (!encoder) { - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC); - } - - if (!encoder) - return 0; - - radeon_encoder = to_radeon_encoder(encoder); - if (!radeon_encoder->enc_priv) - return 0; - if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) { - struct radeon_encoder_atom_dac *dac_int; - dac_int = radeon_encoder->enc_priv; - dac_int->tv_std = val; - } else { - struct radeon_encoder_tv_dac *dac_int; - dac_int = radeon_encoder->enc_priv; - dac_int->tv_std = val; - } - radeon_property_change_mode(&radeon_encoder->base); - } - - if (property == rdev->mode_info.load_detect_property) { - struct radeon_connector *radeon_connector = - to_radeon_connector(connector); - - if (val == 0) - radeon_connector->dac_load_detect = false; - else - radeon_connector->dac_load_detect = true; - } - - if (property == rdev->mode_info.tmds_pll_property) { - struct radeon_encoder_int_tmds *tmds = NULL; - bool ret = false; - /* need to find digital encoder on connector */ - encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); - if (!encoder) - return 0; - - radeon_encoder = to_radeon_encoder(encoder); - - tmds = radeon_encoder->enc_priv; - if (!tmds) - return 0; - - if (val == 0) { - if (rdev->is_atom_bios) - ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds); - else - ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds); - } - if (val == 1 || ret == false) { - radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds); - } - radeon_property_change_mode(&radeon_encoder->base); - } - - return 0; -} - -static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - struct drm_display_mode *t, *mode; - - /* If the EDID preferred mode doesn't match the native mode, use it */ - list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { - if (mode->type & DRM_MODE_TYPE_PREFERRED) { - if (mode->hdisplay != native_mode->hdisplay || - mode->vdisplay != native_mode->vdisplay) - memcpy(native_mode, mode, sizeof(*mode)); - } - } - - /* Try to get native mode details from EDID if necessary */ - if (!native_mode->clock) { - list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { - if (mode->hdisplay == native_mode->hdisplay && - mode->vdisplay == native_mode->vdisplay) { - *native_mode = *mode; - drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); - DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n"); - break; - } - } - } - - if (!native_mode->clock) { - DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); - radeon_encoder->rmx_type = RMX_OFF; - } -} - -static int radeon_lvds_get_modes(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_encoder *encoder; - int ret = 0; - struct drm_display_mode *mode; - - if (radeon_connector->ddc_bus) { - ret = radeon_ddc_get_modes(radeon_connector); - if (ret > 0) { - encoder = radeon_best_single_encoder(connector); - if (encoder) { - radeon_fixup_lvds_native_mode(encoder, connector); - /* add scaled modes */ - radeon_add_common_modes(encoder, connector); - } - return ret; - } - } - - encoder = radeon_best_single_encoder(connector); - if (!encoder) - return 0; - - /* we have no EDID modes */ - mode = radeon_fp_native_mode(encoder); - if (mode) { - ret = 1; - drm_mode_probed_add(connector, mode); - /* add the width/height from vbios tables if available */ - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - /* add scaled modes */ - radeon_add_common_modes(encoder, connector); - } - - return ret; -} - -static int radeon_lvds_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_encoder *encoder = radeon_best_single_encoder(connector); - - if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) - return MODE_PANEL; - - if (encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - - /* AVIVO hardware supports downscaling modes larger than the panel - * to the panel size, but I'm not sure this is desirable. - */ - if ((mode->hdisplay > native_mode->hdisplay) || - (mode->vdisplay > native_mode->vdisplay)) - return MODE_PANEL; - - /* if scaling is disabled, block non-native modes */ - if (radeon_encoder->rmx_type == RMX_OFF) { - if ((mode->hdisplay != native_mode->hdisplay) || - (mode->vdisplay != native_mode->vdisplay)) - return MODE_PANEL; - } - } - - return MODE_OK; -} - -static enum drm_connector_status -radeon_lvds_detect(struct drm_connector *connector, bool force) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_encoder *encoder = radeon_best_single_encoder(connector); - enum drm_connector_status ret = connector_status_disconnected; - - if (encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - - /* check if panel is valid */ - if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) - ret = connector_status_connected; - - } - - /* check for edid as well */ - if (radeon_connector->edid) - ret = connector_status_connected; - else { - if (radeon_connector->ddc_bus) { - radeon_connector->edid = drm_get_edid(&radeon_connector->base, - &radeon_connector->ddc_bus->adapter); - if (radeon_connector->edid) - ret = connector_status_connected; - } - } - /* check acpi lid status ??? */ - - radeon_connector_update_scratch_regs(connector, ret); - return ret; -} - -static void radeon_connector_destroy(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - if (radeon_connector->edid) - kfree(radeon_connector->edid); - kfree(radeon_connector->con_priv); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static int radeon_lvds_set_property(struct drm_connector *connector, - struct drm_property *property, - uint64_t value) -{ - struct drm_device *dev = connector->dev; - struct radeon_encoder *radeon_encoder; - enum radeon_rmx_type rmx_type; - - DRM_DEBUG_KMS("\n"); - if (property != dev->mode_config.scaling_mode_property) - return 0; - - if (connector->encoder) - radeon_encoder = to_radeon_encoder(connector->encoder); - else { - struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector)); - } - - switch (value) { - case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break; - case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break; - case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break; - default: - case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break; - } - if (radeon_encoder->rmx_type == rmx_type) - return 0; - - radeon_encoder->rmx_type = rmx_type; - - radeon_property_change_mode(&radeon_encoder->base); - return 0; -} - - -struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { - .get_modes = radeon_lvds_get_modes, - .mode_valid = radeon_lvds_mode_valid, - .best_encoder = radeon_best_single_encoder, -}; - -struct drm_connector_funcs radeon_lvds_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = radeon_lvds_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = radeon_connector_destroy, - .set_property = radeon_lvds_set_property, -}; - -static int radeon_vga_get_modes(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - int ret; - - ret = radeon_ddc_get_modes(radeon_connector); - - return ret; -} - -static int radeon_vga_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - - /* XXX check mode bandwidth */ - - if ((mode->clock / 10) > rdev->clock.max_pixel_clock) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static enum drm_connector_status -radeon_vga_detect(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_encoder *encoder; - struct drm_encoder_helper_funcs *encoder_funcs; - bool dret = false; - enum drm_connector_status ret = connector_status_disconnected; - - encoder = radeon_best_single_encoder(connector); - if (!encoder) - ret = connector_status_disconnected; - - if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector); - if (dret) { - radeon_connector->detected_by_load = false; - if (radeon_connector->edid) { - kfree(radeon_connector->edid); - radeon_connector->edid = NULL; - } - radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); - - if (!radeon_connector->edid) { - DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", - drm_get_connector_name(connector)); - ret = connector_status_connected; - } else { - radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); - - /* some oems have boards with separate digital and analog connectors - * with a shared ddc line (often vga + hdmi) - */ - if (radeon_connector->use_digital && radeon_connector->shared_ddc) { - kfree(radeon_connector->edid); - radeon_connector->edid = NULL; - ret = connector_status_disconnected; - } else - ret = connector_status_connected; - } - } else { - - /* if we aren't forcing don't do destructive polling */ - if (!force) { - /* only return the previous status if we last - * detected a monitor via load. - */ - if (radeon_connector->detected_by_load) - return connector->status; - else - return ret; - } - - if (radeon_connector->dac_load_detect && encoder) { - encoder_funcs = encoder->helper_private; - ret = encoder_funcs->detect(encoder, connector); - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; - } - } - - if (ret == connector_status_connected) - ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); - - /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the - * vbios to deal with KVMs. If we have one and are not able to detect a monitor - * by other means, assume the CRT is connected and use that EDID. - */ - if ((!rdev->is_atom_bios) && - (ret == connector_status_disconnected) && - rdev->mode_info.bios_hardcoded_edid_size) { - ret = connector_status_connected; - } - - radeon_connector_update_scratch_regs(connector, ret); - return ret; -} - -struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = { - .get_modes = radeon_vga_get_modes, - .mode_valid = radeon_vga_mode_valid, - .best_encoder = radeon_best_single_encoder, -}; - -struct drm_connector_funcs radeon_vga_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = radeon_vga_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = radeon_connector_destroy, - .set_property = radeon_connector_set_property, -}; - -static int radeon_tv_get_modes(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_display_mode *tv_mode; - struct drm_encoder *encoder; - - encoder = radeon_best_single_encoder(connector); - if (!encoder) - return 0; - - /* avivo chips can scale any mode */ - if (rdev->family >= CHIP_RS600) - /* add scaled modes */ - radeon_add_common_modes(encoder, connector); - else { - /* only 800x600 is supported right now on pre-avivo chips */ - tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); - tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, tv_mode); - } - return 1; -} - -static int radeon_tv_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) - return MODE_CLOCK_RANGE; - return MODE_OK; -} - -static enum drm_connector_status -radeon_tv_detect(struct drm_connector *connector, bool force) -{ - struct drm_encoder *encoder; - struct drm_encoder_helper_funcs *encoder_funcs; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - enum drm_connector_status ret = connector_status_disconnected; - - if (!radeon_connector->dac_load_detect) - return ret; - - encoder = radeon_best_single_encoder(connector); - if (!encoder) - ret = connector_status_disconnected; - else { - encoder_funcs = encoder->helper_private; - ret = encoder_funcs->detect(encoder, connector); - } - if (ret == connector_status_connected) - ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); - radeon_connector_update_scratch_regs(connector, ret); - return ret; -} - -struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = { - .get_modes = radeon_tv_get_modes, - .mode_valid = radeon_tv_mode_valid, - .best_encoder = radeon_best_single_encoder, -}; - -struct drm_connector_funcs radeon_tv_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = radeon_tv_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = radeon_connector_destroy, - .set_property = radeon_connector_set_property, -}; - -static int radeon_dvi_get_modes(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - int ret; - - ret = radeon_ddc_get_modes(radeon_connector); - return ret; -} - -static bool radeon_check_hpd_status_unchanged(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - enum drm_connector_status status; - - /* We only trust HPD on R600 and newer ASICS. */ - if (rdev->family >= CHIP_R600 - && radeon_connector->hpd.hpd != RADEON_HPD_NONE) { - if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) - status = connector_status_connected; - else - status = connector_status_disconnected; - if (connector->status == status) - return true; - } - - return false; -} - -/* - * DVI is complicated - * Do a DDC probe, if DDC probe passes, get the full EDID so - * we can do analog/digital monitor detection at this point. - * If the monitor is an analog monitor or we got no DDC, - * we need to find the DAC encoder object for this connector. - * If we got no DDC, we do load detection on the DAC encoder object. - * If we got analog DDC or load detection passes on the DAC encoder - * we have to check if this analog encoder is shared with anyone else (TV) - * if its shared we have to set the other connector to disconnected. - */ -static enum drm_connector_status -radeon_dvi_detect(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_encoder *encoder = NULL; - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_mode_object *obj; - int i; - enum drm_connector_status ret = connector_status_disconnected; - bool dret = false; - - if (!force && radeon_check_hpd_status_unchanged(connector)) - return connector->status; - - if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector); - if (dret) { - radeon_connector->detected_by_load = false; - if (radeon_connector->edid) { - kfree(radeon_connector->edid); - radeon_connector->edid = NULL; - } - radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); - - if (!radeon_connector->edid) { - DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", - drm_get_connector_name(connector)); - /* rs690 seems to have a problem with connectors not existing and always - * return a block of 0's. If we see this just stop polling on this output */ - if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) { - ret = connector_status_disconnected; - DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); - radeon_connector->ddc_bus = NULL; - } - } else { - radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); - - /* some oems have boards with separate digital and analog connectors - * with a shared ddc line (often vga + hdmi) - */ - if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) { - kfree(radeon_connector->edid); - radeon_connector->edid = NULL; - ret = connector_status_disconnected; - } else - ret = connector_status_connected; - - /* This gets complicated. We have boards with VGA + HDMI with a - * shared DDC line and we have boards with DVI-D + HDMI with a shared - * DDC line. The latter is more complex because with DVI<->HDMI adapters - * you don't really know what's connected to which port as both are digital. - */ - if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { - struct drm_connector *list_connector; - struct radeon_connector *list_radeon_connector; - list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) { - if (connector == list_connector) - continue; - list_radeon_connector = to_radeon_connector(list_connector); - if (list_radeon_connector->shared_ddc && - (list_radeon_connector->ddc_bus->rec.i2c_id == - radeon_connector->ddc_bus->rec.i2c_id)) { - /* cases where both connectors are digital */ - if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) { - /* hpd is our only option in this case */ - if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { - kfree(radeon_connector->edid); - radeon_connector->edid = NULL; - ret = connector_status_disconnected; - } - } - } - } - } - } - } - - if ((ret == connector_status_connected) && (radeon_connector->use_digital == true)) - goto out; - - /* DVI-D and HDMI-A are digital only */ - if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) || - (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA)) - goto out; - - /* if we aren't forcing don't do destructive polling */ - if (!force) { - /* only return the previous status if we last - * detected a monitor via load. - */ - if (radeon_connector->detected_by_load) - ret = connector->status; - goto out; - } - - /* find analog encoder */ - if (radeon_connector->dac_load_detect) { - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) - break; - - obj = drm_mode_object_find(connector->dev, - connector->encoder_ids[i], - DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - - encoder = obj_to_encoder(obj); - - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && - encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) - continue; - - encoder_funcs = encoder->helper_private; - if (encoder_funcs->detect) { - if (ret != connector_status_connected) { - ret = encoder_funcs->detect(encoder, connector); - if (ret == connector_status_connected) { - radeon_connector->use_digital = false; - } - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; - } - break; - } - } - } - - if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) && - encoder) { - ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); - } - - /* RN50 and some RV100 asics in servers often have a hardcoded EDID in the - * vbios to deal with KVMs. If we have one and are not able to detect a monitor - * by other means, assume the DFP is connected and use that EDID. In most - * cases the DVI port is actually a virtual KVM port connected to the service - * processor. - */ -out: - if ((!rdev->is_atom_bios) && - (ret == connector_status_disconnected) && - rdev->mode_info.bios_hardcoded_edid_size) { - radeon_connector->use_digital = true; - ret = connector_status_connected; - } - - /* updated in get modes as well since we need to know if it's analog or digital */ - radeon_connector_update_scratch_regs(connector, ret); - return ret; -} - -/* okay need to be smart in here about which encoder to pick */ -struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) -{ - int enc_id = connector->encoder_ids[0]; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct drm_mode_object *obj; - struct drm_encoder *encoder; - int i; - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) - break; - - obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - - encoder = obj_to_encoder(obj); - - if (radeon_connector->use_digital == true) { - if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) - return encoder; - } else { - if (encoder->encoder_type == DRM_MODE_ENCODER_DAC || - encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) - return encoder; - } - } - - /* see if we have a default encoder TODO */ - - /* then check use digitial */ - /* pick the first one */ - if (enc_id) { - obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); - if (!obj) - return NULL; - encoder = obj_to_encoder(obj); - return encoder; - } - return NULL; -} - -static void radeon_dvi_force(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - if (connector->force == DRM_FORCE_ON) - radeon_connector->use_digital = false; - if (connector->force == DRM_FORCE_ON_DIGITAL) - radeon_connector->use_digital = true; -} - -static int radeon_dvi_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - /* XXX check mode bandwidth */ - - /* clocks over 135 MHz have heat issues with DVI on RV100 */ - if (radeon_connector->use_digital && - (rdev->family == CHIP_RV100) && - (mode->clock > 135000)) - return MODE_CLOCK_HIGH; - - if (radeon_connector->use_digital && (mode->clock > 165000)) { - if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || - (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || - (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) - return MODE_OK; - else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { - if (ASIC_IS_DCE6(rdev)) { - /* HDMI 1.3+ supports max clock of 340 Mhz */ - if (mode->clock > 340000) - return MODE_CLOCK_HIGH; - else - return MODE_OK; - } else - return MODE_CLOCK_HIGH; - } else - return MODE_CLOCK_HIGH; - } - - /* check against the max pixel clock */ - if ((mode->clock / 10) > rdev->clock.max_pixel_clock) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { - .get_modes = radeon_dvi_get_modes, - .mode_valid = radeon_dvi_mode_valid, - .best_encoder = radeon_dvi_encoder, -}; - -struct drm_connector_funcs radeon_dvi_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = radeon_dvi_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = radeon_connector_set_property, - .destroy = radeon_connector_destroy, - .force = radeon_dvi_force, -}; - -static void radeon_dp_connector_destroy(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - - if (radeon_connector->edid) - kfree(radeon_connector->edid); - if (radeon_dig_connector->dp_i2c_bus) - radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); - kfree(radeon_connector->con_priv); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - -static int radeon_dp_get_modes(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - struct drm_encoder *encoder = radeon_best_single_encoder(connector); - int ret; - - if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || - (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { - struct drm_display_mode *mode; - - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { - if (!radeon_dig_connector->edp_on) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_ON); - ret = radeon_ddc_get_modes(radeon_connector); - if (!radeon_dig_connector->edp_on) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_OFF); - } else { - /* need to setup ddc on the bridge */ - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != - ENCODER_OBJECT_ID_NONE) { - if (encoder) - radeon_atom_ext_encoder_setup_ddc(encoder); - } - ret = radeon_ddc_get_modes(radeon_connector); - } - - if (ret > 0) { - if (encoder) { - radeon_fixup_lvds_native_mode(encoder, connector); - /* add scaled modes */ - radeon_add_common_modes(encoder, connector); - } - return ret; - } - - if (!encoder) - return 0; - - /* we have no EDID modes */ - mode = radeon_fp_native_mode(encoder); - if (mode) { - ret = 1; - drm_mode_probed_add(connector, mode); - /* add the width/height from vbios tables if available */ - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - /* add scaled modes */ - radeon_add_common_modes(encoder, connector); - } - } else { - /* need to setup ddc on the bridge */ - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != - ENCODER_OBJECT_ID_NONE) { - if (encoder) - radeon_atom_ext_encoder_setup_ddc(encoder); - } - ret = radeon_ddc_get_modes(radeon_connector); - } - - return ret; -} - -u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector) -{ - struct drm_mode_object *obj; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - int i; - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) - break; - - obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - - encoder = obj_to_encoder(obj); - radeon_encoder = to_radeon_encoder(encoder); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_TRAVIS: - case ENCODER_OBJECT_ID_NUTMEG: - return radeon_encoder->encoder_id; - default: - break; - } - } - - return ENCODER_OBJECT_ID_NONE; -} - -bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) -{ - struct drm_mode_object *obj; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - int i; - bool found = false; - - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - if (connector->encoder_ids[i] == 0) - break; - - obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER); - if (!obj) - continue; - - encoder = obj_to_encoder(obj); - radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2) - found = true; - } - - return found; -} - -bool radeon_connector_is_dp12_capable(struct drm_connector *connector) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - - if (ASIC_IS_DCE5(rdev) && - (rdev->clock.dp_extclk >= 53900) && - radeon_connector_encoder_is_hbr2(connector)) { - return true; - } - - return false; -} - -static enum drm_connector_status -radeon_dp_detect(struct drm_connector *connector, bool force) -{ - struct drm_device *dev = connector->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - enum drm_connector_status ret = connector_status_disconnected; - struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - struct drm_encoder *encoder = radeon_best_single_encoder(connector); - - if (!force && radeon_check_hpd_status_unchanged(connector)) - return connector->status; - - if (radeon_connector->edid) { - kfree(radeon_connector->edid); - radeon_connector->edid = NULL; - } - - if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || - (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { - if (encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - - /* check if panel is valid */ - if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) - ret = connector_status_connected; - } - /* eDP is always DP */ - radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; - if (!radeon_dig_connector->edp_on) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_ON); - if (radeon_dp_getdpcd(radeon_connector)) - ret = connector_status_connected; - if (!radeon_dig_connector->edp_on) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_OFF); - } else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != - ENCODER_OBJECT_ID_NONE) { - /* DP bridges are always DP */ - radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; - /* get the DPCD from the bridge */ - radeon_dp_getdpcd(radeon_connector); - - if (encoder) { - /* setup ddc on the bridge */ - radeon_atom_ext_encoder_setup_ddc(encoder); - if (radeon_ddc_probe(radeon_connector)) /* try DDC */ - ret = connector_status_connected; - else if (radeon_connector->dac_load_detect) { /* try load detection */ - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - ret = encoder_funcs->detect(encoder, connector); - } - } - } else { - radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); - if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { - ret = connector_status_connected; - if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) - radeon_dp_getdpcd(radeon_connector); - } else { - if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { - if (radeon_dp_getdpcd(radeon_connector)) - ret = connector_status_connected; - } else { - if (radeon_ddc_probe(radeon_connector)) - ret = connector_status_connected; - } - } - } - - radeon_connector_update_scratch_regs(connector, ret); - return ret; -} - -static int radeon_dp_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - - /* XXX check mode bandwidth */ - - if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) || - (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { - struct drm_encoder *encoder = radeon_best_single_encoder(connector); - - if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) - return MODE_PANEL; - - if (encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - - /* AVIVO hardware supports downscaling modes larger than the panel - * to the panel size, but I'm not sure this is desirable. - */ - if ((mode->hdisplay > native_mode->hdisplay) || - (mode->vdisplay > native_mode->vdisplay)) - return MODE_PANEL; - - /* if scaling is disabled, block non-native modes */ - if (radeon_encoder->rmx_type == RMX_OFF) { - if ((mode->hdisplay != native_mode->hdisplay) || - (mode->vdisplay != native_mode->vdisplay)) - return MODE_PANEL; - } - } - return MODE_OK; - } else { - if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || - (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) - return radeon_dp_mode_valid_helper(connector, mode); - else - return MODE_OK; - } -} - -struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { - .get_modes = radeon_dp_get_modes, - .mode_valid = radeon_dp_mode_valid, - .best_encoder = radeon_dvi_encoder, -}; - -struct drm_connector_funcs radeon_dp_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .detect = radeon_dp_detect, - .fill_modes = drm_helper_probe_single_connector_modes, - .set_property = radeon_connector_set_property, - .destroy = radeon_dp_connector_destroy, - .force = radeon_dvi_force, -}; - -void -radeon_add_atom_connector(struct drm_device *dev, - uint32_t connector_id, - uint32_t supported_device, - int connector_type, - struct radeon_i2c_bus_rec *i2c_bus, - uint32_t igp_lane_info, - uint16_t connector_object_id, - struct radeon_hpd *hpd, - struct radeon_router *router) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *radeon_dig_connector; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - uint32_t subpixel_order = SubPixelNone; - bool shared_ddc = false; - bool is_dp_bridge = false; - - if (connector_type == DRM_MODE_CONNECTOR_Unknown) - return; - - /* if the user selected tv=0 don't try and add the connector */ - if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || - (connector_type == DRM_MODE_CONNECTOR_Composite) || - (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && - (radeon_tv == 0)) - return; - - /* see if we already added it */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - if (radeon_connector->connector_id == connector_id) { - radeon_connector->devices |= supported_device; - return; - } - if (radeon_connector->ddc_bus && i2c_bus->valid) { - if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) { - radeon_connector->shared_ddc = true; - shared_ddc = true; - } - if (radeon_connector->router_bus && router->ddc_valid && - (radeon_connector->router.router_id == router->router_id)) { - radeon_connector->shared_ddc = false; - shared_ddc = false; - } - } - } - - /* check if it's a dp bridge */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->devices & supported_device) { - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_TRAVIS: - case ENCODER_OBJECT_ID_NUTMEG: - is_dp_bridge = true; - break; - default: - break; - } - } - } - - radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); - if (!radeon_connector) - return; - - connector = &radeon_connector->base; - - radeon_connector->connector_id = connector_id; - radeon_connector->devices = supported_device; - radeon_connector->shared_ddc = shared_ddc; - radeon_connector->connector_object_id = connector_object_id; - radeon_connector->hpd = *hpd; - - radeon_connector->router = *router; - if (router->ddc_valid || router->cd_valid) { - radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); - if (!radeon_connector->router_bus) - DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n"); - } - - if (is_dp_bridge) { - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); - if (!radeon_dig_connector) - goto failed; - radeon_dig_connector->igp_lane_info = igp_lane_info; - radeon_connector->con_priv = radeon_dig_connector; - drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); - if (i2c_bus->valid) { - /* add DP i2c bus */ - if (connector_type == DRM_MODE_CONNECTOR_eDP) - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); - else - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - switch (connector_type) { - case DRM_MODE_CONNECTOR_VGA: - case DRM_MODE_CONNECTOR_DVIA: - default: - connector->interlace_allowed = true; - connector->doublescan_allowed = true; - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - break; - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_HDMIB: - case DRM_MODE_CONNECTOR_DisplayPort: - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_OFF); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_hborder_property, - 0); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_vborder_property, - 0); - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = true; - if (connector_type == DRM_MODE_CONNECTOR_HDMIB) - connector->doublescan_allowed = true; - else - connector->doublescan_allowed = false; - if (connector_type == DRM_MODE_CONNECTOR_DVII) { - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - } - break; - case DRM_MODE_CONNECTOR_LVDS: - case DRM_MODE_CONNECTOR_eDP: - drm_connector_attach_property(&radeon_connector->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - break; - } - } else { - switch (connector_type) { - case DRM_MODE_CONNECTOR_VGA: - drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - /* no HPD on analog connectors */ - radeon_connector->hpd.hpd = RADEON_HPD_NONE; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - connector->interlace_allowed = true; - connector->doublescan_allowed = true; - break; - case DRM_MODE_CONNECTOR_DVIA: - drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - /* no HPD on analog connectors */ - radeon_connector->hpd.hpd = RADEON_HPD_NONE; - connector->interlace_allowed = true; - connector->doublescan_allowed = true; - break; - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); - if (!radeon_dig_connector) - goto failed; - radeon_dig_connector->igp_lane_info = igp_lane_info; - radeon_connector->con_priv = radeon_dig_connector; - drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - subpixel_order = SubPixelHorizontalRGB; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.coherent_mode_property, - 1); - if (ASIC_IS_AVIVO(rdev)) { - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_OFF); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_hborder_property, - 0); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_vborder_property, - 0); - } - if (connector_type == DRM_MODE_CONNECTOR_DVII) { - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - } - connector->interlace_allowed = true; - if (connector_type == DRM_MODE_CONNECTOR_DVII) - connector->doublescan_allowed = true; - else - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_HDMIB: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); - if (!radeon_dig_connector) - goto failed; - radeon_dig_connector->igp_lane_info = igp_lane_info; - radeon_connector->con_priv = radeon_dig_connector; - drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.coherent_mode_property, - 1); - if (ASIC_IS_AVIVO(rdev)) { - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_OFF); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_hborder_property, - 0); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_vborder_property, - 0); - } - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = true; - if (connector_type == DRM_MODE_CONNECTOR_HDMIB) - connector->doublescan_allowed = true; - else - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_DisplayPort: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); - if (!radeon_dig_connector) - goto failed; - radeon_dig_connector->igp_lane_info = igp_lane_info; - radeon_connector->con_priv = radeon_dig_connector; - drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); - if (i2c_bus->valid) { - /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - subpixel_order = SubPixelHorizontalRGB; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.coherent_mode_property, - 1); - if (ASIC_IS_AVIVO(rdev)) { - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_property, - UNDERSCAN_OFF); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_hborder_property, - 0); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.underscan_vborder_property, - 0); - } - connector->interlace_allowed = true; - /* in theory with a DP to VGA converter... */ - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_eDP: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); - if (!radeon_dig_connector) - goto failed; - radeon_dig_connector->igp_lane_info = igp_lane_info; - radeon_connector->con_priv = radeon_dig_connector; - drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); - if (i2c_bus->valid) { - /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - drm_connector_attach_property(&radeon_connector->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_9PinDIN: - drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.tv_std_property, - radeon_atombios_get_tv_info(rdev)); - /* no HPD on analog connectors */ - radeon_connector->hpd.hpd = RADEON_HPD_NONE; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_LVDS: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); - if (!radeon_dig_connector) - goto failed; - radeon_dig_connector->igp_lane_info = igp_lane_info; - radeon_connector->con_priv = radeon_dig_connector; - drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - drm_connector_attach_property(&radeon_connector->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - break; - } - } - - if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { - if (i2c_bus->valid) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - } else - connector->polled = DRM_CONNECTOR_POLL_HPD; - - connector->display_info.subpixel_order = subpixel_order; - drm_sysfs_connector_add(connector); - return; - -failed: - drm_connector_cleanup(connector); - kfree(connector); -} - -void -radeon_add_legacy_connector(struct drm_device *dev, - uint32_t connector_id, - uint32_t supported_device, - int connector_type, - struct radeon_i2c_bus_rec *i2c_bus, - uint16_t connector_object_id, - struct radeon_hpd *hpd) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - uint32_t subpixel_order = SubPixelNone; - - if (connector_type == DRM_MODE_CONNECTOR_Unknown) - return; - - /* if the user selected tv=0 don't try and add the connector */ - if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || - (connector_type == DRM_MODE_CONNECTOR_Composite) || - (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && - (radeon_tv == 0)) - return; - - /* see if we already added it */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - if (radeon_connector->connector_id == connector_id) { - radeon_connector->devices |= supported_device; - return; - } - } - - radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); - if (!radeon_connector) - return; - - connector = &radeon_connector->base; - - radeon_connector->connector_id = connector_id; - radeon_connector->devices = supported_device; - radeon_connector->connector_object_id = connector_object_id; - radeon_connector->hpd = *hpd; - - switch (connector_type) { - case DRM_MODE_CONNECTOR_VGA: - drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - /* no HPD on analog connectors */ - radeon_connector->hpd.hpd = RADEON_HPD_NONE; - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - connector->interlace_allowed = true; - connector->doublescan_allowed = true; - break; - case DRM_MODE_CONNECTOR_DVIA: - drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - /* no HPD on analog connectors */ - radeon_connector->hpd.hpd = RADEON_HPD_NONE; - connector->interlace_allowed = true; - connector->doublescan_allowed = true; - break; - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - if (connector_type == DRM_MODE_CONNECTOR_DVII) { - radeon_connector->dac_load_detect = true; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - 1); - } - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = true; - if (connector_type == DRM_MODE_CONNECTOR_DVII) - connector->doublescan_allowed = true; - else - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_9PinDIN: - drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); - radeon_connector->dac_load_detect = true; - /* RS400,RC410,RS480 chipset seems to report a lot - * of false positive on load detect, we haven't yet - * found a way to make load detect reliable on those - * chipset, thus just disable it for TV. - */ - if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) - radeon_connector->dac_load_detect = false; - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.load_detect_property, - radeon_connector->dac_load_detect); - drm_connector_attach_property(&radeon_connector->base, - rdev->mode_info.tv_std_property, - radeon_combios_get_tv_info(rdev)); - /* no HPD on analog connectors */ - radeon_connector->hpd.hpd = RADEON_HPD_NONE; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - break; - case DRM_MODE_CONNECTOR_LVDS: - drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); - drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); - if (i2c_bus->valid) { - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) - DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); - } - drm_connector_attach_property(&radeon_connector->base, - dev->mode_config.scaling_mode_property, - DRM_MODE_SCALE_FULLSCREEN); - subpixel_order = SubPixelHorizontalRGB; - connector->interlace_allowed = false; - connector->doublescan_allowed = false; - break; - } - - if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) { - if (i2c_bus->valid) - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - } else - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->display_info.subpixel_order = subpixel_order; - drm_sysfs_connector_add(connector); - if (connector_type == DRM_MODE_CONNECTOR_LVDS) { - struct drm_encoder *drm_encoder; - - list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) { - struct radeon_encoder *radeon_encoder; - - radeon_encoder = to_radeon_encoder(drm_encoder); - if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_LVDS) - radeon_legacy_backlight_init(radeon_encoder, connector); - } - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cp.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cp.c deleted file mode 100644 index 0ebb7d47..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cp.c +++ /dev/null @@ -1,2261 +0,0 @@ -/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */ -/* - * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * Copyright 2007 Advanced Micro Devices, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kevin E. Martin - * Gareth Hughes - */ - -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_sarea.h" -#include "radeon_drm.h" -#include "radeon_drv.h" -#include "r300_reg.h" - -#define RADEON_FIFO_DEBUG 0 - -/* Firmware Names */ -#define FIRMWARE_R100 "radeon/R100_cp.bin" -#define FIRMWARE_R200 "radeon/R200_cp.bin" -#define FIRMWARE_R300 "radeon/R300_cp.bin" -#define FIRMWARE_R420 "radeon/R420_cp.bin" -#define FIRMWARE_RS690 "radeon/RS690_cp.bin" -#define FIRMWARE_RS600 "radeon/RS600_cp.bin" -#define FIRMWARE_R520 "radeon/R520_cp.bin" - -MODULE_FIRMWARE(FIRMWARE_R100); -MODULE_FIRMWARE(FIRMWARE_R200); -MODULE_FIRMWARE(FIRMWARE_R300); -MODULE_FIRMWARE(FIRMWARE_R420); -MODULE_FIRMWARE(FIRMWARE_RS690); -MODULE_FIRMWARE(FIRMWARE_RS600); -MODULE_FIRMWARE(FIRMWARE_R520); - -static int radeon_do_cleanup_cp(struct drm_device * dev); -static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); - -u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) -{ - u32 val; - - if (dev_priv->flags & RADEON_IS_AGP) { - val = DRM_READ32(dev_priv->ring_rptr, off); - } else { - val = *(((volatile u32 *) - dev_priv->ring_rptr->handle) + - (off / sizeof(u32))); - val = le32_to_cpu(val); - } - return val; -} - -u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) -{ - if (dev_priv->writeback_works) - return radeon_read_ring_rptr(dev_priv, 0); - else { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return RADEON_READ(R600_CP_RB_RPTR); - else - return RADEON_READ(RADEON_CP_RB_RPTR); - } -} - -void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) -{ - if (dev_priv->flags & RADEON_IS_AGP) - DRM_WRITE32(dev_priv->ring_rptr, off, val); - else - *(((volatile u32 *) dev_priv->ring_rptr->handle) + - (off / sizeof(u32))) = cpu_to_le32(val); -} - -void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) -{ - radeon_write_ring_rptr(dev_priv, 0, val); -} - -u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) -{ - if (dev_priv->writeback_works) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return radeon_read_ring_rptr(dev_priv, - R600_SCRATCHOFF(index)); - else - return radeon_read_ring_rptr(dev_priv, - RADEON_SCRATCHOFF(index)); - } else { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return RADEON_READ(R600_SCRATCH_REG0 + 4*index); - else - return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); - } -} - -u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - - if (addr < 0x10000) - ret = DRM_READ32(dev_priv->mmio, addr); - else { - DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); - ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); - } - - return ret; -} - -static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff)); - ret = RADEON_READ(R520_MC_IND_DATA); - RADEON_WRITE(R520_MC_IND_INDEX, 0); - return ret; -} - -static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff); - ret = RADEON_READ(RS480_NB_MC_DATA); - RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); - return ret; -} - -static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); - ret = RADEON_READ(RS690_MC_DATA); - RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK); - return ret; -} - -static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | - RS600_MC_IND_CITF_ARB0)); - ret = RADEON_READ(RS600_MC_DATA); - return ret; -} - -static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) -{ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) - return RS690_READ_MCIND(dev_priv, addr); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - return RS600_READ_MCIND(dev_priv, addr); - else - return RS480_READ_MCIND(dev_priv, addr); -} - -u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) -{ - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - return RADEON_READ(R700_MC_VM_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return RADEON_READ(R600_MC_VM_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) - return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); - else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) - return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) - return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); - else - return RADEON_READ(RADEON_MC_FB_LOCATION); -} - -static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) -{ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) - R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); - else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) - RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) - R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); - else - RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); -} - -void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) -{ - /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { - RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ - RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ - RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) - R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); - else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) - RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) - R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); - else - RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); -} - -void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) -{ - u32 agp_base_hi = upper_32_bits(agp_base); - u32 agp_base_lo = agp_base & 0xffffffff; - u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; - - /* R6xx/R7xx must be aligned to a 4MB boundary */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) - RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { - R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); - R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); - RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); - RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { - R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); - R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); - RADEON_WRITE(RS480_AGP_BASE_2, agp_base_hi); - } else { - RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo); - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200) - RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi); - } -} - -void radeon_enable_bm(struct drm_radeon_private *dev_priv) -{ - u32 tmp; - /* Turn on bus mastering */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - /* rs600/rs690/rs740 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); - } /* PCIE cards appears to not need this */ -} - -static int RADEON_READ_PLL(struct drm_device * dev, int addr) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); - return RADEON_READ(RADEON_CLOCK_CNTL_DATA); -} - -static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) -{ - RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); - return RADEON_READ(RADEON_PCIE_DATA); -} - -#if RADEON_FIFO_DEBUG -static void radeon_status(drm_radeon_private_t * dev_priv) -{ - printk("%s:\n", __func__); - printk("RBBM_STATUS = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_RBBM_STATUS)); - printk("CP_RB_RTPR = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR)); - printk("CP_RB_WTPR = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR)); - printk("AIC_CNTL = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_CNTL)); - printk("AIC_STAT = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_STAT)); - printk("AIC_PT_BASE = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE)); - printk("TLB_ADDR = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR)); - printk("TLB_DATA = 0x%08x\n", - (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA)); -} -#endif - -/* ================================================================ - * Engine, FIFO control - */ - -static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) -{ - u32 tmp; - int i; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { - tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB3D_DC_FLUSH_ALL; - RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) - & RADEON_RB3D_DC_BUSY)) { - return 0; - } - DRM_UDELAY(1); - } - } else { - /* don't flush or purge cache here or lockup */ - return 0; - } - -#if RADEON_FIFO_DEBUG - DRM_ERROR("failed!\n"); - radeon_status(dev_priv); -#endif - return -EBUSY; -} - -static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries) -{ - int i; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - int slots = (RADEON_READ(RADEON_RBBM_STATUS) - & RADEON_RBBM_FIFOCNT_MASK); - if (slots >= entries) - return 0; - DRM_UDELAY(1); - } - DRM_DEBUG("wait for fifo failed status : 0x%08X 0x%08X\n", - RADEON_READ(RADEON_RBBM_STATUS), - RADEON_READ(R300_VAP_CNTL_STATUS)); - -#if RADEON_FIFO_DEBUG - DRM_ERROR("failed!\n"); - radeon_status(dev_priv); -#endif - return -EBUSY; -} - -static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) -{ - int i, ret; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - ret = radeon_do_wait_for_fifo(dev_priv, 64); - if (ret) - return ret; - - for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RBBM_STATUS) - & RADEON_RBBM_ACTIVE)) { - radeon_do_pixcache_flush(dev_priv); - return 0; - } - DRM_UDELAY(1); - } - DRM_DEBUG("wait idle failed status : 0x%08X 0x%08X\n", - RADEON_READ(RADEON_RBBM_STATUS), - RADEON_READ(R300_VAP_CNTL_STATUS)); - -#if RADEON_FIFO_DEBUG - DRM_ERROR("failed!\n"); - radeon_status(dev_priv); -#endif - return -EBUSY; -} - -static void radeon_init_pipes(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - uint32_t gb_tile_config, gb_pipe_sel = 0; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { - uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2); - if ((z_pipe_sel & 3) == 3) - dev_priv->num_z_pipes = 2; - else - dev_priv->num_z_pipes = 1; - } else - dev_priv->num_z_pipes = 1; - - /* RS4xx/RS6xx/R4xx/R5xx */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { - gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); - dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; - /* SE cards have 1 pipe */ - if ((dev->pdev->device == 0x5e4c) || - (dev->pdev->device == 0x5e4f)) - dev_priv->num_gb_pipes = 1; - } else { - /* R3xx */ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 && - dev->pdev->device != 0x4144) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 && - dev->pdev->device != 0x4148)) { - dev_priv->num_gb_pipes = 2; - } else { - /* RV3xx/R300 AD/R350 AH */ - dev_priv->num_gb_pipes = 1; - } - } - DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes); - - gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/); - - switch (dev_priv->num_gb_pipes) { - case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break; - case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break; - case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break; - default: - case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { - RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); - RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); - } - RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); - radeon_do_wait_for_idle(dev_priv); - RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG); - RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) | - R300_DC_AUTOFLUSH_ENABLE | - R300_DC_DC_DISABLE_IGNORE_PE)); - - -} - -/* ================================================================ - * CP control, initialization - */ - -/* Load the microcode for the CP */ -static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv) -{ - struct platform_device *pdev; - const char *fw_name = NULL; - int err; - - DRM_DEBUG("\n"); - - pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); - err = IS_ERR(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); - return -EINVAL; - } - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { - DRM_INFO("Loading R100 Microcode\n"); - fw_name = FIRMWARE_R100; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { - DRM_INFO("Loading R200 Microcode\n"); - fw_name = FIRMWARE_R200; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - DRM_INFO("Loading R300 Microcode\n"); - fw_name = FIRMWARE_R300; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { - DRM_INFO("Loading R400 Microcode\n"); - fw_name = FIRMWARE_R420; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - DRM_INFO("Loading RS690/RS740 Microcode\n"); - fw_name = FIRMWARE_RS690; - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - DRM_INFO("Loading RS600 Microcode\n"); - fw_name = FIRMWARE_RS600; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R580) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { - DRM_INFO("Loading R500 Microcode\n"); - fw_name = FIRMWARE_R520; - } - - err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev); - platform_device_unregister(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", - fw_name); - } else if (dev_priv->me_fw->size % 8) { - printk(KERN_ERR - "radeon_cp: Bogus length %zu in firmware \"%s\"\n", - dev_priv->me_fw->size, fw_name); - err = -EINVAL; - release_firmware(dev_priv->me_fw); - dev_priv->me_fw = NULL; - } - return err; -} - -static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv) -{ - const __be32 *fw_data; - int i, size; - - radeon_do_wait_for_idle(dev_priv); - - if (dev_priv->me_fw) { - size = dev_priv->me_fw->size / 4; - fw_data = (const __be32 *)&dev_priv->me_fw->data[0]; - RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); - for (i = 0; i < size; i += 2) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, - be32_to_cpup(&fw_data[i])); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, - be32_to_cpup(&fw_data[i + 1])); - } - } -} - -/* Flush any pending commands to the CP. This should only be used just - * prior to a wait for idle, as it informs the engine that the command - * stream is ending. - */ -static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv) -{ - DRM_DEBUG("\n"); -#if 0 - u32 tmp; - - tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31); - RADEON_WRITE(RADEON_CP_RB_WPTR, tmp); -#endif -} - -/* Wait for the CP to go idle. - */ -int radeon_do_cp_idle(drm_radeon_private_t * dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(6); - - RADEON_PURGE_CACHE(); - RADEON_PURGE_ZCACHE(); - RADEON_WAIT_UNTIL_IDLE(); - - ADVANCE_RING(); - COMMIT_RING(); - - return radeon_do_wait_for_idle(dev_priv); -} - -/* Start the Command Processor. - */ -static void radeon_do_cp_start(drm_radeon_private_t * dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - radeon_do_wait_for_idle(dev_priv); - - RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode); - - dev_priv->cp_running = 1; - - /* on r420, any DMA from CP to system memory while 2D is active - * can cause a hang. workaround is to queue a CP RESYNC token - */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) { - BEGIN_RING(3); - OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1)); - OUT_RING(5); /* scratch reg 5 */ - OUT_RING(0xdeadbeef); - ADVANCE_RING(); - COMMIT_RING(); - } - - BEGIN_RING(8); - /* isync can only be written through cp on r5xx write it here */ - OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0)); - OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D | - RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI); - RADEON_PURGE_CACHE(); - RADEON_PURGE_ZCACHE(); - RADEON_WAIT_UNTIL_IDLE(); - ADVANCE_RING(); - COMMIT_RING(); - - dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED; -} - -/* Reset the Command Processor. This will not flush any pending - * commands, so you must wait for the CP command stream to complete - * before calling this routine. - */ -static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv) -{ - u32 cur_read_ptr; - DRM_DEBUG("\n"); - - cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); - RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); - SET_RING_HEAD(dev_priv, cur_read_ptr); - dev_priv->ring.tail = cur_read_ptr; -} - -/* Stop the Command Processor. This will not flush any pending - * commands, so you must flush the command stream and wait for the CP - * to go idle before calling this routine. - */ -static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv) -{ - RING_LOCALS; - DRM_DEBUG("\n"); - - /* finish the pending CP_RESYNC token */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) { - BEGIN_RING(2); - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - OUT_RING(R300_RB3D_DC_FINISH); - ADVANCE_RING(); - COMMIT_RING(); - radeon_do_wait_for_idle(dev_priv); - } - - RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS); - - dev_priv->cp_running = 0; -} - -/* Reset the engine. This will stop the CP if it is running. - */ -static int radeon_do_engine_reset(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - u32 clock_cntl_index = 0, mclk_cntl = 0, rbbm_soft_reset; - DRM_DEBUG("\n"); - - radeon_do_pixcache_flush(dev_priv); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - /* may need something similar for newer chips */ - clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX); - mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL); - - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl | - RADEON_FORCEON_MCLKA | - RADEON_FORCEON_MCLKB | - RADEON_FORCEON_YCLKA | - RADEON_FORCEON_YCLKB | - RADEON_FORCEON_MC | - RADEON_FORCEON_AIC)); - } - - rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET); - - RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset | - RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB)); - RADEON_READ(RADEON_RBBM_SOFT_RESET); - RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & - ~(RADEON_SOFT_RESET_CP | - RADEON_SOFT_RESET_HI | - RADEON_SOFT_RESET_SE | - RADEON_SOFT_RESET_RE | - RADEON_SOFT_RESET_PP | - RADEON_SOFT_RESET_E2 | - RADEON_SOFT_RESET_RB))); - RADEON_READ(RADEON_RBBM_SOFT_RESET); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) { - RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl); - RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); - RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); - } - - /* setup the raster pipes */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) - radeon_init_pipes(dev); - - /* Reset the CP ring */ - radeon_do_cp_reset(dev_priv); - - /* The CP is no longer running after an engine reset */ - dev_priv->cp_running = 0; - - /* Reset any pending vertex, indirect buffers */ - radeon_freelist_reset(dev); - - return 0; -} - -static void radeon_cp_init_ring_buffer(struct drm_device * dev, - drm_radeon_private_t *dev_priv, - struct drm_file *file_priv) -{ - struct drm_radeon_master_private *master_priv; - u32 ring_start, cur_read_ptr; - - /* Initialize the memory controller. With new memory map, the fb location - * is not changed, it should have been properly initialized already. Part - * of the problem is that the code below is bogus, assuming the GART is - * always appended to the fb which is not necessarily the case - */ - if (!dev_priv->new_memmap) - radeon_write_fb_location(dev_priv, - ((dev_priv->gart_vm_start - 1) & 0xffff0000) - | (dev_priv->fb_location >> 16)); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - radeon_write_agp_base(dev_priv, dev->agp->base); - - radeon_write_agp_location(dev_priv, - (((dev_priv->gart_vm_start - 1 + - dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); - - ring_start = (dev_priv->cp_ring->offset - - dev->agp->base - + dev_priv->gart_vm_start); - } else -#endif - ring_start = (dev_priv->cp_ring->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - RADEON_WRITE(RADEON_CP_RB_BASE, ring_start); - - /* Set the write pointer delay */ - RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0); - - /* Initialize the ring buffer's read and write pointers */ - cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR); - RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr); - SET_RING_HEAD(dev_priv, cur_read_ptr); - dev_priv->ring.tail = cur_read_ptr; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset - - dev->agp->base + dev_priv->gart_vm_start); - } else -#endif - { - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset - - ((unsigned long) dev->sg->virtual) - + dev_priv->gart_vm_start); - } - - /* Set ring buffer size */ -#ifdef __BIG_ENDIAN - RADEON_WRITE(RADEON_CP_RB_CNTL, - RADEON_BUF_SWAP_32BIT | - (dev_priv->ring.fetch_size_l2ow << 18) | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#else - RADEON_WRITE(RADEON_CP_RB_CNTL, - (dev_priv->ring.fetch_size_l2ow << 18) | - (dev_priv->ring.rptr_update_l2qw << 8) | - dev_priv->ring.size_l2qw); -#endif - - - /* Initialize the scratch register pointer. This will cause - * the scratch register values to be written out to memory - * whenever they are updated. - * - * We simply put this behind the ring read pointer, this works - * with PCI GART as well as (whatever kind of) AGP GART - */ - RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) - + RADEON_SCRATCH_REG_OFFSET); - - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); - - radeon_enable_bm(dev_priv); - - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); - RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); - - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); - RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); - - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); - RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); - - /* reset sarea copies of these */ - master_priv = file_priv->master->driver_priv; - if (master_priv->sarea_priv) { - master_priv->sarea_priv->last_frame = 0; - master_priv->sarea_priv->last_dispatch = 0; - master_priv->sarea_priv->last_clear = 0; - } - - radeon_do_wait_for_idle(dev_priv); - - /* Sync everything up */ - RADEON_WRITE(RADEON_ISYNC_CNTL, - (RADEON_ISYNC_ANY2D_IDLE3D | - RADEON_ISYNC_ANY3D_IDLE2D | - RADEON_ISYNC_WAIT_IDLEGUI | - RADEON_ISYNC_CPSCRATCH_IDLEGUI)); - -} - -static void radeon_test_writeback(drm_radeon_private_t * dev_priv) -{ - u32 tmp; - - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - - /* Writeback doesn't seem to work everywhere, test it here and possibly - * enable it if it appears to work - */ - radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); - - RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); - - for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - u32 val; - - val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); - if (val == 0xdeadbeef) - break; - DRM_UDELAY(1); - } - - if (tmp < dev_priv->usec_timeout) { - dev_priv->writeback_works = 1; - DRM_INFO("writeback test succeeded in %d usecs\n", tmp); - } else { - dev_priv->writeback_works = 0; - DRM_INFO("writeback test failed\n"); - } - if (radeon_no_wb == 1) { - dev_priv->writeback_works = 0; - DRM_INFO("writeback forced off\n"); - } - - if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | - RADEON_RB_NO_UPDATE); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); - } -} - -/* Enable or disable IGP GART on the chip */ -static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) -{ - u32 temp; - - if (on) { - DRM_DEBUG("programming igp gart %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - - temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) - IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | - RS690_BLOCK_GFX_D3_EN)); - else - IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); - - IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | - RS480_VA_SIZE_32MB)); - - temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID); - IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN | - RS480_TLB_ENABLE | - RS480_GTW_LAC_EN | - RS480_1LEVEL_GART)); - - temp = dev_priv->gart_info.bus_addr & 0xfffff000; - temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4; - IGP_WRITE_MCIND(RS480_GART_BASE, temp); - - temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL); - IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) | - RS480_REQ_TYPE_SNOOP_DIS)); - - radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start); - - dev_priv->gart_size = 32*1024*1024; - temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & - 0xffff0000) | (dev_priv->gart_vm_start >> 16)); - - radeon_write_agp_location(dev_priv, temp); - - temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE); - IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | - RS480_VA_SIZE_32MB)); - - do { - temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); - if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) - break; - DRM_UDELAY(1); - } while (1); - - IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, - RS480_GART_CACHE_INVALIDATE); - - do { - temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL); - if ((temp & RS480_GART_CACHE_INVALIDATE) == 0) - break; - DRM_UDELAY(1); - } while (1); - - IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0); - } else { - IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0); - } -} - -/* Enable or disable IGP GART on the chip */ -static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) -{ - u32 temp; - int i; - - if (on) { - DRM_DEBUG("programming igp gart %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | - RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); - - for (i = 0; i < 19; i++) - IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, - (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | - RS600_SYSTEM_ACCESS_MODE_IN_SYS | - RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | - RS600_EFFECTIVE_L1_CACHE_SIZE(3) | - RS600_ENABLE_FRAGMENT_PROCESSING | - RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); - - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | - RS600_PAGE_TABLE_TYPE_FLAT)); - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); - - /* setup the page table aperture */ - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, - dev_priv->gart_info.bus_addr); - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, - dev_priv->gart_vm_start); - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, - (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); - IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); - - /* setup the system aperture */ - IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, - dev_priv->gart_vm_start); - IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, - (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); - - /* enable page tables */ - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); - - temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); - IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); - - /* invalidate the cache */ - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); - - } else { - IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); - temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); - temp &= ~RS600_ENABLE_PAGE_TABLES; - IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); - } -} - -static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) -{ - u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); - if (on) { - - DRM_DEBUG("programming pcie %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, - dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, - dev_priv->gart_info.bus_addr); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, - dev_priv->gart_vm_start); - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, - dev_priv->gart_vm_start + - dev_priv->gart_size - 1); - - radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */ - - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, - RADEON_PCIE_TX_GART_EN); - } else { - RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, - tmp & ~RADEON_PCIE_TX_GART_EN); - } -} - -/* Enable or disable PCI GART on the chip */ -static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) -{ - u32 tmp; - - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740) || - (dev_priv->flags & RADEON_IS_IGPGART)) { - radeon_set_igpgart(dev_priv, on); - return; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - rs600_set_igpgart(dev_priv, on); - return; - } - - if (dev_priv->flags & RADEON_IS_PCIE) { - radeon_set_pciegart(dev_priv, on); - return; - } - - tmp = RADEON_READ(RADEON_AIC_CNTL); - - if (on) { - RADEON_WRITE(RADEON_AIC_CNTL, - tmp | RADEON_PCIGART_TRANSLATE_EN); - - /* set PCI GART page-table base address - */ - RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); - - /* set address range for PCI address translate - */ - RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start); - RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start - + dev_priv->gart_size - 1); - - /* Turn off AGP aperture -- is this required for PCI GART? - */ - radeon_write_agp_location(dev_priv, 0xffffffc0); - RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */ - } else { - RADEON_WRITE(RADEON_AIC_CNTL, - tmp & ~RADEON_PCIGART_TRANSLATE_EN); - } -} - -static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) -{ - struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; - struct radeon_virt_surface *vp; - int i; - - for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { - if (!dev_priv->virt_surfaces[i].file_priv || - dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) - break; - } - if (i >= 2 * RADEON_MAX_SURFACES) - return -ENOMEM; - vp = &dev_priv->virt_surfaces[i]; - - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - struct radeon_surface *sp = &dev_priv->surfaces[i]; - if (sp->refcount) - continue; - - vp->surface_index = i; - vp->lower = gart_info->bus_addr; - vp->upper = vp->lower + gart_info->table_size; - vp->flags = 0; - vp->file_priv = PCIGART_FILE_PRIV; - - sp->refcount = 1; - sp->lower = vp->lower; - sp->upper = vp->upper; - sp->flags = 0; - - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); - return 0; - } - - return -ENOMEM; -} - -static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - - DRM_DEBUG("\n"); - - /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { - DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; - } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) { - DRM_DEBUG("Restoring AGP flag\n"); - dev_priv->flags |= RADEON_IS_AGP; - } - - if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { - DRM_ERROR("PCI GART memory not allocated!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->usec_timeout = init->usec_timeout; - if (dev_priv->usec_timeout < 1 || - dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { - DRM_DEBUG("TIMEOUT problem!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - /* Enable vblank on CRTC1 for older X servers - */ - dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; - - switch(init->func) { - case RADEON_INIT_R200_CP: - dev_priv->microcode_version = UCODE_R200; - break; - case RADEON_INIT_R300_CP: - dev_priv->microcode_version = UCODE_R300; - break; - default: - dev_priv->microcode_version = UCODE_R100; - } - - dev_priv->do_boxes = 0; - dev_priv->cp_mode = init->cp_mode; - - /* We don't support anything other than bus-mastering ring mode, - * but the ring can be in either AGP or PCI space for the ring - * read pointer. - */ - if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && - (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { - DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - switch (init->fb_bpp) { - case 16: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; - break; - case 32: - default: - dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; - break; - } - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - - switch (init->depth_bpp) { - case 16: - dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; - break; - case 32: - default: - dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; - break; - } - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - - /* Hardware state for depth clears. Remove this if/when we no - * longer clear the depth buffer with a 3D rectangle. Hard-code - * all values to prevent unwanted 3D state from slipping through - * and screwing with the clear operation. - */ - dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | - (dev_priv->color_fmt << 10) | - (dev_priv->microcode_version == - UCODE_R100 ? RADEON_ZBLOCK16 : 0)); - - dev_priv->depth_clear.rb3d_zstencilcntl = - (dev_priv->depth_fmt | - RADEON_Z_TEST_ALWAYS | - RADEON_STENCIL_TEST_ALWAYS | - RADEON_STENCIL_S_FAIL_REPLACE | - RADEON_STENCIL_ZPASS_REPLACE | - RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE); - - dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | - RADEON_BFACE_SOLID | - RADEON_FFACE_SOLID | - RADEON_FLAT_SHADE_VTX_LAST | - RADEON_DIFFUSE_SHADE_FLAT | - RADEON_ALPHA_SHADE_FLAT | - RADEON_SPECULAR_SHADE_FLAT | - RADEON_FOG_SHADE_FLAT | - RADEON_VTX_PIX_CENTER_OGL | - RADEON_ROUND_MODE_TRUNC | - RADEON_ROUND_PREC_8TH_PIX); - - - dev_priv->ring_offset = init->ring_offset; - dev_priv->ring_rptr_offset = init->ring_rptr_offset; - dev_priv->buffers_offset = init->buffers_offset; - dev_priv->gart_textures_offset = init->gart_textures_offset; - - master_priv->sarea = drm_getsarea(dev); - if (!master_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); - if (!dev_priv->cp_ring) { - DRM_ERROR("could not find cp ring region!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); - if (!dev_priv->ring_rptr) { - DRM_ERROR("could not find ring read pointer!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find dma buffer region!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - - if (init->gart_textures_offset) { - dev_priv->gart_textures = - drm_core_findmap(dev, init->gart_textures_offset); - if (!dev_priv->gart_textures) { - DRM_ERROR("could not find GART texture region!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - } - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - drm_core_ioremap_wc(dev_priv->cp_ring, dev); - drm_core_ioremap_wc(dev_priv->ring_rptr, dev); - drm_core_ioremap_wc(dev->agp_buffer_map, dev); - if (!dev_priv->cp_ring->handle || - !dev_priv->ring_rptr->handle || - !dev->agp_buffer_map->handle) { - DRM_ERROR("could not find ioremap agp regions!\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - } else -#endif - { - dev_priv->cp_ring->handle = - (void *)(unsigned long)dev_priv->cp_ring->offset; - dev_priv->ring_rptr->handle = - (void *)(unsigned long)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = - (void *)(unsigned long)dev->agp_buffer_map->offset; - - DRM_DEBUG("dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle); - DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", - dev_priv->ring_rptr->handle); - DRM_DEBUG("dev->agp_buffer_map->handle %p\n", - dev->agp_buffer_map->handle); - } - - dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16; - dev_priv->fb_size = - ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000) - - dev_priv->fb_location; - - dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | - ((dev_priv->front_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | - ((dev_priv->back_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | - ((dev_priv->depth_offset - + dev_priv->fb_location) >> 10)); - - dev_priv->gart_size = init->gart_size; - - /* New let's set the memory map ... */ - if (dev_priv->new_memmap) { - u32 base = 0; - - DRM_INFO("Setting GART location based on new memory map\n"); - - /* If using AGP, try to locate the AGP aperture at the same - * location in the card and on the bus, though we have to - * align it down. - */ -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - base = dev->agp->base; - /* Check if valid */ - if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && - base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { - DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", - dev->agp->base); - base = 0; - } - } -#endif - /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ - if (base == 0) { - base = dev_priv->fb_location + dev_priv->fb_size; - if (base < dev_priv->fb_location || - ((base + dev_priv->gart_size) & 0xfffffffful) < base) - base = dev_priv->fb_location - - dev_priv->gart_size; - } - dev_priv->gart_vm_start = base & 0xffc00000u; - if (dev_priv->gart_vm_start != base) - DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", - base, dev_priv->gart_vm_start); - } else { - DRM_INFO("Setting GART location based on old memory map\n"); - dev_priv->gart_vm_start = dev_priv->fb_location + - RADEON_READ(RADEON_CONFIG_APER_SIZE); - } - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - dev->agp->base - + dev_priv->gart_vm_start); - else -#endif - dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - - (unsigned long)dev->sg->virtual - + dev_priv->gart_vm_start); - - DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); - DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start); - DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n", - dev_priv->gart_buffers_offset); - - dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; - dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle - + init->ring_size / sizeof(u32)); - dev_priv->ring.size = init->ring_size; - dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); - - dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; - dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8); - - dev_priv->ring.fetch_size = /* init->fetch_size */ 32; - dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16); - dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; - - dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); - } else -#endif - { - u32 sctrl; - int ret; - - dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); - /* if we have an offset set from userspace */ - if (dev_priv->pcigart_offset_set) { - dev_priv->gart_info.bus_addr = - (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location; - dev_priv->gart_info.mapping.offset = - dev_priv->pcigart_offset + dev_priv->fb_aper_offset; - dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; - - drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = - dev_priv->gart_info.mapping.handle; - - if (dev_priv->flags & RADEON_IS_PCIE) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - dev_priv->gart_info.gart_table_location = - DRM_ATI_GART_FB; - - DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", - dev_priv->gart_info.addr, - dev_priv->pcigart_offset); - } else { - if (dev_priv->flags & RADEON_IS_IGPGART) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - dev_priv->gart_info.gart_table_location = - DRM_ATI_GART_MAIN; - dev_priv->gart_info.addr = NULL; - dev_priv->gart_info.bus_addr = 0; - if (dev_priv->flags & RADEON_IS_PCIE) { - DRM_ERROR - ("Cannot use PCI Express without GART in FB memory\n"); - radeon_do_cleanup_cp(dev); - return -EINVAL; - } - } - - sctrl = RADEON_READ(RADEON_SURFACE_CNTL); - RADEON_WRITE(RADEON_SURFACE_CNTL, 0); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - ret = r600_page_table_init(dev); - else - ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); - RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); - - if (!ret) { - DRM_ERROR("failed to init PCI GART!\n"); - radeon_do_cleanup_cp(dev); - return -ENOMEM; - } - - ret = radeon_setup_pcigart_surface(dev_priv); - if (ret) { - DRM_ERROR("failed to setup GART surface!\n"); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - r600_page_table_cleanup(dev, &dev_priv->gart_info); - else - drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); - radeon_do_cleanup_cp(dev); - return ret; - } - - /* Turn on PCI GART */ - radeon_set_pcigart(dev_priv, 1); - } - - if (!dev_priv->me_fw) { - int err = radeon_cp_init_microcode(dev_priv); - if (err) { - DRM_ERROR("Failed to load firmware!\n"); - radeon_do_cleanup_cp(dev); - return err; - } - } - radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); - - dev_priv->last_buf = 0; - - radeon_do_engine_reset(dev); - radeon_test_writeback(dev_priv); - - return 0; -} - -static int radeon_do_cleanup_cp(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - /* Make sure interrupts are disabled here because the uninstall ioctl - * may not have been called from userspace and after dev_private - * is freed, it's too late. - */ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - if (dev_priv->cp_ring != NULL) { - drm_core_ioremapfree(dev_priv->cp_ring, dev); - dev_priv->cp_ring = NULL; - } - if (dev_priv->ring_rptr != NULL) { - drm_core_ioremapfree(dev_priv->ring_rptr, dev); - dev_priv->ring_rptr = NULL; - } - if (dev->agp_buffer_map != NULL) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - dev->agp_buffer_map = NULL; - } - } else -#endif - { - - if (dev_priv->gart_info.bus_addr) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) - r600_page_table_cleanup(dev, &dev_priv->gart_info); - else { - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); - } - } - - if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) - { - drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = NULL; - } - } - /* only clear to the start of flags */ - memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); - - return 0; -} - -/* This code will reinit the Radeon CP hardware after a resume from disc. - * AFAIK, it would be very difficult to pickle the state at suspend time, so - * here we make sure that all Radeon hardware initialisation is re-done without - * affecting running applications. - * - * Charl P. Botha - */ -static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (!dev_priv) { - DRM_ERROR("Called with no initialization\n"); - return -EINVAL; - } - - DRM_DEBUG("Starting radeon_do_resume_cp()\n"); - -#if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { - /* Turn off PCI GART */ - radeon_set_pcigart(dev_priv, 0); - } else -#endif - { - /* Turn on PCI GART */ - radeon_set_pcigart(dev_priv, 1); - } - - radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); - - dev_priv->have_z_offset = 0; - radeon_do_engine_reset(dev); - radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); - - DRM_DEBUG("radeon_do_resume_cp() complete\n"); - - return 0; -} - -int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_init_t *init = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (init->func == RADEON_INIT_R300_CP) - r300_init_reg_flags(dev); - - switch (init->func) { - case RADEON_INIT_CP: - case RADEON_INIT_R200_CP: - case RADEON_INIT_R300_CP: - return radeon_do_init_cp(dev, init, file_priv); - case RADEON_INIT_R600_CP: - return r600_do_init_cp(dev, init, file_priv); - case RADEON_CLEANUP_CP: - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_cleanup_cp(dev); - else - return radeon_do_cleanup_cp(dev); - } - - return -EINVAL; -} - -int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (dev_priv->cp_running) { - DRM_DEBUG("while CP running\n"); - return 0; - } - if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) { - DRM_DEBUG("called with bogus CP mode (%d)\n", - dev_priv->cp_mode); - return 0; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cp_start(dev_priv); - else - radeon_do_cp_start(dev_priv); - - return 0; -} - -/* Stop the CP. The engine must have been idled before calling this - * routine. - */ -int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_cp_stop_t *stop = data; - int ret; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv->cp_running) - return 0; - - /* Flush any pending CP commands. This ensures any outstanding - * commands are exectuted by the engine before we turn it off. - */ - if (stop->flush) { - radeon_do_cp_flush(dev_priv); - } - - /* If we fail to make the engine go idle, we return an error - * code so that the DRM ioctl wrapper can try again. - */ - if (stop->idle) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - ret = r600_do_cp_idle(dev_priv); - else - ret = radeon_do_cp_idle(dev_priv); - if (ret) - return ret; - } - - /* Finally, we can turn off the CP. If the engine isn't idle, - * we will get some dropped triangles as they won't be fully - * rendered before the CP is shut down. - */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cp_stop(dev_priv); - else - radeon_do_cp_stop(dev_priv); - - /* Reset the engine */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_engine_reset(dev); - else - radeon_do_engine_reset(dev); - - return 0; -} - -void radeon_do_release(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int i, ret; - - if (dev_priv) { - if (dev_priv->cp_running) { - /* Stop the cp */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - while ((ret = r600_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); -#ifdef __linux__ - schedule(); -#else - tsleep(&ret, PZERO, "rdnrel", 1); -#endif - } - } else { - while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); -#ifdef __linux__ - schedule(); -#else - tsleep(&ret, PZERO, "rdnrel", 1); -#endif - } - } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - r600_do_cp_stop(dev_priv); - r600_do_engine_reset(dev); - } else { - radeon_do_cp_stop(dev_priv); - radeon_do_engine_reset(dev); - } - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { - /* Disable *all* interrupts */ - if (dev_priv->mmio) /* remove this after permanent addmaps */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - - if (dev_priv->mmio) { /* remove all surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + - 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + - 16 * i, 0); - } - } - } - - /* Free memory heap structures */ - radeon_mem_takedown(&(dev_priv->gart_heap)); - radeon_mem_takedown(&(dev_priv->fb_heap)); - - /* deallocate kernel resources */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cleanup_cp(dev); - else - radeon_do_cleanup_cp(dev); - if (dev_priv->me_fw) { - release_firmware(dev_priv->me_fw); - dev_priv->me_fw = NULL; - } - if (dev_priv->pfp_fw) { - release_firmware(dev_priv->pfp_fw); - dev_priv->pfp_fw = NULL; - } - } -} - -/* Just reset the CP ring. Called as part of an X Server engine reset. - */ -int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (!dev_priv) { - DRM_DEBUG("called before init done\n"); - return -EINVAL; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_do_cp_reset(dev_priv); - else - radeon_do_cp_reset(dev_priv); - - /* The CP is no longer running after an engine reset */ - dev_priv->cp_running = 0; - - return 0; -} - -int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_cp_idle(dev_priv); - else - return radeon_do_cp_idle(dev_priv); -} - -/* Added by Charl P. Botha to call radeon_do_resume_cp(). - */ -int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_resume_cp(dev, file_priv); - else - return radeon_do_resume_cp(dev, file_priv); -} - -int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return r600_do_engine_reset(dev); - else - return radeon_do_engine_reset(dev); -} - -/* ================================================================ - * Fullscreen mode - */ - -/* KW: Deprecated to say the least: - */ -int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - return 0; -} - -/* ================================================================ - * Freelist management - */ - -/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through - * bufs until freelist code is used. Note this hides a problem with - * the scratch register * (used to keep track of last buffer - * completed) being written to before * the last buffer has actually - * completed rendering. - * - * KW: It's also a good way to find free buffers quickly. - * - * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't - * sleep. However, bugs in older versions of radeon_accel.c mean that - * we essentially have to do this, else old clients will break. - * - * However, it does leave open a potential deadlock where all the - * buffers are held by other clients, which can't release them because - * they can't get the lock. - */ - -struct drm_buf *radeon_freelist_get(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_buf_priv_t *buf_priv; - struct drm_buf *buf; - int i, t; - int start; - - if (++dev_priv->last_buf >= dma->buf_count) - dev_priv->last_buf = 0; - - start = dev_priv->last_buf; - - for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = GET_SCRATCH(dev_priv, 1); - DRM_DEBUG("done_age = %d\n", done_age); - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[start]; - buf_priv = buf->dev_private; - if (buf->file_priv == NULL || (buf->pending && - buf_priv->age <= - done_age)) { - dev_priv->stats.requested_bufs++; - buf->pending = 0; - return buf; - } - if (++start >= dma->buf_count) - start = 0; - } - - if (t) { - DRM_UDELAY(1); - dev_priv->stats.freelist_loops++; - } - } - - return NULL; -} - -void radeon_freelist_reset(struct drm_device * dev) -{ - struct drm_device_dma *dma = dev->dma; - drm_radeon_private_t *dev_priv = dev->dev_private; - int i; - - dev_priv->last_buf = 0; - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->age = 0; - } -} - -/* ================================================================ - * CP command submission - */ - -int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) -{ - drm_radeon_ring_buffer_t *ring = &dev_priv->ring; - int i; - u32 last_head = GET_RING_HEAD(dev_priv); - - for (i = 0; i < dev_priv->usec_timeout; i++) { - u32 head = GET_RING_HEAD(dev_priv); - - ring->space = (head - ring->tail) * sizeof(u32); - if (ring->space <= 0) - ring->space += ring->size; - if (ring->space > n) - return 0; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if (head != last_head) - i = 0; - last_head = head; - - DRM_UDELAY(1); - } - - /* FIXME: This return value is ignored in the BEGIN_RING macro! */ -#if RADEON_FIFO_DEBUG - radeon_status(dev_priv); - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; -} - -static int radeon_cp_get_buffers(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_dma * d) -{ - int i; - struct drm_buf *buf; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = radeon_freelist_get(dev); - if (!buf) - return -EBUSY; /* NOTE: broken client */ - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, - sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, - sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - int ret = 0; - struct drm_dma *d = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - d->granted_count = 0; - - if (d->request_count) { - ret = radeon_cp_get_buffers(dev, file_priv, d); - } - - return ret; -} - -int radeon_driver_load(struct drm_device *dev, unsigned long flags) -{ - drm_radeon_private_t *dev_priv; - int ret = 0; - - dev_priv = kzalloc(sizeof(drm_radeon_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev->dev_private = (void *)dev_priv; - dev_priv->flags = flags; - - switch (flags & RADEON_FAMILY_MASK) { - case CHIP_R100: - case CHIP_RV200: - case CHIP_R200: - case CHIP_R300: - case CHIP_R350: - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - case CHIP_RV515: - case CHIP_R520: - case CHIP_RV570: - case CHIP_R580: - dev_priv->flags |= RADEON_HAS_HIERZ; - break; - default: - /* all other chips have no hierarchical z buffer */ - break; - } - - pci_set_master(dev->pdev); - - if (drm_pci_device_is_agp(dev)) - dev_priv->flags |= RADEON_IS_AGP; - else if (pci_is_pcie(dev->pdev)) - dev_priv->flags |= RADEON_IS_PCIE; - else - dev_priv->flags |= RADEON_IS_PCI; - - ret = drm_addmap(dev, pci_resource_start(dev->pdev, 2), - pci_resource_len(dev->pdev, 2), _DRM_REGISTERS, - _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); - if (ret != 0) - return ret; - - ret = drm_vblank_init(dev, 2); - if (ret) { - radeon_driver_unload(dev); - return ret; - } - - DRM_DEBUG("%s card detected\n", - ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); - return ret; -} - -int radeon_master_create(struct drm_device *dev, struct drm_master *master) -{ - struct drm_radeon_master_private *master_priv; - unsigned long sareapage; - int ret; - - master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); - if (!master_priv) - return -ENOMEM; - - /* prebuild the SAREA */ - sareapage = max_t(unsigned long, SAREA_MAX, PAGE_SIZE); - ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, - &master_priv->sarea); - if (ret) { - DRM_ERROR("SAREA setup failed\n"); - kfree(master_priv); - return ret; - } - master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); - master_priv->sarea_priv->pfCurrentPage = 0; - - master->driver_priv = master_priv; - return 0; -} - -void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) -{ - struct drm_radeon_master_private *master_priv = master->driver_priv; - - if (!master_priv) - return; - - if (master_priv->sarea_priv && - master_priv->sarea_priv->pfCurrentPage != 0) - radeon_cp_dispatch_flip(dev, master); - - master_priv->sarea_priv = NULL; - if (master_priv->sarea) - drm_rmmap_locked(dev, master_priv->sarea); - - kfree(master_priv); - - master->driver_priv = NULL; -} - -/* Create mappings for registers and framebuffer so userland doesn't necessarily - * have to find them. - */ -int radeon_driver_firstopen(struct drm_device *dev) -{ - int ret; - drm_local_map_t *map; - drm_radeon_private_t *dev_priv = dev->dev_private; - - dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - - dev_priv->fb_aper_offset = pci_resource_start(dev->pdev, 0); - ret = drm_addmap(dev, dev_priv->fb_aper_offset, - pci_resource_len(dev->pdev, 0), _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING, &map); - if (ret != 0) - return ret; - - return 0; -} - -int radeon_driver_unload(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - DRM_DEBUG("\n"); - - drm_rmmap(dev, dev_priv->mmio); - - kfree(dev_priv); - - dev->dev_private = NULL; - return 0; -} - -void radeon_commit_ring(drm_radeon_private_t *dev_priv) -{ - int i; - u32 *ring; - int tail_aligned; - - /* check if the ring is padded out to 16-dword alignment */ - - tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1); - if (tail_aligned) { - int num_p2 = RADEON_RING_ALIGN - tail_aligned; - - ring = dev_priv->ring.start; - /* pad with some CP_PACKET2 */ - for (i = 0; i < num_p2; i++) - ring[dev_priv->ring.tail + i] = CP_PACKET2(); - - dev_priv->ring.tail += i; - - dev_priv->ring.space -= num_p2 * sizeof(u32); - } - - dev_priv->ring.tail &= dev_priv->ring.tail_mask; - - DRM_MEMORYBARRIER(); - GET_RING_HEAD( dev_priv ); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); - /* read from PCI bus to ensure correct posting */ - RADEON_READ(R600_CP_RB_RPTR); - } else { - RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); - /* read from PCI bus to ensure correct posting */ - RADEON_READ(RADEON_CP_RB_RPTR); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cs.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cs.c deleted file mode 100644 index 2418cf6d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cs.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Copyright 2008 Jerome Glisse. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon_reg.h" -#include "radeon.h" - -void r100_cs_dump_packet(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt); - -int radeon_cs_parser_relocs(struct radeon_cs_parser *p) -{ - struct drm_device *ddev = p->rdev->ddev; - struct radeon_cs_chunk *chunk; - unsigned i, j; - bool duplicate; - - if (p->chunk_relocs_idx == -1) { - return 0; - } - chunk = &p->chunks[p->chunk_relocs_idx]; - /* FIXME: we assume that each relocs use 4 dwords */ - p->nrelocs = chunk->length_dw / 4; - p->relocs_ptr = kcalloc(p->nrelocs, sizeof(void *), GFP_KERNEL); - if (p->relocs_ptr == NULL) { - return -ENOMEM; - } - p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL); - if (p->relocs == NULL) { - return -ENOMEM; - } - for (i = 0; i < p->nrelocs; i++) { - struct drm_radeon_cs_reloc *r; - - duplicate = false; - r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; - for (j = 0; j < i; j++) { - if (r->handle == p->relocs[j].handle) { - p->relocs_ptr[i] = &p->relocs[j]; - duplicate = true; - break; - } - } - if (!duplicate) { - p->relocs[i].gobj = drm_gem_object_lookup(ddev, - p->filp, - r->handle); - if (p->relocs[i].gobj == NULL) { - DRM_ERROR("gem object lookup failed 0x%x\n", - r->handle); - return -ENOENT; - } - p->relocs_ptr[i] = &p->relocs[i]; - p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj); - p->relocs[i].lobj.bo = p->relocs[i].robj; - p->relocs[i].lobj.wdomain = r->write_domain; - p->relocs[i].lobj.rdomain = r->read_domains; - p->relocs[i].lobj.tv.bo = &p->relocs[i].robj->tbo; - p->relocs[i].handle = r->handle; - p->relocs[i].flags = r->flags; - radeon_bo_list_add_object(&p->relocs[i].lobj, - &p->validated); - - } else - p->relocs[i].handle = 0; - } - return radeon_bo_list_validate(&p->validated); -} - -static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority) -{ - p->priority = priority; - - switch (ring) { - default: - DRM_ERROR("unknown ring id: %d\n", ring); - return -EINVAL; - case RADEON_CS_RING_GFX: - p->ring = RADEON_RING_TYPE_GFX_INDEX; - break; - case RADEON_CS_RING_COMPUTE: - if (p->rdev->family >= CHIP_TAHITI) { - if (p->priority > 0) - p->ring = CAYMAN_RING_TYPE_CP1_INDEX; - else - p->ring = CAYMAN_RING_TYPE_CP2_INDEX; - } else - p->ring = RADEON_RING_TYPE_GFX_INDEX; - break; - } - return 0; -} - -static int radeon_cs_sync_rings(struct radeon_cs_parser *p) -{ - bool sync_to_ring[RADEON_NUM_RINGS] = { }; - int i, r; - - for (i = 0; i < p->nrelocs; i++) { - if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj) - continue; - - if (!(p->relocs[i].flags & RADEON_RELOC_DONT_SYNC)) { - struct radeon_fence *fence = p->relocs[i].robj->tbo.sync_obj; - if (!radeon_fence_signaled(fence)) { - sync_to_ring[fence->ring] = true; - } - } - } - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - /* no need to sync to our own or unused rings */ - if (i == p->ring || !sync_to_ring[i] || !p->rdev->ring[i].ready) - continue; - - if (!p->ib->fence->semaphore) { - r = radeon_semaphore_create(p->rdev, &p->ib->fence->semaphore); - if (r) - return r; - } - - r = radeon_ring_lock(p->rdev, &p->rdev->ring[i], 3); - if (r) - return r; - radeon_semaphore_emit_signal(p->rdev, i, p->ib->fence->semaphore); - radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[i]); - - r = radeon_ring_lock(p->rdev, &p->rdev->ring[p->ring], 3); - if (r) - return r; - radeon_semaphore_emit_wait(p->rdev, p->ring, p->ib->fence->semaphore); - radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[p->ring]); - } - return 0; -} - -/* XXX: note that this is called from the legacy UMS CS ioctl as well */ -int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) -{ - struct drm_radeon_cs *cs = data; - uint64_t *chunk_array_ptr; - unsigned size, i; - u32 ring = RADEON_CS_RING_GFX; - s32 priority = 0; - - if (!cs->num_chunks) { - return 0; - } - /* get chunks */ - INIT_LIST_HEAD(&p->validated); - p->idx = 0; - p->chunk_ib_idx = -1; - p->chunk_relocs_idx = -1; - p->chunk_flags_idx = -1; - p->chunk_const_ib_idx = -1; - p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); - if (p->chunks_array == NULL) { - return -ENOMEM; - } - chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); - if (DRM_COPY_FROM_USER(p->chunks_array, chunk_array_ptr, - sizeof(uint64_t)*cs->num_chunks)) { - return -EFAULT; - } - p->cs_flags = 0; - p->nchunks = cs->num_chunks; - p->chunks = kcalloc(p->nchunks, sizeof(struct radeon_cs_chunk), GFP_KERNEL); - if (p->chunks == NULL) { - return -ENOMEM; - } - for (i = 0; i < p->nchunks; i++) { - struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; - struct drm_radeon_cs_chunk user_chunk; - uint32_t __user *cdata; - - chunk_ptr = (void __user*)(unsigned long)p->chunks_array[i]; - if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, - sizeof(struct drm_radeon_cs_chunk))) { - return -EFAULT; - } - p->chunks[i].length_dw = user_chunk.length_dw; - p->chunks[i].kdata = NULL; - p->chunks[i].chunk_id = user_chunk.chunk_id; - - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) { - p->chunk_relocs_idx = i; - } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_IB) { - p->chunk_ib_idx = i; - /* zero length IB isn't useful */ - if (p->chunks[i].length_dw == 0) - return -EINVAL; - } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) { - p->chunk_const_ib_idx = i; - /* zero length CONST IB isn't useful */ - if (p->chunks[i].length_dw == 0) - return -EINVAL; - } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { - p->chunk_flags_idx = i; - /* zero length flags aren't useful */ - if (p->chunks[i].length_dw == 0) - return -EINVAL; - } - - p->chunks[i].length_dw = user_chunk.length_dw; - p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; - - cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; - if ((p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) || - (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS)) { - size = p->chunks[i].length_dw * sizeof(uint32_t); - p->chunks[i].kdata = kmalloc(size, GFP_KERNEL); - if (p->chunks[i].kdata == NULL) { - return -ENOMEM; - } - if (DRM_COPY_FROM_USER(p->chunks[i].kdata, - p->chunks[i].user_ptr, size)) { - return -EFAULT; - } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { - p->cs_flags = p->chunks[i].kdata[0]; - if (p->chunks[i].length_dw > 1) - ring = p->chunks[i].kdata[1]; - if (p->chunks[i].length_dw > 2) - priority = (s32)p->chunks[i].kdata[2]; - } - } - } - - /* these are KMS only */ - if (p->rdev) { - if ((p->cs_flags & RADEON_CS_USE_VM) && - !p->rdev->vm_manager.enabled) { - DRM_ERROR("VM not active on asic!\n"); - return -EINVAL; - } - - /* we only support VM on SI+ */ - if ((p->rdev->family >= CHIP_TAHITI) && - ((p->cs_flags & RADEON_CS_USE_VM) == 0)) { - DRM_ERROR("VM required on SI+!\n"); - return -EINVAL; - } - - if (radeon_cs_get_ring(p, ring, priority)) - return -EINVAL; - } - - /* deal with non-vm */ - if ((p->chunk_ib_idx != -1) && - ((p->cs_flags & RADEON_CS_USE_VM) == 0) && - (p->chunks[p->chunk_ib_idx].chunk_id == RADEON_CHUNK_ID_IB)) { - if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) { - DRM_ERROR("cs IB too big: %d\n", - p->chunks[p->chunk_ib_idx].length_dw); - return -EINVAL; - } - p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); - p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || - p->chunks[p->chunk_ib_idx].kpage[1] == NULL) - return -ENOMEM; - p->chunks[p->chunk_ib_idx].kpage_idx[0] = -1; - p->chunks[p->chunk_ib_idx].kpage_idx[1] = -1; - p->chunks[p->chunk_ib_idx].last_copied_page = -1; - p->chunks[p->chunk_ib_idx].last_page_index = - ((p->chunks[p->chunk_ib_idx].length_dw * 4) - 1) / PAGE_SIZE; - } - - return 0; -} - -/** - * cs_parser_fini() - clean parser states - * @parser: parser structure holding parsing context. - * @error: error number - * - * If error is set than unvalidate buffer, otherwise just free memory - * used by parsing context. - **/ -static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) -{ - unsigned i; - - - if (!error && parser->ib) - ttm_eu_fence_buffer_objects(&parser->validated, - parser->ib->fence); - else - ttm_eu_backoff_reservation(&parser->validated); - - if (parser->relocs != NULL) { - for (i = 0; i < parser->nrelocs; i++) { - if (parser->relocs[i].gobj) - drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); - } - } - kfree(parser->track); - kfree(parser->relocs); - kfree(parser->relocs_ptr); - for (i = 0; i < parser->nchunks; i++) { - kfree(parser->chunks[i].kdata); - kfree(parser->chunks[i].kpage[0]); - kfree(parser->chunks[i].kpage[1]); - } - kfree(parser->chunks); - kfree(parser->chunks_array); - radeon_ib_free(parser->rdev, &parser->ib); -} - -static int radeon_cs_ib_chunk(struct radeon_device *rdev, - struct radeon_cs_parser *parser) -{ - struct radeon_cs_chunk *ib_chunk; - int r; - - if (parser->chunk_ib_idx == -1) - return 0; - - if (parser->cs_flags & RADEON_CS_USE_VM) - return 0; - - ib_chunk = &parser->chunks[parser->chunk_ib_idx]; - /* Copy the packet into the IB, the parser will read from the - * input memory (cached) and write to the IB (which can be - * uncached). - */ - r = radeon_ib_get(rdev, parser->ring, &parser->ib, - ib_chunk->length_dw * 4); - if (r) { - DRM_ERROR("Failed to get ib !\n"); - return r; - } - parser->ib->length_dw = ib_chunk->length_dw; - r = radeon_cs_parse(rdev, parser->ring, parser); - if (r || parser->parser_error) { - DRM_ERROR("Invalid command stream !\n"); - return r; - } - r = radeon_cs_finish_pages(parser); - if (r) { - DRM_ERROR("Invalid command stream !\n"); - return r; - } - r = radeon_cs_sync_rings(parser); - if (r) { - DRM_ERROR("Failed to synchronize rings !\n"); - } - parser->ib->vm_id = 0; - r = radeon_ib_schedule(rdev, parser->ib); - if (r) { - DRM_ERROR("Failed to schedule IB !\n"); - } - return 0; -} - -static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, - struct radeon_vm *vm) -{ - struct radeon_bo_list *lobj; - struct radeon_bo *bo; - int r; - - list_for_each_entry(lobj, &parser->validated, tv.head) { - bo = lobj->bo; - r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem); - if (r) { - return r; - } - } - return 0; -} - -static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, - struct radeon_cs_parser *parser) -{ - struct radeon_cs_chunk *ib_chunk; - struct radeon_fpriv *fpriv = parser->filp->driver_priv; - struct radeon_vm *vm = &fpriv->vm; - int r; - - if (parser->chunk_ib_idx == -1) - return 0; - - if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) - return 0; - - if ((rdev->family >= CHIP_TAHITI) && - (parser->chunk_const_ib_idx != -1)) { - ib_chunk = &parser->chunks[parser->chunk_const_ib_idx]; - if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { - DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); - return -EINVAL; - } - r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, - ib_chunk->length_dw * 4); - if (r) { - DRM_ERROR("Failed to get const ib !\n"); - return r; - } - parser->const_ib->is_const_ib = true; - parser->const_ib->length_dw = ib_chunk->length_dw; - /* Copy the packet into the IB */ - if (DRM_COPY_FROM_USER(parser->const_ib->ptr, ib_chunk->user_ptr, - ib_chunk->length_dw * 4)) { - return -EFAULT; - } - r = radeon_ring_ib_parse(rdev, parser->ring, parser->const_ib); - if (r) { - return r; - } - } - - ib_chunk = &parser->chunks[parser->chunk_ib_idx]; - if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { - DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); - return -EINVAL; - } - r = radeon_ib_get(rdev, parser->ring, &parser->ib, - ib_chunk->length_dw * 4); - if (r) { - DRM_ERROR("Failed to get ib !\n"); - return r; - } - parser->ib->length_dw = ib_chunk->length_dw; - /* Copy the packet into the IB */ - if (DRM_COPY_FROM_USER(parser->ib->ptr, ib_chunk->user_ptr, - ib_chunk->length_dw * 4)) { - return -EFAULT; - } - r = radeon_ring_ib_parse(rdev, parser->ring, parser->ib); - if (r) { - return r; - } - - mutex_lock(&vm->mutex); - r = radeon_vm_bind(rdev, vm); - if (r) { - goto out; - } - r = radeon_bo_vm_update_pte(parser, vm); - if (r) { - goto out; - } - r = radeon_cs_sync_rings(parser); - if (r) { - DRM_ERROR("Failed to synchronize rings !\n"); - } - - if ((rdev->family >= CHIP_TAHITI) && - (parser->chunk_const_ib_idx != -1)) { - parser->const_ib->vm_id = vm->id; - /* ib pool is bind at 0 in virtual address space to gpu_addr is the - * offset inside the pool bo - */ - parser->const_ib->gpu_addr = parser->const_ib->sa_bo.offset; - r = radeon_ib_schedule(rdev, parser->const_ib); - if (r) - goto out; - } - - parser->ib->vm_id = vm->id; - /* ib pool is bind at 0 in virtual address space to gpu_addr is the - * offset inside the pool bo - */ - parser->ib->gpu_addr = parser->ib->sa_bo.offset; - parser->ib->is_const_ib = false; - r = radeon_ib_schedule(rdev, parser->ib); -out: - if (!r) { - if (vm->fence) { - radeon_fence_unref(&vm->fence); - } - vm->fence = radeon_fence_ref(parser->ib->fence); - } - mutex_unlock(&fpriv->vm.mutex); - return r; -} - -int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_cs_parser parser; - int r; - - radeon_mutex_lock(&rdev->cs_mutex); - if (!rdev->accel_working) { - radeon_mutex_unlock(&rdev->cs_mutex); - return -EBUSY; - } - /* initialize parser */ - memset(&parser, 0, sizeof(struct radeon_cs_parser)); - parser.filp = filp; - parser.rdev = rdev; - parser.dev = rdev->dev; - parser.family = rdev->family; - r = radeon_cs_parser_init(&parser, data); - if (r) { - DRM_ERROR("Failed to initialize parser !\n"); - radeon_cs_parser_fini(&parser, r); - radeon_mutex_unlock(&rdev->cs_mutex); - return r; - } - r = radeon_cs_parser_relocs(&parser); - if (r) { - if (r != -ERESTARTSYS) - DRM_ERROR("Failed to parse relocation %d!\n", r); - radeon_cs_parser_fini(&parser, r); - radeon_mutex_unlock(&rdev->cs_mutex); - return r; - } - r = radeon_cs_ib_chunk(rdev, &parser); - if (r) { - goto out; - } - r = radeon_cs_ib_vm_chunk(rdev, &parser); - if (r) { - goto out; - } -out: - radeon_cs_parser_fini(&parser, r); - radeon_mutex_unlock(&rdev->cs_mutex); - return r; -} - -int radeon_cs_finish_pages(struct radeon_cs_parser *p) -{ - struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; - int i; - int size = PAGE_SIZE; - - for (i = ibc->last_copied_page + 1; i <= ibc->last_page_index; i++) { - if (i == ibc->last_page_index) { - size = (ibc->length_dw * 4) % PAGE_SIZE; - if (size == 0) - size = PAGE_SIZE; - } - - if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)), - ibc->user_ptr + (i * PAGE_SIZE), - size)) - return -EFAULT; - } - return 0; -} - -int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) -{ - int new_page; - struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; - int i; - int size = PAGE_SIZE; - - for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { - if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)), - ibc->user_ptr + (i * PAGE_SIZE), - PAGE_SIZE)) { - p->parser_error = -EFAULT; - return 0; - } - } - - new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1; - - if (pg_idx == ibc->last_page_index) { - size = (ibc->length_dw * 4) % PAGE_SIZE; - if (size == 0) - size = PAGE_SIZE; - } - - if (DRM_COPY_FROM_USER(ibc->kpage[new_page], - ibc->user_ptr + (pg_idx * PAGE_SIZE), - size)) { - p->parser_error = -EFAULT; - return 0; - } - - /* copy to IB here */ - memcpy((void *)(p->ib->ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size); - - ibc->last_copied_page = pg_idx; - ibc->kpage_idx[new_page] = pg_idx; - - return new_page; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cursor.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cursor.c deleted file mode 100644 index 42acc644..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_cursor.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" - -#define CURSOR_WIDTH 64 -#define CURSOR_HEIGHT 64 - -static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock) -{ - struct radeon_device *rdev = crtc->dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - uint32_t cur_lock; - - if (ASIC_IS_DCE4(rdev)) { - cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset); - if (lock) - cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK; - else - cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK; - WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); - } else if (ASIC_IS_AVIVO(rdev)) { - cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); - if (lock) - cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK; - else - cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK; - WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock); - } else { - cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset); - if (lock) - cur_lock |= RADEON_CUR_LOCK; - else - cur_lock &= ~RADEON_CUR_LOCK; - WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock); - } -} - -static void radeon_hide_cursor(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) { - WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); - WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); - } else if (ASIC_IS_AVIVO(rdev)) { - WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); - WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); - } else { - switch (radeon_crtc->crtc_id) { - case 0: - WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); - break; - case 1: - WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL); - break; - default: - return; - } - WREG32_P(RADEON_MM_DATA, 0, ~RADEON_CRTC_CUR_EN); - } -} - -static void radeon_show_cursor(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) { - WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); - WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | - EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); - } else if (ASIC_IS_AVIVO(rdev)) { - WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); - WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | - (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); - } else { - switch (radeon_crtc->crtc_id) { - case 0: - WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL); - break; - case 1: - WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL); - break; - default: - return; - } - - WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN | - (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)), - ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK)); - } -} - -static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, - uint64_t gpu_addr) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) { - WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, - upper_32_bits(gpu_addr)); - WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - gpu_addr & 0xffffffff); - } else if (ASIC_IS_AVIVO(rdev)) { - if (rdev->family >= CHIP_RV770) { - if (radeon_crtc->crtc_id) - WREG32(R700_D2CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); - else - WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, upper_32_bits(gpu_addr)); - } - WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - gpu_addr & 0xffffffff); - } else { - radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr; - /* offset is from DISP(2)_BASE_ADDRESS */ - WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset); - } -} - -int radeon_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; - struct drm_gem_object *obj; - struct radeon_bo *robj; - uint64_t gpu_addr; - int ret; - - if (!handle) { - /* turn off cursor */ - radeon_hide_cursor(crtc); - obj = NULL; - goto unpin; - } - - if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { - DRM_ERROR("bad cursor width or height %d x %d\n", width, height); - return -EINVAL; - } - - obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); - if (!obj) { - DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); - return -ENOENT; - } - - robj = gem_to_radeon_bo(obj); - ret = radeon_bo_reserve(robj, false); - if (unlikely(ret != 0)) - goto fail; - /* Only 27 bit offset for legacy cursor */ - ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, - ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, - &gpu_addr); - radeon_bo_unreserve(robj); - if (ret) - goto fail; - - radeon_crtc->cursor_width = width; - radeon_crtc->cursor_height = height; - - radeon_lock_cursor(crtc, true); - radeon_set_cursor(crtc, obj, gpu_addr); - radeon_show_cursor(crtc); - radeon_lock_cursor(crtc, false); - -unpin: - if (radeon_crtc->cursor_bo) { - robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); - ret = radeon_bo_reserve(robj, false); - if (likely(ret == 0)) { - radeon_bo_unpin(robj); - radeon_bo_unreserve(robj); - } - drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); - } - - radeon_crtc->cursor_bo = obj; - return 0; -fail: - drm_gem_object_unreference_unlocked(obj); - - return ret; -} - -int radeon_crtc_cursor_move(struct drm_crtc *crtc, - int x, int y) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_device *rdev = crtc->dev->dev_private; - int xorigin = 0, yorigin = 0; - int w = radeon_crtc->cursor_width; - - if (ASIC_IS_AVIVO(rdev)) { - /* avivo cursor are offset into the total surface */ - x += crtc->x; - y += crtc->y; - } - DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); - - if (x < 0) { - xorigin = min(-x, CURSOR_WIDTH - 1); - x = 0; - } - if (y < 0) { - yorigin = min(-y, CURSOR_HEIGHT - 1); - y = 0; - } - - if (ASIC_IS_AVIVO(rdev)) { - int i = 0; - struct drm_crtc *crtc_p; - - /* avivo cursor image can't end on 128 pixel boundary or - * go past the end of the frame if both crtcs are enabled - */ - list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) { - if (crtc_p->enabled) - i++; - } - if (i > 1) { - int cursor_end, frame_end; - - cursor_end = x - xorigin + w; - frame_end = crtc->x + crtc->mode.crtc_hdisplay; - if (cursor_end >= frame_end) { - w = w - (cursor_end - frame_end); - if (!(frame_end & 0x7f)) - w--; - } else { - if (!(cursor_end & 0x7f)) - w--; - } - if (w <= 0) - w = 1; - } - } - - radeon_lock_cursor(crtc, true); - if (ASIC_IS_DCE4(rdev)) { - WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); - WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); - WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, - ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); - } else if (ASIC_IS_AVIVO(rdev)) { - WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); - WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); - WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, - ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); - } else { - if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) - y *= 2; - - WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset, - (RADEON_CUR_LOCK - | (xorigin << 16) - | yorigin)); - WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset, - (RADEON_CUR_LOCK - | (x << 16) - | y)); - /* offset is from DISP(2)_BASE_ADDRESS */ - WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset + - (yorigin * 256))); - } - radeon_lock_cursor(crtc, false); - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_device.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_device.c deleted file mode 100644 index 5992502a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_device.c +++ /dev/null @@ -1,1081 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "radeon_reg.h" -#include "radeon.h" -#include "atom.h" - -static const char radeon_family_name[][16] = { - "R100", - "RV100", - "RS100", - "RV200", - "RS200", - "R200", - "RV250", - "RS300", - "RV280", - "R300", - "R350", - "RV350", - "RV380", - "R420", - "R423", - "RV410", - "RS400", - "RS480", - "RS600", - "RS690", - "RS740", - "RV515", - "R520", - "RV530", - "RV560", - "RV570", - "R580", - "R600", - "RV610", - "RV630", - "RV670", - "RV620", - "RV635", - "RS780", - "RS880", - "RV770", - "RV730", - "RV710", - "RV740", - "CEDAR", - "REDWOOD", - "JUNIPER", - "CYPRESS", - "HEMLOCK", - "PALM", - "SUMO", - "SUMO2", - "BARTS", - "TURKS", - "CAICOS", - "CAYMAN", - "ARUBA", - "TAHITI", - "PITCAIRN", - "VERDE", - "LAST", -}; - -/* - * Clear GPU surface registers. - */ -void radeon_surface_init(struct radeon_device *rdev) -{ - /* FIXME: check this out */ - if (rdev->family < CHIP_R600) { - int i; - - for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { - if (rdev->surface_regs[i].bo) - radeon_bo_get_surface_reg(rdev->surface_regs[i].bo); - else - radeon_clear_surface_reg(rdev, i); - } - /* enable surfaces */ - WREG32(RADEON_SURFACE_CNTL, 0); - } -} - -/* - * GPU scratch registers helpers function. - */ -void radeon_scratch_init(struct radeon_device *rdev) -{ - int i; - - /* FIXME: check this out */ - if (rdev->family < CHIP_R300) { - rdev->scratch.num_reg = 5; - } else { - rdev->scratch.num_reg = 7; - } - rdev->scratch.reg_base = RADEON_SCRATCH_REG0; - for (i = 0; i < rdev->scratch.num_reg; i++) { - rdev->scratch.free[i] = true; - rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); - } -} - -int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg) -{ - int i; - - for (i = 0; i < rdev->scratch.num_reg; i++) { - if (rdev->scratch.free[i]) { - rdev->scratch.free[i] = false; - *reg = rdev->scratch.reg[i]; - return 0; - } - } - return -EINVAL; -} - -void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg) -{ - int i; - - for (i = 0; i < rdev->scratch.num_reg; i++) { - if (rdev->scratch.reg[i] == reg) { - rdev->scratch.free[i] = true; - return; - } - } -} - -void radeon_wb_disable(struct radeon_device *rdev) -{ - int r; - - if (rdev->wb.wb_obj) { - r = radeon_bo_reserve(rdev->wb.wb_obj, false); - if (unlikely(r != 0)) - return; - radeon_bo_kunmap(rdev->wb.wb_obj); - radeon_bo_unpin(rdev->wb.wb_obj); - radeon_bo_unreserve(rdev->wb.wb_obj); - } - rdev->wb.enabled = false; -} - -void radeon_wb_fini(struct radeon_device *rdev) -{ - radeon_wb_disable(rdev); - if (rdev->wb.wb_obj) { - radeon_bo_unref(&rdev->wb.wb_obj); - rdev->wb.wb = NULL; - rdev->wb.wb_obj = NULL; - } -} - -int radeon_wb_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->wb.wb_obj == NULL) { - r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); - if (r) { - dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); - return r; - } - } - r = radeon_bo_reserve(rdev->wb.wb_obj, false); - if (unlikely(r != 0)) { - radeon_wb_fini(rdev); - return r; - } - r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, - &rdev->wb.gpu_addr); - if (r) { - radeon_bo_unreserve(rdev->wb.wb_obj); - dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); - radeon_wb_fini(rdev); - return r; - } - r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); - radeon_bo_unreserve(rdev->wb.wb_obj); - if (r) { - dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); - radeon_wb_fini(rdev); - return r; - } - - /* clear wb memory */ - memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE); - /* disable event_write fences */ - rdev->wb.use_event = false; - /* disabled via module param */ - if (radeon_no_wb == 1) - rdev->wb.enabled = false; - else { - if (rdev->flags & RADEON_IS_AGP) { - /* often unreliable on AGP */ - rdev->wb.enabled = false; - } else if (rdev->family < CHIP_R300) { - /* often unreliable on pre-r300 */ - rdev->wb.enabled = false; - } else { - rdev->wb.enabled = true; - /* event_write fences are only available on r600+ */ - if (rdev->family >= CHIP_R600) - rdev->wb.use_event = true; - } - } - /* always use writeback/events on NI, APUs */ - if (rdev->family >= CHIP_PALM) { - rdev->wb.enabled = true; - rdev->wb.use_event = true; - } - - dev_info(rdev->dev, "WB %sabled\n", rdev->wb.enabled ? "en" : "dis"); - - return 0; -} - -/** - * radeon_vram_location - try to find VRAM location - * @rdev: radeon device structure holding all necessary informations - * @mc: memory controller structure holding memory informations - * @base: base address at which to put VRAM - * - * Function will place try to place VRAM at base address provided - * as parameter (which is so far either PCI aperture address or - * for IGP TOM base address). - * - * If there is not enough space to fit the unvisible VRAM in the 32bits - * address space then we limit the VRAM size to the aperture. - * - * If we are using AGP and if the AGP aperture doesn't allow us to have - * room for all the VRAM than we restrict the VRAM to the PCI aperture - * size and print a warning. - * - * This function will never fails, worst case are limiting VRAM. - * - * Note: GTT start, end, size should be initialized before calling this - * function on AGP platform. - * - * Note: We don't explicitly enforce VRAM start to be aligned on VRAM size, - * this shouldn't be a problem as we are using the PCI aperture as a reference. - * Otherwise this would be needed for rv280, all r3xx, and all r4xx, but - * not IGP. - * - * Note: we use mc_vram_size as on some board we need to program the mc to - * cover the whole aperture even if VRAM size is inferior to aperture size - * Novell bug 204882 + along with lots of ubuntu ones - * - * Note: when limiting vram it's safe to overwritte real_vram_size because - * we are not in case where real_vram_size is inferior to mc_vram_size (ie - * note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu - * ones) - * - * Note: IGP TOM addr should be the same as the aperture addr, we don't - * explicitly check for that thought. - * - * FIXME: when reducing VRAM size align new size on power of 2. - */ -void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) -{ - mc->vram_start = base; - if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { - dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); - mc->real_vram_size = mc->aper_size; - mc->mc_vram_size = mc->aper_size; - } - mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { - dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); - mc->real_vram_size = mc->aper_size; - mc->mc_vram_size = mc->aper_size; - } - mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) - mc->real_vram_size = radeon_vram_limit; - dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", - mc->mc_vram_size >> 20, mc->vram_start, - mc->vram_end, mc->real_vram_size >> 20); -} - -/** - * radeon_gtt_location - try to find GTT location - * @rdev: radeon device structure holding all necessary informations - * @mc: memory controller structure holding memory informations - * - * Function will place try to place GTT before or after VRAM. - * - * If GTT size is bigger than space left then we ajust GTT size. - * Thus function will never fails. - * - * FIXME: when reducing GTT size align new size on power of 2. - */ -void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) -{ - u64 size_af, size_bf; - - size_af = ((0xFFFFFFFF - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align; - size_bf = mc->vram_start & ~mc->gtt_base_align; - if (size_bf > size_af) { - if (mc->gtt_size > size_bf) { - dev_warn(rdev->dev, "limiting GTT\n"); - mc->gtt_size = size_bf; - } - mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size; - } else { - if (mc->gtt_size > size_af) { - dev_warn(rdev->dev, "limiting GTT\n"); - mc->gtt_size = size_af; - } - mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; - } - mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; - dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", - mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); -} - -/* - * GPU helpers function. - */ -bool radeon_card_posted(struct radeon_device *rdev) -{ - uint32_t reg; - - if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) - return false; - - /* first check CRTCs */ - if (ASIC_IS_DCE41(rdev)) { - reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); - if (reg & EVERGREEN_CRTC_MASTER_EN) - return true; - } else if (ASIC_IS_DCE4(rdev)) { - reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); - if (reg & EVERGREEN_CRTC_MASTER_EN) - return true; - } else if (ASIC_IS_AVIVO(rdev)) { - reg = RREG32(AVIVO_D1CRTC_CONTROL) | - RREG32(AVIVO_D2CRTC_CONTROL); - if (reg & AVIVO_CRTC_EN) { - return true; - } - } else { - reg = RREG32(RADEON_CRTC_GEN_CNTL) | - RREG32(RADEON_CRTC2_GEN_CNTL); - if (reg & RADEON_CRTC_EN) { - return true; - } - } - - /* then check MEM_SIZE, in case the crtcs are off */ - if (rdev->family >= CHIP_R600) - reg = RREG32(R600_CONFIG_MEMSIZE); - else - reg = RREG32(RADEON_CONFIG_MEMSIZE); - - if (reg) - return true; - - return false; - -} - -void radeon_update_bandwidth_info(struct radeon_device *rdev) -{ - fixed20_12 a; - u32 sclk = rdev->pm.current_sclk; - u32 mclk = rdev->pm.current_mclk; - - /* sclk/mclk in Mhz */ - a.full = dfixed_const(100); - rdev->pm.sclk.full = dfixed_const(sclk); - rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); - rdev->pm.mclk.full = dfixed_const(mclk); - rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); - - if (rdev->flags & RADEON_IS_IGP) { - a.full = dfixed_const(16); - /* core_bandwidth = sclk(Mhz) * 16 */ - rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); - } -} - -bool radeon_boot_test_post_card(struct radeon_device *rdev) -{ - if (radeon_card_posted(rdev)) - return true; - - if (rdev->bios) { - DRM_INFO("GPU not posted. posting now...\n"); - if (rdev->is_atom_bios) - atom_asic_init(rdev->mode_info.atom_context); - else - radeon_combios_asic_init(rdev->ddev); - return true; - } else { - dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); - return false; - } -} - -int radeon_dummy_page_init(struct radeon_device *rdev) -{ - if (rdev->dummy_page.page) - return 0; - rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); - if (rdev->dummy_page.page == NULL) - return -ENOMEM; - rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page, - 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(rdev->pdev, rdev->dummy_page.addr)) { - dev_err(&rdev->pdev->dev, "Failed to DMA MAP the dummy page\n"); - __free_page(rdev->dummy_page.page); - rdev->dummy_page.page = NULL; - return -ENOMEM; - } - return 0; -} - -void radeon_dummy_page_fini(struct radeon_device *rdev) -{ - if (rdev->dummy_page.page == NULL) - return; - pci_unmap_page(rdev->pdev, rdev->dummy_page.addr, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - __free_page(rdev->dummy_page.page); - rdev->dummy_page.page = NULL; -} - - -/* ATOM accessor methods */ -static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) -{ - struct radeon_device *rdev = info->dev->dev_private; - uint32_t r; - - r = rdev->pll_rreg(rdev, reg); - return r; -} - -static void cail_pll_write(struct card_info *info, uint32_t reg, uint32_t val) -{ - struct radeon_device *rdev = info->dev->dev_private; - - rdev->pll_wreg(rdev, reg, val); -} - -static uint32_t cail_mc_read(struct card_info *info, uint32_t reg) -{ - struct radeon_device *rdev = info->dev->dev_private; - uint32_t r; - - r = rdev->mc_rreg(rdev, reg); - return r; -} - -static void cail_mc_write(struct card_info *info, uint32_t reg, uint32_t val) -{ - struct radeon_device *rdev = info->dev->dev_private; - - rdev->mc_wreg(rdev, reg, val); -} - -static void cail_reg_write(struct card_info *info, uint32_t reg, uint32_t val) -{ - struct radeon_device *rdev = info->dev->dev_private; - - WREG32(reg*4, val); -} - -static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) -{ - struct radeon_device *rdev = info->dev->dev_private; - uint32_t r; - - r = RREG32(reg*4); - return r; -} - -static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) -{ - struct radeon_device *rdev = info->dev->dev_private; - - WREG32_IO(reg*4, val); -} - -static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) -{ - struct radeon_device *rdev = info->dev->dev_private; - uint32_t r; - - r = RREG32_IO(reg*4); - return r; -} - -int radeon_atombios_init(struct radeon_device *rdev) -{ - struct card_info *atom_card_info = - kzalloc(sizeof(struct card_info), GFP_KERNEL); - - if (!atom_card_info) - return -ENOMEM; - - rdev->mode_info.atom_card_info = atom_card_info; - atom_card_info->dev = rdev->ddev; - atom_card_info->reg_read = cail_reg_read; - atom_card_info->reg_write = cail_reg_write; - /* needed for iio ops */ - if (rdev->rio_mem) { - atom_card_info->ioreg_read = cail_ioreg_read; - atom_card_info->ioreg_write = cail_ioreg_write; - } else { - DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n"); - atom_card_info->ioreg_read = cail_reg_read; - atom_card_info->ioreg_write = cail_reg_write; - } - atom_card_info->mc_read = cail_mc_read; - atom_card_info->mc_write = cail_mc_write; - atom_card_info->pll_read = cail_pll_read; - atom_card_info->pll_write = cail_pll_write; - - rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); - mutex_init(&rdev->mode_info.atom_context->mutex); - radeon_atom_initialize_bios_scratch_regs(rdev->ddev); - atom_allocate_fb_scratch(rdev->mode_info.atom_context); - return 0; -} - -void radeon_atombios_fini(struct radeon_device *rdev) -{ - if (rdev->mode_info.atom_context) { - kfree(rdev->mode_info.atom_context->scratch); - kfree(rdev->mode_info.atom_context); - } - kfree(rdev->mode_info.atom_card_info); -} - -int radeon_combios_init(struct radeon_device *rdev) -{ - radeon_combios_initialize_bios_scratch_regs(rdev->ddev); - return 0; -} - -void radeon_combios_fini(struct radeon_device *rdev) -{ -} - -/* if we get transitioned to only one device, tak VGA back */ -static unsigned int radeon_vga_set_decode(void *cookie, bool state) -{ - struct radeon_device *rdev = cookie; - radeon_vga_set_state(rdev, state); - if (state) - return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | - VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; - else - return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; -} - -void radeon_check_arguments(struct radeon_device *rdev) -{ - /* vramlimit must be a power of two */ - switch (radeon_vram_limit) { - case 0: - case 4: - case 8: - case 16: - case 32: - case 64: - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - break; - default: - dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", - radeon_vram_limit); - radeon_vram_limit = 0; - break; - } - radeon_vram_limit = radeon_vram_limit << 20; - /* gtt size must be power of two and greater or equal to 32M */ - switch (radeon_gart_size) { - case 4: - case 8: - case 16: - dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", - radeon_gart_size); - radeon_gart_size = 512; - break; - case 32: - case 64: - case 128: - case 256: - case 512: - case 1024: - case 2048: - case 4096: - break; - default: - dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", - radeon_gart_size); - radeon_gart_size = 512; - break; - } - rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; - /* AGP mode can only be -1, 1, 2, 4, 8 */ - switch (radeon_agpmode) { - case -1: - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: - dev_warn(rdev->dev, "invalid AGP mode %d (valid mode: " - "-1, 0, 1, 2, 4, 8)\n", radeon_agpmode); - radeon_agpmode = 0; - break; - } -} - -static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; - if (state == VGA_SWITCHEROO_ON) { - printk(KERN_INFO "radeon: switched on\n"); - /* don't suspend or resume card normally */ - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - radeon_resume_kms(dev); - dev->switch_power_state = DRM_SWITCH_POWER_ON; - drm_kms_helper_poll_enable(dev); - } else { - printk(KERN_INFO "radeon: switched off\n"); - drm_kms_helper_poll_disable(dev); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - radeon_suspend_kms(dev, pmm); - dev->switch_power_state = DRM_SWITCH_POWER_OFF; - } -} - -static bool radeon_switcheroo_can_switch(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - bool can_switch; - - spin_lock(&dev->count_lock); - can_switch = (dev->open_count == 0); - spin_unlock(&dev->count_lock); - return can_switch; -} - - -int radeon_device_init(struct radeon_device *rdev, - struct drm_device *ddev, - struct pci_dev *pdev, - uint32_t flags) -{ - int r, i; - int dma_bits; - - rdev->shutdown = false; - rdev->dev = &pdev->dev; - rdev->ddev = ddev; - rdev->pdev = pdev; - rdev->flags = flags; - rdev->family = flags & RADEON_FAMILY_MASK; - rdev->is_atom_bios = false; - rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; - rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; - rdev->gpu_lockup = false; - rdev->accel_working = false; - - DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", - radeon_family_name[rdev->family], pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); - - /* mutex initialization are all done here so we - * can recall function without having locking issues */ - radeon_mutex_init(&rdev->cs_mutex); - radeon_mutex_init(&rdev->ib_pool.mutex); - for (i = 0; i < RADEON_NUM_RINGS; ++i) - mutex_init(&rdev->ring[i].mutex); - mutex_init(&rdev->dc_hw_i2c_mutex); - if (rdev->family >= CHIP_R600) - spin_lock_init(&rdev->ih.lock); - mutex_init(&rdev->gem.mutex); - mutex_init(&rdev->pm.mutex); - mutex_init(&rdev->vram_mutex); - rwlock_init(&rdev->fence_lock); - rwlock_init(&rdev->semaphore_drv.lock); - INIT_LIST_HEAD(&rdev->gem.objects); - init_waitqueue_head(&rdev->irq.vblank_queue); - init_waitqueue_head(&rdev->irq.idle_queue); - INIT_LIST_HEAD(&rdev->semaphore_drv.bo); - /* initialize vm here */ - rdev->vm_manager.use_bitmap = 1; - rdev->vm_manager.max_pfn = 1 << 20; - INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); - - /* Set asic functions */ - r = radeon_asic_init(rdev); - if (r) - return r; - radeon_check_arguments(rdev); - - /* all of the newer IGP chips have an internal gart - * However some rs4xx report as AGP, so remove that here. - */ - if ((rdev->family >= CHIP_RS400) && - (rdev->flags & RADEON_IS_IGP)) { - rdev->flags &= ~RADEON_IS_AGP; - } - - if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { - radeon_agp_disable(rdev); - } - - /* set DMA mask + need_dma32 flags. - * PCIE - can handle 40-bits. - * IGP - can handle 40-bits - * AGP - generally dma32 is safest - * PCI - dma32 for legacy pci gart, 40 bits on newer asics - */ - rdev->need_dma32 = false; - if (rdev->flags & RADEON_IS_AGP) - rdev->need_dma32 = true; - if ((rdev->flags & RADEON_IS_PCI) && - (rdev->family < CHIP_RS400)) - rdev->need_dma32 = true; - - dma_bits = rdev->need_dma32 ? 32 : 40; - r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); - if (r) { - rdev->need_dma32 = true; - dma_bits = 32; - printk(KERN_WARNING "radeon: No suitable DMA available.\n"); - } - r = pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits)); - if (r) { - pci_set_consistent_dma_mask(rdev->pdev, DMA_BIT_MASK(32)); - printk(KERN_WARNING "radeon: No coherent DMA available.\n"); - } - - /* Registers mapping */ - /* TODO: block userspace mapping of io register */ - rdev->rmmio_base = pci_resource_start(rdev->pdev, 2); - rdev->rmmio_size = pci_resource_len(rdev->pdev, 2); - rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size); - if (rdev->rmmio == NULL) { - return -ENOMEM; - } - DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); - DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); - - /* io port mapping */ - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) { - rdev->rio_mem_size = pci_resource_len(rdev->pdev, i); - rdev->rio_mem = pci_iomap(rdev->pdev, i, rdev->rio_mem_size); - break; - } - } - if (rdev->rio_mem == NULL) - DRM_ERROR("Unable to find PCI I/O BAR\n"); - - /* if we have > 1 VGA cards, then disable the radeon VGA resources */ - /* this will fail for cards that aren't VGA class devices, just - * ignore it */ - vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); - vga_switcheroo_register_client(rdev->pdev, - radeon_switcheroo_set_state, - NULL, - radeon_switcheroo_can_switch); - - r = radeon_init(rdev); - if (r) - return r; - - if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { - /* Acceleration not working on AGP card try again - * with fallback to PCI or PCIE GART - */ - radeon_asic_reset(rdev); - radeon_fini(rdev); - radeon_agp_disable(rdev); - r = radeon_init(rdev); - if (r) - return r; - } - if ((radeon_testing & 1)) { - radeon_test_moves(rdev); - } - if ((radeon_testing & 2)) { - radeon_test_syncing(rdev); - } - if (radeon_benchmarking) { - radeon_benchmark(rdev, radeon_benchmarking); - } - return 0; -} - -static void radeon_debugfs_remove_files(struct radeon_device *rdev); - -void radeon_device_fini(struct radeon_device *rdev) -{ - DRM_INFO("radeon: finishing device.\n"); - rdev->shutdown = true; - /* evict vram memory */ - radeon_bo_evict_vram(rdev); - radeon_fini(rdev); - vga_switcheroo_unregister_client(rdev->pdev); - vga_client_register(rdev->pdev, NULL, NULL, NULL); - if (rdev->rio_mem) - pci_iounmap(rdev->pdev, rdev->rio_mem); - rdev->rio_mem = NULL; - iounmap(rdev->rmmio); - rdev->rmmio = NULL; - radeon_debugfs_remove_files(rdev); -} - - -/* - * Suspend & resume. - */ -int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) -{ - struct radeon_device *rdev; - struct drm_crtc *crtc; - struct drm_connector *connector; - int i, r; - - if (dev == NULL || dev->dev_private == NULL) { - return -ENODEV; - } - if (state.event == PM_EVENT_PRETHAW) { - return 0; - } - rdev = dev->dev_private; - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - drm_kms_helper_poll_disable(dev); - - /* turn off display hw */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); - } - - /* unpin the front buffers */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); - struct radeon_bo *robj; - - if (rfb == NULL || rfb->obj == NULL) { - continue; - } - robj = gem_to_radeon_bo(rfb->obj); - /* don't unpin kernel fb objects */ - if (!radeon_fbdev_robj_is_fb(rdev, robj)) { - r = radeon_bo_reserve(robj, false); - if (r == 0) { - radeon_bo_unpin(robj); - radeon_bo_unreserve(robj); - } - } - } - /* evict vram memory */ - radeon_bo_evict_vram(rdev); - /* wait for gpu to finish processing current batch */ - for (i = 0; i < RADEON_NUM_RINGS; i++) - radeon_fence_wait_last(rdev, i); - - radeon_save_bios_scratch_regs(rdev); - - radeon_pm_suspend(rdev); - radeon_suspend(rdev); - radeon_hpd_fini(rdev); - /* evict remaining vram memory */ - radeon_bo_evict_vram(rdev); - - radeon_agp_suspend(rdev); - - pci_save_state(dev->pdev); - if (state.event == PM_EVENT_SUSPEND) { - /* Shut down the device */ - pci_disable_device(dev->pdev); - pci_set_power_state(dev->pdev, PCI_D3hot); - } - console_lock(); - radeon_fbdev_set_suspend(rdev, 1); - console_unlock(); - return 0; -} - -int radeon_resume_kms(struct drm_device *dev) -{ - struct drm_connector *connector; - struct radeon_device *rdev = dev->dev_private; - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - console_lock(); - pci_set_power_state(dev->pdev, PCI_D0); - pci_restore_state(dev->pdev); - if (pci_enable_device(dev->pdev)) { - console_unlock(); - return -1; - } - pci_set_master(dev->pdev); - /* resume AGP if in use */ - radeon_agp_resume(rdev); - radeon_resume(rdev); - radeon_pm_resume(rdev); - radeon_restore_bios_scratch_regs(rdev); - - radeon_fbdev_set_suspend(rdev, 0); - console_unlock(); - - /* init dig PHYs, disp eng pll */ - if (rdev->is_atom_bios) { - radeon_atom_encoder_init(rdev); - radeon_atom_disp_eng_pll_init(rdev); - } - /* reset hpd state */ - radeon_hpd_init(rdev); - /* blat the mode back in */ - drm_helper_resume_force_mode(dev); - /* turn on display hw */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - } - - drm_kms_helper_poll_enable(dev); - return 0; -} - -int radeon_gpu_reset(struct radeon_device *rdev) -{ - int r; - int resched; - - /* Prevent CS ioctl from interfering */ - radeon_mutex_lock(&rdev->cs_mutex); - - radeon_save_bios_scratch_regs(rdev); - /* block TTM */ - resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); - radeon_suspend(rdev); - - r = radeon_asic_reset(rdev); - if (!r) { - dev_info(rdev->dev, "GPU reset succeed\n"); - radeon_resume(rdev); - radeon_restore_bios_scratch_regs(rdev); - drm_helper_resume_force_mode(rdev->ddev); - ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); - } - - radeon_mutex_unlock(&rdev->cs_mutex); - - if (r) { - /* bad news, how to tell it to userspace ? */ - dev_info(rdev->dev, "GPU reset failed\n"); - } - - return r; -} - - -/* - * Debugfs - */ -int radeon_debugfs_add_files(struct radeon_device *rdev, - struct drm_info_list *files, - unsigned nfiles) -{ - unsigned i; - - for (i = 0; i < rdev->debugfs_count; i++) { - if (rdev->debugfs[i].files == files) { - /* Already registered */ - return 0; - } - } - - i = rdev->debugfs_count + 1; - if (i > RADEON_DEBUGFS_MAX_COMPONENTS) { - DRM_ERROR("Reached maximum number of debugfs components.\n"); - DRM_ERROR("Report so we increase " - "RADEON_DEBUGFS_MAX_COMPONENTS.\n"); - return -EINVAL; - } - rdev->debugfs[rdev->debugfs_count].files = files; - rdev->debugfs[rdev->debugfs_count].num_files = nfiles; - rdev->debugfs_count = i; -#if defined(CONFIG_DEBUG_FS) - drm_debugfs_create_files(files, nfiles, - rdev->ddev->control->debugfs_root, - rdev->ddev->control); - drm_debugfs_create_files(files, nfiles, - rdev->ddev->primary->debugfs_root, - rdev->ddev->primary); -#endif - return 0; -} - -static void radeon_debugfs_remove_files(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - unsigned i; - - for (i = 0; i < rdev->debugfs_count; i++) { - drm_debugfs_remove_files(rdev->debugfs[i].files, - rdev->debugfs[i].num_files, - rdev->ddev->control); - drm_debugfs_remove_files(rdev->debugfs[i].files, - rdev->debugfs[i].num_files, - rdev->ddev->primary); - } -#endif -} - -#if defined(CONFIG_DEBUG_FS) -int radeon_debugfs_init(struct drm_minor *minor) -{ - return 0; -} - -void radeon_debugfs_cleanup(struct drm_minor *minor) -{ -} -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_display.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_display.c deleted file mode 100644 index 0a1d4bd6..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_display.c +++ /dev/null @@ -1,1589 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" - -#include "atom.h" -#include - -#include "drm_crtc_helper.h" -#include "drm_edid.h" - -static void avivo_crtc_load_lut(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int i; - - DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); - WREG32(AVIVO_DC_LUTA_CONTROL + radeon_crtc->crtc_offset, 0); - - WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); - WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); - WREG32(AVIVO_DC_LUTA_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); - - WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); - WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); - WREG32(AVIVO_DC_LUTA_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); - - WREG32(AVIVO_DC_LUT_RW_SELECT, radeon_crtc->crtc_id); - WREG32(AVIVO_DC_LUT_RW_MODE, 0); - WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f); - - WREG8(AVIVO_DC_LUT_RW_INDEX, 0); - for (i = 0; i < 256; i++) { - WREG32(AVIVO_DC_LUT_30_COLOR, - (radeon_crtc->lut_r[i] << 20) | - (radeon_crtc->lut_g[i] << 10) | - (radeon_crtc->lut_b[i] << 0)); - } - - WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); -} - -static void dce4_crtc_load_lut(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int i; - - DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); - WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); - - WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); - - WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); - WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); - WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); - - WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); - - WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); - for (i = 0; i < 256; i++) { - WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, - (radeon_crtc->lut_r[i] << 20) | - (radeon_crtc->lut_g[i] << 10) | - (radeon_crtc->lut_b[i] << 0)); - } -} - -static void dce5_crtc_load_lut(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int i; - - DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); - - WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset, - (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) | - NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); - WREG32(NI_PRESCALE_GRPH_CONTROL + radeon_crtc->crtc_offset, - NI_GRPH_PRESCALE_BYPASS); - WREG32(NI_PRESCALE_OVL_CONTROL + radeon_crtc->crtc_offset, - NI_OVL_PRESCALE_BYPASS); - WREG32(NI_INPUT_GAMMA_CONTROL + radeon_crtc->crtc_offset, - (NI_GRPH_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT) | - NI_OVL_INPUT_GAMMA_MODE(NI_INPUT_GAMMA_USE_LUT))); - - WREG32(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0); - - WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_BLUE + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_GREEN + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_DC_LUT_BLACK_OFFSET_RED + radeon_crtc->crtc_offset, 0); - - WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_BLUE + radeon_crtc->crtc_offset, 0xffff); - WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); - WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); - - WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); - WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); - - WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0); - for (i = 0; i < 256; i++) { - WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset, - (radeon_crtc->lut_r[i] << 20) | - (radeon_crtc->lut_g[i] << 10) | - (radeon_crtc->lut_b[i] << 0)); - } - - WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset, - (NI_GRPH_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | - NI_OVL_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | - NI_ICON_DEGAMMA_MODE(NI_DEGAMMA_BYPASS) | - NI_CURSOR_DEGAMMA_MODE(NI_DEGAMMA_BYPASS))); - WREG32(NI_GAMUT_REMAP_CONTROL + radeon_crtc->crtc_offset, - (NI_GRPH_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS) | - NI_OVL_GAMUT_REMAP_MODE(NI_GAMUT_REMAP_BYPASS))); - WREG32(NI_REGAMMA_CONTROL + radeon_crtc->crtc_offset, - (NI_GRPH_REGAMMA_MODE(NI_REGAMMA_BYPASS) | - NI_OVL_REGAMMA_MODE(NI_REGAMMA_BYPASS))); - WREG32(NI_OUTPUT_CSC_CONTROL + radeon_crtc->crtc_offset, - (NI_OUTPUT_CSC_GRPH_MODE(NI_OUTPUT_CSC_BYPASS) | - NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS))); - /* XXX match this to the depth of the crtc fmt block, move to modeset? */ - WREG32(0x6940 + radeon_crtc->crtc_offset, 0); - -} - -static void legacy_crtc_load_lut(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - int i; - uint32_t dac2_cntl; - - dac2_cntl = RREG32(RADEON_DAC_CNTL2); - if (radeon_crtc->crtc_id == 0) - dac2_cntl &= (uint32_t)~RADEON_DAC2_PALETTE_ACC_CTL; - else - dac2_cntl |= RADEON_DAC2_PALETTE_ACC_CTL; - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - - WREG8(RADEON_PALETTE_INDEX, 0); - for (i = 0; i < 256; i++) { - WREG32(RADEON_PALETTE_30_DATA, - (radeon_crtc->lut_r[i] << 20) | - (radeon_crtc->lut_g[i] << 10) | - (radeon_crtc->lut_b[i] << 0)); - } -} - -void radeon_crtc_load_lut(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - - if (!crtc->enabled) - return; - - if (ASIC_IS_DCE5(rdev)) - dce5_crtc_load_lut(crtc); - else if (ASIC_IS_DCE4(rdev)) - dce4_crtc_load_lut(crtc); - else if (ASIC_IS_AVIVO(rdev)) - avivo_crtc_load_lut(crtc); - else - legacy_crtc_load_lut(crtc); -} - -/** Sets the color ramps on behalf of fbcon */ -void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - radeon_crtc->lut_r[regno] = red >> 6; - radeon_crtc->lut_g[regno] = green >> 6; - radeon_crtc->lut_b[regno] = blue >> 6; -} - -/** Gets the color ramps on behalf of fbcon */ -void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - *red = radeon_crtc->lut_r[regno] << 6; - *green = radeon_crtc->lut_g[regno] << 6; - *blue = radeon_crtc->lut_b[regno] << 6; -} - -static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, uint32_t start, uint32_t size) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - int end = (start + size > 256) ? 256 : start + size, i; - - /* userspace palettes are always correct as is */ - for (i = start; i < end; i++) { - radeon_crtc->lut_r[i] = red[i] >> 6; - radeon_crtc->lut_g[i] = green[i] >> 6; - radeon_crtc->lut_b[i] = blue[i] >> 6; - } - radeon_crtc_load_lut(crtc); -} - -static void radeon_crtc_destroy(struct drm_crtc *crtc) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - drm_crtc_cleanup(crtc); - kfree(radeon_crtc); -} - -/* - * Handle unpin events outside the interrupt handler proper. - */ -static void radeon_unpin_work_func(struct work_struct *__work) -{ - struct radeon_unpin_work *work = - container_of(__work, struct radeon_unpin_work, work); - int r; - - /* unpin of the old buffer */ - r = radeon_bo_reserve(work->old_rbo, false); - if (likely(r == 0)) { - r = radeon_bo_unpin(work->old_rbo); - if (unlikely(r != 0)) { - DRM_ERROR("failed to unpin buffer after flip\n"); - } - radeon_bo_unreserve(work->old_rbo); - } else - DRM_ERROR("failed to reserve buffer after flip\n"); - - drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); - kfree(work); -} - -void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; - struct radeon_unpin_work *work; - struct drm_pending_vblank_event *e; - struct timeval now; - unsigned long flags; - u32 update_pending; - int vpos, hpos; - - spin_lock_irqsave(&rdev->ddev->event_lock, flags); - work = radeon_crtc->unpin_work; - if (work == NULL || - (work->fence && !radeon_fence_signaled(work->fence))) { - spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); - return; - } - /* New pageflip, or just completion of a previous one? */ - if (!radeon_crtc->deferred_flip_completion) { - /* do the flip (mmio) */ - update_pending = radeon_page_flip(rdev, crtc_id, work->new_crtc_base); - } else { - /* This is just a completion of a flip queued in crtc - * at last invocation. Make sure we go directly to - * completion routine. - */ - update_pending = 0; - radeon_crtc->deferred_flip_completion = 0; - } - - /* Has the pageflip already completed in crtc, or is it certain - * to complete in this vblank? - */ - if (update_pending && - (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, - &vpos, &hpos)) && - ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || - (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { - /* crtc didn't flip in this target vblank interval, - * but flip is pending in crtc. Based on the current - * scanout position we know that the current frame is - * (nearly) complete and the flip will (likely) - * complete before the start of the next frame. - */ - update_pending = 0; - } - if (update_pending) { - /* crtc didn't flip in this target vblank interval, - * but flip is pending in crtc. It will complete it - * in next vblank interval, so complete the flip at - * next vblank irq. - */ - radeon_crtc->deferred_flip_completion = 1; - spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); - return; - } - - /* Pageflip (will be) certainly completed in this vblank. Clean up. */ - radeon_crtc->unpin_work = NULL; - - /* wakeup userspace */ - if (work->event) { - e = work->event; - e->event.sequence = drm_vblank_count_and_time(rdev->ddev, crtc_id, &now); - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; - list_add_tail(&e->base.link, &e->base.file_priv->event_list); - wake_up_interruptible(&e->base.file_priv->event_wait); - } - spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); - - drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id); - radeon_fence_unref(&work->fence); - radeon_post_page_flip(work->rdev, work->crtc_id); - schedule_work(&work->work); -} - -static int radeon_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_framebuffer *old_radeon_fb; - struct radeon_framebuffer *new_radeon_fb; - struct drm_gem_object *obj; - struct radeon_bo *rbo; - struct radeon_unpin_work *work; - unsigned long flags; - u32 tiling_flags, pitch_pixels; - u64 base; - int r; - - work = kzalloc(sizeof *work, GFP_KERNEL); - if (work == NULL) - return -ENOMEM; - - work->event = event; - work->rdev = rdev; - work->crtc_id = radeon_crtc->crtc_id; - old_radeon_fb = to_radeon_framebuffer(crtc->fb); - new_radeon_fb = to_radeon_framebuffer(fb); - /* schedule unpin of the old buffer */ - obj = old_radeon_fb->obj; - /* take a reference to the old object */ - drm_gem_object_reference(obj); - rbo = gem_to_radeon_bo(obj); - work->old_rbo = rbo; - obj = new_radeon_fb->obj; - rbo = gem_to_radeon_bo(obj); - if (rbo->tbo.sync_obj) - work->fence = radeon_fence_ref(rbo->tbo.sync_obj); - INIT_WORK(&work->work, radeon_unpin_work_func); - - /* We borrow the event spin lock for protecting unpin_work */ - spin_lock_irqsave(&dev->event_lock, flags); - if (radeon_crtc->unpin_work) { - DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); - r = -EBUSY; - goto unlock_free; - } - radeon_crtc->unpin_work = work; - radeon_crtc->deferred_flip_completion = 0; - spin_unlock_irqrestore(&dev->event_lock, flags); - - /* pin the new buffer */ - DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n", - work->old_rbo, rbo); - - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) { - DRM_ERROR("failed to reserve new rbo buffer before flip\n"); - goto pflip_cleanup; - } - /* Only 27 bit offset for legacy CRTC */ - r = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM, - ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base); - if (unlikely(r != 0)) { - radeon_bo_unreserve(rbo); - r = -EINVAL; - DRM_ERROR("failed to pin new rbo buffer before flip\n"); - goto pflip_cleanup; - } - radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); - radeon_bo_unreserve(rbo); - - if (!ASIC_IS_AVIVO(rdev)) { - /* crtc offset is from display base addr not FB location */ - base -= radeon_crtc->legacy_display_base_addr; - pitch_pixels = fb->pitches[0] / (fb->bits_per_pixel / 8); - - if (tiling_flags & RADEON_TILING_MACRO) { - if (ASIC_IS_R300(rdev)) { - base &= ~0x7ff; - } else { - int byteshift = fb->bits_per_pixel >> 4; - int tile_addr = (((crtc->y >> 3) * pitch_pixels + crtc->x) >> (8 - byteshift)) << 11; - base += tile_addr + ((crtc->x << byteshift) % 256) + ((crtc->y % 8) << 8); - } - } else { - int offset = crtc->y * pitch_pixels + crtc->x; - switch (fb->bits_per_pixel) { - case 8: - default: - offset *= 1; - break; - case 15: - case 16: - offset *= 2; - break; - case 24: - offset *= 3; - break; - case 32: - offset *= 4; - break; - } - base += offset; - } - base &= ~7; - } - - spin_lock_irqsave(&dev->event_lock, flags); - work->new_crtc_base = base; - spin_unlock_irqrestore(&dev->event_lock, flags); - - /* update crtc fb */ - crtc->fb = fb; - - r = drm_vblank_get(dev, radeon_crtc->crtc_id); - if (r) { - DRM_ERROR("failed to get vblank before flip\n"); - goto pflip_cleanup1; - } - - /* set the proper interrupt */ - radeon_pre_page_flip(rdev, radeon_crtc->crtc_id); - - return 0; - -pflip_cleanup1: - if (unlikely(radeon_bo_reserve(rbo, false) != 0)) { - DRM_ERROR("failed to reserve new rbo in error path\n"); - goto pflip_cleanup; - } - if (unlikely(radeon_bo_unpin(rbo) != 0)) { - DRM_ERROR("failed to unpin new rbo in error path\n"); - } - radeon_bo_unreserve(rbo); - -pflip_cleanup: - spin_lock_irqsave(&dev->event_lock, flags); - radeon_crtc->unpin_work = NULL; -unlock_free: - spin_unlock_irqrestore(&dev->event_lock, flags); - drm_gem_object_unreference_unlocked(old_radeon_fb->obj); - radeon_fence_unref(&work->fence); - kfree(work); - - return r; -} - -static const struct drm_crtc_funcs radeon_crtc_funcs = { - .cursor_set = radeon_crtc_cursor_set, - .cursor_move = radeon_crtc_cursor_move, - .gamma_set = radeon_crtc_gamma_set, - .set_config = drm_crtc_helper_set_config, - .destroy = radeon_crtc_destroy, - .page_flip = radeon_crtc_page_flip, -}; - -static void radeon_crtc_init(struct drm_device *dev, int index) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc; - int i; - - radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); - if (radeon_crtc == NULL) - return; - - drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); - - drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); - radeon_crtc->crtc_id = index; - rdev->mode_info.crtcs[index] = radeon_crtc; - -#if 0 - radeon_crtc->mode_set.crtc = &radeon_crtc->base; - radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); - radeon_crtc->mode_set.num_connectors = 0; -#endif - - for (i = 0; i < 256; i++) { - radeon_crtc->lut_r[i] = i << 2; - radeon_crtc->lut_g[i] = i << 2; - radeon_crtc->lut_b[i] = i << 2; - } - - if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)) - radeon_atombios_init_crtc(dev, radeon_crtc); - else - radeon_legacy_init_crtc(dev, radeon_crtc); -} - -static const char *encoder_names[37] = { - "NONE", - "INTERNAL_LVDS", - "INTERNAL_TMDS1", - "INTERNAL_TMDS2", - "INTERNAL_DAC1", - "INTERNAL_DAC2", - "INTERNAL_SDVOA", - "INTERNAL_SDVOB", - "SI170B", - "CH7303", - "CH7301", - "INTERNAL_DVO1", - "EXTERNAL_SDVOA", - "EXTERNAL_SDVOB", - "TITFP513", - "INTERNAL_LVTM1", - "VT1623", - "HDMI_SI1930", - "HDMI_INTERNAL", - "INTERNAL_KLDSCP_TMDS1", - "INTERNAL_KLDSCP_DVO1", - "INTERNAL_KLDSCP_DAC1", - "INTERNAL_KLDSCP_DAC2", - "SI178", - "MVPU_FPGA", - "INTERNAL_DDI", - "VT1625", - "HDMI_SI1932", - "DP_AN9801", - "DP_DP501", - "INTERNAL_UNIPHY", - "INTERNAL_KLDSCP_LVTMA", - "INTERNAL_UNIPHY1", - "INTERNAL_UNIPHY2", - "NUTMEG", - "TRAVIS", - "INTERNAL_VCE" -}; - -static const char *connector_names[15] = { - "Unknown", - "VGA", - "DVI-I", - "DVI-D", - "DVI-A", - "Composite", - "S-video", - "LVDS", - "Component", - "DIN", - "DisplayPort", - "HDMI-A", - "HDMI-B", - "TV", - "eDP", -}; - -static const char *hpd_names[6] = { - "HPD1", - "HPD2", - "HPD3", - "HPD4", - "HPD5", - "HPD6", -}; - -static void radeon_print_display_setup(struct drm_device *dev) -{ - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - uint32_t devices; - int i = 0; - - DRM_INFO("Radeon Display Connectors\n"); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - DRM_INFO("Connector %d:\n", i); - DRM_INFO(" %s\n", connector_names[connector->connector_type]); - if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) - DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); - if (radeon_connector->ddc_bus) { - DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", - radeon_connector->ddc_bus->rec.mask_clk_reg, - radeon_connector->ddc_bus->rec.mask_data_reg, - radeon_connector->ddc_bus->rec.a_clk_reg, - radeon_connector->ddc_bus->rec.a_data_reg, - radeon_connector->ddc_bus->rec.en_clk_reg, - radeon_connector->ddc_bus->rec.en_data_reg, - radeon_connector->ddc_bus->rec.y_clk_reg, - radeon_connector->ddc_bus->rec.y_data_reg); - if (radeon_connector->router.ddc_valid) - DRM_INFO(" DDC Router 0x%x/0x%x\n", - radeon_connector->router.ddc_mux_control_pin, - radeon_connector->router.ddc_mux_state); - if (radeon_connector->router.cd_valid) - DRM_INFO(" Clock/Data Router 0x%x/0x%x\n", - radeon_connector->router.cd_mux_control_pin, - radeon_connector->router.cd_mux_state); - } else { - if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || - connector->connector_type == DRM_MODE_CONNECTOR_DVII || - connector->connector_type == DRM_MODE_CONNECTOR_DVID || - connector->connector_type == DRM_MODE_CONNECTOR_DVIA || - connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || - connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) - DRM_INFO(" DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n"); - } - DRM_INFO(" Encoders:\n"); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); - devices = radeon_encoder->devices & radeon_connector->devices; - if (devices) { - if (devices & ATOM_DEVICE_CRT1_SUPPORT) - DRM_INFO(" CRT1: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_CRT2_SUPPORT) - DRM_INFO(" CRT2: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_LCD1_SUPPORT) - DRM_INFO(" LCD1: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_DFP1_SUPPORT) - DRM_INFO(" DFP1: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_DFP2_SUPPORT) - DRM_INFO(" DFP2: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_DFP3_SUPPORT) - DRM_INFO(" DFP3: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_DFP4_SUPPORT) - DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_DFP5_SUPPORT) - DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_DFP6_SUPPORT) - DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_TV1_SUPPORT) - DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); - if (devices & ATOM_DEVICE_CV_SUPPORT) - DRM_INFO(" CV: %s\n", encoder_names[radeon_encoder->encoder_id]); - } - } - i++; - } -} - -static bool radeon_setup_enc_conn(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - bool ret = false; - - if (rdev->bios) { - if (rdev->is_atom_bios) { - ret = radeon_get_atom_connector_info_from_supported_devices_table(dev); - if (ret == false) - ret = radeon_get_atom_connector_info_from_object_table(dev); - } else { - ret = radeon_get_legacy_connector_info_from_bios(dev); - if (ret == false) - ret = radeon_get_legacy_connector_info_from_table(dev); - } - } else { - if (!ASIC_IS_AVIVO(rdev)) - ret = radeon_get_legacy_connector_info_from_table(dev); - } - if (ret) { - radeon_setup_encoder_clones(dev); - radeon_print_display_setup(dev); - } - - return ret; -} - -int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) -{ - struct drm_device *dev = radeon_connector->base.dev; - struct radeon_device *rdev = dev->dev_private; - int ret = 0; - - /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); - - if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || - (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || - (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != - ENCODER_OBJECT_ID_NONE)) { - struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - - if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || - dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) - radeon_connector->edid = drm_get_edid(&radeon_connector->base, - &dig->dp_i2c_bus->adapter); - else if (radeon_connector->ddc_bus && !radeon_connector->edid) - radeon_connector->edid = drm_get_edid(&radeon_connector->base, - &radeon_connector->ddc_bus->adapter); - } else { - if (radeon_connector->ddc_bus && !radeon_connector->edid) - radeon_connector->edid = drm_get_edid(&radeon_connector->base, - &radeon_connector->ddc_bus->adapter); - } - - if (!radeon_connector->edid) { - if (rdev->is_atom_bios) { - /* some laptops provide a hardcoded edid in rom for LCDs */ - if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) || - (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP))) - radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); - } else - /* some servers provide a hardcoded edid in rom for KVMs */ - radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); - } - if (radeon_connector->edid) { - drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); - ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); - return ret; - } - drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); - return 0; -} - -/* avivo */ -static void avivo_get_fb_div(struct radeon_pll *pll, - u32 target_clock, - u32 post_div, - u32 ref_div, - u32 *fb_div, - u32 *frac_fb_div) -{ - u32 tmp = post_div * ref_div; - - tmp *= target_clock; - *fb_div = tmp / pll->reference_freq; - *frac_fb_div = tmp % pll->reference_freq; - - if (*fb_div > pll->max_feedback_div) - *fb_div = pll->max_feedback_div; - else if (*fb_div < pll->min_feedback_div) - *fb_div = pll->min_feedback_div; -} - -static u32 avivo_get_post_div(struct radeon_pll *pll, - u32 target_clock) -{ - u32 vco, post_div, tmp; - - if (pll->flags & RADEON_PLL_USE_POST_DIV) - return pll->post_div; - - if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) { - if (pll->flags & RADEON_PLL_IS_LCD) - vco = pll->lcd_pll_out_min; - else - vco = pll->pll_out_min; - } else { - if (pll->flags & RADEON_PLL_IS_LCD) - vco = pll->lcd_pll_out_max; - else - vco = pll->pll_out_max; - } - - post_div = vco / target_clock; - tmp = vco % target_clock; - - if (pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP) { - if (tmp) - post_div++; - } else { - if (!tmp) - post_div--; - } - - if (post_div > pll->max_post_div) - post_div = pll->max_post_div; - else if (post_div < pll->min_post_div) - post_div = pll->min_post_div; - - return post_div; -} - -#define MAX_TOLERANCE 10 - -void radeon_compute_pll_avivo(struct radeon_pll *pll, - u32 freq, - u32 *dot_clock_p, - u32 *fb_div_p, - u32 *frac_fb_div_p, - u32 *ref_div_p, - u32 *post_div_p) -{ - u32 target_clock = freq / 10; - u32 post_div = avivo_get_post_div(pll, target_clock); - u32 ref_div = pll->min_ref_div; - u32 fb_div = 0, frac_fb_div = 0, tmp; - - if (pll->flags & RADEON_PLL_USE_REF_DIV) - ref_div = pll->reference_div; - - if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { - avivo_get_fb_div(pll, target_clock, post_div, ref_div, &fb_div, &frac_fb_div); - frac_fb_div = (100 * frac_fb_div) / pll->reference_freq; - if (frac_fb_div >= 5) { - frac_fb_div -= 5; - frac_fb_div = frac_fb_div / 10; - frac_fb_div++; - } - if (frac_fb_div >= 10) { - fb_div++; - frac_fb_div = 0; - } - } else { - while (ref_div <= pll->max_ref_div) { - avivo_get_fb_div(pll, target_clock, post_div, ref_div, - &fb_div, &frac_fb_div); - if (frac_fb_div >= (pll->reference_freq / 2)) - fb_div++; - frac_fb_div = 0; - tmp = (pll->reference_freq * fb_div) / (post_div * ref_div); - tmp = (tmp * 10000) / target_clock; - - if (tmp > (10000 + MAX_TOLERANCE)) - ref_div++; - else if (tmp >= (10000 - MAX_TOLERANCE)) - break; - else - ref_div++; - } - } - - *dot_clock_p = ((pll->reference_freq * fb_div * 10) + (pll->reference_freq * frac_fb_div)) / - (ref_div * post_div * 10); - *fb_div_p = fb_div; - *frac_fb_div_p = frac_fb_div; - *ref_div_p = ref_div; - *post_div_p = post_div; - DRM_DEBUG_KMS("%d, pll dividers - fb: %d.%d ref: %d, post %d\n", - *dot_clock_p, fb_div, frac_fb_div, ref_div, post_div); -} - -/* pre-avivo */ -static inline uint32_t radeon_div(uint64_t n, uint32_t d) -{ - uint64_t mod; - - n += d / 2; - - mod = do_div(n, d); - return n; -} - -void radeon_compute_pll_legacy(struct radeon_pll *pll, - uint64_t freq, - uint32_t *dot_clock_p, - uint32_t *fb_div_p, - uint32_t *frac_fb_div_p, - uint32_t *ref_div_p, - uint32_t *post_div_p) -{ - uint32_t min_ref_div = pll->min_ref_div; - uint32_t max_ref_div = pll->max_ref_div; - uint32_t min_post_div = pll->min_post_div; - uint32_t max_post_div = pll->max_post_div; - uint32_t min_fractional_feed_div = 0; - uint32_t max_fractional_feed_div = 0; - uint32_t best_vco = pll->best_vco; - uint32_t best_post_div = 1; - uint32_t best_ref_div = 1; - uint32_t best_feedback_div = 1; - uint32_t best_frac_feedback_div = 0; - uint32_t best_freq = -1; - uint32_t best_error = 0xffffffff; - uint32_t best_vco_diff = 1; - uint32_t post_div; - u32 pll_out_min, pll_out_max; - - DRM_DEBUG_KMS("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); - freq = freq * 1000; - - if (pll->flags & RADEON_PLL_IS_LCD) { - pll_out_min = pll->lcd_pll_out_min; - pll_out_max = pll->lcd_pll_out_max; - } else { - pll_out_min = pll->pll_out_min; - pll_out_max = pll->pll_out_max; - } - - if (pll_out_min > 64800) - pll_out_min = 64800; - - if (pll->flags & RADEON_PLL_USE_REF_DIV) - min_ref_div = max_ref_div = pll->reference_div; - else { - while (min_ref_div < max_ref_div-1) { - uint32_t mid = (min_ref_div + max_ref_div) / 2; - uint32_t pll_in = pll->reference_freq / mid; - if (pll_in < pll->pll_in_min) - max_ref_div = mid; - else if (pll_in > pll->pll_in_max) - min_ref_div = mid; - else - break; - } - } - - if (pll->flags & RADEON_PLL_USE_POST_DIV) - min_post_div = max_post_div = pll->post_div; - - if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { - min_fractional_feed_div = pll->min_frac_feedback_div; - max_fractional_feed_div = pll->max_frac_feedback_div; - } - - for (post_div = max_post_div; post_div >= min_post_div; --post_div) { - uint32_t ref_div; - - if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) - continue; - - /* legacy radeons only have a few post_divs */ - if (pll->flags & RADEON_PLL_LEGACY) { - if ((post_div == 5) || - (post_div == 7) || - (post_div == 9) || - (post_div == 10) || - (post_div == 11) || - (post_div == 13) || - (post_div == 14) || - (post_div == 15)) - continue; - } - - for (ref_div = min_ref_div; ref_div <= max_ref_div; ++ref_div) { - uint32_t feedback_div, current_freq = 0, error, vco_diff; - uint32_t pll_in = pll->reference_freq / ref_div; - uint32_t min_feed_div = pll->min_feedback_div; - uint32_t max_feed_div = pll->max_feedback_div + 1; - - if (pll_in < pll->pll_in_min || pll_in > pll->pll_in_max) - continue; - - while (min_feed_div < max_feed_div) { - uint32_t vco; - uint32_t min_frac_feed_div = min_fractional_feed_div; - uint32_t max_frac_feed_div = max_fractional_feed_div + 1; - uint32_t frac_feedback_div; - uint64_t tmp; - - feedback_div = (min_feed_div + max_feed_div) / 2; - - tmp = (uint64_t)pll->reference_freq * feedback_div; - vco = radeon_div(tmp, ref_div); - - if (vco < pll_out_min) { - min_feed_div = feedback_div + 1; - continue; - } else if (vco > pll_out_max) { - max_feed_div = feedback_div; - continue; - } - - while (min_frac_feed_div < max_frac_feed_div) { - frac_feedback_div = (min_frac_feed_div + max_frac_feed_div) / 2; - tmp = (uint64_t)pll->reference_freq * 10000 * feedback_div; - tmp += (uint64_t)pll->reference_freq * 1000 * frac_feedback_div; - current_freq = radeon_div(tmp, ref_div * post_div); - - if (pll->flags & RADEON_PLL_PREFER_CLOSEST_LOWER) { - if (freq < current_freq) - error = 0xffffffff; - else - error = freq - current_freq; - } else - error = abs(current_freq - freq); - vco_diff = abs(vco - best_vco); - - if ((best_vco == 0 && error < best_error) || - (best_vco != 0 && - ((best_error > 100 && error < best_error - 100) || - (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) { - best_post_div = post_div; - best_ref_div = ref_div; - best_feedback_div = feedback_div; - best_frac_feedback_div = frac_feedback_div; - best_freq = current_freq; - best_error = error; - best_vco_diff = vco_diff; - } else if (current_freq == freq) { - if (best_freq == -1) { - best_post_div = post_div; - best_ref_div = ref_div; - best_feedback_div = feedback_div; - best_frac_feedback_div = frac_feedback_div; - best_freq = current_freq; - best_error = error; - best_vco_diff = vco_diff; - } else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) || - ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) || - ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) || - ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) || - ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) || - ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) { - best_post_div = post_div; - best_ref_div = ref_div; - best_feedback_div = feedback_div; - best_frac_feedback_div = frac_feedback_div; - best_freq = current_freq; - best_error = error; - best_vco_diff = vco_diff; - } - } - if (current_freq < freq) - min_frac_feed_div = frac_feedback_div + 1; - else - max_frac_feed_div = frac_feedback_div; - } - if (current_freq < freq) - min_feed_div = feedback_div + 1; - else - max_feed_div = feedback_div; - } - } - } - - *dot_clock_p = best_freq / 10000; - *fb_div_p = best_feedback_div; - *frac_fb_div_p = best_frac_feedback_div; - *ref_div_p = best_ref_div; - *post_div_p = best_post_div; - DRM_DEBUG_KMS("%lld %d, pll dividers - fb: %d.%d ref: %d, post %d\n", - (long long)freq, - best_freq / 1000, best_feedback_div, best_frac_feedback_div, - best_ref_div, best_post_div); - -} - -static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); - - if (radeon_fb->obj) { - drm_gem_object_unreference_unlocked(radeon_fb->obj); - } - drm_framebuffer_cleanup(fb); - kfree(radeon_fb); -} - -static int radeon_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); - - return drm_gem_handle_create(file_priv, radeon_fb->obj, handle); -} - -static const struct drm_framebuffer_funcs radeon_fb_funcs = { - .destroy = radeon_user_framebuffer_destroy, - .create_handle = radeon_user_framebuffer_create_handle, -}; - -int -radeon_framebuffer_init(struct drm_device *dev, - struct radeon_framebuffer *rfb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) -{ - int ret; - rfb->obj = obj; - ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); - if (ret) { - rfb->obj = NULL; - return ret; - } - drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); - return 0; -} - -static struct drm_framebuffer * -radeon_user_framebuffer_create(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_gem_object *obj; - struct radeon_framebuffer *radeon_fb; - int ret; - - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); - if (obj == NULL) { - dev_err(&dev->pdev->dev, "No GEM object associated to handle 0x%08X, " - "can't create framebuffer\n", mode_cmd->handles[0]); - return ERR_PTR(-ENOENT); - } - - radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL); - if (radeon_fb == NULL) - return ERR_PTR(-ENOMEM); - - ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); - if (ret) { - kfree(radeon_fb); - drm_gem_object_unreference_unlocked(obj); - return NULL; - } - - return &radeon_fb->base; -} - -static void radeon_output_poll_changed(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - radeon_fb_output_poll_changed(rdev); -} - -static const struct drm_mode_config_funcs radeon_mode_funcs = { - .fb_create = radeon_user_framebuffer_create, - .output_poll_changed = radeon_output_poll_changed -}; - -static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] = -{ { 0, "driver" }, - { 1, "bios" }, -}; - -static struct drm_prop_enum_list radeon_tv_std_enum_list[] = -{ { TV_STD_NTSC, "ntsc" }, - { TV_STD_PAL, "pal" }, - { TV_STD_PAL_M, "pal-m" }, - { TV_STD_PAL_60, "pal-60" }, - { TV_STD_NTSC_J, "ntsc-j" }, - { TV_STD_SCART_PAL, "scart-pal" }, - { TV_STD_PAL_CN, "pal-cn" }, - { TV_STD_SECAM, "secam" }, -}; - -static struct drm_prop_enum_list radeon_underscan_enum_list[] = -{ { UNDERSCAN_OFF, "off" }, - { UNDERSCAN_ON, "on" }, - { UNDERSCAN_AUTO, "auto" }, -}; - -static int radeon_modeset_create_props(struct radeon_device *rdev) -{ - int sz; - - if (rdev->is_atom_bios) { - rdev->mode_info.coherent_mode_property = - drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1); - if (!rdev->mode_info.coherent_mode_property) - return -ENOMEM; - } - - if (!ASIC_IS_AVIVO(rdev)) { - sz = ARRAY_SIZE(radeon_tmds_pll_enum_list); - rdev->mode_info.tmds_pll_property = - drm_property_create_enum(rdev->ddev, 0, - "tmds_pll", - radeon_tmds_pll_enum_list, sz); - } - - rdev->mode_info.load_detect_property = - drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1); - if (!rdev->mode_info.load_detect_property) - return -ENOMEM; - - drm_mode_create_scaling_mode_property(rdev->ddev); - - sz = ARRAY_SIZE(radeon_tv_std_enum_list); - rdev->mode_info.tv_std_property = - drm_property_create_enum(rdev->ddev, 0, - "tv standard", - radeon_tv_std_enum_list, sz); - - sz = ARRAY_SIZE(radeon_underscan_enum_list); - rdev->mode_info.underscan_property = - drm_property_create_enum(rdev->ddev, 0, - "underscan", - radeon_underscan_enum_list, sz); - - rdev->mode_info.underscan_hborder_property = - drm_property_create_range(rdev->ddev, 0, - "underscan hborder", 0, 128); - if (!rdev->mode_info.underscan_hborder_property) - return -ENOMEM; - - rdev->mode_info.underscan_vborder_property = - drm_property_create_range(rdev->ddev, 0, - "underscan vborder", 0, 128); - if (!rdev->mode_info.underscan_vborder_property) - return -ENOMEM; - - return 0; -} - -void radeon_update_display_priority(struct radeon_device *rdev) -{ - /* adjustment options for the display watermarks */ - if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) { - /* set display priority to high for r3xx, rv515 chips - * this avoids flickering due to underflow to the - * display controllers during heavy acceleration. - * Don't force high on rs4xx igp chips as it seems to - * affect the sound card. See kernel bug 15982. - */ - if ((ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515)) && - !(rdev->flags & RADEON_IS_IGP)) - rdev->disp_priority = 2; - else - rdev->disp_priority = 0; - } else - rdev->disp_priority = radeon_disp_priority; - -} - -int radeon_modeset_init(struct radeon_device *rdev) -{ - int i; - int ret; - - drm_mode_config_init(rdev->ddev); - rdev->mode_info.mode_config_initialized = true; - - rdev->ddev->mode_config.funcs = (void *)&radeon_mode_funcs; - - if (ASIC_IS_DCE5(rdev)) { - rdev->ddev->mode_config.max_width = 16384; - rdev->ddev->mode_config.max_height = 16384; - } else if (ASIC_IS_AVIVO(rdev)) { - rdev->ddev->mode_config.max_width = 8192; - rdev->ddev->mode_config.max_height = 8192; - } else { - rdev->ddev->mode_config.max_width = 4096; - rdev->ddev->mode_config.max_height = 4096; - } - - rdev->ddev->mode_config.preferred_depth = 24; - rdev->ddev->mode_config.prefer_shadow = 1; - - rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; - - ret = radeon_modeset_create_props(rdev); - if (ret) { - return ret; - } - - /* init i2c buses */ - radeon_i2c_init(rdev); - - /* check combios for a valid hardcoded EDID - Sun servers */ - if (!rdev->is_atom_bios) { - /* check for hardcoded EDID in BIOS */ - radeon_combios_check_hardcoded_edid(rdev); - } - - /* allocate crtcs */ - for (i = 0; i < rdev->num_crtc; i++) { - radeon_crtc_init(rdev->ddev, i); - } - - /* okay we should have all the bios connectors */ - ret = radeon_setup_enc_conn(rdev->ddev); - if (!ret) { - return ret; - } - - /* init dig PHYs, disp eng pll */ - if (rdev->is_atom_bios) { - radeon_atom_encoder_init(rdev); - radeon_atom_disp_eng_pll_init(rdev); - } - - /* initialize hpd */ - radeon_hpd_init(rdev); - - /* Initialize power management */ - radeon_pm_init(rdev); - - radeon_fbdev_init(rdev); - drm_kms_helper_poll_init(rdev->ddev); - - return 0; -} - -void radeon_modeset_fini(struct radeon_device *rdev) -{ - radeon_fbdev_fini(rdev); - kfree(rdev->mode_info.bios_hardcoded_edid); - radeon_pm_fini(rdev); - - if (rdev->mode_info.mode_config_initialized) { - drm_kms_helper_poll_fini(rdev->ddev); - radeon_hpd_fini(rdev); - drm_mode_config_cleanup(rdev->ddev); - rdev->mode_info.mode_config_initialized = false; - } - /* free i2c buses */ - radeon_i2c_fini(rdev); -} - -static bool is_hdtv_mode(struct drm_display_mode *mode) -{ - /* try and guess if this is a tv or a monitor */ - if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ - (mode->vdisplay == 576) || /* 576p */ - (mode->vdisplay == 720) || /* 720p */ - (mode->vdisplay == 1080)) /* 1080p */ - return true; - else - return false; -} - -bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_encoder *radeon_encoder; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - bool first = true; - u32 src_v = 1, dst_v = 1; - u32 src_h = 1, dst_h = 1; - - radeon_crtc->h_border = 0; - radeon_crtc->v_border = 0; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc != crtc) - continue; - radeon_encoder = to_radeon_encoder(encoder); - connector = radeon_get_connector_for_encoder(encoder); - radeon_connector = to_radeon_connector(connector); - - if (first) { - /* set scaling */ - if (radeon_encoder->rmx_type == RMX_OFF) - radeon_crtc->rmx_type = RMX_OFF; - else if (mode->hdisplay < radeon_encoder->native_mode.hdisplay || - mode->vdisplay < radeon_encoder->native_mode.vdisplay) - radeon_crtc->rmx_type = radeon_encoder->rmx_type; - else - radeon_crtc->rmx_type = RMX_OFF; - /* copy native mode */ - memcpy(&radeon_crtc->native_mode, - &radeon_encoder->native_mode, - sizeof(struct drm_display_mode)); - src_v = crtc->mode.vdisplay; - dst_v = radeon_crtc->native_mode.vdisplay; - src_h = crtc->mode.hdisplay; - dst_h = radeon_crtc->native_mode.hdisplay; - - /* fix up for overscan on hdmi */ - if (ASIC_IS_AVIVO(rdev) && - (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && - ((radeon_encoder->underscan_type == UNDERSCAN_ON) || - ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && - drm_detect_hdmi_monitor(radeon_connector->edid) && - is_hdtv_mode(mode)))) { - if (radeon_encoder->underscan_hborder != 0) - radeon_crtc->h_border = radeon_encoder->underscan_hborder; - else - radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; - if (radeon_encoder->underscan_vborder != 0) - radeon_crtc->v_border = radeon_encoder->underscan_vborder; - else - radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; - radeon_crtc->rmx_type = RMX_FULL; - src_v = crtc->mode.vdisplay; - dst_v = crtc->mode.vdisplay - (radeon_crtc->v_border * 2); - src_h = crtc->mode.hdisplay; - dst_h = crtc->mode.hdisplay - (radeon_crtc->h_border * 2); - } - first = false; - } else { - if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { - /* WARNING: Right now this can't happen but - * in the future we need to check that scaling - * are consistent across different encoder - * (ie all encoder can work with the same - * scaling). - */ - DRM_ERROR("Scaling not consistent across encoder.\n"); - return false; - } - } - } - if (radeon_crtc->rmx_type != RMX_OFF) { - fixed20_12 a, b; - a.full = dfixed_const(src_v); - b.full = dfixed_const(dst_v); - radeon_crtc->vsc.full = dfixed_div(a, b); - a.full = dfixed_const(src_h); - b.full = dfixed_const(dst_h); - radeon_crtc->hsc.full = dfixed_div(a, b); - } else { - radeon_crtc->vsc.full = dfixed_const(1); - radeon_crtc->hsc.full = dfixed_const(1); - } - return true; -} - -/* - * Retrieve current video scanout position of crtc on a given gpu. - * - * \param dev Device to query. - * \param crtc Crtc to query. - * \param *vpos Location where vertical scanout position should be stored. - * \param *hpos Location where horizontal scanout position should go. - * - * Returns vpos as a positive number while in active scanout area. - * Returns vpos as a negative number inside vblank, counting the number - * of scanlines to go until end of vblank, e.g., -1 means "one scanline - * until start of active scanout / end of vblank." - * - * \return Flags, or'ed together as follows: - * - * DRM_SCANOUTPOS_VALID = Query successful. - * DRM_SCANOUTPOS_INVBL = Inside vblank. - * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of - * this flag means that returned position may be offset by a constant but - * unknown small number of scanlines wrt. real scanout position. - * - */ -int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos) -{ - u32 stat_crtc = 0, vbl = 0, position = 0; - int vbl_start, vbl_end, vtotal, ret = 0; - bool in_vbl = true; - - struct radeon_device *rdev = dev->dev_private; - - if (ASIC_IS_DCE4(rdev)) { - if (crtc == 0) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC0_REGISTER_OFFSET); - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC0_REGISTER_OFFSET); - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 1) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC1_REGISTER_OFFSET); - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC1_REGISTER_OFFSET); - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 2) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC2_REGISTER_OFFSET); - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC2_REGISTER_OFFSET); - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 3) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC3_REGISTER_OFFSET); - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC3_REGISTER_OFFSET); - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 4) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC4_REGISTER_OFFSET); - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC4_REGISTER_OFFSET); - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 5) { - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + - EVERGREEN_CRTC5_REGISTER_OFFSET); - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + - EVERGREEN_CRTC5_REGISTER_OFFSET); - ret |= DRM_SCANOUTPOS_VALID; - } - } else if (ASIC_IS_AVIVO(rdev)) { - if (crtc == 0) { - vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); - position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 1) { - vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); - position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); - ret |= DRM_SCANOUTPOS_VALID; - } - } else { - /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ - if (crtc == 0) { - /* Assume vbl_end == 0, get vbl_start from - * upper 16 bits. - */ - vbl = (RREG32(RADEON_CRTC_V_TOTAL_DISP) & - RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT; - /* Only retrieve vpos from upper 16 bits, set hpos == 0. */ - position = (RREG32(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL; - stat_crtc = RREG32(RADEON_CRTC_STATUS); - if (!(stat_crtc & 1)) - in_vbl = false; - - ret |= DRM_SCANOUTPOS_VALID; - } - if (crtc == 1) { - vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & - RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT; - position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL; - stat_crtc = RREG32(RADEON_CRTC2_STATUS); - if (!(stat_crtc & 1)) - in_vbl = false; - - ret |= DRM_SCANOUTPOS_VALID; - } - } - - /* Decode into vertical and horizontal scanout position. */ - *vpos = position & 0x1fff; - *hpos = (position >> 16) & 0x1fff; - - /* Valid vblank area boundaries from gpu retrieved? */ - if (vbl > 0) { - /* Yes: Decode. */ - ret |= DRM_SCANOUTPOS_ACCURATE; - vbl_start = vbl & 0x1fff; - vbl_end = (vbl >> 16) & 0x1fff; - } - else { - /* No: Fake something reasonable which gives at least ok results. */ - vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; - vbl_end = 0; - } - - /* Test scanout position against vblank region. */ - if ((*vpos < vbl_start) && (*vpos >= vbl_end)) - in_vbl = false; - - /* Check if inside vblank area and apply corrective offsets: - * vpos will then be >=0 in video scanout area, but negative - * within vblank area, counting down the number of lines until - * start of scanout. - */ - - /* Inside "upper part" of vblank area? Apply corrective offset if so: */ - if (in_vbl && (*vpos >= vbl_start)) { - vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; - *vpos = *vpos - vtotal; - } - - /* Correct for shifted end of vbl at vbl_end. */ - *vpos = *vpos - vbl_end; - - /* In vblank? */ - if (in_vbl) - ret |= DRM_SCANOUTPOS_INVBL; - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.c deleted file mode 100644 index 15250fbe..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.c +++ /dev/null @@ -1,441 +0,0 @@ -/** - * \file radeon_drv.c - * ATI Radeon driver - * - * \author Gareth Hughes - */ - -/* - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -#include "drm_pciids.h" -#include -#include - - -/* - * KMS wrapper. - * - 2.0.0 - initial interface - * - 2.1.0 - add square tiling interface - * - 2.2.0 - add r6xx/r7xx const buffer support - * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs - * - 2.4.0 - add crtc id query - * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen - * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) - * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs - * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query - * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query - * 2.10.0 - fusion 2D tiling - * 2.11.0 - backend map, initial compute support for the CS checker - * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS - * 2.13.0 - virtual memory support, streamout - * 2.14.0 - add evergreen tiling informations - * 2.15.0 - add max_pipes query - * 2.16.0 - fix evergreen 2D tiled surface calculation - */ -#define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 16 -#define KMS_DRIVER_PATCHLEVEL 0 -int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); -int radeon_driver_unload_kms(struct drm_device *dev); -int radeon_driver_firstopen_kms(struct drm_device *dev); -void radeon_driver_lastclose_kms(struct drm_device *dev); -int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv); -void radeon_driver_postclose_kms(struct drm_device *dev, - struct drm_file *file_priv); -void radeon_driver_preclose_kms(struct drm_device *dev, - struct drm_file *file_priv); -int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); -int radeon_resume_kms(struct drm_device *dev); -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); -int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); -void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags); -void radeon_driver_irq_preinstall_kms(struct drm_device *dev); -int radeon_driver_irq_postinstall_kms(struct drm_device *dev); -void radeon_driver_irq_uninstall_kms(struct drm_device *dev); -irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS); -int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, - struct drm_file *file_priv); -int radeon_gem_object_init(struct drm_gem_object *obj); -void radeon_gem_object_free(struct drm_gem_object *obj); -int radeon_gem_object_open(struct drm_gem_object *obj, - struct drm_file *file_priv); -void radeon_gem_object_close(struct drm_gem_object *obj, - struct drm_file *file_priv); -extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, - int *vpos, int *hpos); -extern struct drm_ioctl_desc radeon_ioctls_kms[]; -extern int radeon_max_kms_ioctl; -int radeon_mmap(struct file *filp, struct vm_area_struct *vma); -int radeon_mode_dumb_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p); -int radeon_mode_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args); -int radeon_mode_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle); - -#if defined(CONFIG_DEBUG_FS) -int radeon_debugfs_init(struct drm_minor *minor); -void radeon_debugfs_cleanup(struct drm_minor *minor); -#endif - - -int radeon_no_wb; -int radeon_modeset = -1; -int radeon_dynclks = -1; -int radeon_r4xx_atom = 0; -int radeon_agpmode = 0; -int radeon_vram_limit = 0; -int radeon_gart_size = 512; /* default gart size */ -int radeon_benchmarking = 0; -int radeon_testing = 0; -int radeon_connector_table = 0; -int radeon_tv = 1; -int radeon_audio = 0; -int radeon_disp_priority = 0; -int radeon_hw_i2c = 0; -int radeon_pcie_gen2 = 0; -int radeon_msi = -1; - -MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); -module_param_named(no_wb, radeon_no_wb, int, 0444); - -MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); -module_param_named(modeset, radeon_modeset, int, 0400); - -MODULE_PARM_DESC(dynclks, "Disable/Enable dynamic clocks"); -module_param_named(dynclks, radeon_dynclks, int, 0444); - -MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx"); -module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444); - -MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing"); -module_param_named(vramlimit, radeon_vram_limit, int, 0600); - -MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); -module_param_named(agpmode, radeon_agpmode, int, 0444); - -MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc)"); -module_param_named(gartsize, radeon_gart_size, int, 0600); - -MODULE_PARM_DESC(benchmark, "Run benchmark"); -module_param_named(benchmark, radeon_benchmarking, int, 0444); - -MODULE_PARM_DESC(test, "Run tests"); -module_param_named(test, radeon_testing, int, 0444); - -MODULE_PARM_DESC(connector_table, "Force connector table"); -module_param_named(connector_table, radeon_connector_table, int, 0444); - -MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); -module_param_named(tv, radeon_tv, int, 0444); - -MODULE_PARM_DESC(audio, "Audio enable (1 = enable)"); -module_param_named(audio, radeon_audio, int, 0444); - -MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)"); -module_param_named(disp_priority, radeon_disp_priority, int, 0444); - -MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); -module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); - -MODULE_PARM_DESC(pcie_gen2, "PCIE Gen2 mode (1 = enable)"); -module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); - -MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); -module_param_named(msi, radeon_msi, int, 0444); - -static int radeon_suspend(struct drm_device *dev, pm_message_t state) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return 0; - - /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) - RADEON_WRITE(R500_DxMODE_INT_MASK, 0); - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - return 0; -} - -static int radeon_resume(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return 0; - - /* Restore interrupt registers */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) - RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); - return 0; -} - -static struct pci_device_id pciidlist[] = { - radeon_PCI_IDS -}; - -#if defined(CONFIG_DRM_RADEON_KMS) -MODULE_DEVICE_TABLE(pci, pciidlist); -#endif - -static const struct file_operations radeon_driver_old_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, -#ifdef CONFIG_COMPAT - .compat_ioctl = radeon_compat_ioctl, -#endif - .llseek = noop_llseek, -}; - -static struct drm_driver driver_old = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED, - .dev_priv_size = sizeof(drm_radeon_buf_priv_t), - .load = radeon_driver_load, - .firstopen = radeon_driver_firstopen, - .open = radeon_driver_open, - .preclose = radeon_driver_preclose, - .postclose = radeon_driver_postclose, - .lastclose = radeon_driver_lastclose, - .unload = radeon_driver_unload, - .suspend = radeon_suspend, - .resume = radeon_resume, - .get_vblank_counter = radeon_get_vblank_counter, - .enable_vblank = radeon_enable_vblank, - .disable_vblank = radeon_disable_vblank, - .master_create = radeon_master_create, - .master_destroy = radeon_master_destroy, - .irq_preinstall = radeon_driver_irq_preinstall, - .irq_postinstall = radeon_driver_irq_postinstall, - .irq_uninstall = radeon_driver_irq_uninstall, - .irq_handler = radeon_driver_irq_handler, - .reclaim_buffers = drm_core_reclaim_buffers, - .ioctls = radeon_ioctls, - .dma_ioctl = radeon_cp_buffers, - .fops = &radeon_driver_old_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct drm_driver kms_driver; - -static void radeon_kick_out_firmware_fb(struct pci_dev *pdev) -{ - struct apertures_struct *ap; - bool primary = false; - - ap = alloc_apertures(1); - ap->ranges[0].base = pci_resource_start(pdev, 0); - ap->ranges[0].size = pci_resource_len(pdev, 0); - -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif - remove_conflicting_framebuffers(ap, "radeondrmfb", primary); - kfree(ap); -} - -static int __devinit -radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - /* Get rid of things like offb */ - radeon_kick_out_firmware_fb(pdev); - - return drm_get_pci_dev(pdev, ent, &kms_driver); -} - -static void -radeon_pci_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - drm_put_dev(dev); -} - -static int -radeon_pci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - return radeon_suspend_kms(dev, state); -} - -static int -radeon_pci_resume(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - return radeon_resume_kms(dev); -} - -static const struct file_operations radeon_driver_kms_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = radeon_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .read = drm_read, -#ifdef CONFIG_COMPAT - .compat_ioctl = radeon_kms_compat_ioctl, -#endif -}; - -static struct drm_driver kms_driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | - DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM, - .dev_priv_size = 0, - .load = radeon_driver_load_kms, - .firstopen = radeon_driver_firstopen_kms, - .open = radeon_driver_open_kms, - .preclose = radeon_driver_preclose_kms, - .postclose = radeon_driver_postclose_kms, - .lastclose = radeon_driver_lastclose_kms, - .unload = radeon_driver_unload_kms, - .suspend = radeon_suspend_kms, - .resume = radeon_resume_kms, - .get_vblank_counter = radeon_get_vblank_counter_kms, - .enable_vblank = radeon_enable_vblank_kms, - .disable_vblank = radeon_disable_vblank_kms, - .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, - .get_scanout_position = radeon_get_crtc_scanoutpos, -#if defined(CONFIG_DEBUG_FS) - .debugfs_init = radeon_debugfs_init, - .debugfs_cleanup = radeon_debugfs_cleanup, -#endif - .irq_preinstall = radeon_driver_irq_preinstall_kms, - .irq_postinstall = radeon_driver_irq_postinstall_kms, - .irq_uninstall = radeon_driver_irq_uninstall_kms, - .irq_handler = radeon_driver_irq_handler_kms, - .reclaim_buffers = drm_core_reclaim_buffers, - .ioctls = radeon_ioctls_kms, - .gem_init_object = radeon_gem_object_init, - .gem_free_object = radeon_gem_object_free, - .gem_open_object = radeon_gem_object_open, - .gem_close_object = radeon_gem_object_close, - .dma_ioctl = radeon_dma_ioctl_kms, - .dumb_create = radeon_mode_dumb_create, - .dumb_map_offset = radeon_mode_dumb_mmap, - .dumb_destroy = radeon_mode_dumb_destroy, - .fops = &radeon_driver_kms_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = KMS_DRIVER_MAJOR, - .minor = KMS_DRIVER_MINOR, - .patchlevel = KMS_DRIVER_PATCHLEVEL, -}; - -static struct drm_driver *driver; -static struct pci_driver *pdriver; - -static struct pci_driver radeon_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, -}; - -static struct pci_driver radeon_kms_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = radeon_pci_probe, - .remove = radeon_pci_remove, - .suspend = radeon_pci_suspend, - .resume = radeon_pci_resume, -}; - -static int __init radeon_init(void) -{ - driver = &driver_old; - pdriver = &radeon_pci_driver; - driver->num_ioctls = radeon_max_ioctl; -#ifdef CONFIG_VGA_CONSOLE - if (vgacon_text_force() && radeon_modeset == -1) { - DRM_INFO("VGACON disable radeon kernel modesetting.\n"); - driver = &driver_old; - pdriver = &radeon_pci_driver; - driver->driver_features &= ~DRIVER_MODESET; - radeon_modeset = 0; - } -#endif - /* if enabled by default */ - if (radeon_modeset == -1) { -#ifdef CONFIG_DRM_RADEON_KMS - DRM_INFO("radeon defaulting to kernel modesetting.\n"); - radeon_modeset = 1; -#else - DRM_INFO("radeon defaulting to userspace modesetting.\n"); - radeon_modeset = 0; -#endif - } - if (radeon_modeset == 1) { - DRM_INFO("radeon kernel modesetting enabled.\n"); - driver = &kms_driver; - pdriver = &radeon_kms_pci_driver; - driver->driver_features |= DRIVER_MODESET; - driver->num_ioctls = radeon_max_kms_ioctl; - radeon_register_atpx_handler(); - } - /* if the vga console setting is enabled still - * let modprobe override it */ - return drm_pci_init(driver, pdriver); -} - -static void __exit radeon_exit(void) -{ - drm_pci_exit(driver, pdriver); - radeon_unregister_atpx_handler(); -} - -module_init(radeon_init); -module_exit(radeon_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.h deleted file mode 100644 index a1b59ca9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_drv.h +++ /dev/null @@ -1,2171 +0,0 @@ -/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*- - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kevin E. Martin - * Gareth Hughes - */ - -#ifndef __RADEON_DRV_H__ -#define __RADEON_DRV_H__ - -#include -#include - -#include "radeon_family.h" - -/* General customization: - */ - -#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others." - -#define DRIVER_NAME "radeon" -#define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20080528" - -/* Interface history: - * - * 1.1 - ?? - * 1.2 - Add vertex2 ioctl (keith) - * - Add stencil capability to clear ioctl (gareth, keith) - * - Increase MAX_TEXTURE_LEVELS (brian) - * 1.3 - Add cmdbuf ioctl (keith) - * - Add support for new radeon packets (keith) - * - Add getparam ioctl (keith) - * - Add flip-buffers ioctl, deprecate fullscreen foo (keith). - * 1.4 - Add scratch registers to get_param ioctl. - * 1.5 - Add r200 packets to cmdbuf ioctl - * - Add r200 function to init ioctl - * - Add 'scalar2' instruction to cmdbuf - * 1.6 - Add static GART memory manager - * Add irq handler (won't be turned on unless X server knows to) - * Add irq ioctls and irq_active getparam. - * Add wait command for cmdbuf ioctl - * Add GART offset query for getparam - * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5] - * and R200_PP_CUBIC_OFFSET_F1_[0..5]. - * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and - * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian) - * 1.8 - Remove need to call cleanup ioctls on last client exit (keith) - * Add 'GET' queries for starting additional clients on different VT's. - * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl. - * Add texture rectangle support for r100. - * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which - * clients use to tell the DRM where they think the framebuffer is - * located in the card's address space - * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color - * and GL_EXT_blend_[func|equation]_separate on r200 - * 1.12- Add R300 CP microcode support - this just loads the CP on r300 - * (No 3D support yet - just microcode loading). - * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters - * - Add hyperz support, add hyperz flags to clear ioctl. - * 1.14- Add support for color tiling - * - Add R100/R200 surface allocation/free support - * 1.15- Add support for texture micro tiling - * - Add support for r100 cube maps - * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear - * texture filtering on r200 - * 1.17- Add initial support for R300 (3D). - * 1.18- Add support for GL_ATI_fragment_shader, new packets - * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces - * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR - * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) - * 1.19- Add support for gart table in FB memory and PCIE r300 - * 1.20- Add support for r300 texrect - * 1.21- Add support for card type getparam - * 1.22- Add support for texture cache flushes (R300_TX_CNTL) - * 1.23- Add new radeon memory map work from benh - * 1.24- Add general-purpose packet for manipulating scratch registers (r300) - * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, - * new packet type) - * 1.26- Add support for variable size PCI(E) gart aperture - * 1.27- Add support for IGP GART - * 1.28- Add support for VBL on CRTC2 - * 1.29- R500 3D cmd buffer support - * 1.30- Add support for occlusion queries - * 1.31- Add support for num Z pipes from GET_PARAM - * 1.32- fixes for rv740 setup - * 1.33- Add r6xx/r7xx const buffer support - */ -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 33 -#define DRIVER_PATCHLEVEL 0 - -enum radeon_cp_microcode_version { - UCODE_R100, - UCODE_R200, - UCODE_R300, -}; - -typedef struct drm_radeon_freelist { - unsigned int age; - struct drm_buf *buf; - struct drm_radeon_freelist *next; - struct drm_radeon_freelist *prev; -} drm_radeon_freelist_t; - -typedef struct drm_radeon_ring_buffer { - u32 *start; - u32 *end; - int size; - int size_l2qw; - - int rptr_update; /* Double Words */ - int rptr_update_l2qw; /* log2 Quad Words */ - - int fetch_size; /* Double Words */ - int fetch_size_l2ow; /* log2 Oct Words */ - - u32 tail; - u32 tail_mask; - int space; - - int high_mark; -} drm_radeon_ring_buffer_t; - -typedef struct drm_radeon_depth_clear_t { - u32 rb3d_cntl; - u32 rb3d_zstencilcntl; - u32 se_cntl; -} drm_radeon_depth_clear_t; - -struct drm_radeon_driver_file_fields { - int64_t radeon_fb_delta; -}; - -struct mem_block { - struct mem_block *next; - struct mem_block *prev; - int start; - int size; - struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ -}; - -struct radeon_surface { - int refcount; - u32 lower; - u32 upper; - u32 flags; -}; - -struct radeon_virt_surface { - int surface_index; - u32 lower; - u32 upper; - u32 flags; - struct drm_file *file_priv; -#define PCIGART_FILE_PRIV ((void *) -1L) -}; - -#define RADEON_FLUSH_EMITED (1 << 0) -#define RADEON_PURGE_EMITED (1 << 1) - -struct drm_radeon_master_private { - drm_local_map_t *sarea; - drm_radeon_sarea_t *sarea_priv; -}; - -typedef struct drm_radeon_private { - drm_radeon_ring_buffer_t ring; - - u32 fb_location; - u32 fb_size; - int new_memmap; - - int gart_size; - u32 gart_vm_start; - unsigned long gart_buffers_offset; - - int cp_mode; - int cp_running; - - drm_radeon_freelist_t *head; - drm_radeon_freelist_t *tail; - int last_buf; - int writeback_works; - - int usec_timeout; - - int microcode_version; - - struct { - u32 boxes; - int freelist_timeouts; - int freelist_loops; - int requested_bufs; - int last_frame_reads; - int last_clear_reads; - int clears; - int texture_uploads; - } stats; - - int do_boxes; - int page_flipping; - - u32 color_fmt; - unsigned int front_offset; - unsigned int front_pitch; - unsigned int back_offset; - unsigned int back_pitch; - - u32 depth_fmt; - unsigned int depth_offset; - unsigned int depth_pitch; - - u32 front_pitch_offset; - u32 back_pitch_offset; - u32 depth_pitch_offset; - - drm_radeon_depth_clear_t depth_clear; - - unsigned long ring_offset; - unsigned long ring_rptr_offset; - unsigned long buffers_offset; - unsigned long gart_textures_offset; - - drm_local_map_t *sarea; - drm_local_map_t *cp_ring; - drm_local_map_t *ring_rptr; - drm_local_map_t *gart_textures; - - struct mem_block *gart_heap; - struct mem_block *fb_heap; - - /* SW interrupt */ - wait_queue_head_t swi_queue; - atomic_t swi_emitted; - int vblank_crtc; - uint32_t irq_enable_reg; - uint32_t r500_disp_irq_reg; - - struct radeon_surface surfaces[RADEON_MAX_SURFACES]; - struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; - - unsigned long pcigart_offset; - unsigned int pcigart_offset_set; - struct drm_ati_pcigart_info gart_info; - - u32 scratch_ages[5]; - - int have_z_offset; - - /* starting from here on, data is preserved across an open */ - uint32_t flags; /* see radeon_chip_flags */ - resource_size_t fb_aper_offset; - - int num_gb_pipes; - int num_z_pipes; - int track_flush; - drm_local_map_t *mmio; - - /* r6xx/r7xx pipe/shader config */ - int r600_max_pipes; - int r600_max_tile_pipes; - int r600_max_simds; - int r600_max_backends; - int r600_max_gprs; - int r600_max_threads; - int r600_max_stack_entries; - int r600_max_hw_contexts; - int r600_max_gs_threads; - int r600_sx_max_export_size; - int r600_sx_max_export_pos_size; - int r600_sx_max_export_smx_size; - int r600_sq_num_cf_insts; - int r700_sx_num_of_sets; - int r700_sc_prim_fifo_size; - int r700_sc_hiz_tile_fifo_size; - int r700_sc_earlyz_tile_fifo_fize; - int r600_group_size; - int r600_npipes; - int r600_nbanks; - - struct mutex cs_mutex; - u32 cs_id_scnt; - u32 cs_id_wcnt; - /* r6xx/r7xx drm blit vertex buffer */ - struct drm_buf *blit_vb; - - /* firmware */ - const struct firmware *me_fw, *pfp_fw; -} drm_radeon_private_t; - -typedef struct drm_radeon_buf_priv { - u32 age; -} drm_radeon_buf_priv_t; - -struct drm_buffer; - -typedef struct drm_radeon_kcmd_buffer { - int bufsz; - struct drm_buffer *buffer; - int nbox; - struct drm_clip_rect __user *boxes; -} drm_radeon_kcmd_buffer_t; - -extern int radeon_no_wb; -extern struct drm_ioctl_desc radeon_ioctls[]; -extern int radeon_max_ioctl; - -extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); -extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); - -#define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv) -#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val) - -/* Check whether the given hardware address is inside the framebuffer or the - * GART area. - */ -static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, - u64 off) -{ - u32 fb_start = dev_priv->fb_location; - u32 fb_end = fb_start + dev_priv->fb_size - 1; - u32 gart_start = dev_priv->gart_vm_start; - u32 gart_end = gart_start + dev_priv->gart_size - 1; - - return ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)); -} - -/* radeon_state.c */ -extern void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf); - - /* radeon_cp.c */ -extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); -extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc); -extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); -extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr); - -extern void radeon_freelist_reset(struct drm_device * dev); -extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); - -extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); - -extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); - -extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags); -extern int radeon_presetup(struct drm_device *dev); -extern int radeon_driver_postcleanup(struct drm_device *dev); - -extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void radeon_mem_takedown(struct mem_block **heap); -extern void radeon_mem_release(struct drm_file *file_priv, - struct mem_block *heap); - -extern void radeon_enable_bm(struct drm_radeon_private *dev_priv); -extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off); -extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val); - - /* radeon_irq.c */ -extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state); -extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); - -extern void radeon_do_release(struct drm_device * dev); -extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc); -extern int radeon_enable_vblank(struct drm_device *dev, int crtc); -extern void radeon_disable_vblank(struct drm_device *dev, int crtc); -extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS); -extern void radeon_driver_irq_preinstall(struct drm_device * dev); -extern int radeon_driver_irq_postinstall(struct drm_device *dev); -extern void radeon_driver_irq_uninstall(struct drm_device * dev); -extern void radeon_enable_interrupt(struct drm_device *dev); -extern int radeon_vblank_crtc_get(struct drm_device *dev); -extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value); - -extern int radeon_driver_load(struct drm_device *dev, unsigned long flags); -extern int radeon_driver_unload(struct drm_device *dev); -extern int radeon_driver_firstopen(struct drm_device *dev); -extern void radeon_driver_preclose(struct drm_device *dev, - struct drm_file *file_priv); -extern void radeon_driver_postclose(struct drm_device *dev, - struct drm_file *file_priv); -extern void radeon_driver_lastclose(struct drm_device * dev); -extern int radeon_driver_open(struct drm_device *dev, - struct drm_file *file_priv); -extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); -extern long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); - -extern int radeon_master_create(struct drm_device *dev, struct drm_master *master); -extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master); -extern void radeon_cp_dispatch_flip(struct drm_device *dev, struct drm_master *master); -/* r300_cmdbuf.c */ -extern void r300_init_reg_flags(struct drm_device *dev); - -extern int r300_do_cp_cmdbuf(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf); - -/* r600_cp.c */ -extern int r600_do_engine_reset(struct drm_device *dev); -extern int r600_do_cleanup_cp(struct drm_device *dev); -extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - struct drm_file *file_priv); -extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv); -extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv); -extern void r600_do_cp_start(drm_radeon_private_t *dev_priv); -extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv); -extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv); -extern int r600_cp_dispatch_indirect(struct drm_device *dev, - struct drm_buf *buf, int start, int end); -extern int r600_page_table_init(struct drm_device *dev); -extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); -extern int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); -extern void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv); -extern int r600_cp_dispatch_texture(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_texture_t *tex, - drm_radeon_tex_image_t *image); -/* r600_blit.c */ -extern int r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv); -extern void r600_done_blit_copy(struct drm_device *dev); -extern void r600_blit_copy(struct drm_device *dev, - uint64_t src_gpu_addr, uint64_t dst_gpu_addr, - int size_bytes); -extern void r600_blit_swap(struct drm_device *dev, - uint64_t src_gpu_addr, uint64_t dst_gpu_addr, - int sx, int sy, int dx, int dy, - int w, int h, int src_pitch, int dst_pitch, int cpp); - -/* atpx handler */ -#if defined(CONFIG_VGA_SWITCHEROO) -void radeon_register_atpx_handler(void); -void radeon_unregister_atpx_handler(void); -#else -static inline void radeon_register_atpx_handler(void) {} -static inline void radeon_unregister_atpx_handler(void) {} -#endif - -/* Flags for stats.boxes - */ -#define RADEON_BOX_DMA_IDLE 0x1 -#define RADEON_BOX_RING_FULL 0x2 -#define RADEON_BOX_FLIP 0x4 -#define RADEON_BOX_WAIT_IDLE 0x8 -#define RADEON_BOX_TEXTURE_LOAD 0x10 - -/* Register definitions, register access macros and drmAddMap constants - * for Radeon kernel driver. - */ -#define RADEON_MM_INDEX 0x0000 -#define RADEON_MM_DATA 0x0004 - -#define RADEON_AGP_COMMAND 0x0f60 -#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ -# define RADEON_AGP_ENABLE (1<<8) -#define RADEON_AUX_SCISSOR_CNTL 0x26f0 -# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) -# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) -# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26) -# define RADEON_SCISSOR_0_ENABLE (1 << 28) -# define RADEON_SCISSOR_1_ENABLE (1 << 29) -# define RADEON_SCISSOR_2_ENABLE (1 << 30) - -/* - * PCIE radeons (rv370/rv380, rv410, r423/r430/r480, r5xx) - * don't have an explicit bus mastering disable bit. It's handled - * by the PCI D-states. PMI_BM_DIS disables D-state bus master - * handling, not bus mastering itself. - */ -#define RADEON_BUS_CNTL 0x0030 -/* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ -# define RADEON_BUS_MASTER_DIS (1 << 6) -/* rs600/rs690/rs740 */ -# define RS600_BUS_MASTER_DIS (1 << 14) -# define RS600_MSI_REARM (1 << 20) -/* see RS400_MSI_REARM in AIC_CNTL for rs480 */ - -#define RADEON_BUS_CNTL1 0x0034 -# define RADEON_PMI_BM_DIS (1 << 2) -# define RADEON_PMI_INT_DIS (1 << 3) - -#define RV370_BUS_CNTL 0x004c -# define RV370_PMI_BM_DIS (1 << 5) -# define RV370_PMI_INT_DIS (1 << 6) - -#define RADEON_MSI_REARM_EN 0x0160 -/* rv370/rv380, rv410, r423/r430/r480, r5xx */ -# define RV370_MSI_REARM_EN (1 << 0) - -#define RADEON_CLOCK_CNTL_DATA 0x000c -# define RADEON_PLL_WR_EN (1 << 7) -#define RADEON_CLOCK_CNTL_INDEX 0x0008 -#define RADEON_CONFIG_APER_SIZE 0x0108 -#define RADEON_CONFIG_MEMSIZE 0x00f8 -#define RADEON_CRTC_OFFSET 0x0224 -#define RADEON_CRTC_OFFSET_CNTL 0x0228 -# define RADEON_CRTC_TILE_EN (1 << 15) -# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) -#define RADEON_CRTC2_OFFSET 0x0324 -#define RADEON_CRTC2_OFFSET_CNTL 0x0328 - -#define RADEON_PCIE_INDEX 0x0030 -#define RADEON_PCIE_DATA 0x0034 -#define RADEON_PCIE_TX_GART_CNTL 0x10 -# define RADEON_PCIE_TX_GART_EN (1 << 0) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0 << 1) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1 << 1) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3 << 1) -# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0 << 3) -# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1 << 3) -# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1 << 5) -# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1 << 8) -#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11 -#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12 -#define RADEON_PCIE_TX_GART_BASE 0x13 -#define RADEON_PCIE_TX_GART_START_LO 0x14 -#define RADEON_PCIE_TX_GART_START_HI 0x15 -#define RADEON_PCIE_TX_GART_END_LO 0x16 -#define RADEON_PCIE_TX_GART_END_HI 0x17 - -#define RS480_NB_MC_INDEX 0x168 -# define RS480_NB_MC_IND_WR_EN (1 << 8) -#define RS480_NB_MC_DATA 0x16c - -#define RS690_MC_INDEX 0x78 -# define RS690_MC_INDEX_MASK 0x1ff -# define RS690_MC_INDEX_WR_EN (1 << 9) -# define RS690_MC_INDEX_WR_ACK 0x7f -#define RS690_MC_DATA 0x7c - -/* MC indirect registers */ -#define RS480_MC_MISC_CNTL 0x18 -# define RS480_DISABLE_GTW (1 << 1) -/* switch between MCIND GART and MM GART registers. 0 = mmgart, 1 = mcind gart */ -# define RS480_GART_INDEX_REG_EN (1 << 12) -# define RS690_BLOCK_GFX_D3_EN (1 << 14) -#define RS480_K8_FB_LOCATION 0x1e -#define RS480_GART_FEATURE_ID 0x2b -# define RS480_HANG_EN (1 << 11) -# define RS480_TLB_ENABLE (1 << 18) -# define RS480_P2P_ENABLE (1 << 19) -# define RS480_GTW_LAC_EN (1 << 25) -# define RS480_2LEVEL_GART (0 << 30) -# define RS480_1LEVEL_GART (1 << 30) -# define RS480_PDC_EN (1 << 31) -#define RS480_GART_BASE 0x2c -#define RS480_GART_CACHE_CNTRL 0x2e -# define RS480_GART_CACHE_INVALIDATE (1 << 0) /* wait for it to clear */ -#define RS480_AGP_ADDRESS_SPACE_SIZE 0x38 -# define RS480_GART_EN (1 << 0) -# define RS480_VA_SIZE_32MB (0 << 1) -# define RS480_VA_SIZE_64MB (1 << 1) -# define RS480_VA_SIZE_128MB (2 << 1) -# define RS480_VA_SIZE_256MB (3 << 1) -# define RS480_VA_SIZE_512MB (4 << 1) -# define RS480_VA_SIZE_1GB (5 << 1) -# define RS480_VA_SIZE_2GB (6 << 1) -#define RS480_AGP_MODE_CNTL 0x39 -# define RS480_POST_GART_Q_SIZE (1 << 18) -# define RS480_NONGART_SNOOP (1 << 19) -# define RS480_AGP_RD_BUF_SIZE (1 << 20) -# define RS480_REQ_TYPE_SNOOP_SHIFT 22 -# define RS480_REQ_TYPE_SNOOP_MASK 0x3 -# define RS480_REQ_TYPE_SNOOP_DIS (1 << 24) -#define RS480_MC_MISC_UMA_CNTL 0x5f -#define RS480_MC_MCLK_CNTL 0x7a -#define RS480_MC_UMA_DUALCH_CNTL 0x86 - -#define RS690_MC_FB_LOCATION 0x100 -#define RS690_MC_AGP_LOCATION 0x101 -#define RS690_MC_AGP_BASE 0x102 -#define RS690_MC_AGP_BASE_2 0x103 - -#define RS600_MC_INDEX 0x70 -# define RS600_MC_ADDR_MASK 0xffff -# define RS600_MC_IND_SEQ_RBS_0 (1 << 16) -# define RS600_MC_IND_SEQ_RBS_1 (1 << 17) -# define RS600_MC_IND_SEQ_RBS_2 (1 << 18) -# define RS600_MC_IND_SEQ_RBS_3 (1 << 19) -# define RS600_MC_IND_AIC_RBS (1 << 20) -# define RS600_MC_IND_CITF_ARB0 (1 << 21) -# define RS600_MC_IND_CITF_ARB1 (1 << 22) -# define RS600_MC_IND_WR_EN (1 << 23) -#define RS600_MC_DATA 0x74 - -#define RS600_MC_STATUS 0x0 -# define RS600_MC_IDLE (1 << 1) -#define RS600_MC_FB_LOCATION 0x4 -#define RS600_MC_AGP_LOCATION 0x5 -#define RS600_AGP_BASE 0x6 -#define RS600_AGP_BASE_2 0x7 -#define RS600_MC_CNTL1 0x9 -# define RS600_ENABLE_PAGE_TABLES (1 << 26) -#define RS600_MC_PT0_CNTL 0x100 -# define RS600_ENABLE_PT (1 << 0) -# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15) -# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21) -# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28) -# define RS600_INVALIDATE_L2_CACHE (1 << 29) -#define RS600_MC_PT0_CONTEXT0_CNTL 0x102 -# define RS600_ENABLE_PAGE_TABLE (1 << 0) -# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1) -#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112 -#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114 -#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c -#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c -#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c -#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c -#define RS600_MC_PT0_CLIENT0_CNTL 0x16c -# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0) -# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1) -# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8) -# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8) -# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8) -# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8) -# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8) -# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10) -# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10) -# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11) -# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14) -# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) -# define RS600_INVALIDATE_L1_TLB (1 << 20) - -#define R520_MC_IND_INDEX 0x70 -#define R520_MC_IND_WR_EN (1 << 24) -#define R520_MC_IND_DATA 0x74 - -#define RV515_MC_FB_LOCATION 0x01 -#define RV515_MC_AGP_LOCATION 0x02 -#define RV515_MC_AGP_BASE 0x03 -#define RV515_MC_AGP_BASE_2 0x04 - -#define R520_MC_FB_LOCATION 0x04 -#define R520_MC_AGP_LOCATION 0x05 -#define R520_MC_AGP_BASE 0x06 -#define R520_MC_AGP_BASE_2 0x07 - -#define RADEON_MPP_TB_CONFIG 0x01c0 -#define RADEON_MEM_CNTL 0x0140 -#define RADEON_MEM_SDRAM_MODE_REG 0x0158 -#define RADEON_AGP_BASE_2 0x015c /* r200+ only */ -#define RS480_AGP_BASE_2 0x0164 -#define RADEON_AGP_BASE 0x0170 - -/* pipe config regs */ -#define R400_GB_PIPE_SELECT 0x402c -#define RV530_GB_PIPE_SELECT2 0x4124 -#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */ -#define R300_GB_TILE_CONFIG 0x4018 -# define R300_ENABLE_TILING (1 << 0) -# define R300_PIPE_COUNT_RV350 (0 << 1) -# define R300_PIPE_COUNT_R300 (3 << 1) -# define R300_PIPE_COUNT_R420_3P (6 << 1) -# define R300_PIPE_COUNT_R420 (7 << 1) -# define R300_TILE_SIZE_8 (0 << 4) -# define R300_TILE_SIZE_16 (1 << 4) -# define R300_TILE_SIZE_32 (2 << 4) -# define R300_SUBPIXEL_1_12 (0 << 16) -# define R300_SUBPIXEL_1_16 (1 << 16) -#define R300_DST_PIPE_CONFIG 0x170c -# define R300_PIPE_AUTO_CONFIG (1 << 31) -#define R300_RB2D_DSTCACHE_MODE 0x3428 -# define R300_DC_AUTOFLUSH_ENABLE (1 << 8) -# define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17) - -#define RADEON_RB3D_COLOROFFSET 0x1c40 -#define RADEON_RB3D_COLORPITCH 0x1c48 - -#define RADEON_SRC_X_Y 0x1590 - -#define RADEON_DP_GUI_MASTER_CNTL 0x146c -# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) -# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) -# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) -# define RADEON_GMC_BRUSH_NONE (15 << 4) -# define RADEON_GMC_DST_16BPP (4 << 8) -# define RADEON_GMC_DST_24BPP (5 << 8) -# define RADEON_GMC_DST_32BPP (6 << 8) -# define RADEON_GMC_DST_DATATYPE_SHIFT 8 -# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) -# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) -# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) -# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) -# define RADEON_GMC_WR_MSK_DIS (1 << 30) -# define RADEON_ROP3_S 0x00cc0000 -# define RADEON_ROP3_P 0x00f00000 -#define RADEON_DP_WRITE_MASK 0x16cc -#define RADEON_SRC_PITCH_OFFSET 0x1428 -#define RADEON_DST_PITCH_OFFSET 0x142c -#define RADEON_DST_PITCH_OFFSET_C 0x1c80 -# define RADEON_DST_TILE_LINEAR (0 << 30) -# define RADEON_DST_TILE_MACRO (1 << 30) -# define RADEON_DST_TILE_MICRO (2 << 30) -# define RADEON_DST_TILE_BOTH (3 << 30) - -#define RADEON_SCRATCH_REG0 0x15e0 -#define RADEON_SCRATCH_REG1 0x15e4 -#define RADEON_SCRATCH_REG2 0x15e8 -#define RADEON_SCRATCH_REG3 0x15ec -#define RADEON_SCRATCH_REG4 0x15f0 -#define RADEON_SCRATCH_REG5 0x15f4 -#define RADEON_SCRATCH_UMSK 0x0770 -#define RADEON_SCRATCH_ADDR 0x0774 - -#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) - -extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); - -#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x) - -#define R600_SCRATCH_REG0 0x8500 -#define R600_SCRATCH_REG1 0x8504 -#define R600_SCRATCH_REG2 0x8508 -#define R600_SCRATCH_REG3 0x850c -#define R600_SCRATCH_REG4 0x8510 -#define R600_SCRATCH_REG5 0x8514 -#define R600_SCRATCH_REG6 0x8518 -#define R600_SCRATCH_REG7 0x851c -#define R600_SCRATCH_UMSK 0x8540 -#define R600_SCRATCH_ADDR 0x8544 - -#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x)) - -#define RADEON_GEN_INT_CNTL 0x0040 -# define RADEON_CRTC_VBLANK_MASK (1 << 0) -# define RADEON_CRTC2_VBLANK_MASK (1 << 9) -# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) -# define RADEON_SW_INT_ENABLE (1 << 25) - -#define RADEON_GEN_INT_STATUS 0x0044 -# define RADEON_CRTC_VBLANK_STAT (1 << 0) -# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) -# define RADEON_CRTC2_VBLANK_STAT (1 << 9) -# define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) -# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) -# define RADEON_SW_INT_TEST (1 << 25) -# define RADEON_SW_INT_TEST_ACK (1 << 25) -# define RADEON_SW_INT_FIRE (1 << 26) -# define R500_DISPLAY_INT_STATUS (1 << 0) - -#define RADEON_HOST_PATH_CNTL 0x0130 -# define RADEON_HDP_SOFT_RESET (1 << 26) -# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) -# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28) - -#define RADEON_ISYNC_CNTL 0x1724 -# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) -# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) -# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) -# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) -# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) -# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) - -#define RADEON_RBBM_GUICNTL 0x172c -# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) -# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) -# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) -# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) - -#define RADEON_MC_AGP_LOCATION 0x014c -#define RADEON_MC_FB_LOCATION 0x0148 -#define RADEON_MCLK_CNTL 0x0012 -# define RADEON_FORCEON_MCLKA (1 << 16) -# define RADEON_FORCEON_MCLKB (1 << 17) -# define RADEON_FORCEON_YCLKA (1 << 18) -# define RADEON_FORCEON_YCLKB (1 << 19) -# define RADEON_FORCEON_MC (1 << 20) -# define RADEON_FORCEON_AIC (1 << 21) - -#define RADEON_PP_BORDER_COLOR_0 0x1d40 -#define RADEON_PP_BORDER_COLOR_1 0x1d44 -#define RADEON_PP_BORDER_COLOR_2 0x1d48 -#define RADEON_PP_CNTL 0x1c38 -# define RADEON_SCISSOR_ENABLE (1 << 1) -#define RADEON_PP_LUM_MATRIX 0x1d00 -#define RADEON_PP_MISC 0x1c14 -#define RADEON_PP_ROT_MATRIX_0 0x1d58 -#define RADEON_PP_TXFILTER_0 0x1c54 -#define RADEON_PP_TXOFFSET_0 0x1c5c -#define RADEON_PP_TXFILTER_1 0x1c6c -#define RADEON_PP_TXFILTER_2 0x1c84 - -#define R300_RB2D_DSTCACHE_CTLSTAT 0x342c /* use R300_DSTCACHE_CTLSTAT */ -#define R300_DSTCACHE_CTLSTAT 0x1714 -# define R300_RB2D_DC_FLUSH (3 << 0) -# define R300_RB2D_DC_FREE (3 << 2) -# define R300_RB2D_DC_FLUSH_ALL 0xf -# define R300_RB2D_DC_BUSY (1 << 31) -#define RADEON_RB3D_CNTL 0x1c3c -# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) -# define RADEON_PLANE_MASK_ENABLE (1 << 1) -# define RADEON_DITHER_ENABLE (1 << 2) -# define RADEON_ROUND_ENABLE (1 << 3) -# define RADEON_SCALE_DITHER_ENABLE (1 << 4) -# define RADEON_DITHER_INIT (1 << 5) -# define RADEON_ROP_ENABLE (1 << 6) -# define RADEON_STENCIL_ENABLE (1 << 7) -# define RADEON_Z_ENABLE (1 << 8) -# define RADEON_ZBLOCK16 (1 << 15) -#define RADEON_RB3D_DEPTHOFFSET 0x1c24 -#define RADEON_RB3D_DEPTHCLEARVALUE 0x3230 -#define RADEON_RB3D_DEPTHPITCH 0x1c28 -#define RADEON_RB3D_PLANEMASK 0x1d84 -#define RADEON_RB3D_STENCILREFMASK 0x1d7c -#define RADEON_RB3D_ZCACHE_MODE 0x3250 -#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254 -# define RADEON_RB3D_ZC_FLUSH (1 << 0) -# define RADEON_RB3D_ZC_FREE (1 << 2) -# define RADEON_RB3D_ZC_FLUSH_ALL 0x5 -# define RADEON_RB3D_ZC_BUSY (1 << 31) -#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 -# define R300_ZC_FLUSH (1 << 0) -# define R300_ZC_FREE (1 << 1) -# define R300_ZC_BUSY (1 << 31) -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c -# define RADEON_RB3D_DC_FLUSH (3 << 0) -# define RADEON_RB3D_DC_FREE (3 << 2) -# define RADEON_RB3D_DC_FLUSH_ALL 0xf -# define RADEON_RB3D_DC_BUSY (1 << 31) -#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c -# define R300_RB3D_DC_FLUSH (2 << 0) -# define R300_RB3D_DC_FREE (2 << 2) -# define R300_RB3D_DC_FINISH (1 << 4) -#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c -# define RADEON_Z_TEST_MASK (7 << 4) -# define RADEON_Z_TEST_ALWAYS (7 << 4) -# define RADEON_Z_HIERARCHY_ENABLE (1 << 8) -# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) -# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) -# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) -# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) -# define RADEON_FORCE_Z_DIRTY (1 << 29) -# define RADEON_Z_WRITE_ENABLE (1 << 30) -# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) -#define RADEON_RBBM_SOFT_RESET 0x00f0 -# define RADEON_SOFT_RESET_CP (1 << 0) -# define RADEON_SOFT_RESET_HI (1 << 1) -# define RADEON_SOFT_RESET_SE (1 << 2) -# define RADEON_SOFT_RESET_RE (1 << 3) -# define RADEON_SOFT_RESET_PP (1 << 4) -# define RADEON_SOFT_RESET_E2 (1 << 5) -# define RADEON_SOFT_RESET_RB (1 << 6) -# define RADEON_SOFT_RESET_HDP (1 << 7) -/* - * 6:0 Available slots in the FIFO - * 8 Host Interface active - * 9 CP request active - * 10 FIFO request active - * 11 Host Interface retry active - * 12 CP retry active - * 13 FIFO retry active - * 14 FIFO pipeline busy - * 15 Event engine busy - * 16 CP command stream busy - * 17 2D engine busy - * 18 2D portion of render backend busy - * 20 3D setup engine busy - * 26 GA engine busy - * 27 CBA 2D engine busy - * 31 2D engine busy or 3D engine busy or FIFO not empty or CP busy or - * command stream queue not empty or Ring Buffer not empty - */ -#define RADEON_RBBM_STATUS 0x0e40 -/* Same as the previous RADEON_RBBM_STATUS; this is a mirror of that register. */ -/* #define RADEON_RBBM_STATUS 0x1740 */ -/* bits 6:0 are dword slots available in the cmd fifo */ -# define RADEON_RBBM_FIFOCNT_MASK 0x007f -# define RADEON_HIRQ_ON_RBB (1 << 8) -# define RADEON_CPRQ_ON_RBB (1 << 9) -# define RADEON_CFRQ_ON_RBB (1 << 10) -# define RADEON_HIRQ_IN_RTBUF (1 << 11) -# define RADEON_CPRQ_IN_RTBUF (1 << 12) -# define RADEON_CFRQ_IN_RTBUF (1 << 13) -# define RADEON_PIPE_BUSY (1 << 14) -# define RADEON_ENG_EV_BUSY (1 << 15) -# define RADEON_CP_CMDSTRM_BUSY (1 << 16) -# define RADEON_E2_BUSY (1 << 17) -# define RADEON_RB2D_BUSY (1 << 18) -# define RADEON_RB3D_BUSY (1 << 19) /* not used on r300 */ -# define RADEON_VAP_BUSY (1 << 20) -# define RADEON_RE_BUSY (1 << 21) /* not used on r300 */ -# define RADEON_TAM_BUSY (1 << 22) /* not used on r300 */ -# define RADEON_TDM_BUSY (1 << 23) /* not used on r300 */ -# define RADEON_PB_BUSY (1 << 24) /* not used on r300 */ -# define RADEON_TIM_BUSY (1 << 25) /* not used on r300 */ -# define RADEON_GA_BUSY (1 << 26) -# define RADEON_CBA2D_BUSY (1 << 27) -# define RADEON_RBBM_ACTIVE (1 << 31) -#define RADEON_RE_LINE_PATTERN 0x1cd0 -#define RADEON_RE_MISC 0x26c4 -#define RADEON_RE_TOP_LEFT 0x26c0 -#define RADEON_RE_WIDTH_HEIGHT 0x1c44 -#define RADEON_RE_STIPPLE_ADDR 0x1cc8 -#define RADEON_RE_STIPPLE_DATA 0x1ccc - -#define RADEON_SCISSOR_TL_0 0x1cd8 -#define RADEON_SCISSOR_BR_0 0x1cdc -#define RADEON_SCISSOR_TL_1 0x1ce0 -#define RADEON_SCISSOR_BR_1 0x1ce4 -#define RADEON_SCISSOR_TL_2 0x1ce8 -#define RADEON_SCISSOR_BR_2 0x1cec -#define RADEON_SE_COORD_FMT 0x1c50 -#define RADEON_SE_CNTL 0x1c4c -# define RADEON_FFACE_CULL_CW (0 << 0) -# define RADEON_BFACE_SOLID (3 << 1) -# define RADEON_FFACE_SOLID (3 << 3) -# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) -# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) -# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) -# define RADEON_ALPHA_SHADE_FLAT (1 << 10) -# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) -# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) -# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) -# define RADEON_FOG_SHADE_FLAT (1 << 14) -# define RADEON_FOG_SHADE_GOURAUD (2 << 14) -# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) -# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) -# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) -# define RADEON_ROUND_MODE_TRUNC (0 << 28) -# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) -#define RADEON_SE_CNTL_STATUS 0x2140 -#define RADEON_SE_LINE_WIDTH 0x1db8 -#define RADEON_SE_VPORT_XSCALE 0x1d98 -#define RADEON_SE_ZBIAS_FACTOR 0x1db0 -#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 -#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 -#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200 -# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16 -# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28 -#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204 -#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208 -# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16 -#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C -#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8 -#define RADEON_SURFACE_ACCESS_CLR 0x0bfc -#define RADEON_SURFACE_CNTL 0x0b00 -# define RADEON_SURF_TRANSLATION_DIS (1 << 8) -# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20) -# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20) -# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20) -# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20) -# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22) -# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22) -# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22) -# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22) -#define RADEON_SURFACE0_INFO 0x0b0c -# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0) -# define RADEON_SURF_TILE_MODE_MASK (3 << 16) -# define RADEON_SURF_TILE_MODE_MACRO (0 << 16) -# define RADEON_SURF_TILE_MODE_MICRO (1 << 16) -# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16) -# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16) -#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 -#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 -# define RADEON_SURF_ADDRESS_FIXED_MASK (0x3ff << 0) -#define RADEON_SURFACE1_INFO 0x0b1c -#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 -#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 -#define RADEON_SURFACE2_INFO 0x0b2c -#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 -#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 -#define RADEON_SURFACE3_INFO 0x0b3c -#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 -#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 -#define RADEON_SURFACE4_INFO 0x0b4c -#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 -#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 -#define RADEON_SURFACE5_INFO 0x0b5c -#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 -#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 -#define RADEON_SURFACE6_INFO 0x0b6c -#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 -#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 -#define RADEON_SURFACE7_INFO 0x0b7c -#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 -#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 -#define RADEON_SW_SEMAPHORE 0x013c - -#define RADEON_WAIT_UNTIL 0x1720 -# define RADEON_WAIT_CRTC_PFLIP (1 << 0) -# define RADEON_WAIT_2D_IDLE (1 << 14) -# define RADEON_WAIT_3D_IDLE (1 << 15) -# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) -# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) -# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) - -#define RADEON_RB3D_ZMASKOFFSET 0x3234 -#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c -# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) -# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) - -/* CP registers */ -#define RADEON_CP_ME_RAM_ADDR 0x07d4 -#define RADEON_CP_ME_RAM_RADDR 0x07d8 -#define RADEON_CP_ME_RAM_DATAH 0x07dc -#define RADEON_CP_ME_RAM_DATAL 0x07e0 - -#define RADEON_CP_RB_BASE 0x0700 -#define RADEON_CP_RB_CNTL 0x0704 -# define RADEON_BUF_SWAP_32BIT (2 << 16) -# define RADEON_RB_NO_UPDATE (1 << 27) -# define RADEON_RB_RPTR_WR_ENA (1 << 31) -#define RADEON_CP_RB_RPTR_ADDR 0x070c -#define RADEON_CP_RB_RPTR 0x0710 -#define RADEON_CP_RB_WPTR 0x0714 - -#define RADEON_CP_RB_WPTR_DELAY 0x0718 -# define RADEON_PRE_WRITE_TIMER_SHIFT 0 -# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 - -#define RADEON_CP_IB_BASE 0x0738 - -#define RADEON_CP_CSQ_CNTL 0x0740 -# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) -# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) -# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) -# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) -# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) -# define RADEON_CSQ_PRIBM_INDBM (4 << 28) -# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) - -#define R300_CP_RESYNC_ADDR 0x0778 -#define R300_CP_RESYNC_DATA 0x077c - -#define RADEON_AIC_CNTL 0x01d0 -# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -# define RS400_MSI_REARM (1 << 3) -#define RADEON_AIC_STAT 0x01d4 -#define RADEON_AIC_PT_BASE 0x01d8 -#define RADEON_AIC_LO_ADDR 0x01dc -#define RADEON_AIC_HI_ADDR 0x01e0 -#define RADEON_AIC_TLB_ADDR 0x01e4 -#define RADEON_AIC_TLB_DATA 0x01e8 - -/* CP command packets */ -#define RADEON_CP_PACKET0 0x00000000 -# define RADEON_ONE_REG_WR (1 << 15) -#define RADEON_CP_PACKET1 0x40000000 -#define RADEON_CP_PACKET2 0x80000000 -#define RADEON_CP_PACKET3 0xC0000000 -# define RADEON_CP_NOP 0x00001000 -# define RADEON_CP_NEXT_CHAR 0x00001900 -# define RADEON_CP_PLY_NEXTSCAN 0x00001D00 -# define RADEON_CP_SET_SCISSORS 0x00001E00 - /* GEN_INDX_PRIM is unsupported starting with R300 */ -# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 -# define RADEON_WAIT_FOR_IDLE 0x00002600 -# define RADEON_3D_DRAW_VBUF 0x00002800 -# define RADEON_3D_DRAW_IMMD 0x00002900 -# define RADEON_3D_DRAW_INDX 0x00002A00 -# define RADEON_CP_LOAD_PALETTE 0x00002C00 -# define RADEON_3D_LOAD_VBPNTR 0x00002F00 -# define RADEON_MPEG_IDCT_MACROBLOCK 0x00003000 -# define RADEON_MPEG_IDCT_MACROBLOCK_REV 0x00003100 -# define RADEON_3D_CLEAR_ZMASK 0x00003200 -# define RADEON_CP_INDX_BUFFER 0x00003300 -# define RADEON_CP_3D_DRAW_VBUF_2 0x00003400 -# define RADEON_CP_3D_DRAW_IMMD_2 0x00003500 -# define RADEON_CP_3D_DRAW_INDX_2 0x00003600 -# define RADEON_3D_CLEAR_HIZ 0x00003700 -# define RADEON_CP_3D_CLEAR_CMASK 0x00003802 -# define RADEON_CNTL_HOSTDATA_BLT 0x00009400 -# define RADEON_CNTL_PAINT_MULTI 0x00009A00 -# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 -# define RADEON_CNTL_SET_SCISSORS 0xC0001E00 - -# define R600_IT_INDIRECT_BUFFER_END 0x00001700 -# define R600_IT_SET_PREDICATION 0x00002000 -# define R600_IT_REG_RMW 0x00002100 -# define R600_IT_COND_EXEC 0x00002200 -# define R600_IT_PRED_EXEC 0x00002300 -# define R600_IT_START_3D_CMDBUF 0x00002400 -# define R600_IT_DRAW_INDEX_2 0x00002700 -# define R600_IT_CONTEXT_CONTROL 0x00002800 -# define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 -# define R600_IT_INDEX_TYPE 0x00002A00 -# define R600_IT_DRAW_INDEX 0x00002B00 -# define R600_IT_DRAW_INDEX_AUTO 0x00002D00 -# define R600_IT_DRAW_INDEX_IMMD 0x00002E00 -# define R600_IT_NUM_INSTANCES 0x00002F00 -# define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 -# define R600_IT_INDIRECT_BUFFER_MP 0x00003800 -# define R600_IT_MEM_SEMAPHORE 0x00003900 -# define R600_IT_MPEG_INDEX 0x00003A00 -# define R600_IT_WAIT_REG_MEM 0x00003C00 -# define R600_IT_MEM_WRITE 0x00003D00 -# define R600_IT_INDIRECT_BUFFER 0x00003200 -# define R600_IT_SURFACE_SYNC 0x00004300 -# define R600_CB0_DEST_BASE_ENA (1 << 6) -# define R600_TC_ACTION_ENA (1 << 23) -# define R600_VC_ACTION_ENA (1 << 24) -# define R600_CB_ACTION_ENA (1 << 25) -# define R600_DB_ACTION_ENA (1 << 26) -# define R600_SH_ACTION_ENA (1 << 27) -# define R600_SMX_ACTION_ENA (1 << 28) -# define R600_IT_ME_INITIALIZE 0x00004400 -# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -# define R600_IT_COND_WRITE 0x00004500 -# define R600_IT_EVENT_WRITE 0x00004600 -# define R600_IT_EVENT_WRITE_EOP 0x00004700 -# define R600_IT_ONE_REG_WRITE 0x00005700 -# define R600_IT_SET_CONFIG_REG 0x00006800 -# define R600_SET_CONFIG_REG_OFFSET 0x00008000 -# define R600_SET_CONFIG_REG_END 0x0000ac00 -# define R600_IT_SET_CONTEXT_REG 0x00006900 -# define R600_SET_CONTEXT_REG_OFFSET 0x00028000 -# define R600_SET_CONTEXT_REG_END 0x00029000 -# define R600_IT_SET_ALU_CONST 0x00006A00 -# define R600_SET_ALU_CONST_OFFSET 0x00030000 -# define R600_SET_ALU_CONST_END 0x00032000 -# define R600_IT_SET_BOOL_CONST 0x00006B00 -# define R600_SET_BOOL_CONST_OFFSET 0x0003e380 -# define R600_SET_BOOL_CONST_END 0x00040000 -# define R600_IT_SET_LOOP_CONST 0x00006C00 -# define R600_SET_LOOP_CONST_OFFSET 0x0003e200 -# define R600_SET_LOOP_CONST_END 0x0003e380 -# define R600_IT_SET_RESOURCE 0x00006D00 -# define R600_SET_RESOURCE_OFFSET 0x00038000 -# define R600_SET_RESOURCE_END 0x0003c000 -# define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 -# define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 -# define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 -# define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 -# define R600_IT_SET_SAMPLER 0x00006E00 -# define R600_SET_SAMPLER_OFFSET 0x0003c000 -# define R600_SET_SAMPLER_END 0x0003cff0 -# define R600_IT_SET_CTL_CONST 0x00006F00 -# define R600_SET_CTL_CONST_OFFSET 0x0003cff0 -# define R600_SET_CTL_CONST_END 0x0003e200 -# define R600_IT_SURFACE_BASE_UPDATE 0x00007300 - -#define RADEON_CP_PACKET_MASK 0xC0000000 -#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 -#define RADEON_CP_PACKET0_REG_MASK 0x000007ff -#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff -#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 - -#define RADEON_VTX_Z_PRESENT (1 << 31) -#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3) - -#define RADEON_PRIM_TYPE_NONE (0 << 0) -#define RADEON_PRIM_TYPE_POINT (1 << 0) -#define RADEON_PRIM_TYPE_LINE (2 << 0) -#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0) -#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0) -#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0) -#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0) -#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0) -#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0) -#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) -#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) -#define RADEON_PRIM_TYPE_MASK 0xf -#define RADEON_PRIM_WALK_IND (1 << 4) -#define RADEON_PRIM_WALK_LIST (2 << 4) -#define RADEON_PRIM_WALK_RING (3 << 4) -#define RADEON_COLOR_ORDER_BGRA (0 << 6) -#define RADEON_COLOR_ORDER_RGBA (1 << 6) -#define RADEON_MAOS_ENABLE (1 << 7) -#define RADEON_VTX_FMT_R128_MODE (0 << 8) -#define RADEON_VTX_FMT_RADEON_MODE (1 << 8) -#define RADEON_NUM_VERTICES_SHIFT 16 - -#define RADEON_COLOR_FORMAT_CI8 2 -#define RADEON_COLOR_FORMAT_ARGB1555 3 -#define RADEON_COLOR_FORMAT_RGB565 4 -#define RADEON_COLOR_FORMAT_ARGB8888 6 -#define RADEON_COLOR_FORMAT_RGB332 7 -#define RADEON_COLOR_FORMAT_RGB8 9 -#define RADEON_COLOR_FORMAT_ARGB4444 15 - -#define RADEON_TXFORMAT_I8 0 -#define RADEON_TXFORMAT_AI88 1 -#define RADEON_TXFORMAT_RGB332 2 -#define RADEON_TXFORMAT_ARGB1555 3 -#define RADEON_TXFORMAT_RGB565 4 -#define RADEON_TXFORMAT_ARGB4444 5 -#define RADEON_TXFORMAT_ARGB8888 6 -#define RADEON_TXFORMAT_RGBA8888 7 -#define RADEON_TXFORMAT_Y8 8 -#define RADEON_TXFORMAT_VYUY422 10 -#define RADEON_TXFORMAT_YVYU422 11 -#define RADEON_TXFORMAT_DXT1 12 -#define RADEON_TXFORMAT_DXT23 14 -#define RADEON_TXFORMAT_DXT45 15 - -#define R200_PP_TXCBLEND_0 0x2f00 -#define R200_PP_TXCBLEND_1 0x2f10 -#define R200_PP_TXCBLEND_2 0x2f20 -#define R200_PP_TXCBLEND_3 0x2f30 -#define R200_PP_TXCBLEND_4 0x2f40 -#define R200_PP_TXCBLEND_5 0x2f50 -#define R200_PP_TXCBLEND_6 0x2f60 -#define R200_PP_TXCBLEND_7 0x2f70 -#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 -#define R200_PP_TFACTOR_0 0x2ee0 -#define R200_SE_VTX_FMT_0 0x2088 -#define R200_SE_VAP_CNTL 0x2080 -#define R200_SE_TCL_MATRIX_SEL_0 0x2230 -#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 -#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 -#define R200_PP_TXFILTER_5 0x2ca0 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFILTER_0 0x2c00 -#define R200_PP_TXOFFSET_5 0x2d78 -#define R200_PP_TXOFFSET_4 0x2d60 -#define R200_PP_TXOFFSET_3 0x2d48 -#define R200_PP_TXOFFSET_2 0x2d30 -#define R200_PP_TXOFFSET_1 0x2d18 -#define R200_PP_TXOFFSET_0 0x2d00 - -#define R200_PP_CUBIC_FACES_0 0x2c18 -#define R200_PP_CUBIC_FACES_1 0x2c38 -#define R200_PP_CUBIC_FACES_2 0x2c58 -#define R200_PP_CUBIC_FACES_3 0x2c78 -#define R200_PP_CUBIC_FACES_4 0x2c98 -#define R200_PP_CUBIC_FACES_5 0x2cb8 -#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 -#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c -#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 -#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c -#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 -#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c - -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_SE_VTE_CNTL 0x20b0 -#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 -#define R200_PP_TAM_DEBUG3 0x2d9c -#define R200_PP_CNTL_X 0x2cc4 -#define R200_SE_VAP_CNTL_STATUS 0x2140 -#define R200_RE_SCISSOR_TL_0 0x1cd8 -#define R200_RE_SCISSOR_TL_1 0x1ce0 -#define R200_RE_SCISSOR_TL_2 0x1ce8 -#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_SE_VTX_STATE_CNTL 0x2180 -#define R200_RE_POINTSIZE 0x2648 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 - -#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ -#define RADEON_PP_TEX_SIZE_1 0x1d0c -#define RADEON_PP_TEX_SIZE_2 0x1d14 - -#define RADEON_PP_CUBIC_FACES_0 0x1d24 -#define RADEON_PP_CUBIC_FACES_1 0x1d28 -#define RADEON_PP_CUBIC_FACES_2 0x1d2c -#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */ -#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 -#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 - -#define RADEON_SE_TCL_STATE_FLUSH 0x2284 - -#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 -#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 -#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012 -#define SE_VTE_CNTL__VTX_XY_FMT_MASK 0x00000100 -#define SE_VTE_CNTL__VTX_Z_FMT_MASK 0x00000200 -#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK 0x00000001 -#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK 0x00000002 -#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b -#define R200_3D_DRAW_IMMD_2 0xC0003500 -#define R200_SE_VTX_FMT_1 0x208c -#define R200_RE_CNTL 0x1c50 - -#define R200_RB3D_BLENDCOLOR 0x3218 - -#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 - -#define R200_PP_TRI_PERF 0x2cf8 - -#define R200_PP_AFS_0 0x2f80 -#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ - -#define R200_VAP_PVS_CNTL_1 0x22D0 - -#define RADEON_CRTC_CRNT_FRAME 0x0214 -#define RADEON_CRTC2_CRNT_FRAME 0x0314 - -#define R500_D1CRTC_STATUS 0x609c -#define R500_D2CRTC_STATUS 0x689c -#define R500_CRTC_V_BLANK (1<<0) - -#define R500_D1CRTC_FRAME_COUNT 0x60a4 -#define R500_D2CRTC_FRAME_COUNT 0x68a4 - -#define R500_D1MODE_V_COUNTER 0x6530 -#define R500_D2MODE_V_COUNTER 0x6d30 - -#define R500_D1MODE_VBLANK_STATUS 0x6534 -#define R500_D2MODE_VBLANK_STATUS 0x6d34 -#define R500_VBLANK_OCCURED (1<<0) -#define R500_VBLANK_ACK (1<<4) -#define R500_VBLANK_STAT (1<<12) -#define R500_VBLANK_INT (1<<16) - -#define R500_DxMODE_INT_MASK 0x6540 -#define R500_D1MODE_INT_MASK (1<<0) -#define R500_D2MODE_INT_MASK (1<<8) - -#define R500_DISP_INTERRUPT_STATUS 0x7edc -#define R500_D1_VBLANK_INTERRUPT (1 << 4) -#define R500_D2_VBLANK_INTERRUPT (1 << 5) - -/* R6xx/R7xx registers */ -#define R600_MC_VM_FB_LOCATION 0x2180 -#define R600_MC_VM_AGP_TOP 0x2184 -#define R600_MC_VM_AGP_BOT 0x2188 -#define R600_MC_VM_AGP_BASE 0x218c -#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 -#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 -#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 - -#define R700_MC_VM_FB_LOCATION 0x2024 -#define R700_MC_VM_AGP_TOP 0x2028 -#define R700_MC_VM_AGP_BOT 0x202c -#define R700_MC_VM_AGP_BASE 0x2030 -#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c - -#define R600_MCD_RD_A_CNTL 0x219c -#define R600_MCD_RD_B_CNTL 0x21a0 - -#define R600_MCD_WR_A_CNTL 0x21a4 -#define R600_MCD_WR_B_CNTL 0x21a8 - -#define R600_MCD_RD_SYS_CNTL 0x2200 -#define R600_MCD_WR_SYS_CNTL 0x2214 - -#define R600_MCD_RD_GFX_CNTL 0x21fc -#define R600_MCD_RD_HDP_CNTL 0x2204 -#define R600_MCD_RD_PDMA_CNTL 0x2208 -#define R600_MCD_RD_SEM_CNTL 0x220c -#define R600_MCD_WR_GFX_CNTL 0x2210 -#define R600_MCD_WR_HDP_CNTL 0x2218 -#define R600_MCD_WR_PDMA_CNTL 0x221c -#define R600_MCD_WR_SEM_CNTL 0x2220 - -# define R600_MCD_L1_TLB (1 << 0) -# define R600_MCD_L1_FRAG_PROC (1 << 1) -# define R600_MCD_L1_STRICT_ORDERING (1 << 2) - -# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) -# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) - -# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) -# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) - -# define R600_MCD_SEMAPHORE_MODE (1 << 10) -# define R600_MCD_WAIT_L2_QUERY (1 << 11) -# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12) -# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) - -#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654 -#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658 -#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c - -#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234 -#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238 -#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c -#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240 - -# define R700_ENABLE_L1_TLB (1 << 0) -# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15) -# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18) - -#define R700_MC_ARB_RAMCFG 0x2760 -# define R700_NOOFBANK_SHIFT 0 -# define R700_NOOFBANK_MASK 0x3 -# define R700_NOOFRANK_SHIFT 2 -# define R700_NOOFRANK_MASK 0x1 -# define R700_NOOFROWS_SHIFT 3 -# define R700_NOOFROWS_MASK 0x7 -# define R700_NOOFCOLS_SHIFT 6 -# define R700_NOOFCOLS_MASK 0x3 -# define R700_CHANSIZE_SHIFT 8 -# define R700_CHANSIZE_MASK 0x1 -# define R700_BURSTLENGTH_SHIFT 9 -# define R700_BURSTLENGTH_MASK 0x1 -#define R600_RAMCFG 0x2408 -# define R600_NOOFBANK_SHIFT 0 -# define R600_NOOFBANK_MASK 0x1 -# define R600_NOOFRANK_SHIFT 1 -# define R600_NOOFRANK_MASK 0x1 -# define R600_NOOFROWS_SHIFT 2 -# define R600_NOOFROWS_MASK 0x7 -# define R600_NOOFCOLS_SHIFT 5 -# define R600_NOOFCOLS_MASK 0x3 -# define R600_CHANSIZE_SHIFT 7 -# define R600_CHANSIZE_MASK 0x1 -# define R600_BURSTLENGTH_SHIFT 8 -# define R600_BURSTLENGTH_MASK 0x1 - -#define R600_VM_L2_CNTL 0x1400 -# define R600_VM_L2_CACHE_EN (1 << 0) -# define R600_VM_L2_FRAG_PROC (1 << 1) -# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9) -# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13) -# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14) - -#define R600_VM_L2_CNTL2 0x1404 -# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0) -# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1) -#define R600_VM_L2_CNTL3 0x1408 -# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0) -# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5) -# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10) -# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0) -# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6) - -#define R600_VM_L2_STATUS 0x140c - -#define R600_VM_CONTEXT0_CNTL 0x1410 -# define R600_VM_ENABLE_CONTEXT (1 << 0) -# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1) - -#define R600_VM_CONTEXT0_CNTL2 0x1430 -#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 -#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0 -#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 -#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 -#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4 - -#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c -#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c -#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c - -#define R600_HDP_HOST_PATH_CNTL 0x2c00 - -#define R600_GRBM_CNTL 0x8000 -# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0) - -#define R600_GRBM_STATUS 0x8010 -# define R600_CMDFIFO_AVAIL_MASK 0x1f -# define R700_CMDFIFO_AVAIL_MASK 0xf -# define R600_GUI_ACTIVE (1 << 31) -#define R600_GRBM_STATUS2 0x8014 -#define R600_GRBM_SOFT_RESET 0x8020 -# define R600_SOFT_RESET_CP (1 << 0) -#define R600_WAIT_UNTIL 0x8040 - -#define R600_CP_SEM_WAIT_TIMER 0x85bc -#define R600_CP_ME_CNTL 0x86d8 -# define R600_CP_ME_HALT (1 << 28) -#define R600_CP_QUEUE_THRESHOLDS 0x8760 -# define R600_ROQ_IB1_START(x) ((x) << 0) -# define R600_ROQ_IB2_START(x) ((x) << 8) -#define R600_CP_MEQ_THRESHOLDS 0x8764 -# define R700_STQ_SPLIT(x) ((x) << 0) -# define R600_MEQ_END(x) ((x) << 16) -# define R600_ROQ_END(x) ((x) << 24) -#define R600_CP_PERFMON_CNTL 0x87fc -#define R600_CP_RB_BASE 0xc100 -#define R600_CP_RB_CNTL 0xc104 -# define R600_RB_BUFSZ(x) ((x) << 0) -# define R600_RB_BLKSZ(x) ((x) << 8) -# define R600_BUF_SWAP_32BIT (2 << 16) -# define R600_RB_NO_UPDATE (1 << 27) -# define R600_RB_RPTR_WR_ENA (1 << 31) -#define R600_CP_RB_RPTR_WR 0xc108 -#define R600_CP_RB_RPTR_ADDR 0xc10c -#define R600_CP_RB_RPTR_ADDR_HI 0xc110 -#define R600_CP_RB_WPTR 0xc114 -#define R600_CP_RB_WPTR_ADDR 0xc118 -#define R600_CP_RB_WPTR_ADDR_HI 0xc11c -#define R600_CP_RB_RPTR 0x8700 -#define R600_CP_RB_WPTR_DELAY 0x8704 -#define R600_CP_PFP_UCODE_ADDR 0xc150 -#define R600_CP_PFP_UCODE_DATA 0xc154 -#define R600_CP_ME_RAM_RADDR 0xc158 -#define R600_CP_ME_RAM_WADDR 0xc15c -#define R600_CP_ME_RAM_DATA 0xc160 -#define R600_CP_DEBUG 0xc1fc - -#define R600_PA_CL_ENHANCE 0x8a14 -# define R600_CLIP_VTX_REORDER_ENA (1 << 0) -# define R600_NUM_CLIP_SEQ(x) ((x) << 1) -#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10 -#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20 -#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24 -# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) -#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40 -#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44 -#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48 -#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c -# define R600_S0_X(x) ((x) << 0) -# define R600_S0_Y(x) ((x) << 4) -# define R600_S1_X(x) ((x) << 8) -# define R600_S1_Y(x) ((x) << 12) -# define R600_S2_X(x) ((x) << 16) -# define R600_S2_Y(x) ((x) << 20) -# define R600_S3_X(x) ((x) << 24) -# define R600_S3_Y(x) ((x) << 28) -# define R600_S4_X(x) ((x) << 0) -# define R600_S4_Y(x) ((x) << 4) -# define R600_S5_X(x) ((x) << 8) -# define R600_S5_Y(x) ((x) << 12) -# define R600_S6_X(x) ((x) << 16) -# define R600_S6_Y(x) ((x) << 20) -# define R600_S7_X(x) ((x) << 24) -# define R600_S7_Y(x) ((x) << 28) -#define R600_PA_SC_FIFO_SIZE 0x8bd0 -# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0) -# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8) -# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16) -#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc -# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0) -# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) -#define R600_PA_SC_ENHANCE 0x8bf0 -# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) -#define R600_PA_SC_CLIPRECT_RULE 0x2820c -#define R700_PA_SC_EDGERULE 0x28230 -#define R600_PA_SC_LINE_STIPPLE 0x28a0c -#define R600_PA_SC_MODE_CNTL 0x28a4c -#define R600_PA_SC_AA_CONFIG 0x28c04 - -#define R600_SX_EXPORT_BUFFER_SIZES 0x900c -# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0) -# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8) -# define R600_SMX_BUFFER_SIZE(x) ((x) << 16) -#define R600_SX_DEBUG_1 0x9054 -# define R600_SMX_EVENT_RELEASE (1 << 0) -# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16) -#define R700_SX_DEBUG_1 0x9058 -# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16) -#define R600_SX_MISC 0x28350 - -#define R600_DB_DEBUG 0x9830 -# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) -#define R600_DB_WATERMARKS 0x9838 -# define R600_DEPTH_FREE(x) ((x) << 0) -# define R600_DEPTH_FLUSH(x) ((x) << 5) -# define R600_DEPTH_PENDING_FREE(x) ((x) << 15) -# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20) -#define R700_DB_DEBUG3 0x98b0 -# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11) -#define RV700_DB_DEBUG4 0x9b8c -# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) - -#define R600_VGT_CACHE_INVALIDATION 0x88c4 -# define R600_CACHE_INVALIDATION(x) ((x) << 0) -# define R600_VC_ONLY 0 -# define R600_TC_ONLY 1 -# define R600_VC_AND_TC 2 -# define R700_AUTO_INVLD_EN(x) ((x) << 6) -# define R700_NO_AUTO 0 -# define R700_ES_AUTO 1 -# define R700_GS_AUTO 2 -# define R700_ES_AND_GS_AUTO 3 -#define R600_VGT_GS_PER_ES 0x88c8 -#define R600_VGT_ES_PER_GS 0x88cc -#define R600_VGT_GS_PER_VS 0x88e8 -#define R600_VGT_GS_VERTEX_REUSE 0x88d4 -#define R600_VGT_NUM_INSTANCES 0x8974 -#define R600_VGT_STRMOUT_EN 0x28ab0 -#define R600_VGT_EVENT_INITIATOR 0x28a90 -# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) -#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58 -# define R600_VTX_REUSE_DEPTH_MASK 0xff -#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c -# define R600_DEALLOC_DIST_MASK 0x7f - -#define R600_CB_COLOR0_BASE 0x28040 -#define R600_CB_COLOR1_BASE 0x28044 -#define R600_CB_COLOR2_BASE 0x28048 -#define R600_CB_COLOR3_BASE 0x2804c -#define R600_CB_COLOR4_BASE 0x28050 -#define R600_CB_COLOR5_BASE 0x28054 -#define R600_CB_COLOR6_BASE 0x28058 -#define R600_CB_COLOR7_BASE 0x2805c -#define R600_CB_COLOR7_FRAG 0x280fc - -#define R600_CB_COLOR0_SIZE 0x28060 -#define R600_CB_COLOR0_VIEW 0x28080 -#define R600_CB_COLOR0_INFO 0x280a0 -#define R600_CB_COLOR0_TILE 0x280c0 -#define R600_CB_COLOR0_FRAG 0x280e0 -#define R600_CB_COLOR0_MASK 0x28100 - -#define AVIVO_D1MODE_VLINE_START_END 0x6538 -#define AVIVO_D2MODE_VLINE_START_END 0x6d38 -#define R600_CP_COHER_BASE 0x85f8 -#define R600_DB_DEPTH_BASE 0x2800c -#define R600_SQ_PGM_START_FS 0x28894 -#define R600_SQ_PGM_START_ES 0x28880 -#define R600_SQ_PGM_START_VS 0x28858 -#define R600_SQ_PGM_RESOURCES_VS 0x28868 -#define R600_SQ_PGM_CF_OFFSET_VS 0x288d0 -#define R600_SQ_PGM_START_GS 0x2886c -#define R600_SQ_PGM_START_PS 0x28840 -#define R600_SQ_PGM_RESOURCES_PS 0x28850 -#define R600_SQ_PGM_EXPORTS_PS 0x28854 -#define R600_SQ_PGM_CF_OFFSET_PS 0x288cc -#define R600_VGT_DMA_BASE 0x287e8 -#define R600_VGT_DMA_BASE_HI 0x287e4 -#define R600_VGT_STRMOUT_BASE_OFFSET_0 0x28b10 -#define R600_VGT_STRMOUT_BASE_OFFSET_1 0x28b14 -#define R600_VGT_STRMOUT_BASE_OFFSET_2 0x28b18 -#define R600_VGT_STRMOUT_BASE_OFFSET_3 0x28b1c -#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0 0x28b44 -#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1 0x28b48 -#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2 0x28b4c -#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3 0x28b50 -#define R600_VGT_STRMOUT_BUFFER_BASE_0 0x28ad8 -#define R600_VGT_STRMOUT_BUFFER_BASE_1 0x28ae8 -#define R600_VGT_STRMOUT_BUFFER_BASE_2 0x28af8 -#define R600_VGT_STRMOUT_BUFFER_BASE_3 0x28b08 -#define R600_VGT_STRMOUT_BUFFER_OFFSET_0 0x28adc -#define R600_VGT_STRMOUT_BUFFER_OFFSET_1 0x28aec -#define R600_VGT_STRMOUT_BUFFER_OFFSET_2 0x28afc -#define R600_VGT_STRMOUT_BUFFER_OFFSET_3 0x28b0c - -#define R600_VGT_PRIMITIVE_TYPE 0x8958 - -#define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030 -#define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240 -#define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204 - -#define R600_TC_CNTL 0x9608 -# define R600_TC_L2_SIZE(x) ((x) << 5) -# define R600_L2_DISABLE_LATE_HIT (1 << 9) - -#define R600_ARB_POP 0x2418 -# define R600_ENABLE_TC128 (1 << 30) -#define R600_ARB_GDEC_RD_CNTL 0x246c - -#define R600_TA_CNTL_AUX 0x9508 -# define R600_DISABLE_CUBE_WRAP (1 << 0) -# define R600_DISABLE_CUBE_ANISO (1 << 1) -# define R700_GETLOD_SELECT(x) ((x) << 2) -# define R600_SYNC_GRADIENT (1 << 24) -# define R600_SYNC_WALKER (1 << 25) -# define R600_SYNC_ALIGNER (1 << 26) -# define R600_BILINEAR_PRECISION_6_BIT (0 << 31) -# define R600_BILINEAR_PRECISION_8_BIT (1 << 31) - -#define R700_TCP_CNTL 0x9610 - -#define R600_SMX_DC_CTL0 0xa020 -# define R700_USE_HASH_FUNCTION (1 << 0) -# define R700_CACHE_DEPTH(x) ((x) << 1) -# define R700_FLUSH_ALL_ON_EVENT (1 << 10) -# define R700_STALL_ON_EVENT (1 << 11) -#define R700_SMX_EVENT_CTL 0xa02c -# define R700_ES_FLUSH_CTL(x) ((x) << 0) -# define R700_GS_FLUSH_CTL(x) ((x) << 3) -# define R700_ACK_FLUSH_CTL(x) ((x) << 6) -# define R700_SYNC_FLUSH_CTL (1 << 8) - -#define R600_SQ_CONFIG 0x8c00 -# define R600_VC_ENABLE (1 << 0) -# define R600_EXPORT_SRC_C (1 << 1) -# define R600_DX9_CONSTS (1 << 2) -# define R600_ALU_INST_PREFER_VECTOR (1 << 3) -# define R600_DX10_CLAMP (1 << 4) -# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8) -# define R600_PS_PRIO(x) ((x) << 24) -# define R600_VS_PRIO(x) ((x) << 26) -# define R600_GS_PRIO(x) ((x) << 28) -# define R600_ES_PRIO(x) ((x) << 30) -#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04 -# define R600_NUM_PS_GPRS(x) ((x) << 0) -# define R600_NUM_VS_GPRS(x) ((x) << 16) -# define R700_DYN_GPR_ENABLE (1 << 27) -# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08 -# define R600_NUM_GS_GPRS(x) ((x) << 0) -# define R600_NUM_ES_GPRS(x) ((x) << 16) -#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c -# define R600_NUM_PS_THREADS(x) ((x) << 0) -# define R600_NUM_VS_THREADS(x) ((x) << 8) -# define R600_NUM_GS_THREADS(x) ((x) << 16) -# define R600_NUM_ES_THREADS(x) ((x) << 24) -#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10 -# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0) -# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16) -#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14 -# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0) -# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16) -#define R600_SQ_MS_FIFO_SIZES 0x8cf0 -# define R600_CACHE_FIFO_SIZE(x) ((x) << 0) -# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8) -# define R600_DONE_FIFO_HIWATER(x) ((x) << 16) -# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0 -# define R700_SIMDA_RING0(x) ((x) << 0) -# define R700_SIMDA_RING1(x) ((x) << 8) -# define R700_SIMDB_RING0(x) ((x) << 16) -# define R700_SIMDB_RING1(x) ((x) << 24) -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8 -#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc - -#define R600_SPI_PS_IN_CONTROL_0 0x286cc -# define R600_NUM_INTERP(x) ((x) << 0) -# define R600_POSITION_ENA (1 << 8) -# define R600_POSITION_CENTROID (1 << 9) -# define R600_POSITION_ADDR(x) ((x) << 10) -# define R600_PARAM_GEN(x) ((x) << 15) -# define R600_PARAM_GEN_ADDR(x) ((x) << 19) -# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26) -# define R600_PERSP_GRADIENT_ENA (1 << 28) -# define R600_LINEAR_GRADIENT_ENA (1 << 29) -# define R600_POSITION_SAMPLE (1 << 30) -# define R600_BARYC_AT_SAMPLE_ENA (1 << 31) -#define R600_SPI_PS_IN_CONTROL_1 0x286d0 -# define R600_GEN_INDEX_PIX (1 << 0) -# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1) -# define R600_FRONT_FACE_ENA (1 << 8) -# define R600_FRONT_FACE_CHAN(x) ((x) << 9) -# define R600_FRONT_FACE_ALL_BITS (1 << 11) -# define R600_FRONT_FACE_ADDR(x) ((x) << 12) -# define R600_FOG_ADDR(x) ((x) << 17) -# define R600_FIXED_PT_POSITION_ENA (1 << 24) -# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25) -# define R700_POSITION_ULC (1 << 30) -#define R600_SPI_INPUT_Z 0x286d8 - -#define R600_SPI_CONFIG_CNTL 0x9100 -# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0) -# define R600_DISABLE_INTERP_1 (1 << 5) -#define R600_SPI_CONFIG_CNTL_1 0x913c -# define R600_VTX_DONE_DELAY(x) ((x) << 0) -# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4) - -#define R600_GB_TILING_CONFIG 0x98f0 -# define R600_PIPE_TILING(x) ((x) << 1) -# define R600_BANK_TILING(x) ((x) << 4) -# define R600_GROUP_SIZE(x) ((x) << 6) -# define R600_ROW_TILING(x) ((x) << 8) -# define R600_BANK_SWAPS(x) ((x) << 11) -# define R600_SAMPLE_SPLIT(x) ((x) << 14) -# define R600_BACKEND_MAP(x) ((x) << 16) -#define R600_DCP_TILING_CONFIG 0x6ca0 -#define R600_HDP_TILING_CONFIG 0x2f3c - -#define R600_CC_RB_BACKEND_DISABLE 0x98f4 -#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88 -# define R600_BACKEND_DISABLE(x) ((x) << 16) - -#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950 -#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954 -# define R600_INACTIVE_QD_PIPES(x) ((x) << 8) -# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8) -# define R600_INACTIVE_SIMDS(x) ((x) << 16) -# define R600_INACTIVE_SIMDS_MASK (0xff << 16) - -#define R700_CGTS_SYS_TCC_DISABLE 0x3f90 -#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94 -#define R700_CGTS_TCC_DISABLE 0x9148 -#define R700_CGTS_USER_TCC_DISABLE 0x914c - -/* Constants */ -#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ - -#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0 -#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1 -#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2 -#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 -#define RADEON_LAST_DISPATCH 1 - -#define R600_LAST_FRAME_REG R600_SCRATCH_REG0 -#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1 -#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2 -#define R600_LAST_SWI_REG R600_SCRATCH_REG3 - -#define RADEON_MAX_VB_AGE 0x7fffffff -#define RADEON_MAX_VB_VERTS (0xffff) - -#define RADEON_RING_HIGH_MARK 128 - -#define RADEON_PCIGART_TABLE_SIZE (32*1024) - -#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define RADEON_WRITE(reg, val) \ -do { \ - if (reg < 0x10000) { \ - DRM_WRITE32(dev_priv->mmio, (reg), (val)); \ - } else { \ - DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \ - DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \ - } \ -} while (0) -#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) -#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) - -#define RADEON_WRITE_PLL(addr, val) \ -do { \ - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ - RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ -} while (0) - -#define RADEON_WRITE_PCIE(addr, val) \ -do { \ - RADEON_WRITE8(RADEON_PCIE_INDEX, \ - ((addr) & 0xff)); \ - RADEON_WRITE(RADEON_PCIE_DATA, (val)); \ -} while (0) - -#define R500_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \ - RADEON_WRITE(R520_MC_IND_DATA, (val)); \ - RADEON_WRITE(R520_MC_IND_INDEX, 0); \ -} while (0) - -#define RS480_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(RS480_NB_MC_INDEX, \ - ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \ - RADEON_WRITE(RS480_NB_MC_DATA, (val)); \ - RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); \ -} while (0) - -#define RS690_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \ - RADEON_WRITE(RS690_MC_DATA, val); \ - RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ -} while (0) - -#define RS600_WRITE_MCIND(addr, val) \ -do { \ - RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \ - RADEON_WRITE(RS600_MC_DATA, val); \ -} while (0) - -#define IGP_WRITE_MCIND(addr, val) \ -do { \ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ - RS690_WRITE_MCIND(addr, val); \ - else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \ - RS600_WRITE_MCIND(addr, val); \ - else \ - RS480_WRITE_MCIND(addr, val); \ -} while (0) - -#define CP_PACKET0( reg, n ) \ - (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) -#define CP_PACKET0_TABLE( reg, n ) \ - (RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2)) -#define CP_PACKET1( reg0, reg1 ) \ - (RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2)) -#define CP_PACKET2() \ - (RADEON_CP_PACKET2) -#define CP_PACKET3( pkt, n ) \ - (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) - -/* ================================================================ - * Engine control helper macros - */ - -#define RADEON_WAIT_UNTIL_2D_IDLE() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ - RADEON_WAIT_HOST_IDLECLEAN) ); \ -} while (0) - -#define RADEON_WAIT_UNTIL_3D_IDLE() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ - RADEON_WAIT_HOST_IDLECLEAN) ); \ -} while (0) - -#define RADEON_WAIT_UNTIL_IDLE() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ - RADEON_WAIT_3D_IDLECLEAN | \ - RADEON_WAIT_HOST_IDLECLEAN) ); \ -} while (0) - -#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \ - OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ - OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \ -} while (0) - -#define RADEON_FLUSH_CACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH); \ - } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_RB3D_DC_FLUSH); \ - } \ -} while (0) - -#define RADEON_PURGE_CACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \ - } else { \ - OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); \ - } \ -} while (0) - -#define RADEON_FLUSH_ZCACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_ZC_FLUSH); \ - } else { \ - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_ZC_FLUSH); \ - } \ -} while (0) - -#define RADEON_PURGE_ZCACHE() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \ - OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \ - } else { \ - OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \ - OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \ - } \ -} while (0) - -/* ================================================================ - * Misc helper macros - */ - -/* Perfbox functionality only. - */ -#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \ - u32 head = GET_RING_HEAD( dev_priv ); \ - if (head == dev_priv->ring.tail) \ - dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \ - } \ -} while (0) - -#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ -do { \ - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \ - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \ - if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ - int __ret; \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \ - __ret = r600_do_cp_idle(dev_priv); \ - else \ - __ret = radeon_do_cp_idle(dev_priv); \ - if ( __ret ) return __ret; \ - sarea_priv->last_dispatch = 0; \ - radeon_freelist_reset( dev ); \ - } \ -} while (0) - -#define RADEON_DISPATCH_AGE( age ) do { \ - OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \ - OUT_RING( age ); \ -} while (0) - -#define RADEON_FRAME_AGE( age ) do { \ - OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \ - OUT_RING( age ); \ -} while (0) - -#define RADEON_CLEAR_AGE( age ) do { \ - OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \ - OUT_RING( age ); \ -} while (0) - -#define R600_DISPATCH_AGE(age) do { \ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ - OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ - OUT_RING(age); \ -} while (0) - -#define R600_FRAME_AGE(age) do { \ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ - OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ - OUT_RING(age); \ -} while (0) - -#define R600_CLEAR_AGE(age) do { \ - OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ - OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ - OUT_RING(age); \ -} while (0) - -/* ================================================================ - * Ring control - */ - -#define RADEON_VERBOSE 0 - -#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; - -#define RADEON_RING_ALIGN 16 - -#define BEGIN_RING( n ) do { \ - if ( RADEON_VERBOSE ) { \ - DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ - } \ - _align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN-1)); \ - _align_nr += n; \ - if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ - COMMIT_RING(); \ - radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ - } \ - _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ - ring = dev_priv->ring.start; \ - write = dev_priv->ring.tail; \ - mask = dev_priv->ring.tail_mask; \ -} while (0) - -#define ADVANCE_RING() do { \ - if ( RADEON_VERBOSE ) { \ - DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ - write, dev_priv->ring.tail ); \ - } \ - if (((dev_priv->ring.tail + _nr) & mask) != write) { \ - DRM_ERROR( \ - "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ - ((dev_priv->ring.tail + _nr) & mask), \ - write, __LINE__); \ - } else \ - dev_priv->ring.tail = write; \ -} while (0) - -extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); - -#define COMMIT_RING() do { \ - radeon_commit_ring(dev_priv); \ - } while(0) - -#define OUT_RING( x ) do { \ - if ( RADEON_VERBOSE ) { \ - DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ - (unsigned int)(x), write ); \ - } \ - ring[write++] = (x); \ - write &= mask; \ -} while (0) - -#define OUT_RING_REG( reg, val ) do { \ - OUT_RING( CP_PACKET0( reg, 0 ) ); \ - OUT_RING( val ); \ -} while (0) - -#define OUT_RING_TABLE( tab, sz ) do { \ - int _size = (sz); \ - int *_tab = (int *)(tab); \ - \ - if (write + _size > mask) { \ - int _i = (mask+1) - write; \ - _size -= _i; \ - while (_i > 0 ) { \ - *(int *)(ring + write) = *_tab++; \ - write++; \ - _i--; \ - } \ - write = 0; \ - _tab += _i; \ - } \ - while (_size > 0) { \ - *(ring + write) = *_tab++; \ - write++; \ - _size--; \ - } \ - write &= mask; \ -} while (0) - -/** - * Copy given number of dwords from drm buffer to the ring buffer. - */ -#define OUT_RING_DRM_BUFFER(buf, sz) do { \ - int _size = (sz) * 4; \ - struct drm_buffer *_buf = (buf); \ - int _part_size; \ - while (_size > 0) { \ - _part_size = _size; \ - \ - if (write + _part_size/4 > mask) \ - _part_size = ((mask + 1) - write)*4; \ - \ - if (drm_buffer_index(_buf) + _part_size > PAGE_SIZE) \ - _part_size = PAGE_SIZE - drm_buffer_index(_buf);\ - \ - \ - \ - memcpy(ring + write, &_buf->data[drm_buffer_page(_buf)] \ - [drm_buffer_index(_buf)], _part_size); \ - \ - _size -= _part_size; \ - write = (write + _part_size/4) & mask; \ - drm_buffer_advance(_buf, _part_size); \ - } \ -} while (0) - - -#endif /* __RADEON_DRV_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_encoders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_encoders.c deleted file mode 100644 index 74670696..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_encoders.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" - -static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *clone_encoder; - uint32_t index_mask = 0; - int count; - - /* DIG routing gets problematic */ - if (rdev->family >= CHIP_R600) - return index_mask; - /* LVDS/TV are too wacky */ - if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) - return index_mask; - /* DVO requires 2x ppll clocks depending on tmds chip */ - if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) - return index_mask; - - count = -1; - list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { - struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); - count++; - - if (clone_encoder == encoder) - continue; - if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) - continue; - if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT) - continue; - else - index_mask |= (1 << count); - } - return index_mask; -} - -void radeon_setup_encoder_clones(struct drm_device *dev) -{ - struct drm_encoder *encoder; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - encoder->possible_clones = radeon_encoder_clones(encoder); - } -} - -uint32_t -radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac) -{ - struct radeon_device *rdev = dev->dev_private; - uint32_t ret = 0; - - switch (supported_device) { - case ATOM_DEVICE_CRT1_SUPPORT: - case ATOM_DEVICE_TV1_SUPPORT: - case ATOM_DEVICE_TV2_SUPPORT: - case ATOM_DEVICE_CRT2_SUPPORT: - case ATOM_DEVICE_CV_SUPPORT: - switch (dac) { - case 1: /* dac a */ - if ((rdev->family == CHIP_RS300) || - (rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) - ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; - else if (ASIC_IS_AVIVO(rdev)) - ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1; - else - ret = ENCODER_INTERNAL_DAC1_ENUM_ID1; - break; - case 2: /* dac b */ - if (ASIC_IS_AVIVO(rdev)) - ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1; - else { - /*if (rdev->family == CHIP_R200) - ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; - else*/ - ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; - } - break; - case 3: /* external dac */ - if (ASIC_IS_AVIVO(rdev)) - ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; - else - ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; - break; - } - break; - case ATOM_DEVICE_LCD1_SUPPORT: - if (ASIC_IS_AVIVO(rdev)) - ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; - else - ret = ENCODER_INTERNAL_LVDS_ENUM_ID1; - break; - case ATOM_DEVICE_DFP1_SUPPORT: - if ((rdev->family == CHIP_RS300) || - (rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) - ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; - else if (ASIC_IS_AVIVO(rdev)) - ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1; - else - ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1; - break; - case ATOM_DEVICE_LCD2_SUPPORT: - case ATOM_DEVICE_DFP2_SUPPORT: - if ((rdev->family == CHIP_RS600) || - (rdev->family == CHIP_RS690) || - (rdev->family == CHIP_RS740)) - ret = ENCODER_INTERNAL_DDI_ENUM_ID1; - else if (ASIC_IS_AVIVO(rdev)) - ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; - else - ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; - break; - case ATOM_DEVICE_DFP3_SUPPORT: - ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; - break; - } - - return ret; -} - -void -radeon_link_encoder_connector(struct drm_device *dev) -{ - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - - /* walk the list and link encoders to connectors */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->devices & radeon_connector->devices) - drm_mode_connector_attach_encoder(connector, encoder); - } - } -} - -void radeon_encoder_set_active_device(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->encoder == encoder) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; - DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n", - radeon_encoder->active_device, radeon_encoder->devices, - radeon_connector->devices, encoder->encoder_type); - } - } -} - -struct drm_connector * -radeon_get_connector_for_encoder(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - if (radeon_encoder->active_device & radeon_connector->devices) - return connector; - } - return NULL; -} - -struct drm_connector * -radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - radeon_connector = to_radeon_connector(connector); - if (radeon_encoder->devices & radeon_connector->devices) - return connector; - } - return NULL; -} - -struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *other_encoder; - struct radeon_encoder *other_radeon_encoder; - - if (radeon_encoder->is_ext_encoder) - return NULL; - - list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { - if (other_encoder == encoder) - continue; - other_radeon_encoder = to_radeon_encoder(other_encoder); - if (other_radeon_encoder->is_ext_encoder && - (radeon_encoder->devices & other_radeon_encoder->devices)) - return other_encoder; - } - return NULL; -} - -u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) -{ - struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder); - - if (other_encoder) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_TRAVIS: - case ENCODER_OBJECT_ID_NUTMEG: - return radeon_encoder->encoder_id; - default: - return ENCODER_OBJECT_ID_NONE; - } - } - return ENCODER_OBJECT_ID_NONE; -} - -void radeon_panel_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *adjusted_mode) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_display_mode *native_mode = &radeon_encoder->native_mode; - unsigned hblank = native_mode->htotal - native_mode->hdisplay; - unsigned vblank = native_mode->vtotal - native_mode->vdisplay; - unsigned hover = native_mode->hsync_start - native_mode->hdisplay; - unsigned vover = native_mode->vsync_start - native_mode->vdisplay; - unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start; - unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start; - - adjusted_mode->clock = native_mode->clock; - adjusted_mode->flags = native_mode->flags; - - if (ASIC_IS_AVIVO(rdev)) { - adjusted_mode->hdisplay = native_mode->hdisplay; - adjusted_mode->vdisplay = native_mode->vdisplay; - } - - adjusted_mode->htotal = native_mode->hdisplay + hblank; - adjusted_mode->hsync_start = native_mode->hdisplay + hover; - adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width; - - adjusted_mode->vtotal = native_mode->vdisplay + vblank; - adjusted_mode->vsync_start = native_mode->vdisplay + vover; - adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width; - - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); - - if (ASIC_IS_AVIVO(rdev)) { - adjusted_mode->crtc_hdisplay = native_mode->hdisplay; - adjusted_mode->crtc_vdisplay = native_mode->vdisplay; - } - - adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank; - adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover; - adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width; - - adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank; - adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover; - adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width; - -} - -bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, - u32 pixel_clock) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct drm_connector *connector; - struct radeon_connector *radeon_connector; - struct radeon_connector_atom_dig *dig_connector; - - connector = radeon_get_connector_for_encoder(encoder); - /* if we don't have an active device yet, just use one of - * the connectors tied to the encoder. - */ - if (!connector) - connector = radeon_get_connector_for_encoder_init(encoder); - radeon_connector = to_radeon_connector(connector); - - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_HDMIB: - if (radeon_connector->use_digital) { - /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { - if (pixel_clock > 340000) - return true; - else - return false; - } else { - if (pixel_clock > 165000) - return true; - else - return false; - } - } else - return false; - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_DisplayPort: - dig_connector = radeon_connector->con_priv; - if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || - (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) - return false; - else { - /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { - if (pixel_clock > 340000) - return true; - else - return false; - } else { - if (pixel_clock > 165000) - return true; - else - return false; - } - } - default: - return false; - } -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_family.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_family.h deleted file mode 100644 index d1fafeab..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_family.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ - -/* this file defines the CHIP_ and family flags used in the pciids, - * its is common between kms and non-kms because duplicating it and - * changing one place is fail. - */ -#ifndef RADEON_FAMILY_H -#define RADEON_FAMILY_H -/* - * Radeon chip families - */ -enum radeon_family { - CHIP_R100 = 0, - CHIP_RV100, - CHIP_RS100, - CHIP_RV200, - CHIP_RS200, - CHIP_R200, - CHIP_RV250, - CHIP_RS300, - CHIP_RV280, - CHIP_R300, - CHIP_R350, - CHIP_RV350, - CHIP_RV380, - CHIP_R420, - CHIP_R423, - CHIP_RV410, - CHIP_RS400, - CHIP_RS480, - CHIP_RS600, - CHIP_RS690, - CHIP_RS740, - CHIP_RV515, - CHIP_R520, - CHIP_RV530, - CHIP_RV560, - CHIP_RV570, - CHIP_R580, - CHIP_R600, - CHIP_RV610, - CHIP_RV630, - CHIP_RV670, - CHIP_RV620, - CHIP_RV635, - CHIP_RS780, - CHIP_RS880, - CHIP_RV770, - CHIP_RV730, - CHIP_RV710, - CHIP_RV740, - CHIP_CEDAR, - CHIP_REDWOOD, - CHIP_JUNIPER, - CHIP_CYPRESS, - CHIP_HEMLOCK, - CHIP_PALM, - CHIP_SUMO, - CHIP_SUMO2, - CHIP_BARTS, - CHIP_TURKS, - CHIP_CAICOS, - CHIP_CAYMAN, - CHIP_ARUBA, - CHIP_TAHITI, - CHIP_PITCAIRN, - CHIP_VERDE, - CHIP_LAST, -}; - -/* - * Chip flags - */ -enum radeon_chip_flags { - RADEON_FAMILY_MASK = 0x0000ffffUL, - RADEON_FLAGS_MASK = 0xffff0000UL, - RADEON_IS_MOBILITY = 0x00010000UL, - RADEON_IS_IGP = 0x00020000UL, - RADEON_SINGLE_CRTC = 0x00040000UL, - RADEON_IS_AGP = 0x00080000UL, - RADEON_HAS_HIERZ = 0x00100000UL, - RADEON_IS_PCIE = 0x00200000UL, - RADEON_NEW_MEMMAP = 0x00400000UL, - RADEON_IS_PCI = 0x00800000UL, - RADEON_IS_IGPGART = 0x01000000UL, -}; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fb.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fb.c deleted file mode 100644 index 5906914a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fb.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright © 2007 David Airlie - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * David Airlie - */ -#include -#include -#include - -#include "drmP.h" -#include "drm.h" -#include "drm_crtc.h" -#include "drm_crtc_helper.h" -#include "radeon_drm.h" -#include "radeon.h" - -#include "drm_fb_helper.h" - -#include - -/* object hierarchy - - this contains a helper + a radeon fb - the helper contains a pointer to radeon framebuffer baseclass. -*/ -struct radeon_fbdev { - struct drm_fb_helper helper; - struct radeon_framebuffer rfb; - struct list_head fbdev_list; - struct radeon_device *rdev; -}; - -static struct fb_ops radeonfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, -}; - - -int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) -{ - int aligned = width; - int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; - int pitch_mask = 0; - - switch (bpp / 8) { - case 1: - pitch_mask = align_large ? 255 : 127; - break; - case 2: - pitch_mask = align_large ? 127 : 31; - break; - case 3: - case 4: - pitch_mask = align_large ? 63 : 15; - break; - } - - aligned += pitch_mask; - aligned &= ~pitch_mask; - return aligned; -} - -static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) -{ - struct radeon_bo *rbo = gem_to_radeon_bo(gobj); - int ret; - - ret = radeon_bo_reserve(rbo, false); - if (likely(ret == 0)) { - radeon_bo_kunmap(rbo); - radeon_bo_unpin(rbo); - radeon_bo_unreserve(rbo); - } - drm_gem_object_unreference_unlocked(gobj); -} - -static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object **gobj_p) -{ - struct radeon_device *rdev = rfbdev->rdev; - struct drm_gem_object *gobj = NULL; - struct radeon_bo *rbo = NULL; - bool fb_tiled = false; /* useful for testing */ - u32 tiling_flags = 0; - int ret; - int aligned_size, size; - int height = mode_cmd->height; - u32 bpp, depth; - - drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); - - /* need to align pitch with crtc limits */ - mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp, - fb_tiled) * ((bpp + 1) / 8); - - if (rdev->family >= CHIP_R600) - height = ALIGN(mode_cmd->height, 8); - size = mode_cmd->pitches[0] * height; - aligned_size = ALIGN(size, PAGE_SIZE); - ret = radeon_gem_object_create(rdev, aligned_size, 0, - RADEON_GEM_DOMAIN_VRAM, - false, true, - &gobj); - if (ret) { - printk(KERN_ERR "failed to allocate framebuffer (%d)\n", - aligned_size); - return -ENOMEM; - } - rbo = gem_to_radeon_bo(gobj); - - if (fb_tiled) - tiling_flags = RADEON_TILING_MACRO; - -#ifdef __BIG_ENDIAN - switch (bpp) { - case 32: - tiling_flags |= RADEON_TILING_SWAP_32BIT; - break; - case 16: - tiling_flags |= RADEON_TILING_SWAP_16BIT; - default: - break; - } -#endif - - if (tiling_flags) { - ret = radeon_bo_set_tiling_flags(rbo, - tiling_flags | RADEON_TILING_SURFACE, - mode_cmd->pitches[0]); - if (ret) - dev_err(rdev->dev, "FB failed to set tiling flags\n"); - } - - - ret = radeon_bo_reserve(rbo, false); - if (unlikely(ret != 0)) - goto out_unref; - /* Only 27 bit offset for legacy CRTC */ - ret = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM, - ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, - NULL); - if (ret) { - radeon_bo_unreserve(rbo); - goto out_unref; - } - if (fb_tiled) - radeon_bo_check_tiling(rbo, 0, 0); - ret = radeon_bo_kmap(rbo, NULL); - radeon_bo_unreserve(rbo); - if (ret) { - goto out_unref; - } - - *gobj_p = gobj; - return 0; -out_unref: - radeonfb_destroy_pinned_object(gobj); - *gobj_p = NULL; - return ret; -} - -static int radeonfb_create(struct radeon_fbdev *rfbdev, - struct drm_fb_helper_surface_size *sizes) -{ - struct radeon_device *rdev = rfbdev->rdev; - struct fb_info *info; - struct drm_framebuffer *fb = NULL; - struct drm_mode_fb_cmd2 mode_cmd; - struct drm_gem_object *gobj = NULL; - struct radeon_bo *rbo = NULL; - struct device *device = &rdev->pdev->dev; - int ret; - unsigned long tmp; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - - /* avivo can't scanout real 24bpp */ - if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev)) - sizes->surface_bpp = 32; - - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); - if (ret) { - DRM_ERROR("failed to create fbcon object %d\n", ret); - return ret; - } - - rbo = gem_to_radeon_bo(gobj); - - /* okay we have an object now allocate the framebuffer */ - info = framebuffer_alloc(0, device); - if (info == NULL) { - ret = -ENOMEM; - goto out_unref; - } - - info->par = rfbdev; - - ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); - if (ret) { - DRM_ERROR("failed to initalise framebuffer %d\n", ret); - goto out_unref; - } - - fb = &rfbdev->rfb.base; - - /* setup helper */ - rfbdev->helper.fb = fb; - rfbdev->helper.fbdev = info; - - memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo)); - - strcpy(info->fix.id, "radeondrmfb"); - - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); - - info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; - info->fbops = &radeonfb_ops; - - tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start; - info->fix.smem_start = rdev->mc.aper_base + tmp; - info->fix.smem_len = radeon_bo_size(rbo); - info->screen_base = rbo->kptr; - info->screen_size = radeon_bo_size(rbo); - - drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height); - - /* setup aperture base/size for vesafb takeover */ - info->apertures = alloc_apertures(1); - if (!info->apertures) { - ret = -ENOMEM; - goto out_unref; - } - info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; - info->apertures->ranges[0].size = rdev->mc.aper_size; - - /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - - if (info->screen_base == NULL) { - ret = -ENOSPC; - goto out_unref; - } - - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) { - ret = -ENOMEM; - goto out_unref; - } - - DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); - DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); - DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo)); - DRM_INFO("fb depth is %d\n", fb->depth); - DRM_INFO(" pitch is %d\n", fb->pitches[0]); - - vga_switcheroo_client_fb_set(rdev->ddev->pdev, info); - return 0; - -out_unref: - if (rbo) { - - } - if (fb && ret) { - drm_gem_object_unreference(gobj); - drm_framebuffer_cleanup(fb); - kfree(fb); - } - return ret; -} - -static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct radeon_fbdev *rfbdev = (struct radeon_fbdev *)helper; - int new_fb = 0; - int ret; - - if (!helper->fb) { - ret = radeonfb_create(rfbdev, sizes); - if (ret) - return ret; - new_fb = 1; - } - return new_fb; -} - -static char *mode_option; -int radeon_parse_options(char *options) -{ - char *this_opt; - - if (!options || !*options) - return 0; - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) - continue; - mode_option = this_opt; - } - return 0; -} - -void radeon_fb_output_poll_changed(struct radeon_device *rdev) -{ - drm_fb_helper_hotplug_event(&rdev->mode_info.rfbdev->helper); -} - -static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) -{ - struct fb_info *info; - struct radeon_framebuffer *rfb = &rfbdev->rfb; - - if (rfbdev->helper.fbdev) { - info = rfbdev->helper.fbdev; - - unregister_framebuffer(info); - if (info->cmap.len) - fb_dealloc_cmap(&info->cmap); - framebuffer_release(info); - } - - if (rfb->obj) { - radeonfb_destroy_pinned_object(rfb->obj); - rfb->obj = NULL; - } - drm_fb_helper_fini(&rfbdev->helper); - drm_framebuffer_cleanup(&rfb->base); - - return 0; -} - -static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { - .gamma_set = radeon_crtc_fb_gamma_set, - .gamma_get = radeon_crtc_fb_gamma_get, - .fb_probe = radeon_fb_find_or_create_single, -}; - -int radeon_fbdev_init(struct radeon_device *rdev) -{ - struct radeon_fbdev *rfbdev; - int bpp_sel = 32; - int ret; - - /* select 8 bpp console on RN50 or 16MB cards */ - if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024)) - bpp_sel = 8; - - rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL); - if (!rfbdev) - return -ENOMEM; - - rfbdev->rdev = rdev; - rdev->mode_info.rfbdev = rfbdev; - rfbdev->helper.funcs = &radeon_fb_helper_funcs; - - ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, - rdev->num_crtc, - RADEONFB_CONN_LIMIT); - if (ret) { - kfree(rfbdev); - return ret; - } - - drm_fb_helper_single_add_all_connectors(&rfbdev->helper); - drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); - return 0; -} - -void radeon_fbdev_fini(struct radeon_device *rdev) -{ - if (!rdev->mode_info.rfbdev) - return; - - radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev); - kfree(rdev->mode_info.rfbdev); - rdev->mode_info.rfbdev = NULL; -} - -void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state) -{ - fb_set_suspend(rdev->mode_info.rfbdev->helper.fbdev, state); -} - -int radeon_fbdev_total_size(struct radeon_device *rdev) -{ - struct radeon_bo *robj; - int size = 0; - - robj = gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj); - size += radeon_bo_size(robj); - return size; -} - -bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj) -{ - if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj)) - return true; - return false; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fence.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fence.c deleted file mode 100644 index 4bd36a35..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_fence.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright 2009 Jerome Glisse. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: - * Jerome Glisse - * Dave Airlie - */ -#include -#include -#include -#include -#include -#include -#include "drmP.h" -#include "drm.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "radeon_trace.h" - -static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) -{ - if (rdev->wb.enabled) { - *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq); - } else { - WREG32(rdev->fence_drv[ring].scratch_reg, seq); - } -} - -static u32 radeon_fence_read(struct radeon_device *rdev, int ring) -{ - u32 seq = 0; - - if (rdev->wb.enabled) { - seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr); - } else { - seq = RREG32(rdev->fence_drv[ring].scratch_reg); - } - return seq; -} - -int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) -{ - unsigned long irq_flags; - - write_lock_irqsave(&rdev->fence_lock, irq_flags); - if (fence->emitted) { - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; - } - fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq); - if (!rdev->ring[fence->ring].ready) - /* FIXME: cp is not running assume everythings is done right - * away - */ - radeon_fence_write(rdev, fence->seq, fence->ring); - else - radeon_fence_ring_emit(rdev, fence->ring, fence); - - trace_radeon_fence_emit(rdev->ddev, fence->seq); - fence->emitted = true; - list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; -} - -static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring) -{ - struct radeon_fence *fence; - struct list_head *i, *n; - uint32_t seq; - bool wake = false; - unsigned long cjiffies; - - seq = radeon_fence_read(rdev, ring); - if (seq != rdev->fence_drv[ring].last_seq) { - rdev->fence_drv[ring].last_seq = seq; - rdev->fence_drv[ring].last_jiffies = jiffies; - rdev->fence_drv[ring].last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; - } else { - cjiffies = jiffies; - if (time_after(cjiffies, rdev->fence_drv[ring].last_jiffies)) { - cjiffies -= rdev->fence_drv[ring].last_jiffies; - if (time_after(rdev->fence_drv[ring].last_timeout, cjiffies)) { - /* update the timeout */ - rdev->fence_drv[ring].last_timeout -= cjiffies; - } else { - /* the 500ms timeout is elapsed we should test - * for GPU lockup - */ - rdev->fence_drv[ring].last_timeout = 1; - } - } else { - /* wrap around update last jiffies, we will just wait - * a little longer - */ - rdev->fence_drv[ring].last_jiffies = cjiffies; - } - return false; - } - n = NULL; - list_for_each(i, &rdev->fence_drv[ring].emitted) { - fence = list_entry(i, struct radeon_fence, list); - if (fence->seq == seq) { - n = i; - break; - } - } - /* all fence previous to this one are considered as signaled */ - if (n) { - i = n; - do { - n = i->prev; - list_move_tail(i, &rdev->fence_drv[ring].signaled); - fence = list_entry(i, struct radeon_fence, list); - fence->signaled = true; - i = n; - } while (i != &rdev->fence_drv[ring].emitted); - wake = true; - } - return wake; -} - -static void radeon_fence_destroy(struct kref *kref) -{ - unsigned long irq_flags; - struct radeon_fence *fence; - - fence = container_of(kref, struct radeon_fence, kref); - write_lock_irqsave(&fence->rdev->fence_lock, irq_flags); - list_del(&fence->list); - fence->emitted = false; - write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags); - if (fence->semaphore) - radeon_semaphore_free(fence->rdev, fence->semaphore); - kfree(fence); -} - -int radeon_fence_create(struct radeon_device *rdev, - struct radeon_fence **fence, - int ring) -{ - unsigned long irq_flags; - - *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); - if ((*fence) == NULL) { - return -ENOMEM; - } - kref_init(&((*fence)->kref)); - (*fence)->rdev = rdev; - (*fence)->emitted = false; - (*fence)->signaled = false; - (*fence)->seq = 0; - (*fence)->ring = ring; - (*fence)->semaphore = NULL; - INIT_LIST_HEAD(&(*fence)->list); - - write_lock_irqsave(&rdev->fence_lock, irq_flags); - list_add_tail(&(*fence)->list, &rdev->fence_drv[ring].created); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; -} - -bool radeon_fence_signaled(struct radeon_fence *fence) -{ - unsigned long irq_flags; - bool signaled = false; - - if (!fence) - return true; - - if (fence->rdev->gpu_lockup) - return true; - - write_lock_irqsave(&fence->rdev->fence_lock, irq_flags); - signaled = fence->signaled; - /* if we are shuting down report all fence as signaled */ - if (fence->rdev->shutdown) { - signaled = true; - } - if (!fence->emitted) { - WARN(1, "Querying an unemitted fence : %p !\n", fence); - signaled = true; - } - if (!signaled) { - radeon_fence_poll_locked(fence->rdev, fence->ring); - signaled = fence->signaled; - } - write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags); - return signaled; -} - -int radeon_fence_wait(struct radeon_fence *fence, bool intr) -{ - struct radeon_device *rdev; - unsigned long irq_flags, timeout; - u32 seq; - int r; - - if (fence == NULL) { - WARN(1, "Querying an invalid fence : %p !\n", fence); - return 0; - } - rdev = fence->rdev; - if (radeon_fence_signaled(fence)) { - return 0; - } - timeout = rdev->fence_drv[fence->ring].last_timeout; -retry: - /* save current sequence used to check for GPU lockup */ - seq = rdev->fence_drv[fence->ring].last_seq; - trace_radeon_fence_wait_begin(rdev->ddev, seq); - if (intr) { - radeon_irq_kms_sw_irq_get(rdev, fence->ring); - r = wait_event_interruptible_timeout(rdev->fence_drv[fence->ring].queue, - radeon_fence_signaled(fence), timeout); - radeon_irq_kms_sw_irq_put(rdev, fence->ring); - if (unlikely(r < 0)) { - return r; - } - } else { - radeon_irq_kms_sw_irq_get(rdev, fence->ring); - r = wait_event_timeout(rdev->fence_drv[fence->ring].queue, - radeon_fence_signaled(fence), timeout); - radeon_irq_kms_sw_irq_put(rdev, fence->ring); - } - trace_radeon_fence_wait_end(rdev->ddev, seq); - if (unlikely(!radeon_fence_signaled(fence))) { - /* we were interrupted for some reason and fence isn't - * isn't signaled yet, resume wait - */ - if (r) { - timeout = r; - goto retry; - } - /* don't protect read access to rdev->fence_drv[t].last_seq - * if we experiencing a lockup the value doesn't change - */ - if (seq == rdev->fence_drv[fence->ring].last_seq && - radeon_gpu_is_lockup(rdev, &rdev->ring[fence->ring])) { - /* good news we believe it's a lockup */ - printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", - fence->seq, seq); - /* FIXME: what should we do ? marking everyone - * as signaled for now - */ - rdev->gpu_lockup = true; - r = radeon_gpu_reset(rdev); - if (r) - return r; - radeon_fence_write(rdev, fence->seq, fence->ring); - rdev->gpu_lockup = false; - } - timeout = RADEON_FENCE_JIFFIES_TIMEOUT; - write_lock_irqsave(&rdev->fence_lock, irq_flags); - rdev->fence_drv[fence->ring].last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; - rdev->fence_drv[fence->ring].last_jiffies = jiffies; - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - goto retry; - } - return 0; -} - -int radeon_fence_wait_next(struct radeon_device *rdev, int ring) -{ - unsigned long irq_flags; - struct radeon_fence *fence; - int r; - - if (rdev->gpu_lockup) { - return 0; - } - write_lock_irqsave(&rdev->fence_lock, irq_flags); - if (list_empty(&rdev->fence_drv[ring].emitted)) { - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; - } - fence = list_entry(rdev->fence_drv[ring].emitted.next, - struct radeon_fence, list); - radeon_fence_ref(fence); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - r = radeon_fence_wait(fence, false); - radeon_fence_unref(&fence); - return r; -} - -int radeon_fence_wait_last(struct radeon_device *rdev, int ring) -{ - unsigned long irq_flags; - struct radeon_fence *fence; - int r; - - if (rdev->gpu_lockup) { - return 0; - } - write_lock_irqsave(&rdev->fence_lock, irq_flags); - if (list_empty(&rdev->fence_drv[ring].emitted)) { - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; - } - fence = list_entry(rdev->fence_drv[ring].emitted.prev, - struct radeon_fence, list); - radeon_fence_ref(fence); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - r = radeon_fence_wait(fence, false); - radeon_fence_unref(&fence); - return r; -} - -struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) -{ - kref_get(&fence->kref); - return fence; -} - -void radeon_fence_unref(struct radeon_fence **fence) -{ - struct radeon_fence *tmp = *fence; - - *fence = NULL; - if (tmp) { - kref_put(&tmp->kref, radeon_fence_destroy); - } -} - -void radeon_fence_process(struct radeon_device *rdev, int ring) -{ - unsigned long irq_flags; - bool wake; - - write_lock_irqsave(&rdev->fence_lock, irq_flags); - wake = radeon_fence_poll_locked(rdev, ring); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - if (wake) { - wake_up_all(&rdev->fence_drv[ring].queue); - } -} - -int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) -{ - unsigned long irq_flags; - int not_processed = 0; - - read_lock_irqsave(&rdev->fence_lock, irq_flags); - if (!rdev->fence_drv[ring].initialized) { - read_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; - } - - if (!list_empty(&rdev->fence_drv[ring].emitted)) { - struct list_head *ptr; - list_for_each(ptr, &rdev->fence_drv[ring].emitted) { - /* count up to 3, that's enought info */ - if (++not_processed >= 3) - break; - } - } - read_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return not_processed; -} - -int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) -{ - unsigned long irq_flags; - uint64_t index; - int r; - - write_lock_irqsave(&rdev->fence_lock, irq_flags); - radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); - if (rdev->wb.use_event) { - rdev->fence_drv[ring].scratch_reg = 0; - index = R600_WB_EVENT_OFFSET + ring * 4; - } else { - r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg); - if (r) { - dev_err(rdev->dev, "fence failed to get scratch register\n"); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return r; - } - index = RADEON_WB_SCRATCH_OFFSET + - rdev->fence_drv[ring].scratch_reg - - rdev->scratch.reg_base; - } - rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; - rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; - radeon_fence_write(rdev, atomic_read(&rdev->fence_drv[ring].seq), ring); - rdev->fence_drv[ring].initialized = true; - DRM_INFO("fence driver on ring %d use gpu addr 0x%08Lx and cpu addr 0x%p\n", - ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - return 0; -} - -static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) -{ - rdev->fence_drv[ring].scratch_reg = -1; - rdev->fence_drv[ring].cpu_addr = NULL; - rdev->fence_drv[ring].gpu_addr = 0; - atomic_set(&rdev->fence_drv[ring].seq, 0); - INIT_LIST_HEAD(&rdev->fence_drv[ring].created); - INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted); - INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled); - init_waitqueue_head(&rdev->fence_drv[ring].queue); - rdev->fence_drv[ring].initialized = false; -} - -int radeon_fence_driver_init(struct radeon_device *rdev) -{ - unsigned long irq_flags; - int ring; - - write_lock_irqsave(&rdev->fence_lock, irq_flags); - for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { - radeon_fence_driver_init_ring(rdev, ring); - } - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - if (radeon_debugfs_fence_init(rdev)) { - dev_err(rdev->dev, "fence debugfs file creation failed\n"); - } - return 0; -} - -void radeon_fence_driver_fini(struct radeon_device *rdev) -{ - unsigned long irq_flags; - int ring; - - for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { - if (!rdev->fence_drv[ring].initialized) - continue; - radeon_fence_wait_last(rdev, ring); - wake_up_all(&rdev->fence_drv[ring].queue); - write_lock_irqsave(&rdev->fence_lock, irq_flags); - radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); - rdev->fence_drv[ring].initialized = false; - } -} - - -/* - * Fence debugfs - */ -#if defined(CONFIG_DEBUG_FS) -static int radeon_debugfs_fence_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_fence *fence; - int i; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (!rdev->fence_drv[i].initialized) - continue; - - seq_printf(m, "--- ring %d ---\n", i); - seq_printf(m, "Last signaled fence 0x%08X\n", - radeon_fence_read(rdev, i)); - if (!list_empty(&rdev->fence_drv[i].emitted)) { - fence = list_entry(rdev->fence_drv[i].emitted.prev, - struct radeon_fence, list); - seq_printf(m, "Last emitted fence %p with 0x%08X\n", - fence, fence->seq); - } - } - return 0; -} - -static struct drm_info_list radeon_debugfs_fence_list[] = { - {"radeon_fence_info", &radeon_debugfs_fence_info, 0, NULL}, -}; -#endif - -int radeon_debugfs_fence_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, radeon_debugfs_fence_list, 1); -#else - return 0; -#endif -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gart.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gart.c deleted file mode 100644 index 2a4c592a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gart.c +++ /dev/null @@ -1,688 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "radeon_reg.h" - -/* - * Common GART table functions. - */ -int radeon_gart_table_ram_alloc(struct radeon_device *rdev) -{ - void *ptr; - - ptr = pci_alloc_consistent(rdev->pdev, rdev->gart.table_size, - &rdev->gart.table_addr); - if (ptr == NULL) { - return -ENOMEM; - } -#ifdef CONFIG_X86 - if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || - rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { - set_memory_uc((unsigned long)ptr, - rdev->gart.table_size >> PAGE_SHIFT); - } -#endif - rdev->gart.ptr = ptr; - memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size); - return 0; -} - -void radeon_gart_table_ram_free(struct radeon_device *rdev) -{ - if (rdev->gart.ptr == NULL) { - return; - } -#ifdef CONFIG_X86 - if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || - rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { - set_memory_wb((unsigned long)rdev->gart.ptr, - rdev->gart.table_size >> PAGE_SHIFT); - } -#endif - pci_free_consistent(rdev->pdev, rdev->gart.table_size, - (void *)rdev->gart.ptr, - rdev->gart.table_addr); - rdev->gart.ptr = NULL; - rdev->gart.table_addr = 0; -} - -int radeon_gart_table_vram_alloc(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.robj == NULL) { - r = radeon_bo_create(rdev, rdev->gart.table_size, - PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, - &rdev->gart.robj); - if (r) { - return r; - } - } - return 0; -} - -int radeon_gart_table_vram_pin(struct radeon_device *rdev) -{ - uint64_t gpu_addr; - int r; - - r = radeon_bo_reserve(rdev->gart.robj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->gart.robj, - RADEON_GEM_DOMAIN_VRAM, &gpu_addr); - if (r) { - radeon_bo_unreserve(rdev->gart.robj); - return r; - } - r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr); - if (r) - radeon_bo_unpin(rdev->gart.robj); - radeon_bo_unreserve(rdev->gart.robj); - rdev->gart.table_addr = gpu_addr; - return r; -} - -void radeon_gart_table_vram_unpin(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.robj == NULL) { - return; - } - r = radeon_bo_reserve(rdev->gart.robj, false); - if (likely(r == 0)) { - radeon_bo_kunmap(rdev->gart.robj); - radeon_bo_unpin(rdev->gart.robj); - radeon_bo_unreserve(rdev->gart.robj); - rdev->gart.ptr = NULL; - } -} - -void radeon_gart_table_vram_free(struct radeon_device *rdev) -{ - if (rdev->gart.robj == NULL) { - return; - } - radeon_gart_table_vram_unpin(rdev); - radeon_bo_unref(&rdev->gart.robj); -} - - - - -/* - * Common gart functions. - */ -void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, - int pages) -{ - unsigned t; - unsigned p; - int i, j; - u64 page_base; - - if (!rdev->gart.ready) { - WARN(1, "trying to unbind memory from uninitialized GART !\n"); - return; - } - t = offset / RADEON_GPU_PAGE_SIZE; - p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); - for (i = 0; i < pages; i++, p++) { - if (rdev->gart.pages[p]) { - rdev->gart.pages[p] = NULL; - rdev->gart.pages_addr[p] = rdev->dummy_page.addr; - page_base = rdev->gart.pages_addr[p]; - for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { - if (rdev->gart.ptr) { - radeon_gart_set_page(rdev, t, page_base); - } - page_base += RADEON_GPU_PAGE_SIZE; - } - } - } - mb(); - radeon_gart_tlb_flush(rdev); -} - -int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, - int pages, struct page **pagelist, dma_addr_t *dma_addr) -{ - unsigned t; - unsigned p; - uint64_t page_base; - int i, j; - - if (!rdev->gart.ready) { - WARN(1, "trying to bind memory to uninitialized GART !\n"); - return -EINVAL; - } - t = offset / RADEON_GPU_PAGE_SIZE; - p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); - - for (i = 0; i < pages; i++, p++) { - rdev->gart.pages_addr[p] = dma_addr[i]; - rdev->gart.pages[p] = pagelist[i]; - if (rdev->gart.ptr) { - page_base = rdev->gart.pages_addr[p]; - for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { - radeon_gart_set_page(rdev, t, page_base); - page_base += RADEON_GPU_PAGE_SIZE; - } - } - } - mb(); - radeon_gart_tlb_flush(rdev); - return 0; -} - -void radeon_gart_restore(struct radeon_device *rdev) -{ - int i, j, t; - u64 page_base; - - if (!rdev->gart.ptr) { - return; - } - for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { - page_base = rdev->gart.pages_addr[i]; - for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { - radeon_gart_set_page(rdev, t, page_base); - page_base += RADEON_GPU_PAGE_SIZE; - } - } - mb(); - radeon_gart_tlb_flush(rdev); -} - -int radeon_gart_init(struct radeon_device *rdev) -{ - int r, i; - - if (rdev->gart.pages) { - return 0; - } - /* We need PAGE_SIZE >= RADEON_GPU_PAGE_SIZE */ - if (PAGE_SIZE < RADEON_GPU_PAGE_SIZE) { - DRM_ERROR("Page size is smaller than GPU page size!\n"); - return -EINVAL; - } - r = radeon_dummy_page_init(rdev); - if (r) - return r; - /* Compute table size */ - rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; - rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE; - DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", - rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); - /* Allocate pages table */ - rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages, - GFP_KERNEL); - if (rdev->gart.pages == NULL) { - radeon_gart_fini(rdev); - return -ENOMEM; - } - rdev->gart.pages_addr = kzalloc(sizeof(dma_addr_t) * - rdev->gart.num_cpu_pages, GFP_KERNEL); - if (rdev->gart.pages_addr == NULL) { - radeon_gart_fini(rdev); - return -ENOMEM; - } - /* set GART entry to point to the dummy page by default */ - for (i = 0; i < rdev->gart.num_cpu_pages; i++) { - rdev->gart.pages_addr[i] = rdev->dummy_page.addr; - } - return 0; -} - -void radeon_gart_fini(struct radeon_device *rdev) -{ - if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { - /* unbind pages */ - radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); - } - rdev->gart.ready = false; - kfree(rdev->gart.pages); - kfree(rdev->gart.pages_addr); - rdev->gart.pages = NULL; - rdev->gart.pages_addr = NULL; - - radeon_dummy_page_fini(rdev); -} - -/* - * vm helpers - * - * TODO bind a default page at vm initialization for default address - */ -int radeon_vm_manager_init(struct radeon_device *rdev) -{ - int r; - - rdev->vm_manager.enabled = false; - - /* mark first vm as always in use, it's the system one */ - /* allocate enough for 2 full VM pts */ - r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8 * 2, - RADEON_GEM_DOMAIN_VRAM); - if (r) { - dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", - (rdev->vm_manager.max_pfn * 8) >> 10); - return r; - } - - r = rdev->vm_manager.funcs->init(rdev); - if (r == 0) - rdev->vm_manager.enabled = true; - - return r; -} - -/* cs mutex must be lock */ -static void radeon_vm_unbind_locked(struct radeon_device *rdev, - struct radeon_vm *vm) -{ - struct radeon_bo_va *bo_va; - - if (vm->id == -1) { - return; - } - - /* wait for vm use to end */ - if (vm->fence) { - radeon_fence_wait(vm->fence, false); - radeon_fence_unref(&vm->fence); - } - - /* hw unbind */ - rdev->vm_manager.funcs->unbind(rdev, vm); - rdev->vm_manager.use_bitmap &= ~(1 << vm->id); - list_del_init(&vm->list); - vm->id = -1; - radeon_sa_bo_free(rdev, &vm->sa_bo); - vm->pt = NULL; - - list_for_each_entry(bo_va, &vm->va, vm_list) { - bo_va->valid = false; - } -} - -void radeon_vm_manager_fini(struct radeon_device *rdev) -{ - if (rdev->vm_manager.sa_manager.bo == NULL) - return; - radeon_vm_manager_suspend(rdev); - rdev->vm_manager.funcs->fini(rdev); - radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager); - rdev->vm_manager.enabled = false; -} - -int radeon_vm_manager_start(struct radeon_device *rdev) -{ - if (rdev->vm_manager.sa_manager.bo == NULL) { - return -EINVAL; - } - return radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); -} - -int radeon_vm_manager_suspend(struct radeon_device *rdev) -{ - struct radeon_vm *vm, *tmp; - - radeon_mutex_lock(&rdev->cs_mutex); - /* unbind all active vm */ - list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { - radeon_vm_unbind_locked(rdev, vm); - } - rdev->vm_manager.funcs->fini(rdev); - radeon_mutex_unlock(&rdev->cs_mutex); - return radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); -} - -/* cs mutex must be lock */ -void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) -{ - mutex_lock(&vm->mutex); - radeon_vm_unbind_locked(rdev, vm); - mutex_unlock(&vm->mutex); -} - -/* cs mutex must be lock & vm mutex must be lock */ -int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) -{ - struct radeon_vm *vm_evict; - unsigned i; - int id = -1, r; - - if (vm == NULL) { - return -EINVAL; - } - - if (vm->id != -1) { - /* update lru */ - list_del_init(&vm->list); - list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); - return 0; - } - -retry: - r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, - RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8), - RADEON_GPU_PAGE_SIZE); - if (r) { - if (list_empty(&rdev->vm_manager.lru_vm)) { - return r; - } - vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); - radeon_vm_unbind(rdev, vm_evict); - goto retry; - } - vm->pt = rdev->vm_manager.sa_manager.cpu_ptr; - vm->pt += (vm->sa_bo.offset >> 3); - vm->pt_gpu_addr = rdev->vm_manager.sa_manager.gpu_addr; - vm->pt_gpu_addr += vm->sa_bo.offset; - memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8)); - -retry_id: - /* search for free vm */ - for (i = 0; i < rdev->vm_manager.nvm; i++) { - if (!(rdev->vm_manager.use_bitmap & (1 << i))) { - id = i; - break; - } - } - /* evict vm if necessary */ - if (id == -1) { - vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); - radeon_vm_unbind(rdev, vm_evict); - goto retry_id; - } - - /* do hw bind */ - r = rdev->vm_manager.funcs->bind(rdev, vm, id); - if (r) { - radeon_sa_bo_free(rdev, &vm->sa_bo); - return r; - } - rdev->vm_manager.use_bitmap |= 1 << id; - vm->id = id; - list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); - return radeon_vm_bo_update_pte(rdev, vm, rdev->ib_pool.sa_manager.bo, - &rdev->ib_pool.sa_manager.bo->tbo.mem); -} - -/* object have to be reserved */ -int radeon_vm_bo_add(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_bo *bo, - uint64_t offset, - uint32_t flags) -{ - struct radeon_bo_va *bo_va, *tmp; - struct list_head *head; - uint64_t size = radeon_bo_size(bo), last_offset = 0; - unsigned last_pfn; - - bo_va = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); - if (bo_va == NULL) { - return -ENOMEM; - } - bo_va->vm = vm; - bo_va->bo = bo; - bo_va->soffset = offset; - bo_va->eoffset = offset + size; - bo_va->flags = flags; - bo_va->valid = false; - INIT_LIST_HEAD(&bo_va->bo_list); - INIT_LIST_HEAD(&bo_va->vm_list); - /* make sure object fit at this offset */ - if (bo_va->soffset >= bo_va->eoffset) { - kfree(bo_va); - return -EINVAL; - } - - last_pfn = bo_va->eoffset / RADEON_GPU_PAGE_SIZE; - if (last_pfn > rdev->vm_manager.max_pfn) { - kfree(bo_va); - dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", - last_pfn, rdev->vm_manager.max_pfn); - return -EINVAL; - } - - mutex_lock(&vm->mutex); - if (last_pfn > vm->last_pfn) { - /* release mutex and lock in right order */ - mutex_unlock(&vm->mutex); - radeon_mutex_lock(&rdev->cs_mutex); - mutex_lock(&vm->mutex); - /* and check again */ - if (last_pfn > vm->last_pfn) { - /* grow va space 32M by 32M */ - unsigned align = ((32 << 20) >> 12) - 1; - radeon_vm_unbind_locked(rdev, vm); - vm->last_pfn = (last_pfn + align) & ~align; - } - radeon_mutex_unlock(&rdev->cs_mutex); - } - head = &vm->va; - last_offset = 0; - list_for_each_entry(tmp, &vm->va, vm_list) { - if (bo_va->soffset >= last_offset && bo_va->eoffset < tmp->soffset) { - /* bo can be added before this one */ - break; - } - if (bo_va->soffset >= tmp->soffset && bo_va->soffset < tmp->eoffset) { - /* bo and tmp overlap, invalid offset */ - dev_err(rdev->dev, "bo %p va 0x%08X conflict with (bo %p 0x%08X 0x%08X)\n", - bo, (unsigned)bo_va->soffset, tmp->bo, - (unsigned)tmp->soffset, (unsigned)tmp->eoffset); - kfree(bo_va); - mutex_unlock(&vm->mutex); - return -EINVAL; - } - last_offset = tmp->eoffset; - head = &tmp->vm_list; - } - list_add(&bo_va->vm_list, head); - list_add_tail(&bo_va->bo_list, &bo->va); - mutex_unlock(&vm->mutex); - return 0; -} - -static u64 radeon_vm_get_addr(struct radeon_device *rdev, - struct ttm_mem_reg *mem, - unsigned pfn) -{ - u64 addr = 0; - - switch (mem->mem_type) { - case TTM_PL_VRAM: - addr = (mem->start << PAGE_SHIFT); - addr += pfn * RADEON_GPU_PAGE_SIZE; - addr += rdev->vm_manager.vram_base_offset; - break; - case TTM_PL_TT: - /* offset inside page table */ - addr = mem->start << PAGE_SHIFT; - addr += pfn * RADEON_GPU_PAGE_SIZE; - addr = addr >> PAGE_SHIFT; - /* page table offset */ - addr = rdev->gart.pages_addr[addr]; - /* in case cpu page size != gpu page size*/ - addr += (pfn * RADEON_GPU_PAGE_SIZE) & (~PAGE_MASK); - break; - default: - break; - } - return addr; -} - -/* object have to be reserved & cs mutex took & vm mutex took */ -int radeon_vm_bo_update_pte(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_bo *bo, - struct ttm_mem_reg *mem) -{ - struct radeon_bo_va *bo_va; - unsigned ngpu_pages, i; - uint64_t addr = 0, pfn; - uint32_t flags; - - /* nothing to do if vm isn't bound */ - if (vm->id == -1) - return 0;; - - bo_va = radeon_bo_va(bo, vm); - if (bo_va == NULL) { - dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm); - return -EINVAL; - } - - if (bo_va->valid) - return 0; - - ngpu_pages = radeon_bo_ngpu_pages(bo); - bo_va->flags &= ~RADEON_VM_PAGE_VALID; - bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; - if (mem) { - if (mem->mem_type != TTM_PL_SYSTEM) { - bo_va->flags |= RADEON_VM_PAGE_VALID; - bo_va->valid = true; - } - if (mem->mem_type == TTM_PL_TT) { - bo_va->flags |= RADEON_VM_PAGE_SYSTEM; - } - } - pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE; - flags = rdev->vm_manager.funcs->page_flags(rdev, bo_va->vm, bo_va->flags); - for (i = 0, addr = 0; i < ngpu_pages; i++) { - if (mem && bo_va->valid) { - addr = radeon_vm_get_addr(rdev, mem, i); - } - rdev->vm_manager.funcs->set_page(rdev, bo_va->vm, i + pfn, addr, flags); - } - rdev->vm_manager.funcs->tlb_flush(rdev, bo_va->vm); - return 0; -} - -/* object have to be reserved */ -int radeon_vm_bo_rmv(struct radeon_device *rdev, - struct radeon_vm *vm, - struct radeon_bo *bo) -{ - struct radeon_bo_va *bo_va; - - bo_va = radeon_bo_va(bo, vm); - if (bo_va == NULL) - return 0; - - radeon_mutex_lock(&rdev->cs_mutex); - mutex_lock(&vm->mutex); - radeon_vm_bo_update_pte(rdev, vm, bo, NULL); - radeon_mutex_unlock(&rdev->cs_mutex); - list_del(&bo_va->vm_list); - mutex_unlock(&vm->mutex); - list_del(&bo_va->bo_list); - - kfree(bo_va); - return 0; -} - -void radeon_vm_bo_invalidate(struct radeon_device *rdev, - struct radeon_bo *bo) -{ - struct radeon_bo_va *bo_va; - - BUG_ON(!atomic_read(&bo->tbo.reserved)); - list_for_each_entry(bo_va, &bo->va, bo_list) { - bo_va->valid = false; - } -} - -int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) -{ - int r; - - vm->id = -1; - vm->fence = NULL; - mutex_init(&vm->mutex); - INIT_LIST_HEAD(&vm->list); - INIT_LIST_HEAD(&vm->va); - /* SI requires equal sized PTs for all VMs, so always set - * last_pfn to max_pfn. cayman allows variable sized - * pts so we can grow then as needed. Once we switch - * to two level pts we can unify this again. - */ - if (rdev->family >= CHIP_TAHITI) - vm->last_pfn = rdev->vm_manager.max_pfn; - else - vm->last_pfn = 0; - /* map the ib pool buffer at 0 in virtual address space, set - * read only - */ - r = radeon_vm_bo_add(rdev, vm, rdev->ib_pool.sa_manager.bo, 0, - RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); - return r; -} - -void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) -{ - struct radeon_bo_va *bo_va, *tmp; - int r; - - radeon_mutex_lock(&rdev->cs_mutex); - mutex_lock(&vm->mutex); - radeon_vm_unbind_locked(rdev, vm); - radeon_mutex_unlock(&rdev->cs_mutex); - - /* remove all bo */ - r = radeon_bo_reserve(rdev->ib_pool.sa_manager.bo, false); - if (!r) { - bo_va = radeon_bo_va(rdev->ib_pool.sa_manager.bo, vm); - list_del_init(&bo_va->bo_list); - list_del_init(&bo_va->vm_list); - radeon_bo_unreserve(rdev->ib_pool.sa_manager.bo); - kfree(bo_va); - } - if (!list_empty(&vm->va)) { - dev_err(rdev->dev, "still active bo inside vm\n"); - } - list_for_each_entry_safe(bo_va, tmp, &vm->va, vm_list) { - list_del_init(&bo_va->vm_list); - r = radeon_bo_reserve(bo_va->bo, false); - if (!r) { - list_del_init(&bo_va->bo_list); - radeon_bo_unreserve(bo_va->bo); - kfree(bo_va); - } - } - mutex_unlock(&vm->mutex); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gem.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gem.c deleted file mode 100644 index c7008b52..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_gem.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon.h" - -int radeon_gem_object_init(struct drm_gem_object *obj) -{ - BUG(); - - return 0; -} - -void radeon_gem_object_free(struct drm_gem_object *gobj) -{ - struct radeon_bo *robj = gem_to_radeon_bo(gobj); - - if (robj) { - radeon_bo_unref(&robj); - } -} - -int radeon_gem_object_create(struct radeon_device *rdev, int size, - int alignment, int initial_domain, - bool discardable, bool kernel, - struct drm_gem_object **obj) -{ - struct radeon_bo *robj; - int r; - - *obj = NULL; - /* At least align on page size */ - if (alignment < PAGE_SIZE) { - alignment = PAGE_SIZE; - } - r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, &robj); - if (r) { - if (r != -ERESTARTSYS) - DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", - size, initial_domain, alignment, r); - return r; - } - *obj = &robj->gem_base; - - mutex_lock(&rdev->gem.mutex); - list_add_tail(&robj->list, &rdev->gem.objects); - mutex_unlock(&rdev->gem.mutex); - - return 0; -} - -int radeon_gem_set_domain(struct drm_gem_object *gobj, - uint32_t rdomain, uint32_t wdomain) -{ - struct radeon_bo *robj; - uint32_t domain; - int r; - - /* FIXME: reeimplement */ - robj = gem_to_radeon_bo(gobj); - /* work out where to validate the buffer to */ - domain = wdomain; - if (!domain) { - domain = rdomain; - } - if (!domain) { - /* Do nothings */ - printk(KERN_WARNING "Set domain withou domain !\n"); - return 0; - } - if (domain == RADEON_GEM_DOMAIN_CPU) { - /* Asking for cpu access wait for object idle */ - r = radeon_bo_wait(robj, NULL, false); - if (r) { - printk(KERN_ERR "Failed to wait for object !\n"); - return r; - } - } - return 0; -} - -int radeon_gem_init(struct radeon_device *rdev) -{ - INIT_LIST_HEAD(&rdev->gem.objects); - return 0; -} - -void radeon_gem_fini(struct radeon_device *rdev) -{ - radeon_bo_force_delete(rdev); -} - -/* - * Call from drm_gem_handle_create which appear in both new and open ioctl - * case. - */ -int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) -{ - return 0; -} - -void radeon_gem_object_close(struct drm_gem_object *obj, - struct drm_file *file_priv) -{ - struct radeon_bo *rbo = gem_to_radeon_bo(obj); - struct radeon_device *rdev = rbo->rdev; - struct radeon_fpriv *fpriv = file_priv->driver_priv; - struct radeon_vm *vm = &fpriv->vm; - struct radeon_bo_va *bo_va, *tmp; - - if (rdev->family < CHIP_CAYMAN) { - return; - } - - if (radeon_bo_reserve(rbo, false)) { - return; - } - list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { - if (bo_va->vm == vm) { - /* remove from this vm address space */ - mutex_lock(&vm->mutex); - list_del(&bo_va->vm_list); - mutex_unlock(&vm->mutex); - list_del(&bo_va->bo_list); - kfree(bo_va); - } - } - radeon_bo_unreserve(rbo); -} - - -/* - * GEM ioctls. - */ -int radeon_gem_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_radeon_gem_info *args = data; - struct ttm_mem_type_manager *man; - unsigned i; - - man = &rdev->mman.bdev.man[TTM_PL_VRAM]; - - args->vram_size = rdev->mc.real_vram_size; - args->vram_visible = (u64)man->size << PAGE_SHIFT; - if (rdev->stollen_vga_memory) - args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); - args->vram_visible -= radeon_fbdev_total_size(rdev); - args->gart_size = rdev->mc.gtt_size - 4096 - RADEON_IB_POOL_SIZE*64*1024; - for(i = 0; i < RADEON_NUM_RINGS; ++i) - args->gart_size -= rdev->ring[i].ring_size; - return 0; -} - -int radeon_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - /* TODO: implement */ - DRM_ERROR("unimplemented %s\n", __func__); - return -ENOSYS; -} - -int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - /* TODO: implement */ - DRM_ERROR("unimplemented %s\n", __func__); - return -ENOSYS; -} - -int radeon_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_radeon_gem_create *args = data; - struct drm_gem_object *gobj; - uint32_t handle; - int r; - - /* create a gem object to contain this object in */ - args->size = roundup(args->size, PAGE_SIZE); - r = radeon_gem_object_create(rdev, args->size, args->alignment, - args->initial_domain, false, - false, &gobj); - if (r) { - return r; - } - r = drm_gem_handle_create(filp, gobj, &handle); - /* drop reference from allocate - handle holds it now */ - drm_gem_object_unreference_unlocked(gobj); - if (r) { - return r; - } - args->handle = handle; - return 0; -} - -int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - /* transition the BO to a domain - - * just validate the BO into a certain domain */ - struct drm_radeon_gem_set_domain *args = data; - struct drm_gem_object *gobj; - struct radeon_bo *robj; - int r; - - /* for now if someone requests domain CPU - - * just make sure the buffer is finished with */ - - /* just do a BO wait for now */ - gobj = drm_gem_object_lookup(dev, filp, args->handle); - if (gobj == NULL) { - return -ENOENT; - } - robj = gem_to_radeon_bo(gobj); - - r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); - - drm_gem_object_unreference_unlocked(gobj); - return r; -} - -int radeon_mode_dumb_mmap(struct drm_file *filp, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p) -{ - struct drm_gem_object *gobj; - struct radeon_bo *robj; - - gobj = drm_gem_object_lookup(dev, filp, handle); - if (gobj == NULL) { - return -ENOENT; - } - robj = gem_to_radeon_bo(gobj); - *offset_p = radeon_bo_mmap_offset(robj); - drm_gem_object_unreference_unlocked(gobj); - return 0; -} - -int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct drm_radeon_gem_mmap *args = data; - - return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); -} - -int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct drm_radeon_gem_busy *args = data; - struct drm_gem_object *gobj; - struct radeon_bo *robj; - int r; - uint32_t cur_placement = 0; - - gobj = drm_gem_object_lookup(dev, filp, args->handle); - if (gobj == NULL) { - return -ENOENT; - } - robj = gem_to_radeon_bo(gobj); - r = radeon_bo_wait(robj, &cur_placement, true); - switch (cur_placement) { - case TTM_PL_VRAM: - args->domain = RADEON_GEM_DOMAIN_VRAM; - break; - case TTM_PL_TT: - args->domain = RADEON_GEM_DOMAIN_GTT; - break; - case TTM_PL_SYSTEM: - args->domain = RADEON_GEM_DOMAIN_CPU; - default: - break; - } - drm_gem_object_unreference_unlocked(gobj); - return r; -} - -int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct drm_radeon_gem_wait_idle *args = data; - struct drm_gem_object *gobj; - struct radeon_bo *robj; - int r; - - gobj = drm_gem_object_lookup(dev, filp, args->handle); - if (gobj == NULL) { - return -ENOENT; - } - robj = gem_to_radeon_bo(gobj); - r = radeon_bo_wait(robj, NULL, false); - /* callback hw specific functions if any */ - if (robj->rdev->asic->ioctl_wait_idle) - robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); - drm_gem_object_unreference_unlocked(gobj); - return r; -} - -int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct drm_radeon_gem_set_tiling *args = data; - struct drm_gem_object *gobj; - struct radeon_bo *robj; - int r = 0; - - DRM_DEBUG("%d \n", args->handle); - gobj = drm_gem_object_lookup(dev, filp, args->handle); - if (gobj == NULL) - return -ENOENT; - robj = gem_to_radeon_bo(gobj); - r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch); - drm_gem_object_unreference_unlocked(gobj); - return r; -} - -int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct drm_radeon_gem_get_tiling *args = data; - struct drm_gem_object *gobj; - struct radeon_bo *rbo; - int r = 0; - - DRM_DEBUG("\n"); - gobj = drm_gem_object_lookup(dev, filp, args->handle); - if (gobj == NULL) - return -ENOENT; - rbo = gem_to_radeon_bo(gobj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - goto out; - radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch); - radeon_bo_unreserve(rbo); -out: - drm_gem_object_unreference_unlocked(gobj); - return r; -} - -int radeon_gem_va_ioctl(struct drm_device *dev, void *data, - struct drm_file *filp) -{ - struct drm_radeon_gem_va *args = data; - struct drm_gem_object *gobj; - struct radeon_device *rdev = dev->dev_private; - struct radeon_fpriv *fpriv = filp->driver_priv; - struct radeon_bo *rbo; - struct radeon_bo_va *bo_va; - u32 invalid_flags; - int r = 0; - - if (!rdev->vm_manager.enabled) { - args->operation = RADEON_VA_RESULT_ERROR; - return -ENOTTY; - } - - /* !! DONT REMOVE !! - * We don't support vm_id yet, to be sure we don't have have broken - * userspace, reject anyone trying to use non 0 value thus moving - * forward we can use those fields without breaking existant userspace - */ - if (args->vm_id) { - args->operation = RADEON_VA_RESULT_ERROR; - return -EINVAL; - } - - if (args->offset < RADEON_VA_RESERVED_SIZE) { - dev_err(&dev->pdev->dev, - "offset 0x%lX is in reserved area 0x%X\n", - (unsigned long)args->offset, - RADEON_VA_RESERVED_SIZE); - args->operation = RADEON_VA_RESULT_ERROR; - return -EINVAL; - } - - /* don't remove, we need to enforce userspace to set the snooped flag - * otherwise we will endup with broken userspace and we won't be able - * to enable this feature without adding new interface - */ - invalid_flags = RADEON_VM_PAGE_VALID | RADEON_VM_PAGE_SYSTEM; - if ((args->flags & invalid_flags)) { - dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n", - args->flags, invalid_flags); - args->operation = RADEON_VA_RESULT_ERROR; - return -EINVAL; - } - if (!(args->flags & RADEON_VM_PAGE_SNOOPED)) { - dev_err(&dev->pdev->dev, "only supported snooped mapping for now\n"); - args->operation = RADEON_VA_RESULT_ERROR; - return -EINVAL; - } - - switch (args->operation) { - case RADEON_VA_MAP: - case RADEON_VA_UNMAP: - break; - default: - dev_err(&dev->pdev->dev, "unsupported operation %d\n", - args->operation); - args->operation = RADEON_VA_RESULT_ERROR; - return -EINVAL; - } - - gobj = drm_gem_object_lookup(dev, filp, args->handle); - if (gobj == NULL) { - args->operation = RADEON_VA_RESULT_ERROR; - return -ENOENT; - } - rbo = gem_to_radeon_bo(gobj); - r = radeon_bo_reserve(rbo, false); - if (r) { - args->operation = RADEON_VA_RESULT_ERROR; - drm_gem_object_unreference_unlocked(gobj); - return r; - } - switch (args->operation) { - case RADEON_VA_MAP: - bo_va = radeon_bo_va(rbo, &fpriv->vm); - if (bo_va) { - args->operation = RADEON_VA_RESULT_VA_EXIST; - args->offset = bo_va->soffset; - goto out; - } - r = radeon_vm_bo_add(rdev, &fpriv->vm, rbo, - args->offset, args->flags); - break; - case RADEON_VA_UNMAP: - r = radeon_vm_bo_rmv(rdev, &fpriv->vm, rbo); - break; - default: - break; - } - args->operation = RADEON_VA_RESULT_OK; - if (r) { - args->operation = RADEON_VA_RESULT_ERROR; - } -out: - radeon_bo_unreserve(rbo); - drm_gem_object_unreference_unlocked(gobj); - return r; -} - -int radeon_mode_dumb_create(struct drm_file *file_priv, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_gem_object *gobj; - uint32_t handle; - int r; - - args->pitch = radeon_align_pitch(rdev, args->width, args->bpp, 0) * ((args->bpp + 1) / 8); - args->size = args->pitch * args->height; - args->size = ALIGN(args->size, PAGE_SIZE); - - r = radeon_gem_object_create(rdev, args->size, 0, - RADEON_GEM_DOMAIN_VRAM, - false, ttm_bo_type_device, - &gobj); - if (r) - return -ENOMEM; - - r = drm_gem_handle_create(file_priv, gobj, &handle); - /* drop reference from allocate - handle holds it now */ - drm_gem_object_unreference_unlocked(gobj); - if (r) { - return r; - } - args->handle = handle; - return 0; -} - -int radeon_mode_dumb_destroy(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle) -{ - return drm_gem_handle_delete(file_priv, handle); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_i2c.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_i2c.c deleted file mode 100644 index 3edec1c1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_i2c.c +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include - -#include "drmP.h" -#include "drm_edid.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" - -extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num); -extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); - -/** - * radeon_ddc_probe - * - */ -bool radeon_ddc_probe(struct radeon_connector *radeon_connector) -{ - u8 out = 0x0; - u8 buf[8]; - int ret; - struct i2c_msg msgs[] = { - { - .addr = DDC_ADDR, - .flags = 0, - .len = 1, - .buf = &out, - }, - { - .addr = DDC_ADDR, - .flags = I2C_M_RD, - .len = 8, - .buf = buf, - } - }; - - /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); - - ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); - if (ret != 2) - /* Couldn't find an accessible DDC on this connector */ - return false; - /* Probe also for valid EDID header - * EDID header starts with: - * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. - * Only the first 6 bytes must be valid as - * drm_edid_block_valid() can fix the last 2 bytes */ - if (drm_edid_header_is_valid(buf) < 6) { - /* Couldn't find an accessible EDID on this - * connector */ - return false; - } - return true; -} - -/* bit banging i2c */ - -static int pre_xfer(struct i2c_adapter *i2c_adap) -{ - struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - uint32_t temp; - - /* RV410 appears to have a bug where the hw i2c in reset - * holds the i2c port in a bad state - switch hw i2c away before - * doing DDC - do this for all r200s/r300s/r400s for safety sake - */ - if (rec->hw_capable) { - if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { - u32 reg; - - if (rdev->family >= CHIP_RV350) - reg = RADEON_GPIO_MONID; - else if ((rdev->family == CHIP_R300) || - (rdev->family == CHIP_R350)) - reg = RADEON_GPIO_DVI_DDC; - else - reg = RADEON_GPIO_CRT2_DDC; - - mutex_lock(&rdev->dc_hw_i2c_mutex); - if (rec->a_clk_reg == reg) { - WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | - R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); - } else { - WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | - R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); - } - mutex_unlock(&rdev->dc_hw_i2c_mutex); - } - } - - /* switch the pads to ddc mode */ - if (ASIC_IS_DCE3(rdev) && rec->hw_capable) { - temp = RREG32(rec->mask_clk_reg); - temp &= ~(1 << 16); - WREG32(rec->mask_clk_reg, temp); - } - - /* clear the output pin values */ - temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; - WREG32(rec->a_clk_reg, temp); - - temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; - WREG32(rec->a_data_reg, temp); - - /* set the pins to input */ - temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; - WREG32(rec->en_clk_reg, temp); - - temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; - WREG32(rec->en_data_reg, temp); - - /* mask the gpio pins for software use */ - temp = RREG32(rec->mask_clk_reg) | rec->mask_clk_mask; - WREG32(rec->mask_clk_reg, temp); - temp = RREG32(rec->mask_clk_reg); - - temp = RREG32(rec->mask_data_reg) | rec->mask_data_mask; - WREG32(rec->mask_data_reg, temp); - temp = RREG32(rec->mask_data_reg); - - return 0; -} - -static void post_xfer(struct i2c_adapter *i2c_adap) -{ - struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - uint32_t temp; - - /* unmask the gpio pins for software use */ - temp = RREG32(rec->mask_clk_reg) & ~rec->mask_clk_mask; - WREG32(rec->mask_clk_reg, temp); - temp = RREG32(rec->mask_clk_reg); - - temp = RREG32(rec->mask_data_reg) & ~rec->mask_data_mask; - WREG32(rec->mask_data_reg, temp); - temp = RREG32(rec->mask_data_reg); -} - -static int get_clock(void *i2c_priv) -{ - struct radeon_i2c_chan *i2c = i2c_priv; - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - uint32_t val; - - /* read the value off the pin */ - val = RREG32(rec->y_clk_reg); - val &= rec->y_clk_mask; - - return (val != 0); -} - - -static int get_data(void *i2c_priv) -{ - struct radeon_i2c_chan *i2c = i2c_priv; - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - uint32_t val; - - /* read the value off the pin */ - val = RREG32(rec->y_data_reg); - val &= rec->y_data_mask; - - return (val != 0); -} - -static void set_clock(void *i2c_priv, int clock) -{ - struct radeon_i2c_chan *i2c = i2c_priv; - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - uint32_t val; - - /* set pin direction */ - val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; - val |= clock ? 0 : rec->en_clk_mask; - WREG32(rec->en_clk_reg, val); -} - -static void set_data(void *i2c_priv, int data) -{ - struct radeon_i2c_chan *i2c = i2c_priv; - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - uint32_t val; - - /* set pin direction */ - val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; - val |= data ? 0 : rec->en_data_mask; - WREG32(rec->en_data_reg, val); -} - -/* hw i2c */ - -static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) -{ - u32 sclk = rdev->pm.current_sclk; - u32 prescale = 0; - u32 nm; - u8 n, m, loop; - int i2c_clock; - - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - case CHIP_R200: - case CHIP_RV250: - case CHIP_RS300: - case CHIP_RV280: - case CHIP_R300: - case CHIP_R350: - case CHIP_RV350: - i2c_clock = 60; - nm = (sclk * 10) / (i2c_clock * 4); - for (loop = 1; loop < 255; loop++) { - if ((nm / loop) < loop) - break; - } - n = loop - 1; - m = loop - 2; - prescale = m | (n << 8); - break; - case CHIP_RV380: - case CHIP_RS400: - case CHIP_RS480: - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; - break; - case CHIP_RS600: - case CHIP_RS690: - case CHIP_RS740: - /* todo */ - break; - case CHIP_RV515: - case CHIP_R520: - case CHIP_RV530: - case CHIP_RV560: - case CHIP_RV570: - case CHIP_R580: - i2c_clock = 50; - if (rdev->family == CHIP_R520) - prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); - else - prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; - break; - case CHIP_R600: - case CHIP_RV610: - case CHIP_RV630: - case CHIP_RV670: - /* todo */ - break; - case CHIP_RV620: - case CHIP_RV635: - case CHIP_RS780: - case CHIP_RS880: - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - case CHIP_RV740: - /* todo */ - break; - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_JUNIPER: - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - /* todo */ - break; - default: - DRM_ERROR("i2c: unhandled radeon chip\n"); - break; - } - return prescale; -} - - -/* hw i2c engine for r1xx-4xx hardware - * hw can buffer up to 15 bytes - */ -static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - struct i2c_msg *p; - int i, j, k, ret = num; - u32 prescale; - u32 i2c_cntl_0, i2c_cntl_1, i2c_data; - u32 tmp, reg; - - mutex_lock(&rdev->dc_hw_i2c_mutex); - /* take the pm lock since we need a constant sclk */ - mutex_lock(&rdev->pm.mutex); - - prescale = radeon_get_i2c_prescale(rdev); - - reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | - RADEON_I2C_DRIVE_EN | - RADEON_I2C_START | - RADEON_I2C_STOP | - RADEON_I2C_GO); - - if (rdev->is_atom_bios) { - tmp = RREG32(RADEON_BIOS_6_SCRATCH); - WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); - } - - if (rec->mm_i2c) { - i2c_cntl_0 = RADEON_I2C_CNTL_0; - i2c_cntl_1 = RADEON_I2C_CNTL_1; - i2c_data = RADEON_I2C_DATA; - } else { - i2c_cntl_0 = RADEON_DVI_I2C_CNTL_0; - i2c_cntl_1 = RADEON_DVI_I2C_CNTL_1; - i2c_data = RADEON_DVI_I2C_DATA; - - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - case CHIP_RS300: - switch (rec->mask_clk_reg) { - case RADEON_GPIO_DVI_DDC: - /* no gpio select bit */ - break; - default: - DRM_ERROR("gpio not supported with hw i2c\n"); - ret = -EINVAL; - goto done; - } - break; - case CHIP_R200: - /* only bit 4 on r200 */ - switch (rec->mask_clk_reg) { - case RADEON_GPIO_DVI_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); - break; - case RADEON_GPIO_MONID: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); - break; - default: - DRM_ERROR("gpio not supported with hw i2c\n"); - ret = -EINVAL; - goto done; - } - break; - case CHIP_RV250: - case CHIP_RV280: - /* bits 3 and 4 */ - switch (rec->mask_clk_reg) { - case RADEON_GPIO_DVI_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); - break; - case RADEON_GPIO_VGA_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); - break; - case RADEON_GPIO_CRT2_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); - break; - default: - DRM_ERROR("gpio not supported with hw i2c\n"); - ret = -EINVAL; - goto done; - } - break; - case CHIP_R300: - case CHIP_R350: - /* only bit 4 on r300/r350 */ - switch (rec->mask_clk_reg) { - case RADEON_GPIO_VGA_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); - break; - case RADEON_GPIO_DVI_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); - break; - default: - DRM_ERROR("gpio not supported with hw i2c\n"); - ret = -EINVAL; - goto done; - } - break; - case CHIP_RV350: - case CHIP_RV380: - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - case CHIP_RS400: - case CHIP_RS480: - /* bits 3 and 4 */ - switch (rec->mask_clk_reg) { - case RADEON_GPIO_VGA_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); - break; - case RADEON_GPIO_DVI_DDC: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); - break; - case RADEON_GPIO_MONID: - reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); - break; - default: - DRM_ERROR("gpio not supported with hw i2c\n"); - ret = -EINVAL; - goto done; - } - break; - default: - DRM_ERROR("unsupported asic\n"); - ret = -EINVAL; - goto done; - break; - } - } - - /* check for bus probe */ - p = &msgs[0]; - if ((num == 1) && (p->len == 0)) { - WREG32(i2c_cntl_0, (RADEON_I2C_DONE | - RADEON_I2C_NACK | - RADEON_I2C_HALT | - RADEON_I2C_SOFT_RST)); - WREG32(i2c_data, (p->addr << 1) & 0xff); - WREG32(i2c_data, 0); - WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | - (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | - RADEON_I2C_EN | - (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); - WREG32(i2c_cntl_0, reg); - for (k = 0; k < 32; k++) { - udelay(10); - tmp = RREG32(i2c_cntl_0); - if (tmp & RADEON_I2C_GO) - continue; - tmp = RREG32(i2c_cntl_0); - if (tmp & RADEON_I2C_DONE) - break; - else { - DRM_DEBUG("i2c write error 0x%08x\n", tmp); - WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); - ret = -EIO; - goto done; - } - } - goto done; - } - - for (i = 0; i < num; i++) { - p = &msgs[i]; - for (j = 0; j < p->len; j++) { - if (p->flags & I2C_M_RD) { - WREG32(i2c_cntl_0, (RADEON_I2C_DONE | - RADEON_I2C_NACK | - RADEON_I2C_HALT | - RADEON_I2C_SOFT_RST)); - WREG32(i2c_data, ((p->addr << 1) & 0xff) | 0x1); - WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | - (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | - RADEON_I2C_EN | - (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); - WREG32(i2c_cntl_0, reg | RADEON_I2C_RECEIVE); - for (k = 0; k < 32; k++) { - udelay(10); - tmp = RREG32(i2c_cntl_0); - if (tmp & RADEON_I2C_GO) - continue; - tmp = RREG32(i2c_cntl_0); - if (tmp & RADEON_I2C_DONE) - break; - else { - DRM_DEBUG("i2c read error 0x%08x\n", tmp); - WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); - ret = -EIO; - goto done; - } - } - p->buf[j] = RREG32(i2c_data) & 0xff; - } else { - WREG32(i2c_cntl_0, (RADEON_I2C_DONE | - RADEON_I2C_NACK | - RADEON_I2C_HALT | - RADEON_I2C_SOFT_RST)); - WREG32(i2c_data, (p->addr << 1) & 0xff); - WREG32(i2c_data, p->buf[j]); - WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | - (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | - RADEON_I2C_EN | - (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); - WREG32(i2c_cntl_0, reg); - for (k = 0; k < 32; k++) { - udelay(10); - tmp = RREG32(i2c_cntl_0); - if (tmp & RADEON_I2C_GO) - continue; - tmp = RREG32(i2c_cntl_0); - if (tmp & RADEON_I2C_DONE) - break; - else { - DRM_DEBUG("i2c write error 0x%08x\n", tmp); - WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); - ret = -EIO; - goto done; - } - } - } - } - } - -done: - WREG32(i2c_cntl_0, 0); - WREG32(i2c_cntl_1, 0); - WREG32(i2c_cntl_0, (RADEON_I2C_DONE | - RADEON_I2C_NACK | - RADEON_I2C_HALT | - RADEON_I2C_SOFT_RST)); - - if (rdev->is_atom_bios) { - tmp = RREG32(RADEON_BIOS_6_SCRATCH); - tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; - WREG32(RADEON_BIOS_6_SCRATCH, tmp); - } - - mutex_unlock(&rdev->pm.mutex); - mutex_unlock(&rdev->dc_hw_i2c_mutex); - - return ret; -} - -/* hw i2c engine for r5xx hardware - * hw can buffer up to 15 bytes - */ -static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - struct i2c_msg *p; - int i, j, remaining, current_count, buffer_offset, ret = num; - u32 prescale; - u32 tmp, reg; - u32 saved1, saved2; - - mutex_lock(&rdev->dc_hw_i2c_mutex); - /* take the pm lock since we need a constant sclk */ - mutex_lock(&rdev->pm.mutex); - - prescale = radeon_get_i2c_prescale(rdev); - - /* clear gpio mask bits */ - tmp = RREG32(rec->mask_clk_reg); - tmp &= ~rec->mask_clk_mask; - WREG32(rec->mask_clk_reg, tmp); - tmp = RREG32(rec->mask_clk_reg); - - tmp = RREG32(rec->mask_data_reg); - tmp &= ~rec->mask_data_mask; - WREG32(rec->mask_data_reg, tmp); - tmp = RREG32(rec->mask_data_reg); - - /* clear pin values */ - tmp = RREG32(rec->a_clk_reg); - tmp &= ~rec->a_clk_mask; - WREG32(rec->a_clk_reg, tmp); - tmp = RREG32(rec->a_clk_reg); - - tmp = RREG32(rec->a_data_reg); - tmp &= ~rec->a_data_mask; - WREG32(rec->a_data_reg, tmp); - tmp = RREG32(rec->a_data_reg); - - /* set the pins to input */ - tmp = RREG32(rec->en_clk_reg); - tmp &= ~rec->en_clk_mask; - WREG32(rec->en_clk_reg, tmp); - tmp = RREG32(rec->en_clk_reg); - - tmp = RREG32(rec->en_data_reg); - tmp &= ~rec->en_data_mask; - WREG32(rec->en_data_reg, tmp); - tmp = RREG32(rec->en_data_reg); - - /* */ - tmp = RREG32(RADEON_BIOS_6_SCRATCH); - WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); - saved1 = RREG32(AVIVO_DC_I2C_CONTROL1); - saved2 = RREG32(0x494); - WREG32(0x494, saved2 | 0x1); - - WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C); - for (i = 0; i < 50; i++) { - udelay(1); - if (RREG32(AVIVO_DC_I2C_ARBITRATION) & AVIVO_DC_I2C_SW_CAN_USE_I2C) - break; - } - if (i == 50) { - DRM_ERROR("failed to get i2c bus\n"); - ret = -EBUSY; - goto done; - } - - reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN; - switch (rec->mask_clk_reg) { - case AVIVO_DC_GPIO_DDC1_MASK: - reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC1); - break; - case AVIVO_DC_GPIO_DDC2_MASK: - reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC2); - break; - case AVIVO_DC_GPIO_DDC3_MASK: - reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC3); - break; - default: - DRM_ERROR("gpio not supported with hw i2c\n"); - ret = -EINVAL; - goto done; - } - - /* check for bus probe */ - p = &msgs[0]; - if ((num == 1) && (p->len == 0)) { - WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | - AVIVO_DC_I2C_NACK | - AVIVO_DC_I2C_HALT)); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); - udelay(1); - WREG32(AVIVO_DC_I2C_RESET, 0); - - WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff); - WREG32(AVIVO_DC_I2C_DATA, 0); - - WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); - WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | - AVIVO_DC_I2C_DATA_COUNT(1) | - (prescale << 16))); - WREG32(AVIVO_DC_I2C_CONTROL1, reg); - WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); - for (j = 0; j < 200; j++) { - udelay(50); - tmp = RREG32(AVIVO_DC_I2C_STATUS1); - if (tmp & AVIVO_DC_I2C_GO) - continue; - tmp = RREG32(AVIVO_DC_I2C_STATUS1); - if (tmp & AVIVO_DC_I2C_DONE) - break; - else { - DRM_DEBUG("i2c write error 0x%08x\n", tmp); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); - ret = -EIO; - goto done; - } - } - goto done; - } - - for (i = 0; i < num; i++) { - p = &msgs[i]; - remaining = p->len; - buffer_offset = 0; - if (p->flags & I2C_M_RD) { - while (remaining) { - if (remaining > 15) - current_count = 15; - else - current_count = remaining; - WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | - AVIVO_DC_I2C_NACK | - AVIVO_DC_I2C_HALT)); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); - udelay(1); - WREG32(AVIVO_DC_I2C_RESET, 0); - - WREG32(AVIVO_DC_I2C_DATA, ((p->addr << 1) & 0xff) | 0x1); - WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); - WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | - AVIVO_DC_I2C_DATA_COUNT(current_count) | - (prescale << 16))); - WREG32(AVIVO_DC_I2C_CONTROL1, reg | AVIVO_DC_I2C_RECEIVE); - WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); - for (j = 0; j < 200; j++) { - udelay(50); - tmp = RREG32(AVIVO_DC_I2C_STATUS1); - if (tmp & AVIVO_DC_I2C_GO) - continue; - tmp = RREG32(AVIVO_DC_I2C_STATUS1); - if (tmp & AVIVO_DC_I2C_DONE) - break; - else { - DRM_DEBUG("i2c read error 0x%08x\n", tmp); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); - ret = -EIO; - goto done; - } - } - for (j = 0; j < current_count; j++) - p->buf[buffer_offset + j] = RREG32(AVIVO_DC_I2C_DATA) & 0xff; - remaining -= current_count; - buffer_offset += current_count; - } - } else { - while (remaining) { - if (remaining > 15) - current_count = 15; - else - current_count = remaining; - WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | - AVIVO_DC_I2C_NACK | - AVIVO_DC_I2C_HALT)); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); - udelay(1); - WREG32(AVIVO_DC_I2C_RESET, 0); - - WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff); - for (j = 0; j < current_count; j++) - WREG32(AVIVO_DC_I2C_DATA, p->buf[buffer_offset + j]); - - WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); - WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | - AVIVO_DC_I2C_DATA_COUNT(current_count) | - (prescale << 16))); - WREG32(AVIVO_DC_I2C_CONTROL1, reg); - WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); - for (j = 0; j < 200; j++) { - udelay(50); - tmp = RREG32(AVIVO_DC_I2C_STATUS1); - if (tmp & AVIVO_DC_I2C_GO) - continue; - tmp = RREG32(AVIVO_DC_I2C_STATUS1); - if (tmp & AVIVO_DC_I2C_DONE) - break; - else { - DRM_DEBUG("i2c write error 0x%08x\n", tmp); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); - ret = -EIO; - goto done; - } - } - remaining -= current_count; - buffer_offset += current_count; - } - } - } - -done: - WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | - AVIVO_DC_I2C_NACK | - AVIVO_DC_I2C_HALT)); - WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); - udelay(1); - WREG32(AVIVO_DC_I2C_RESET, 0); - - WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_DONE_USING_I2C); - WREG32(AVIVO_DC_I2C_CONTROL1, saved1); - WREG32(0x494, saved2); - tmp = RREG32(RADEON_BIOS_6_SCRATCH); - tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; - WREG32(RADEON_BIOS_6_SCRATCH, tmp); - - mutex_unlock(&rdev->pm.mutex); - mutex_unlock(&rdev->dc_hw_i2c_mutex); - - return ret; -} - -static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); - struct radeon_device *rdev = i2c->dev->dev_private; - struct radeon_i2c_bus_rec *rec = &i2c->rec; - int ret = 0; - - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - case CHIP_R200: - case CHIP_RV250: - case CHIP_RS300: - case CHIP_RV280: - case CHIP_R300: - case CHIP_R350: - case CHIP_RV350: - case CHIP_RV380: - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - case CHIP_RS400: - case CHIP_RS480: - ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); - break; - case CHIP_RS600: - case CHIP_RS690: - case CHIP_RS740: - /* XXX fill in hw i2c implementation */ - break; - case CHIP_RV515: - case CHIP_R520: - case CHIP_RV530: - case CHIP_RV560: - case CHIP_RV570: - case CHIP_R580: - if (rec->mm_i2c) - ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); - else - ret = r500_hw_i2c_xfer(i2c_adap, msgs, num); - break; - case CHIP_R600: - case CHIP_RV610: - case CHIP_RV630: - case CHIP_RV670: - /* XXX fill in hw i2c implementation */ - break; - case CHIP_RV620: - case CHIP_RV635: - case CHIP_RS780: - case CHIP_RS880: - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - case CHIP_RV740: - /* XXX fill in hw i2c implementation */ - break; - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_JUNIPER: - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - /* XXX fill in hw i2c implementation */ - break; - default: - DRM_ERROR("i2c: unhandled radeon chip\n"); - ret = -EIO; - break; - } - - return ret; -} - -static u32 radeon_hw_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm radeon_i2c_algo = { - .master_xfer = radeon_hw_i2c_xfer, - .functionality = radeon_hw_i2c_func, -}; - -static const struct i2c_algorithm radeon_atom_i2c_algo = { - .master_xfer = radeon_atom_hw_i2c_xfer, - .functionality = radeon_atom_hw_i2c_func, -}; - -struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name) -{ - struct radeon_device *rdev = dev->dev_private; - struct radeon_i2c_chan *i2c; - int ret; - - /* don't add the mm_i2c bus unless hw_i2c is enabled */ - if (rec->mm_i2c && (radeon_hw_i2c == 0)) - return NULL; - - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); - if (i2c == NULL) - return NULL; - - i2c->rec = *rec; - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; - i2c->dev = dev; - i2c_set_adapdata(&i2c->adapter, i2c); - if (rec->mm_i2c || - (rec->hw_capable && - radeon_hw_i2c && - ((rdev->family <= CHIP_RS480) || - ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) { - /* set the radeon hw i2c adapter */ - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), - "Radeon i2c hw bus %s", name); - i2c->adapter.algo = &radeon_i2c_algo; - ret = i2c_add_adapter(&i2c->adapter); - if (ret) { - DRM_ERROR("Failed to register hw i2c %s\n", name); - goto out_free; - } - } else if (rec->hw_capable && - radeon_hw_i2c && - ASIC_IS_DCE3(rdev)) { - /* hw i2c using atom */ - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), - "Radeon i2c hw bus %s", name); - i2c->adapter.algo = &radeon_atom_i2c_algo; - ret = i2c_add_adapter(&i2c->adapter); - if (ret) { - DRM_ERROR("Failed to register hw i2c %s\n", name); - goto out_free; - } - } else { - /* set the radeon bit adapter */ - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), - "Radeon i2c bit bus %s", name); - i2c->adapter.algo_data = &i2c->algo.bit; - i2c->algo.bit.pre_xfer = pre_xfer; - i2c->algo.bit.post_xfer = post_xfer; - i2c->algo.bit.setsda = set_data; - i2c->algo.bit.setscl = set_clock; - i2c->algo.bit.getsda = get_data; - i2c->algo.bit.getscl = get_clock; - i2c->algo.bit.udelay = 10; - i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ - i2c->algo.bit.data = i2c; - ret = i2c_bit_add_bus(&i2c->adapter); - if (ret) { - DRM_ERROR("Failed to register bit i2c %s\n", name); - goto out_free; - } - } - - return i2c; -out_free: - kfree(i2c); - return NULL; - -} - -struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name) -{ - struct radeon_i2c_chan *i2c; - int ret; - - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); - if (i2c == NULL) - return NULL; - - i2c->rec = *rec; - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; - i2c->dev = dev; - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), - "Radeon aux bus %s", name); - i2c_set_adapdata(&i2c->adapter, i2c); - i2c->adapter.algo_data = &i2c->algo.dp; - i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; - i2c->algo.dp.address = 0; - ret = i2c_dp_aux_add_bus(&i2c->adapter); - if (ret) { - DRM_INFO("Failed to register i2c %s\n", name); - goto out_free; - } - - return i2c; -out_free: - kfree(i2c); - return NULL; - -} - -void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) -{ - if (!i2c) - return; - i2c_del_adapter(&i2c->adapter); - kfree(i2c); -} - -/* Add the default buses */ -void radeon_i2c_init(struct radeon_device *rdev) -{ - if (rdev->is_atom_bios) - radeon_atombios_i2c_init(rdev); - else - radeon_combios_i2c_init(rdev); -} - -/* remove all the buses */ -void radeon_i2c_fini(struct radeon_device *rdev) -{ - int i; - - for (i = 0; i < RADEON_MAX_I2C_BUS; i++) { - if (rdev->i2c_bus[i]) { - radeon_i2c_destroy(rdev->i2c_bus[i]); - rdev->i2c_bus[i] = NULL; - } - } -} - -/* Add additional buses */ -void radeon_i2c_add(struct radeon_device *rdev, - struct radeon_i2c_bus_rec *rec, - const char *name) -{ - struct drm_device *dev = rdev->ddev; - int i; - - for (i = 0; i < RADEON_MAX_I2C_BUS; i++) { - if (!rdev->i2c_bus[i]) { - rdev->i2c_bus[i] = radeon_i2c_create(dev, rec, name); - return; - } - } -} - -/* looks up bus based on id */ -struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev, - struct radeon_i2c_bus_rec *i2c_bus) -{ - int i; - - for (i = 0; i < RADEON_MAX_I2C_BUS; i++) { - if (rdev->i2c_bus[i] && - (rdev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) { - return rdev->i2c_bus[i]; - } - } - return NULL; -} - -struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) -{ - return NULL; -} - -void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, - u8 slave_addr, - u8 addr, - u8 *val) -{ - u8 out_buf[2]; - u8 in_buf[2]; - struct i2c_msg msgs[] = { - { - .addr = slave_addr, - .flags = 0, - .len = 1, - .buf = out_buf, - }, - { - .addr = slave_addr, - .flags = I2C_M_RD, - .len = 1, - .buf = in_buf, - } - }; - - out_buf[0] = addr; - out_buf[1] = 0; - - if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) { - *val = in_buf[0]; - DRM_DEBUG("val = 0x%02x\n", *val); - } else { - DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n", - addr, *val); - } -} - -void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, - u8 slave_addr, - u8 addr, - u8 val) -{ - uint8_t out_buf[2]; - struct i2c_msg msg = { - .addr = slave_addr, - .flags = 0, - .len = 2, - .buf = out_buf, - }; - - out_buf[0] = addr; - out_buf[1] = val; - - if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) - DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n", - addr, val); -} - -/* ddc router switching */ -void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) -{ - u8 val; - - if (!radeon_connector->router.ddc_valid) - return; - - if (!radeon_connector->router_bus) - return; - - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, &val); - val &= ~radeon_connector->router.ddc_mux_control_pin; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, val); - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, &val); - val &= ~radeon_connector->router.ddc_mux_control_pin; - val |= radeon_connector->router.ddc_mux_state; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, val); -} - -/* clock/data router switching */ -void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) -{ - u8 val; - - if (!radeon_connector->router.cd_valid) - return; - - if (!radeon_connector->router_bus) - return; - - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, &val); - val &= ~radeon_connector->router.cd_mux_control_pin; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, val); - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, &val); - val &= ~radeon_connector->router.cd_mux_control_pin; - val |= radeon_connector->router.cd_mux_state; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, val); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ioc32.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ioc32.c deleted file mode 100644 index 48b7cea3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ioc32.c +++ /dev/null @@ -1,425 +0,0 @@ -/** - * \file radeon_ioc32.c - * - * 32-bit ioctl compatibility routines for the Radeon DRM. - * - * \author Paul Mackerras - * - * Copyright (C) Paul Mackerras 2005 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -typedef struct drm_radeon_init32 { - int func; - u32 sarea_priv_offset; - int is_pci; - int cp_mode; - int gart_size; - int ring_size; - int usec_timeout; - - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - u32 fb_offset; - u32 mmio_offset; - u32 ring_offset; - u32 ring_rptr_offset; - u32 buffers_offset; - u32 gart_textures_offset; -} drm_radeon_init32_t; - -static int compat_radeon_cp_init(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_init32_t init32; - drm_radeon_init_t __user *init; - - if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) - return -EFAULT; - - init = compat_alloc_user_space(sizeof(*init)); - if (!access_ok(VERIFY_WRITE, init, sizeof(*init)) - || __put_user(init32.func, &init->func) - || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset) - || __put_user(init32.is_pci, &init->is_pci) - || __put_user(init32.cp_mode, &init->cp_mode) - || __put_user(init32.gart_size, &init->gart_size) - || __put_user(init32.ring_size, &init->ring_size) - || __put_user(init32.usec_timeout, &init->usec_timeout) - || __put_user(init32.fb_bpp, &init->fb_bpp) - || __put_user(init32.front_offset, &init->front_offset) - || __put_user(init32.front_pitch, &init->front_pitch) - || __put_user(init32.back_offset, &init->back_offset) - || __put_user(init32.back_pitch, &init->back_pitch) - || __put_user(init32.depth_bpp, &init->depth_bpp) - || __put_user(init32.depth_offset, &init->depth_offset) - || __put_user(init32.depth_pitch, &init->depth_pitch) - || __put_user(init32.fb_offset, &init->fb_offset) - || __put_user(init32.mmio_offset, &init->mmio_offset) - || __put_user(init32.ring_offset, &init->ring_offset) - || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset) - || __put_user(init32.buffers_offset, &init->buffers_offset) - || __put_user(init32.gart_textures_offset, - &init->gart_textures_offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); -} - -typedef struct drm_radeon_clear32 { - unsigned int flags; - unsigned int clear_color; - unsigned int clear_depth; - unsigned int color_mask; - unsigned int depth_mask; /* misnamed field: should be stencil */ - u32 depth_boxes; -} drm_radeon_clear32_t; - -static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_clear32_t clr32; - drm_radeon_clear_t __user *clr; - - if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32))) - return -EFAULT; - - clr = compat_alloc_user_space(sizeof(*clr)); - if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr)) - || __put_user(clr32.flags, &clr->flags) - || __put_user(clr32.clear_color, &clr->clear_color) - || __put_user(clr32.clear_depth, &clr->clear_depth) - || __put_user(clr32.color_mask, &clr->color_mask) - || __put_user(clr32.depth_mask, &clr->depth_mask) - || __put_user((void __user *)(unsigned long)clr32.depth_boxes, - &clr->depth_boxes)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); -} - -typedef struct drm_radeon_stipple32 { - u32 mask; -} drm_radeon_stipple32_t; - -static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_stipple32_t __user *argp = (void __user *)arg; - drm_radeon_stipple_t __user *request; - u32 mask; - - if (get_user(mask, &argp->mask)) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((unsigned int __user *)(unsigned long)mask, - &request->mask)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); -} - -typedef struct drm_radeon_tex_image32 { - unsigned int x, y; /* Blit coordinates */ - unsigned int width, height; - u32 data; -} drm_radeon_tex_image32_t; - -typedef struct drm_radeon_texture32 { - unsigned int offset; - int pitch; - int format; - int width; /* Texture image coordinates */ - int height; - u32 image; -} drm_radeon_texture32_t; - -static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_texture32_t req32; - drm_radeon_texture_t __user *request; - drm_radeon_tex_image32_t img32; - drm_radeon_tex_image_t __user *image; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - if (req32.image == 0) - return -EINVAL; - if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image, - sizeof(img32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request) + sizeof(*image)); - if (!access_ok(VERIFY_WRITE, request, - sizeof(*request) + sizeof(*image))) - return -EFAULT; - image = (drm_radeon_tex_image_t __user *) (request + 1); - - if (__put_user(req32.offset, &request->offset) - || __put_user(req32.pitch, &request->pitch) - || __put_user(req32.format, &request->format) - || __put_user(req32.width, &request->width) - || __put_user(req32.height, &request->height) - || __put_user(image, &request->image) - || __put_user(img32.x, &image->x) - || __put_user(img32.y, &image->y) - || __put_user(img32.width, &image->width) - || __put_user(img32.height, &image->height) - || __put_user((const void __user *)(unsigned long)img32.data, - &image->data)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); -} - -typedef struct drm_radeon_vertex2_32 { - int idx; /* Index of vertex buffer */ - int discard; /* Client finished with buffer? */ - int nr_states; - u32 state; - int nr_prims; - u32 prim; -} drm_radeon_vertex2_32_t; - -static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_vertex2_32_t req32; - drm_radeon_vertex2_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.idx, &request->idx) - || __put_user(req32.discard, &request->discard) - || __put_user(req32.nr_states, &request->nr_states) - || __put_user((void __user *)(unsigned long)req32.state, - &request->state) - || __put_user(req32.nr_prims, &request->nr_prims) - || __put_user((void __user *)(unsigned long)req32.prim, - &request->prim)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); -} - -typedef struct drm_radeon_cmd_buffer32 { - int bufsz; - u32 buf; - int nbox; - u32 boxes; -} drm_radeon_cmd_buffer32_t; - -static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_cmd_buffer32_t req32; - drm_radeon_cmd_buffer_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.bufsz, &request->bufsz) - || __put_user((void __user *)(unsigned long)req32.buf, - &request->buf) - || __put_user(req32.nbox, &request->nbox) - || __put_user((void __user *)(unsigned long)req32.boxes, - &request->boxes)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); -} - -typedef struct drm_radeon_getparam32 { - int param; - u32 value; -} drm_radeon_getparam32_t; - -static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_getparam32_t req32; - drm_radeon_getparam_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); -} - -typedef struct drm_radeon_mem_alloc32 { - int region; - int alignment; - int size; - u32 region_offset; /* offset from start of fb or GART */ -} drm_radeon_mem_alloc32_t; - -static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_mem_alloc32_t req32; - drm_radeon_mem_alloc_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.region, &request->region) - || __put_user(req32.alignment, &request->alignment) - || __put_user(req32.size, &request->size) - || __put_user((int __user *)(unsigned long)req32.region_offset, - &request->region_offset)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); -} - -typedef struct drm_radeon_irq_emit32 { - u32 irq_seq; -} drm_radeon_irq_emit32_t; - -static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_irq_emit32_t req32; - drm_radeon_irq_emit_t __user *request; - - if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user((int __user *)(unsigned long)req32.irq_seq, - &request->irq_seq)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); -} - -/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */ -#if defined (CONFIG_X86_64) || defined(CONFIG_IA64) -typedef struct drm_radeon_setparam32 { - int param; - u64 value; -} __attribute__((packed)) drm_radeon_setparam32_t; - -static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_radeon_setparam32_t req32; - drm_radeon_setparam_t __user *request; - - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.param, &request->param) - || __put_user((void __user *)(unsigned long)req32.value, - &request->value)) - return -EFAULT; - - return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request); -} -#else -#define compat_radeon_cp_setparam NULL -#endif /* X86_64 || IA64 */ - -drm_ioctl_compat_t *radeon_compat_ioctls[] = { - [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, - [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, - [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple, - [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture, - [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2, - [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf, - [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam, - [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam, - [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc, - [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit, -}; - -/** - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/dri/card. - * - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. - * \return zero on success or negative number on failure. - */ -long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - drm_ioctl_compat_t *fn = NULL; - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) - fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; - - if (fn != NULL) - ret = (*fn) (filp, cmd, arg); - else - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} - -long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - unsigned int nr = DRM_IOCTL_NR(cmd); - int ret; - - if (nr < DRM_COMMAND_BASE) - return drm_compat_ioctl(filp, cmd, arg); - - ret = drm_ioctl(filp, cmd, arg); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq.c deleted file mode 100644 index 00da3842..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq.c +++ /dev/null @@ -1,401 +0,0 @@ -/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - * Michel D�zer - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (state) - dev_priv->irq_enable_reg |= mask; - else - dev_priv->irq_enable_reg &= ~mask; - - if (dev->irq_enabled) - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); -} - -static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (state) - dev_priv->r500_disp_irq_reg |= mask; - else - dev_priv->r500_disp_irq_reg &= ~mask; - - if (dev->irq_enabled) - RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg); -} - -int radeon_enable_vblank(struct drm_device *dev, int crtc) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - switch (crtc) { - case 0: - r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); - break; - case 1: - r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return -EINVAL; - } - } else { - switch (crtc) { - case 0: - radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); - break; - case 1: - radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - return -EINVAL; - } - } - - return 0; -} - -void radeon_disable_vblank(struct drm_device *dev, int crtc) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - switch (crtc) { - case 0: - r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); - break; - case 1: - r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - break; - } - } else { - switch (crtc) { - case 0: - radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); - break; - case 1: - radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); - break; - default: - DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", - crtc); - break; - } - } -} - -static u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int) -{ - u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS); - u32 irq_mask = RADEON_SW_INT_TEST; - - *r500_disp_int = 0; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - /* vbl interrupts in a different place */ - - if (irqs & R500_DISPLAY_INT_STATUS) { - /* if a display interrupt */ - u32 disp_irq; - - disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS); - - *r500_disp_int = disp_irq; - if (disp_irq & R500_D1_VBLANK_INTERRUPT) - RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK); - if (disp_irq & R500_D2_VBLANK_INTERRUPT) - RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK); - } - irq_mask |= R500_DISPLAY_INT_STATUS; - } else - irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT; - - irqs &= irq_mask; - - if (irqs) - RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); - - return irqs; -} - -/* Interrupts - Used for device synchronization and flushing in the - * following circumstances: - * - * - Exclusive FB access with hw idle: - * - Wait for GUI Idle (?) interrupt, then do normal flush. - * - * - Frame throttling, NV_fence: - * - Drop marker irq's into command stream ahead of time. - * - Wait on irq's with lock *not held* - * - Check each for termination condition - * - * - Internally in cp_getbuffer, etc: - * - as above, but wait with lock held??? - * - * NOTE: These functions are misleadingly named -- the irq's aren't - * tied to dma at all, this is just a hangover from dri prehistory. - */ - -irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - u32 stat; - u32 r500_disp_int; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return IRQ_NONE; - - /* Only consider the bits we're interested in - others could be used - * outside the DRM - */ - stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int); - if (!stat) - return IRQ_NONE; - - stat &= dev_priv->irq_enable_reg; - - /* SW interrupt */ - if (stat & RADEON_SW_INT_TEST) - DRM_WAKEUP(&dev_priv->swi_queue); - - /* VBLANK interrupt */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) - drm_handle_vblank(dev, 0); - if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) - drm_handle_vblank(dev, 1); - } else { - if (stat & RADEON_CRTC_VBLANK_STAT) - drm_handle_vblank(dev, 0); - if (stat & RADEON_CRTC2_VBLANK_STAT) - drm_handle_vblank(dev, 1); - } - return IRQ_HANDLED; -} - -static int radeon_emit_irq(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - unsigned int ret; - RING_LOCALS; - - atomic_inc(&dev_priv->swi_emitted); - ret = atomic_read(&dev_priv->swi_emitted); - - BEGIN_RING(4); - OUT_RING_REG(RADEON_LAST_SWI_REG, ret); - OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE); - ADVANCE_RING(); - COMMIT_RING(); - - return ret; -} - -static int radeon_wait_irq(struct drm_device * dev, int swi_nr) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - int ret = 0; - - if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) - return 0; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, - RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); - - return ret; -} - -u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if (crtc < 0 || crtc > 1) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { - if (crtc == 0) - return RADEON_READ(R500_D1CRTC_FRAME_COUNT); - else - return RADEON_READ(R500_D2CRTC_FRAME_COUNT); - } else { - if (crtc == 0) - return RADEON_READ(RADEON_CRTC_CRNT_FRAME); - else - return RADEON_READ(RADEON_CRTC2_CRNT_FRAME); - } -} - -/* Needs the lock as it touches the ring. - */ -int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_irq_emit_t *emit = data; - int result; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return -EINVAL; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - result = radeon_emit_irq(dev); - - if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -/* Doesn't need the hardware lock. - */ -int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_irq_wait_t *irqwait = data; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return -EINVAL; - - return radeon_wait_irq(dev, irqwait->irq_seq); -} - -/* drm_dma.h hooks -*/ -void radeon_driver_irq_preinstall(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - u32 dummy; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return; - - /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) - RADEON_WRITE(R500_DxMODE_INT_MASK, 0); - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - - /* Clear bits if they're already high */ - radeon_acknowledge_irqs(dev_priv, &dummy); -} - -int radeon_driver_irq_postinstall(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - - atomic_set(&dev_priv->swi_emitted, 0); - DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - - dev->max_vblank_count = 0x001fffff; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return 0; - - radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); - - return 0; -} - -void radeon_driver_irq_uninstall(struct drm_device * dev) -{ - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - if (!dev_priv) - return; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - return; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) - RADEON_WRITE(R500_DxMODE_INT_MASK, 0); - /* Disable *all* interrupts */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); -} - - -int radeon_vblank_crtc_get(struct drm_device *dev) -{ - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - - return dev_priv->vblank_crtc; -} - -int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value) -{ - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { - DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value); - return -EINVAL; - } - dev_priv->vblank_crtc = (unsigned int)value; - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq_kms.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq_kms.c deleted file mode 100644 index 65060b77..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "radeon_drm.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "atom.h" - -irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) -{ - struct drm_device *dev = (struct drm_device *) arg; - struct radeon_device *rdev = dev->dev_private; - - return radeon_irq_process(rdev); -} - -/* - * Handle hotplug events outside the interrupt handler proper. - */ -static void radeon_hotplug_work_func(struct work_struct *work) -{ - struct radeon_device *rdev = container_of(work, struct radeon_device, - hotplug_work); - struct drm_device *dev = rdev->ddev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *connector; - - if (mode_config->num_connector) { - list_for_each_entry(connector, &mode_config->connector_list, head) - radeon_connector_hotplug(connector); - } - /* Just fire off a uevent and let userspace tell us what to do */ - drm_helper_hpd_irq_event(dev); -} - -void radeon_driver_irq_preinstall_kms(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - unsigned i; - - /* Disable *all* interrupts */ - for (i = 0; i < RADEON_NUM_RINGS; i++) - rdev->irq.sw_int[i] = false; - rdev->irq.gui_idle = false; - for (i = 0; i < RADEON_MAX_HPD_PINS; i++) - rdev->irq.hpd[i] = false; - for (i = 0; i < RADEON_MAX_CRTCS; i++) { - rdev->irq.crtc_vblank_int[i] = false; - rdev->irq.pflip[i] = false; - } - radeon_irq_set(rdev); - /* Clear bits */ - radeon_irq_process(rdev); -} - -int radeon_driver_irq_postinstall_kms(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - unsigned i; - - dev->max_vblank_count = 0x001fffff; - for (i = 0; i < RADEON_NUM_RINGS; i++) - rdev->irq.sw_int[i] = true; - radeon_irq_set(rdev); - return 0; -} - -void radeon_driver_irq_uninstall_kms(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - unsigned i; - - if (rdev == NULL) { - return; - } - /* Disable *all* interrupts */ - for (i = 0; i < RADEON_NUM_RINGS; i++) - rdev->irq.sw_int[i] = false; - rdev->irq.gui_idle = false; - for (i = 0; i < RADEON_MAX_HPD_PINS; i++) - rdev->irq.hpd[i] = false; - for (i = 0; i < RADEON_MAX_CRTCS; i++) { - rdev->irq.crtc_vblank_int[i] = false; - rdev->irq.pflip[i] = false; - } - radeon_irq_set(rdev); -} - -static bool radeon_msi_ok(struct radeon_device *rdev) -{ - /* RV370/RV380 was first asic with MSI support */ - if (rdev->family < CHIP_RV380) - return false; - - /* MSIs don't work on AGP */ - if (rdev->flags & RADEON_IS_AGP) - return false; - - /* force MSI on */ - if (radeon_msi == 1) - return true; - else if (radeon_msi == 0) - return false; - - /* Quirks */ - /* HP RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x103c) && - (rdev->pdev->subsystem_device == 0x30c2)) - return true; - - /* Dell RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x1028) && - (rdev->pdev->subsystem_device == 0x01fc)) - return true; - - /* Dell RS690 only seems to work with MSIs. */ - if ((rdev->pdev->device == 0x791f) && - (rdev->pdev->subsystem_vendor == 0x1028) && - (rdev->pdev->subsystem_device == 0x01fd)) - return true; - - /* RV515 seems to have MSI issues where it loses - * MSI rearms occasionally. This leads to lockups and freezes. - * disable it by default. - */ - if (rdev->family == CHIP_RV515) - return false; - if (rdev->flags & RADEON_IS_IGP) { - /* APUs work fine with MSIs */ - if (rdev->family >= CHIP_PALM) - return true; - /* lots of IGPs have problems with MSIs */ - return false; - } - - return true; -} - -int radeon_irq_kms_init(struct radeon_device *rdev) -{ - int i; - int r = 0; - - INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); - - spin_lock_init(&rdev->irq.sw_lock); - for (i = 0; i < rdev->num_crtc; i++) - spin_lock_init(&rdev->irq.pflip_lock[i]); - r = drm_vblank_init(rdev->ddev, rdev->num_crtc); - if (r) { - return r; - } - /* enable msi */ - rdev->msi_enabled = 0; - - if (radeon_msi_ok(rdev)) { - int ret = pci_enable_msi(rdev->pdev); - if (!ret) { - rdev->msi_enabled = 1; - dev_info(rdev->dev, "radeon: using MSI.\n"); - } - } - rdev->irq.installed = true; - r = drm_irq_install(rdev->ddev); - if (r) { - rdev->irq.installed = false; - return r; - } - DRM_INFO("radeon: irq initialized.\n"); - return 0; -} - -void radeon_irq_kms_fini(struct radeon_device *rdev) -{ - drm_vblank_cleanup(rdev->ddev); - if (rdev->irq.installed) { - drm_irq_uninstall(rdev->ddev); - rdev->irq.installed = false; - if (rdev->msi_enabled) - pci_disable_msi(rdev->pdev); - } - flush_work_sync(&rdev->hotplug_work); -} - -void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring) -{ - unsigned long irqflags; - - spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); - if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount[ring] == 1)) { - rdev->irq.sw_int[ring] = true; - radeon_irq_set(rdev); - } - spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); -} - -void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) -{ - unsigned long irqflags; - - spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); - BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount[ring] <= 0); - if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount[ring] == 0)) { - rdev->irq.sw_int[ring] = false; - radeon_irq_set(rdev); - } - spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); -} - -void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) -{ - unsigned long irqflags; - - if (crtc < 0 || crtc >= rdev->num_crtc) - return; - - spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); - if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == 1)) { - rdev->irq.pflip[crtc] = true; - radeon_irq_set(rdev); - } - spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); -} - -void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) -{ - unsigned long irqflags; - - if (crtc < 0 || crtc >= rdev->num_crtc) - return; - - spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); - BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); - if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { - rdev->irq.pflip[crtc] = false; - radeon_irq_set(rdev); - } - spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_kms.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_kms.c deleted file mode 100644 index 3c2628b1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_kms.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "drm_sarea.h" -#include "radeon.h" -#include "radeon_drm.h" - -#include -#include - -int radeon_driver_unload_kms(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - - if (rdev == NULL) - return 0; - radeon_modeset_fini(rdev); - radeon_device_fini(rdev); - kfree(rdev); - dev->dev_private = NULL; - return 0; -} - -int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) -{ - struct radeon_device *rdev; - int r, acpi_status; - - rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL); - if (rdev == NULL) { - return -ENOMEM; - } - dev->dev_private = (void *)rdev; - - pci_set_master(dev->pdev); - - /* update BUS flag */ - if (drm_pci_device_is_agp(dev)) { - flags |= RADEON_IS_AGP; - } else if (pci_is_pcie(dev->pdev)) { - flags |= RADEON_IS_PCIE; - } else { - flags |= RADEON_IS_PCI; - } - - /* radeon_device_init should report only fatal error - * like memory allocation failure or iomapping failure, - * or memory manager initialization failure, it must - * properly initialize the GPU MC controller and permit - * VRAM allocation - */ - r = radeon_device_init(rdev, dev, dev->pdev, flags); - if (r) { - dev_err(&dev->pdev->dev, "Fatal error during GPU init\n"); - goto out; - } - - /* Call ACPI methods */ - acpi_status = radeon_acpi_init(rdev); - if (acpi_status) - dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n"); - - /* Again modeset_init should fail only on fatal error - * otherwise it should provide enough functionalities - * for shadowfb to run - */ - r = radeon_modeset_init(rdev); - if (r) - dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); -out: - if (r) - radeon_driver_unload_kms(dev); - return r; -} - -static void radeon_set_filp_rights(struct drm_device *dev, - struct drm_file **owner, - struct drm_file *applier, - uint32_t *value) -{ - mutex_lock(&dev->struct_mutex); - if (*value == 1) { - /* wants rights */ - if (!*owner) - *owner = applier; - } else if (*value == 0) { - /* revokes rights */ - if (*owner == applier) - *owner = NULL; - } - *value = *owner == applier ? 1 : 0; - mutex_unlock(&dev->struct_mutex); -} - -/* - * Userspace get information ioctl - */ -int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_radeon_info *info; - struct radeon_mode_info *minfo = &rdev->mode_info; - uint32_t *value_ptr; - uint32_t value; - struct drm_crtc *crtc; - int i, found; - - info = data; - value_ptr = (uint32_t *)((unsigned long)info->value); - if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) - return -EFAULT; - - switch (info->request) { - case RADEON_INFO_DEVICE_ID: - value = dev->pci_device; - break; - case RADEON_INFO_NUM_GB_PIPES: - value = rdev->num_gb_pipes; - break; - case RADEON_INFO_NUM_Z_PIPES: - value = rdev->num_z_pipes; - break; - case RADEON_INFO_ACCEL_WORKING: - /* xf86-video-ati 6.13.0 relies on this being false for evergreen */ - if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) - value = false; - else - value = rdev->accel_working; - break; - case RADEON_INFO_CRTC_FROM_ID: - for (i = 0, found = 0; i < rdev->num_crtc; i++) { - crtc = (struct drm_crtc *)minfo->crtcs[i]; - if (crtc && crtc->base.id == value) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - value = radeon_crtc->crtc_id; - found = 1; - break; - } - } - if (!found) { - DRM_DEBUG_KMS("unknown crtc id %d\n", value); - return -EINVAL; - } - break; - case RADEON_INFO_ACCEL_WORKING2: - value = rdev->accel_working; - break; - case RADEON_INFO_TILING_CONFIG: - if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.tile_config; - else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.tile_config; - else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.tile_config; - else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.tile_config; - else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.tile_config; - else { - DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); - return -EINVAL; - } - break; - case RADEON_INFO_WANT_HYPERZ: - /* The "value" here is both an input and output parameter. - * If the input value is 1, filp requests hyper-z access. - * If the input value is 0, filp revokes its hyper-z access. - * - * When returning, the value is 1 if filp owns hyper-z access, - * 0 otherwise. */ - if (value >= 2) { - DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value); - return -EINVAL; - } - radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value); - break; - case RADEON_INFO_WANT_CMASK: - /* The same logic as Hyper-Z. */ - if (value >= 2) { - DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value); - return -EINVAL; - } - radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value); - break; - case RADEON_INFO_CLOCK_CRYSTAL_FREQ: - /* return clock value in KHz */ - value = rdev->clock.spll.reference_freq * 10; - break; - case RADEON_INFO_NUM_BACKENDS: - if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_backends_per_se * - rdev->config.si.max_shader_engines; - else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_backends_per_se * - rdev->config.cayman.max_shader_engines; - else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.max_backends; - else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.max_backends; - else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.max_backends; - else { - return -EINVAL; - } - break; - case RADEON_INFO_NUM_TILE_PIPES: - if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_tile_pipes; - else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_tile_pipes; - else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.max_tile_pipes; - else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.max_tile_pipes; - else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.max_tile_pipes; - else { - return -EINVAL; - } - break; - case RADEON_INFO_FUSION_GART_WORKING: - value = 1; - break; - case RADEON_INFO_BACKEND_MAP: - if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.backend_map; - else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.backend_map; - else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.backend_map; - else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.backend_map; - else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.backend_map; - else { - return -EINVAL; - } - break; - case RADEON_INFO_VA_START: - /* this is where we report if vm is supported or not */ - if (rdev->family < CHIP_CAYMAN) - return -EINVAL; - value = RADEON_VA_RESERVED_SIZE; - break; - case RADEON_INFO_IB_VM_MAX_SIZE: - /* this is where we report if vm is supported or not */ - if (rdev->family < CHIP_CAYMAN) - return -EINVAL; - value = RADEON_IB_VM_MAX_SIZE; - break; - case RADEON_INFO_MAX_PIPES: - if (rdev->family >= CHIP_TAHITI) - value = rdev->config.si.max_pipes_per_simd; - else if (rdev->family >= CHIP_CAYMAN) - value = rdev->config.cayman.max_pipes_per_simd; - else if (rdev->family >= CHIP_CEDAR) - value = rdev->config.evergreen.max_pipes; - else if (rdev->family >= CHIP_RV770) - value = rdev->config.rv770.max_pipes; - else if (rdev->family >= CHIP_R600) - value = rdev->config.r600.max_pipes; - else { - return -EINVAL; - } - break; - default: - DRM_DEBUG_KMS("Invalid request %d\n", info->request); - return -EINVAL; - } - if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - return 0; -} - - -/* - * Outdated mess for old drm with Xorg being in charge (void function now). - */ -int radeon_driver_firstopen_kms(struct drm_device *dev) -{ - return 0; -} - -void radeon_driver_lastclose_kms(struct drm_device *dev) -{ - vga_switcheroo_process_delayed_switch(); -} - -int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) -{ - struct radeon_device *rdev = dev->dev_private; - - file_priv->driver_priv = NULL; - - /* new gpu have virtual address space support */ - if (rdev->family >= CHIP_CAYMAN) { - struct radeon_fpriv *fpriv; - int r; - - fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); - if (unlikely(!fpriv)) { - return -ENOMEM; - } - - r = radeon_vm_init(rdev, &fpriv->vm); - if (r) { - radeon_vm_fini(rdev, &fpriv->vm); - kfree(fpriv); - return r; - } - - file_priv->driver_priv = fpriv; - } - return 0; -} - -void radeon_driver_postclose_kms(struct drm_device *dev, - struct drm_file *file_priv) -{ - struct radeon_device *rdev = dev->dev_private; - - /* new gpu have virtual address space support */ - if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { - struct radeon_fpriv *fpriv = file_priv->driver_priv; - - radeon_vm_fini(rdev, &fpriv->vm); - kfree(fpriv); - file_priv->driver_priv = NULL; - } -} - -void radeon_driver_preclose_kms(struct drm_device *dev, - struct drm_file *file_priv) -{ - struct radeon_device *rdev = dev->dev_private; - if (rdev->hyperz_filp == file_priv) - rdev->hyperz_filp = NULL; - if (rdev->cmask_filp == file_priv) - rdev->cmask_filp = NULL; -} - -/* - * VBlank related functions. - */ -u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) -{ - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= rdev->num_crtc) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; - } - - return radeon_get_vblank_counter(rdev, crtc); -} - -int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) -{ - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= rdev->num_crtc) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; - } - - rdev->irq.crtc_vblank_int[crtc] = true; - - return radeon_irq_set(rdev); -} - -void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) -{ - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= rdev->num_crtc) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return; - } - - rdev->irq.crtc_vblank_int[crtc] = false; - - radeon_irq_set(rdev); -} - -int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, - int *max_error, - struct timeval *vblank_time, - unsigned flags) -{ - struct drm_crtc *drmcrtc; - struct radeon_device *rdev = dev->dev_private; - - if (crtc < 0 || crtc >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %d\n", crtc); - return -EINVAL; - } - - /* Get associated drm_crtc: */ - drmcrtc = &rdev->mode_info.crtcs[crtc]->base; - - /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, - vblank_time, flags, - drmcrtc); -} - -/* - * IOCTL. - */ -int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - /* Not valid in KMS. */ - return -EINVAL; -} - -#define KMS_INVALID_IOCTL(name) \ -int name(struct drm_device *dev, void *data, struct drm_file *file_priv)\ -{ \ - DRM_ERROR("invalid ioctl with kms %s\n", __func__); \ - return -EINVAL; \ -} - -/* - * All these ioctls are invalid in kms world. - */ -KMS_INVALID_IOCTL(radeon_cp_init_kms) -KMS_INVALID_IOCTL(radeon_cp_start_kms) -KMS_INVALID_IOCTL(radeon_cp_stop_kms) -KMS_INVALID_IOCTL(radeon_cp_reset_kms) -KMS_INVALID_IOCTL(radeon_cp_idle_kms) -KMS_INVALID_IOCTL(radeon_cp_resume_kms) -KMS_INVALID_IOCTL(radeon_engine_reset_kms) -KMS_INVALID_IOCTL(radeon_fullscreen_kms) -KMS_INVALID_IOCTL(radeon_cp_swap_kms) -KMS_INVALID_IOCTL(radeon_cp_clear_kms) -KMS_INVALID_IOCTL(radeon_cp_vertex_kms) -KMS_INVALID_IOCTL(radeon_cp_indices_kms) -KMS_INVALID_IOCTL(radeon_cp_texture_kms) -KMS_INVALID_IOCTL(radeon_cp_stipple_kms) -KMS_INVALID_IOCTL(radeon_cp_indirect_kms) -KMS_INVALID_IOCTL(radeon_cp_vertex2_kms) -KMS_INVALID_IOCTL(radeon_cp_cmdbuf_kms) -KMS_INVALID_IOCTL(radeon_cp_getparam_kms) -KMS_INVALID_IOCTL(radeon_cp_flip_kms) -KMS_INVALID_IOCTL(radeon_mem_alloc_kms) -KMS_INVALID_IOCTL(radeon_mem_free_kms) -KMS_INVALID_IOCTL(radeon_mem_init_heap_kms) -KMS_INVALID_IOCTL(radeon_irq_emit_kms) -KMS_INVALID_IOCTL(radeon_irq_wait_kms) -KMS_INVALID_IOCTL(radeon_cp_setparam_kms) -KMS_INVALID_IOCTL(radeon_surface_alloc_kms) -KMS_INVALID_IOCTL(radeon_surface_free_kms) - - -struct drm_ioctl_desc radeon_ioctls_kms[] = { - DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), - /* KMS */ - DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|DRM_UNLOCKED), -}; -int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_crtc.c deleted file mode 100644 index 210317c7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include -#include -#include -#include -#include "radeon.h" -#include "atom.h" - -static void radeon_overscan_setup(struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - WREG32(RADEON_OVR_CLR + radeon_crtc->crtc_offset, 0); - WREG32(RADEON_OVR_WID_LEFT_RIGHT + radeon_crtc->crtc_offset, 0); - WREG32(RADEON_OVR_WID_TOP_BOTTOM + radeon_crtc->crtc_offset, 0); -} - -static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - int xres = mode->hdisplay; - int yres = mode->vdisplay; - bool hscale = true, vscale = true; - int hsync_wid; - int vsync_wid; - int hsync_start; - int blank_width; - u32 scale, inc, crtc_more_cntl; - u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active; - u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp; - u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp; - struct drm_display_mode *native_mode = &radeon_crtc->native_mode; - - fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) & - (RADEON_VERT_STRETCH_RESERVED | - RADEON_VERT_AUTO_RATIO_INC); - fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH) & - (RADEON_HORZ_FP_LOOP_STRETCH | - RADEON_HORZ_AUTO_RATIO_INC); - - crtc_more_cntl = 0; - if ((rdev->family == CHIP_RS100) || - (rdev->family == CHIP_RS200)) { - /* This is to workaround the asic bug for RMX, some versions - of BIOS dosen't have this register initialized correctly. */ - crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN; - } - - - fp_crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff) - | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); - - hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; - if (!hsync_wid) - hsync_wid = 1; - hsync_start = mode->crtc_hsync_start - 8; - - fp_h_sync_strt_wid = ((hsync_start & 0x1fff) - | ((hsync_wid & 0x3f) << 16) - | ((mode->flags & DRM_MODE_FLAG_NHSYNC) - ? RADEON_CRTC_H_SYNC_POL - : 0)); - - fp_crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff) - | ((mode->crtc_vdisplay - 1) << 16)); - - vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; - if (!vsync_wid) - vsync_wid = 1; - - fp_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff) - | ((vsync_wid & 0x1f) << 16) - | ((mode->flags & DRM_MODE_FLAG_NVSYNC) - ? RADEON_CRTC_V_SYNC_POL - : 0)); - - fp_horz_vert_active = 0; - - if (native_mode->hdisplay == 0 || - native_mode->vdisplay == 0) { - hscale = false; - vscale = false; - } else { - if (xres > native_mode->hdisplay) - xres = native_mode->hdisplay; - if (yres > native_mode->vdisplay) - yres = native_mode->vdisplay; - - if (xres == native_mode->hdisplay) - hscale = false; - if (yres == native_mode->vdisplay) - vscale = false; - } - - switch (radeon_crtc->rmx_type) { - case RMX_FULL: - case RMX_ASPECT: - if (!hscale) - fp_horz_stretch |= ((xres/8-1) << 16); - else { - inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; - scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) - / native_mode->hdisplay + 1; - fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | - RADEON_HORZ_STRETCH_BLEND | - RADEON_HORZ_STRETCH_ENABLE | - ((native_mode->hdisplay/8-1) << 16)); - } - - if (!vscale) - fp_vert_stretch |= ((yres-1) << 12); - else { - inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; - scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) - / native_mode->vdisplay + 1; - fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | - RADEON_VERT_STRETCH_ENABLE | - RADEON_VERT_STRETCH_BLEND | - ((native_mode->vdisplay-1) << 12)); - } - break; - case RMX_CENTER: - fp_horz_stretch |= ((xres/8-1) << 16); - fp_vert_stretch |= ((yres-1) << 12); - - crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN | - RADEON_CRTC_AUTO_VERT_CENTER_EN); - - blank_width = (mode->crtc_hblank_end - mode->crtc_hblank_start) / 8; - if (blank_width > 110) - blank_width = 110; - - fp_crtc_h_total_disp = (((blank_width) & 0x3ff) - | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); - - hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; - if (!hsync_wid) - hsync_wid = 1; - - fp_h_sync_strt_wid = ((((mode->crtc_hsync_start - mode->crtc_hblank_start) / 8) & 0x1fff) - | ((hsync_wid & 0x3f) << 16) - | ((mode->flags & DRM_MODE_FLAG_NHSYNC) - ? RADEON_CRTC_H_SYNC_POL - : 0)); - - fp_crtc_v_total_disp = (((mode->crtc_vblank_end - mode->crtc_vblank_start) & 0xffff) - | ((mode->crtc_vdisplay - 1) << 16)); - - vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; - if (!vsync_wid) - vsync_wid = 1; - - fp_v_sync_strt_wid = ((((mode->crtc_vsync_start - mode->crtc_vblank_start) & 0xfff) - | ((vsync_wid & 0x1f) << 16) - | ((mode->flags & DRM_MODE_FLAG_NVSYNC) - ? RADEON_CRTC_V_SYNC_POL - : 0))); - - fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) | - (((native_mode->hdisplay / 8) & 0x1ff) << 16)); - break; - case RMX_OFF: - default: - fp_horz_stretch |= ((xres/8-1) << 16); - fp_vert_stretch |= ((yres-1) << 12); - break; - } - - WREG32(RADEON_FP_HORZ_STRETCH, fp_horz_stretch); - WREG32(RADEON_FP_VERT_STRETCH, fp_vert_stretch); - WREG32(RADEON_CRTC_MORE_CNTL, crtc_more_cntl); - WREG32(RADEON_FP_HORZ_VERT_ACTIVE, fp_horz_vert_active); - WREG32(RADEON_FP_H_SYNC_STRT_WID, fp_h_sync_strt_wid); - WREG32(RADEON_FP_V_SYNC_STRT_WID, fp_v_sync_strt_wid); - WREG32(RADEON_FP_CRTC_H_TOTAL_DISP, fp_crtc_h_total_disp); - WREG32(RADEON_FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp); -} - -void radeon_restore_common_regs(struct drm_device *dev) -{ - /* don't need this yet */ -} - -static void radeon_pll_wait_for_read_update_complete(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - int i = 0; - - /* FIXME: Certain revisions of R300 can't recover here. Not sure of - the cause yet, but this workaround will mask the problem for now. - Other chips usually will pass at the very first test, so the - workaround shouldn't have any effect on them. */ - for (i = 0; - (i < 10000 && - RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R); - i++); -} - -static void radeon_pll_write_update(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - - while (RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R); - - WREG32_PLL_P(RADEON_PPLL_REF_DIV, - RADEON_PPLL_ATOMIC_UPDATE_W, - ~(RADEON_PPLL_ATOMIC_UPDATE_W)); -} - -static void radeon_pll2_wait_for_read_update_complete(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - int i = 0; - - - /* FIXME: Certain revisions of R300 can't recover here. Not sure of - the cause yet, but this workaround will mask the problem for now. - Other chips usually will pass at the very first test, so the - workaround shouldn't have any effect on them. */ - for (i = 0; - (i < 10000 && - RREG32_PLL(RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R); - i++); -} - -static void radeon_pll2_write_update(struct drm_device *dev) -{ - struct radeon_device *rdev = dev->dev_private; - - while (RREG32_PLL(RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R); - - WREG32_PLL_P(RADEON_P2PLL_REF_DIV, - RADEON_P2PLL_ATOMIC_UPDATE_W, - ~(RADEON_P2PLL_ATOMIC_UPDATE_W)); -} - -static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, - uint16_t fb_div) -{ - unsigned int vcoFreq; - - if (!ref_div) - return 1; - - vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div; - - /* - * This is horribly crude: the VCO frequency range is divided into - * 3 parts, each part having a fixed PLL gain value. - */ - if (vcoFreq >= 30000) - /* - * [300..max] MHz : 7 - */ - return 7; - else if (vcoFreq >= 18000) - /* - * [180..300) MHz : 4 - */ - return 4; - else - /* - * [0..180) MHz : 1 - */ - return 1; -} - -void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t mask; - - if (radeon_crtc->crtc_id) - mask = (RADEON_CRTC2_DISP_DIS | - RADEON_CRTC2_VSYNC_DIS | - RADEON_CRTC2_HSYNC_DIS | - RADEON_CRTC2_DISP_REQ_EN_B); - else - mask = (RADEON_CRTC_DISPLAY_DIS | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS); - - switch (mode) { - case DRM_MODE_DPMS_ON: - radeon_crtc->enabled = true; - /* adjust pm to dpms changes BEFORE enabling crtcs */ - radeon_pm_compute_clocks(rdev); - if (radeon_crtc->crtc_id) - WREG32_P(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_EN, ~(RADEON_CRTC2_EN | mask)); - else { - WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | - RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); - } - drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); - radeon_crtc_load_lut(crtc); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); - if (radeon_crtc->crtc_id) - WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); - else { - WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | - RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); - } - radeon_crtc->enabled = false; - /* adjust pm to dpms changes AFTER disabling crtcs */ - radeon_pm_compute_clocks(rdev); - break; - } -} - -int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0); -} - -int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, enum mode_set_atomic state) -{ - return radeon_crtc_do_set_base(crtc, fb, x, y, 1); -} - -int radeon_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct radeon_framebuffer *radeon_fb; - struct drm_framebuffer *target_fb; - struct drm_gem_object *obj; - struct radeon_bo *rbo; - uint64_t base; - uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; - uint32_t crtc_pitch, pitch_pixels; - uint32_t tiling_flags; - int format; - uint32_t gen_cntl_reg, gen_cntl_val; - int r; - - DRM_DEBUG_KMS("\n"); - /* no fb bound */ - if (!atomic && !crtc->fb) { - DRM_DEBUG_KMS("No FB bound\n"); - return 0; - } - - if (atomic) { - radeon_fb = to_radeon_framebuffer(fb); - target_fb = fb; - } - else { - radeon_fb = to_radeon_framebuffer(crtc->fb); - target_fb = crtc->fb; - } - - switch (target_fb->bits_per_pixel) { - case 8: - format = 2; - break; - case 15: /* 555 */ - format = 3; - break; - case 16: /* 565 */ - format = 4; - break; - case 24: /* RGB */ - format = 5; - break; - case 32: /* xRGB */ - format = 6; - break; - default: - return false; - } - - /* Pin framebuffer & get tilling informations */ - obj = radeon_fb->obj; - rbo = gem_to_radeon_bo(obj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - return r; - /* Only 27 bit offset for legacy CRTC */ - r = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM, 1 << 27, - &base); - if (unlikely(r != 0)) { - radeon_bo_unreserve(rbo); - return -EINVAL; - } - radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); - radeon_bo_unreserve(rbo); - if (tiling_flags & RADEON_TILING_MICRO) - DRM_ERROR("trying to scanout microtiled buffer\n"); - - /* if scanout was in GTT this really wouldn't work */ - /* crtc offset is from display base addr not FB location */ - radeon_crtc->legacy_display_base_addr = rdev->mc.vram_start; - - base -= radeon_crtc->legacy_display_base_addr; - - crtc_offset_cntl = 0; - - pitch_pixels = target_fb->pitches[0] / (target_fb->bits_per_pixel / 8); - crtc_pitch = (((pitch_pixels * target_fb->bits_per_pixel) + - ((target_fb->bits_per_pixel * 8) - 1)) / - (target_fb->bits_per_pixel * 8)); - crtc_pitch |= crtc_pitch << 16; - - crtc_offset_cntl |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN; - if (tiling_flags & RADEON_TILING_MACRO) { - if (ASIC_IS_R300(rdev)) - crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | - R300_CRTC_MICRO_TILE_BUFFER_DIS | - R300_CRTC_MACRO_TILE_EN); - else - crtc_offset_cntl |= RADEON_CRTC_TILE_EN; - } else { - if (ASIC_IS_R300(rdev)) - crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN | - R300_CRTC_MICRO_TILE_BUFFER_DIS | - R300_CRTC_MACRO_TILE_EN); - else - crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN; - } - - if (tiling_flags & RADEON_TILING_MACRO) { - if (ASIC_IS_R300(rdev)) { - crtc_tile_x0_y0 = x | (y << 16); - base &= ~0x7ff; - } else { - int byteshift = target_fb->bits_per_pixel >> 4; - int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11; - base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); - crtc_offset_cntl |= (y % 16); - } - } else { - int offset = y * pitch_pixels + x; - switch (target_fb->bits_per_pixel) { - case 8: - offset *= 1; - break; - case 15: - case 16: - offset *= 2; - break; - case 24: - offset *= 3; - break; - case 32: - offset *= 4; - break; - default: - return false; - } - base += offset; - } - - base &= ~7; - - if (radeon_crtc->crtc_id == 1) - gen_cntl_reg = RADEON_CRTC2_GEN_CNTL; - else - gen_cntl_reg = RADEON_CRTC_GEN_CNTL; - - gen_cntl_val = RREG32(gen_cntl_reg); - gen_cntl_val &= ~(0xf << 8); - gen_cntl_val |= (format << 8); - gen_cntl_val &= ~RADEON_CRTC_VSTAT_MODE_MASK; - WREG32(gen_cntl_reg, gen_cntl_val); - - crtc_offset = (u32)base; - - WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr); - - if (ASIC_IS_R300(rdev)) { - if (radeon_crtc->crtc_id) - WREG32(R300_CRTC2_TILE_X0_Y0, crtc_tile_x0_y0); - else - WREG32(R300_CRTC_TILE_X0_Y0, crtc_tile_x0_y0); - } - WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, crtc_offset_cntl); - WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); - WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); - - if (!atomic && fb && fb != crtc->fb) { - radeon_fb = to_radeon_framebuffer(fb); - rbo = gem_to_radeon_bo(radeon_fb->obj); - r = radeon_bo_reserve(rbo, false); - if (unlikely(r != 0)) - return r; - radeon_bo_unpin(rbo); - radeon_bo_unreserve(rbo); - } - - /* Bytes per pixel may have changed */ - radeon_bandwidth_update(rdev); - - return 0; -} - -static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mode *mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_encoder *encoder; - int format; - int hsync_start; - int hsync_wid; - int vsync_wid; - uint32_t crtc_h_total_disp; - uint32_t crtc_h_sync_strt_wid; - uint32_t crtc_v_total_disp; - uint32_t crtc_v_sync_strt_wid; - bool is_tv = false; - - DRM_DEBUG_KMS("\n"); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { - is_tv = true; - DRM_INFO("crtc %d is connected to a TV\n", radeon_crtc->crtc_id); - break; - } - } - } - - switch (crtc->fb->bits_per_pixel) { - case 8: - format = 2; - break; - case 15: /* 555 */ - format = 3; - break; - case 16: /* 565 */ - format = 4; - break; - case 24: /* RGB */ - format = 5; - break; - case 32: /* xRGB */ - format = 6; - break; - default: - return false; - } - - crtc_h_total_disp = ((((mode->crtc_htotal / 8) - 1) & 0x3ff) - | ((((mode->crtc_hdisplay / 8) - 1) & 0x1ff) << 16)); - - hsync_wid = (mode->crtc_hsync_end - mode->crtc_hsync_start) / 8; - if (!hsync_wid) - hsync_wid = 1; - hsync_start = mode->crtc_hsync_start - 8; - - crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) - | ((hsync_wid & 0x3f) << 16) - | ((mode->flags & DRM_MODE_FLAG_NHSYNC) - ? RADEON_CRTC_H_SYNC_POL - : 0)); - - /* This works for double scan mode. */ - crtc_v_total_disp = (((mode->crtc_vtotal - 1) & 0xffff) - | ((mode->crtc_vdisplay - 1) << 16)); - - vsync_wid = mode->crtc_vsync_end - mode->crtc_vsync_start; - if (!vsync_wid) - vsync_wid = 1; - - crtc_v_sync_strt_wid = (((mode->crtc_vsync_start - 1) & 0xfff) - | ((vsync_wid & 0x1f) << 16) - | ((mode->flags & DRM_MODE_FLAG_NVSYNC) - ? RADEON_CRTC_V_SYNC_POL - : 0)); - - if (radeon_crtc->crtc_id) { - uint32_t crtc2_gen_cntl; - uint32_t disp2_merge_cntl; - - /* if TV DAC is enabled for another crtc and keep it enabled */ - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL) & 0x00718080; - crtc2_gen_cntl |= ((format << 8) - | RADEON_CRTC2_VSYNC_DIS - | RADEON_CRTC2_HSYNC_DIS - | RADEON_CRTC2_DISP_DIS - | RADEON_CRTC2_DISP_REQ_EN_B - | ((mode->flags & DRM_MODE_FLAG_DBLSCAN) - ? RADEON_CRTC2_DBL_SCAN_EN - : 0) - | ((mode->flags & DRM_MODE_FLAG_CSYNC) - ? RADEON_CRTC2_CSYNC_EN - : 0) - | ((mode->flags & DRM_MODE_FLAG_INTERLACE) - ? RADEON_CRTC2_INTERLACE_EN - : 0)); - - /* rs4xx chips seem to like to have the crtc enabled when the timing is set */ - if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480)) - crtc2_gen_cntl |= RADEON_CRTC2_EN; - - disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL); - disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; - - WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - - WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid); - WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid); - } else { - uint32_t crtc_gen_cntl; - uint32_t crtc_ext_cntl; - uint32_t disp_merge_cntl; - - crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL) & 0x00718000; - crtc_gen_cntl |= (RADEON_CRTC_EXT_DISP_EN - | (format << 8) - | RADEON_CRTC_DISP_REQ_EN_B - | ((mode->flags & DRM_MODE_FLAG_DBLSCAN) - ? RADEON_CRTC_DBL_SCAN_EN - : 0) - | ((mode->flags & DRM_MODE_FLAG_CSYNC) - ? RADEON_CRTC_CSYNC_EN - : 0) - | ((mode->flags & DRM_MODE_FLAG_INTERLACE) - ? RADEON_CRTC_INTERLACE_EN - : 0)); - - /* rs4xx chips seem to like to have the crtc enabled when the timing is set */ - if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480)) - crtc_gen_cntl |= RADEON_CRTC_EN; - - crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - crtc_ext_cntl |= (RADEON_XCRT_CNT_EN | - RADEON_CRTC_VSYNC_DIS | - RADEON_CRTC_HSYNC_DIS | - RADEON_CRTC_DISPLAY_DIS); - - disp_merge_cntl = RREG32(RADEON_DISP_MERGE_CNTL); - disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; - - WREG32(RADEON_DISP_MERGE_CNTL, disp_merge_cntl); - WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); - } - - if (is_tv) - radeon_legacy_tv_adjust_crtc_reg(encoder, &crtc_h_total_disp, - &crtc_h_sync_strt_wid, &crtc_v_total_disp, - &crtc_v_sync_strt_wid); - - WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp); - WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid); - WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp); - WREG32(RADEON_CRTC_V_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_v_sync_strt_wid); - - return true; -} - -static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) -{ - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - struct drm_encoder *encoder; - uint32_t feedback_div = 0; - uint32_t frac_fb_div = 0; - uint32_t reference_div = 0; - uint32_t post_divider = 0; - uint32_t freq = 0; - uint8_t pll_gain; - bool use_bios_divs = false; - /* PLL registers */ - uint32_t pll_ref_div = 0; - uint32_t pll_fb_post_div = 0; - uint32_t htotal_cntl = 0; - bool is_tv = false; - struct radeon_pll *pll; - - struct { - int divider; - int bitvalue; - } *post_div, post_divs[] = { - /* From RAGE 128 VR/RAGE 128 GL Register - * Reference Manual (Technical Reference - * Manual P/N RRG-G04100-C Rev. 0.04), page - * 3-17 (PLL_DIV_[3:0]). - */ - { 1, 0 }, /* VCLK_SRC */ - { 2, 1 }, /* VCLK_SRC/2 */ - { 4, 2 }, /* VCLK_SRC/4 */ - { 8, 3 }, /* VCLK_SRC/8 */ - { 3, 4 }, /* VCLK_SRC/3 */ - { 16, 5 }, /* VCLK_SRC/16 */ - { 6, 6 }, /* VCLK_SRC/6 */ - { 12, 7 }, /* VCLK_SRC/12 */ - { 0, 0 } - }; - - if (radeon_crtc->crtc_id) - pll = &rdev->clock.p2pll; - else - pll = &rdev->clock.p1pll; - - pll->flags = RADEON_PLL_LEGACY; - - if (mode->clock > 200000) /* range limits??? */ - pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; - else - pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - - if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { - is_tv = true; - break; - } - - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) - pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; - if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { - if (!rdev->is_atom_bios) { - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; - if (lvds) { - if (lvds->use_bios_dividers) { - pll_ref_div = lvds->panel_ref_divider; - pll_fb_post_div = (lvds->panel_fb_divider | - (lvds->panel_post_divider << 16)); - htotal_cntl = 0; - use_bios_divs = true; - } - } - } - pll->flags |= RADEON_PLL_USE_REF_DIV; - } - } - } - - DRM_DEBUG_KMS("\n"); - - if (!use_bios_divs) { - radeon_compute_pll_legacy(pll, mode->clock, - &freq, &feedback_div, &frac_fb_div, - &reference_div, &post_divider); - - for (post_div = &post_divs[0]; post_div->divider; ++post_div) { - if (post_div->divider == post_divider) - break; - } - - if (!post_div->divider) - post_div = &post_divs[0]; - - DRM_DEBUG_KMS("dc=%u, fd=%d, rd=%d, pd=%d\n", - (unsigned)freq, - feedback_div, - reference_div, - post_divider); - - pll_ref_div = reference_div; -#if defined(__powerpc__) && (0) /* TODO */ - /* apparently programming this otherwise causes a hang??? */ - if (info->MacModel == RADEON_MAC_IBOOK) - pll_fb_post_div = 0x000600ad; - else -#endif - pll_fb_post_div = (feedback_div | (post_div->bitvalue << 16)); - - htotal_cntl = mode->htotal & 0x7; - - } - - pll_gain = radeon_compute_pll_gain(pll->reference_freq, - pll_ref_div & 0x3ff, - pll_fb_post_div & 0x7ff); - - if (radeon_crtc->crtc_id) { - uint32_t pixclks_cntl = ((RREG32_PLL(RADEON_PIXCLKS_CNTL) & - ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | - RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); - - if (is_tv) { - radeon_legacy_tv_adjust_pll2(encoder, &htotal_cntl, - &pll_ref_div, &pll_fb_post_div, - &pixclks_cntl); - } - - WREG32_PLL_P(RADEON_PIXCLKS_CNTL, - RADEON_PIX2CLK_SRC_SEL_CPUCLK, - ~(RADEON_PIX2CLK_SRC_SEL_MASK)); - - WREG32_PLL_P(RADEON_P2PLL_CNTL, - RADEON_P2PLL_RESET - | RADEON_P2PLL_ATOMIC_UPDATE_EN - | ((uint32_t)pll_gain << RADEON_P2PLL_PVG_SHIFT), - ~(RADEON_P2PLL_RESET - | RADEON_P2PLL_ATOMIC_UPDATE_EN - | RADEON_P2PLL_PVG_MASK)); - - WREG32_PLL_P(RADEON_P2PLL_REF_DIV, - pll_ref_div, - ~RADEON_P2PLL_REF_DIV_MASK); - - WREG32_PLL_P(RADEON_P2PLL_DIV_0, - pll_fb_post_div, - ~RADEON_P2PLL_FB0_DIV_MASK); - - WREG32_PLL_P(RADEON_P2PLL_DIV_0, - pll_fb_post_div, - ~RADEON_P2PLL_POST0_DIV_MASK); - - radeon_pll2_write_update(dev); - radeon_pll2_wait_for_read_update_complete(dev); - - WREG32_PLL(RADEON_HTOTAL2_CNTL, htotal_cntl); - - WREG32_PLL_P(RADEON_P2PLL_CNTL, - 0, - ~(RADEON_P2PLL_RESET - | RADEON_P2PLL_SLEEP - | RADEON_P2PLL_ATOMIC_UPDATE_EN)); - - DRM_DEBUG_KMS("Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n", - (unsigned)pll_ref_div, - (unsigned)pll_fb_post_div, - (unsigned)htotal_cntl, - RREG32_PLL(RADEON_P2PLL_CNTL)); - DRM_DEBUG_KMS("Wrote2: rd=%u, fd=%u, pd=%u\n", - (unsigned)pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, - (unsigned)pll_fb_post_div & RADEON_P2PLL_FB0_DIV_MASK, - (unsigned)((pll_fb_post_div & - RADEON_P2PLL_POST0_DIV_MASK) >> 16)); - - mdelay(50); /* Let the clock to lock */ - - WREG32_PLL_P(RADEON_PIXCLKS_CNTL, - RADEON_PIX2CLK_SRC_SEL_P2PLLCLK, - ~(RADEON_PIX2CLK_SRC_SEL_MASK)); - - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - } else { - uint32_t pixclks_cntl; - - - if (is_tv) { - pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); - radeon_legacy_tv_adjust_pll1(encoder, &htotal_cntl, &pll_ref_div, - &pll_fb_post_div, &pixclks_cntl); - } - - if (rdev->flags & RADEON_IS_MOBILITY) { - /* A temporal workaround for the occasional blanking on certain laptop panels. - This appears to related to the PLL divider registers (fail to lock?). - It occurs even when all dividers are the same with their old settings. - In this case we really don't need to fiddle with PLL registers. - By doing this we can avoid the blanking problem with some panels. - */ - if ((pll_ref_div == (RREG32_PLL(RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) && - (pll_fb_post_div == (RREG32_PLL(RADEON_PPLL_DIV_3) & - (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) { - WREG32_P(RADEON_CLOCK_CNTL_INDEX, - RADEON_PLL_DIV_SEL, - ~(RADEON_PLL_DIV_SEL)); - r100_pll_errata_after_index(rdev); - return; - } - } - - WREG32_PLL_P(RADEON_VCLK_ECP_CNTL, - RADEON_VCLK_SRC_SEL_CPUCLK, - ~(RADEON_VCLK_SRC_SEL_MASK)); - WREG32_PLL_P(RADEON_PPLL_CNTL, - RADEON_PPLL_RESET - | RADEON_PPLL_ATOMIC_UPDATE_EN - | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN - | ((uint32_t)pll_gain << RADEON_PPLL_PVG_SHIFT), - ~(RADEON_PPLL_RESET - | RADEON_PPLL_ATOMIC_UPDATE_EN - | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN - | RADEON_PPLL_PVG_MASK)); - - WREG32_P(RADEON_CLOCK_CNTL_INDEX, - RADEON_PLL_DIV_SEL, - ~(RADEON_PLL_DIV_SEL)); - r100_pll_errata_after_index(rdev); - - if (ASIC_IS_R300(rdev) || - (rdev->family == CHIP_RS300) || - (rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { - if (pll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { - /* When restoring console mode, use saved PPLL_REF_DIV - * setting. - */ - WREG32_PLL_P(RADEON_PPLL_REF_DIV, - pll_ref_div, - 0); - } else { - /* R300 uses ref_div_acc field as real ref divider */ - WREG32_PLL_P(RADEON_PPLL_REF_DIV, - (pll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), - ~R300_PPLL_REF_DIV_ACC_MASK); - } - } else - WREG32_PLL_P(RADEON_PPLL_REF_DIV, - pll_ref_div, - ~RADEON_PPLL_REF_DIV_MASK); - - WREG32_PLL_P(RADEON_PPLL_DIV_3, - pll_fb_post_div, - ~RADEON_PPLL_FB3_DIV_MASK); - - WREG32_PLL_P(RADEON_PPLL_DIV_3, - pll_fb_post_div, - ~RADEON_PPLL_POST3_DIV_MASK); - - radeon_pll_write_update(dev); - radeon_pll_wait_for_read_update_complete(dev); - - WREG32_PLL(RADEON_HTOTAL_CNTL, htotal_cntl); - - WREG32_PLL_P(RADEON_PPLL_CNTL, - 0, - ~(RADEON_PPLL_RESET - | RADEON_PPLL_SLEEP - | RADEON_PPLL_ATOMIC_UPDATE_EN - | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); - - DRM_DEBUG_KMS("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", - pll_ref_div, - pll_fb_post_div, - (unsigned)htotal_cntl, - RREG32_PLL(RADEON_PPLL_CNTL)); - DRM_DEBUG_KMS("Wrote: rd=%d, fd=%d, pd=%d\n", - pll_ref_div & RADEON_PPLL_REF_DIV_MASK, - pll_fb_post_div & RADEON_PPLL_FB3_DIV_MASK, - (pll_fb_post_div & RADEON_PPLL_POST3_DIV_MASK) >> 16); - - mdelay(50); /* Let the clock to lock */ - - WREG32_PLL_P(RADEON_VCLK_ECP_CNTL, - RADEON_VCLK_SRC_SEL_PPLLCLK, - ~(RADEON_VCLK_SRC_SEL_MASK)); - - if (is_tv) - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - } -} - -static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) - return false; - return true; -} - -static int radeon_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - - /* TODO TV */ - radeon_crtc_set_base(crtc, x, y, old_fb); - radeon_set_crtc_timing(crtc, adjusted_mode); - radeon_set_pll(crtc, adjusted_mode); - radeon_overscan_setup(crtc, adjusted_mode); - if (radeon_crtc->crtc_id == 0) { - radeon_legacy_rmx_mode_set(crtc, adjusted_mode); - } else { - if (radeon_crtc->rmx_type != RMX_OFF) { - /* FIXME: only first crtc has rmx what should we - * do ? - */ - DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); - } - } - return 0; -} - -static void radeon_crtc_prepare(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_crtc *crtci; - - /* - * The hardware wedges sometimes if you reconfigure one CRTC - * whilst another is running (see fdo bug #24611). - */ - list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) - radeon_crtc_dpms(crtci, DRM_MODE_DPMS_OFF); -} - -static void radeon_crtc_commit(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_crtc *crtci; - - /* - * Reenable the CRTCs that should be running. - */ - list_for_each_entry(crtci, &dev->mode_config.crtc_list, head) { - if (crtci->enabled) - radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); - } -} - -static const struct drm_crtc_helper_funcs legacy_helper_funcs = { - .dpms = radeon_crtc_dpms, - .mode_fixup = radeon_crtc_mode_fixup, - .mode_set = radeon_crtc_mode_set, - .mode_set_base = radeon_crtc_set_base, - .mode_set_base_atomic = radeon_crtc_set_base_atomic, - .prepare = radeon_crtc_prepare, - .commit = radeon_crtc_commit, - .load_lut = radeon_crtc_load_lut, -}; - - -void radeon_legacy_init_crtc(struct drm_device *dev, - struct radeon_crtc *radeon_crtc) -{ - if (radeon_crtc->crtc_id == 1) - radeon_crtc->crtc_offset = RADEON_CRTC2_H_TOTAL_DISP - RADEON_CRTC_H_TOTAL_DISP; - drm_crtc_helper_add(&radeon_crtc->base, &legacy_helper_funcs); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_encoders.c deleted file mode 100644 index 42db254f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* - * Copyright 2007-8 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - */ -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "radeon_drm.h" -#include "radeon.h" -#include "atom.h" -#include -#ifdef CONFIG_PMAC_BACKLIGHT -#include -#endif - -static void radeon_legacy_encoder_disable(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder_helper_funcs *encoder_funcs; - - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); - radeon_encoder->active_device = 0; -} - -static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; - int panel_pwr_delay = 2000; - bool is_mac = false; - uint8_t backlight_level; - DRM_DEBUG_KMS("\n"); - - lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); - backlight_level = (lvds_gen_cntl >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; - - if (radeon_encoder->enc_priv) { - if (rdev->is_atom_bios) { - struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; - panel_pwr_delay = lvds->panel_pwr_delay; - if (lvds->bl_dev) - backlight_level = lvds->backlight_level; - } else { - struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; - panel_pwr_delay = lvds->panel_pwr_delay; - if (lvds->bl_dev) - backlight_level = lvds->backlight_level; - } - } - - /* macs (and possibly some x86 oem systems?) wire up LVDS strangely - * Taken from radeonfb. - */ - if ((rdev->mode_info.connector_table == CT_IBOOK) || - (rdev->mode_info.connector_table == CT_POWERBOOK_EXTERNAL) || - (rdev->mode_info.connector_table == CT_POWERBOOK_INTERNAL) || - (rdev->mode_info.connector_table == CT_POWERBOOK_VGA)) - is_mac = true; - - switch (mode) { - case DRM_MODE_DPMS_ON: - disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); - disp_pwr_man |= RADEON_AUTO_PWRUP_EN; - WREG32(RADEON_DISP_PWR_MAN, disp_pwr_man); - lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); - lvds_pll_cntl |= RADEON_LVDS_PLL_EN; - WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - mdelay(1); - - lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); - lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; - WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - - lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS | - RADEON_LVDS_BL_MOD_LEVEL_MASK); - lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | - RADEON_LVDS_DIGON | RADEON_LVDS_BLON | - (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); - if (is_mac) - lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; - mdelay(panel_pwr_delay); - WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); - WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); - lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - if (is_mac) { - lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; - WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); - lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_EN); - } else { - WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); - lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); - } - mdelay(panel_pwr_delay); - WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - mdelay(panel_pwr_delay); - break; - } - - if (rdev->is_atom_bios) - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - else - radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - -} - -static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - DRM_DEBUG("\n"); - - if (radeon_encoder->enc_priv) { - if (rdev->is_atom_bios) { - struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; - lvds->dpms_mode = mode; - } else { - struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; - lvds->dpms_mode = mode; - } - } - - radeon_legacy_lvds_update(encoder, mode); -} - -static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON); - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, false); - else - radeon_combios_output_lock(encoder, false); -} - -static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; - - DRM_DEBUG_KMS("\n"); - - lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); - lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; - - lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); - if (rdev->is_atom_bios) { - /* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl - * need to call that on resume to set up the reg properly. - */ - radeon_encoder->pixel_clock = adjusted_mode->clock; - atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); - lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); - } else { - struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; - if (lvds) { - DRM_DEBUG_KMS("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); - lvds_gen_cntl = lvds->lvds_gen_cntl; - lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | - (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); - lvds_ss_gen_cntl |= ((lvds->panel_digon_delay << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | - (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); - } else - lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); - } - lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; - lvds_gen_cntl &= ~(RADEON_LVDS_ON | - RADEON_LVDS_BLON | - RADEON_LVDS_EN | - RADEON_LVDS_RST_FM); - - if (ASIC_IS_R300(rdev)) - lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK); - - if (radeon_crtc->crtc_id == 0) { - if (ASIC_IS_R300(rdev)) { - if (radeon_encoder->rmx_type != RMX_OFF) - lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX; - } else - lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2; - } else { - if (ASIC_IS_R300(rdev)) - lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2; - else - lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; - } - - WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); - WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - WREG32(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl); - - if (rdev->family == CHIP_RV410) - WREG32(RADEON_CLOCK_CNTL_INDEX, 0); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - else - radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); -} - -static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - - /* set the active encoder to connector routing */ - radeon_encoder_set_active_device(encoder); - drm_mode_set_crtcinfo(adjusted_mode, 0); - - /* get the native mode for LVDS */ - if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) - radeon_panel_mode_fixup(encoder, adjusted_mode); - - return true; -} - -static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { - .dpms = radeon_legacy_lvds_dpms, - .mode_fixup = radeon_legacy_mode_fixup, - .prepare = radeon_legacy_lvds_prepare, - .mode_set = radeon_legacy_lvds_mode_set, - .commit = radeon_legacy_lvds_commit, - .disable = radeon_legacy_encoder_disable, -}; - -#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) - -#define MAX_RADEON_LEVEL 0xFF - -struct radeon_backlight_privdata { - struct radeon_encoder *encoder; - uint8_t negative; -}; - -static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) -{ - struct radeon_backlight_privdata *pdata = bl_get_data(bd); - uint8_t level; - - /* Convert brightness to hardware level */ - if (bd->props.brightness < 0) - level = 0; - else if (bd->props.brightness > MAX_RADEON_LEVEL) - level = MAX_RADEON_LEVEL; - else - level = bd->props.brightness; - - if (pdata->negative) - level = MAX_RADEON_LEVEL - level; - - return level; -} - -static int radeon_legacy_backlight_update_status(struct backlight_device *bd) -{ - struct radeon_backlight_privdata *pdata = bl_get_data(bd); - struct radeon_encoder *radeon_encoder = pdata->encoder; - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - int dpms_mode = DRM_MODE_DPMS_ON; - - if (radeon_encoder->enc_priv) { - if (rdev->is_atom_bios) { - struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; - dpms_mode = lvds->dpms_mode; - lvds->backlight_level = radeon_legacy_lvds_level(bd); - } else { - struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; - dpms_mode = lvds->dpms_mode; - lvds->backlight_level = radeon_legacy_lvds_level(bd); - } - } - - if (bd->props.brightness > 0) - radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); - else - radeon_legacy_lvds_update(&radeon_encoder->base, DRM_MODE_DPMS_OFF); - - return 0; -} - -static int radeon_legacy_backlight_get_brightness(struct backlight_device *bd) -{ - struct radeon_backlight_privdata *pdata = bl_get_data(bd); - struct radeon_encoder *radeon_encoder = pdata->encoder; - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint8_t backlight_level; - - backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> - RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; - - return pdata->negative ? MAX_RADEON_LEVEL - backlight_level : backlight_level; -} - -static const struct backlight_ops radeon_backlight_ops = { - .get_brightness = radeon_legacy_backlight_get_brightness, - .update_status = radeon_legacy_backlight_update_status, -}; - -void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, - struct drm_connector *drm_connector) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct backlight_device *bd; - struct backlight_properties props; - struct radeon_backlight_privdata *pdata; - uint8_t backlight_level; - - if (!radeon_encoder->enc_priv) - return; - -#ifdef CONFIG_PMAC_BACKLIGHT - if (!pmac_has_backlight_type("ati") && - !pmac_has_backlight_type("mnca")) - return; -#endif - - pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL); - if (!pdata) { - DRM_ERROR("Memory allocation failed\n"); - goto error; - } - - props.max_brightness = MAX_RADEON_LEVEL; - props.type = BACKLIGHT_RAW; - bd = backlight_device_register("radeon_bl", &drm_connector->kdev, - pdata, &radeon_backlight_ops, &props); - if (IS_ERR(bd)) { - DRM_ERROR("Backlight registration failed\n"); - goto error; - } - - pdata->encoder = radeon_encoder; - - backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> - RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; - - /* First, try to detect backlight level sense based on the assumption - * that firmware set it up at full brightness - */ - if (backlight_level == 0) - pdata->negative = true; - else if (backlight_level == 0xff) - pdata->negative = false; - else { - /* XXX hack... maybe some day we can figure out in what direction - * backlight should work on a given panel? - */ - pdata->negative = (rdev->family != CHIP_RV200 && - rdev->family != CHIP_RV250 && - rdev->family != CHIP_RV280 && - rdev->family != CHIP_RV350); - -#ifdef CONFIG_PMAC_BACKLIGHT - pdata->negative = (pdata->negative || - of_machine_is_compatible("PowerBook4,3") || - of_machine_is_compatible("PowerBook6,3") || - of_machine_is_compatible("PowerBook6,5")); -#endif - } - - if (rdev->is_atom_bios) { - struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; - lvds->bl_dev = bd; - } else { - struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; - lvds->bl_dev = bd; - } - - bd->props.brightness = radeon_legacy_backlight_get_brightness(bd); - bd->props.power = FB_BLANK_UNBLANK; - backlight_update_status(bd); - - DRM_INFO("radeon legacy LVDS backlight initialized\n"); - - return; - -error: - kfree(pdata); - return; -} - -static void radeon_legacy_backlight_exit(struct radeon_encoder *radeon_encoder) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct backlight_device *bd = NULL; - - if (!radeon_encoder->enc_priv) - return; - - if (rdev->is_atom_bios) { - struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; - bd = lvds->bl_dev; - lvds->bl_dev = NULL; - } else { - struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; - bd = lvds->bl_dev; - lvds->bl_dev = NULL; - } - - if (bd) { - struct radeon_legacy_backlight_privdata *pdata; - - pdata = bl_get_data(bd); - backlight_device_unregister(bd); - kfree(pdata); - - DRM_INFO("radeon legacy LVDS backlight unloaded\n"); - } -} - -#else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */ - -void radeon_legacy_backlight_init(struct radeon_encoder *encoder) -{ -} - -static void radeon_legacy_backlight_exit(struct radeon_encoder *encoder) -{ -} - -#endif - - -static void radeon_lvds_enc_destroy(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - - if (radeon_encoder->enc_priv) { - radeon_legacy_backlight_exit(radeon_encoder); - kfree(radeon_encoder->enc_priv); - } - drm_encoder_cleanup(encoder); - kfree(radeon_encoder); -} - -static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { - .destroy = radeon_lvds_enc_destroy, -}; - -static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL); - uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); - - DRM_DEBUG_KMS("\n"); - - switch (mode) { - case DRM_MODE_DPMS_ON: - crtc_ext_cntl |= RADEON_CRTC_CRT_ON; - dac_cntl &= ~RADEON_DAC_PDWN; - dac_macro_cntl &= ~(RADEON_DAC_PDWN_R | - RADEON_DAC_PDWN_G | - RADEON_DAC_PDWN_B); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; - dac_cntl |= RADEON_DAC_PDWN; - dac_macro_cntl |= (RADEON_DAC_PDWN_R | - RADEON_DAC_PDWN_G | - RADEON_DAC_PDWN_B); - break; - } - - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); - WREG32(RADEON_DAC_CNTL, dac_cntl); - WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - else - radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - -} - -static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON); - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, false); - else - radeon_combios_output_lock(encoder, false); -} - -static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; - - DRM_DEBUG_KMS("\n"); - - if (radeon_crtc->crtc_id == 0) { - if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL) & - ~(RADEON_DISP_DAC_SOURCE_MASK); - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - } else { - dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~(RADEON_DAC2_DAC_CLK_SEL); - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - } - } else { - if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL) & - ~(RADEON_DISP_DAC_SOURCE_MASK); - disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2; - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - } else { - dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC_CLK_SEL; - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - } - } - - dac_cntl = (RADEON_DAC_MASK_ALL | - RADEON_DAC_VGA_ADR_EN | - /* TODO 6-bits */ - RADEON_DAC_8BIT_EN); - - WREG32_P(RADEON_DAC_CNTL, - dac_cntl, - RADEON_DAC_RANGE_CNTL | - RADEON_DAC_BLANKING); - - if (radeon_encoder->enc_priv) { - struct radeon_encoder_primary_dac *p_dac = (struct radeon_encoder_primary_dac *)radeon_encoder->enc_priv; - dac_macro_cntl = p_dac->ps2_pdac_adj; - } else - dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); - dac_macro_cntl |= RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B; - WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - else - radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); -} - -static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t vclk_ecp_cntl, crtc_ext_cntl; - uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp; - enum drm_connector_status found = connector_status_disconnected; - bool color = true; - - /* save the regs we need */ - vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL); - crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); - dac_cntl = RREG32(RADEON_DAC_CNTL); - dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); - - tmp = vclk_ecp_cntl & - ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - - tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; - WREG32(RADEON_CRTC_EXT_CNTL, tmp); - - tmp = RADEON_DAC_FORCE_BLANK_OFF_EN | - RADEON_DAC_FORCE_DATA_EN; - - if (color) - tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; - else - tmp |= RADEON_DAC_FORCE_DATA_SEL_G; - - if (ASIC_IS_R300(rdev)) - tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); - else - tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); - - WREG32(RADEON_DAC_EXT_CNTL, tmp); - - tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN); - tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; - WREG32(RADEON_DAC_CNTL, tmp); - - tmp &= ~(RADEON_DAC_PDWN_R | - RADEON_DAC_PDWN_G | - RADEON_DAC_PDWN_B); - - WREG32(RADEON_DAC_MACRO_CNTL, tmp); - - mdelay(2); - - if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) - found = connector_status_connected; - - /* restore the regs we used */ - WREG32(RADEON_DAC_CNTL, dac_cntl); - WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); - WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); - WREG32_PLL(RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl); - - return found; -} - -static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { - .dpms = radeon_legacy_primary_dac_dpms, - .mode_fixup = radeon_legacy_mode_fixup, - .prepare = radeon_legacy_primary_dac_prepare, - .mode_set = radeon_legacy_primary_dac_mode_set, - .commit = radeon_legacy_primary_dac_commit, - .detect = radeon_legacy_primary_dac_detect, - .disable = radeon_legacy_encoder_disable, -}; - - -static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { - .destroy = radeon_enc_destroy, -}; - -static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL); - DRM_DEBUG_KMS("\n"); - - switch (mode) { - case DRM_MODE_DPMS_ON: - fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - break; - } - - WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - else - radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - -} - -static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON); - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); -} - -static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; - int i; - - DRM_DEBUG_KMS("\n"); - - tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL); - tmp &= 0xfffff; - if (rdev->family == CHIP_RV280) { - /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ - tmp ^= (1 << 22); - tmds_pll_cntl ^= (1 << 22); - } - - if (radeon_encoder->enc_priv) { - struct radeon_encoder_int_tmds *tmds = (struct radeon_encoder_int_tmds *)radeon_encoder->enc_priv; - - for (i = 0; i < 4; i++) { - if (tmds->tmds_pll[i].freq == 0) - break; - if ((uint32_t)(mode->clock / 10) < tmds->tmds_pll[i].freq) { - tmp = tmds->tmds_pll[i].value ; - break; - } - } - } - - if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV280)) { - if (tmp & 0xfff00000) - tmds_pll_cntl = tmp; - else { - tmds_pll_cntl &= 0xfff00000; - tmds_pll_cntl |= tmp; - } - } else - tmds_pll_cntl = tmp; - - tmds_transmitter_cntl = RREG32(RADEON_TMDS_TRANSMITTER_CNTL) & - ~(RADEON_TMDS_TRANSMITTER_PLLRST); - - if (rdev->family == CHIP_R200 || - rdev->family == CHIP_R100 || - ASIC_IS_R300(rdev)) - tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN); - else /* RV chips got this bit reversed */ - tmds_transmitter_cntl |= RADEON_TMDS_TRANSMITTER_PLLEN; - - fp_gen_cntl = (RREG32(RADEON_FP_GEN_CNTL) | - (RADEON_FP_CRTC_DONT_SHADOW_VPAR | - RADEON_FP_CRTC_DONT_SHADOW_HEND)); - - fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - - fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | - RADEON_FP_DFP_SYNC_SEL | - RADEON_FP_CRT_SYNC_SEL | - RADEON_FP_CRTC_LOCK_8DOT | - RADEON_FP_USE_SHADOW_EN | - RADEON_FP_CRTC_USE_SHADOW_VEND | - RADEON_FP_CRT_SYNC_ALT); - - if (1) /* FIXME rgbBits == 8 */ - fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ - else - fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */ - - if (radeon_crtc->crtc_id == 0) { - if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { - fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; - if (radeon_encoder->rmx_type != RMX_OFF) - fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX; - else - fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; - } else - fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2; - } else { - if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { - fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; - fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2; - } else - fp_gen_cntl |= RADEON_FP_SEL_CRTC2; - } - - WREG32(RADEON_TMDS_PLL_CNTL, tmds_pll_cntl); - WREG32(RADEON_TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl); - WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - else - radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); -} - -static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { - .dpms = radeon_legacy_tmds_int_dpms, - .mode_fixup = radeon_legacy_mode_fixup, - .prepare = radeon_legacy_tmds_int_prepare, - .mode_set = radeon_legacy_tmds_int_mode_set, - .commit = radeon_legacy_tmds_int_commit, - .disable = radeon_legacy_encoder_disable, -}; - - -static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { - .destroy = radeon_enc_destroy, -}; - -static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - DRM_DEBUG_KMS("\n"); - - switch (mode) { - case DRM_MODE_DPMS_ON: - fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; - fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - fp2_gen_cntl |= RADEON_FP2_BLANK_EN; - fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - break; - } - - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - else - radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - -} - -static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON); - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, false); - else - radeon_combios_output_lock(encoder, false); -} - -static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t fp2_gen_cntl; - - DRM_DEBUG_KMS("\n"); - - if (rdev->is_atom_bios) { - radeon_encoder->pixel_clock = adjusted_mode->clock; - atombios_dvo_setup(encoder, ATOM_ENABLE); - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - } else { - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - - if (1) /* FIXME rgbBits == 8 */ - fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */ - else - fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */ - - fp2_gen_cntl &= ~(RADEON_FP2_ON | - RADEON_FP2_DVO_EN | - RADEON_FP2_DVO_RATE_SEL_SDR); - - /* XXX: these are oem specific */ - if (ASIC_IS_R300(rdev)) { - if ((dev->pdev->device == 0x4850) && - (dev->pdev->subsystem_vendor == 0x1028) && - (dev->pdev->subsystem_device == 0x2001)) /* Dell Inspiron 8600 */ - fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE; - else - fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE; - - /*if (mode->clock > 165000) - fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ - } - if (!radeon_combios_external_tmds_setup(encoder)) - radeon_external_tmds_setup(encoder); - } - - if (radeon_crtc->crtc_id == 0) { - if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)) { - fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; - if (radeon_encoder->rmx_type != RMX_OFF) - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; - else - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; - } else - fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2; - } else { - if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)) { - fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; - } else - fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; - } - - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - else - radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); -} - -static void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv; - if (tmds) { - if (tmds->i2c_bus) - radeon_i2c_destroy(tmds->i2c_bus); - } - kfree(radeon_encoder->enc_priv); - drm_encoder_cleanup(encoder); - kfree(radeon_encoder); -} - -static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { - .dpms = radeon_legacy_tmds_ext_dpms, - .mode_fixup = radeon_legacy_mode_fixup, - .prepare = radeon_legacy_tmds_ext_prepare, - .mode_set = radeon_legacy_tmds_ext_mode_set, - .commit = radeon_legacy_tmds_ext_commit, - .disable = radeon_legacy_encoder_disable, -}; - - -static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { - .destroy = radeon_ext_tmds_enc_destroy, -}; - -static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; - uint32_t tv_master_cntl = 0; - bool is_tv; - DRM_DEBUG_KMS("\n"); - - is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; - - if (rdev->family == CHIP_R200) - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - else { - if (is_tv) - tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); - else - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - } - - switch (mode) { - case DRM_MODE_DPMS_ON: - if (rdev->family == CHIP_R200) { - fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); - } else { - if (is_tv) - tv_master_cntl |= RADEON_TV_ON; - else - crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; - - if (rdev->family == CHIP_R420 || - rdev->family == CHIP_R423 || - rdev->family == CHIP_RV410) - tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | - R420_TV_DAC_GDACPD | - R420_TV_DAC_BDACPD | - RADEON_TV_DAC_BGSLEEP); - else - tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD | - RADEON_TV_DAC_BGSLEEP); - } - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (rdev->family == CHIP_R200) - fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - else { - if (is_tv) - tv_master_cntl &= ~RADEON_TV_ON; - else - crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; - - if (rdev->family == CHIP_R420 || - rdev->family == CHIP_R423 || - rdev->family == CHIP_RV410) - tv_dac_cntl |= (R420_TV_DAC_RDACPD | - R420_TV_DAC_GDACPD | - R420_TV_DAC_BDACPD | - RADEON_TV_DAC_BGSLEEP); - else - tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD | - RADEON_TV_DAC_BGSLEEP); - } - break; - } - - if (rdev->family == CHIP_R200) { - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - } else { - if (is_tv) - WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - else - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - } - - if (rdev->is_atom_bios) - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - else - radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); - -} - -static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) -{ - struct radeon_device *rdev = encoder->dev->dev_private; - - radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON); - - if (rdev->is_atom_bios) - radeon_atom_output_lock(encoder, true); - else - radeon_combios_output_lock(encoder, true); -} - -static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; - uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; - bool is_tv = false; - - DRM_DEBUG_KMS("\n"); - - is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; - - if (rdev->family != CHIP_R200) { - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - if (rdev->family == CHIP_R420 || - rdev->family == CHIP_R423 || - rdev->family == CHIP_RV410) { - tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | - RADEON_TV_DAC_BGADJ_MASK | - R420_TV_DAC_DACADJ_MASK | - R420_TV_DAC_RDACPD | - R420_TV_DAC_GDACPD | - R420_TV_DAC_BDACPD | - R420_TV_DAC_TVENABLE); - } else { - tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | - RADEON_TV_DAC_BGADJ_MASK | - RADEON_TV_DAC_DACADJ_MASK | - RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD); - } - - tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; - - if (is_tv) { - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) - tv_dac_cntl |= tv_dac->ntsc_tvdac_adj; - else - tv_dac_cntl |= tv_dac->pal_tvdac_adj; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J) - tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; - else - tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; - } else - tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 | - tv_dac->ps2_tvdac_adj); - - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - } - - if (ASIC_IS_R300(rdev)) { - gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - } else if (rdev->family != CHIP_R200) - disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - else if (rdev->family == CHIP_R200) - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - - if (rdev->family >= CHIP_R200) - disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL); - - if (is_tv) { - uint32_t dac_cntl; - - dac_cntl = RREG32(RADEON_DAC_CNTL); - dac_cntl &= ~RADEON_DAC_TVO_EN; - WREG32(RADEON_DAC_CNTL, dac_cntl); - - if (ASIC_IS_R300(rdev)) - gpiopad_a = RREG32(RADEON_GPIOPAD_A) & ~1; - - dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~RADEON_DAC2_DAC2_CLK_SEL; - if (radeon_crtc->crtc_id == 0) { - if (ASIC_IS_R300(rdev)) { - disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; - disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC | - RADEON_DISP_TV_SOURCE_CRTC); - } - if (rdev->family >= CHIP_R200) { - disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2; - } else { - disp_hw_debug |= RADEON_CRT2_DISP1_SEL; - } - } else { - if (ASIC_IS_R300(rdev)) { - disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; - disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC; - } - if (rdev->family >= CHIP_R200) { - disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2; - } else { - disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; - } - } - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - } else { - - dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; - - if (radeon_crtc->crtc_id == 0) { - if (ASIC_IS_R300(rdev)) { - disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; - disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; - } else if (rdev->family == CHIP_R200) { - fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_RATE_SEL_SDR); - } else - disp_hw_debug |= RADEON_CRT2_DISP1_SEL; - } else { - if (ASIC_IS_R300(rdev)) { - disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; - disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - } else if (rdev->family == CHIP_R200) { - fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | - RADEON_FP2_DVO_RATE_SEL_SDR); - fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; - } else - disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; - } - WREG32(RADEON_DAC_CNTL2, dac2_cntl); - } - - if (ASIC_IS_R300(rdev)) { - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - } else if (rdev->family != CHIP_R200) - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - else if (rdev->family == CHIP_R200) - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - - if (rdev->family >= CHIP_R200) - WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl); - - if (is_tv) - radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode); - - if (rdev->is_atom_bios) - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - else - radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - -} - -static bool r300_legacy_tv_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; - uint32_t disp_output_cntl, gpiopad_a, tmp; - bool found = false; - - /* save regs needed */ - gpiopad_a = RREG32(RADEON_GPIOPAD_A); - dac_cntl2 = RREG32(RADEON_DAC_CNTL2); - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - - WREG32_P(RADEON_GPIOPAD_A, 0, ~1); - - WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL); - - WREG32(RADEON_CRTC2_GEN_CNTL, - RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT); - - tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; - tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); - - WREG32(RADEON_DAC_EXT_CNTL, - RADEON_DAC2_FORCE_BLANK_OFF_EN | - RADEON_DAC2_FORCE_DATA_EN | - RADEON_DAC_FORCE_DATA_SEL_RGB | - (0xec << RADEON_DAC_FORCE_DATA_SHIFT)); - - WREG32(RADEON_TV_DAC_CNTL, - RADEON_TV_DAC_STD_NTSC | - (8 << RADEON_TV_DAC_BGADJ_SHIFT) | - (6 << RADEON_TV_DAC_DACADJ_SHIFT)); - - RREG32(RADEON_TV_DAC_CNTL); - mdelay(4); - - WREG32(RADEON_TV_DAC_CNTL, - RADEON_TV_DAC_NBLANK | - RADEON_TV_DAC_NHOLD | - RADEON_TV_MONITOR_DETECT_EN | - RADEON_TV_DAC_STD_NTSC | - (8 << RADEON_TV_DAC_BGADJ_SHIFT) | - (6 << RADEON_TV_DAC_DACADJ_SHIFT)); - - RREG32(RADEON_TV_DAC_CNTL); - mdelay(6); - - tmp = RREG32(RADEON_TV_DAC_CNTL); - if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { - found = true; - DRM_DEBUG_KMS("S-video TV connection detected\n"); - } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { - found = true; - DRM_DEBUG_KMS("Composite TV connection detected\n"); - } - - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32(RADEON_DAC_CNTL2, dac_cntl2); - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); - return found; -} - -static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tv_dac_cntl, dac_cntl2; - uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp; - bool found = false; - - if (ASIC_IS_R300(rdev)) - return r300_legacy_tv_detect(encoder, connector); - - dac_cntl2 = RREG32(RADEON_DAC_CNTL2); - tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - config_cntl = RREG32(RADEON_CONFIG_CNTL); - tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL); - - tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL; - WREG32(RADEON_DAC_CNTL2, tmp); - - tmp = tv_master_cntl | RADEON_TV_ON; - tmp &= ~(RADEON_TV_ASYNC_RST | - RADEON_RESTART_PHASE_FIX | - RADEON_CRT_FIFO_CE_EN | - RADEON_TV_FIFO_CE_EN | - RADEON_RE_SYNC_NOW_SEL_MASK); - tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST; - WREG32(RADEON_TV_MASTER_CNTL, tmp); - - tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | - RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC | - (8 << RADEON_TV_DAC_BGADJ_SHIFT); - - if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK) - tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT); - else - tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT); - WREG32(RADEON_TV_DAC_CNTL, tmp); - - tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN | - RADEON_RED_MX_FORCE_DAC_DATA | - RADEON_GRN_MX_FORCE_DAC_DATA | - RADEON_BLU_MX_FORCE_DAC_DATA | - (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT); - WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp); - - mdelay(3); - tmp = RREG32(RADEON_TV_DAC_CNTL); - if (tmp & RADEON_TV_DAC_GDACDET) { - found = true; - DRM_DEBUG_KMS("S-video TV connection detected\n"); - } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { - found = true; - DRM_DEBUG_KMS("Composite TV connection detected\n"); - } - - WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - WREG32(RADEON_DAC_CNTL2, dac_cntl2); - return found; -} - -static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; - uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; - enum drm_connector_status found = connector_status_disconnected; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - bool color = true; - struct drm_crtc *crtc; - - /* find out if crtc2 is in use or if this encoder is using it */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - if ((radeon_crtc->crtc_id == 1) && crtc->enabled) { - if (encoder->crtc != crtc) { - return connector_status_disconnected; - } - } - } - - if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO || - connector->connector_type == DRM_MODE_CONNECTOR_Composite || - connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN) { - bool tv_detect; - - if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT)) - return connector_status_disconnected; - - tv_detect = radeon_legacy_tv_detect(encoder, connector); - if (tv_detect && tv_dac) - found = connector_status_connected; - return found; - } - - /* don't probe if the encoder is being used for something else not CRT related */ - if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) { - DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device); - return connector_status_disconnected; - } - - /* save the regs we need */ - pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); - gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; - disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; - disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); - dac_cntl2 = RREG32(RADEON_DAC_CNTL2); - - tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb - | RADEON_PIX2CLK_DAC_ALWAYS_ONb); - WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - - if (ASIC_IS_R300(rdev)) - WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - - tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; - tmp |= RADEON_CRTC2_CRT2_ON | - (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); - - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); - - if (ASIC_IS_R300(rdev)) { - tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; - tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); - } else { - tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; - WREG32(RADEON_DISP_HW_DEBUG, tmp); - } - - tmp = RADEON_TV_DAC_NBLANK | - RADEON_TV_DAC_NHOLD | - RADEON_TV_MONITOR_DETECT_EN | - RADEON_TV_DAC_STD_PS2; - - WREG32(RADEON_TV_DAC_CNTL, tmp); - - tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN | - RADEON_DAC2_FORCE_DATA_EN; - - if (color) - tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; - else - tmp |= RADEON_DAC_FORCE_DATA_SEL_G; - - if (ASIC_IS_R300(rdev)) - tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); - else - tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); - - WREG32(RADEON_DAC_EXT_CNTL, tmp); - - tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; - WREG32(RADEON_DAC_CNTL2, tmp); - - mdelay(10); - - if (ASIC_IS_R300(rdev)) { - if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) - found = connector_status_connected; - } else { - if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) - found = connector_status_connected; - } - - /* restore regs we used */ - WREG32(RADEON_DAC_CNTL2, dac_cntl2); - WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - - if (ASIC_IS_R300(rdev)) { - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); - } else { - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - } - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - - return found; - -} - -static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { - .dpms = radeon_legacy_tv_dac_dpms, - .mode_fixup = radeon_legacy_mode_fixup, - .prepare = radeon_legacy_tv_dac_prepare, - .mode_set = radeon_legacy_tv_dac_mode_set, - .commit = radeon_legacy_tv_dac_commit, - .detect = radeon_legacy_tv_dac_detect, - .disable = radeon_legacy_encoder_disable, -}; - - -static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = { - .destroy = radeon_enc_destroy, -}; - - -static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_int_tmds *tmds = NULL; - bool ret; - - tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); - - if (!tmds) - return NULL; - - if (rdev->is_atom_bios) - ret = radeon_atombios_get_tmds_info(encoder, tmds); - else - ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds); - - if (ret == false) - radeon_legacy_get_tmds_info_from_table(encoder, tmds); - - return tmds; -} - -static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder) -{ - struct drm_device *dev = encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_ext_tmds *tmds = NULL; - bool ret; - - if (rdev->is_atom_bios) - return NULL; - - tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL); - - if (!tmds) - return NULL; - - ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds); - - if (ret == false) - radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds); - - return tmds; -} - -void -radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) -{ - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - struct radeon_encoder *radeon_encoder; - - /* see if we already added it */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - radeon_encoder = to_radeon_encoder(encoder); - if (radeon_encoder->encoder_enum == encoder_enum) { - radeon_encoder->devices |= supported_device; - return; - } - - } - - /* add a new one */ - radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); - if (!radeon_encoder) - return; - - encoder = &radeon_encoder->base; - if (rdev->flags & RADEON_SINGLE_CRTC) - encoder->possible_crtcs = 0x1; - else - encoder->possible_crtcs = 0x3; - - radeon_encoder->enc_priv = NULL; - - radeon_encoder->encoder_enum = encoder_enum; - radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - radeon_encoder->devices = supported_device; - radeon_encoder->rmx_type = RMX_OFF; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_LVDS: - encoder->possible_crtcs = 0x1; - drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); - drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); - if (rdev->is_atom_bios) - radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); - else - radeon_encoder->enc_priv = radeon_combios_get_lvds_info(radeon_encoder); - radeon_encoder->rmx_type = RMX_FULL; - break; - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); - radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC); - drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs); - if (rdev->is_atom_bios) - radeon_encoder->enc_priv = radeon_atombios_get_primary_dac_info(radeon_encoder); - else - radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, DRM_MODE_ENCODER_TVDAC); - drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs); - if (rdev->is_atom_bios) - radeon_encoder->enc_priv = radeon_atombios_get_tv_dac_info(radeon_encoder); - else - radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder); - break; - case ENCODER_OBJECT_ID_INTERNAL_DVO1: - drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); - if (!rdev->is_atom_bios) - radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder); - break; - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_tv.c deleted file mode 100644 index b37ec0f1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ /dev/null @@ -1,923 +0,0 @@ -#include "drmP.h" -#include "drm_crtc_helper.h" -#include "radeon.h" - -/* - * Integrated TV out support based on the GATOS code by - * Federico Ulivi - */ - - -/* - * Limits of h/v positions (hPos & vPos) - */ -#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */ -#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */ - -/* - * Unit for hPos (in TV clock periods) - */ -#define H_POS_UNIT 10 - -/* - * Indexes in h. code timing table for horizontal line position adjustment - */ -#define H_TABLE_POS1 6 -#define H_TABLE_POS2 8 - -/* - * Limits of hor. size (hSize) - */ -#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */ - -/* tv standard constants */ -#define NTSC_TV_CLOCK_T 233 -#define NTSC_TV_VFTOTAL 1 -#define NTSC_TV_LINES_PER_FRAME 525 -#define NTSC_TV_ZERO_H_SIZE 479166 -#define NTSC_TV_H_SIZE_UNIT 9478 - -#define PAL_TV_CLOCK_T 188 -#define PAL_TV_VFTOTAL 3 -#define PAL_TV_LINES_PER_FRAME 625 -#define PAL_TV_ZERO_H_SIZE 473200 -#define PAL_TV_H_SIZE_UNIT 9360 - -/* tv pll setting for 27 mhz ref clk */ -#define NTSC_TV_PLL_M_27 22 -#define NTSC_TV_PLL_N_27 175 -#define NTSC_TV_PLL_P_27 5 - -#define PAL_TV_PLL_M_27 113 -#define PAL_TV_PLL_N_27 668 -#define PAL_TV_PLL_P_27 3 - -/* tv pll setting for 14 mhz ref clk */ -#define NTSC_TV_PLL_M_14 33 -#define NTSC_TV_PLL_N_14 693 -#define NTSC_TV_PLL_P_14 7 - -#define PAL_TV_PLL_M_14 19 -#define PAL_TV_PLL_N_14 353 -#define PAL_TV_PLL_P_14 5 - -#define VERT_LEAD_IN_LINES 2 -#define FRAC_BITS 0xe -#define FRAC_MASK 0x3fff - -struct radeon_tv_mode_constants { - uint16_t hor_resolution; - uint16_t ver_resolution; - enum radeon_tv_std standard; - uint16_t hor_total; - uint16_t ver_total; - uint16_t hor_start; - uint16_t hor_syncstart; - uint16_t ver_syncstart; - unsigned def_restart; - uint16_t crtcPLL_N; - uint8_t crtcPLL_M; - uint8_t crtcPLL_post_div; - unsigned pix_to_tv; -}; - -static const uint16_t hor_timing_NTSC[MAX_H_CODE_TIMING_LEN] = { - 0x0007, - 0x003f, - 0x0263, - 0x0a24, - 0x2a6b, - 0x0a36, - 0x126d, /* H_TABLE_POS1 */ - 0x1bfe, - 0x1a8f, /* H_TABLE_POS2 */ - 0x1ec7, - 0x3863, - 0x1bfe, - 0x1bfe, - 0x1a2a, - 0x1e95, - 0x0e31, - 0x201b, - 0 -}; - -static const uint16_t vert_timing_NTSC[MAX_V_CODE_TIMING_LEN] = { - 0x2001, - 0x200d, - 0x1006, - 0x0c06, - 0x1006, - 0x1818, - 0x21e3, - 0x1006, - 0x0c06, - 0x1006, - 0x1817, - 0x21d4, - 0x0002, - 0 -}; - -static const uint16_t hor_timing_PAL[MAX_H_CODE_TIMING_LEN] = { - 0x0007, - 0x0058, - 0x027c, - 0x0a31, - 0x2a77, - 0x0a95, - 0x124f, /* H_TABLE_POS1 */ - 0x1bfe, - 0x1b22, /* H_TABLE_POS2 */ - 0x1ef9, - 0x387c, - 0x1bfe, - 0x1bfe, - 0x1b31, - 0x1eb5, - 0x0e43, - 0x201b, - 0 -}; - -static const uint16_t vert_timing_PAL[MAX_V_CODE_TIMING_LEN] = { - 0x2001, - 0x200c, - 0x1005, - 0x0c05, - 0x1005, - 0x1401, - 0x1821, - 0x2240, - 0x1005, - 0x0c05, - 0x1005, - 0x1401, - 0x1822, - 0x2230, - 0x0002, - 0 -}; - -/********************************************************************** - * - * availableModes - * - * Table of all allowed modes for tv output - * - **********************************************************************/ -static const struct radeon_tv_mode_constants available_tv_modes[] = { - { /* NTSC timing for 27 Mhz ref clk */ - 800, /* horResolution */ - 600, /* verResolution */ - TV_STD_NTSC, /* standard */ - 990, /* horTotal */ - 740, /* verTotal */ - 813, /* horStart */ - 824, /* horSyncStart */ - 632, /* verSyncStart */ - 625592, /* defRestart */ - 592, /* crtcPLL_N */ - 91, /* crtcPLL_M */ - 4, /* crtcPLL_postDiv */ - 1022, /* pixToTV */ - }, - { /* PAL timing for 27 Mhz ref clk */ - 800, /* horResolution */ - 600, /* verResolution */ - TV_STD_PAL, /* standard */ - 1144, /* horTotal */ - 706, /* verTotal */ - 812, /* horStart */ - 824, /* horSyncStart */ - 669, /* verSyncStart */ - 696700, /* defRestart */ - 1382, /* crtcPLL_N */ - 231, /* crtcPLL_M */ - 4, /* crtcPLL_postDiv */ - 759, /* pixToTV */ - }, - { /* NTSC timing for 14 Mhz ref clk */ - 800, /* horResolution */ - 600, /* verResolution */ - TV_STD_NTSC, /* standard */ - 1018, /* horTotal */ - 727, /* verTotal */ - 813, /* horStart */ - 840, /* horSyncStart */ - 633, /* verSyncStart */ - 630627, /* defRestart */ - 347, /* crtcPLL_N */ - 14, /* crtcPLL_M */ - 8, /* crtcPLL_postDiv */ - 1022, /* pixToTV */ - }, - { /* PAL timing for 14 Mhz ref clk */ - 800, /* horResolution */ - 600, /* verResolution */ - TV_STD_PAL, /* standard */ - 1131, /* horTotal */ - 742, /* verTotal */ - 813, /* horStart */ - 840, /* horSyncStart */ - 633, /* verSyncStart */ - 708369, /* defRestart */ - 211, /* crtcPLL_N */ - 9, /* crtcPLL_M */ - 8, /* crtcPLL_postDiv */ - 759, /* pixToTV */ - }, -}; - -#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes) - -static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder, - uint16_t *pll_ref_freq) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc; - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - const struct radeon_tv_mode_constants *const_ptr; - struct radeon_pll *pll; - - radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc); - if (radeon_crtc->crtc_id == 1) - pll = &rdev->clock.p2pll; - else - pll = &rdev->clock.p1pll; - - if (pll_ref_freq) - *pll_ref_freq = pll->reference_freq; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M) { - if (pll->reference_freq == 2700) - const_ptr = &available_tv_modes[0]; - else - const_ptr = &available_tv_modes[2]; - } else { - if (pll->reference_freq == 2700) - const_ptr = &available_tv_modes[1]; - else - const_ptr = &available_tv_modes[3]; - } - return const_ptr; -} - -static long YCOEF_value[5] = { 2, 2, 0, 4, 0 }; -static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 }; -static long SLOPE_value[5] = { 1, 2, 2, 4, 8 }; -static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 }; - -static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests, - unsigned n_wait_loops, unsigned cnt_threshold) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t save_pll_test; - unsigned int i, j; - - WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100); - save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL); - WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B); - - WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL); - for (i = 0; i < n_tests; i++) { - WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0); - for (j = 0; j < n_wait_loops; j++) - if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold) - break; - } - WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test); - WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff); -} - - -static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder, - uint16_t addr, uint32_t value) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - int i = 0; - - WREG32(RADEON_TV_HOST_WRITE_DATA, value); - - WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr); - WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT); - - do { - tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL); - if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0) - break; - i++; - } while (i < 10000); - WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0); -} - -#if 0 /* included for completeness */ -static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - int i = 0; - - WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr); - WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD); - - do { - tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL); - if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0) - break; - i++; - } while (i < 10000); - WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0); - return RREG32(RADEON_TV_HOST_READ_DATA); -} -#endif - -static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr) -{ - uint16_t h_table; - - switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) { - case 0: - h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL; - break; - case 1: - h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2; - break; - case 2: - h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2; - break; - default: - h_table = 0; - break; - } - return h_table; -} - -static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr) -{ - uint16_t v_table; - - switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) { - case 0: - v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1; - break; - case 1: - v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1; - break; - case 2: - v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1; - break; - default: - v_table = 0; - break; - } - return v_table; -} - -static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - uint16_t h_table, v_table; - uint32_t tmp; - int i; - - WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr); - h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr); - v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr); - - for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) { - tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]); - radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp); - if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0) - break; - } - for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) { - tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]); - radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp); - if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0) - break; - } -} - -static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder) -{ - struct drm_device *dev = radeon_encoder->base.dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart); - WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart); - WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart); -} - -static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - struct radeon_crtc *radeon_crtc; - int restart; - unsigned int h_total, v_total, f_total; - int v_offset, h_offset; - u16 p1, p2, h_inc; - bool h_changed; - const struct radeon_tv_mode_constants *const_ptr; - struct radeon_pll *pll; - - radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc); - if (radeon_crtc->crtc_id == 1) - pll = &rdev->clock.p2pll; - else - pll = &rdev->clock.p1pll; - - const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); - if (!const_ptr) - return false; - - h_total = const_ptr->hor_total; - v_total = const_ptr->ver_total; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) - f_total = NTSC_TV_VFTOTAL + 1; - else - f_total = PAL_TV_VFTOTAL + 1; - - /* adjust positions 1&2 in hor. cod timing table */ - h_offset = tv_dac->h_pos * H_POS_UNIT; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M) { - h_offset -= 50; - p1 = hor_timing_NTSC[H_TABLE_POS1]; - p2 = hor_timing_NTSC[H_TABLE_POS2]; - } else { - p1 = hor_timing_PAL[H_TABLE_POS1]; - p2 = hor_timing_PAL[H_TABLE_POS2]; - } - - p1 = (u16)((int)p1 + h_offset); - p2 = (u16)((int)p2 - h_offset); - - h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] || - p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]); - - tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1; - tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2; - - /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */ - h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000; - - /* adjust restart */ - restart = const_ptr->def_restart; - - /* - * convert v_pos TV lines to n. of CRTC pixels - */ - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) - v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME); - else - v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME); - - restart -= v_offset + h_offset; - - DRM_DEBUG_KMS("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", - const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart); - - tv_dac->tv.hrestart = restart % h_total; - restart /= h_total; - tv_dac->tv.vrestart = restart % v_total; - restart /= v_total; - tv_dac->tv.frestart = restart % f_total; - - DRM_DEBUG_KMS("compute_restart: F/H/V=%u,%u,%u\n", - (unsigned)tv_dac->tv.frestart, - (unsigned)tv_dac->tv.vrestart, - (unsigned)tv_dac->tv.hrestart); - - /* compute h_inc from hsize */ - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M) - h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) / - (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE))); - else - h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) / - (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE))); - - tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) | - ((u32)h_inc << RADEON_H_INC_SHIFT); - - DRM_DEBUG_KMS("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); - - return h_changed; -} - -void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - const struct radeon_tv_mode_constants *const_ptr; - struct radeon_crtc *radeon_crtc; - int i; - uint16_t pll_ref_freq; - uint32_t vert_space, flicker_removal, tmp; - uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl; - uint32_t tv_modulator_cntl1, tv_modulator_cntl2; - uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2; - uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal; - uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl; - uint32_t m, n, p; - const uint16_t *hor_timing; - const uint16_t *vert_timing; - - const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq); - if (!const_ptr) - return; - - radeon_crtc = to_radeon_crtc(encoder->crtc); - - tv_master_cntl = (RADEON_VIN_ASYNC_RST | - RADEON_CRT_FIFO_CE_EN | - RADEON_TV_FIFO_CE_EN | - RADEON_TV_ON); - - if (!ASIC_IS_R300(rdev)) - tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J) - tv_master_cntl |= RADEON_RESTART_PHASE_FIX; - - tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT | - RADEON_SYNC_TIP_LEVEL | - RADEON_YFLT_EN | - RADEON_UVFLT_EN | - (6 << RADEON_CY_FILT_BLEND_SHIFT)); - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J) { - tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) | - (0x3b << RADEON_BLANK_LEVEL_SHIFT); - tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) | - ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); - } else if (tv_dac->tv_std == TV_STD_SCART_PAL) { - tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN; - tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) | - ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); - } else { - tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN | - (0x3b << RADEON_SET_UP_LEVEL_SHIFT) | - (0x3b << RADEON_BLANK_LEVEL_SHIFT); - tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) | - ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); - } - - - tv_rgb_cntl = (RADEON_RGB_DITHER_EN - | RADEON_TVOUT_SCALE_EN - | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT) - | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT) - | RADEON_RGB_ATTEN_SEL(0x3) - | RADEON_RGB_ATTEN_VAL(0xc)); - - if (radeon_crtc->crtc_id == 1) - tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2; - else { - if (radeon_crtc->rmx_type != RMX_OFF) - tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX; - else - tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1; - } - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) - vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME; - else - vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME; - - tmp = RREG32(RADEON_TV_VSCALER_CNTL1); - tmp &= 0xe3ff0000; - tmp |= (vert_space * (1 << FRAC_BITS) / 10000); - tv_vscaler_cntl1 = tmp; - - if (pll_ref_freq == 2700) - tv_vscaler_cntl1 |= RADEON_RESTART_FIELD; - - if (const_ptr->hor_resolution == 1024) - tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT); - else - tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT); - - /* scale up for int divide */ - tmp = const_ptr->ver_total * 2 * 1000; - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) { - tmp /= NTSC_TV_LINES_PER_FRAME; - } else { - tmp /= PAL_TV_LINES_PER_FRAME; - } - flicker_removal = (tmp + 500) / 1000; - - if (flicker_removal < 3) - flicker_removal = 3; - for (i = 0; i < ARRAY_SIZE(SLOPE_limit); ++i) { - if (flicker_removal == SLOPE_limit[i]) - break; - } - - tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) + - 5001) / 10000 / 8 | ((SLOPE_value[i] * - (1 << (FRAC_BITS - 1)) / 8) << 16); - tv_y_fall_cntl = - (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) | - RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) / - 1024; - tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG| - (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024; - - tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0; - tv_vscaler_cntl2 |= (0x10 << 24) | - RADEON_DITHER_MODE | - RADEON_Y_OUTPUT_DITHER_EN | - RADEON_UV_OUTPUT_DITHER_EN | - RADEON_UV_TO_BUF_DITHER_EN; - - tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK; - tmp = ((16384 * 256 * 10) / tmp + 5) / 10; - tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000; - tv_dac->tv.timing_cntl = tmp; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) - tv_dac_cntl = tv_dac->ntsc_tvdac_adj; - else - tv_dac_cntl = tv_dac->pal_tvdac_adj; - - tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J) - tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; - else - tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J) { - if (pll_ref_freq == 2700) { - m = NTSC_TV_PLL_M_27; - n = NTSC_TV_PLL_N_27; - p = NTSC_TV_PLL_P_27; - } else { - m = NTSC_TV_PLL_M_14; - n = NTSC_TV_PLL_N_14; - p = NTSC_TV_PLL_P_14; - } - } else { - if (pll_ref_freq == 2700) { - m = PAL_TV_PLL_M_27; - n = PAL_TV_PLL_N_27; - p = PAL_TV_PLL_P_27; - } else { - m = PAL_TV_PLL_M_14; - n = PAL_TV_PLL_N_14; - p = PAL_TV_PLL_P_14; - } - } - - tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) | - (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) | - ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) | - (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) | - ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT); - - tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) | - ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) | - ((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) | - RADEON_TVCLK_SRC_SEL_TVPLL | - RADEON_TVPLL_TEST_DIS); - - tv_dac->tv.tv_uv_adr = 0xc8; - - if (tv_dac->tv_std == TV_STD_NTSC || - tv_dac->tv_std == TV_STD_NTSC_J || - tv_dac->tv_std == TV_STD_PAL_M || - tv_dac->tv_std == TV_STD_PAL_60) { - tv_ftotal = NTSC_TV_VFTOTAL; - hor_timing = hor_timing_NTSC; - vert_timing = vert_timing_NTSC; - } else { - hor_timing = hor_timing_PAL; - vert_timing = vert_timing_PAL; - tv_ftotal = PAL_TV_VFTOTAL; - } - - for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) { - if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0) - break; - } - - for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) { - if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0) - break; - } - - radeon_legacy_tv_init_restarts(encoder); - - /* play with DAC_CNTL */ - /* play with GPIOPAD_A */ - /* DISP_OUTPUT_CNTL */ - /* use reference freq */ - - /* program the TV registers */ - WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST | - RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST)); - - tmp = RREG32(RADEON_TV_DAC_CNTL); - tmp &= ~RADEON_TV_DAC_NBLANK; - tmp |= RADEON_TV_DAC_BGSLEEP | - RADEON_TV_DAC_RDACPD | - RADEON_TV_DAC_GDACPD | - RADEON_TV_DAC_BDACPD; - WREG32(RADEON_TV_DAC_CNTL, tmp); - - /* TV PLL */ - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL); - WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl); - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET); - - radeon_wait_pll_lock(encoder, 200, 800, 135); - - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET); - - radeon_wait_pll_lock(encoder, 300, 160, 27); - radeon_wait_pll_lock(encoder, 200, 800, 135); - - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf); - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL); - - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK); - WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP); - - /* TV HV */ - WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl); - WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1); - WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1); - WREG32(RADEON_TV_HSTART, const_ptr->hor_start); - - WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1); - WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1); - WREG32(RADEON_TV_FTOTAL, tv_ftotal); - WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1); - WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2); - - WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl); - WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl); - WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl); - - WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST | - RADEON_CRT_ASYNC_RST)); - - /* TV restarts */ - radeon_legacy_write_tv_restarts(radeon_encoder); - - /* tv timings */ - radeon_restore_tv_timing_tables(radeon_encoder); - - WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST)); - - /* tv std */ - WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE)); - WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl); - WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1); - WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2); - WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN | - RADEON_C_GRN_EN | - RADEON_CMP_BLU_EN | - RADEON_DAC_DITHER_EN)); - - WREG32(RADEON_TV_CRC_CNTL, 0); - - WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - - WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) | - (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT))); - WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) | - (0x100 << RADEON_Y_GAIN_SHIFT))); - - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - -} - -void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, - uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, - uint32_t *v_total_disp, uint32_t *v_sync_strt_wid) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - const struct radeon_tv_mode_constants *const_ptr; - uint32_t tmp; - - const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); - if (!const_ptr) - return; - - *h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) | - (((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT); - - tmp = *h_sync_strt_wid; - tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR); - tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) | - (const_ptr->hor_syncstart & 7); - *h_sync_strt_wid = tmp; - - *v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | - ((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT); - - tmp = *v_sync_strt_wid; - tmp &= ~RADEON_CRTC_V_SYNC_STRT; - tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); - *v_sync_strt_wid = tmp; -} - -static int get_post_div(int value) -{ - int post_div; - switch (value) { - case 1: post_div = 0; break; - case 2: post_div = 1; break; - case 3: post_div = 4; break; - case 4: post_div = 2; break; - case 6: post_div = 6; break; - case 8: post_div = 3; break; - case 12: post_div = 7; break; - case 16: - default: post_div = 5; break; - } - return post_div; -} - -void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder, - uint32_t *htotal_cntl, uint32_t *ppll_ref_div, - uint32_t *ppll_div_3, uint32_t *pixclks_cntl) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - const struct radeon_tv_mode_constants *const_ptr; - - const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); - if (!const_ptr) - return; - - *htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN; - - *ppll_ref_div = const_ptr->crtcPLL_M; - - *ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16); - *pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL); - *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK; -} - -void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder, - uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div, - uint32_t *p2pll_div_0, uint32_t *pixclks_cntl) -{ - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - const struct radeon_tv_mode_constants *const_ptr; - - const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); - if (!const_ptr) - return; - - *htotal2_cntl = (const_ptr->hor_total & 0x7); - - *p2pll_ref_div = const_ptr->crtcPLL_M; - - *p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16); - *pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK; - *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mem.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mem.c deleted file mode 100644 index 988548ef..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mem.c +++ /dev/null @@ -1,301 +0,0 @@ -/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */ -/* - * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - * - * The Weather Channel (TM) funded Tungsten Graphics to develop the - * initial release of the Radeon 8500 driver under the XFree86 license. - * This notice must be preserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - -#include "drmP.h" -#include "drm.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -/* Very simple allocator for GART memory, working on a static range - * already mapped into each client's address space. - */ - -static struct mem_block *split_block(struct mem_block *p, int start, int size, - struct drm_file *file_priv) -{ - /* Maybe cut off the start of an existing block */ - if (start > p->start) { - struct mem_block *newblock = kmalloc(sizeof(*newblock), - GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start; - newblock->size = p->size - (start - p->start); - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size -= newblock->size; - p = newblock; - } - - /* Maybe cut off the end of an existing block */ - if (size < p->size) { - struct mem_block *newblock = kmalloc(sizeof(*newblock), - GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start + size; - newblock->size = p->size - size; - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size = size; - } - - out: - /* Our block is in the middle */ - p->file_priv = file_priv; - return p; -} - -static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, struct drm_file *file_priv) -{ - struct mem_block *p; - int mask = (1 << align2) - 1; - - list_for_each(p, heap) { - int start = (p->start + mask) & ~mask; - if (p->file_priv == NULL && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - - return NULL; -} - -static struct mem_block *find_block(struct mem_block *heap, int start) -{ - struct mem_block *p; - - list_for_each(p, heap) - if (p->start == start) - return p; - - return NULL; -} - -static void free_block(struct mem_block *p) -{ - p->file_priv = NULL; - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - if (p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - - if (p->prev->file_priv == NULL) { - struct mem_block *q = p->prev; - q->size += p->size; - q->next = p->next; - q->next->prev = q; - kfree(p); - } -} - -/* Initialize. How to check for an uninitialized heap? - */ -static int init_heap(struct mem_block **heap, int start, int size) -{ - struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); - - if (!blocks) - return -ENOMEM; - - *heap = kzalloc(sizeof(**heap), GFP_KERNEL); - if (!*heap) { - kfree(blocks); - return -ENOMEM; - } - - blocks->start = start; - blocks->size = size; - blocks->file_priv = NULL; - blocks->next = blocks->prev = *heap; - - (*heap)->file_priv = (struct drm_file *) - 1; - (*heap)->next = (*heap)->prev = blocks; - return 0; -} - -/* Free all blocks associated with the releasing file. - */ -void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap || !heap->next) - return; - - list_for_each(p, heap) { - if (p->file_priv == file_priv) - p->file_priv = NULL; - } - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - list_for_each(p, heap) { - while (p->file_priv == NULL && p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - } -} - -/* Shutdown. - */ -void radeon_mem_takedown(struct mem_block **heap) -{ - struct mem_block *p; - - if (!*heap) - return; - - for (p = (*heap)->next; p != *heap;) { - struct mem_block *q = p; - p = p->next; - kfree(q); - } - - kfree(*heap); - *heap = NULL; -} - -/* IOCTL HANDLERS */ - -static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region) -{ - switch (region) { - case RADEON_MEM_REGION_GART: - return &dev_priv->gart_heap; - case RADEON_MEM_REGION_FB: - return &dev_priv->fb_heap; - default: - return NULL; - } -} - -int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_alloc_t *alloc = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, alloc->region); - if (!heap || !*heap) - return -EFAULT; - - /* Make things easier on ourselves: all allocations at least - * 4k aligned. - */ - if (alloc->alignment < 12) - alloc->alignment = 12; - - block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); - - if (!block) - return -ENOMEM; - - if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, - sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_free_t *memfree = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, memfree->region); - if (!heap || !*heap) - return -EFAULT; - - block = find_block(*heap, memfree->region_offset); - if (!block) - return -EFAULT; - - if (block->file_priv != file_priv) - return -EPERM; - - free_block(block); - return 0; -} - -int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_mem_init_heap_t *initheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, initheap->region); - if (!heap) - return -EFAULT; - - if (*heap) { - DRM_ERROR("heap already initialized?"); - return -EFAULT; - } - - return init_heap(heap, initheap->start, initheap->size); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mode.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mode.h deleted file mode 100644 index f7eb5d8b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_mode.h +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and - * VA Linux Systems Inc., Fremont, California. - * Copyright 2008 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Original Authors: - * Kevin E. Martin, Rickard E. Faith, Alan Hourihane - * - * Kernel port Author: Dave Airlie - */ - -#ifndef RADEON_MODE_H -#define RADEON_MODE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -struct radeon_bo; -struct radeon_device; - -#define to_radeon_crtc(x) container_of(x, struct radeon_crtc, base) -#define to_radeon_connector(x) container_of(x, struct radeon_connector, base) -#define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base) -#define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base) - -enum radeon_rmx_type { - RMX_OFF, - RMX_FULL, - RMX_CENTER, - RMX_ASPECT -}; - -enum radeon_tv_std { - TV_STD_NTSC, - TV_STD_PAL, - TV_STD_PAL_M, - TV_STD_PAL_60, - TV_STD_NTSC_J, - TV_STD_SCART_PAL, - TV_STD_SECAM, - TV_STD_PAL_CN, - TV_STD_PAL_N, -}; - -enum radeon_underscan_type { - UNDERSCAN_OFF, - UNDERSCAN_ON, - UNDERSCAN_AUTO, -}; - -enum radeon_hpd_id { - RADEON_HPD_1 = 0, - RADEON_HPD_2, - RADEON_HPD_3, - RADEON_HPD_4, - RADEON_HPD_5, - RADEON_HPD_6, - RADEON_HPD_NONE = 0xff, -}; - -#define RADEON_MAX_I2C_BUS 16 - -/* radeon gpio-based i2c - * 1. "mask" reg and bits - * grabs the gpio pins for software use - * 0=not held 1=held - * 2. "a" reg and bits - * output pin value - * 0=low 1=high - * 3. "en" reg and bits - * sets the pin direction - * 0=input 1=output - * 4. "y" reg and bits - * input pin value - * 0=low 1=high - */ -struct radeon_i2c_bus_rec { - bool valid; - /* id used by atom */ - uint8_t i2c_id; - /* id used by atom */ - enum radeon_hpd_id hpd; - /* can be used with hw i2c engine */ - bool hw_capable; - /* uses multi-media i2c engine */ - bool mm_i2c; - /* regs and bits */ - uint32_t mask_clk_reg; - uint32_t mask_data_reg; - uint32_t a_clk_reg; - uint32_t a_data_reg; - uint32_t en_clk_reg; - uint32_t en_data_reg; - uint32_t y_clk_reg; - uint32_t y_data_reg; - uint32_t mask_clk_mask; - uint32_t mask_data_mask; - uint32_t a_clk_mask; - uint32_t a_data_mask; - uint32_t en_clk_mask; - uint32_t en_data_mask; - uint32_t y_clk_mask; - uint32_t y_data_mask; -}; - -struct radeon_tmds_pll { - uint32_t freq; - uint32_t value; -}; - -#define RADEON_MAX_BIOS_CONNECTOR 16 - -/* pll flags */ -#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) -#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) -#define RADEON_PLL_USE_REF_DIV (1 << 2) -#define RADEON_PLL_LEGACY (1 << 3) -#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4) -#define RADEON_PLL_PREFER_HIGH_REF_DIV (1 << 5) -#define RADEON_PLL_PREFER_LOW_FB_DIV (1 << 6) -#define RADEON_PLL_PREFER_HIGH_FB_DIV (1 << 7) -#define RADEON_PLL_PREFER_LOW_POST_DIV (1 << 8) -#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) -#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) -#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) -#define RADEON_PLL_USE_POST_DIV (1 << 12) -#define RADEON_PLL_IS_LCD (1 << 13) -#define RADEON_PLL_PREFER_MINM_OVER_MAXP (1 << 14) - -struct radeon_pll { - /* reference frequency */ - uint32_t reference_freq; - - /* fixed dividers */ - uint32_t reference_div; - uint32_t post_div; - - /* pll in/out limits */ - uint32_t pll_in_min; - uint32_t pll_in_max; - uint32_t pll_out_min; - uint32_t pll_out_max; - uint32_t lcd_pll_out_min; - uint32_t lcd_pll_out_max; - uint32_t best_vco; - - /* divider limits */ - uint32_t min_ref_div; - uint32_t max_ref_div; - uint32_t min_post_div; - uint32_t max_post_div; - uint32_t min_feedback_div; - uint32_t max_feedback_div; - uint32_t min_frac_feedback_div; - uint32_t max_frac_feedback_div; - - /* flags for the current clock */ - uint32_t flags; - - /* pll id */ - uint32_t id; -}; - -struct radeon_i2c_chan { - struct i2c_adapter adapter; - struct drm_device *dev; - union { - struct i2c_algo_bit_data bit; - struct i2c_algo_dp_aux_data dp; - } algo; - struct radeon_i2c_bus_rec rec; -}; - -/* mostly for macs, but really any system without connector tables */ -enum radeon_connector_table { - CT_NONE = 0, - CT_GENERIC, - CT_IBOOK, - CT_POWERBOOK_EXTERNAL, - CT_POWERBOOK_INTERNAL, - CT_POWERBOOK_VGA, - CT_MINI_EXTERNAL, - CT_MINI_INTERNAL, - CT_IMAC_G5_ISIGHT, - CT_EMAC, - CT_RN50_POWER, - CT_MAC_X800, - CT_MAC_G5_9600, -}; - -enum radeon_dvo_chip { - DVO_SIL164, - DVO_SIL1178, -}; - -struct radeon_fbdev; - -struct radeon_mode_info { - struct atom_context *atom_context; - struct card_info *atom_card_info; - enum radeon_connector_table connector_table; - bool mode_config_initialized; - struct radeon_crtc *crtcs[6]; - /* DVI-I properties */ - struct drm_property *coherent_mode_property; - /* DAC enable load detect */ - struct drm_property *load_detect_property; - /* TV standard */ - struct drm_property *tv_std_property; - /* legacy TMDS PLL detect */ - struct drm_property *tmds_pll_property; - /* underscan */ - struct drm_property *underscan_property; - struct drm_property *underscan_hborder_property; - struct drm_property *underscan_vborder_property; - /* hardcoded DFP edid from BIOS */ - struct edid *bios_hardcoded_edid; - int bios_hardcoded_edid_size; - - /* pointer to fbdev info structure */ - struct radeon_fbdev *rfbdev; -}; - -#define MAX_H_CODE_TIMING_LEN 32 -#define MAX_V_CODE_TIMING_LEN 32 - -/* need to store these as reading - back code tables is excessive */ -struct radeon_tv_regs { - uint32_t tv_uv_adr; - uint32_t timing_cntl; - uint32_t hrestart; - uint32_t vrestart; - uint32_t frestart; - uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN]; - uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN]; -}; - -struct radeon_crtc { - struct drm_crtc base; - int crtc_id; - u16 lut_r[256], lut_g[256], lut_b[256]; - bool enabled; - bool can_tile; - uint32_t crtc_offset; - struct drm_gem_object *cursor_bo; - uint64_t cursor_addr; - int cursor_width; - int cursor_height; - uint32_t legacy_display_base_addr; - uint32_t legacy_cursor_offset; - enum radeon_rmx_type rmx_type; - u8 h_border; - u8 v_border; - fixed20_12 vsc; - fixed20_12 hsc; - struct drm_display_mode native_mode; - int pll_id; - /* page flipping */ - struct radeon_unpin_work *unpin_work; - int deferred_flip_completion; -}; - -struct radeon_encoder_primary_dac { - /* legacy primary dac */ - uint32_t ps2_pdac_adj; -}; - -struct radeon_encoder_lvds { - /* legacy lvds */ - uint16_t panel_vcc_delay; - uint8_t panel_pwr_delay; - uint8_t panel_digon_delay; - uint8_t panel_blon_delay; - uint16_t panel_ref_divider; - uint8_t panel_post_divider; - uint16_t panel_fb_divider; - bool use_bios_dividers; - uint32_t lvds_gen_cntl; - /* panel mode */ - struct drm_display_mode native_mode; - struct backlight_device *bl_dev; - int dpms_mode; - uint8_t backlight_level; -}; - -struct radeon_encoder_tv_dac { - /* legacy tv dac */ - uint32_t ps2_tvdac_adj; - uint32_t ntsc_tvdac_adj; - uint32_t pal_tvdac_adj; - - int h_pos; - int v_pos; - int h_size; - int supported_tv_stds; - bool tv_on; - enum radeon_tv_std tv_std; - struct radeon_tv_regs tv; -}; - -struct radeon_encoder_int_tmds { - /* legacy int tmds */ - struct radeon_tmds_pll tmds_pll[4]; -}; - -struct radeon_encoder_ext_tmds { - /* tmds over dvo */ - struct radeon_i2c_chan *i2c_bus; - uint8_t slave_addr; - enum radeon_dvo_chip dvo_chip; -}; - -/* spread spectrum */ -struct radeon_atom_ss { - uint16_t percentage; - uint8_t type; - uint16_t step; - uint8_t delay; - uint8_t range; - uint8_t refdiv; - /* asic_ss */ - uint16_t rate; - uint16_t amount; -}; - -struct radeon_encoder_atom_dig { - bool linkb; - /* atom dig */ - bool coherent_mode; - int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB, etc. */ - /* atom lvds/edp */ - uint32_t lcd_misc; - uint16_t panel_pwr_delay; - uint32_t lcd_ss_id; - /* panel mode */ - struct drm_display_mode native_mode; - struct backlight_device *bl_dev; - int dpms_mode; - uint8_t backlight_level; - int panel_mode; -}; - -struct radeon_encoder_atom_dac { - enum radeon_tv_std tv_std; -}; - -struct radeon_encoder { - struct drm_encoder base; - uint32_t encoder_enum; - uint32_t encoder_id; - uint32_t devices; - uint32_t active_device; - uint32_t flags; - uint32_t pixel_clock; - enum radeon_rmx_type rmx_type; - enum radeon_underscan_type underscan_type; - uint32_t underscan_hborder; - uint32_t underscan_vborder; - struct drm_display_mode native_mode; - void *enc_priv; - int audio_polling_active; - int hdmi_offset; - int hdmi_config_offset; - int hdmi_audio_workaround; - int hdmi_buffer_status; - bool is_ext_encoder; - u16 caps; -}; - -struct radeon_connector_atom_dig { - uint32_t igp_lane_info; - /* displayport */ - struct radeon_i2c_chan *dp_i2c_bus; - u8 dpcd[8]; - u8 dp_sink_type; - int dp_clock; - int dp_lane_count; - bool edp_on; -}; - -struct radeon_gpio_rec { - bool valid; - u8 id; - u32 reg; - u32 mask; -}; - -struct radeon_hpd { - enum radeon_hpd_id hpd; - u8 plugged_state; - struct radeon_gpio_rec gpio; -}; - -struct radeon_router { - u32 router_id; - struct radeon_i2c_bus_rec i2c_info; - u8 i2c_addr; - /* i2c mux */ - bool ddc_valid; - u8 ddc_mux_type; - u8 ddc_mux_control_pin; - u8 ddc_mux_state; - /* clock/data mux */ - bool cd_valid; - u8 cd_mux_type; - u8 cd_mux_control_pin; - u8 cd_mux_state; -}; - -struct radeon_connector { - struct drm_connector base; - uint32_t connector_id; - uint32_t devices; - struct radeon_i2c_chan *ddc_bus; - /* some systems have an hdmi and vga port with a shared ddc line */ - bool shared_ddc; - bool use_digital; - /* we need to mind the EDID between detect - and get modes due to analog/digital/tvencoder */ - struct edid *edid; - void *con_priv; - bool dac_load_detect; - bool detected_by_load; /* if the connection status was determined by load */ - uint16_t connector_object_id; - struct radeon_hpd hpd; - struct radeon_router router; - struct radeon_i2c_chan *router_bus; -}; - -struct radeon_framebuffer { - struct drm_framebuffer base; - struct drm_gem_object *obj; -}; - -#define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ - ((em) == ATOM_ENCODER_MODE_DP_MST)) - -extern enum radeon_tv_std -radeon_combios_get_tv_info(struct radeon_device *rdev); -extern enum radeon_tv_std -radeon_atombios_get_tv_info(struct radeon_device *rdev); - -extern struct drm_connector * -radeon_get_connector_for_encoder(struct drm_encoder *encoder); -extern struct drm_connector * -radeon_get_connector_for_encoder_init(struct drm_encoder *encoder); -extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, - u32 pixel_clock); - -extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); -extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); -extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); -extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); - -extern void radeon_connector_hotplug(struct drm_connector *connector); -extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, - struct drm_display_mode *mode); -extern void radeon_dp_set_link_config(struct drm_connector *connector, - struct drm_display_mode *mode); -extern void radeon_dp_link_train(struct drm_encoder *encoder, - struct drm_connector *connector); -extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); -extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); -extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); -extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, - struct drm_connector *connector); -extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); -extern void radeon_atom_encoder_init(struct radeon_device *rdev); -extern void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev); -extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, - int action, uint8_t lane_num, - uint8_t lane_set); -extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); -extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder); -extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, - u8 write_byte, u8 *read_byte); - -extern void radeon_i2c_init(struct radeon_device *rdev); -extern void radeon_i2c_fini(struct radeon_device *rdev); -extern void radeon_combios_i2c_init(struct radeon_device *rdev); -extern void radeon_atombios_i2c_init(struct radeon_device *rdev); -extern void radeon_i2c_add(struct radeon_device *rdev, - struct radeon_i2c_bus_rec *rec, - const char *name); -extern struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev, - struct radeon_i2c_bus_rec *i2c_bus); -extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name); -extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name); -extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); -extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, - u8 slave_addr, - u8 addr, - u8 *val); -extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, - u8 slave_addr, - u8 addr, - u8 val); -extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); -extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); -extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); -extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); - -extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); - -extern bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, - struct radeon_atom_ss *ss, - int id); -extern bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, - struct radeon_atom_ss *ss, - int id, u32 clock); - -extern void radeon_compute_pll_legacy(struct radeon_pll *pll, - uint64_t freq, - uint32_t *dot_clock_p, - uint32_t *fb_div_p, - uint32_t *frac_fb_div_p, - uint32_t *ref_div_p, - uint32_t *post_div_p); - -extern void radeon_compute_pll_avivo(struct radeon_pll *pll, - u32 freq, - u32 *dot_clock_p, - u32 *fb_div_p, - u32 *frac_fb_div_p, - u32 *ref_div_p, - u32 *post_div_p); - -extern void radeon_setup_encoder_clones(struct drm_device *dev); - -struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); -struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int with_tv); -struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv); -struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index); -struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); -extern void atombios_dvo_setup(struct drm_encoder *encoder, int action); -extern void atombios_digital_setup(struct drm_encoder *encoder, int action); -extern int atombios_get_encoder_mode(struct drm_encoder *encoder); -extern bool atombios_set_edp_panel_power(struct drm_connector *connector, int action); -extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); - -extern void radeon_crtc_load_lut(struct drm_crtc *crtc); -extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb); -extern int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, - enum mode_set_atomic state); -extern int atombios_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, - struct drm_framebuffer *old_fb); -extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); - -extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb); -extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, - enum mode_set_atomic state); -extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic); -extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height); -extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, - int x, int y); - -extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, - int *vpos, int *hpos); - -extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); -extern struct edid * -radeon_bios_get_hardcoded_edid(struct radeon_device *rdev); -extern bool radeon_atom_get_clock_info(struct drm_device *dev); -extern bool radeon_combios_get_clock_info(struct drm_device *dev); -extern struct radeon_encoder_atom_dig * -radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); -extern bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, - struct radeon_encoder_int_tmds *tmds); -extern bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, - struct radeon_encoder_int_tmds *tmds); -extern bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, - struct radeon_encoder_int_tmds *tmds); -extern bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder, - struct radeon_encoder_ext_tmds *tmds); -extern bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder, - struct radeon_encoder_ext_tmds *tmds); -extern struct radeon_encoder_primary_dac * -radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); -extern struct radeon_encoder_tv_dac * -radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder); -extern struct radeon_encoder_lvds * -radeon_combios_get_lvds_info(struct radeon_encoder *encoder); -extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder); -extern struct radeon_encoder_tv_dac * -radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); -extern struct radeon_encoder_primary_dac * -radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); -extern bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder); -extern void radeon_external_tmds_setup(struct drm_encoder *encoder); -extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); -extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); -extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); -extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev); -extern void radeon_save_bios_scratch_regs(struct radeon_device *rdev); -extern void radeon_restore_bios_scratch_regs(struct radeon_device *rdev); -extern void -radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc); -extern void -radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on); -extern void -radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc); -extern void -radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on); -extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno); -extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno); -int radeon_framebuffer_init(struct drm_device *dev, - struct radeon_framebuffer *rfb, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); - -int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); -bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev); -bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev); -void radeon_atombios_init_crtc(struct drm_device *dev, - struct radeon_crtc *radeon_crtc); -void radeon_legacy_init_crtc(struct drm_device *dev, - struct radeon_crtc *radeon_crtc); - -void radeon_get_clock_info(struct drm_device *dev); - -extern bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev); -extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct drm_device *dev); - -void radeon_enc_destroy(struct drm_encoder *encoder); -void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); -void radeon_combios_asic_init(struct drm_device *dev); -bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); -void radeon_panel_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *adjusted_mode); -void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); - -/* legacy tv */ -void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, - uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, - uint32_t *v_total_disp, uint32_t *v_sync_strt_wid); -void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder, - uint32_t *htotal_cntl, uint32_t *ppll_ref_div, - uint32_t *ppll_div_3, uint32_t *pixclks_cntl); -void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder, - uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div, - uint32_t *p2pll_div_0, uint32_t *pixclks_cntl); -void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); - -/* fbdev layer */ -int radeon_fbdev_init(struct radeon_device *rdev); -void radeon_fbdev_fini(struct radeon_device *rdev); -void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state); -int radeon_fbdev_total_size(struct radeon_device *rdev); -bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); - -void radeon_fb_output_poll_changed(struct radeon_device *rdev); - -void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id); - -int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled); -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.c deleted file mode 100644 index df6a4dbd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright 2009 Jerome Glisse. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: - * Jerome Glisse - * Thomas Hellstrom - * Dave Airlie - */ -#include -#include -#include -#include "radeon_drm.h" -#include "radeon.h" -#include "radeon_trace.h" - - -int radeon_ttm_init(struct radeon_device *rdev); -void radeon_ttm_fini(struct radeon_device *rdev); -static void radeon_bo_clear_surface_reg(struct radeon_bo *bo); - -/* - * To exclude mutual BO access we rely on bo_reserve exclusion, as all - * function are calling it. - */ - -void radeon_bo_clear_va(struct radeon_bo *bo) -{ - struct radeon_bo_va *bo_va, *tmp; - - list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { - /* remove from all vm address space */ - mutex_lock(&bo_va->vm->mutex); - list_del(&bo_va->vm_list); - mutex_unlock(&bo_va->vm->mutex); - list_del(&bo_va->bo_list); - kfree(bo_va); - } -} - -static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) -{ - struct radeon_bo *bo; - - bo = container_of(tbo, struct radeon_bo, tbo); - mutex_lock(&bo->rdev->gem.mutex); - list_del_init(&bo->list); - mutex_unlock(&bo->rdev->gem.mutex); - radeon_bo_clear_surface_reg(bo); - radeon_bo_clear_va(bo); - drm_gem_object_release(&bo->gem_base); - kfree(bo); -} - -bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo) -{ - if (bo->destroy == &radeon_ttm_bo_destroy) - return true; - return false; -} - -void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) -{ - u32 c = 0; - - rbo->placement.fpfn = 0; - rbo->placement.lpfn = 0; - rbo->placement.placement = rbo->placements; - rbo->placement.busy_placement = rbo->placements; - if (domain & RADEON_GEM_DOMAIN_VRAM) - rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_VRAM; - if (domain & RADEON_GEM_DOMAIN_GTT) - rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; - if (domain & RADEON_GEM_DOMAIN_CPU) - rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - if (!c) - rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - rbo->placement.num_placement = c; - rbo->placement.num_busy_placement = c; -} - -int radeon_bo_create(struct radeon_device *rdev, - unsigned long size, int byte_align, bool kernel, u32 domain, - struct radeon_bo **bo_ptr) -{ - struct radeon_bo *bo; - enum ttm_bo_type type; - unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; - unsigned long max_size = 0; - size_t acc_size; - int r; - - size = ALIGN(size, PAGE_SIZE); - - if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { - rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; - } - if (kernel) { - type = ttm_bo_type_kernel; - } else { - type = ttm_bo_type_device; - } - *bo_ptr = NULL; - - /* maximun bo size is the minimun btw visible vram and gtt size */ - max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); - if ((page_align << PAGE_SHIFT) >= max_size) { - printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", - __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); - return -ENOMEM; - } - - acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, - sizeof(struct radeon_bo)); - -retry: - bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); - if (bo == NULL) - return -ENOMEM; - r = drm_gem_object_init(rdev->ddev, &bo->gem_base, size); - if (unlikely(r)) { - kfree(bo); - return r; - } - bo->rdev = rdev; - bo->gem_base.driver_private = NULL; - bo->surface_reg = -1; - INIT_LIST_HEAD(&bo->list); - INIT_LIST_HEAD(&bo->va); - radeon_ttm_placement_from_domain(bo, domain); - /* Kernel allocation are uninterruptible */ - mutex_lock(&rdev->vram_mutex); - r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, - &bo->placement, page_align, 0, !kernel, NULL, - acc_size, &radeon_ttm_bo_destroy); - mutex_unlock(&rdev->vram_mutex); - if (unlikely(r != 0)) { - if (r != -ERESTARTSYS) { - if (domain == RADEON_GEM_DOMAIN_VRAM) { - domain |= RADEON_GEM_DOMAIN_GTT; - goto retry; - } - dev_err(rdev->dev, - "object_init failed for (%lu, 0x%08X)\n", - size, domain); - } - return r; - } - *bo_ptr = bo; - - trace_radeon_bo_create(bo); - - return 0; -} - -int radeon_bo_kmap(struct radeon_bo *bo, void **ptr) -{ - bool is_iomem; - int r; - - if (bo->kptr) { - if (ptr) { - *ptr = bo->kptr; - } - return 0; - } - r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); - if (r) { - return r; - } - bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); - if (ptr) { - *ptr = bo->kptr; - } - radeon_bo_check_tiling(bo, 0, 0); - return 0; -} - -void radeon_bo_kunmap(struct radeon_bo *bo) -{ - if (bo->kptr == NULL) - return; - bo->kptr = NULL; - radeon_bo_check_tiling(bo, 0, 0); - ttm_bo_kunmap(&bo->kmap); -} - -void radeon_bo_unref(struct radeon_bo **bo) -{ - struct ttm_buffer_object *tbo; - struct radeon_device *rdev; - - if ((*bo) == NULL) - return; - rdev = (*bo)->rdev; - tbo = &((*bo)->tbo); - mutex_lock(&rdev->vram_mutex); - ttm_bo_unref(&tbo); - mutex_unlock(&rdev->vram_mutex); - if (tbo == NULL) - *bo = NULL; -} - -int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, - u64 *gpu_addr) -{ - int r, i; - - if (bo->pin_count) { - bo->pin_count++; - if (gpu_addr) - *gpu_addr = radeon_bo_gpu_offset(bo); - - if (max_offset != 0) { - u64 domain_start; - - if (domain == RADEON_GEM_DOMAIN_VRAM) - domain_start = bo->rdev->mc.vram_start; - else - domain_start = bo->rdev->mc.gtt_start; - WARN_ON_ONCE(max_offset < - (radeon_bo_gpu_offset(bo) - domain_start)); - } - - return 0; - } - radeon_ttm_placement_from_domain(bo, domain); - if (domain == RADEON_GEM_DOMAIN_VRAM) { - /* force to pin into visible video ram */ - bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; - } - if (max_offset) { - u64 lpfn = max_offset >> PAGE_SHIFT; - - if (!bo->placement.lpfn) - bo->placement.lpfn = bo->rdev->mc.gtt_size >> PAGE_SHIFT; - - if (lpfn < bo->placement.lpfn) - bo->placement.lpfn = lpfn; - } - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i] |= TTM_PL_FLAG_NO_EVICT; - r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false); - if (likely(r == 0)) { - bo->pin_count = 1; - if (gpu_addr != NULL) - *gpu_addr = radeon_bo_gpu_offset(bo); - } - if (unlikely(r != 0)) - dev_err(bo->rdev->dev, "%p pin failed\n", bo); - return r; -} - -int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) -{ - return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr); -} - -int radeon_bo_unpin(struct radeon_bo *bo) -{ - int r, i; - - if (!bo->pin_count) { - dev_warn(bo->rdev->dev, "%p unpin not necessary\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT; - r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false); - if (unlikely(r != 0)) - dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo); - return r; -} - -int radeon_bo_evict_vram(struct radeon_device *rdev) -{ - /* late 2.6.33 fix IGP hibernate - we need pm ops to do this correct */ - if (0 && (rdev->flags & RADEON_IS_IGP)) { - if (rdev->mc.igp_sideport_enabled == false) - /* Useless to evict on IGP chips */ - return 0; - } - return ttm_bo_evict_mm(&rdev->mman.bdev, TTM_PL_VRAM); -} - -void radeon_bo_force_delete(struct radeon_device *rdev) -{ - struct radeon_bo *bo, *n; - - if (list_empty(&rdev->gem.objects)) { - return; - } - dev_err(rdev->dev, "Userspace still has active objects !\n"); - list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) { - mutex_lock(&rdev->ddev->struct_mutex); - dev_err(rdev->dev, "%p %p %lu %lu force free\n", - &bo->gem_base, bo, (unsigned long)bo->gem_base.size, - *((unsigned long *)&bo->gem_base.refcount)); - mutex_lock(&bo->rdev->gem.mutex); - list_del_init(&bo->list); - mutex_unlock(&bo->rdev->gem.mutex); - /* this should unref the ttm bo */ - drm_gem_object_unreference(&bo->gem_base); - mutex_unlock(&rdev->ddev->struct_mutex); - } -} - -int radeon_bo_init(struct radeon_device *rdev) -{ - /* Add an MTRR for the VRAM */ - rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, - MTRR_TYPE_WRCOMB, 1); - DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n", - rdev->mc.mc_vram_size >> 20, - (unsigned long long)rdev->mc.aper_size >> 20); - DRM_INFO("RAM width %dbits %cDR\n", - rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S'); - return radeon_ttm_init(rdev); -} - -void radeon_bo_fini(struct radeon_device *rdev) -{ - radeon_ttm_fini(rdev); -} - -void radeon_bo_list_add_object(struct radeon_bo_list *lobj, - struct list_head *head) -{ - if (lobj->wdomain) { - list_add(&lobj->tv.head, head); - } else { - list_add_tail(&lobj->tv.head, head); - } -} - -int radeon_bo_list_validate(struct list_head *head) -{ - struct radeon_bo_list *lobj; - struct radeon_bo *bo; - u32 domain; - int r; - - r = ttm_eu_reserve_buffers(head); - if (unlikely(r != 0)) { - return r; - } - list_for_each_entry(lobj, head, tv.head) { - bo = lobj->bo; - if (!bo->pin_count) { - domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; - - retry: - radeon_ttm_placement_from_domain(bo, domain); - r = ttm_bo_validate(&bo->tbo, &bo->placement, - true, false, false); - if (unlikely(r)) { - if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) { - domain |= RADEON_GEM_DOMAIN_GTT; - goto retry; - } - return r; - } - } - lobj->gpu_offset = radeon_bo_gpu_offset(bo); - lobj->tiling_flags = bo->tiling_flags; - } - return 0; -} - -int radeon_bo_fbdev_mmap(struct radeon_bo *bo, - struct vm_area_struct *vma) -{ - return ttm_fbdev_mmap(vma, &bo->tbo); -} - -int radeon_bo_get_surface_reg(struct radeon_bo *bo) -{ - struct radeon_device *rdev = bo->rdev; - struct radeon_surface_reg *reg; - struct radeon_bo *old_object; - int steal; - int i; - - BUG_ON(!atomic_read(&bo->tbo.reserved)); - - if (!bo->tiling_flags) - return 0; - - if (bo->surface_reg >= 0) { - reg = &rdev->surface_regs[bo->surface_reg]; - i = bo->surface_reg; - goto out; - } - - steal = -1; - for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { - - reg = &rdev->surface_regs[i]; - if (!reg->bo) - break; - - old_object = reg->bo; - if (old_object->pin_count == 0) - steal = i; - } - - /* if we are all out */ - if (i == RADEON_GEM_MAX_SURFACES) { - if (steal == -1) - return -ENOMEM; - /* find someone with a surface reg and nuke their BO */ - reg = &rdev->surface_regs[steal]; - old_object = reg->bo; - /* blow away the mapping */ - DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object); - ttm_bo_unmap_virtual(&old_object->tbo); - old_object->surface_reg = -1; - i = steal; - } - - bo->surface_reg = i; - reg->bo = bo; - -out: - radeon_set_surface_reg(rdev, i, bo->tiling_flags, bo->pitch, - bo->tbo.mem.start << PAGE_SHIFT, - bo->tbo.num_pages << PAGE_SHIFT); - return 0; -} - -static void radeon_bo_clear_surface_reg(struct radeon_bo *bo) -{ - struct radeon_device *rdev = bo->rdev; - struct radeon_surface_reg *reg; - - if (bo->surface_reg == -1) - return; - - reg = &rdev->surface_regs[bo->surface_reg]; - radeon_clear_surface_reg(rdev, bo->surface_reg); - - reg->bo = NULL; - bo->surface_reg = -1; -} - -int radeon_bo_set_tiling_flags(struct radeon_bo *bo, - uint32_t tiling_flags, uint32_t pitch) -{ - struct radeon_device *rdev = bo->rdev; - int r; - - if (rdev->family >= CHIP_CEDAR) { - unsigned bankw, bankh, mtaspect, tilesplit, stilesplit; - - bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; - bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; - mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; - tilesplit = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK; - stilesplit = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK; - switch (bankw) { - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: - return -EINVAL; - } - switch (bankh) { - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: - return -EINVAL; - } - switch (mtaspect) { - case 0: - case 1: - case 2: - case 4: - case 8: - break; - default: - return -EINVAL; - } - if (tilesplit > 6) { - return -EINVAL; - } - if (stilesplit > 6) { - return -EINVAL; - } - } - r = radeon_bo_reserve(bo, false); - if (unlikely(r != 0)) - return r; - bo->tiling_flags = tiling_flags; - bo->pitch = pitch; - radeon_bo_unreserve(bo); - return 0; -} - -void radeon_bo_get_tiling_flags(struct radeon_bo *bo, - uint32_t *tiling_flags, - uint32_t *pitch) -{ - BUG_ON(!atomic_read(&bo->tbo.reserved)); - if (tiling_flags) - *tiling_flags = bo->tiling_flags; - if (pitch) - *pitch = bo->pitch; -} - -int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, - bool force_drop) -{ - BUG_ON(!atomic_read(&bo->tbo.reserved)); - - if (!(bo->tiling_flags & RADEON_TILING_SURFACE)) - return 0; - - if (force_drop) { - radeon_bo_clear_surface_reg(bo); - return 0; - } - - if (bo->tbo.mem.mem_type != TTM_PL_VRAM) { - if (!has_moved) - return 0; - - if (bo->surface_reg >= 0) - radeon_bo_clear_surface_reg(bo); - return 0; - } - - if ((bo->surface_reg >= 0) && !has_moved) - return 0; - - return radeon_bo_get_surface_reg(bo); -} - -void radeon_bo_move_notify(struct ttm_buffer_object *bo, - struct ttm_mem_reg *mem) -{ - struct radeon_bo *rbo; - if (!radeon_ttm_bo_is_radeon_bo(bo)) - return; - rbo = container_of(bo, struct radeon_bo, tbo); - radeon_bo_check_tiling(rbo, 0, 1); - radeon_vm_bo_invalidate(rbo->rdev, rbo); -} - -int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) -{ - struct radeon_device *rdev; - struct radeon_bo *rbo; - unsigned long offset, size; - int r; - - if (!radeon_ttm_bo_is_radeon_bo(bo)) - return 0; - rbo = container_of(bo, struct radeon_bo, tbo); - radeon_bo_check_tiling(rbo, 0, 0); - rdev = rbo->rdev; - if (bo->mem.mem_type == TTM_PL_VRAM) { - size = bo->mem.num_pages << PAGE_SHIFT; - offset = bo->mem.start << PAGE_SHIFT; - if ((offset + size) > rdev->mc.visible_vram_size) { - /* hurrah the memory is not visible ! */ - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); - rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT; - r = ttm_bo_validate(bo, &rbo->placement, false, true, false); - if (unlikely(r != 0)) - return r; - offset = bo->mem.start << PAGE_SHIFT; - /* this should not happen */ - if ((offset + size) > rdev->mc.visible_vram_size) - return -EINVAL; - } - } - return 0; -} - -int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait) -{ - int r; - - r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); - if (unlikely(r != 0)) - return r; - spin_lock(&bo->tbo.bdev->fence_lock); - if (mem_type) - *mem_type = bo->tbo.mem.mem_type; - if (bo->tbo.sync_obj) - r = ttm_bo_wait(&bo->tbo, true, true, no_wait); - spin_unlock(&bo->tbo.bdev->fence_lock); - ttm_bo_unreserve(&bo->tbo); - return r; -} - - -/** - * radeon_bo_reserve - reserve bo - * @bo: bo structure - * @no_wait: don't sleep while trying to reserve (return -EBUSY) - * - * Returns: - * -EBUSY: buffer is busy and @no_wait is true - * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by - * a signal. Release all buffer reservations and return to user-space. - */ -int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) -{ - int r; - - r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); - if (unlikely(r != 0)) { - if (r != -ERESTARTSYS) - dev_err(bo->rdev->dev, "%p reserve failed\n", bo); - return r; - } - return 0; -} - -/* object have to be reserved */ -struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, struct radeon_vm *vm) -{ - struct radeon_bo_va *bo_va; - - list_for_each_entry(bo_va, &rbo->va, bo_list) { - if (bo_va->vm == vm) { - return bo_va; - } - } - return NULL; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.h deleted file mode 100644 index f9104be8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_object.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RADEON_OBJECT_H__ -#define __RADEON_OBJECT_H__ - -#include -#include "radeon.h" - -/** - * radeon_mem_type_to_domain - return domain corresponding to mem_type - * @mem_type: ttm memory type - * - * Returns corresponding domain of the ttm mem_type - */ -static inline unsigned radeon_mem_type_to_domain(u32 mem_type) -{ - switch (mem_type) { - case TTM_PL_VRAM: - return RADEON_GEM_DOMAIN_VRAM; - case TTM_PL_TT: - return RADEON_GEM_DOMAIN_GTT; - case TTM_PL_SYSTEM: - return RADEON_GEM_DOMAIN_CPU; - default: - break; - } - return 0; -} - -int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait); - -static inline void radeon_bo_unreserve(struct radeon_bo *bo) -{ - ttm_bo_unreserve(&bo->tbo); -} - -/** - * radeon_bo_gpu_offset - return GPU offset of bo - * @bo: radeon object for which we query the offset - * - * Returns current GPU offset of the object. - * - * Note: object should either be pinned or reserved when calling this - * function, it might be useful to add check for this for debugging. - */ -static inline u64 radeon_bo_gpu_offset(struct radeon_bo *bo) -{ - return bo->tbo.offset; -} - -static inline unsigned long radeon_bo_size(struct radeon_bo *bo) -{ - return bo->tbo.num_pages << PAGE_SHIFT; -} - -static inline bool radeon_bo_is_reserved(struct radeon_bo *bo) -{ - return !!atomic_read(&bo->tbo.reserved); -} - -static inline unsigned radeon_bo_ngpu_pages(struct radeon_bo *bo) -{ - return (bo->tbo.num_pages << PAGE_SHIFT) / RADEON_GPU_PAGE_SIZE; -} - -static inline unsigned radeon_bo_gpu_page_alignment(struct radeon_bo *bo) -{ - return (bo->tbo.mem.page_alignment << PAGE_SHIFT) / RADEON_GPU_PAGE_SIZE; -} - -/** - * radeon_bo_mmap_offset - return mmap offset of bo - * @bo: radeon object for which we query the offset - * - * Returns mmap offset of the object. - * - * Note: addr_space_offset is constant after ttm bo init thus isn't protected - * by any lock. - */ -static inline u64 radeon_bo_mmap_offset(struct radeon_bo *bo) -{ - return bo->tbo.addr_space_offset; -} - -extern int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, - bool no_wait); - -extern int radeon_bo_create(struct radeon_device *rdev, - unsigned long size, int byte_align, - bool kernel, u32 domain, - struct radeon_bo **bo_ptr); -extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); -extern void radeon_bo_kunmap(struct radeon_bo *bo); -extern void radeon_bo_unref(struct radeon_bo **bo); -extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr); -extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, - u64 max_offset, u64 *gpu_addr); -extern int radeon_bo_unpin(struct radeon_bo *bo); -extern int radeon_bo_evict_vram(struct radeon_device *rdev); -extern void radeon_bo_force_delete(struct radeon_device *rdev); -extern int radeon_bo_init(struct radeon_device *rdev); -extern void radeon_bo_fini(struct radeon_device *rdev); -extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, - struct list_head *head); -extern int radeon_bo_list_validate(struct list_head *head); -extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, - struct vm_area_struct *vma); -extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, - u32 tiling_flags, u32 pitch); -extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo, - u32 *tiling_flags, u32 *pitch); -extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, - bool force_drop); -extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, - struct ttm_mem_reg *mem); -extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); -extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); -extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, - struct radeon_vm *vm); - -/* - * sub allocation - */ -extern int radeon_sa_bo_manager_init(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager, - unsigned size, u32 domain); -extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager); -extern int radeon_sa_bo_manager_start(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager); -extern int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager); -extern int radeon_sa_bo_new(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager, - struct radeon_sa_bo *sa_bo, - unsigned size, unsigned align); -extern void radeon_sa_bo_free(struct radeon_device *rdev, - struct radeon_sa_bo *sa_bo); - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_pm.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_pm.c deleted file mode 100644 index caa55d68..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_pm.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Rafał Miłecki - * Alex Deucher - */ -#include "drmP.h" -#include "radeon.h" -#include "avivod.h" -#include "atom.h" -#ifdef CONFIG_ACPI -#include -#endif -#include -#include -#include - -#define RADEON_IDLE_LOOP_MS 100 -#define RADEON_RECLOCK_DELAY_MS 200 -#define RADEON_WAIT_VBLANK_TIMEOUT 200 -#define RADEON_WAIT_IDLE_TIMEOUT 200 - -static const char *radeon_pm_state_type_name[5] = { - "Default", - "Powersave", - "Battery", - "Balanced", - "Performance", -}; - -static void radeon_dynpm_idle_work_handler(struct work_struct *work); -static int radeon_debugfs_pm_init(struct radeon_device *rdev); -static bool radeon_pm_in_vbl(struct radeon_device *rdev); -static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); -static void radeon_pm_update_profile(struct radeon_device *rdev); -static void radeon_pm_set_clocks(struct radeon_device *rdev); - -#define ACPI_AC_CLASS "ac_adapter" - -int radeon_pm_get_type_index(struct radeon_device *rdev, - enum radeon_pm_state_type ps_type, - int instance) -{ - int i; - int found_instance = -1; - - for (i = 0; i < rdev->pm.num_power_states; i++) { - if (rdev->pm.power_state[i].type == ps_type) { - found_instance++; - if (found_instance == instance) - return i; - } - } - /* return default if no match */ - return rdev->pm.default_power_state_index; -} - -#ifdef CONFIG_ACPI -static int radeon_acpi_event(struct notifier_block *nb, - unsigned long val, - void *data) -{ - struct radeon_device *rdev = container_of(nb, struct radeon_device, acpi_nb); - struct acpi_bus_event *entry = (struct acpi_bus_event *)data; - - if (strcmp(entry->device_class, ACPI_AC_CLASS) == 0) { - if (power_supply_is_system_supplied() > 0) - DRM_DEBUG_DRIVER("pm: AC\n"); - else - DRM_DEBUG_DRIVER("pm: DC\n"); - - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - if (rdev->pm.profile == PM_PROFILE_AUTO) { - mutex_lock(&rdev->pm.mutex); - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - mutex_unlock(&rdev->pm.mutex); - } - } - } - - return NOTIFY_OK; -} -#endif - -static void radeon_pm_update_profile(struct radeon_device *rdev) -{ - switch (rdev->pm.profile) { - case PM_PROFILE_DEFAULT: - rdev->pm.profile_index = PM_PROFILE_DEFAULT_IDX; - break; - case PM_PROFILE_AUTO: - if (power_supply_is_system_supplied() > 0) { - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX; - } else { - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_MID_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_MID_SH_IDX; - } - break; - case PM_PROFILE_LOW: - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_LOW_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_LOW_SH_IDX; - break; - case PM_PROFILE_MID: - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_MID_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_MID_SH_IDX; - break; - case PM_PROFILE_HIGH: - if (rdev->pm.active_crtc_count > 1) - rdev->pm.profile_index = PM_PROFILE_HIGH_MH_IDX; - else - rdev->pm.profile_index = PM_PROFILE_HIGH_SH_IDX; - break; - } - - if (rdev->pm.active_crtc_count == 0) { - rdev->pm.requested_power_state_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_off_ps_idx; - rdev->pm.requested_clock_mode_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_off_cm_idx; - } else { - rdev->pm.requested_power_state_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_on_ps_idx; - rdev->pm.requested_clock_mode_index = - rdev->pm.profiles[rdev->pm.profile_index].dpms_on_cm_idx; - } -} - -static void radeon_unmap_vram_bos(struct radeon_device *rdev) -{ - struct radeon_bo *bo, *n; - - if (list_empty(&rdev->gem.objects)) - return; - - list_for_each_entry_safe(bo, n, &rdev->gem.objects, list) { - if (bo->tbo.mem.mem_type == TTM_PL_VRAM) - ttm_bo_unmap_virtual(&bo->tbo); - } -} - -static void radeon_sync_with_vblank(struct radeon_device *rdev) -{ - if (rdev->pm.active_crtcs) { - rdev->pm.vblank_sync = false; - wait_event_timeout( - rdev->irq.vblank_queue, rdev->pm.vblank_sync, - msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); - } -} - -static void radeon_set_power_state(struct radeon_device *rdev) -{ - u32 sclk, mclk; - bool misc_after = false; - - if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && - (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) - return; - - if (radeon_gui_idle(rdev)) { - sclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].sclk; - if (sclk > rdev->pm.default_sclk) - sclk = rdev->pm.default_sclk; - - mclk = rdev->pm.power_state[rdev->pm.requested_power_state_index]. - clock_info[rdev->pm.requested_clock_mode_index].mclk; - if (mclk > rdev->pm.default_mclk) - mclk = rdev->pm.default_mclk; - - /* upvolt before raising clocks, downvolt after lowering clocks */ - if (sclk < rdev->pm.current_sclk) - misc_after = true; - - radeon_sync_with_vblank(rdev); - - if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - if (!radeon_pm_in_vbl(rdev)) - return; - } - - radeon_pm_prepare(rdev); - - if (!misc_after) - /* voltage, pcie lanes, etc.*/ - radeon_pm_misc(rdev); - - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_sclk = sclk; - DRM_DEBUG_DRIVER("Setting: e: %d\n", sclk); - } - - /* set memory clock */ - if (rdev->asic->pm.set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = mclk; - DRM_DEBUG_DRIVER("Setting: m: %d\n", mclk); - } - - if (misc_after) - /* voltage, pcie lanes, etc.*/ - radeon_pm_misc(rdev); - - radeon_pm_finish(rdev); - - rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; - rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; - } else - DRM_DEBUG_DRIVER("pm: GUI not idle!!!\n"); -} - -static void radeon_pm_set_clocks(struct radeon_device *rdev) -{ - int i; - - /* no need to take locks, etc. if nothing's going to change */ - if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && - (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) - return; - - mutex_lock(&rdev->ddev->struct_mutex); - mutex_lock(&rdev->vram_mutex); - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (rdev->ring[i].ring_obj) - mutex_lock(&rdev->ring[i].mutex); - } - - /* gui idle int has issues on older chips it seems */ - if (rdev->family >= CHIP_R600) { - if (rdev->irq.installed) { - /* wait for GPU idle */ - rdev->pm.gui_idle = false; - rdev->irq.gui_idle = true; - radeon_irq_set(rdev); - wait_event_interruptible_timeout( - rdev->irq.idle_queue, rdev->pm.gui_idle, - msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); - rdev->irq.gui_idle = false; - radeon_irq_set(rdev); - } - } else { - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - if (ring->ready) { - struct radeon_fence *fence; - radeon_ring_alloc(rdev, ring, 64); - radeon_fence_create(rdev, &fence, radeon_ring_index(rdev, ring)); - radeon_fence_emit(rdev, fence); - radeon_ring_commit(rdev, ring); - radeon_fence_wait(fence, false); - radeon_fence_unref(&fence); - } - } - radeon_unmap_vram_bos(rdev); - - if (rdev->irq.installed) { - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->pm.active_crtcs & (1 << i)) { - rdev->pm.req_vblank |= (1 << i); - drm_vblank_get(rdev->ddev, i); - } - } - } - - radeon_set_power_state(rdev); - - if (rdev->irq.installed) { - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->pm.req_vblank & (1 << i)) { - rdev->pm.req_vblank &= ~(1 << i); - drm_vblank_put(rdev->ddev, i); - } - } - } - - /* update display watermarks based on new power state */ - radeon_update_bandwidth_info(rdev); - if (rdev->pm.active_crtc_count) - radeon_bandwidth_update(rdev); - - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (rdev->ring[i].ring_obj) - mutex_unlock(&rdev->ring[i].mutex); - } - mutex_unlock(&rdev->vram_mutex); - mutex_unlock(&rdev->ddev->struct_mutex); -} - -static void radeon_pm_print_states(struct radeon_device *rdev) -{ - int i, j; - struct radeon_power_state *power_state; - struct radeon_pm_clock_info *clock_info; - - DRM_DEBUG_DRIVER("%d Power State(s)\n", rdev->pm.num_power_states); - for (i = 0; i < rdev->pm.num_power_states; i++) { - power_state = &rdev->pm.power_state[i]; - DRM_DEBUG_DRIVER("State %d: %s\n", i, - radeon_pm_state_type_name[power_state->type]); - if (i == rdev->pm.default_power_state_index) - DRM_DEBUG_DRIVER("\tDefault"); - if ((rdev->flags & RADEON_IS_PCIE) && !(rdev->flags & RADEON_IS_IGP)) - DRM_DEBUG_DRIVER("\t%d PCIE Lanes\n", power_state->pcie_lanes); - if (power_state->flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY) - DRM_DEBUG_DRIVER("\tSingle display only\n"); - DRM_DEBUG_DRIVER("\t%d Clock Mode(s)\n", power_state->num_clock_modes); - for (j = 0; j < power_state->num_clock_modes; j++) { - clock_info = &(power_state->clock_info[j]); - if (rdev->flags & RADEON_IS_IGP) - DRM_DEBUG_DRIVER("\t\t%d e: %d%s\n", - j, - clock_info->sclk * 10, - clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); - else - DRM_DEBUG_DRIVER("\t\t%d e: %d\tm: %d\tv: %d%s\n", - j, - clock_info->sclk * 10, - clock_info->mclk * 10, - clock_info->voltage.voltage, - clock_info->flags & RADEON_PM_MODE_NO_DISPLAY ? "\tNo display only" : ""); - } - } -} - -static ssize_t radeon_get_pm_profile(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - int cp = rdev->pm.profile; - - return snprintf(buf, PAGE_SIZE, "%s\n", - (cp == PM_PROFILE_AUTO) ? "auto" : - (cp == PM_PROFILE_LOW) ? "low" : - (cp == PM_PROFILE_MID) ? "mid" : - (cp == PM_PROFILE_HIGH) ? "high" : "default"); -} - -static ssize_t radeon_set_pm_profile(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - if (strncmp("default", buf, strlen("default")) == 0) - rdev->pm.profile = PM_PROFILE_DEFAULT; - else if (strncmp("auto", buf, strlen("auto")) == 0) - rdev->pm.profile = PM_PROFILE_AUTO; - else if (strncmp("low", buf, strlen("low")) == 0) - rdev->pm.profile = PM_PROFILE_LOW; - else if (strncmp("mid", buf, strlen("mid")) == 0) - rdev->pm.profile = PM_PROFILE_MID; - else if (strncmp("high", buf, strlen("high")) == 0) - rdev->pm.profile = PM_PROFILE_HIGH; - else { - count = -EINVAL; - goto fail; - } - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - } else - count = -EINVAL; - -fail: - mutex_unlock(&rdev->pm.mutex); - - return count; -} - -static ssize_t radeon_get_pm_method(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - int pm = rdev->pm.pm_method; - - return snprintf(buf, PAGE_SIZE, "%s\n", - (pm == PM_METHOD_DYNPM) ? "dynpm" : "profile"); -} - -static ssize_t radeon_set_pm_method(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - - - if (strncmp("dynpm", buf, strlen("dynpm")) == 0) { - mutex_lock(&rdev->pm.mutex); - rdev->pm.pm_method = PM_METHOD_DYNPM; - rdev->pm.dynpm_state = DYNPM_STATE_PAUSED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; - mutex_unlock(&rdev->pm.mutex); - } else if (strncmp("profile", buf, strlen("profile")) == 0) { - mutex_lock(&rdev->pm.mutex); - /* disable dynpm */ - rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - rdev->pm.pm_method = PM_METHOD_PROFILE; - mutex_unlock(&rdev->pm.mutex); - cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); - } else { - count = -EINVAL; - goto fail; - } - radeon_pm_compute_clocks(rdev); -fail: - return count; -} - -static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile); -static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method); - -static ssize_t radeon_hwmon_show_temp(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev)); - struct radeon_device *rdev = ddev->dev_private; - int temp; - - switch (rdev->pm.int_thermal_type) { - case THERMAL_TYPE_RV6XX: - temp = rv6xx_get_temp(rdev); - break; - case THERMAL_TYPE_RV770: - temp = rv770_get_temp(rdev); - break; - case THERMAL_TYPE_EVERGREEN: - case THERMAL_TYPE_NI: - temp = evergreen_get_temp(rdev); - break; - case THERMAL_TYPE_SUMO: - temp = sumo_get_temp(rdev); - break; - case THERMAL_TYPE_SI: - temp = si_get_temp(rdev); - break; - default: - temp = 0; - break; - } - - return snprintf(buf, PAGE_SIZE, "%d\n", temp); -} - -static ssize_t radeon_hwmon_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "radeon\n"); -} - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, radeon_hwmon_show_temp, NULL, 0); -static SENSOR_DEVICE_ATTR(name, S_IRUGO, radeon_hwmon_show_name, NULL, 0); - -static struct attribute *hwmon_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_name.dev_attr.attr, - NULL -}; - -static const struct attribute_group hwmon_attrgroup = { - .attrs = hwmon_attributes, -}; - -static int radeon_hwmon_init(struct radeon_device *rdev) -{ - int err = 0; - - rdev->pm.int_hwmon_dev = NULL; - - switch (rdev->pm.int_thermal_type) { - case THERMAL_TYPE_RV6XX: - case THERMAL_TYPE_RV770: - case THERMAL_TYPE_EVERGREEN: - case THERMAL_TYPE_NI: - case THERMAL_TYPE_SUMO: - case THERMAL_TYPE_SI: - /* No support for TN yet */ - if (rdev->family == CHIP_ARUBA) - return err; - rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); - if (IS_ERR(rdev->pm.int_hwmon_dev)) { - err = PTR_ERR(rdev->pm.int_hwmon_dev); - dev_err(rdev->dev, - "Unable to register hwmon device: %d\n", err); - break; - } - dev_set_drvdata(rdev->pm.int_hwmon_dev, rdev->ddev); - err = sysfs_create_group(&rdev->pm.int_hwmon_dev->kobj, - &hwmon_attrgroup); - if (err) { - dev_err(rdev->dev, - "Unable to create hwmon sysfs file: %d\n", err); - hwmon_device_unregister(rdev->dev); - } - break; - default: - break; - } - - return err; -} - -static void radeon_hwmon_fini(struct radeon_device *rdev) -{ - if (rdev->pm.int_hwmon_dev) { - sysfs_remove_group(&rdev->pm.int_hwmon_dev->kobj, &hwmon_attrgroup); - hwmon_device_unregister(rdev->pm.int_hwmon_dev); - } -} - -void radeon_pm_suspend(struct radeon_device *rdev) -{ - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) - rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; - } - mutex_unlock(&rdev->pm.mutex); - - cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); -} - -void radeon_pm_resume(struct radeon_device *rdev) -{ - /* set up the default clocks if the MC ucode is loaded */ - if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { - if (rdev->pm.default_vddc) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, - SET_VOLTAGE_TYPE_ASIC_VDDC); - if (rdev->pm.default_vddci) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, - SET_VOLTAGE_TYPE_ASIC_VDDCI); - if (rdev->pm.default_sclk) - radeon_set_engine_clock(rdev, rdev->pm.default_sclk); - if (rdev->pm.default_mclk) - radeon_set_memory_clock(rdev, rdev->pm.default_mclk); - } - /* asic init will reset the default power state */ - mutex_lock(&rdev->pm.mutex); - rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; - rdev->pm.current_clock_mode_index = 0; - rdev->pm.current_sclk = rdev->pm.default_sclk; - rdev->pm.current_mclk = rdev->pm.default_mclk; - rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; - rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci; - if (rdev->pm.pm_method == PM_METHOD_DYNPM - && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; - schedule_delayed_work(&rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - } - mutex_unlock(&rdev->pm.mutex); - radeon_pm_compute_clocks(rdev); -} - -int radeon_pm_init(struct radeon_device *rdev) -{ - int ret; - - /* default to profile method */ - rdev->pm.pm_method = PM_METHOD_PROFILE; - rdev->pm.profile = PM_PROFILE_DEFAULT; - rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - rdev->pm.dynpm_can_upclock = true; - rdev->pm.dynpm_can_downclock = true; - rdev->pm.default_sclk = rdev->clock.default_sclk; - rdev->pm.default_mclk = rdev->clock.default_mclk; - rdev->pm.current_sclk = rdev->clock.default_sclk; - rdev->pm.current_mclk = rdev->clock.default_mclk; - rdev->pm.int_thermal_type = THERMAL_TYPE_NONE; - - if (rdev->bios) { - if (rdev->is_atom_bios) - radeon_atombios_get_power_modes(rdev); - else - radeon_combios_get_power_modes(rdev); - radeon_pm_print_states(rdev); - radeon_pm_init_profile(rdev); - /* set up the default clocks if the MC ucode is loaded */ - if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { - if (rdev->pm.default_vddc) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, - SET_VOLTAGE_TYPE_ASIC_VDDC); - if (rdev->pm.default_vddci) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, - SET_VOLTAGE_TYPE_ASIC_VDDCI); - if (rdev->pm.default_sclk) - radeon_set_engine_clock(rdev, rdev->pm.default_sclk); - if (rdev->pm.default_mclk) - radeon_set_memory_clock(rdev, rdev->pm.default_mclk); - } - } - - /* set up the internal thermal sensor if applicable */ - ret = radeon_hwmon_init(rdev); - if (ret) - return ret; - - INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler); - - if (rdev->pm.num_power_states > 1) { - /* where's the best place to put these? */ - ret = device_create_file(rdev->dev, &dev_attr_power_profile); - if (ret) - DRM_ERROR("failed to create device file for power profile\n"); - ret = device_create_file(rdev->dev, &dev_attr_power_method); - if (ret) - DRM_ERROR("failed to create device file for power method\n"); - -#ifdef CONFIG_ACPI - rdev->acpi_nb.notifier_call = radeon_acpi_event; - register_acpi_notifier(&rdev->acpi_nb); -#endif - if (radeon_debugfs_pm_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for PM!\n"); - } - - DRM_INFO("radeon: power management initialized\n"); - } - - return 0; -} - -void radeon_pm_fini(struct radeon_device *rdev) -{ - if (rdev->pm.num_power_states > 1) { - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - rdev->pm.profile = PM_PROFILE_DEFAULT; - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - /* reset default clocks */ - rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; - radeon_pm_set_clocks(rdev); - } - mutex_unlock(&rdev->pm.mutex); - - cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work); - - device_remove_file(rdev->dev, &dev_attr_power_profile); - device_remove_file(rdev->dev, &dev_attr_power_method); -#ifdef CONFIG_ACPI - unregister_acpi_notifier(&rdev->acpi_nb); -#endif - } - - if (rdev->pm.power_state) - kfree(rdev->pm.power_state); - - radeon_hwmon_fini(rdev); -} - -void radeon_pm_compute_clocks(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - - if (rdev->pm.num_power_states < 2) - return; - - mutex_lock(&rdev->pm.mutex); - - rdev->pm.active_crtcs = 0; - rdev->pm.active_crtc_count = 0; - list_for_each_entry(crtc, - &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); - rdev->pm.active_crtc_count++; - } - } - - if (rdev->pm.pm_method == PM_METHOD_PROFILE) { - radeon_pm_update_profile(rdev); - radeon_pm_set_clocks(rdev); - } else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - if (rdev->pm.dynpm_state != DYNPM_STATE_DISABLED) { - if (rdev->pm.active_crtc_count > 1) { - if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) { - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - - rdev->pm.dynpm_state = DYNPM_STATE_PAUSED; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - - DRM_DEBUG_DRIVER("radeon: dynamic power management deactivated\n"); - } - } else if (rdev->pm.active_crtc_count == 1) { - /* TODO: Increase clocks if needed for current mode */ - - if (rdev->pm.dynpm_state == DYNPM_STATE_MINIMUM) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_UPCLOCK; - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - - schedule_delayed_work(&rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { - rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; - schedule_delayed_work(&rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); - } - } else { /* count == 0 */ - if (rdev->pm.dynpm_state != DYNPM_STATE_MINIMUM) { - cancel_delayed_work(&rdev->pm.dynpm_idle_work); - - rdev->pm.dynpm_state = DYNPM_STATE_MINIMUM; - rdev->pm.dynpm_planned_action = DYNPM_ACTION_MINIMUM; - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - } - } - } - } - - mutex_unlock(&rdev->pm.mutex); -} - -static bool radeon_pm_in_vbl(struct radeon_device *rdev) -{ - int crtc, vpos, hpos, vbl_status; - bool in_vbl = true; - - /* Iterate over all active crtc's. All crtc's must be in vblank, - * otherwise return in_vbl == false. - */ - for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { - if (rdev->pm.active_crtcs & (1 << crtc)) { - vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos); - if ((vbl_status & DRM_SCANOUTPOS_VALID) && - !(vbl_status & DRM_SCANOUTPOS_INVBL)) - in_vbl = false; - } - } - - return in_vbl; -} - -static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish) -{ - u32 stat_crtc = 0; - bool in_vbl = radeon_pm_in_vbl(rdev); - - if (in_vbl == false) - DRM_DEBUG_DRIVER("not in vbl for pm change %08x at %s\n", stat_crtc, - finish ? "exit" : "entry"); - return in_vbl; -} - -static void radeon_dynpm_idle_work_handler(struct work_struct *work) -{ - struct radeon_device *rdev; - int resched; - rdev = container_of(work, struct radeon_device, - pm.dynpm_idle_work.work); - - resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); - mutex_lock(&rdev->pm.mutex); - if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) { - int not_processed = 0; - int i; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - not_processed += radeon_fence_count_emitted(rdev, i); - if (not_processed >= 3) - break; - } - - if (not_processed >= 3) { /* should upclock */ - if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_DOWNCLOCK) { - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - } else if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_NONE && - rdev->pm.dynpm_can_upclock) { - rdev->pm.dynpm_planned_action = - DYNPM_ACTION_UPCLOCK; - rdev->pm.dynpm_action_timeout = jiffies + - msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); - } - } else if (not_processed == 0) { /* should downclock */ - if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_UPCLOCK) { - rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - } else if (rdev->pm.dynpm_planned_action == DYNPM_ACTION_NONE && - rdev->pm.dynpm_can_downclock) { - rdev->pm.dynpm_planned_action = - DYNPM_ACTION_DOWNCLOCK; - rdev->pm.dynpm_action_timeout = jiffies + - msecs_to_jiffies(RADEON_RECLOCK_DELAY_MS); - } - } - - /* Note, radeon_pm_set_clocks is called with static_switch set - * to false since we want to wait for vbl to avoid flicker. - */ - if (rdev->pm.dynpm_planned_action != DYNPM_ACTION_NONE && - jiffies > rdev->pm.dynpm_action_timeout) { - radeon_pm_get_dynpm_state(rdev); - radeon_pm_set_clocks(rdev); - } - - schedule_delayed_work(&rdev->pm.dynpm_idle_work, - msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); - } - mutex_unlock(&rdev->pm.mutex); - ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); -} - -/* - * Debugfs info - */ -#if defined(CONFIG_DEBUG_FS) - -static int radeon_debugfs_pm_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - - seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk); - seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); - seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk); - if (rdev->asic->pm.get_memory_clock) - seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); - if (rdev->pm.current_vddc) - seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc); - if (rdev->asic->pm.get_pcie_lanes) - seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev)); - - return 0; -} - -static struct drm_info_list radeon_pm_info_list[] = { - {"radeon_pm_info", radeon_debugfs_pm_info, 0, NULL}, -}; -#endif - -static int radeon_debugfs_pm_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); -#else - return 0; -#endif -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_reg.h deleted file mode 100644 index 5d8f735d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_reg.h +++ /dev/null @@ -1,3709 +0,0 @@ -/* - * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and - * VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR - * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* - * Authors: - * Kevin E. Martin - * Rickard E. Faith - * Alan Hourihane - * - * References: - * - * !!!! FIXME !!!! - * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical - * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April - * 1999. - * - * !!!! FIXME !!!! - * RAGE 128 Software Development Manual (Technical Reference Manual P/N - * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. - * - */ - -/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h - * AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT - * ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */ -#ifndef _RADEON_REG_H_ -#define _RADEON_REG_H_ - -#include "r300_reg.h" -#include "r500_reg.h" -#include "r600_reg.h" -#include "evergreen_reg.h" -#include "ni_reg.h" -#include "si_reg.h" - -#define RADEON_MC_AGP_LOCATION 0x014c -#define RADEON_MC_AGP_START_MASK 0x0000FFFF -#define RADEON_MC_AGP_START_SHIFT 0 -#define RADEON_MC_AGP_TOP_MASK 0xFFFF0000 -#define RADEON_MC_AGP_TOP_SHIFT 16 -#define RADEON_MC_FB_LOCATION 0x0148 -#define RADEON_MC_FB_START_MASK 0x0000FFFF -#define RADEON_MC_FB_START_SHIFT 0 -#define RADEON_MC_FB_TOP_MASK 0xFFFF0000 -#define RADEON_MC_FB_TOP_SHIFT 16 -#define RADEON_AGP_BASE_2 0x015c /* r200+ only */ -#define RADEON_AGP_BASE 0x0170 - -#define ATI_DATATYPE_VQ 0 -#define ATI_DATATYPE_CI4 1 -#define ATI_DATATYPE_CI8 2 -#define ATI_DATATYPE_ARGB1555 3 -#define ATI_DATATYPE_RGB565 4 -#define ATI_DATATYPE_RGB888 5 -#define ATI_DATATYPE_ARGB8888 6 -#define ATI_DATATYPE_RGB332 7 -#define ATI_DATATYPE_Y8 8 -#define ATI_DATATYPE_RGB8 9 -#define ATI_DATATYPE_CI16 10 -#define ATI_DATATYPE_VYUY_422 11 -#define ATI_DATATYPE_YVYU_422 12 -#define ATI_DATATYPE_AYUV_444 14 -#define ATI_DATATYPE_ARGB4444 15 - - /* Registers for 2D/Video/Overlay */ -#define RADEON_ADAPTER_ID 0x0f2c /* PCI */ -#define RADEON_AGP_BASE 0x0170 -#define RADEON_AGP_CNTL 0x0174 -# define RADEON_AGP_APER_SIZE_256MB (0x00 << 0) -# define RADEON_AGP_APER_SIZE_128MB (0x20 << 0) -# define RADEON_AGP_APER_SIZE_64MB (0x30 << 0) -# define RADEON_AGP_APER_SIZE_32MB (0x38 << 0) -# define RADEON_AGP_APER_SIZE_16MB (0x3c << 0) -# define RADEON_AGP_APER_SIZE_8MB (0x3e << 0) -# define RADEON_AGP_APER_SIZE_4MB (0x3f << 0) -# define RADEON_AGP_APER_SIZE_MASK (0x3f << 0) -#define RADEON_STATUS_PCI_CONFIG 0x06 -# define RADEON_CAP_LIST 0x100000 -#define RADEON_CAPABILITIES_PTR_PCI_CONFIG 0x34 /* offset in PCI config*/ -# define RADEON_CAP_PTR_MASK 0xfc /* mask off reserved bits of CAP_PTR */ -# define RADEON_CAP_ID_NULL 0x00 /* End of capability list */ -# define RADEON_CAP_ID_AGP 0x02 /* AGP capability ID */ -# define RADEON_CAP_ID_EXP 0x10 /* PCI Express */ -#define RADEON_AGP_COMMAND 0x0f60 /* PCI */ -#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config*/ -# define RADEON_AGP_ENABLE (1<<8) -#define RADEON_AGP_PLL_CNTL 0x000b /* PLL */ -#define RADEON_AGP_STATUS 0x0f5c /* PCI */ -# define RADEON_AGP_1X_MODE 0x01 -# define RADEON_AGP_2X_MODE 0x02 -# define RADEON_AGP_4X_MODE 0x04 -# define RADEON_AGP_FW_MODE 0x10 -# define RADEON_AGP_MODE_MASK 0x17 -# define RADEON_AGPv3_MODE 0x08 -# define RADEON_AGPv3_4X_MODE 0x01 -# define RADEON_AGPv3_8X_MODE 0x02 -#define RADEON_ATTRDR 0x03c1 /* VGA */ -#define RADEON_ATTRDW 0x03c0 /* VGA */ -#define RADEON_ATTRX 0x03c0 /* VGA */ -#define RADEON_AUX_SC_CNTL 0x1660 -# define RADEON_AUX1_SC_EN (1 << 0) -# define RADEON_AUX1_SC_MODE_OR (0 << 1) -# define RADEON_AUX1_SC_MODE_NAND (1 << 1) -# define RADEON_AUX2_SC_EN (1 << 2) -# define RADEON_AUX2_SC_MODE_OR (0 << 3) -# define RADEON_AUX2_SC_MODE_NAND (1 << 3) -# define RADEON_AUX3_SC_EN (1 << 4) -# define RADEON_AUX3_SC_MODE_OR (0 << 5) -# define RADEON_AUX3_SC_MODE_NAND (1 << 5) -#define RADEON_AUX1_SC_BOTTOM 0x1670 -#define RADEON_AUX1_SC_LEFT 0x1664 -#define RADEON_AUX1_SC_RIGHT 0x1668 -#define RADEON_AUX1_SC_TOP 0x166c -#define RADEON_AUX2_SC_BOTTOM 0x1680 -#define RADEON_AUX2_SC_LEFT 0x1674 -#define RADEON_AUX2_SC_RIGHT 0x1678 -#define RADEON_AUX2_SC_TOP 0x167c -#define RADEON_AUX3_SC_BOTTOM 0x1690 -#define RADEON_AUX3_SC_LEFT 0x1684 -#define RADEON_AUX3_SC_RIGHT 0x1688 -#define RADEON_AUX3_SC_TOP 0x168c -#define RADEON_AUX_WINDOW_HORZ_CNTL 0x02d8 -#define RADEON_AUX_WINDOW_VERT_CNTL 0x02dc - -#define RADEON_BASE_CODE 0x0f0b -#define RADEON_BIOS_0_SCRATCH 0x0010 -# define RADEON_FP_PANEL_SCALABLE (1 << 16) -# define RADEON_FP_PANEL_SCALE_EN (1 << 17) -# define RADEON_FP_CHIP_SCALE_EN (1 << 18) -# define RADEON_DRIVER_BRIGHTNESS_EN (1 << 26) -# define RADEON_DISPLAY_ROT_MASK (3 << 28) -# define RADEON_DISPLAY_ROT_00 (0 << 28) -# define RADEON_DISPLAY_ROT_90 (1 << 28) -# define RADEON_DISPLAY_ROT_180 (2 << 28) -# define RADEON_DISPLAY_ROT_270 (3 << 28) -#define RADEON_BIOS_1_SCRATCH 0x0014 -#define RADEON_BIOS_2_SCRATCH 0x0018 -#define RADEON_BIOS_3_SCRATCH 0x001c -#define RADEON_BIOS_4_SCRATCH 0x0020 -# define RADEON_CRT1_ATTACHED_MASK (3 << 0) -# define RADEON_CRT1_ATTACHED_MONO (1 << 0) -# define RADEON_CRT1_ATTACHED_COLOR (2 << 0) -# define RADEON_LCD1_ATTACHED (1 << 2) -# define RADEON_DFP1_ATTACHED (1 << 3) -# define RADEON_TV1_ATTACHED_MASK (3 << 4) -# define RADEON_TV1_ATTACHED_COMP (1 << 4) -# define RADEON_TV1_ATTACHED_SVIDEO (2 << 4) -# define RADEON_CRT2_ATTACHED_MASK (3 << 8) -# define RADEON_CRT2_ATTACHED_MONO (1 << 8) -# define RADEON_CRT2_ATTACHED_COLOR (2 << 8) -# define RADEON_DFP2_ATTACHED (1 << 11) -#define RADEON_BIOS_5_SCRATCH 0x0024 -# define RADEON_LCD1_ON (1 << 0) -# define RADEON_CRT1_ON (1 << 1) -# define RADEON_TV1_ON (1 << 2) -# define RADEON_DFP1_ON (1 << 3) -# define RADEON_CRT2_ON (1 << 5) -# define RADEON_CV1_ON (1 << 6) -# define RADEON_DFP2_ON (1 << 7) -# define RADEON_LCD1_CRTC_MASK (1 << 8) -# define RADEON_LCD1_CRTC_SHIFT 8 -# define RADEON_CRT1_CRTC_MASK (1 << 9) -# define RADEON_CRT1_CRTC_SHIFT 9 -# define RADEON_TV1_CRTC_MASK (1 << 10) -# define RADEON_TV1_CRTC_SHIFT 10 -# define RADEON_DFP1_CRTC_MASK (1 << 11) -# define RADEON_DFP1_CRTC_SHIFT 11 -# define RADEON_CRT2_CRTC_MASK (1 << 12) -# define RADEON_CRT2_CRTC_SHIFT 12 -# define RADEON_CV1_CRTC_MASK (1 << 13) -# define RADEON_CV1_CRTC_SHIFT 13 -# define RADEON_DFP2_CRTC_MASK (1 << 14) -# define RADEON_DFP2_CRTC_SHIFT 14 -# define RADEON_ACC_REQ_LCD1 (1 << 16) -# define RADEON_ACC_REQ_CRT1 (1 << 17) -# define RADEON_ACC_REQ_TV1 (1 << 18) -# define RADEON_ACC_REQ_DFP1 (1 << 19) -# define RADEON_ACC_REQ_CRT2 (1 << 21) -# define RADEON_ACC_REQ_TV2 (1 << 22) -# define RADEON_ACC_REQ_DFP2 (1 << 23) -#define RADEON_BIOS_6_SCRATCH 0x0028 -# define RADEON_ACC_MODE_CHANGE (1 << 2) -# define RADEON_EXT_DESKTOP_MODE (1 << 3) -# define RADEON_LCD_DPMS_ON (1 << 20) -# define RADEON_CRT_DPMS_ON (1 << 21) -# define RADEON_TV_DPMS_ON (1 << 22) -# define RADEON_DFP_DPMS_ON (1 << 23) -# define RADEON_DPMS_MASK (3 << 24) -# define RADEON_DPMS_ON (0 << 24) -# define RADEON_DPMS_STANDBY (1 << 24) -# define RADEON_DPMS_SUSPEND (2 << 24) -# define RADEON_DPMS_OFF (3 << 24) -# define RADEON_SCREEN_BLANKING (1 << 26) -# define RADEON_DRIVER_CRITICAL (1 << 27) -# define RADEON_DISPLAY_SWITCHING_DIS (1 << 30) -#define RADEON_BIOS_7_SCRATCH 0x002c -# define RADEON_SYS_HOTKEY (1 << 10) -# define RADEON_DRV_LOADED (1 << 12) -#define RADEON_BIOS_ROM 0x0f30 /* PCI */ -#define RADEON_BIST 0x0f0f /* PCI */ -#define RADEON_BRUSH_DATA0 0x1480 -#define RADEON_BRUSH_DATA1 0x1484 -#define RADEON_BRUSH_DATA10 0x14a8 -#define RADEON_BRUSH_DATA11 0x14ac -#define RADEON_BRUSH_DATA12 0x14b0 -#define RADEON_BRUSH_DATA13 0x14b4 -#define RADEON_BRUSH_DATA14 0x14b8 -#define RADEON_BRUSH_DATA15 0x14bc -#define RADEON_BRUSH_DATA16 0x14c0 -#define RADEON_BRUSH_DATA17 0x14c4 -#define RADEON_BRUSH_DATA18 0x14c8 -#define RADEON_BRUSH_DATA19 0x14cc -#define RADEON_BRUSH_DATA2 0x1488 -#define RADEON_BRUSH_DATA20 0x14d0 -#define RADEON_BRUSH_DATA21 0x14d4 -#define RADEON_BRUSH_DATA22 0x14d8 -#define RADEON_BRUSH_DATA23 0x14dc -#define RADEON_BRUSH_DATA24 0x14e0 -#define RADEON_BRUSH_DATA25 0x14e4 -#define RADEON_BRUSH_DATA26 0x14e8 -#define RADEON_BRUSH_DATA27 0x14ec -#define RADEON_BRUSH_DATA28 0x14f0 -#define RADEON_BRUSH_DATA29 0x14f4 -#define RADEON_BRUSH_DATA3 0x148c -#define RADEON_BRUSH_DATA30 0x14f8 -#define RADEON_BRUSH_DATA31 0x14fc -#define RADEON_BRUSH_DATA32 0x1500 -#define RADEON_BRUSH_DATA33 0x1504 -#define RADEON_BRUSH_DATA34 0x1508 -#define RADEON_BRUSH_DATA35 0x150c -#define RADEON_BRUSH_DATA36 0x1510 -#define RADEON_BRUSH_DATA37 0x1514 -#define RADEON_BRUSH_DATA38 0x1518 -#define RADEON_BRUSH_DATA39 0x151c -#define RADEON_BRUSH_DATA4 0x1490 -#define RADEON_BRUSH_DATA40 0x1520 -#define RADEON_BRUSH_DATA41 0x1524 -#define RADEON_BRUSH_DATA42 0x1528 -#define RADEON_BRUSH_DATA43 0x152c -#define RADEON_BRUSH_DATA44 0x1530 -#define RADEON_BRUSH_DATA45 0x1534 -#define RADEON_BRUSH_DATA46 0x1538 -#define RADEON_BRUSH_DATA47 0x153c -#define RADEON_BRUSH_DATA48 0x1540 -#define RADEON_BRUSH_DATA49 0x1544 -#define RADEON_BRUSH_DATA5 0x1494 -#define RADEON_BRUSH_DATA50 0x1548 -#define RADEON_BRUSH_DATA51 0x154c -#define RADEON_BRUSH_DATA52 0x1550 -#define RADEON_BRUSH_DATA53 0x1554 -#define RADEON_BRUSH_DATA54 0x1558 -#define RADEON_BRUSH_DATA55 0x155c -#define RADEON_BRUSH_DATA56 0x1560 -#define RADEON_BRUSH_DATA57 0x1564 -#define RADEON_BRUSH_DATA58 0x1568 -#define RADEON_BRUSH_DATA59 0x156c -#define RADEON_BRUSH_DATA6 0x1498 -#define RADEON_BRUSH_DATA60 0x1570 -#define RADEON_BRUSH_DATA61 0x1574 -#define RADEON_BRUSH_DATA62 0x1578 -#define RADEON_BRUSH_DATA63 0x157c -#define RADEON_BRUSH_DATA7 0x149c -#define RADEON_BRUSH_DATA8 0x14a0 -#define RADEON_BRUSH_DATA9 0x14a4 -#define RADEON_BRUSH_SCALE 0x1470 -#define RADEON_BRUSH_Y_X 0x1474 -#define RADEON_BUS_CNTL 0x0030 -# define RADEON_BUS_MASTER_DIS (1 << 6) -# define RADEON_BUS_BIOS_DIS_ROM (1 << 12) -# define RS600_BUS_MASTER_DIS (1 << 14) -# define RS600_MSI_REARM (1 << 20) /* rs600/rs690/rs740 */ -# define RADEON_BUS_RD_DISCARD_EN (1 << 24) -# define RADEON_BUS_RD_ABORT_EN (1 << 25) -# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) -# define RADEON_BUS_WRT_BURST (1 << 29) -# define RADEON_BUS_READ_BURST (1 << 30) -#define RADEON_BUS_CNTL1 0x0034 -# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) -#define RV370_BUS_CNTL 0x004c -# define RV370_BUS_BIOS_DIS_ROM (1 << 2) -/* rv370/rv380, rv410, r423/r430/r480, r5xx */ -#define RADEON_MSI_REARM_EN 0x0160 -# define RV370_MSI_REARM_EN (1 << 0) - -/* #define RADEON_PCIE_INDEX 0x0030 */ -/* #define RADEON_PCIE_DATA 0x0034 */ -#define RADEON_PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE */ -# define RADEON_PCIE_LC_LINK_WIDTH_SHIFT 0 -# define RADEON_PCIE_LC_LINK_WIDTH_MASK 0x7 -# define RADEON_PCIE_LC_LINK_WIDTH_X0 0 -# define RADEON_PCIE_LC_LINK_WIDTH_X1 1 -# define RADEON_PCIE_LC_LINK_WIDTH_X2 2 -# define RADEON_PCIE_LC_LINK_WIDTH_X4 3 -# define RADEON_PCIE_LC_LINK_WIDTH_X8 4 -# define RADEON_PCIE_LC_LINK_WIDTH_X12 5 -# define RADEON_PCIE_LC_LINK_WIDTH_X16 6 -# define RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT 4 -# define RADEON_PCIE_LC_LINK_WIDTH_RD_MASK 0x70 -# define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) -# define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) -# define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) -# define R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) -# define R600_PCIE_LC_RENEGOTIATION_SUPPORT (1 << 9) -# define R600_PCIE_LC_RENEGOTIATE_EN (1 << 10) -# define R600_PCIE_LC_SHORT_RECONFIG_EN (1 << 11) -# define R600_PCIE_LC_UPCONFIGURE_SUPPORT (1 << 12) -# define R600_PCIE_LC_UPCONFIGURE_DIS (1 << 13) - -#define R600_TARGET_AND_CURRENT_PROFILE_INDEX 0x70c -#define R700_TARGET_AND_CURRENT_PROFILE_INDEX 0x66c - -#define RADEON_CACHE_CNTL 0x1724 -#define RADEON_CACHE_LINE 0x0f0c /* PCI */ -#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ -#define RADEON_CAPABILITIES_PTR 0x0f34 /* PCI */ -#define RADEON_CLK_PIN_CNTL 0x0001 /* PLL */ -# define RADEON_DONT_USE_XTALIN (1 << 4) -# define RADEON_SCLK_DYN_START_CNTL (1 << 15) -#define RADEON_CLOCK_CNTL_DATA 0x000c -#define RADEON_CLOCK_CNTL_INDEX 0x0008 -# define RADEON_PLL_WR_EN (1 << 7) -# define RADEON_PLL_DIV_SEL (3 << 8) -# define RADEON_PLL2_DIV_SEL_MASK (~(3 << 8)) -#define RADEON_CLK_PWRMGT_CNTL 0x0014 -# define RADEON_ENGIN_DYNCLK_MODE (1 << 12) -# define RADEON_ACTIVE_HILO_LAT_MASK (3 << 13) -# define RADEON_ACTIVE_HILO_LAT_SHIFT 13 -# define RADEON_DISP_DYN_STOP_LAT_MASK (1 << 12) -# define RADEON_MC_BUSY (1 << 16) -# define RADEON_DLL_READY (1 << 19) -# define RADEON_CG_NO1_DEBUG_0 (1 << 24) -# define RADEON_CG_NO1_DEBUG_MASK (0x1f << 24) -# define RADEON_DYN_STOP_MODE_MASK (7 << 21) -# define RADEON_TVPLL_PWRMGT_OFF (1 << 30) -# define RADEON_TVCLK_TURNOFF (1 << 31) -#define RADEON_PLL_PWRMGT_CNTL 0x0015 /* PLL */ -# define RADEON_PM_MODE_SEL (1 << 13) -# define RADEON_TCL_BYPASS_DISABLE (1 << 20) -#define RADEON_CLR_CMP_CLR_3D 0x1a24 -#define RADEON_CLR_CMP_CLR_DST 0x15c8 -#define RADEON_CLR_CMP_CLR_SRC 0x15c4 -#define RADEON_CLR_CMP_CNTL 0x15c0 -# define RADEON_SRC_CMP_EQ_COLOR (4 << 0) -# define RADEON_SRC_CMP_NEQ_COLOR (5 << 0) -# define RADEON_CLR_CMP_SRC_SOURCE (1 << 24) -#define RADEON_CLR_CMP_MASK 0x15cc -# define RADEON_CLR_CMP_MSK 0xffffffff -#define RADEON_CLR_CMP_MASK_3D 0x1A28 -#define RADEON_COMMAND 0x0f04 /* PCI */ -#define RADEON_COMPOSITE_SHADOW_ID 0x1a0c -#define RADEON_CONFIG_APER_0_BASE 0x0100 -#define RADEON_CONFIG_APER_1_BASE 0x0104 -#define RADEON_CONFIG_APER_SIZE 0x0108 -#define RADEON_CONFIG_BONDS 0x00e8 -#define RADEON_CONFIG_CNTL 0x00e0 -# define RADEON_CFG_VGA_RAM_EN (1 << 8) -# define RADEON_CFG_VGA_IO_DIS (1 << 9) -# define RADEON_CFG_ATI_REV_A11 (0 << 16) -# define RADEON_CFG_ATI_REV_A12 (1 << 16) -# define RADEON_CFG_ATI_REV_A13 (2 << 16) -# define RADEON_CFG_ATI_REV_ID_MASK (0xf << 16) -#define RADEON_CONFIG_MEMSIZE 0x00f8 -#define RADEON_CONFIG_MEMSIZE_EMBEDDED 0x0114 -#define RADEON_CONFIG_REG_1_BASE 0x010c -#define RADEON_CONFIG_REG_APER_SIZE 0x0110 -#define RADEON_CONFIG_XSTRAP 0x00e4 -#define RADEON_CONSTANT_COLOR_C 0x1d34 -# define RADEON_CONSTANT_COLOR_MASK 0x00ffffff -# define RADEON_CONSTANT_COLOR_ONE 0x00ffffff -# define RADEON_CONSTANT_COLOR_ZERO 0x00000000 -#define RADEON_CRC_CMDFIFO_ADDR 0x0740 -#define RADEON_CRC_CMDFIFO_DOUT 0x0744 -#define RADEON_GRPH_BUFFER_CNTL 0x02f0 -# define RADEON_GRPH_START_REQ_MASK (0x7f) -# define RADEON_GRPH_START_REQ_SHIFT 0 -# define RADEON_GRPH_STOP_REQ_MASK (0x7f<<8) -# define RADEON_GRPH_STOP_REQ_SHIFT 8 -# define RADEON_GRPH_CRITICAL_POINT_MASK (0x7f<<16) -# define RADEON_GRPH_CRITICAL_POINT_SHIFT 16 -# define RADEON_GRPH_CRITICAL_CNTL (1<<28) -# define RADEON_GRPH_BUFFER_SIZE (1<<29) -# define RADEON_GRPH_CRITICAL_AT_SOF (1<<30) -# define RADEON_GRPH_STOP_CNTL (1<<31) -#define RADEON_GRPH2_BUFFER_CNTL 0x03f0 -# define RADEON_GRPH2_START_REQ_MASK (0x7f) -# define RADEON_GRPH2_START_REQ_SHIFT 0 -# define RADEON_GRPH2_STOP_REQ_MASK (0x7f<<8) -# define RADEON_GRPH2_STOP_REQ_SHIFT 8 -# define RADEON_GRPH2_CRITICAL_POINT_MASK (0x7f<<16) -# define RADEON_GRPH2_CRITICAL_POINT_SHIFT 16 -# define RADEON_GRPH2_CRITICAL_CNTL (1<<28) -# define RADEON_GRPH2_BUFFER_SIZE (1<<29) -# define RADEON_GRPH2_CRITICAL_AT_SOF (1<<30) -# define RADEON_GRPH2_STOP_CNTL (1<<31) -#define RADEON_CRTC_CRNT_FRAME 0x0214 -#define RADEON_CRTC_EXT_CNTL 0x0054 -# define RADEON_CRTC_VGA_XOVERSCAN (1 << 0) -# define RADEON_VGA_ATI_LINEAR (1 << 3) -# define RADEON_XCRT_CNT_EN (1 << 6) -# define RADEON_CRTC_HSYNC_DIS (1 << 8) -# define RADEON_CRTC_VSYNC_DIS (1 << 9) -# define RADEON_CRTC_DISPLAY_DIS (1 << 10) -# define RADEON_CRTC_SYNC_TRISTAT (1 << 11) -# define RADEON_CRTC_CRT_ON (1 << 15) -#define RADEON_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 -# define RADEON_CRTC_HSYNC_DIS_BYTE (1 << 0) -# define RADEON_CRTC_VSYNC_DIS_BYTE (1 << 1) -# define RADEON_CRTC_DISPLAY_DIS_BYTE (1 << 2) -#define RADEON_CRTC_GEN_CNTL 0x0050 -# define RADEON_CRTC_DBL_SCAN_EN (1 << 0) -# define RADEON_CRTC_INTERLACE_EN (1 << 1) -# define RADEON_CRTC_CSYNC_EN (1 << 4) -# define RADEON_CRTC_ICON_EN (1 << 15) -# define RADEON_CRTC_CUR_EN (1 << 16) -# define RADEON_CRTC_VSTAT_MODE_MASK (3 << 17) -# define RADEON_CRTC_CUR_MODE_MASK (7 << 20) -# define RADEON_CRTC_CUR_MODE_SHIFT 20 -# define RADEON_CRTC_CUR_MODE_MONO 0 -# define RADEON_CRTC_CUR_MODE_24BPP 2 -# define RADEON_CRTC_EXT_DISP_EN (1 << 24) -# define RADEON_CRTC_EN (1 << 25) -# define RADEON_CRTC_DISP_REQ_EN_B (1 << 26) -#define RADEON_CRTC2_GEN_CNTL 0x03f8 -# define RADEON_CRTC2_DBL_SCAN_EN (1 << 0) -# define RADEON_CRTC2_INTERLACE_EN (1 << 1) -# define RADEON_CRTC2_SYNC_TRISTAT (1 << 4) -# define RADEON_CRTC2_HSYNC_TRISTAT (1 << 5) -# define RADEON_CRTC2_VSYNC_TRISTAT (1 << 6) -# define RADEON_CRTC2_CRT2_ON (1 << 7) -# define RADEON_CRTC2_PIX_WIDTH_SHIFT 8 -# define RADEON_CRTC2_PIX_WIDTH_MASK (0xf << 8) -# define RADEON_CRTC2_ICON_EN (1 << 15) -# define RADEON_CRTC2_CUR_EN (1 << 16) -# define RADEON_CRTC2_CUR_MODE_MASK (7 << 20) -# define RADEON_CRTC2_DISP_DIS (1 << 23) -# define RADEON_CRTC2_EN (1 << 25) -# define RADEON_CRTC2_DISP_REQ_EN_B (1 << 26) -# define RADEON_CRTC2_CSYNC_EN (1 << 27) -# define RADEON_CRTC2_HSYNC_DIS (1 << 28) -# define RADEON_CRTC2_VSYNC_DIS (1 << 29) -#define RADEON_CRTC_MORE_CNTL 0x27c -# define RADEON_CRTC_AUTO_HORZ_CENTER_EN (1<<2) -# define RADEON_CRTC_AUTO_VERT_CENTER_EN (1<<3) -# define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4) -# define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5) -#define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 -#define RADEON_CRTC_H_SYNC_STRT_WID 0x0204 -# define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0) -# define RADEON_CRTC_H_SYNC_STRT_CHAR (0x3ff << 3) -# define RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 -# define RADEON_CRTC_H_SYNC_WID (0x3f << 16) -# define RADEON_CRTC_H_SYNC_WID_SHIFT 16 -# define RADEON_CRTC_H_SYNC_POL (1 << 23) -#define RADEON_CRTC2_H_SYNC_STRT_WID 0x0304 -# define RADEON_CRTC2_H_SYNC_STRT_PIX (0x07 << 0) -# define RADEON_CRTC2_H_SYNC_STRT_CHAR (0x3ff << 3) -# define RADEON_CRTC2_H_SYNC_STRT_CHAR_SHIFT 3 -# define RADEON_CRTC2_H_SYNC_WID (0x3f << 16) -# define RADEON_CRTC2_H_SYNC_WID_SHIFT 16 -# define RADEON_CRTC2_H_SYNC_POL (1 << 23) -#define RADEON_CRTC_H_TOTAL_DISP 0x0200 -# define RADEON_CRTC_H_TOTAL (0x03ff << 0) -# define RADEON_CRTC_H_TOTAL_SHIFT 0 -# define RADEON_CRTC_H_DISP (0x01ff << 16) -# define RADEON_CRTC_H_DISP_SHIFT 16 -#define RADEON_CRTC2_H_TOTAL_DISP 0x0300 -# define RADEON_CRTC2_H_TOTAL (0x03ff << 0) -# define RADEON_CRTC2_H_TOTAL_SHIFT 0 -# define RADEON_CRTC2_H_DISP (0x01ff << 16) -# define RADEON_CRTC2_H_DISP_SHIFT 16 - -#define RADEON_CRTC_OFFSET_RIGHT 0x0220 -#define RADEON_CRTC_OFFSET 0x0224 -# define RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET (1<<30) -# define RADEON_CRTC_OFFSET__OFFSET_LOCK (1<<31) - -#define RADEON_CRTC2_OFFSET 0x0324 -# define RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET (1<<30) -# define RADEON_CRTC2_OFFSET__OFFSET_LOCK (1<<31) -#define RADEON_CRTC_OFFSET_CNTL 0x0228 -# define RADEON_CRTC_TILE_LINE_SHIFT 0 -# define RADEON_CRTC_TILE_LINE_RIGHT_SHIFT 4 -# define R300_CRTC_X_Y_MODE_EN_RIGHT (1 << 6) -# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_MASK (3 << 7) -# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_AUTO (0 << 7) -# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_SINGLE (1 << 7) -# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_DOUBLE (2 << 7) -# define R300_CRTC_MICRO_TILE_BUFFER_RIGHT_DIS (3 << 7) -# define R300_CRTC_X_Y_MODE_EN (1 << 9) -# define R300_CRTC_MICRO_TILE_BUFFER_MASK (3 << 10) -# define R300_CRTC_MICRO_TILE_BUFFER_AUTO (0 << 10) -# define R300_CRTC_MICRO_TILE_BUFFER_SINGLE (1 << 10) -# define R300_CRTC_MICRO_TILE_BUFFER_DOUBLE (2 << 10) -# define R300_CRTC_MICRO_TILE_BUFFER_DIS (3 << 10) -# define R300_CRTC_MICRO_TILE_EN_RIGHT (1 << 12) -# define R300_CRTC_MICRO_TILE_EN (1 << 13) -# define R300_CRTC_MACRO_TILE_EN_RIGHT (1 << 14) -# define R300_CRTC_MACRO_TILE_EN (1 << 15) -# define RADEON_CRTC_TILE_EN_RIGHT (1 << 14) -# define RADEON_CRTC_TILE_EN (1 << 15) -# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) -# define RADEON_CRTC_STEREO_OFFSET_EN (1 << 17) -# define RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN (1 << 28) -# define RADEON_CRTC_GUI_TRIG_OFFSET_RIGHT_EN (1 << 29) - -#define R300_CRTC_TILE_X0_Y0 0x0350 -#define R300_CRTC2_TILE_X0_Y0 0x0358 - -#define RADEON_CRTC2_OFFSET_CNTL 0x0328 -# define RADEON_CRTC2_OFFSET_FLIP_CNTL (1 << 16) -# define RADEON_CRTC2_TILE_EN (1 << 15) -#define RADEON_CRTC_PITCH 0x022c -# define RADEON_CRTC_PITCH__SHIFT 0 -# define RADEON_CRTC_PITCH__RIGHT_SHIFT 16 - -#define RADEON_CRTC2_PITCH 0x032c -#define RADEON_CRTC_STATUS 0x005c -# define RADEON_CRTC_VBLANK_CUR (1 << 0) -# define RADEON_CRTC_VBLANK_SAVE (1 << 1) -# define RADEON_CRTC_VBLANK_SAVE_CLEAR (1 << 1) -#define RADEON_CRTC2_STATUS 0x03fc -# define RADEON_CRTC2_VBLANK_CUR (1 << 0) -# define RADEON_CRTC2_VBLANK_SAVE (1 << 1) -# define RADEON_CRTC2_VBLANK_SAVE_CLEAR (1 << 1) -#define RADEON_CRTC_V_SYNC_STRT_WID 0x020c -# define RADEON_CRTC_V_SYNC_STRT (0x7ff << 0) -# define RADEON_CRTC_V_SYNC_STRT_SHIFT 0 -# define RADEON_CRTC_V_SYNC_WID (0x1f << 16) -# define RADEON_CRTC_V_SYNC_WID_SHIFT 16 -# define RADEON_CRTC_V_SYNC_POL (1 << 23) -#define RADEON_CRTC2_V_SYNC_STRT_WID 0x030c -# define RADEON_CRTC2_V_SYNC_STRT (0x7ff << 0) -# define RADEON_CRTC2_V_SYNC_STRT_SHIFT 0 -# define RADEON_CRTC2_V_SYNC_WID (0x1f << 16) -# define RADEON_CRTC2_V_SYNC_WID_SHIFT 16 -# define RADEON_CRTC2_V_SYNC_POL (1 << 23) -#define RADEON_CRTC_V_TOTAL_DISP 0x0208 -# define RADEON_CRTC_V_TOTAL (0x07ff << 0) -# define RADEON_CRTC_V_TOTAL_SHIFT 0 -# define RADEON_CRTC_V_DISP (0x07ff << 16) -# define RADEON_CRTC_V_DISP_SHIFT 16 -#define RADEON_CRTC2_V_TOTAL_DISP 0x0308 -# define RADEON_CRTC2_V_TOTAL (0x07ff << 0) -# define RADEON_CRTC2_V_TOTAL_SHIFT 0 -# define RADEON_CRTC2_V_DISP (0x07ff << 16) -# define RADEON_CRTC2_V_DISP_SHIFT 16 -#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210 -# define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16) -#define RADEON_CRTC2_CRNT_FRAME 0x0314 -#define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318 -#define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310 -#define RADEON_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ -#define RADEON_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ -#define RADEON_CUR_CLR0 0x026c -#define RADEON_CUR_CLR1 0x0270 -#define RADEON_CUR_HORZ_VERT_OFF 0x0268 -#define RADEON_CUR_HORZ_VERT_POSN 0x0264 -#define RADEON_CUR_OFFSET 0x0260 -# define RADEON_CUR_LOCK (1 << 31) -#define RADEON_CUR2_CLR0 0x036c -#define RADEON_CUR2_CLR1 0x0370 -#define RADEON_CUR2_HORZ_VERT_OFF 0x0368 -#define RADEON_CUR2_HORZ_VERT_POSN 0x0364 -#define RADEON_CUR2_OFFSET 0x0360 -# define RADEON_CUR2_LOCK (1 << 31) - -#define RADEON_DAC_CNTL 0x0058 -# define RADEON_DAC_RANGE_CNTL (3 << 0) -# define RADEON_DAC_RANGE_CNTL_PS2 (2 << 0) -# define RADEON_DAC_RANGE_CNTL_MASK 0x03 -# define RADEON_DAC_BLANKING (1 << 2) -# define RADEON_DAC_CMP_EN (1 << 3) -# define RADEON_DAC_CMP_OUTPUT (1 << 7) -# define RADEON_DAC_8BIT_EN (1 << 8) -# define RADEON_DAC_TVO_EN (1 << 10) -# define RADEON_DAC_VGA_ADR_EN (1 << 13) -# define RADEON_DAC_PDWN (1 << 15) -# define RADEON_DAC_MASK_ALL (0xff << 24) -#define RADEON_DAC_CNTL2 0x007c -# define RADEON_DAC2_TV_CLK_SEL (0 << 1) -# define RADEON_DAC2_DAC_CLK_SEL (1 << 0) -# define RADEON_DAC2_DAC2_CLK_SEL (1 << 1) -# define RADEON_DAC2_PALETTE_ACC_CTL (1 << 5) -# define RADEON_DAC2_CMP_EN (1 << 7) -# define RADEON_DAC2_CMP_OUT_R (1 << 8) -# define RADEON_DAC2_CMP_OUT_G (1 << 9) -# define RADEON_DAC2_CMP_OUT_B (1 << 10) -# define RADEON_DAC2_CMP_OUTPUT (1 << 11) -#define RADEON_DAC_EXT_CNTL 0x0280 -# define RADEON_DAC2_FORCE_BLANK_OFF_EN (1 << 0) -# define RADEON_DAC2_FORCE_DATA_EN (1 << 1) -# define RADEON_DAC_FORCE_BLANK_OFF_EN (1 << 4) -# define RADEON_DAC_FORCE_DATA_EN (1 << 5) -# define RADEON_DAC_FORCE_DATA_SEL_MASK (3 << 6) -# define RADEON_DAC_FORCE_DATA_SEL_R (0 << 6) -# define RADEON_DAC_FORCE_DATA_SEL_G (1 << 6) -# define RADEON_DAC_FORCE_DATA_SEL_B (2 << 6) -# define RADEON_DAC_FORCE_DATA_SEL_RGB (3 << 6) -# define RADEON_DAC_FORCE_DATA_MASK 0x0003ff00 -# define RADEON_DAC_FORCE_DATA_SHIFT 8 -#define RADEON_DAC_MACRO_CNTL 0x0d04 -# define RADEON_DAC_PDWN_R (1 << 16) -# define RADEON_DAC_PDWN_G (1 << 17) -# define RADEON_DAC_PDWN_B (1 << 18) -#define RADEON_DISP_PWR_MAN 0x0d08 -# define RADEON_DISP_PWR_MAN_D3_CRTC_EN (1 << 0) -# define RADEON_DISP_PWR_MAN_D3_CRTC2_EN (1 << 4) -# define RADEON_DISP_PWR_MAN_DPMS_ON (0 << 8) -# define RADEON_DISP_PWR_MAN_DPMS_STANDBY (1 << 8) -# define RADEON_DISP_PWR_MAN_DPMS_SUSPEND (2 << 8) -# define RADEON_DISP_PWR_MAN_DPMS_OFF (3 << 8) -# define RADEON_DISP_D3_RST (1 << 16) -# define RADEON_DISP_D3_REG_RST (1 << 17) -# define RADEON_DISP_D3_GRPH_RST (1 << 18) -# define RADEON_DISP_D3_SUBPIC_RST (1 << 19) -# define RADEON_DISP_D3_OV0_RST (1 << 20) -# define RADEON_DISP_D1D2_GRPH_RST (1 << 21) -# define RADEON_DISP_D1D2_SUBPIC_RST (1 << 22) -# define RADEON_DISP_D1D2_OV0_RST (1 << 23) -# define RADEON_DIG_TMDS_ENABLE_RST (1 << 24) -# define RADEON_TV_ENABLE_RST (1 << 25) -# define RADEON_AUTO_PWRUP_EN (1 << 26) -#define RADEON_TV_DAC_CNTL 0x088c -# define RADEON_TV_DAC_NBLANK (1 << 0) -# define RADEON_TV_DAC_NHOLD (1 << 1) -# define RADEON_TV_DAC_PEDESTAL (1 << 2) -# define RADEON_TV_MONITOR_DETECT_EN (1 << 4) -# define RADEON_TV_DAC_CMPOUT (1 << 5) -# define RADEON_TV_DAC_STD_MASK (3 << 8) -# define RADEON_TV_DAC_STD_PAL (0 << 8) -# define RADEON_TV_DAC_STD_NTSC (1 << 8) -# define RADEON_TV_DAC_STD_PS2 (2 << 8) -# define RADEON_TV_DAC_STD_RS343 (3 << 8) -# define RADEON_TV_DAC_BGSLEEP (1 << 6) -# define RADEON_TV_DAC_BGADJ_MASK (0xf << 16) -# define RADEON_TV_DAC_BGADJ_SHIFT 16 -# define RADEON_TV_DAC_DACADJ_MASK (0xf << 20) -# define RADEON_TV_DAC_DACADJ_SHIFT 20 -# define RADEON_TV_DAC_RDACPD (1 << 24) -# define RADEON_TV_DAC_GDACPD (1 << 25) -# define RADEON_TV_DAC_BDACPD (1 << 26) -# define RADEON_TV_DAC_RDACDET (1 << 29) -# define RADEON_TV_DAC_GDACDET (1 << 30) -# define RADEON_TV_DAC_BDACDET (1 << 31) -# define R420_TV_DAC_DACADJ_MASK (0x1f << 20) -# define R420_TV_DAC_RDACPD (1 << 25) -# define R420_TV_DAC_GDACPD (1 << 26) -# define R420_TV_DAC_BDACPD (1 << 27) -# define R420_TV_DAC_TVENABLE (1 << 28) -#define RADEON_DISP_HW_DEBUG 0x0d14 -# define RADEON_CRT2_DISP1_SEL (1 << 5) -#define RADEON_DISP_OUTPUT_CNTL 0x0d64 -# define RADEON_DISP_DAC_SOURCE_MASK 0x03 -# define RADEON_DISP_DAC2_SOURCE_MASK 0x0c -# define RADEON_DISP_DAC_SOURCE_CRTC2 0x01 -# define RADEON_DISP_DAC_SOURCE_RMX 0x02 -# define RADEON_DISP_DAC_SOURCE_LTU 0x03 -# define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04 -# define RADEON_DISP_TVDAC_SOURCE_MASK (0x03 << 2) -# define RADEON_DISP_TVDAC_SOURCE_CRTC 0x0 -# define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01 << 2) -# define RADEON_DISP_TVDAC_SOURCE_RMX (0x02 << 2) -# define RADEON_DISP_TVDAC_SOURCE_LTU (0x03 << 2) -# define RADEON_DISP_TRANS_MATRIX_MASK (0x03 << 4) -# define RADEON_DISP_TRANS_MATRIX_ALPHA_MSB (0x00 << 4) -# define RADEON_DISP_TRANS_MATRIX_GRAPHICS (0x01 << 4) -# define RADEON_DISP_TRANS_MATRIX_VIDEO (0x02 << 4) -# define RADEON_DISP_TV_SOURCE_CRTC (1 << 16) /* crtc1 or crtc2 */ -# define RADEON_DISP_TV_SOURCE_LTU (0 << 16) /* linear transform unit */ -#define RADEON_DISP_TV_OUT_CNTL 0x0d6c -# define RADEON_DISP_TV_PATH_SRC_CRTC2 (1 << 16) -# define RADEON_DISP_TV_PATH_SRC_CRTC1 (0 << 16) -#define RADEON_DAC_CRC_SIG 0x02cc -#define RADEON_DAC_DATA 0x03c9 /* VGA */ -#define RADEON_DAC_MASK 0x03c6 /* VGA */ -#define RADEON_DAC_R_INDEX 0x03c7 /* VGA */ -#define RADEON_DAC_W_INDEX 0x03c8 /* VGA */ -#define RADEON_DDA_CONFIG 0x02e0 -#define RADEON_DDA_ON_OFF 0x02e4 -#define RADEON_DEFAULT_OFFSET 0x16e0 -#define RADEON_DEFAULT_PITCH 0x16e4 -#define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 -# define RADEON_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) -# define RADEON_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) -#define RADEON_DESTINATION_3D_CLR_CMP_VAL 0x1820 -#define RADEON_DESTINATION_3D_CLR_CMP_MSK 0x1824 -#define RADEON_DEVICE_ID 0x0f02 /* PCI */ -#define RADEON_DISP_MISC_CNTL 0x0d00 -# define RADEON_SOFT_RESET_GRPH_PP (1 << 0) -#define RADEON_DISP_MERGE_CNTL 0x0d60 -# define RADEON_DISP_ALPHA_MODE_MASK 0x03 -# define RADEON_DISP_ALPHA_MODE_KEY 0 -# define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1 -# define RADEON_DISP_ALPHA_MODE_GLOBAL 2 -# define RADEON_DISP_RGB_OFFSET_EN (1 << 8) -# define RADEON_DISP_GRPH_ALPHA_MASK (0xff << 16) -# define RADEON_DISP_OV0_ALPHA_MASK (0xff << 24) -# define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9) -#define RADEON_DISP2_MERGE_CNTL 0x0d68 -# define RADEON_DISP2_RGB_OFFSET_EN (1 << 8) -#define RADEON_DISP_LIN_TRANS_GRPH_A 0x0d80 -#define RADEON_DISP_LIN_TRANS_GRPH_B 0x0d84 -#define RADEON_DISP_LIN_TRANS_GRPH_C 0x0d88 -#define RADEON_DISP_LIN_TRANS_GRPH_D 0x0d8c -#define RADEON_DISP_LIN_TRANS_GRPH_E 0x0d90 -#define RADEON_DISP_LIN_TRANS_GRPH_F 0x0d98 -#define RADEON_DP_BRUSH_BKGD_CLR 0x1478 -#define RADEON_DP_BRUSH_FRGD_CLR 0x147c -#define RADEON_DP_CNTL 0x16c0 -# define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0) -# define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1) -# define RADEON_DP_DST_TILE_LINEAR (0 << 3) -# define RADEON_DP_DST_TILE_MACRO (1 << 3) -# define RADEON_DP_DST_TILE_MICRO (2 << 3) -# define RADEON_DP_DST_TILE_BOTH (3 << 3) -#define RADEON_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 -# define RADEON_DST_Y_MAJOR (1 << 2) -# define RADEON_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) -# define RADEON_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) -#define RADEON_DP_DATATYPE 0x16c4 -# define RADEON_HOST_BIG_ENDIAN_EN (1 << 29) -#define RADEON_DP_GUI_MASTER_CNTL 0x146c -# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) -# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) -# define RADEON_GMC_SRC_CLIPPING (1 << 2) -# define RADEON_GMC_DST_CLIPPING (1 << 3) -# define RADEON_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) -# define RADEON_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) -# define RADEON_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) -# define RADEON_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) -# define RADEON_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) -# define RADEON_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) -# define RADEON_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) -# define RADEON_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4) -# define RADEON_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4) -# define RADEON_GMC_BRUSH_8x8_COLOR (10 << 4) -# define RADEON_GMC_BRUSH_1X8_COLOR (12 << 4) -# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) -# define RADEON_GMC_BRUSH_NONE (15 << 4) -# define RADEON_GMC_DST_8BPP_CI (2 << 8) -# define RADEON_GMC_DST_15BPP (3 << 8) -# define RADEON_GMC_DST_16BPP (4 << 8) -# define RADEON_GMC_DST_24BPP (5 << 8) -# define RADEON_GMC_DST_32BPP (6 << 8) -# define RADEON_GMC_DST_8BPP_RGB (7 << 8) -# define RADEON_GMC_DST_Y8 (8 << 8) -# define RADEON_GMC_DST_RGB8 (9 << 8) -# define RADEON_GMC_DST_VYUY (11 << 8) -# define RADEON_GMC_DST_YVYU (12 << 8) -# define RADEON_GMC_DST_AYUV444 (14 << 8) -# define RADEON_GMC_DST_ARGB4444 (15 << 8) -# define RADEON_GMC_DST_DATATYPE_MASK (0x0f << 8) -# define RADEON_GMC_DST_DATATYPE_SHIFT 8 -# define RADEON_GMC_SRC_DATATYPE_MASK (3 << 12) -# define RADEON_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) -# define RADEON_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) -# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) -# define RADEON_GMC_BYTE_PIX_ORDER (1 << 14) -# define RADEON_GMC_BYTE_MSB_TO_LSB (0 << 14) -# define RADEON_GMC_BYTE_LSB_TO_MSB (1 << 14) -# define RADEON_GMC_CONVERSION_TEMP (1 << 15) -# define RADEON_GMC_CONVERSION_TEMP_6500 (0 << 15) -# define RADEON_GMC_CONVERSION_TEMP_9300 (1 << 15) -# define RADEON_GMC_ROP3_MASK (0xff << 16) -# define RADEON_DP_SRC_SOURCE_MASK (7 << 24) -# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) -# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) -# define RADEON_GMC_3D_FCN_EN (1 << 27) -# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) -# define RADEON_GMC_AUX_CLIP_DIS (1 << 29) -# define RADEON_GMC_WR_MSK_DIS (1 << 30) -# define RADEON_GMC_LD_BRUSH_Y_X (1 << 31) -# define RADEON_ROP3_ZERO 0x00000000 -# define RADEON_ROP3_DSa 0x00880000 -# define RADEON_ROP3_SDna 0x00440000 -# define RADEON_ROP3_S 0x00cc0000 -# define RADEON_ROP3_DSna 0x00220000 -# define RADEON_ROP3_D 0x00aa0000 -# define RADEON_ROP3_DSx 0x00660000 -# define RADEON_ROP3_DSo 0x00ee0000 -# define RADEON_ROP3_DSon 0x00110000 -# define RADEON_ROP3_DSxn 0x00990000 -# define RADEON_ROP3_Dn 0x00550000 -# define RADEON_ROP3_SDno 0x00dd0000 -# define RADEON_ROP3_Sn 0x00330000 -# define RADEON_ROP3_DSno 0x00bb0000 -# define RADEON_ROP3_DSan 0x00770000 -# define RADEON_ROP3_ONE 0x00ff0000 -# define RADEON_ROP3_DPa 0x00a00000 -# define RADEON_ROP3_PDna 0x00500000 -# define RADEON_ROP3_P 0x00f00000 -# define RADEON_ROP3_DPna 0x000a0000 -# define RADEON_ROP3_D 0x00aa0000 -# define RADEON_ROP3_DPx 0x005a0000 -# define RADEON_ROP3_DPo 0x00fa0000 -# define RADEON_ROP3_DPon 0x00050000 -# define RADEON_ROP3_PDxn 0x00a50000 -# define RADEON_ROP3_PDno 0x00f50000 -# define RADEON_ROP3_Pn 0x000f0000 -# define RADEON_ROP3_DPno 0x00af0000 -# define RADEON_ROP3_DPan 0x005f0000 -#define RADEON_DP_GUI_MASTER_CNTL_C 0x1c84 -#define RADEON_DP_MIX 0x16c8 -#define RADEON_DP_SRC_BKGD_CLR 0x15dc -#define RADEON_DP_SRC_FRGD_CLR 0x15d8 -#define RADEON_DP_WRITE_MASK 0x16cc -#define RADEON_DST_BRES_DEC 0x1630 -#define RADEON_DST_BRES_ERR 0x1628 -#define RADEON_DST_BRES_INC 0x162c -#define RADEON_DST_BRES_LNTH 0x1634 -#define RADEON_DST_BRES_LNTH_SUB 0x1638 -#define RADEON_DST_HEIGHT 0x1410 -#define RADEON_DST_HEIGHT_WIDTH 0x143c -#define RADEON_DST_HEIGHT_WIDTH_8 0x158c -#define RADEON_DST_HEIGHT_WIDTH_BW 0x15b4 -#define RADEON_DST_HEIGHT_Y 0x15a0 -#define RADEON_DST_LINE_START 0x1600 -#define RADEON_DST_LINE_END 0x1604 -#define RADEON_DST_LINE_PATCOUNT 0x1608 -# define RADEON_BRES_CNTL_SHIFT 8 -#define RADEON_DST_OFFSET 0x1404 -#define RADEON_DST_PITCH 0x1408 -#define RADEON_DST_PITCH_OFFSET 0x142c -#define RADEON_DST_PITCH_OFFSET_C 0x1c80 -# define RADEON_PITCH_SHIFT 21 -# define RADEON_DST_TILE_LINEAR (0 << 30) -# define RADEON_DST_TILE_MACRO (1 << 30) -# define RADEON_DST_TILE_MICRO (2 << 30) -# define RADEON_DST_TILE_BOTH (3 << 30) -#define RADEON_DST_WIDTH 0x140c -#define RADEON_DST_WIDTH_HEIGHT 0x1598 -#define RADEON_DST_WIDTH_X 0x1588 -#define RADEON_DST_WIDTH_X_INCY 0x159c -#define RADEON_DST_X 0x141c -#define RADEON_DST_X_SUB 0x15a4 -#define RADEON_DST_X_Y 0x1594 -#define RADEON_DST_Y 0x1420 -#define RADEON_DST_Y_SUB 0x15a8 -#define RADEON_DST_Y_X 0x1438 - -#define RADEON_FCP_CNTL 0x0910 -# define RADEON_FCP0_SRC_PCICLK 0 -# define RADEON_FCP0_SRC_PCLK 1 -# define RADEON_FCP0_SRC_PCLKb 2 -# define RADEON_FCP0_SRC_HREF 3 -# define RADEON_FCP0_SRC_GND 4 -# define RADEON_FCP0_SRC_HREFb 5 -#define RADEON_FLUSH_1 0x1704 -#define RADEON_FLUSH_2 0x1708 -#define RADEON_FLUSH_3 0x170c -#define RADEON_FLUSH_4 0x1710 -#define RADEON_FLUSH_5 0x1714 -#define RADEON_FLUSH_6 0x1718 -#define RADEON_FLUSH_7 0x171c -#define RADEON_FOG_3D_TABLE_START 0x1810 -#define RADEON_FOG_3D_TABLE_END 0x1814 -#define RADEON_FOG_3D_TABLE_DENSITY 0x181c -#define RADEON_FOG_TABLE_INDEX 0x1a14 -#define RADEON_FOG_TABLE_DATA 0x1a18 -#define RADEON_FP_CRTC_H_TOTAL_DISP 0x0250 -#define RADEON_FP_CRTC_V_TOTAL_DISP 0x0254 -# define RADEON_FP_CRTC_H_TOTAL_MASK 0x000003ff -# define RADEON_FP_CRTC_H_DISP_MASK 0x01ff0000 -# define RADEON_FP_CRTC_V_TOTAL_MASK 0x00000fff -# define RADEON_FP_CRTC_V_DISP_MASK 0x0fff0000 -# define RADEON_FP_H_SYNC_STRT_CHAR_MASK 0x00001ff8 -# define RADEON_FP_H_SYNC_WID_MASK 0x003f0000 -# define RADEON_FP_V_SYNC_STRT_MASK 0x00000fff -# define RADEON_FP_V_SYNC_WID_MASK 0x001f0000 -# define RADEON_FP_CRTC_H_TOTAL_SHIFT 0x00000000 -# define RADEON_FP_CRTC_H_DISP_SHIFT 0x00000010 -# define RADEON_FP_CRTC_V_TOTAL_SHIFT 0x00000000 -# define RADEON_FP_CRTC_V_DISP_SHIFT 0x00000010 -# define RADEON_FP_H_SYNC_STRT_CHAR_SHIFT 0x00000003 -# define RADEON_FP_H_SYNC_WID_SHIFT 0x00000010 -# define RADEON_FP_V_SYNC_STRT_SHIFT 0x00000000 -# define RADEON_FP_V_SYNC_WID_SHIFT 0x00000010 -#define RADEON_FP_GEN_CNTL 0x0284 -# define RADEON_FP_FPON (1 << 0) -# define RADEON_FP_BLANK_EN (1 << 1) -# define RADEON_FP_TMDS_EN (1 << 2) -# define RADEON_FP_PANEL_FORMAT (1 << 3) -# define RADEON_FP_EN_TMDS (1 << 7) -# define RADEON_FP_DETECT_SENSE (1 << 8) -# define RADEON_FP_DETECT_INT_POL (1 << 9) -# define R200_FP_SOURCE_SEL_MASK (3 << 10) -# define R200_FP_SOURCE_SEL_CRTC1 (0 << 10) -# define R200_FP_SOURCE_SEL_CRTC2 (1 << 10) -# define R200_FP_SOURCE_SEL_RMX (2 << 10) -# define R200_FP_SOURCE_SEL_TRANS (3 << 10) -# define RADEON_FP_SEL_CRTC1 (0 << 13) -# define RADEON_FP_SEL_CRTC2 (1 << 13) -# define R300_HPD_SEL(x) ((x) << 13) -# define RADEON_FP_CRTC_DONT_SHADOW_HPAR (1 << 15) -# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) -# define RADEON_FP_CRTC_DONT_SHADOW_HEND (1 << 17) -# define RADEON_FP_CRTC_USE_SHADOW_VEND (1 << 18) -# define RADEON_FP_RMX_HVSYNC_CONTROL_EN (1 << 20) -# define RADEON_FP_DFP_SYNC_SEL (1 << 21) -# define RADEON_FP_CRTC_LOCK_8DOT (1 << 22) -# define RADEON_FP_CRT_SYNC_SEL (1 << 23) -# define RADEON_FP_USE_SHADOW_EN (1 << 24) -# define RADEON_FP_CRT_SYNC_ALT (1 << 26) -#define RADEON_FP2_GEN_CNTL 0x0288 -# define RADEON_FP2_BLANK_EN (1 << 1) -# define RADEON_FP2_ON (1 << 2) -# define RADEON_FP2_PANEL_FORMAT (1 << 3) -# define RADEON_FP2_DETECT_SENSE (1 << 8) -# define RADEON_FP2_DETECT_INT_POL (1 << 9) -# define R200_FP2_SOURCE_SEL_MASK (3 << 10) -# define R200_FP2_SOURCE_SEL_CRTC1 (0 << 10) -# define R200_FP2_SOURCE_SEL_CRTC2 (1 << 10) -# define R200_FP2_SOURCE_SEL_RMX (2 << 10) -# define R200_FP2_SOURCE_SEL_TRANS_UNIT (3 << 10) -# define RADEON_FP2_SRC_SEL_MASK (3 << 13) -# define RADEON_FP2_SRC_SEL_CRTC2 (1 << 13) -# define RADEON_FP2_FP_POL (1 << 16) -# define RADEON_FP2_LP_POL (1 << 17) -# define RADEON_FP2_SCK_POL (1 << 18) -# define RADEON_FP2_LCD_CNTL_MASK (7 << 19) -# define RADEON_FP2_PAD_FLOP_EN (1 << 22) -# define RADEON_FP2_CRC_EN (1 << 23) -# define RADEON_FP2_CRC_READ_EN (1 << 24) -# define RADEON_FP2_DVO_EN (1 << 25) -# define RADEON_FP2_DVO_RATE_SEL_SDR (1 << 26) -# define R200_FP2_DVO_RATE_SEL_SDR (1 << 27) -# define R300_FP2_DVO_CLOCK_MODE_SINGLE (1 << 28) -# define R300_FP2_DVO_DUAL_CHANNEL_EN (1 << 29) -#define RADEON_FP_H_SYNC_STRT_WID 0x02c4 -#define RADEON_FP_H2_SYNC_STRT_WID 0x03c4 -#define RADEON_FP_HORZ_STRETCH 0x028c -#define RADEON_FP_HORZ2_STRETCH 0x038c -# define RADEON_HORZ_STRETCH_RATIO_MASK 0xffff -# define RADEON_HORZ_STRETCH_RATIO_MAX 4096 -# define RADEON_HORZ_PANEL_SIZE (0x1ff << 16) -# define RADEON_HORZ_PANEL_SHIFT 16 -# define RADEON_HORZ_STRETCH_PIXREP (0 << 25) -# define RADEON_HORZ_STRETCH_BLEND (1 << 26) -# define RADEON_HORZ_STRETCH_ENABLE (1 << 25) -# define RADEON_HORZ_AUTO_RATIO (1 << 27) -# define RADEON_HORZ_FP_LOOP_STRETCH (0x7 << 28) -# define RADEON_HORZ_AUTO_RATIO_INC (1 << 31) -#define RADEON_FP_HORZ_VERT_ACTIVE 0x0278 -#define RADEON_FP_V_SYNC_STRT_WID 0x02c8 -#define RADEON_FP_VERT_STRETCH 0x0290 -#define RADEON_FP_V2_SYNC_STRT_WID 0x03c8 -#define RADEON_FP_VERT2_STRETCH 0x0390 -# define RADEON_VERT_PANEL_SIZE (0xfff << 12) -# define RADEON_VERT_PANEL_SHIFT 12 -# define RADEON_VERT_STRETCH_RATIO_MASK 0xfff -# define RADEON_VERT_STRETCH_RATIO_SHIFT 0 -# define RADEON_VERT_STRETCH_RATIO_MAX 4096 -# define RADEON_VERT_STRETCH_ENABLE (1 << 25) -# define RADEON_VERT_STRETCH_LINEREP (0 << 26) -# define RADEON_VERT_STRETCH_BLEND (1 << 26) -# define RADEON_VERT_AUTO_RATIO_EN (1 << 27) -# define RADEON_VERT_AUTO_RATIO_INC (1 << 31) -# define RADEON_VERT_STRETCH_RESERVED 0x71000000 -#define RS400_FP_2ND_GEN_CNTL 0x0384 -# define RS400_FP_2ND_ON (1 << 0) -# define RS400_FP_2ND_BLANK_EN (1 << 1) -# define RS400_TMDS_2ND_EN (1 << 2) -# define RS400_PANEL_FORMAT_2ND (1 << 3) -# define RS400_FP_2ND_EN_TMDS (1 << 7) -# define RS400_FP_2ND_DETECT_SENSE (1 << 8) -# define RS400_FP_2ND_SOURCE_SEL_MASK (3 << 10) -# define RS400_FP_2ND_SOURCE_SEL_CRTC1 (0 << 10) -# define RS400_FP_2ND_SOURCE_SEL_CRTC2 (1 << 10) -# define RS400_FP_2ND_SOURCE_SEL_RMX (2 << 10) -# define RS400_FP_2ND_DETECT_EN (1 << 12) -# define RS400_HPD_2ND_SEL (1 << 13) -#define RS400_FP2_2_GEN_CNTL 0x0388 -# define RS400_FP2_2_BLANK_EN (1 << 1) -# define RS400_FP2_2_ON (1 << 2) -# define RS400_FP2_2_PANEL_FORMAT (1 << 3) -# define RS400_FP2_2_DETECT_SENSE (1 << 8) -# define RS400_FP2_2_SOURCE_SEL_MASK (3 << 10) -# define RS400_FP2_2_SOURCE_SEL_CRTC1 (0 << 10) -# define RS400_FP2_2_SOURCE_SEL_CRTC2 (1 << 10) -# define RS400_FP2_2_SOURCE_SEL_RMX (2 << 10) -# define RS400_FP2_2_DVO2_EN (1 << 25) -#define RS400_TMDS2_CNTL 0x0394 -#define RS400_TMDS2_TRANSMITTER_CNTL 0x03a4 -# define RS400_TMDS2_PLLEN (1 << 0) -# define RS400_TMDS2_PLLRST (1 << 1) - -#define RADEON_GEN_INT_CNTL 0x0040 -# define RADEON_CRTC_VBLANK_MASK (1 << 0) -# define RADEON_FP_DETECT_MASK (1 << 4) -# define RADEON_CRTC2_VBLANK_MASK (1 << 9) -# define RADEON_FP2_DETECT_MASK (1 << 10) -# define RADEON_GUI_IDLE_MASK (1 << 19) -# define RADEON_SW_INT_ENABLE (1 << 25) -#define RADEON_GEN_INT_STATUS 0x0044 -# define AVIVO_DISPLAY_INT_STATUS (1 << 0) -# define RADEON_CRTC_VBLANK_STAT (1 << 0) -# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0) -# define RADEON_FP_DETECT_STAT (1 << 4) -# define RADEON_FP_DETECT_STAT_ACK (1 << 4) -# define RADEON_CRTC2_VBLANK_STAT (1 << 9) -# define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) -# define RADEON_FP2_DETECT_STAT (1 << 10) -# define RADEON_FP2_DETECT_STAT_ACK (1 << 10) -# define RADEON_GUI_IDLE_STAT (1 << 19) -# define RADEON_GUI_IDLE_STAT_ACK (1 << 19) -# define RADEON_SW_INT_FIRE (1 << 26) -# define RADEON_SW_INT_TEST (1 << 25) -# define RADEON_SW_INT_TEST_ACK (1 << 25) -#define RADEON_GENENB 0x03c3 /* VGA */ -#define RADEON_GENFC_RD 0x03ca /* VGA */ -#define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ -#define RADEON_GENMO_RD 0x03cc /* VGA */ -#define RADEON_GENMO_WT 0x03c2 /* VGA */ -#define RADEON_GENS0 0x03c2 /* VGA */ -#define RADEON_GENS1 0x03da /* VGA, 0x03ba */ -#define RADEON_GPIO_MONID 0x0068 /* DDC interface via I2C */ /* DDC3 */ -#define RADEON_GPIO_MONIDB 0x006c -#define RADEON_GPIO_CRT2_DDC 0x006c -#define RADEON_GPIO_DVI_DDC 0x0064 /* DDC2 */ -#define RADEON_GPIO_VGA_DDC 0x0060 /* DDC1 */ -# define RADEON_GPIO_A_0 (1 << 0) -# define RADEON_GPIO_A_1 (1 << 1) -# define RADEON_GPIO_Y_0 (1 << 8) -# define RADEON_GPIO_Y_1 (1 << 9) -# define RADEON_GPIO_Y_SHIFT_0 8 -# define RADEON_GPIO_Y_SHIFT_1 9 -# define RADEON_GPIO_EN_0 (1 << 16) -# define RADEON_GPIO_EN_1 (1 << 17) -# define RADEON_GPIO_MASK_0 (1 << 24) /*??*/ -# define RADEON_GPIO_MASK_1 (1 << 25) /*??*/ -#define RADEON_GRPH8_DATA 0x03cf /* VGA */ -#define RADEON_GRPH8_IDX 0x03ce /* VGA */ -#define RADEON_GUI_SCRATCH_REG0 0x15e0 -#define RADEON_GUI_SCRATCH_REG1 0x15e4 -#define RADEON_GUI_SCRATCH_REG2 0x15e8 -#define RADEON_GUI_SCRATCH_REG3 0x15ec -#define RADEON_GUI_SCRATCH_REG4 0x15f0 -#define RADEON_GUI_SCRATCH_REG5 0x15f4 - -#define RADEON_HEADER 0x0f0e /* PCI */ -#define RADEON_HOST_DATA0 0x17c0 -#define RADEON_HOST_DATA1 0x17c4 -#define RADEON_HOST_DATA2 0x17c8 -#define RADEON_HOST_DATA3 0x17cc -#define RADEON_HOST_DATA4 0x17d0 -#define RADEON_HOST_DATA5 0x17d4 -#define RADEON_HOST_DATA6 0x17d8 -#define RADEON_HOST_DATA7 0x17dc -#define RADEON_HOST_DATA_LAST 0x17e0 -#define RADEON_HOST_PATH_CNTL 0x0130 -# define RADEON_HP_LIN_RD_CACHE_DIS (1 << 24) -# define RADEON_HDP_READ_BUFFER_INVALIDATE (1 << 27) -# define RADEON_HDP_SOFT_RESET (1 << 26) -# define RADEON_HDP_APER_CNTL (1 << 23) -#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */ -# define RADEON_HTOT_CNTL_VGA_EN (1 << 28) -#define RADEON_HTOTAL2_CNTL 0x002e /* PLL */ - - /* Multimedia I2C bus */ -#define RADEON_I2C_CNTL_0 0x0090 -# define RADEON_I2C_DONE (1 << 0) -# define RADEON_I2C_NACK (1 << 1) -# define RADEON_I2C_HALT (1 << 2) -# define RADEON_I2C_SOFT_RST (1 << 5) -# define RADEON_I2C_DRIVE_EN (1 << 6) -# define RADEON_I2C_DRIVE_SEL (1 << 7) -# define RADEON_I2C_START (1 << 8) -# define RADEON_I2C_STOP (1 << 9) -# define RADEON_I2C_RECEIVE (1 << 10) -# define RADEON_I2C_ABORT (1 << 11) -# define RADEON_I2C_GO (1 << 12) -# define RADEON_I2C_PRESCALE_SHIFT 16 -#define RADEON_I2C_CNTL_1 0x0094 -# define RADEON_I2C_DATA_COUNT_SHIFT 0 -# define RADEON_I2C_ADDR_COUNT_SHIFT 4 -# define RADEON_I2C_INTRA_BYTE_DELAY_SHIFT 8 -# define RADEON_I2C_SEL (1 << 16) -# define RADEON_I2C_EN (1 << 17) -# define RADEON_I2C_TIME_LIMIT_SHIFT 24 -#define RADEON_I2C_DATA 0x0098 - -#define RADEON_DVI_I2C_CNTL_0 0x02e0 -# define R200_DVI_I2C_PIN_SEL(x) ((x) << 3) -# define R200_SEL_DDC1 0 /* depends on asic */ -# define R200_SEL_DDC2 1 /* depends on asic */ -# define R200_SEL_DDC3 2 /* depends on asic */ -# define RADEON_SW_WANTS_TO_USE_DVI_I2C (1 << 13) -# define RADEON_SW_CAN_USE_DVI_I2C (1 << 13) -# define RADEON_SW_DONE_USING_DVI_I2C (1 << 14) -# define RADEON_HW_NEEDS_DVI_I2C (1 << 14) -# define RADEON_ABORT_HW_DVI_I2C (1 << 15) -# define RADEON_HW_USING_DVI_I2C (1 << 15) -#define RADEON_DVI_I2C_CNTL_1 0x02e4 -#define RADEON_DVI_I2C_DATA 0x02e8 - -#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ -#define RADEON_INTERRUPT_PIN 0x0f3d /* PCI */ -#define RADEON_IO_BASE 0x0f14 /* PCI */ - -#define RADEON_LATENCY 0x0f0d /* PCI */ -#define RADEON_LEAD_BRES_DEC 0x1608 -#define RADEON_LEAD_BRES_LNTH 0x161c -#define RADEON_LEAD_BRES_LNTH_SUB 0x1624 -#define RADEON_LVDS_GEN_CNTL 0x02d0 -# define RADEON_LVDS_ON (1 << 0) -# define RADEON_LVDS_DISPLAY_DIS (1 << 1) -# define RADEON_LVDS_PANEL_TYPE (1 << 2) -# define RADEON_LVDS_PANEL_FORMAT (1 << 3) -# define RADEON_LVDS_NO_FM (0 << 4) -# define RADEON_LVDS_2_GREY (1 << 4) -# define RADEON_LVDS_4_GREY (2 << 4) -# define RADEON_LVDS_RST_FM (1 << 6) -# define RADEON_LVDS_EN (1 << 7) -# define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8 -# define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8) -# define RADEON_LVDS_BL_MOD_EN (1 << 16) -# define RADEON_LVDS_BL_CLK_SEL (1 << 17) -# define RADEON_LVDS_DIGON (1 << 18) -# define RADEON_LVDS_BLON (1 << 19) -# define RADEON_LVDS_FP_POL_LOW (1 << 20) -# define RADEON_LVDS_LP_POL_LOW (1 << 21) -# define RADEON_LVDS_DTM_POL_LOW (1 << 22) -# define RADEON_LVDS_SEL_CRTC2 (1 << 23) -# define RADEON_LVDS_FPDI_EN (1 << 27) -# define RADEON_LVDS_HSYNC_DELAY_SHIFT 28 -#define RADEON_LVDS_PLL_CNTL 0x02d4 -# define RADEON_HSYNC_DELAY_SHIFT 28 -# define RADEON_HSYNC_DELAY_MASK (0xf << 28) -# define RADEON_LVDS_PLL_EN (1 << 16) -# define RADEON_LVDS_PLL_RESET (1 << 17) -# define R300_LVDS_SRC_SEL_MASK (3 << 18) -# define R300_LVDS_SRC_SEL_CRTC1 (0 << 18) -# define R300_LVDS_SRC_SEL_CRTC2 (1 << 18) -# define R300_LVDS_SRC_SEL_RMX (2 << 18) -#define RADEON_LVDS_SS_GEN_CNTL 0x02ec -# define RADEON_LVDS_PWRSEQ_DELAY1_SHIFT 16 -# define RADEON_LVDS_PWRSEQ_DELAY2_SHIFT 20 - -#define RADEON_MAX_LATENCY 0x0f3f /* PCI */ -#define RADEON_DISPLAY_BASE_ADDR 0x23c -#define RADEON_DISPLAY2_BASE_ADDR 0x33c -#define RADEON_OV0_BASE_ADDR 0x43c -#define RADEON_NB_TOM 0x15c -#define R300_MC_INIT_MISC_LAT_TIMER 0x180 -# define R300_MC_DISP0R_INIT_LAT_SHIFT 8 -# define R300_MC_DISP0R_INIT_LAT_MASK 0xf -# define R300_MC_DISP1R_INIT_LAT_SHIFT 12 -# define R300_MC_DISP1R_INIT_LAT_MASK 0xf -#define RADEON_MCLK_CNTL 0x0012 /* PLL */ -# define RADEON_MCLKA_SRC_SEL_MASK 0x7 -# define RADEON_FORCEON_MCLKA (1 << 16) -# define RADEON_FORCEON_MCLKB (1 << 17) -# define RADEON_FORCEON_YCLKA (1 << 18) -# define RADEON_FORCEON_YCLKB (1 << 19) -# define RADEON_FORCEON_MC (1 << 20) -# define RADEON_FORCEON_AIC (1 << 21) -# define R300_DISABLE_MC_MCLKA (1 << 21) -# define R300_DISABLE_MC_MCLKB (1 << 21) -#define RADEON_MCLK_MISC 0x001f /* PLL */ -# define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1 << 12) -# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13) -# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) -# define RADEON_IO_MCLK_DYN_ENABLE (1 << 15) - -#define RADEON_GPIOPAD_MASK 0x0198 -#define RADEON_GPIOPAD_A 0x019c -#define RADEON_GPIOPAD_EN 0x01a0 -#define RADEON_GPIOPAD_Y 0x01a4 -#define RADEON_MDGPIO_MASK 0x01a8 -#define RADEON_MDGPIO_A 0x01ac -#define RADEON_MDGPIO_EN 0x01b0 -#define RADEON_MDGPIO_Y 0x01b4 - -#define RADEON_MEM_ADDR_CONFIG 0x0148 -#define RADEON_MEM_BASE 0x0f10 /* PCI */ -#define RADEON_MEM_CNTL 0x0140 -# define RADEON_MEM_NUM_CHANNELS_MASK 0x01 -# define RADEON_MEM_USE_B_CH_ONLY (1 << 1) -# define RV100_HALF_MODE (1 << 3) -# define R300_MEM_NUM_CHANNELS_MASK 0x03 -# define R300_MEM_USE_CD_CH_ONLY (1 << 2) -#define RADEON_MEM_TIMING_CNTL 0x0144 /* EXT_MEM_CNTL */ -#define RADEON_MEM_INIT_LAT_TIMER 0x0154 -#define RADEON_MEM_INTF_CNTL 0x014c -#define RADEON_MEM_SDRAM_MODE_REG 0x0158 -# define RADEON_SDRAM_MODE_MASK 0xffff0000 -# define RADEON_B3MEM_RESET_MASK 0x6fffffff -# define RADEON_MEM_CFG_TYPE_DDR (1 << 30) -#define RADEON_MEM_STR_CNTL 0x0150 -# define RADEON_MEM_PWRUP_COMPL_A (1 << 0) -# define RADEON_MEM_PWRUP_COMPL_B (1 << 1) -# define R300_MEM_PWRUP_COMPL_C (1 << 2) -# define R300_MEM_PWRUP_COMPL_D (1 << 3) -# define RADEON_MEM_PWRUP_COMPLETE 0x03 -# define R300_MEM_PWRUP_COMPLETE 0x0f -#define RADEON_MC_STATUS 0x0150 -# define RADEON_MC_IDLE (1 << 2) -# define R300_MC_IDLE (1 << 4) -#define RADEON_MEM_VGA_RP_SEL 0x003c -#define RADEON_MEM_VGA_WP_SEL 0x0038 -#define RADEON_MIN_GRANT 0x0f3e /* PCI */ -#define RADEON_MM_DATA 0x0004 -#define RADEON_MM_INDEX 0x0000 -# define RADEON_MM_APER (1 << 31) -#define RADEON_MPLL_CNTL 0x000e /* PLL */ -#define RADEON_MPP_TB_CONFIG 0x01c0 /* ? */ -#define RADEON_MPP_GP_CONFIG 0x01c8 /* ? */ -#define RADEON_SEPROM_CNTL1 0x01c0 -# define RADEON_SCK_PRESCALE_SHIFT 24 -# define RADEON_SCK_PRESCALE_MASK (0xff << 24) -#define R300_MC_IND_INDEX 0x01f8 -# define R300_MC_IND_ADDR_MASK 0x3f -# define R300_MC_IND_WR_EN (1 << 8) -#define R300_MC_IND_DATA 0x01fc -#define R300_MC_READ_CNTL_AB 0x017c -# define R300_MEM_RBS_POSITION_A_MASK 0x03 -#define R300_MC_READ_CNTL_CD_mcind 0x24 -# define R300_MEM_RBS_POSITION_C_MASK 0x03 - -#define RADEON_N_VIF_COUNT 0x0248 - -#define RADEON_OV0_AUTO_FLIP_CNTL 0x0470 -# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_NUM 0x00000007 -# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_REPEAT_FIELD 0x00000008 -# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 0x00000010 -# define RADEON_OV0_AUTO_FLIP_CNTL_IGNORE_REPEAT_FIELD 0x00000020 -# define RADEON_OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE 0x00000040 -# define RADEON_OV0_AUTO_FLIP_CNTL_VID_PORT_SELECT 0x00000300 -# define RADEON_OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 0x00010000 -# define RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN 0x00040000 -# define RADEON_OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN 0x00080000 -# define RADEON_OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE 0x00800000 - -#define RADEON_OV0_COLOUR_CNTL 0x04E0 -#define RADEON_OV0_DEINTERLACE_PATTERN 0x0474 -#define RADEON_OV0_EXCLUSIVE_HORZ 0x0408 -# define RADEON_EXCL_HORZ_START_MASK 0x000000ff -# define RADEON_EXCL_HORZ_END_MASK 0x0000ff00 -# define RADEON_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 -# define RADEON_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 -#define RADEON_OV0_EXCLUSIVE_VERT 0x040C -# define RADEON_EXCL_VERT_START_MASK 0x000003ff -# define RADEON_EXCL_VERT_END_MASK 0x03ff0000 -#define RADEON_OV0_FILTER_CNTL 0x04A0 -# define RADEON_FILTER_PROGRAMMABLE_COEF 0x0 -# define RADEON_FILTER_HC_COEF_HORZ_Y 0x1 -# define RADEON_FILTER_HC_COEF_HORZ_UV 0x2 -# define RADEON_FILTER_HC_COEF_VERT_Y 0x4 -# define RADEON_FILTER_HC_COEF_VERT_UV 0x8 -# define RADEON_FILTER_HARDCODED_COEF 0xf -# define RADEON_FILTER_COEF_MASK 0xf - -#define RADEON_OV0_FOUR_TAP_COEF_0 0x04B0 -#define RADEON_OV0_FOUR_TAP_COEF_1 0x04B4 -#define RADEON_OV0_FOUR_TAP_COEF_2 0x04B8 -#define RADEON_OV0_FOUR_TAP_COEF_3 0x04BC -#define RADEON_OV0_FOUR_TAP_COEF_4 0x04C0 -#define RADEON_OV0_FLAG_CNTL 0x04DC -#define RADEON_OV0_GAMMA_000_00F 0x0d40 -#define RADEON_OV0_GAMMA_010_01F 0x0d44 -#define RADEON_OV0_GAMMA_020_03F 0x0d48 -#define RADEON_OV0_GAMMA_040_07F 0x0d4c -#define RADEON_OV0_GAMMA_080_0BF 0x0e00 -#define RADEON_OV0_GAMMA_0C0_0FF 0x0e04 -#define RADEON_OV0_GAMMA_100_13F 0x0e08 -#define RADEON_OV0_GAMMA_140_17F 0x0e0c -#define RADEON_OV0_GAMMA_180_1BF 0x0e10 -#define RADEON_OV0_GAMMA_1C0_1FF 0x0e14 -#define RADEON_OV0_GAMMA_200_23F 0x0e18 -#define RADEON_OV0_GAMMA_240_27F 0x0e1c -#define RADEON_OV0_GAMMA_280_2BF 0x0e20 -#define RADEON_OV0_GAMMA_2C0_2FF 0x0e24 -#define RADEON_OV0_GAMMA_300_33F 0x0e28 -#define RADEON_OV0_GAMMA_340_37F 0x0e2c -#define RADEON_OV0_GAMMA_380_3BF 0x0d50 -#define RADEON_OV0_GAMMA_3C0_3FF 0x0d54 -#define RADEON_OV0_GRAPHICS_KEY_CLR_LOW 0x04EC -#define RADEON_OV0_GRAPHICS_KEY_CLR_HIGH 0x04F0 -#define RADEON_OV0_H_INC 0x0480 -#define RADEON_OV0_KEY_CNTL 0x04F4 -# define RADEON_VIDEO_KEY_FN_MASK 0x00000003L -# define RADEON_VIDEO_KEY_FN_FALSE 0x00000000L -# define RADEON_VIDEO_KEY_FN_TRUE 0x00000001L -# define RADEON_VIDEO_KEY_FN_EQ 0x00000002L -# define RADEON_VIDEO_KEY_FN_NE 0x00000003L -# define RADEON_GRAPHIC_KEY_FN_MASK 0x00000030L -# define RADEON_GRAPHIC_KEY_FN_FALSE 0x00000000L -# define RADEON_GRAPHIC_KEY_FN_TRUE 0x00000010L -# define RADEON_GRAPHIC_KEY_FN_EQ 0x00000020L -# define RADEON_GRAPHIC_KEY_FN_NE 0x00000030L -# define RADEON_CMP_MIX_MASK 0x00000100L -# define RADEON_CMP_MIX_OR 0x00000000L -# define RADEON_CMP_MIX_AND 0x00000100L -#define RADEON_OV0_LIN_TRANS_A 0x0d20 -#define RADEON_OV0_LIN_TRANS_B 0x0d24 -#define RADEON_OV0_LIN_TRANS_C 0x0d28 -#define RADEON_OV0_LIN_TRANS_D 0x0d2c -#define RADEON_OV0_LIN_TRANS_E 0x0d30 -#define RADEON_OV0_LIN_TRANS_F 0x0d34 -#define RADEON_OV0_P1_BLANK_LINES_AT_TOP 0x0430 -# define RADEON_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL -# define RADEON_P1_ACTIVE_LINES_M1 0x0fff0000L -#define RADEON_OV0_P1_H_ACCUM_INIT 0x0488 -#define RADEON_OV0_P1_V_ACCUM_INIT 0x0428 -# define RADEON_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L -# define RADEON_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L -#define RADEON_OV0_P1_X_START_END 0x0494 -#define RADEON_OV0_P2_X_START_END 0x0498 -#define RADEON_OV0_P23_BLANK_LINES_AT_TOP 0x0434 -# define RADEON_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL -# define RADEON_P23_ACTIVE_LINES_M1 0x07ff0000L -#define RADEON_OV0_P23_H_ACCUM_INIT 0x048C -#define RADEON_OV0_P23_V_ACCUM_INIT 0x042C -#define RADEON_OV0_P3_X_START_END 0x049C -#define RADEON_OV0_REG_LOAD_CNTL 0x0410 -# define RADEON_REG_LD_CTL_LOCK 0x00000001L -# define RADEON_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L -# define RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L -# define RADEON_REG_LD_CTL_LOCK_READBACK 0x00000008L -# define RADEON_REG_LD_CTL_FLIP_READBACK 0x00000010L -#define RADEON_OV0_SCALE_CNTL 0x0420 -# define RADEON_SCALER_HORZ_PICK_NEAREST 0x00000004L -# define RADEON_SCALER_VERT_PICK_NEAREST 0x00000008L -# define RADEON_SCALER_SIGNED_UV 0x00000010L -# define RADEON_SCALER_GAMMA_SEL_MASK 0x00000060L -# define RADEON_SCALER_GAMMA_SEL_BRIGHT 0x00000000L -# define RADEON_SCALER_GAMMA_SEL_G22 0x00000020L -# define RADEON_SCALER_GAMMA_SEL_G18 0x00000040L -# define RADEON_SCALER_GAMMA_SEL_G14 0x00000060L -# define RADEON_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L -# define RADEON_SCALER_SURFAC_FORMAT 0x00000f00L -# define RADEON_SCALER_SOURCE_15BPP 0x00000300L -# define RADEON_SCALER_SOURCE_16BPP 0x00000400L -# define RADEON_SCALER_SOURCE_32BPP 0x00000600L -# define RADEON_SCALER_SOURCE_YUV9 0x00000900L -# define RADEON_SCALER_SOURCE_YUV12 0x00000A00L -# define RADEON_SCALER_SOURCE_VYUY422 0x00000B00L -# define RADEON_SCALER_SOURCE_YVYU422 0x00000C00L -# define RADEON_SCALER_ADAPTIVE_DEINT 0x00001000L -# define RADEON_SCALER_TEMPORAL_DEINT 0x00002000L -# define RADEON_SCALER_CRTC_SEL 0x00004000L -# define RADEON_SCALER_SMART_SWITCH 0x00008000L -# define RADEON_SCALER_BURST_PER_PLANE 0x007F0000L -# define RADEON_SCALER_DOUBLE_BUFFER 0x01000000L -# define RADEON_SCALER_DIS_LIMIT 0x08000000L -# define RADEON_SCALER_LIN_TRANS_BYPASS 0x10000000L -# define RADEON_SCALER_INT_EMU 0x20000000L -# define RADEON_SCALER_ENABLE 0x40000000L -# define RADEON_SCALER_SOFT_RESET 0x80000000L -#define RADEON_OV0_STEP_BY 0x0484 -#define RADEON_OV0_TEST 0x04F8 -#define RADEON_OV0_V_INC 0x0424 -#define RADEON_OV0_VID_BUF_PITCH0_VALUE 0x0460 -#define RADEON_OV0_VID_BUF_PITCH1_VALUE 0x0464 -#define RADEON_OV0_VID_BUF0_BASE_ADRS 0x0440 -# define RADEON_VIF_BUF0_PITCH_SEL 0x00000001L -# define RADEON_VIF_BUF0_TILE_ADRS 0x00000002L -# define RADEON_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L -# define RADEON_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L -#define RADEON_OV0_VID_BUF1_BASE_ADRS 0x0444 -# define RADEON_VIF_BUF1_PITCH_SEL 0x00000001L -# define RADEON_VIF_BUF1_TILE_ADRS 0x00000002L -# define RADEON_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L -# define RADEON_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L -#define RADEON_OV0_VID_BUF2_BASE_ADRS 0x0448 -# define RADEON_VIF_BUF2_PITCH_SEL 0x00000001L -# define RADEON_VIF_BUF2_TILE_ADRS 0x00000002L -# define RADEON_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L -# define RADEON_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L -#define RADEON_OV0_VID_BUF3_BASE_ADRS 0x044C -#define RADEON_OV0_VID_BUF4_BASE_ADRS 0x0450 -#define RADEON_OV0_VID_BUF5_BASE_ADRS 0x0454 -#define RADEON_OV0_VIDEO_KEY_CLR_HIGH 0x04E8 -#define RADEON_OV0_VIDEO_KEY_CLR_LOW 0x04E4 -#define RADEON_OV0_Y_X_START 0x0400 -#define RADEON_OV0_Y_X_END 0x0404 -#define RADEON_OV1_Y_X_START 0x0600 -#define RADEON_OV1_Y_X_END 0x0604 -#define RADEON_OVR_CLR 0x0230 -#define RADEON_OVR_WID_LEFT_RIGHT 0x0234 -#define RADEON_OVR_WID_TOP_BOTTOM 0x0238 -#define RADEON_OVR2_CLR 0x0330 -#define RADEON_OVR2_WID_LEFT_RIGHT 0x0334 -#define RADEON_OVR2_WID_TOP_BOTTOM 0x0338 - -/* first capture unit */ - -#define RADEON_CAP0_BUF0_OFFSET 0x0920 -#define RADEON_CAP0_BUF1_OFFSET 0x0924 -#define RADEON_CAP0_BUF0_EVEN_OFFSET 0x0928 -#define RADEON_CAP0_BUF1_EVEN_OFFSET 0x092C - -#define RADEON_CAP0_BUF_PITCH 0x0930 -#define RADEON_CAP0_V_WINDOW 0x0934 -#define RADEON_CAP0_H_WINDOW 0x0938 -#define RADEON_CAP0_VBI0_OFFSET 0x093C -#define RADEON_CAP0_VBI1_OFFSET 0x0940 -#define RADEON_CAP0_VBI_V_WINDOW 0x0944 -#define RADEON_CAP0_VBI_H_WINDOW 0x0948 -#define RADEON_CAP0_PORT_MODE_CNTL 0x094C -#define RADEON_CAP0_TRIG_CNTL 0x0950 -#define RADEON_CAP0_DEBUG 0x0954 -#define RADEON_CAP0_CONFIG 0x0958 -# define RADEON_CAP0_CONFIG_CONTINUOS 0x00000001 -# define RADEON_CAP0_CONFIG_START_FIELD_EVEN 0x00000002 -# define RADEON_CAP0_CONFIG_START_BUF_GET 0x00000004 -# define RADEON_CAP0_CONFIG_START_BUF_SET 0x00000008 -# define RADEON_CAP0_CONFIG_BUF_TYPE_ALT 0x00000010 -# define RADEON_CAP0_CONFIG_BUF_TYPE_FRAME 0x00000020 -# define RADEON_CAP0_CONFIG_ONESHOT_MODE_FRAME 0x00000040 -# define RADEON_CAP0_CONFIG_BUF_MODE_DOUBLE 0x00000080 -# define RADEON_CAP0_CONFIG_BUF_MODE_TRIPLE 0x00000100 -# define RADEON_CAP0_CONFIG_MIRROR_EN 0x00000200 -# define RADEON_CAP0_CONFIG_ONESHOT_MIRROR_EN 0x00000400 -# define RADEON_CAP0_CONFIG_VIDEO_SIGNED_UV 0x00000800 -# define RADEON_CAP0_CONFIG_ANC_DECODE_EN 0x00001000 -# define RADEON_CAP0_CONFIG_VBI_EN 0x00002000 -# define RADEON_CAP0_CONFIG_SOFT_PULL_DOWN_EN 0x00004000 -# define RADEON_CAP0_CONFIG_VIP_EXTEND_FLAG_EN 0x00008000 -# define RADEON_CAP0_CONFIG_FAKE_FIELD_EN 0x00010000 -# define RADEON_CAP0_CONFIG_ODD_ONE_MORE_LINE 0x00020000 -# define RADEON_CAP0_CONFIG_EVEN_ONE_MORE_LINE 0x00040000 -# define RADEON_CAP0_CONFIG_HORZ_DIVIDE_2 0x00080000 -# define RADEON_CAP0_CONFIG_HORZ_DIVIDE_4 0x00100000 -# define RADEON_CAP0_CONFIG_VERT_DIVIDE_2 0x00200000 -# define RADEON_CAP0_CONFIG_VERT_DIVIDE_4 0x00400000 -# define RADEON_CAP0_CONFIG_FORMAT_BROOKTREE 0x00000000 -# define RADEON_CAP0_CONFIG_FORMAT_CCIR656 0x00800000 -# define RADEON_CAP0_CONFIG_FORMAT_ZV 0x01000000 -# define RADEON_CAP0_CONFIG_FORMAT_VIP 0x01800000 -# define RADEON_CAP0_CONFIG_FORMAT_TRANSPORT 0x02000000 -# define RADEON_CAP0_CONFIG_HORZ_DECIMATOR 0x04000000 -# define RADEON_CAP0_CONFIG_VIDEO_IN_YVYU422 0x00000000 -# define RADEON_CAP0_CONFIG_VIDEO_IN_VYUY422 0x20000000 -# define RADEON_CAP0_CONFIG_VBI_DIVIDE_2 0x40000000 -# define RADEON_CAP0_CONFIG_VBI_DIVIDE_4 0x80000000 -#define RADEON_CAP0_ANC_ODD_OFFSET 0x095C -#define RADEON_CAP0_ANC_EVEN_OFFSET 0x0960 -#define RADEON_CAP0_ANC_H_WINDOW 0x0964 -#define RADEON_CAP0_VIDEO_SYNC_TEST 0x0968 -#define RADEON_CAP0_ONESHOT_BUF_OFFSET 0x096C -#define RADEON_CAP0_BUF_STATUS 0x0970 -/* #define RADEON_CAP0_DWNSC_XRATIO 0x0978 */ -/* #define RADEON_CAP0_XSHARPNESS 0x097C */ -#define RADEON_CAP0_VBI2_OFFSET 0x0980 -#define RADEON_CAP0_VBI3_OFFSET 0x0984 -#define RADEON_CAP0_ANC2_OFFSET 0x0988 -#define RADEON_CAP0_ANC3_OFFSET 0x098C -#define RADEON_VID_BUFFER_CONTROL 0x0900 - -/* second capture unit */ - -#define RADEON_CAP1_BUF0_OFFSET 0x0990 -#define RADEON_CAP1_BUF1_OFFSET 0x0994 -#define RADEON_CAP1_BUF0_EVEN_OFFSET 0x0998 -#define RADEON_CAP1_BUF1_EVEN_OFFSET 0x099C - -#define RADEON_CAP1_BUF_PITCH 0x09A0 -#define RADEON_CAP1_V_WINDOW 0x09A4 -#define RADEON_CAP1_H_WINDOW 0x09A8 -#define RADEON_CAP1_VBI_ODD_OFFSET 0x09AC -#define RADEON_CAP1_VBI_EVEN_OFFSET 0x09B0 -#define RADEON_CAP1_VBI_V_WINDOW 0x09B4 -#define RADEON_CAP1_VBI_H_WINDOW 0x09B8 -#define RADEON_CAP1_PORT_MODE_CNTL 0x09BC -#define RADEON_CAP1_TRIG_CNTL 0x09C0 -#define RADEON_CAP1_DEBUG 0x09C4 -#define RADEON_CAP1_CONFIG 0x09C8 -#define RADEON_CAP1_ANC_ODD_OFFSET 0x09CC -#define RADEON_CAP1_ANC_EVEN_OFFSET 0x09D0 -#define RADEON_CAP1_ANC_H_WINDOW 0x09D4 -#define RADEON_CAP1_VIDEO_SYNC_TEST 0x09D8 -#define RADEON_CAP1_ONESHOT_BUF_OFFSET 0x09DC -#define RADEON_CAP1_BUF_STATUS 0x09E0 -#define RADEON_CAP1_DWNSC_XRATIO 0x09E8 -#define RADEON_CAP1_XSHARPNESS 0x09EC - -/* misc multimedia registers */ - -#define RADEON_IDCT_RUNS 0x1F80 -#define RADEON_IDCT_LEVELS 0x1F84 -#define RADEON_IDCT_CONTROL 0x1FBC -#define RADEON_IDCT_AUTH_CONTROL 0x1F88 -#define RADEON_IDCT_AUTH 0x1F8C - -#define RADEON_P2PLL_CNTL 0x002a /* P2PLL */ -# define RADEON_P2PLL_RESET (1 << 0) -# define RADEON_P2PLL_SLEEP (1 << 1) -# define RADEON_P2PLL_PVG_MASK (7 << 11) -# define RADEON_P2PLL_PVG_SHIFT 11 -# define RADEON_P2PLL_ATOMIC_UPDATE_EN (1 << 16) -# define RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17) -# define RADEON_P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18) -#define RADEON_P2PLL_DIV_0 0x002c -# define RADEON_P2PLL_FB0_DIV_MASK 0x07ff -# define RADEON_P2PLL_POST0_DIV_MASK 0x00070000 -#define RADEON_P2PLL_REF_DIV 0x002B /* PLL */ -# define RADEON_P2PLL_REF_DIV_MASK 0x03ff -# define RADEON_P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ -# define RADEON_P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ -# define R300_PPLL_REF_DIV_ACC_MASK (0x3ff << 18) -# define R300_PPLL_REF_DIV_ACC_SHIFT 18 -#define RADEON_PALETTE_DATA 0x00b4 -#define RADEON_PALETTE_30_DATA 0x00b8 -#define RADEON_PALETTE_INDEX 0x00b0 -#define RADEON_PCI_GART_PAGE 0x017c -#define RADEON_PIXCLKS_CNTL 0x002d -# define RADEON_PIX2CLK_SRC_SEL_MASK 0x03 -# define RADEON_PIX2CLK_SRC_SEL_CPUCLK 0x00 -# define RADEON_PIX2CLK_SRC_SEL_PSCANCLK 0x01 -# define RADEON_PIX2CLK_SRC_SEL_BYTECLK 0x02 -# define RADEON_PIX2CLK_SRC_SEL_P2PLLCLK 0x03 -# define RADEON_PIX2CLK_ALWAYS_ONb (1<<6) -# define RADEON_PIX2CLK_DAC_ALWAYS_ONb (1<<7) -# define RADEON_PIXCLK_TV_SRC_SEL (1 << 8) -# define RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb (1 << 9) -# define R300_DVOCLK_ALWAYS_ONb (1 << 10) -# define RADEON_PIXCLK_BLEND_ALWAYS_ONb (1 << 11) -# define RADEON_PIXCLK_GV_ALWAYS_ONb (1 << 12) -# define RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb (1 << 13) -# define R300_PIXCLK_DVO_ALWAYS_ONb (1 << 13) -# define RADEON_PIXCLK_LVDS_ALWAYS_ONb (1 << 14) -# define RADEON_PIXCLK_TMDS_ALWAYS_ONb (1 << 15) -# define R300_PIXCLK_TRANS_ALWAYS_ONb (1 << 16) -# define R300_PIXCLK_TVO_ALWAYS_ONb (1 << 17) -# define R300_P2G2CLK_ALWAYS_ONb (1 << 18) -# define R300_P2G2CLK_DAC_ALWAYS_ONb (1 << 19) -# define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23) -#define RADEON_PLANE_3D_MASK_C 0x1d44 -#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */ -# define RADEON_PLL_MASK_READ_B (1 << 9) -#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */ -#define RADEON_PMI_DATA 0x0f63 /* PCI */ -#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ -#define RADEON_PMI_PMC_REG 0x0f5e /* PCI */ -#define RADEON_PMI_PMCSR_REG 0x0f60 /* PCI */ -#define RADEON_PMI_REGISTER 0x0f5c /* PCI */ -#define RADEON_PPLL_CNTL 0x0002 /* PLL */ -# define RADEON_PPLL_RESET (1 << 0) -# define RADEON_PPLL_SLEEP (1 << 1) -# define RADEON_PPLL_PVG_MASK (7 << 11) -# define RADEON_PPLL_PVG_SHIFT 11 -# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16) -# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) -# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) -#define RADEON_PPLL_DIV_0 0x0004 /* PLL */ -#define RADEON_PPLL_DIV_1 0x0005 /* PLL */ -#define RADEON_PPLL_DIV_2 0x0006 /* PLL */ -#define RADEON_PPLL_DIV_3 0x0007 /* PLL */ -# define RADEON_PPLL_FB3_DIV_MASK 0x07ff -# define RADEON_PPLL_POST3_DIV_MASK 0x00070000 -#define RADEON_PPLL_REF_DIV 0x0003 /* PLL */ -# define RADEON_PPLL_REF_DIV_MASK 0x03ff -# define RADEON_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ -# define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ -#define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ - -#define RADEON_RBBM_GUICNTL 0x172c -# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) -# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) -# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) -# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) -#define RADEON_RBBM_SOFT_RESET 0x00f0 -# define RADEON_SOFT_RESET_CP (1 << 0) -# define RADEON_SOFT_RESET_HI (1 << 1) -# define RADEON_SOFT_RESET_SE (1 << 2) -# define RADEON_SOFT_RESET_RE (1 << 3) -# define RADEON_SOFT_RESET_PP (1 << 4) -# define RADEON_SOFT_RESET_E2 (1 << 5) -# define RADEON_SOFT_RESET_RB (1 << 6) -# define RADEON_SOFT_RESET_HDP (1 << 7) -#define RADEON_RBBM_STATUS 0x0e40 -# define RADEON_RBBM_FIFOCNT_MASK 0x007f -# define RADEON_RBBM_ACTIVE (1 << 31) -#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c -# define RADEON_RB2D_DC_FLUSH (3 << 0) -# define RADEON_RB2D_DC_FREE (3 << 2) -# define RADEON_RB2D_DC_FLUSH_ALL 0xf -# define RADEON_RB2D_DC_BUSY (1 << 31) -#define RADEON_RB2D_DSTCACHE_MODE 0x3428 -#define RADEON_DSTCACHE_CTLSTAT 0x1714 - -#define RADEON_RB3D_ZCACHE_MODE 0x3250 -#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254 -# define RADEON_RB3D_ZC_FLUSH_ALL 0x5 -#define RADEON_RB3D_DSTCACHE_MODE 0x3258 -# define RADEON_RB3D_DC_CACHE_ENABLE (0) -# define RADEON_RB3D_DC_2D_CACHE_DISABLE (1) -# define RADEON_RB3D_DC_3D_CACHE_DISABLE (2) -# define RADEON_RB3D_DC_CACHE_DISABLE (3) -# define RADEON_RB3D_DC_2D_CACHE_LINESIZE_128 (1 << 2) -# define RADEON_RB3D_DC_3D_CACHE_LINESIZE_128 (2 << 2) -# define RADEON_RB3D_DC_2D_CACHE_AUTOFLUSH (1 << 8) -# define RADEON_RB3D_DC_3D_CACHE_AUTOFLUSH (2 << 8) -# define R200_RB3D_DC_2D_CACHE_AUTOFREE (1 << 10) -# define R200_RB3D_DC_3D_CACHE_AUTOFREE (2 << 10) -# define RADEON_RB3D_DC_FORCE_RMW (1 << 16) -# define RADEON_RB3D_DC_DISABLE_RI_FILL (1 << 24) -# define RADEON_RB3D_DC_DISABLE_RI_READ (1 << 25) - -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325C -# define RADEON_RB3D_DC_FLUSH (3 << 0) -# define RADEON_RB3D_DC_FREE (3 << 2) -# define RADEON_RB3D_DC_FLUSH_ALL 0xf -# define RADEON_RB3D_DC_BUSY (1 << 31) - -#define RADEON_REG_BASE 0x0f18 /* PCI */ -#define RADEON_REGPROG_INF 0x0f09 /* PCI */ -#define RADEON_REVISION_ID 0x0f08 /* PCI */ - -#define RADEON_SC_BOTTOM 0x164c -#define RADEON_SC_BOTTOM_RIGHT 0x16f0 -#define RADEON_SC_BOTTOM_RIGHT_C 0x1c8c -#define RADEON_SC_LEFT 0x1640 -#define RADEON_SC_RIGHT 0x1644 -#define RADEON_SC_TOP 0x1648 -#define RADEON_SC_TOP_LEFT 0x16ec -#define RADEON_SC_TOP_LEFT_C 0x1c88 -# define RADEON_SC_SIGN_MASK_LO 0x8000 -# define RADEON_SC_SIGN_MASK_HI 0x80000000 -#define RADEON_M_SPLL_REF_FB_DIV 0x000a /* PLL */ -# define RADEON_M_SPLL_REF_DIV_SHIFT 0 -# define RADEON_M_SPLL_REF_DIV_MASK 0xff -# define RADEON_MPLL_FB_DIV_SHIFT 8 -# define RADEON_MPLL_FB_DIV_MASK 0xff -# define RADEON_SPLL_FB_DIV_SHIFT 16 -# define RADEON_SPLL_FB_DIV_MASK 0xff -#define RADEON_SPLL_CNTL 0x000c /* PLL */ -# define RADEON_SPLL_SLEEP (1 << 0) -# define RADEON_SPLL_RESET (1 << 1) -# define RADEON_SPLL_PCP_MASK 0x7 -# define RADEON_SPLL_PCP_SHIFT 8 -# define RADEON_SPLL_PVG_MASK 0x7 -# define RADEON_SPLL_PVG_SHIFT 11 -# define RADEON_SPLL_PDC_MASK 0x3 -# define RADEON_SPLL_PDC_SHIFT 14 -#define RADEON_SCLK_CNTL 0x000d /* PLL */ -# define RADEON_SCLK_SRC_SEL_MASK 0x0007 -# define RADEON_DYN_STOP_LAT_MASK 0x00007ff8 -# define RADEON_CP_MAX_DYN_STOP_LAT 0x0008 -# define RADEON_SCLK_FORCEON_MASK 0xffff8000 -# define RADEON_SCLK_FORCE_DISP2 (1<<15) -# define RADEON_SCLK_FORCE_CP (1<<16) -# define RADEON_SCLK_FORCE_HDP (1<<17) -# define RADEON_SCLK_FORCE_DISP1 (1<<18) -# define RADEON_SCLK_FORCE_TOP (1<<19) -# define RADEON_SCLK_FORCE_E2 (1<<20) -# define RADEON_SCLK_FORCE_SE (1<<21) -# define RADEON_SCLK_FORCE_IDCT (1<<22) -# define RADEON_SCLK_FORCE_VIP (1<<23) -# define RADEON_SCLK_FORCE_RE (1<<24) -# define RADEON_SCLK_FORCE_PB (1<<25) -# define RADEON_SCLK_FORCE_TAM (1<<26) -# define RADEON_SCLK_FORCE_TDM (1<<27) -# define RADEON_SCLK_FORCE_RB (1<<28) -# define RADEON_SCLK_FORCE_TV_SCLK (1<<29) -# define RADEON_SCLK_FORCE_SUBPIC (1<<30) -# define RADEON_SCLK_FORCE_OV0 (1<<31) -# define R300_SCLK_FORCE_VAP (1<<21) -# define R300_SCLK_FORCE_SR (1<<25) -# define R300_SCLK_FORCE_PX (1<<26) -# define R300_SCLK_FORCE_TX (1<<27) -# define R300_SCLK_FORCE_US (1<<28) -# define R300_SCLK_FORCE_SU (1<<30) -#define R300_SCLK_CNTL2 0x1e /* PLL */ -# define R300_SCLK_TCL_MAX_DYN_STOP_LAT (1<<10) -# define R300_SCLK_GA_MAX_DYN_STOP_LAT (1<<11) -# define R300_SCLK_CBA_MAX_DYN_STOP_LAT (1<<12) -# define R300_SCLK_FORCE_TCL (1<<13) -# define R300_SCLK_FORCE_CBA (1<<14) -# define R300_SCLK_FORCE_GA (1<<15) -#define RADEON_SCLK_MORE_CNTL 0x0035 /* PLL */ -# define RADEON_SCLK_MORE_MAX_DYN_STOP_LAT 0x0007 -# define RADEON_SCLK_MORE_FORCEON 0x0700 -#define RADEON_SDRAM_MODE_REG 0x0158 -#define RADEON_SEQ8_DATA 0x03c5 /* VGA */ -#define RADEON_SEQ8_IDX 0x03c4 /* VGA */ -#define RADEON_SNAPSHOT_F_COUNT 0x0244 -#define RADEON_SNAPSHOT_VH_COUNTS 0x0240 -#define RADEON_SNAPSHOT_VIF_COUNT 0x024c -#define RADEON_SRC_OFFSET 0x15ac -#define RADEON_SRC_PITCH 0x15b0 -#define RADEON_SRC_PITCH_OFFSET 0x1428 -#define RADEON_SRC_SC_BOTTOM 0x165c -#define RADEON_SRC_SC_BOTTOM_RIGHT 0x16f4 -#define RADEON_SRC_SC_RIGHT 0x1654 -#define RADEON_SRC_X 0x1414 -#define RADEON_SRC_X_Y 0x1590 -#define RADEON_SRC_Y 0x1418 -#define RADEON_SRC_Y_X 0x1434 -#define RADEON_STATUS 0x0f06 /* PCI */ -#define RADEON_SUBPIC_CNTL 0x0540 /* ? */ -#define RADEON_SUB_CLASS 0x0f0a /* PCI */ -#define RADEON_SURFACE_CNTL 0x0b00 -# define RADEON_SURF_TRANSLATION_DIS (1 << 8) -# define RADEON_NONSURF_AP0_SWP_16BPP (1 << 20) -# define RADEON_NONSURF_AP0_SWP_32BPP (1 << 21) -# define RADEON_NONSURF_AP1_SWP_16BPP (1 << 22) -# define RADEON_NONSURF_AP1_SWP_32BPP (1 << 23) -#define RADEON_SURFACE0_INFO 0x0b0c -# define RADEON_SURF_TILE_COLOR_MACRO (0 << 16) -# define RADEON_SURF_TILE_COLOR_BOTH (1 << 16) -# define RADEON_SURF_TILE_DEPTH_32BPP (2 << 16) -# define RADEON_SURF_TILE_DEPTH_16BPP (3 << 16) -# define R200_SURF_TILE_NONE (0 << 16) -# define R200_SURF_TILE_COLOR_MACRO (1 << 16) -# define R200_SURF_TILE_COLOR_MICRO (2 << 16) -# define R200_SURF_TILE_COLOR_BOTH (3 << 16) -# define R200_SURF_TILE_DEPTH_32BPP (4 << 16) -# define R200_SURF_TILE_DEPTH_16BPP (5 << 16) -# define R300_SURF_TILE_NONE (0 << 16) -# define R300_SURF_TILE_COLOR_MACRO (1 << 16) -# define R300_SURF_TILE_DEPTH_32BPP (2 << 16) -# define RADEON_SURF_AP0_SWP_16BPP (1 << 20) -# define RADEON_SURF_AP0_SWP_32BPP (1 << 21) -# define RADEON_SURF_AP1_SWP_16BPP (1 << 22) -# define RADEON_SURF_AP1_SWP_32BPP (1 << 23) -#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 -#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 -#define RADEON_SURFACE1_INFO 0x0b1c -#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 -#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 -#define RADEON_SURFACE2_INFO 0x0b2c -#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 -#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 -#define RADEON_SURFACE3_INFO 0x0b3c -#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 -#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 -#define RADEON_SURFACE4_INFO 0x0b4c -#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 -#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 -#define RADEON_SURFACE5_INFO 0x0b5c -#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 -#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 -#define RADEON_SURFACE6_INFO 0x0b6c -#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 -#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 -#define RADEON_SURFACE7_INFO 0x0b7c -#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 -#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 -#define RADEON_SW_SEMAPHORE 0x013c - -#define RADEON_TEST_DEBUG_CNTL 0x0120 -#define RADEON_TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN 0x00000001 - -#define RADEON_TEST_DEBUG_MUX 0x0124 -#define RADEON_TEST_DEBUG_OUT 0x012c -#define RADEON_TMDS_PLL_CNTL 0x02a8 -#define RADEON_TMDS_TRANSMITTER_CNTL 0x02a4 -# define RADEON_TMDS_TRANSMITTER_PLLEN 1 -# define RADEON_TMDS_TRANSMITTER_PLLRST 2 -#define RADEON_TRAIL_BRES_DEC 0x1614 -#define RADEON_TRAIL_BRES_ERR 0x160c -#define RADEON_TRAIL_BRES_INC 0x1610 -#define RADEON_TRAIL_X 0x1618 -#define RADEON_TRAIL_X_SUB 0x1620 - -#define RADEON_VCLK_ECP_CNTL 0x0008 /* PLL */ -# define RADEON_VCLK_SRC_SEL_MASK 0x03 -# define RADEON_VCLK_SRC_SEL_CPUCLK 0x00 -# define RADEON_VCLK_SRC_SEL_PSCANCLK 0x01 -# define RADEON_VCLK_SRC_SEL_BYTECLK 0x02 -# define RADEON_VCLK_SRC_SEL_PPLLCLK 0x03 -# define RADEON_PIXCLK_ALWAYS_ONb (1<<6) -# define RADEON_PIXCLK_DAC_ALWAYS_ONb (1<<7) -# define R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF (1<<23) - -#define RADEON_VENDOR_ID 0x0f00 /* PCI */ -#define RADEON_VGA_DDA_CONFIG 0x02e8 -#define RADEON_VGA_DDA_ON_OFF 0x02ec -#define RADEON_VID_BUFFER_CONTROL 0x0900 -#define RADEON_VIDEOMUX_CNTL 0x0190 - -/* VIP bus */ -#define RADEON_VIPH_CH0_DATA 0x0c00 -#define RADEON_VIPH_CH1_DATA 0x0c04 -#define RADEON_VIPH_CH2_DATA 0x0c08 -#define RADEON_VIPH_CH3_DATA 0x0c0c -#define RADEON_VIPH_CH0_ADDR 0x0c10 -#define RADEON_VIPH_CH1_ADDR 0x0c14 -#define RADEON_VIPH_CH2_ADDR 0x0c18 -#define RADEON_VIPH_CH3_ADDR 0x0c1c -#define RADEON_VIPH_CH0_SBCNT 0x0c20 -#define RADEON_VIPH_CH1_SBCNT 0x0c24 -#define RADEON_VIPH_CH2_SBCNT 0x0c28 -#define RADEON_VIPH_CH3_SBCNT 0x0c2c -#define RADEON_VIPH_CH0_ABCNT 0x0c30 -#define RADEON_VIPH_CH1_ABCNT 0x0c34 -#define RADEON_VIPH_CH2_ABCNT 0x0c38 -#define RADEON_VIPH_CH3_ABCNT 0x0c3c -#define RADEON_VIPH_CONTROL 0x0c40 -# define RADEON_VIP_BUSY 0 -# define RADEON_VIP_IDLE 1 -# define RADEON_VIP_RESET 2 -# define RADEON_VIPH_EN (1 << 21) -#define RADEON_VIPH_DV_LAT 0x0c44 -#define RADEON_VIPH_BM_CHUNK 0x0c48 -#define RADEON_VIPH_DV_INT 0x0c4c -#define RADEON_VIPH_TIMEOUT_STAT 0x0c50 -#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_STAT 0x00000010 -#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REG_AK 0x00000010 -#define RADEON_VIPH_TIMEOUT_STAT__VIPH_REGR_DIS 0x01000000 - -#define RADEON_VIPH_REG_DATA 0x0084 -#define RADEON_VIPH_REG_ADDR 0x0080 - - -#define RADEON_WAIT_UNTIL 0x1720 -# define RADEON_WAIT_CRTC_PFLIP (1 << 0) -# define RADEON_WAIT_RE_CRTC_VLINE (1 << 1) -# define RADEON_WAIT_FE_CRTC_VLINE (1 << 2) -# define RADEON_WAIT_CRTC_VLINE (1 << 3) -# define RADEON_WAIT_DMA_VID_IDLE (1 << 8) -# define RADEON_WAIT_DMA_GUI_IDLE (1 << 9) -# define RADEON_WAIT_CMDFIFO (1 << 10) /* wait for CMDFIFO_ENTRIES */ -# define RADEON_WAIT_OV0_FLIP (1 << 11) -# define RADEON_WAIT_AGP_FLUSH (1 << 13) -# define RADEON_WAIT_2D_IDLE (1 << 14) -# define RADEON_WAIT_3D_IDLE (1 << 15) -# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) -# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) -# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) -# define RADEON_CMDFIFO_ENTRIES_SHIFT 10 -# define RADEON_CMDFIFO_ENTRIES_MASK 0x7f -# define RADEON_WAIT_VAP_IDLE (1 << 28) -# define RADEON_WAIT_BOTH_CRTC_PFLIP (1 << 30) -# define RADEON_ENG_DISPLAY_SELECT_CRTC0 (0 << 31) -# define RADEON_ENG_DISPLAY_SELECT_CRTC1 (1 << 31) - -#define RADEON_X_MPLL_REF_FB_DIV 0x000a /* PLL */ -#define RADEON_XCLK_CNTL 0x000d /* PLL */ -#define RADEON_XDLL_CNTL 0x000c /* PLL */ -#define RADEON_XPLL_CNTL 0x000b /* PLL */ - - - - /* Registers for 3D/TCL */ -#define RADEON_PP_BORDER_COLOR_0 0x1d40 -#define RADEON_PP_BORDER_COLOR_1 0x1d44 -#define RADEON_PP_BORDER_COLOR_2 0x1d48 -#define RADEON_PP_CNTL 0x1c38 -# define RADEON_STIPPLE_ENABLE (1 << 0) -# define RADEON_SCISSOR_ENABLE (1 << 1) -# define RADEON_PATTERN_ENABLE (1 << 2) -# define RADEON_SHADOW_ENABLE (1 << 3) -# define RADEON_TEX_ENABLE_MASK (0xf << 4) -# define RADEON_TEX_0_ENABLE (1 << 4) -# define RADEON_TEX_1_ENABLE (1 << 5) -# define RADEON_TEX_2_ENABLE (1 << 6) -# define RADEON_TEX_3_ENABLE (1 << 7) -# define RADEON_TEX_BLEND_ENABLE_MASK (0xf << 12) -# define RADEON_TEX_BLEND_0_ENABLE (1 << 12) -# define RADEON_TEX_BLEND_1_ENABLE (1 << 13) -# define RADEON_TEX_BLEND_2_ENABLE (1 << 14) -# define RADEON_TEX_BLEND_3_ENABLE (1 << 15) -# define RADEON_PLANAR_YUV_ENABLE (1 << 20) -# define RADEON_SPECULAR_ENABLE (1 << 21) -# define RADEON_FOG_ENABLE (1 << 22) -# define RADEON_ALPHA_TEST_ENABLE (1 << 23) -# define RADEON_ANTI_ALIAS_NONE (0 << 24) -# define RADEON_ANTI_ALIAS_LINE (1 << 24) -# define RADEON_ANTI_ALIAS_POLY (2 << 24) -# define RADEON_ANTI_ALIAS_LINE_POLY (3 << 24) -# define RADEON_BUMP_MAP_ENABLE (1 << 26) -# define RADEON_BUMPED_MAP_T0 (0 << 27) -# define RADEON_BUMPED_MAP_T1 (1 << 27) -# define RADEON_BUMPED_MAP_T2 (2 << 27) -# define RADEON_TEX_3D_ENABLE_0 (1 << 29) -# define RADEON_TEX_3D_ENABLE_1 (1 << 30) -# define RADEON_MC_ENABLE (1 << 31) -#define RADEON_PP_FOG_COLOR 0x1c18 -# define RADEON_FOG_COLOR_MASK 0x00ffffff -# define RADEON_FOG_VERTEX (0 << 24) -# define RADEON_FOG_TABLE (1 << 24) -# define RADEON_FOG_USE_DEPTH (0 << 25) -# define RADEON_FOG_USE_DIFFUSE_ALPHA (2 << 25) -# define RADEON_FOG_USE_SPEC_ALPHA (3 << 25) -#define RADEON_PP_LUM_MATRIX 0x1d00 -#define RADEON_PP_MISC 0x1c14 -# define RADEON_REF_ALPHA_MASK 0x000000ff -# define RADEON_ALPHA_TEST_FAIL (0 << 8) -# define RADEON_ALPHA_TEST_LESS (1 << 8) -# define RADEON_ALPHA_TEST_LEQUAL (2 << 8) -# define RADEON_ALPHA_TEST_EQUAL (3 << 8) -# define RADEON_ALPHA_TEST_GEQUAL (4 << 8) -# define RADEON_ALPHA_TEST_GREATER (5 << 8) -# define RADEON_ALPHA_TEST_NEQUAL (6 << 8) -# define RADEON_ALPHA_TEST_PASS (7 << 8) -# define RADEON_ALPHA_TEST_OP_MASK (7 << 8) -# define RADEON_CHROMA_FUNC_FAIL (0 << 16) -# define RADEON_CHROMA_FUNC_PASS (1 << 16) -# define RADEON_CHROMA_FUNC_NEQUAL (2 << 16) -# define RADEON_CHROMA_FUNC_EQUAL (3 << 16) -# define RADEON_CHROMA_KEY_NEAREST (0 << 18) -# define RADEON_CHROMA_KEY_ZERO (1 << 18) -# define RADEON_SHADOW_ID_AUTO_INC (1 << 20) -# define RADEON_SHADOW_FUNC_EQUAL (0 << 21) -# define RADEON_SHADOW_FUNC_NEQUAL (1 << 21) -# define RADEON_SHADOW_PASS_1 (0 << 22) -# define RADEON_SHADOW_PASS_2 (1 << 22) -# define RADEON_RIGHT_HAND_CUBE_D3D (0 << 24) -# define RADEON_RIGHT_HAND_CUBE_OGL (1 << 24) -#define RADEON_PP_ROT_MATRIX_0 0x1d58 -#define RADEON_PP_ROT_MATRIX_1 0x1d5c -#define RADEON_PP_TXFILTER_0 0x1c54 -#define RADEON_PP_TXFILTER_1 0x1c6c -#define RADEON_PP_TXFILTER_2 0x1c84 -# define RADEON_MAG_FILTER_NEAREST (0 << 0) -# define RADEON_MAG_FILTER_LINEAR (1 << 0) -# define RADEON_MAG_FILTER_MASK (1 << 0) -# define RADEON_MIN_FILTER_NEAREST (0 << 1) -# define RADEON_MIN_FILTER_LINEAR (1 << 1) -# define RADEON_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) -# define RADEON_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) -# define RADEON_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) -# define RADEON_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) -# define RADEON_MIN_FILTER_ANISO_NEAREST (8 << 1) -# define RADEON_MIN_FILTER_ANISO_LINEAR (9 << 1) -# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) -# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) -# define RADEON_MIN_FILTER_MASK (15 << 1) -# define RADEON_MAX_ANISO_1_TO_1 (0 << 5) -# define RADEON_MAX_ANISO_2_TO_1 (1 << 5) -# define RADEON_MAX_ANISO_4_TO_1 (2 << 5) -# define RADEON_MAX_ANISO_8_TO_1 (3 << 5) -# define RADEON_MAX_ANISO_16_TO_1 (4 << 5) -# define RADEON_MAX_ANISO_MASK (7 << 5) -# define RADEON_LOD_BIAS_MASK (0xff << 8) -# define RADEON_LOD_BIAS_SHIFT 8 -# define RADEON_MAX_MIP_LEVEL_MASK (0x0f << 16) -# define RADEON_MAX_MIP_LEVEL_SHIFT 16 -# define RADEON_YUV_TO_RGB (1 << 20) -# define RADEON_YUV_TEMPERATURE_COOL (0 << 21) -# define RADEON_YUV_TEMPERATURE_HOT (1 << 21) -# define RADEON_YUV_TEMPERATURE_MASK (1 << 21) -# define RADEON_WRAPEN_S (1 << 22) -# define RADEON_CLAMP_S_WRAP (0 << 23) -# define RADEON_CLAMP_S_MIRROR (1 << 23) -# define RADEON_CLAMP_S_CLAMP_LAST (2 << 23) -# define RADEON_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) -# define RADEON_CLAMP_S_CLAMP_BORDER (4 << 23) -# define RADEON_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) -# define RADEON_CLAMP_S_CLAMP_GL (6 << 23) -# define RADEON_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) -# define RADEON_CLAMP_S_MASK (7 << 23) -# define RADEON_WRAPEN_T (1 << 26) -# define RADEON_CLAMP_T_WRAP (0 << 27) -# define RADEON_CLAMP_T_MIRROR (1 << 27) -# define RADEON_CLAMP_T_CLAMP_LAST (2 << 27) -# define RADEON_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) -# define RADEON_CLAMP_T_CLAMP_BORDER (4 << 27) -# define RADEON_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) -# define RADEON_CLAMP_T_CLAMP_GL (6 << 27) -# define RADEON_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) -# define RADEON_CLAMP_T_MASK (7 << 27) -# define RADEON_BORDER_MODE_OGL (0 << 31) -# define RADEON_BORDER_MODE_D3D (1 << 31) -#define RADEON_PP_TXFORMAT_0 0x1c58 -#define RADEON_PP_TXFORMAT_1 0x1c70 -#define RADEON_PP_TXFORMAT_2 0x1c88 -# define RADEON_TXFORMAT_I8 (0 << 0) -# define RADEON_TXFORMAT_AI88 (1 << 0) -# define RADEON_TXFORMAT_RGB332 (2 << 0) -# define RADEON_TXFORMAT_ARGB1555 (3 << 0) -# define RADEON_TXFORMAT_RGB565 (4 << 0) -# define RADEON_TXFORMAT_ARGB4444 (5 << 0) -# define RADEON_TXFORMAT_ARGB8888 (6 << 0) -# define RADEON_TXFORMAT_RGBA8888 (7 << 0) -# define RADEON_TXFORMAT_Y8 (8 << 0) -# define RADEON_TXFORMAT_VYUY422 (10 << 0) -# define RADEON_TXFORMAT_YVYU422 (11 << 0) -# define RADEON_TXFORMAT_DXT1 (12 << 0) -# define RADEON_TXFORMAT_DXT23 (14 << 0) -# define RADEON_TXFORMAT_DXT45 (15 << 0) -# define RADEON_TXFORMAT_SHADOW16 (16 << 0) -# define RADEON_TXFORMAT_SHADOW32 (17 << 0) -# define RADEON_TXFORMAT_DUDV88 (18 << 0) -# define RADEON_TXFORMAT_LDUDV655 (19 << 0) -# define RADEON_TXFORMAT_LDUDUV8888 (20 << 0) -# define RADEON_TXFORMAT_FORMAT_MASK (31 << 0) -# define RADEON_TXFORMAT_FORMAT_SHIFT 0 -# define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5) -# define RADEON_TXFORMAT_ALPHA_IN_MAP (1 << 6) -# define RADEON_TXFORMAT_NON_POWER2 (1 << 7) -# define RADEON_TXFORMAT_WIDTH_MASK (15 << 8) -# define RADEON_TXFORMAT_WIDTH_SHIFT 8 -# define RADEON_TXFORMAT_HEIGHT_MASK (15 << 12) -# define RADEON_TXFORMAT_HEIGHT_SHIFT 12 -# define RADEON_TXFORMAT_F5_WIDTH_MASK (15 << 16) -# define RADEON_TXFORMAT_F5_WIDTH_SHIFT 16 -# define RADEON_TXFORMAT_F5_HEIGHT_MASK (15 << 20) -# define RADEON_TXFORMAT_F5_HEIGHT_SHIFT 20 -# define RADEON_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) -# define RADEON_TXFORMAT_ST_ROUTE_MASK (3 << 24) -# define RADEON_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) -# define RADEON_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) -# define RADEON_TXFORMAT_ENDIAN_NO_SWAP (0 << 26) -# define RADEON_TXFORMAT_ENDIAN_16BPP_SWAP (1 << 26) -# define RADEON_TXFORMAT_ENDIAN_32BPP_SWAP (2 << 26) -# define RADEON_TXFORMAT_ENDIAN_HALFDW_SWAP (3 << 26) -# define RADEON_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) -# define RADEON_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) -# define RADEON_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) -# define RADEON_TXFORMAT_PERSPECTIVE_ENABLE (1 << 31) -#define RADEON_PP_CUBIC_FACES_0 0x1d24 -#define RADEON_PP_CUBIC_FACES_1 0x1d28 -#define RADEON_PP_CUBIC_FACES_2 0x1d2c -# define RADEON_FACE_WIDTH_1_SHIFT 0 -# define RADEON_FACE_HEIGHT_1_SHIFT 4 -# define RADEON_FACE_WIDTH_1_MASK (0xf << 0) -# define RADEON_FACE_HEIGHT_1_MASK (0xf << 4) -# define RADEON_FACE_WIDTH_2_SHIFT 8 -# define RADEON_FACE_HEIGHT_2_SHIFT 12 -# define RADEON_FACE_WIDTH_2_MASK (0xf << 8) -# define RADEON_FACE_HEIGHT_2_MASK (0xf << 12) -# define RADEON_FACE_WIDTH_3_SHIFT 16 -# define RADEON_FACE_HEIGHT_3_SHIFT 20 -# define RADEON_FACE_WIDTH_3_MASK (0xf << 16) -# define RADEON_FACE_HEIGHT_3_MASK (0xf << 20) -# define RADEON_FACE_WIDTH_4_SHIFT 24 -# define RADEON_FACE_HEIGHT_4_SHIFT 28 -# define RADEON_FACE_WIDTH_4_MASK (0xf << 24) -# define RADEON_FACE_HEIGHT_4_MASK (0xf << 28) - -#define RADEON_PP_TXOFFSET_0 0x1c5c -#define RADEON_PP_TXOFFSET_1 0x1c74 -#define RADEON_PP_TXOFFSET_2 0x1c8c -# define RADEON_TXO_ENDIAN_NO_SWAP (0 << 0) -# define RADEON_TXO_ENDIAN_BYTE_SWAP (1 << 0) -# define RADEON_TXO_ENDIAN_WORD_SWAP (2 << 0) -# define RADEON_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -# define RADEON_TXO_MACRO_LINEAR (0 << 2) -# define RADEON_TXO_MACRO_TILE (1 << 2) -# define RADEON_TXO_MICRO_LINEAR (0 << 3) -# define RADEON_TXO_MICRO_TILE_X2 (1 << 3) -# define RADEON_TXO_MICRO_TILE_OPT (2 << 3) -# define RADEON_TXO_OFFSET_MASK 0xffffffe0 -# define RADEON_TXO_OFFSET_SHIFT 5 - -#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */ -#define RADEON_PP_CUBIC_OFFSET_T0_1 0x1dd4 -#define RADEON_PP_CUBIC_OFFSET_T0_2 0x1dd8 -#define RADEON_PP_CUBIC_OFFSET_T0_3 0x1ddc -#define RADEON_PP_CUBIC_OFFSET_T0_4 0x1de0 -#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 -#define RADEON_PP_CUBIC_OFFSET_T1_1 0x1e04 -#define RADEON_PP_CUBIC_OFFSET_T1_2 0x1e08 -#define RADEON_PP_CUBIC_OFFSET_T1_3 0x1e0c -#define RADEON_PP_CUBIC_OFFSET_T1_4 0x1e10 -#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 -#define RADEON_PP_CUBIC_OFFSET_T2_1 0x1e18 -#define RADEON_PP_CUBIC_OFFSET_T2_2 0x1e1c -#define RADEON_PP_CUBIC_OFFSET_T2_3 0x1e20 -#define RADEON_PP_CUBIC_OFFSET_T2_4 0x1e24 - -#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */ -#define RADEON_PP_TEX_SIZE_1 0x1d0c -#define RADEON_PP_TEX_SIZE_2 0x1d14 -# define RADEON_TEX_USIZE_MASK (0x7ff << 0) -# define RADEON_TEX_USIZE_SHIFT 0 -# define RADEON_TEX_VSIZE_MASK (0x7ff << 16) -# define RADEON_TEX_VSIZE_SHIFT 16 -# define RADEON_SIGNED_RGB_MASK (1 << 30) -# define RADEON_SIGNED_RGB_SHIFT 30 -# define RADEON_SIGNED_ALPHA_MASK (1 << 31) -# define RADEON_SIGNED_ALPHA_SHIFT 31 -#define RADEON_PP_TEX_PITCH_0 0x1d08 /* NPOT */ -#define RADEON_PP_TEX_PITCH_1 0x1d10 /* NPOT */ -#define RADEON_PP_TEX_PITCH_2 0x1d18 /* NPOT */ -/* note: bits 13-5: 32 byte aligned stride of texture map */ - -#define RADEON_PP_TXCBLEND_0 0x1c60 -#define RADEON_PP_TXCBLEND_1 0x1c78 -#define RADEON_PP_TXCBLEND_2 0x1c90 -# define RADEON_COLOR_ARG_A_SHIFT 0 -# define RADEON_COLOR_ARG_A_MASK (0x1f << 0) -# define RADEON_COLOR_ARG_A_ZERO (0 << 0) -# define RADEON_COLOR_ARG_A_CURRENT_COLOR (2 << 0) -# define RADEON_COLOR_ARG_A_CURRENT_ALPHA (3 << 0) -# define RADEON_COLOR_ARG_A_DIFFUSE_COLOR (4 << 0) -# define RADEON_COLOR_ARG_A_DIFFUSE_ALPHA (5 << 0) -# define RADEON_COLOR_ARG_A_SPECULAR_COLOR (6 << 0) -# define RADEON_COLOR_ARG_A_SPECULAR_ALPHA (7 << 0) -# define RADEON_COLOR_ARG_A_TFACTOR_COLOR (8 << 0) -# define RADEON_COLOR_ARG_A_TFACTOR_ALPHA (9 << 0) -# define RADEON_COLOR_ARG_A_T0_COLOR (10 << 0) -# define RADEON_COLOR_ARG_A_T0_ALPHA (11 << 0) -# define RADEON_COLOR_ARG_A_T1_COLOR (12 << 0) -# define RADEON_COLOR_ARG_A_T1_ALPHA (13 << 0) -# define RADEON_COLOR_ARG_A_T2_COLOR (14 << 0) -# define RADEON_COLOR_ARG_A_T2_ALPHA (15 << 0) -# define RADEON_COLOR_ARG_A_T3_COLOR (16 << 0) -# define RADEON_COLOR_ARG_A_T3_ALPHA (17 << 0) -# define RADEON_COLOR_ARG_B_SHIFT 5 -# define RADEON_COLOR_ARG_B_MASK (0x1f << 5) -# define RADEON_COLOR_ARG_B_ZERO (0 << 5) -# define RADEON_COLOR_ARG_B_CURRENT_COLOR (2 << 5) -# define RADEON_COLOR_ARG_B_CURRENT_ALPHA (3 << 5) -# define RADEON_COLOR_ARG_B_DIFFUSE_COLOR (4 << 5) -# define RADEON_COLOR_ARG_B_DIFFUSE_ALPHA (5 << 5) -# define RADEON_COLOR_ARG_B_SPECULAR_COLOR (6 << 5) -# define RADEON_COLOR_ARG_B_SPECULAR_ALPHA (7 << 5) -# define RADEON_COLOR_ARG_B_TFACTOR_COLOR (8 << 5) -# define RADEON_COLOR_ARG_B_TFACTOR_ALPHA (9 << 5) -# define RADEON_COLOR_ARG_B_T0_COLOR (10 << 5) -# define RADEON_COLOR_ARG_B_T0_ALPHA (11 << 5) -# define RADEON_COLOR_ARG_B_T1_COLOR (12 << 5) -# define RADEON_COLOR_ARG_B_T1_ALPHA (13 << 5) -# define RADEON_COLOR_ARG_B_T2_COLOR (14 << 5) -# define RADEON_COLOR_ARG_B_T2_ALPHA (15 << 5) -# define RADEON_COLOR_ARG_B_T3_COLOR (16 << 5) -# define RADEON_COLOR_ARG_B_T3_ALPHA (17 << 5) -# define RADEON_COLOR_ARG_C_SHIFT 10 -# define RADEON_COLOR_ARG_C_MASK (0x1f << 10) -# define RADEON_COLOR_ARG_C_ZERO (0 << 10) -# define RADEON_COLOR_ARG_C_CURRENT_COLOR (2 << 10) -# define RADEON_COLOR_ARG_C_CURRENT_ALPHA (3 << 10) -# define RADEON_COLOR_ARG_C_DIFFUSE_COLOR (4 << 10) -# define RADEON_COLOR_ARG_C_DIFFUSE_ALPHA (5 << 10) -# define RADEON_COLOR_ARG_C_SPECULAR_COLOR (6 << 10) -# define RADEON_COLOR_ARG_C_SPECULAR_ALPHA (7 << 10) -# define RADEON_COLOR_ARG_C_TFACTOR_COLOR (8 << 10) -# define RADEON_COLOR_ARG_C_TFACTOR_ALPHA (9 << 10) -# define RADEON_COLOR_ARG_C_T0_COLOR (10 << 10) -# define RADEON_COLOR_ARG_C_T0_ALPHA (11 << 10) -# define RADEON_COLOR_ARG_C_T1_COLOR (12 << 10) -# define RADEON_COLOR_ARG_C_T1_ALPHA (13 << 10) -# define RADEON_COLOR_ARG_C_T2_COLOR (14 << 10) -# define RADEON_COLOR_ARG_C_T2_ALPHA (15 << 10) -# define RADEON_COLOR_ARG_C_T3_COLOR (16 << 10) -# define RADEON_COLOR_ARG_C_T3_ALPHA (17 << 10) -# define RADEON_COMP_ARG_A (1 << 15) -# define RADEON_COMP_ARG_A_SHIFT 15 -# define RADEON_COMP_ARG_B (1 << 16) -# define RADEON_COMP_ARG_B_SHIFT 16 -# define RADEON_COMP_ARG_C (1 << 17) -# define RADEON_COMP_ARG_C_SHIFT 17 -# define RADEON_BLEND_CTL_MASK (7 << 18) -# define RADEON_BLEND_CTL_ADD (0 << 18) -# define RADEON_BLEND_CTL_SUBTRACT (1 << 18) -# define RADEON_BLEND_CTL_ADDSIGNED (2 << 18) -# define RADEON_BLEND_CTL_BLEND (3 << 18) -# define RADEON_BLEND_CTL_DOT3 (4 << 18) -# define RADEON_SCALE_SHIFT 21 -# define RADEON_SCALE_MASK (3 << 21) -# define RADEON_SCALE_1X (0 << 21) -# define RADEON_SCALE_2X (1 << 21) -# define RADEON_SCALE_4X (2 << 21) -# define RADEON_CLAMP_TX (1 << 23) -# define RADEON_T0_EQ_TCUR (1 << 24) -# define RADEON_T1_EQ_TCUR (1 << 25) -# define RADEON_T2_EQ_TCUR (1 << 26) -# define RADEON_T3_EQ_TCUR (1 << 27) -# define RADEON_COLOR_ARG_MASK 0x1f -# define RADEON_COMP_ARG_SHIFT 15 -#define RADEON_PP_TXABLEND_0 0x1c64 -#define RADEON_PP_TXABLEND_1 0x1c7c -#define RADEON_PP_TXABLEND_2 0x1c94 -# define RADEON_ALPHA_ARG_A_SHIFT 0 -# define RADEON_ALPHA_ARG_A_MASK (0xf << 0) -# define RADEON_ALPHA_ARG_A_ZERO (0 << 0) -# define RADEON_ALPHA_ARG_A_CURRENT_ALPHA (1 << 0) -# define RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA (2 << 0) -# define RADEON_ALPHA_ARG_A_SPECULAR_ALPHA (3 << 0) -# define RADEON_ALPHA_ARG_A_TFACTOR_ALPHA (4 << 0) -# define RADEON_ALPHA_ARG_A_T0_ALPHA (5 << 0) -# define RADEON_ALPHA_ARG_A_T1_ALPHA (6 << 0) -# define RADEON_ALPHA_ARG_A_T2_ALPHA (7 << 0) -# define RADEON_ALPHA_ARG_A_T3_ALPHA (8 << 0) -# define RADEON_ALPHA_ARG_B_SHIFT 4 -# define RADEON_ALPHA_ARG_B_MASK (0xf << 4) -# define RADEON_ALPHA_ARG_B_ZERO (0 << 4) -# define RADEON_ALPHA_ARG_B_CURRENT_ALPHA (1 << 4) -# define RADEON_ALPHA_ARG_B_DIFFUSE_ALPHA (2 << 4) -# define RADEON_ALPHA_ARG_B_SPECULAR_ALPHA (3 << 4) -# define RADEON_ALPHA_ARG_B_TFACTOR_ALPHA (4 << 4) -# define RADEON_ALPHA_ARG_B_T0_ALPHA (5 << 4) -# define RADEON_ALPHA_ARG_B_T1_ALPHA (6 << 4) -# define RADEON_ALPHA_ARG_B_T2_ALPHA (7 << 4) -# define RADEON_ALPHA_ARG_B_T3_ALPHA (8 << 4) -# define RADEON_ALPHA_ARG_C_SHIFT 8 -# define RADEON_ALPHA_ARG_C_MASK (0xf << 8) -# define RADEON_ALPHA_ARG_C_ZERO (0 << 8) -# define RADEON_ALPHA_ARG_C_CURRENT_ALPHA (1 << 8) -# define RADEON_ALPHA_ARG_C_DIFFUSE_ALPHA (2 << 8) -# define RADEON_ALPHA_ARG_C_SPECULAR_ALPHA (3 << 8) -# define RADEON_ALPHA_ARG_C_TFACTOR_ALPHA (4 << 8) -# define RADEON_ALPHA_ARG_C_T0_ALPHA (5 << 8) -# define RADEON_ALPHA_ARG_C_T1_ALPHA (6 << 8) -# define RADEON_ALPHA_ARG_C_T2_ALPHA (7 << 8) -# define RADEON_ALPHA_ARG_C_T3_ALPHA (8 << 8) -# define RADEON_DOT_ALPHA_DONT_REPLICATE (1 << 9) -# define RADEON_ALPHA_ARG_MASK 0xf - -#define RADEON_PP_TFACTOR_0 0x1c68 -#define RADEON_PP_TFACTOR_1 0x1c80 -#define RADEON_PP_TFACTOR_2 0x1c98 - -#define RADEON_RB3D_BLENDCNTL 0x1c20 -# define RADEON_COMB_FCN_MASK (3 << 12) -# define RADEON_COMB_FCN_ADD_CLAMP (0 << 12) -# define RADEON_COMB_FCN_ADD_NOCLAMP (1 << 12) -# define RADEON_COMB_FCN_SUB_CLAMP (2 << 12) -# define RADEON_COMB_FCN_SUB_NOCLAMP (3 << 12) -# define RADEON_SRC_BLEND_GL_ZERO (32 << 16) -# define RADEON_SRC_BLEND_GL_ONE (33 << 16) -# define RADEON_SRC_BLEND_GL_SRC_COLOR (34 << 16) -# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) -# define RADEON_SRC_BLEND_GL_DST_COLOR (36 << 16) -# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) -# define RADEON_SRC_BLEND_GL_SRC_ALPHA (38 << 16) -# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) -# define RADEON_SRC_BLEND_GL_DST_ALPHA (40 << 16) -# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) -# define RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) -# define RADEON_SRC_BLEND_MASK (63 << 16) -# define RADEON_DST_BLEND_GL_ZERO (32 << 24) -# define RADEON_DST_BLEND_GL_ONE (33 << 24) -# define RADEON_DST_BLEND_GL_SRC_COLOR (34 << 24) -# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) -# define RADEON_DST_BLEND_GL_DST_COLOR (36 << 24) -# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) -# define RADEON_DST_BLEND_GL_SRC_ALPHA (38 << 24) -# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) -# define RADEON_DST_BLEND_GL_DST_ALPHA (40 << 24) -# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) -# define RADEON_DST_BLEND_MASK (63 << 24) -#define RADEON_RB3D_CNTL 0x1c3c -# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) -# define RADEON_PLANE_MASK_ENABLE (1 << 1) -# define RADEON_DITHER_ENABLE (1 << 2) -# define RADEON_ROUND_ENABLE (1 << 3) -# define RADEON_SCALE_DITHER_ENABLE (1 << 4) -# define RADEON_DITHER_INIT (1 << 5) -# define RADEON_ROP_ENABLE (1 << 6) -# define RADEON_STENCIL_ENABLE (1 << 7) -# define RADEON_Z_ENABLE (1 << 8) -# define RADEON_DEPTHXY_OFFSET_ENABLE (1 << 9) -# define RADEON_RB3D_COLOR_FORMAT_SHIFT 10 - -# define RADEON_COLOR_FORMAT_ARGB1555 3 -# define RADEON_COLOR_FORMAT_RGB565 4 -# define RADEON_COLOR_FORMAT_ARGB8888 6 -# define RADEON_COLOR_FORMAT_RGB332 7 -# define RADEON_COLOR_FORMAT_Y8 8 -# define RADEON_COLOR_FORMAT_RGB8 9 -# define RADEON_COLOR_FORMAT_YUV422_VYUY 11 -# define RADEON_COLOR_FORMAT_YUV422_YVYU 12 -# define RADEON_COLOR_FORMAT_aYUV444 14 -# define RADEON_COLOR_FORMAT_ARGB4444 15 - -# define RADEON_CLRCMP_FLIP_ENABLE (1 << 14) -#define RADEON_RB3D_COLOROFFSET 0x1c40 -# define RADEON_COLOROFFSET_MASK 0xfffffff0 -#define RADEON_RB3D_COLORPITCH 0x1c48 -# define RADEON_COLORPITCH_MASK 0x000001ff8 -# define RADEON_COLOR_TILE_ENABLE (1 << 16) -# define RADEON_COLOR_MICROTILE_ENABLE (1 << 17) -# define RADEON_COLOR_ENDIAN_NO_SWAP (0 << 18) -# define RADEON_COLOR_ENDIAN_WORD_SWAP (1 << 18) -# define RADEON_COLOR_ENDIAN_DWORD_SWAP (2 << 18) -#define RADEON_RB3D_DEPTHOFFSET 0x1c24 -#define RADEON_RB3D_DEPTHPITCH 0x1c28 -# define RADEON_DEPTHPITCH_MASK 0x00001ff8 -# define RADEON_DEPTH_ENDIAN_NO_SWAP (0 << 18) -# define RADEON_DEPTH_ENDIAN_WORD_SWAP (1 << 18) -# define RADEON_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) -#define RADEON_RB3D_PLANEMASK 0x1d84 -#define RADEON_RB3D_ROPCNTL 0x1d80 -# define RADEON_ROP_MASK (15 << 8) -# define RADEON_ROP_CLEAR (0 << 8) -# define RADEON_ROP_NOR (1 << 8) -# define RADEON_ROP_AND_INVERTED (2 << 8) -# define RADEON_ROP_COPY_INVERTED (3 << 8) -# define RADEON_ROP_AND_REVERSE (4 << 8) -# define RADEON_ROP_INVERT (5 << 8) -# define RADEON_ROP_XOR (6 << 8) -# define RADEON_ROP_NAND (7 << 8) -# define RADEON_ROP_AND (8 << 8) -# define RADEON_ROP_EQUIV (9 << 8) -# define RADEON_ROP_NOOP (10 << 8) -# define RADEON_ROP_OR_INVERTED (11 << 8) -# define RADEON_ROP_COPY (12 << 8) -# define RADEON_ROP_OR_REVERSE (13 << 8) -# define RADEON_ROP_OR (14 << 8) -# define RADEON_ROP_SET (15 << 8) -#define RADEON_RB3D_STENCILREFMASK 0x1d7c -# define RADEON_STENCIL_REF_SHIFT 0 -# define RADEON_STENCIL_REF_MASK (0xff << 0) -# define RADEON_STENCIL_MASK_SHIFT 16 -# define RADEON_STENCIL_VALUE_MASK (0xff << 16) -# define RADEON_STENCIL_WRITEMASK_SHIFT 24 -# define RADEON_STENCIL_WRITE_MASK (0xff << 24) -#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c -# define RADEON_DEPTH_FORMAT_MASK (0xf << 0) -# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) -# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) -# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) -# define RADEON_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) -# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) -# define RADEON_DEPTH_FORMAT_16BIT_FLOAT_W (7 << 0) -# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) -# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) -# define RADEON_Z_TEST_NEVER (0 << 4) -# define RADEON_Z_TEST_LESS (1 << 4) -# define RADEON_Z_TEST_LEQUAL (2 << 4) -# define RADEON_Z_TEST_EQUAL (3 << 4) -# define RADEON_Z_TEST_GEQUAL (4 << 4) -# define RADEON_Z_TEST_GREATER (5 << 4) -# define RADEON_Z_TEST_NEQUAL (6 << 4) -# define RADEON_Z_TEST_ALWAYS (7 << 4) -# define RADEON_Z_TEST_MASK (7 << 4) -# define RADEON_STENCIL_TEST_NEVER (0 << 12) -# define RADEON_STENCIL_TEST_LESS (1 << 12) -# define RADEON_STENCIL_TEST_LEQUAL (2 << 12) -# define RADEON_STENCIL_TEST_EQUAL (3 << 12) -# define RADEON_STENCIL_TEST_GEQUAL (4 << 12) -# define RADEON_STENCIL_TEST_GREATER (5 << 12) -# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) -# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_TEST_MASK (0x7 << 12) -# define RADEON_STENCIL_FAIL_KEEP (0 << 16) -# define RADEON_STENCIL_FAIL_ZERO (1 << 16) -# define RADEON_STENCIL_FAIL_REPLACE (2 << 16) -# define RADEON_STENCIL_FAIL_INC (3 << 16) -# define RADEON_STENCIL_FAIL_DEC (4 << 16) -# define RADEON_STENCIL_FAIL_INVERT (5 << 16) -# define RADEON_STENCIL_FAIL_MASK (0x7 << 16) -# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) -# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) -# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) -# define RADEON_STENCIL_ZPASS_INC (3 << 20) -# define RADEON_STENCIL_ZPASS_DEC (4 << 20) -# define RADEON_STENCIL_ZPASS_INVERT (5 << 20) -# define RADEON_STENCIL_ZPASS_MASK (0x7 << 20) -# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) -# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) -# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) -# define RADEON_STENCIL_ZFAIL_INC (3 << 24) -# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) -# define RADEON_STENCIL_ZFAIL_INVERT (5 << 24) -# define RADEON_STENCIL_ZFAIL_MASK (0x7 << 24) -# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) -# define RADEON_FORCE_Z_DIRTY (1 << 29) -# define RADEON_Z_WRITE_ENABLE (1 << 30) -#define RADEON_RE_LINE_PATTERN 0x1cd0 -# define RADEON_LINE_PATTERN_MASK 0x0000ffff -# define RADEON_LINE_REPEAT_COUNT_SHIFT 16 -# define RADEON_LINE_PATTERN_START_SHIFT 24 -# define RADEON_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) -# define RADEON_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) -# define RADEON_LINE_PATTERN_AUTO_RESET (1 << 29) -#define RADEON_RE_LINE_STATE 0x1cd4 -# define RADEON_LINE_CURRENT_PTR_SHIFT 0 -# define RADEON_LINE_CURRENT_COUNT_SHIFT 8 -#define RADEON_RE_MISC 0x26c4 -# define RADEON_STIPPLE_COORD_MASK 0x1f -# define RADEON_STIPPLE_X_OFFSET_SHIFT 0 -# define RADEON_STIPPLE_X_OFFSET_MASK (0x1f << 0) -# define RADEON_STIPPLE_Y_OFFSET_SHIFT 8 -# define RADEON_STIPPLE_Y_OFFSET_MASK (0x1f << 8) -# define RADEON_STIPPLE_LITTLE_BIT_ORDER (0 << 16) -# define RADEON_STIPPLE_BIG_BIT_ORDER (1 << 16) -#define RADEON_RE_SOLID_COLOR 0x1c1c -#define RADEON_RE_TOP_LEFT 0x26c0 -# define RADEON_RE_LEFT_SHIFT 0 -# define RADEON_RE_TOP_SHIFT 16 -#define RADEON_RE_WIDTH_HEIGHT 0x1c44 -# define RADEON_RE_WIDTH_SHIFT 0 -# define RADEON_RE_HEIGHT_SHIFT 16 - -#define RADEON_RB3D_ZPASS_DATA 0x3290 -#define RADEON_RB3D_ZPASS_ADDR 0x3294 - -#define RADEON_SE_CNTL 0x1c4c -# define RADEON_FFACE_CULL_CW (0 << 0) -# define RADEON_FFACE_CULL_CCW (1 << 0) -# define RADEON_FFACE_CULL_DIR_MASK (1 << 0) -# define RADEON_BFACE_CULL (0 << 1) -# define RADEON_BFACE_SOLID (3 << 1) -# define RADEON_FFACE_CULL (0 << 3) -# define RADEON_FFACE_SOLID (3 << 3) -# define RADEON_FFACE_CULL_MASK (3 << 3) -# define RADEON_BADVTX_CULL_DISABLE (1 << 5) -# define RADEON_FLAT_SHADE_VTX_0 (0 << 6) -# define RADEON_FLAT_SHADE_VTX_1 (1 << 6) -# define RADEON_FLAT_SHADE_VTX_2 (2 << 6) -# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) -# define RADEON_DIFFUSE_SHADE_SOLID (0 << 8) -# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) -# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) -# define RADEON_DIFFUSE_SHADE_MASK (3 << 8) -# define RADEON_ALPHA_SHADE_SOLID (0 << 10) -# define RADEON_ALPHA_SHADE_FLAT (1 << 10) -# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) -# define RADEON_ALPHA_SHADE_MASK (3 << 10) -# define RADEON_SPECULAR_SHADE_SOLID (0 << 12) -# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) -# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) -# define RADEON_SPECULAR_SHADE_MASK (3 << 12) -# define RADEON_FOG_SHADE_SOLID (0 << 14) -# define RADEON_FOG_SHADE_FLAT (1 << 14) -# define RADEON_FOG_SHADE_GOURAUD (2 << 14) -# define RADEON_FOG_SHADE_MASK (3 << 14) -# define RADEON_ZBIAS_ENABLE_POINT (1 << 16) -# define RADEON_ZBIAS_ENABLE_LINE (1 << 17) -# define RADEON_ZBIAS_ENABLE_TRI (1 << 18) -# define RADEON_WIDELINE_ENABLE (1 << 20) -# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) -# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) -# define RADEON_VTX_PIX_CENTER_D3D (0 << 27) -# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) -# define RADEON_ROUND_MODE_TRUNC (0 << 28) -# define RADEON_ROUND_MODE_ROUND (1 << 28) -# define RADEON_ROUND_MODE_ROUND_EVEN (2 << 28) -# define RADEON_ROUND_MODE_ROUND_ODD (3 << 28) -# define RADEON_ROUND_PREC_16TH_PIX (0 << 30) -# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) -# define RADEON_ROUND_PREC_4TH_PIX (2 << 30) -# define RADEON_ROUND_PREC_HALF_PIX (3 << 30) -#define R200_RE_CNTL 0x1c50 -# define R200_STIPPLE_ENABLE 0x1 -# define R200_SCISSOR_ENABLE 0x2 -# define R200_PATTERN_ENABLE 0x4 -# define R200_PERSPECTIVE_ENABLE 0x8 -# define R200_POINT_SMOOTH 0x20 -# define R200_VTX_STQ0_D3D 0x00010000 -# define R200_VTX_STQ1_D3D 0x00040000 -# define R200_VTX_STQ2_D3D 0x00100000 -# define R200_VTX_STQ3_D3D 0x00400000 -# define R200_VTX_STQ4_D3D 0x01000000 -# define R200_VTX_STQ5_D3D 0x04000000 -#define RADEON_SE_CNTL_STATUS 0x2140 -# define RADEON_VC_NO_SWAP (0 << 0) -# define RADEON_VC_16BIT_SWAP (1 << 0) -# define RADEON_VC_32BIT_SWAP (2 << 0) -# define RADEON_VC_HALF_DWORD_SWAP (3 << 0) -# define RADEON_TCL_BYPASS (1 << 8) -#define RADEON_SE_COORD_FMT 0x1c50 -# define RADEON_VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0) -# define RADEON_VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1) -# define RADEON_VTX_ST0_NONPARAMETRIC (1 << 8) -# define RADEON_VTX_ST1_NONPARAMETRIC (1 << 9) -# define RADEON_VTX_ST2_NONPARAMETRIC (1 << 10) -# define RADEON_VTX_ST3_NONPARAMETRIC (1 << 11) -# define RADEON_VTX_W0_NORMALIZE (1 << 12) -# define RADEON_VTX_W0_IS_NOT_1_OVER_W0 (1 << 16) -# define RADEON_VTX_ST0_PRE_MULT_1_OVER_W0 (1 << 17) -# define RADEON_VTX_ST1_PRE_MULT_1_OVER_W0 (1 << 19) -# define RADEON_VTX_ST2_PRE_MULT_1_OVER_W0 (1 << 21) -# define RADEON_VTX_ST3_PRE_MULT_1_OVER_W0 (1 << 23) -# define RADEON_TEX1_W_ROUTING_USE_W0 (0 << 26) -# define RADEON_TEX1_W_ROUTING_USE_Q1 (1 << 26) -#define RADEON_SE_LINE_WIDTH 0x1db8 -#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c -# define RADEON_LIGHTING_ENABLE (1 << 0) -# define RADEON_LIGHT_IN_MODELSPACE (1 << 1) -# define RADEON_LOCAL_VIEWER (1 << 2) -# define RADEON_NORMALIZE_NORMALS (1 << 3) -# define RADEON_RESCALE_NORMALS (1 << 4) -# define RADEON_SPECULAR_LIGHTS (1 << 5) -# define RADEON_DIFFUSE_SPECULAR_COMBINE (1 << 6) -# define RADEON_LIGHT_ALPHA (1 << 7) -# define RADEON_LOCAL_LIGHT_VEC_GL (1 << 8) -# define RADEON_LIGHT_NO_NORMAL_AMBIENT_ONLY (1 << 9) -# define RADEON_LM_SOURCE_STATE_PREMULT 0 -# define RADEON_LM_SOURCE_STATE_MULT 1 -# define RADEON_LM_SOURCE_VERTEX_DIFFUSE 2 -# define RADEON_LM_SOURCE_VERTEX_SPECULAR 3 -# define RADEON_EMISSIVE_SOURCE_SHIFT 16 -# define RADEON_AMBIENT_SOURCE_SHIFT 18 -# define RADEON_DIFFUSE_SOURCE_SHIFT 20 -# define RADEON_SPECULAR_SOURCE_SHIFT 22 -#define RADEON_SE_TCL_MATERIAL_AMBIENT_RED 0x2220 -#define RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224 -#define RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228 -#define RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA 0x222c -#define RADEON_SE_TCL_MATERIAL_DIFFUSE_RED 0x2230 -#define RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN 0x2234 -#define RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE 0x2238 -#define RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA 0x223c -#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 -#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN 0x2214 -#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE 0x2218 -#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA 0x221c -#define RADEON_SE_TCL_MATERIAL_SPECULAR_RED 0x2240 -#define RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244 -#define RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248 -#define RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c -#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c -# define RADEON_MODELVIEW_0_SHIFT 0 -# define RADEON_MODELVIEW_1_SHIFT 4 -# define RADEON_MODELVIEW_2_SHIFT 8 -# define RADEON_MODELVIEW_3_SHIFT 12 -# define RADEON_IT_MODELVIEW_0_SHIFT 16 -# define RADEON_IT_MODELVIEW_1_SHIFT 20 -# define RADEON_IT_MODELVIEW_2_SHIFT 24 -# define RADEON_IT_MODELVIEW_3_SHIFT 28 -#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260 -# define RADEON_MODELPROJECT_0_SHIFT 0 -# define RADEON_MODELPROJECT_1_SHIFT 4 -# define RADEON_MODELPROJECT_2_SHIFT 8 -# define RADEON_MODELPROJECT_3_SHIFT 12 -# define RADEON_TEXMAT_0_SHIFT 16 -# define RADEON_TEXMAT_1_SHIFT 20 -# define RADEON_TEXMAT_2_SHIFT 24 -# define RADEON_TEXMAT_3_SHIFT 28 - - -#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 -# define RADEON_TCL_VTX_W0 (1 << 0) -# define RADEON_TCL_VTX_FP_DIFFUSE (1 << 1) -# define RADEON_TCL_VTX_FP_ALPHA (1 << 2) -# define RADEON_TCL_VTX_PK_DIFFUSE (1 << 3) -# define RADEON_TCL_VTX_FP_SPEC (1 << 4) -# define RADEON_TCL_VTX_FP_FOG (1 << 5) -# define RADEON_TCL_VTX_PK_SPEC (1 << 6) -# define RADEON_TCL_VTX_ST0 (1 << 7) -# define RADEON_TCL_VTX_ST1 (1 << 8) -# define RADEON_TCL_VTX_Q1 (1 << 9) -# define RADEON_TCL_VTX_ST2 (1 << 10) -# define RADEON_TCL_VTX_Q2 (1 << 11) -# define RADEON_TCL_VTX_ST3 (1 << 12) -# define RADEON_TCL_VTX_Q3 (1 << 13) -# define RADEON_TCL_VTX_Q0 (1 << 14) -# define RADEON_TCL_VTX_WEIGHT_COUNT_SHIFT 15 -# define RADEON_TCL_VTX_NORM0 (1 << 18) -# define RADEON_TCL_VTX_XY1 (1 << 27) -# define RADEON_TCL_VTX_Z1 (1 << 28) -# define RADEON_TCL_VTX_W1 (1 << 29) -# define RADEON_TCL_VTX_NORM1 (1 << 30) -# define RADEON_TCL_VTX_Z0 (1 << 31) - -#define RADEON_SE_TCL_OUTPUT_VTX_SEL 0x2258 -# define RADEON_TCL_COMPUTE_XYZW (1 << 0) -# define RADEON_TCL_COMPUTE_DIFFUSE (1 << 1) -# define RADEON_TCL_COMPUTE_SPECULAR (1 << 2) -# define RADEON_TCL_FORCE_NAN_IF_COLOR_NAN (1 << 3) -# define RADEON_TCL_FORCE_INORDER_PROC (1 << 4) -# define RADEON_TCL_TEX_INPUT_TEX_0 0 -# define RADEON_TCL_TEX_INPUT_TEX_1 1 -# define RADEON_TCL_TEX_INPUT_TEX_2 2 -# define RADEON_TCL_TEX_INPUT_TEX_3 3 -# define RADEON_TCL_TEX_COMPUTED_TEX_0 8 -# define RADEON_TCL_TEX_COMPUTED_TEX_1 9 -# define RADEON_TCL_TEX_COMPUTED_TEX_2 10 -# define RADEON_TCL_TEX_COMPUTED_TEX_3 11 -# define RADEON_TCL_TEX_0_OUTPUT_SHIFT 16 -# define RADEON_TCL_TEX_1_OUTPUT_SHIFT 20 -# define RADEON_TCL_TEX_2_OUTPUT_SHIFT 24 -# define RADEON_TCL_TEX_3_OUTPUT_SHIFT 28 - -#define RADEON_SE_TCL_PER_LIGHT_CTL_0 0x2270 -# define RADEON_LIGHT_0_ENABLE (1 << 0) -# define RADEON_LIGHT_0_ENABLE_AMBIENT (1 << 1) -# define RADEON_LIGHT_0_ENABLE_SPECULAR (1 << 2) -# define RADEON_LIGHT_0_IS_LOCAL (1 << 3) -# define RADEON_LIGHT_0_IS_SPOT (1 << 4) -# define RADEON_LIGHT_0_DUAL_CONE (1 << 5) -# define RADEON_LIGHT_0_ENABLE_RANGE_ATTEN (1 << 6) -# define RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN (1 << 7) -# define RADEON_LIGHT_0_SHIFT 0 -# define RADEON_LIGHT_1_ENABLE (1 << 16) -# define RADEON_LIGHT_1_ENABLE_AMBIENT (1 << 17) -# define RADEON_LIGHT_1_ENABLE_SPECULAR (1 << 18) -# define RADEON_LIGHT_1_IS_LOCAL (1 << 19) -# define RADEON_LIGHT_1_IS_SPOT (1 << 20) -# define RADEON_LIGHT_1_DUAL_CONE (1 << 21) -# define RADEON_LIGHT_1_ENABLE_RANGE_ATTEN (1 << 22) -# define RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN (1 << 23) -# define RADEON_LIGHT_1_SHIFT 16 -#define RADEON_SE_TCL_PER_LIGHT_CTL_1 0x2274 -# define RADEON_LIGHT_2_SHIFT 0 -# define RADEON_LIGHT_3_SHIFT 16 -#define RADEON_SE_TCL_PER_LIGHT_CTL_2 0x2278 -# define RADEON_LIGHT_4_SHIFT 0 -# define RADEON_LIGHT_5_SHIFT 16 -#define RADEON_SE_TCL_PER_LIGHT_CTL_3 0x227c -# define RADEON_LIGHT_6_SHIFT 0 -# define RADEON_LIGHT_7_SHIFT 16 - -#define RADEON_SE_TCL_SHININESS 0x2250 - -#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268 -# define RADEON_TEXGEN_TEXMAT_0_ENABLE (1 << 0) -# define RADEON_TEXGEN_TEXMAT_1_ENABLE (1 << 1) -# define RADEON_TEXGEN_TEXMAT_2_ENABLE (1 << 2) -# define RADEON_TEXGEN_TEXMAT_3_ENABLE (1 << 3) -# define RADEON_TEXMAT_0_ENABLE (1 << 4) -# define RADEON_TEXMAT_1_ENABLE (1 << 5) -# define RADEON_TEXMAT_2_ENABLE (1 << 6) -# define RADEON_TEXMAT_3_ENABLE (1 << 7) -# define RADEON_TEXGEN_INPUT_MASK 0xf -# define RADEON_TEXGEN_INPUT_TEXCOORD_0 0 -# define RADEON_TEXGEN_INPUT_TEXCOORD_1 1 -# define RADEON_TEXGEN_INPUT_TEXCOORD_2 2 -# define RADEON_TEXGEN_INPUT_TEXCOORD_3 3 -# define RADEON_TEXGEN_INPUT_OBJ 4 -# define RADEON_TEXGEN_INPUT_EYE 5 -# define RADEON_TEXGEN_INPUT_EYE_NORMAL 6 -# define RADEON_TEXGEN_INPUT_EYE_REFLECT 7 -# define RADEON_TEXGEN_INPUT_EYE_NORMALIZED 8 -# define RADEON_TEXGEN_0_INPUT_SHIFT 16 -# define RADEON_TEXGEN_1_INPUT_SHIFT 20 -# define RADEON_TEXGEN_2_INPUT_SHIFT 24 -# define RADEON_TEXGEN_3_INPUT_SHIFT 28 - -#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264 -# define RADEON_UCP_IN_CLIP_SPACE (1 << 0) -# define RADEON_UCP_IN_MODEL_SPACE (1 << 1) -# define RADEON_UCP_ENABLE_0 (1 << 2) -# define RADEON_UCP_ENABLE_1 (1 << 3) -# define RADEON_UCP_ENABLE_2 (1 << 4) -# define RADEON_UCP_ENABLE_3 (1 << 5) -# define RADEON_UCP_ENABLE_4 (1 << 6) -# define RADEON_UCP_ENABLE_5 (1 << 7) -# define RADEON_TCL_FOG_MASK (3 << 8) -# define RADEON_TCL_FOG_DISABLE (0 << 8) -# define RADEON_TCL_FOG_EXP (1 << 8) -# define RADEON_TCL_FOG_EXP2 (2 << 8) -# define RADEON_TCL_FOG_LINEAR (3 << 8) -# define RADEON_RNG_BASED_FOG (1 << 10) -# define RADEON_LIGHT_TWOSIDE (1 << 11) -# define RADEON_BLEND_OP_COUNT_MASK (7 << 12) -# define RADEON_BLEND_OP_COUNT_SHIFT 12 -# define RADEON_POSITION_BLEND_OP_ENABLE (1 << 16) -# define RADEON_NORMAL_BLEND_OP_ENABLE (1 << 17) -# define RADEON_VERTEX_BLEND_SRC_0_PRIMARY (1 << 18) -# define RADEON_VERTEX_BLEND_SRC_0_SECONDARY (1 << 18) -# define RADEON_VERTEX_BLEND_SRC_1_PRIMARY (1 << 19) -# define RADEON_VERTEX_BLEND_SRC_1_SECONDARY (1 << 19) -# define RADEON_VERTEX_BLEND_SRC_2_PRIMARY (1 << 20) -# define RADEON_VERTEX_BLEND_SRC_2_SECONDARY (1 << 20) -# define RADEON_VERTEX_BLEND_SRC_3_PRIMARY (1 << 21) -# define RADEON_VERTEX_BLEND_SRC_3_SECONDARY (1 << 21) -# define RADEON_VERTEX_BLEND_WGT_MINUS_ONE (1 << 22) -# define RADEON_CULL_FRONT_IS_CW (0 << 28) -# define RADEON_CULL_FRONT_IS_CCW (1 << 28) -# define RADEON_CULL_FRONT (1 << 29) -# define RADEON_CULL_BACK (1 << 30) -# define RADEON_FORCE_W_TO_ONE (1 << 31) - -#define RADEON_SE_VPORT_XSCALE 0x1d98 -#define RADEON_SE_VPORT_XOFFSET 0x1d9c -#define RADEON_SE_VPORT_YSCALE 0x1da0 -#define RADEON_SE_VPORT_YOFFSET 0x1da4 -#define RADEON_SE_VPORT_ZSCALE 0x1da8 -#define RADEON_SE_VPORT_ZOFFSET 0x1dac -#define RADEON_SE_ZBIAS_FACTOR 0x1db0 -#define RADEON_SE_ZBIAS_CONSTANT 0x1db4 - -#define RADEON_SE_VTX_FMT 0x2080 -# define RADEON_SE_VTX_FMT_XY 0x00000000 -# define RADEON_SE_VTX_FMT_W0 0x00000001 -# define RADEON_SE_VTX_FMT_FPCOLOR 0x00000002 -# define RADEON_SE_VTX_FMT_FPALPHA 0x00000004 -# define RADEON_SE_VTX_FMT_PKCOLOR 0x00000008 -# define RADEON_SE_VTX_FMT_FPSPEC 0x00000010 -# define RADEON_SE_VTX_FMT_FPFOG 0x00000020 -# define RADEON_SE_VTX_FMT_PKSPEC 0x00000040 -# define RADEON_SE_VTX_FMT_ST0 0x00000080 -# define RADEON_SE_VTX_FMT_ST1 0x00000100 -# define RADEON_SE_VTX_FMT_Q1 0x00000200 -# define RADEON_SE_VTX_FMT_ST2 0x00000400 -# define RADEON_SE_VTX_FMT_Q2 0x00000800 -# define RADEON_SE_VTX_FMT_ST3 0x00001000 -# define RADEON_SE_VTX_FMT_Q3 0x00002000 -# define RADEON_SE_VTX_FMT_Q0 0x00004000 -# define RADEON_SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 -# define RADEON_SE_VTX_FMT_N0 0x00040000 -# define RADEON_SE_VTX_FMT_XY1 0x08000000 -# define RADEON_SE_VTX_FMT_Z1 0x10000000 -# define RADEON_SE_VTX_FMT_W1 0x20000000 -# define RADEON_SE_VTX_FMT_N1 0x40000000 -# define RADEON_SE_VTX_FMT_Z 0x80000000 - -#define RADEON_SE_VF_CNTL 0x2084 -# define RADEON_VF_PRIM_TYPE_POINT_LIST 1 -# define RADEON_VF_PRIM_TYPE_LINE_LIST 2 -# define RADEON_VF_PRIM_TYPE_LINE_STRIP 3 -# define RADEON_VF_PRIM_TYPE_TRIANGLE_LIST 4 -# define RADEON_VF_PRIM_TYPE_TRIANGLE_FAN 5 -# define RADEON_VF_PRIM_TYPE_TRIANGLE_STRIP 6 -# define RADEON_VF_PRIM_TYPE_TRIANGLE_FLAG 7 -# define RADEON_VF_PRIM_TYPE_RECTANGLE_LIST 8 -# define RADEON_VF_PRIM_TYPE_POINT_LIST_3 9 -# define RADEON_VF_PRIM_TYPE_LINE_LIST_3 10 -# define RADEON_VF_PRIM_TYPE_SPIRIT_LIST 11 -# define RADEON_VF_PRIM_TYPE_LINE_LOOP 12 -# define RADEON_VF_PRIM_TYPE_QUAD_LIST 13 -# define RADEON_VF_PRIM_TYPE_QUAD_STRIP 14 -# define RADEON_VF_PRIM_TYPE_POLYGON 15 -# define RADEON_VF_PRIM_WALK_STATE (0<<4) -# define RADEON_VF_PRIM_WALK_INDEX (1<<4) -# define RADEON_VF_PRIM_WALK_LIST (2<<4) -# define RADEON_VF_PRIM_WALK_DATA (3<<4) -# define RADEON_VF_COLOR_ORDER_RGBA (1<<6) -# define RADEON_VF_RADEON_MODE (1<<8) -# define RADEON_VF_TCL_OUTPUT_CTL_ENA (1<<9) -# define RADEON_VF_PROG_STREAM_ENA (1<<10) -# define RADEON_VF_INDEX_SIZE_SHIFT 11 -# define RADEON_VF_NUM_VERTICES_SHIFT 16 - -#define RADEON_SE_PORT_DATA0 0x2000 - -#define R200_SE_VAP_CNTL 0x2080 -# define R200_VAP_TCL_ENABLE 0x00000001 -# define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 -# define R200_VAP_FORCE_W_TO_ONE 0x00010000 -# define R200_VAP_D3D_TEX_DEFAULT 0x00020000 -# define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 -# define R200_VAP_VF_MAX_VTX_NUM (9 << 18) -# define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 -#define R200_VF_MAX_VTX_INDX 0x210c -#define R200_VF_MIN_VTX_INDX 0x2110 -#define R200_SE_VTE_CNTL 0x20b0 -# define R200_VPORT_X_SCALE_ENA 0x00000001 -# define R200_VPORT_X_OFFSET_ENA 0x00000002 -# define R200_VPORT_Y_SCALE_ENA 0x00000004 -# define R200_VPORT_Y_OFFSET_ENA 0x00000008 -# define R200_VPORT_Z_SCALE_ENA 0x00000010 -# define R200_VPORT_Z_OFFSET_ENA 0x00000020 -# define R200_VTX_XY_FMT 0x00000100 -# define R200_VTX_Z_FMT 0x00000200 -# define R200_VTX_W0_FMT 0x00000400 -# define R200_VTX_W0_NORMALIZE 0x00000800 -# define R200_VTX_ST_DENORMALIZED 0x00001000 -#define R200_SE_VAP_CNTL_STATUS 0x2140 -# define R200_VC_NO_SWAP (0 << 0) -# define R200_VC_16BIT_SWAP (1 << 0) -# define R200_VC_32BIT_SWAP (2 << 0) -#define R200_PP_TXFILTER_0 0x2c00 -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFILTER_5 0x2ca0 -# define R200_MAG_FILTER_NEAREST (0 << 0) -# define R200_MAG_FILTER_LINEAR (1 << 0) -# define R200_MAG_FILTER_MASK (1 << 0) -# define R200_MIN_FILTER_NEAREST (0 << 1) -# define R200_MIN_FILTER_LINEAR (1 << 1) -# define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) -# define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) -# define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) -# define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) -# define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) -# define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) -# define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) -# define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) -# define R200_MIN_FILTER_MASK (15 << 1) -# define R200_MAX_ANISO_1_TO_1 (0 << 5) -# define R200_MAX_ANISO_2_TO_1 (1 << 5) -# define R200_MAX_ANISO_4_TO_1 (2 << 5) -# define R200_MAX_ANISO_8_TO_1 (3 << 5) -# define R200_MAX_ANISO_16_TO_1 (4 << 5) -# define R200_MAX_ANISO_MASK (7 << 5) -# define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) -# define R200_MAX_MIP_LEVEL_SHIFT 16 -# define R200_YUV_TO_RGB (1 << 20) -# define R200_YUV_TEMPERATURE_COOL (0 << 21) -# define R200_YUV_TEMPERATURE_HOT (1 << 21) -# define R200_YUV_TEMPERATURE_MASK (1 << 21) -# define R200_WRAPEN_S (1 << 22) -# define R200_CLAMP_S_WRAP (0 << 23) -# define R200_CLAMP_S_MIRROR (1 << 23) -# define R200_CLAMP_S_CLAMP_LAST (2 << 23) -# define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) -# define R200_CLAMP_S_CLAMP_BORDER (4 << 23) -# define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) -# define R200_CLAMP_S_CLAMP_GL (6 << 23) -# define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) -# define R200_CLAMP_S_MASK (7 << 23) -# define R200_WRAPEN_T (1 << 26) -# define R200_CLAMP_T_WRAP (0 << 27) -# define R200_CLAMP_T_MIRROR (1 << 27) -# define R200_CLAMP_T_CLAMP_LAST (2 << 27) -# define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) -# define R200_CLAMP_T_CLAMP_BORDER (4 << 27) -# define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) -# define R200_CLAMP_T_CLAMP_GL (6 << 27) -# define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) -# define R200_CLAMP_T_MASK (7 << 27) -# define R200_KILL_LT_ZERO (1 << 30) -# define R200_BORDER_MODE_OGL (0 << 31) -# define R200_BORDER_MODE_D3D (1 << 31) -#define R200_PP_TXFORMAT_0 0x2c04 -#define R200_PP_TXFORMAT_1 0x2c24 -#define R200_PP_TXFORMAT_2 0x2c44 -#define R200_PP_TXFORMAT_3 0x2c64 -#define R200_PP_TXFORMAT_4 0x2c84 -#define R200_PP_TXFORMAT_5 0x2ca4 -# define R200_TXFORMAT_I8 (0 << 0) -# define R200_TXFORMAT_AI88 (1 << 0) -# define R200_TXFORMAT_RGB332 (2 << 0) -# define R200_TXFORMAT_ARGB1555 (3 << 0) -# define R200_TXFORMAT_RGB565 (4 << 0) -# define R200_TXFORMAT_ARGB4444 (5 << 0) -# define R200_TXFORMAT_ARGB8888 (6 << 0) -# define R200_TXFORMAT_RGBA8888 (7 << 0) -# define R200_TXFORMAT_Y8 (8 << 0) -# define R200_TXFORMAT_AVYU4444 (9 << 0) -# define R200_TXFORMAT_VYUY422 (10 << 0) -# define R200_TXFORMAT_YVYU422 (11 << 0) -# define R200_TXFORMAT_DXT1 (12 << 0) -# define R200_TXFORMAT_DXT23 (14 << 0) -# define R200_TXFORMAT_DXT45 (15 << 0) -# define R200_TXFORMAT_DVDU88 (18 << 0) -# define R200_TXFORMAT_LDVDU655 (19 << 0) -# define R200_TXFORMAT_LDVDU8888 (20 << 0) -# define R200_TXFORMAT_GR1616 (21 << 0) -# define R200_TXFORMAT_ABGR8888 (22 << 0) -# define R200_TXFORMAT_BGR111110 (23 << 0) -# define R200_TXFORMAT_FORMAT_MASK (31 << 0) -# define R200_TXFORMAT_FORMAT_SHIFT 0 -# define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) -# define R200_TXFORMAT_NON_POWER2 (1 << 7) -# define R200_TXFORMAT_WIDTH_MASK (15 << 8) -# define R200_TXFORMAT_WIDTH_SHIFT 8 -# define R200_TXFORMAT_HEIGHT_MASK (15 << 12) -# define R200_TXFORMAT_HEIGHT_SHIFT 12 -# define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */ -# define R200_TXFORMAT_F5_WIDTH_SHIFT 16 -# define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) -# define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 -# define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) -# define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) -# define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) -# define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) -# define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) -# define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) -# define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) -# define R200_TXFORMAT_ST_ROUTE_SHIFT 24 -# define R200_TXFORMAT_LOOKUP_DISABLE (1 << 27) -# define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) -# define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) -# define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) -#define R200_PP_TXFORMAT_X_0 0x2c08 -#define R200_PP_TXFORMAT_X_1 0x2c28 -#define R200_PP_TXFORMAT_X_2 0x2c48 -#define R200_PP_TXFORMAT_X_3 0x2c68 -#define R200_PP_TXFORMAT_X_4 0x2c88 -#define R200_PP_TXFORMAT_X_5 0x2ca8 - -#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ -#define R200_PP_TXSIZE_1 0x2c2c /* NPOT only */ -#define R200_PP_TXSIZE_2 0x2c4c /* NPOT only */ -#define R200_PP_TXSIZE_3 0x2c6c /* NPOT only */ -#define R200_PP_TXSIZE_4 0x2c8c /* NPOT only */ -#define R200_PP_TXSIZE_5 0x2cac /* NPOT only */ - -#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ -#define R200_PP_TXPITCH_1 0x2c30 /* NPOT only */ -#define R200_PP_TXPITCH_2 0x2c50 /* NPOT only */ -#define R200_PP_TXPITCH_3 0x2c70 /* NPOT only */ -#define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */ -#define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */ - -#define R200_PP_CUBIC_FACES_0 0x2c18 -#define R200_PP_CUBIC_FACES_1 0x2c38 -#define R200_PP_CUBIC_FACES_2 0x2c58 -#define R200_PP_CUBIC_FACES_3 0x2c78 -#define R200_PP_CUBIC_FACES_4 0x2c98 -#define R200_PP_CUBIC_FACES_5 0x2cb8 - -#define R200_PP_TXOFFSET_0 0x2d00 -# define R200_TXO_ENDIAN_NO_SWAP (0 << 0) -# define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) -# define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) -# define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -# define R200_TXO_MACRO_LINEAR (0 << 2) -# define R200_TXO_MACRO_TILE (1 << 2) -# define R200_TXO_MICRO_LINEAR (0 << 3) -# define R200_TXO_MICRO_TILE (1 << 3) -# define R200_TXO_OFFSET_MASK 0xffffffe0 -# define R200_TXO_OFFSET_SHIFT 5 -#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 - -#define R200_PP_TXOFFSET_1 0x2d18 -#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c - -#define R200_PP_TXOFFSET_2 0x2d30 -#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 - -#define R200_PP_TXOFFSET_3 0x2d48 -#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c -#define R200_PP_TXOFFSET_4 0x2d60 -#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 -#define R200_PP_TXOFFSET_5 0x2d78 -#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c - -#define R200_PP_TFACTOR_0 0x2ee0 -#define R200_PP_TFACTOR_1 0x2ee4 -#define R200_PP_TFACTOR_2 0x2ee8 -#define R200_PP_TFACTOR_3 0x2eec -#define R200_PP_TFACTOR_4 0x2ef0 -#define R200_PP_TFACTOR_5 0x2ef4 - -#define R200_PP_TXCBLEND_0 0x2f00 -# define R200_TXC_ARG_A_ZERO (0) -# define R200_TXC_ARG_A_CURRENT_COLOR (2) -# define R200_TXC_ARG_A_CURRENT_ALPHA (3) -# define R200_TXC_ARG_A_DIFFUSE_COLOR (4) -# define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) -# define R200_TXC_ARG_A_SPECULAR_COLOR (6) -# define R200_TXC_ARG_A_SPECULAR_ALPHA (7) -# define R200_TXC_ARG_A_TFACTOR_COLOR (8) -# define R200_TXC_ARG_A_TFACTOR_ALPHA (9) -# define R200_TXC_ARG_A_R0_COLOR (10) -# define R200_TXC_ARG_A_R0_ALPHA (11) -# define R200_TXC_ARG_A_R1_COLOR (12) -# define R200_TXC_ARG_A_R1_ALPHA (13) -# define R200_TXC_ARG_A_R2_COLOR (14) -# define R200_TXC_ARG_A_R2_ALPHA (15) -# define R200_TXC_ARG_A_R3_COLOR (16) -# define R200_TXC_ARG_A_R3_ALPHA (17) -# define R200_TXC_ARG_A_R4_COLOR (18) -# define R200_TXC_ARG_A_R4_ALPHA (19) -# define R200_TXC_ARG_A_R5_COLOR (20) -# define R200_TXC_ARG_A_R5_ALPHA (21) -# define R200_TXC_ARG_A_TFACTOR1_COLOR (26) -# define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) -# define R200_TXC_ARG_A_MASK (31 << 0) -# define R200_TXC_ARG_A_SHIFT 0 -# define R200_TXC_ARG_B_ZERO (0 << 5) -# define R200_TXC_ARG_B_CURRENT_COLOR (2 << 5) -# define R200_TXC_ARG_B_CURRENT_ALPHA (3 << 5) -# define R200_TXC_ARG_B_DIFFUSE_COLOR (4 << 5) -# define R200_TXC_ARG_B_DIFFUSE_ALPHA (5 << 5) -# define R200_TXC_ARG_B_SPECULAR_COLOR (6 << 5) -# define R200_TXC_ARG_B_SPECULAR_ALPHA (7 << 5) -# define R200_TXC_ARG_B_TFACTOR_COLOR (8 << 5) -# define R200_TXC_ARG_B_TFACTOR_ALPHA (9 << 5) -# define R200_TXC_ARG_B_R0_COLOR (10 << 5) -# define R200_TXC_ARG_B_R0_ALPHA (11 << 5) -# define R200_TXC_ARG_B_R1_COLOR (12 << 5) -# define R200_TXC_ARG_B_R1_ALPHA (13 << 5) -# define R200_TXC_ARG_B_R2_COLOR (14 << 5) -# define R200_TXC_ARG_B_R2_ALPHA (15 << 5) -# define R200_TXC_ARG_B_R3_COLOR (16 << 5) -# define R200_TXC_ARG_B_R3_ALPHA (17 << 5) -# define R200_TXC_ARG_B_R4_COLOR (18 << 5) -# define R200_TXC_ARG_B_R4_ALPHA (19 << 5) -# define R200_TXC_ARG_B_R5_COLOR (20 << 5) -# define R200_TXC_ARG_B_R5_ALPHA (21 << 5) -# define R200_TXC_ARG_B_TFACTOR1_COLOR (26 << 5) -# define R200_TXC_ARG_B_TFACTOR1_ALPHA (27 << 5) -# define R200_TXC_ARG_B_MASK (31 << 5) -# define R200_TXC_ARG_B_SHIFT 5 -# define R200_TXC_ARG_C_ZERO (0 << 10) -# define R200_TXC_ARG_C_CURRENT_COLOR (2 << 10) -# define R200_TXC_ARG_C_CURRENT_ALPHA (3 << 10) -# define R200_TXC_ARG_C_DIFFUSE_COLOR (4 << 10) -# define R200_TXC_ARG_C_DIFFUSE_ALPHA (5 << 10) -# define R200_TXC_ARG_C_SPECULAR_COLOR (6 << 10) -# define R200_TXC_ARG_C_SPECULAR_ALPHA (7 << 10) -# define R200_TXC_ARG_C_TFACTOR_COLOR (8 << 10) -# define R200_TXC_ARG_C_TFACTOR_ALPHA (9 << 10) -# define R200_TXC_ARG_C_R0_COLOR (10 << 10) -# define R200_TXC_ARG_C_R0_ALPHA (11 << 10) -# define R200_TXC_ARG_C_R1_COLOR (12 << 10) -# define R200_TXC_ARG_C_R1_ALPHA (13 << 10) -# define R200_TXC_ARG_C_R2_COLOR (14 << 10) -# define R200_TXC_ARG_C_R2_ALPHA (15 << 10) -# define R200_TXC_ARG_C_R3_COLOR (16 << 10) -# define R200_TXC_ARG_C_R3_ALPHA (17 << 10) -# define R200_TXC_ARG_C_R4_COLOR (18 << 10) -# define R200_TXC_ARG_C_R4_ALPHA (19 << 10) -# define R200_TXC_ARG_C_R5_COLOR (20 << 10) -# define R200_TXC_ARG_C_R5_ALPHA (21 << 10) -# define R200_TXC_ARG_C_TFACTOR1_COLOR (26 << 10) -# define R200_TXC_ARG_C_TFACTOR1_ALPHA (27 << 10) -# define R200_TXC_ARG_C_MASK (31 << 10) -# define R200_TXC_ARG_C_SHIFT 10 -# define R200_TXC_COMP_ARG_A (1 << 16) -# define R200_TXC_COMP_ARG_A_SHIFT (16) -# define R200_TXC_BIAS_ARG_A (1 << 17) -# define R200_TXC_SCALE_ARG_A (1 << 18) -# define R200_TXC_NEG_ARG_A (1 << 19) -# define R200_TXC_COMP_ARG_B (1 << 20) -# define R200_TXC_COMP_ARG_B_SHIFT (20) -# define R200_TXC_BIAS_ARG_B (1 << 21) -# define R200_TXC_SCALE_ARG_B (1 << 22) -# define R200_TXC_NEG_ARG_B (1 << 23) -# define R200_TXC_COMP_ARG_C (1 << 24) -# define R200_TXC_COMP_ARG_C_SHIFT (24) -# define R200_TXC_BIAS_ARG_C (1 << 25) -# define R200_TXC_SCALE_ARG_C (1 << 26) -# define R200_TXC_NEG_ARG_C (1 << 27) -# define R200_TXC_OP_MADD (0 << 28) -# define R200_TXC_OP_CND0 (2 << 28) -# define R200_TXC_OP_LERP (3 << 28) -# define R200_TXC_OP_DOT3 (4 << 28) -# define R200_TXC_OP_DOT4 (5 << 28) -# define R200_TXC_OP_CONDITIONAL (6 << 28) -# define R200_TXC_OP_DOT2_ADD (7 << 28) -# define R200_TXC_OP_MASK (7 << 28) -#define R200_PP_TXCBLEND2_0 0x2f04 -# define R200_TXC_TFACTOR_SEL_SHIFT 0 -# define R200_TXC_TFACTOR_SEL_MASK 0x7 -# define R200_TXC_TFACTOR1_SEL_SHIFT 4 -# define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) -# define R200_TXC_SCALE_SHIFT 8 -# define R200_TXC_SCALE_MASK (7 << 8) -# define R200_TXC_SCALE_1X (0 << 8) -# define R200_TXC_SCALE_2X (1 << 8) -# define R200_TXC_SCALE_4X (2 << 8) -# define R200_TXC_SCALE_8X (3 << 8) -# define R200_TXC_SCALE_INV2 (5 << 8) -# define R200_TXC_SCALE_INV4 (6 << 8) -# define R200_TXC_SCALE_INV8 (7 << 8) -# define R200_TXC_CLAMP_SHIFT 12 -# define R200_TXC_CLAMP_MASK (3 << 12) -# define R200_TXC_CLAMP_WRAP (0 << 12) -# define R200_TXC_CLAMP_0_1 (1 << 12) -# define R200_TXC_CLAMP_8_8 (2 << 12) -# define R200_TXC_OUTPUT_REG_MASK (7 << 16) -# define R200_TXC_OUTPUT_REG_NONE (0 << 16) -# define R200_TXC_OUTPUT_REG_R0 (1 << 16) -# define R200_TXC_OUTPUT_REG_R1 (2 << 16) -# define R200_TXC_OUTPUT_REG_R2 (3 << 16) -# define R200_TXC_OUTPUT_REG_R3 (4 << 16) -# define R200_TXC_OUTPUT_REG_R4 (5 << 16) -# define R200_TXC_OUTPUT_REG_R5 (6 << 16) -# define R200_TXC_OUTPUT_MASK_MASK (7 << 20) -# define R200_TXC_OUTPUT_MASK_RGB (0 << 20) -# define R200_TXC_OUTPUT_MASK_RG (1 << 20) -# define R200_TXC_OUTPUT_MASK_RB (2 << 20) -# define R200_TXC_OUTPUT_MASK_R (3 << 20) -# define R200_TXC_OUTPUT_MASK_GB (4 << 20) -# define R200_TXC_OUTPUT_MASK_G (5 << 20) -# define R200_TXC_OUTPUT_MASK_B (6 << 20) -# define R200_TXC_OUTPUT_MASK_NONE (7 << 20) -# define R200_TXC_REPL_NORMAL 0 -# define R200_TXC_REPL_RED 1 -# define R200_TXC_REPL_GREEN 2 -# define R200_TXC_REPL_BLUE 3 -# define R200_TXC_REPL_ARG_A_SHIFT 26 -# define R200_TXC_REPL_ARG_A_MASK (3 << 26) -# define R200_TXC_REPL_ARG_B_SHIFT 28 -# define R200_TXC_REPL_ARG_B_MASK (3 << 28) -# define R200_TXC_REPL_ARG_C_SHIFT 30 -# define R200_TXC_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXABLEND_0 0x2f08 -# define R200_TXA_ARG_A_ZERO (0) -# define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ -# define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ -# define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) -# define R200_TXA_ARG_A_DIFFUSE_BLUE (5) -# define R200_TXA_ARG_A_SPECULAR_ALPHA (6) -# define R200_TXA_ARG_A_SPECULAR_BLUE (7) -# define R200_TXA_ARG_A_TFACTOR_ALPHA (8) -# define R200_TXA_ARG_A_TFACTOR_BLUE (9) -# define R200_TXA_ARG_A_R0_ALPHA (10) -# define R200_TXA_ARG_A_R0_BLUE (11) -# define R200_TXA_ARG_A_R1_ALPHA (12) -# define R200_TXA_ARG_A_R1_BLUE (13) -# define R200_TXA_ARG_A_R2_ALPHA (14) -# define R200_TXA_ARG_A_R2_BLUE (15) -# define R200_TXA_ARG_A_R3_ALPHA (16) -# define R200_TXA_ARG_A_R3_BLUE (17) -# define R200_TXA_ARG_A_R4_ALPHA (18) -# define R200_TXA_ARG_A_R4_BLUE (19) -# define R200_TXA_ARG_A_R5_ALPHA (20) -# define R200_TXA_ARG_A_R5_BLUE (21) -# define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) -# define R200_TXA_ARG_A_TFACTOR1_BLUE (27) -# define R200_TXA_ARG_A_MASK (31 << 0) -# define R200_TXA_ARG_A_SHIFT 0 -# define R200_TXA_ARG_B_ZERO (0 << 5) -# define R200_TXA_ARG_B_CURRENT_ALPHA (2 << 5) /* guess */ -# define R200_TXA_ARG_B_CURRENT_BLUE (3 << 5) /* guess */ -# define R200_TXA_ARG_B_DIFFUSE_ALPHA (4 << 5) -# define R200_TXA_ARG_B_DIFFUSE_BLUE (5 << 5) -# define R200_TXA_ARG_B_SPECULAR_ALPHA (6 << 5) -# define R200_TXA_ARG_B_SPECULAR_BLUE (7 << 5) -# define R200_TXA_ARG_B_TFACTOR_ALPHA (8 << 5) -# define R200_TXA_ARG_B_TFACTOR_BLUE (9 << 5) -# define R200_TXA_ARG_B_R0_ALPHA (10 << 5) -# define R200_TXA_ARG_B_R0_BLUE (11 << 5) -# define R200_TXA_ARG_B_R1_ALPHA (12 << 5) -# define R200_TXA_ARG_B_R1_BLUE (13 << 5) -# define R200_TXA_ARG_B_R2_ALPHA (14 << 5) -# define R200_TXA_ARG_B_R2_BLUE (15 << 5) -# define R200_TXA_ARG_B_R3_ALPHA (16 << 5) -# define R200_TXA_ARG_B_R3_BLUE (17 << 5) -# define R200_TXA_ARG_B_R4_ALPHA (18 << 5) -# define R200_TXA_ARG_B_R4_BLUE (19 << 5) -# define R200_TXA_ARG_B_R5_ALPHA (20 << 5) -# define R200_TXA_ARG_B_R5_BLUE (21 << 5) -# define R200_TXA_ARG_B_TFACTOR1_ALPHA (26 << 5) -# define R200_TXA_ARG_B_TFACTOR1_BLUE (27 << 5) -# define R200_TXA_ARG_B_MASK (31 << 5) -# define R200_TXA_ARG_B_SHIFT 5 -# define R200_TXA_ARG_C_ZERO (0 << 10) -# define R200_TXA_ARG_C_CURRENT_ALPHA (2 << 10) /* guess */ -# define R200_TXA_ARG_C_CURRENT_BLUE (3 << 10) /* guess */ -# define R200_TXA_ARG_C_DIFFUSE_ALPHA (4 << 10) -# define R200_TXA_ARG_C_DIFFUSE_BLUE (5 << 10) -# define R200_TXA_ARG_C_SPECULAR_ALPHA (6 << 10) -# define R200_TXA_ARG_C_SPECULAR_BLUE (7 << 10) -# define R200_TXA_ARG_C_TFACTOR_ALPHA (8 << 10) -# define R200_TXA_ARG_C_TFACTOR_BLUE (9 << 10) -# define R200_TXA_ARG_C_R0_ALPHA (10 << 10) -# define R200_TXA_ARG_C_R0_BLUE (11 << 10) -# define R200_TXA_ARG_C_R1_ALPHA (12 << 10) -# define R200_TXA_ARG_C_R1_BLUE (13 << 10) -# define R200_TXA_ARG_C_R2_ALPHA (14 << 10) -# define R200_TXA_ARG_C_R2_BLUE (15 << 10) -# define R200_TXA_ARG_C_R3_ALPHA (16 << 10) -# define R200_TXA_ARG_C_R3_BLUE (17 << 10) -# define R200_TXA_ARG_C_R4_ALPHA (18 << 10) -# define R200_TXA_ARG_C_R4_BLUE (19 << 10) -# define R200_TXA_ARG_C_R5_ALPHA (20 << 10) -# define R200_TXA_ARG_C_R5_BLUE (21 << 10) -# define R200_TXA_ARG_C_TFACTOR1_ALPHA (26 << 10) -# define R200_TXA_ARG_C_TFACTOR1_BLUE (27 << 10) -# define R200_TXA_ARG_C_MASK (31 << 10) -# define R200_TXA_ARG_C_SHIFT 10 -# define R200_TXA_COMP_ARG_A (1 << 16) -# define R200_TXA_COMP_ARG_A_SHIFT (16) -# define R200_TXA_BIAS_ARG_A (1 << 17) -# define R200_TXA_SCALE_ARG_A (1 << 18) -# define R200_TXA_NEG_ARG_A (1 << 19) -# define R200_TXA_COMP_ARG_B (1 << 20) -# define R200_TXA_COMP_ARG_B_SHIFT (20) -# define R200_TXA_BIAS_ARG_B (1 << 21) -# define R200_TXA_SCALE_ARG_B (1 << 22) -# define R200_TXA_NEG_ARG_B (1 << 23) -# define R200_TXA_COMP_ARG_C (1 << 24) -# define R200_TXA_COMP_ARG_C_SHIFT (24) -# define R200_TXA_BIAS_ARG_C (1 << 25) -# define R200_TXA_SCALE_ARG_C (1 << 26) -# define R200_TXA_NEG_ARG_C (1 << 27) -# define R200_TXA_OP_MADD (0 << 28) -# define R200_TXA_OP_CND0 (2 << 28) -# define R200_TXA_OP_LERP (3 << 28) -# define R200_TXA_OP_CONDITIONAL (6 << 28) -# define R200_TXA_OP_MASK (7 << 28) -#define R200_PP_TXABLEND2_0 0x2f0c -# define R200_TXA_TFACTOR_SEL_SHIFT 0 -# define R200_TXA_TFACTOR_SEL_MASK 0x7 -# define R200_TXA_TFACTOR1_SEL_SHIFT 4 -# define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) -# define R200_TXA_SCALE_SHIFT 8 -# define R200_TXA_SCALE_MASK (7 << 8) -# define R200_TXA_SCALE_1X (0 << 8) -# define R200_TXA_SCALE_2X (1 << 8) -# define R200_TXA_SCALE_4X (2 << 8) -# define R200_TXA_SCALE_8X (3 << 8) -# define R200_TXA_SCALE_INV2 (5 << 8) -# define R200_TXA_SCALE_INV4 (6 << 8) -# define R200_TXA_SCALE_INV8 (7 << 8) -# define R200_TXA_CLAMP_SHIFT 12 -# define R200_TXA_CLAMP_MASK (3 << 12) -# define R200_TXA_CLAMP_WRAP (0 << 12) -# define R200_TXA_CLAMP_0_1 (1 << 12) -# define R200_TXA_CLAMP_8_8 (2 << 12) -# define R200_TXA_OUTPUT_REG_MASK (7 << 16) -# define R200_TXA_OUTPUT_REG_NONE (0 << 16) -# define R200_TXA_OUTPUT_REG_R0 (1 << 16) -# define R200_TXA_OUTPUT_REG_R1 (2 << 16) -# define R200_TXA_OUTPUT_REG_R2 (3 << 16) -# define R200_TXA_OUTPUT_REG_R3 (4 << 16) -# define R200_TXA_OUTPUT_REG_R4 (5 << 16) -# define R200_TXA_OUTPUT_REG_R5 (6 << 16) -# define R200_TXA_DOT_ALPHA (1 << 20) -# define R200_TXA_REPL_NORMAL 0 -# define R200_TXA_REPL_RED 1 -# define R200_TXA_REPL_GREEN 2 -# define R200_TXA_REPL_ARG_A_SHIFT 26 -# define R200_TXA_REPL_ARG_A_MASK (3 << 26) -# define R200_TXA_REPL_ARG_B_SHIFT 28 -# define R200_TXA_REPL_ARG_B_MASK (3 << 28) -# define R200_TXA_REPL_ARG_C_SHIFT 30 -# define R200_TXA_REPL_ARG_C_MASK (3 << 30) - -#define R200_SE_VTX_FMT_0 0x2088 -# define R200_VTX_XY 0 /* always have xy */ -# define R200_VTX_Z0 (1<<0) -# define R200_VTX_W0 (1<<1) -# define R200_VTX_WEIGHT_COUNT_SHIFT (2) -# define R200_VTX_PV_MATRIX_SEL (1<<5) -# define R200_VTX_N0 (1<<6) -# define R200_VTX_POINT_SIZE (1<<7) -# define R200_VTX_DISCRETE_FOG (1<<8) -# define R200_VTX_SHININESS_0 (1<<9) -# define R200_VTX_SHININESS_1 (1<<10) -# define R200_VTX_COLOR_NOT_PRESENT 0 -# define R200_VTX_PK_RGBA 1 -# define R200_VTX_FP_RGB 2 -# define R200_VTX_FP_RGBA 3 -# define R200_VTX_COLOR_MASK 3 -# define R200_VTX_COLOR_0_SHIFT 11 -# define R200_VTX_COLOR_1_SHIFT 13 -# define R200_VTX_COLOR_2_SHIFT 15 -# define R200_VTX_COLOR_3_SHIFT 17 -# define R200_VTX_COLOR_4_SHIFT 19 -# define R200_VTX_COLOR_5_SHIFT 21 -# define R200_VTX_COLOR_6_SHIFT 23 -# define R200_VTX_COLOR_7_SHIFT 25 -# define R200_VTX_XY1 (1<<28) -# define R200_VTX_Z1 (1<<29) -# define R200_VTX_W1 (1<<30) -# define R200_VTX_N1 (1<<31) -#define R200_SE_VTX_FMT_1 0x208c -# define R200_VTX_TEX0_COMP_CNT_SHIFT 0 -# define R200_VTX_TEX1_COMP_CNT_SHIFT 3 -# define R200_VTX_TEX2_COMP_CNT_SHIFT 6 -# define R200_VTX_TEX3_COMP_CNT_SHIFT 9 -# define R200_VTX_TEX4_COMP_CNT_SHIFT 12 -# define R200_VTX_TEX5_COMP_CNT_SHIFT 15 - -#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 -#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 -#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 -# define R200_OUTPUT_XYZW (1<<0) -# define R200_OUTPUT_COLOR_0 (1<<8) -# define R200_OUTPUT_COLOR_1 (1<<9) -# define R200_OUTPUT_TEX_0 (1<<16) -# define R200_OUTPUT_TEX_1 (1<<17) -# define R200_OUTPUT_TEX_2 (1<<18) -# define R200_OUTPUT_TEX_3 (1<<19) -# define R200_OUTPUT_TEX_4 (1<<20) -# define R200_OUTPUT_TEX_5 (1<<21) -# define R200_OUTPUT_TEX_MASK (0x3f<<16) -# define R200_OUTPUT_DISCRETE_FOG (1<<24) -# define R200_OUTPUT_PT_SIZE (1<<25) -# define R200_FORCE_INORDER_PROC (1<<31) -#define R200_PP_CNTL_X 0x2cc4 -#define R200_PP_TXMULTI_CTL_0 0x2c1c -#define R200_PP_TXMULTI_CTL_1 0x2c3c -#define R200_PP_TXMULTI_CTL_2 0x2c5c -#define R200_PP_TXMULTI_CTL_3 0x2c7c -#define R200_PP_TXMULTI_CTL_4 0x2c9c -#define R200_PP_TXMULTI_CTL_5 0x2cbc -#define R200_SE_VTX_STATE_CNTL 0x2180 -# define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16) - - /* Registers for CP and Microcode Engine */ -#define RADEON_CP_ME_RAM_ADDR 0x07d4 -#define RADEON_CP_ME_RAM_RADDR 0x07d8 -#define RADEON_CP_ME_RAM_DATAH 0x07dc -#define RADEON_CP_ME_RAM_DATAL 0x07e0 - -#define RADEON_CP_RB_BASE 0x0700 -#define RADEON_CP_RB_CNTL 0x0704 -# define RADEON_RB_BUFSZ_SHIFT 0 -# define RADEON_RB_BUFSZ_MASK (0x3f << 0) -# define RADEON_RB_BLKSZ_SHIFT 8 -# define RADEON_RB_BLKSZ_MASK (0x3f << 8) -# define RADEON_BUF_SWAP_32BIT (2 << 16) -# define RADEON_MAX_FETCH_SHIFT 18 -# define RADEON_MAX_FETCH_MASK (0x3 << 18) -# define RADEON_RB_NO_UPDATE (1 << 27) -# define RADEON_RB_RPTR_WR_ENA (1 << 31) -#define RADEON_CP_RB_RPTR_ADDR 0x070c -#define RADEON_CP_RB_RPTR 0x0710 -#define RADEON_CP_RB_WPTR 0x0714 -#define RADEON_CP_RB_RPTR_WR 0x071c - -#define RADEON_SCRATCH_UMSK 0x0770 -#define RADEON_SCRATCH_ADDR 0x0774 - -#define R600_CP_RB_BASE 0xc100 -#define R600_CP_RB_CNTL 0xc104 -# define R600_RB_BUFSZ(x) ((x) << 0) -# define R600_RB_BLKSZ(x) ((x) << 8) -# define R600_RB_NO_UPDATE (1 << 27) -# define R600_RB_RPTR_WR_ENA (1 << 31) -#define R600_CP_RB_RPTR_WR 0xc108 -#define R600_CP_RB_RPTR_ADDR 0xc10c -#define R600_CP_RB_RPTR_ADDR_HI 0xc110 -#define R600_CP_RB_WPTR 0xc114 -#define R600_CP_RB_WPTR_ADDR 0xc118 -#define R600_CP_RB_WPTR_ADDR_HI 0xc11c -#define R600_CP_RB_RPTR 0x8700 -#define R600_CP_RB_WPTR_DELAY 0x8704 - -#define RADEON_CP_IB_BASE 0x0738 -#define RADEON_CP_IB_BUFSZ 0x073c - -#define RADEON_CP_CSQ_CNTL 0x0740 -# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) -# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) -# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) -# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) -# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) -# define RADEON_CSQ_PRIBM_INDBM (4 << 28) -# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) - -#define R300_CP_RESYNC_ADDR 0x778 -#define R300_CP_RESYNC_DATA 0x77c - -#define RADEON_CP_CSQ_STAT 0x07f8 -# define RADEON_CSQ_RPTR_PRIMARY_MASK (0xff << 0) -# define RADEON_CSQ_WPTR_PRIMARY_MASK (0xff << 8) -# define RADEON_CSQ_RPTR_INDIRECT_MASK (0xff << 16) -# define RADEON_CSQ_WPTR_INDIRECT_MASK (0xff << 24) -#define RADEON_CP_CSQ2_STAT 0x07fc -#define RADEON_CP_CSQ_ADDR 0x07f0 -#define RADEON_CP_CSQ_DATA 0x07f4 -#define RADEON_CP_CSQ_APER_PRIMARY 0x1000 -#define RADEON_CP_CSQ_APER_INDIRECT 0x1300 - -#define RADEON_CP_RB_WPTR_DELAY 0x0718 -# define RADEON_PRE_WRITE_TIMER_SHIFT 0 -# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 -#define RADEON_CP_CSQ_MODE 0x0744 -# define RADEON_INDIRECT2_START_SHIFT 0 -# define RADEON_INDIRECT2_START_MASK (0x7f << 0) -# define RADEON_INDIRECT1_START_SHIFT 8 -# define RADEON_INDIRECT1_START_MASK (0x7f << 8) - -#define RADEON_AIC_CNTL 0x01d0 -# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -# define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) -# define RS400_MSI_REARM (1 << 3) /* rs400/rs480 */ -#define RADEON_AIC_LO_ADDR 0x01dc -#define RADEON_AIC_PT_BASE 0x01d8 -#define RADEON_AIC_HI_ADDR 0x01e0 - - - - /* Constants */ -/* #define RADEON_LAST_FRAME_REG RADEON_GUI_SCRATCH_REG0 */ -/* efine RADEON_LAST_CLEAR_REG RADEON_GUI_SCRATCH_REG2 */ - - - - /* CP packet types */ -#define RADEON_CP_PACKET0 0x00000000 -#define RADEON_CP_PACKET1 0x40000000 -#define RADEON_CP_PACKET2 0x80000000 -#define RADEON_CP_PACKET3 0xC0000000 -# define RADEON_CP_PACKET_MASK 0xC0000000 -# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 -# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) -# define RADEON_CP_PACKET0_REG_MASK 0x000007ff -# define R300_CP_PACKET0_REG_MASK 0x00001fff -# define R600_CP_PACKET0_REG_MASK 0x0000ffff -# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff -# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 - -#define RADEON_CP_PACKET0_ONE_REG_WR 0x00008000 - -#define RADEON_CP_PACKET3_NOP 0xC0001000 -#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 -#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 -#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 -#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 -#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 -#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 -#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 -#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 -#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 -#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 -#define R200_CP_PACKET3_3D_DRAW_IMMD_2 0xc0003500 -#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 -#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 -#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 -#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 -#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 -#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 -#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 -#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 -#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 -#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 - - -#define RADEON_CP_VC_FRMT_XY 0x00000000 -#define RADEON_CP_VC_FRMT_W0 0x00000001 -#define RADEON_CP_VC_FRMT_FPCOLOR 0x00000002 -#define RADEON_CP_VC_FRMT_FPALPHA 0x00000004 -#define RADEON_CP_VC_FRMT_PKCOLOR 0x00000008 -#define RADEON_CP_VC_FRMT_FPSPEC 0x00000010 -#define RADEON_CP_VC_FRMT_FPFOG 0x00000020 -#define RADEON_CP_VC_FRMT_PKSPEC 0x00000040 -#define RADEON_CP_VC_FRMT_ST0 0x00000080 -#define RADEON_CP_VC_FRMT_ST1 0x00000100 -#define RADEON_CP_VC_FRMT_Q1 0x00000200 -#define RADEON_CP_VC_FRMT_ST2 0x00000400 -#define RADEON_CP_VC_FRMT_Q2 0x00000800 -#define RADEON_CP_VC_FRMT_ST3 0x00001000 -#define RADEON_CP_VC_FRMT_Q3 0x00002000 -#define RADEON_CP_VC_FRMT_Q0 0x00004000 -#define RADEON_CP_VC_FRMT_BLND_WEIGHT_CNT_MASK 0x00038000 -#define RADEON_CP_VC_FRMT_N0 0x00040000 -#define RADEON_CP_VC_FRMT_XY1 0x08000000 -#define RADEON_CP_VC_FRMT_Z1 0x10000000 -#define RADEON_CP_VC_FRMT_W1 0x20000000 -#define RADEON_CP_VC_FRMT_N1 0x40000000 -#define RADEON_CP_VC_FRMT_Z 0x80000000 - -#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2 0x00000007 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 -#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a -#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 -#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 -#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 -#define RADEON_CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 -#define RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 -#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080 -#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000 -#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100 -#define RADEON_CP_VC_CNTL_TCL_DISABLE 0x00000000 -#define RADEON_CP_VC_CNTL_TCL_ENABLE 0x00000200 -#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 - -#define RADEON_VS_MATRIX_0_ADDR 0 -#define RADEON_VS_MATRIX_1_ADDR 4 -#define RADEON_VS_MATRIX_2_ADDR 8 -#define RADEON_VS_MATRIX_3_ADDR 12 -#define RADEON_VS_MATRIX_4_ADDR 16 -#define RADEON_VS_MATRIX_5_ADDR 20 -#define RADEON_VS_MATRIX_6_ADDR 24 -#define RADEON_VS_MATRIX_7_ADDR 28 -#define RADEON_VS_MATRIX_8_ADDR 32 -#define RADEON_VS_MATRIX_9_ADDR 36 -#define RADEON_VS_MATRIX_10_ADDR 40 -#define RADEON_VS_MATRIX_11_ADDR 44 -#define RADEON_VS_MATRIX_12_ADDR 48 -#define RADEON_VS_MATRIX_13_ADDR 52 -#define RADEON_VS_MATRIX_14_ADDR 56 -#define RADEON_VS_MATRIX_15_ADDR 60 -#define RADEON_VS_LIGHT_AMBIENT_ADDR 64 -#define RADEON_VS_LIGHT_DIFFUSE_ADDR 72 -#define RADEON_VS_LIGHT_SPECULAR_ADDR 80 -#define RADEON_VS_LIGHT_DIRPOS_ADDR 88 -#define RADEON_VS_LIGHT_HWVSPOT_ADDR 96 -#define RADEON_VS_LIGHT_ATTENUATION_ADDR 104 -#define RADEON_VS_MATRIX_EYE2CLIP_ADDR 112 -#define RADEON_VS_UCP_ADDR 116 -#define RADEON_VS_GLOBAL_AMBIENT_ADDR 122 -#define RADEON_VS_FOG_PARAM_ADDR 123 -#define RADEON_VS_EYE_VECTOR_ADDR 124 - -#define RADEON_SS_LIGHT_DCD_ADDR 0 -#define RADEON_SS_LIGHT_SPOT_EXPONENT_ADDR 8 -#define RADEON_SS_LIGHT_SPOT_CUTOFF_ADDR 16 -#define RADEON_SS_LIGHT_SPECULAR_THRESH_ADDR 24 -#define RADEON_SS_LIGHT_RANGE_CUTOFF_ADDR 32 -#define RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR 48 -#define RADEON_SS_VERT_GUARD_DISCARD_ADJ_ADDR 49 -#define RADEON_SS_HORZ_GUARD_CLIP_ADJ_ADDR 50 -#define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 51 -#define RADEON_SS_SHININESS 60 - -#define RADEON_TV_MASTER_CNTL 0x0800 -# define RADEON_TV_ASYNC_RST (1 << 0) -# define RADEON_CRT_ASYNC_RST (1 << 1) -# define RADEON_RESTART_PHASE_FIX (1 << 3) -# define RADEON_TV_FIFO_ASYNC_RST (1 << 4) -# define RADEON_VIN_ASYNC_RST (1 << 5) -# define RADEON_AUD_ASYNC_RST (1 << 6) -# define RADEON_DVS_ASYNC_RST (1 << 7) -# define RADEON_CRT_FIFO_CE_EN (1 << 9) -# define RADEON_TV_FIFO_CE_EN (1 << 10) -# define RADEON_RE_SYNC_NOW_SEL_MASK (3 << 14) -# define RADEON_TVCLK_ALWAYS_ONb (1 << 30) -# define RADEON_TV_ON (1 << 31) -#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888 -# define RADEON_Y_RED_EN (1 << 0) -# define RADEON_C_GRN_EN (1 << 1) -# define RADEON_CMP_BLU_EN (1 << 2) -# define RADEON_DAC_DITHER_EN (1 << 3) -# define RADEON_RED_MX_FORCE_DAC_DATA (6 << 4) -# define RADEON_GRN_MX_FORCE_DAC_DATA (6 << 8) -# define RADEON_BLU_MX_FORCE_DAC_DATA (6 << 12) -# define RADEON_TV_FORCE_DAC_DATA_SHIFT 16 -#define RADEON_TV_RGB_CNTL 0x0804 -# define RADEON_SWITCH_TO_BLUE (1 << 4) -# define RADEON_RGB_DITHER_EN (1 << 5) -# define RADEON_RGB_SRC_SEL_MASK (3 << 8) -# define RADEON_RGB_SRC_SEL_CRTC1 (0 << 8) -# define RADEON_RGB_SRC_SEL_RMX (1 << 8) -# define RADEON_RGB_SRC_SEL_CRTC2 (2 << 8) -# define RADEON_RGB_CONVERT_BY_PASS (1 << 10) -# define RADEON_UVRAM_READ_MARGIN_SHIFT 16 -# define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20 -# define RADEON_RGB_ATTEN_SEL(x) ((x) << 24) -# define RADEON_TVOUT_SCALE_EN (1 << 26) -# define RADEON_RGB_ATTEN_VAL(x) ((x) << 28) -#define RADEON_TV_SYNC_CNTL 0x0808 -# define RADEON_SYNC_OE (1 << 0) -# define RADEON_SYNC_OUT (1 << 1) -# define RADEON_SYNC_IN (1 << 2) -# define RADEON_SYNC_PUB (1 << 3) -# define RADEON_SYNC_PD (1 << 4) -# define RADEON_TV_SYNC_IO_DRIVE (1 << 5) -#define RADEON_TV_HTOTAL 0x080c -#define RADEON_TV_HDISP 0x0810 -#define RADEON_TV_HSTART 0x0818 -#define RADEON_TV_HCOUNT 0x081C -#define RADEON_TV_VTOTAL 0x0820 -#define RADEON_TV_VDISP 0x0824 -#define RADEON_TV_VCOUNT 0x0828 -#define RADEON_TV_FTOTAL 0x082c -#define RADEON_TV_FCOUNT 0x0830 -#define RADEON_TV_FRESTART 0x0834 -#define RADEON_TV_HRESTART 0x0838 -#define RADEON_TV_VRESTART 0x083c -#define RADEON_TV_HOST_READ_DATA 0x0840 -#define RADEON_TV_HOST_WRITE_DATA 0x0844 -#define RADEON_TV_HOST_RD_WT_CNTL 0x0848 -# define RADEON_HOST_FIFO_RD (1 << 12) -# define RADEON_HOST_FIFO_RD_ACK (1 << 13) -# define RADEON_HOST_FIFO_WT (1 << 14) -# define RADEON_HOST_FIFO_WT_ACK (1 << 15) -#define RADEON_TV_VSCALER_CNTL1 0x084c -# define RADEON_UV_INC_MASK 0xffff -# define RADEON_UV_INC_SHIFT 0 -# define RADEON_Y_W_EN (1 << 24) -# define RADEON_RESTART_FIELD (1 << 29) /* restart on field 0 */ -# define RADEON_Y_DEL_W_SIG_SHIFT 26 -#define RADEON_TV_TIMING_CNTL 0x0850 -# define RADEON_H_INC_MASK 0xfff -# define RADEON_H_INC_SHIFT 0 -# define RADEON_REQ_Y_FIRST (1 << 19) -# define RADEON_FORCE_BURST_ALWAYS (1 << 21) -# define RADEON_UV_POST_SCALE_BYPASS (1 << 23) -# define RADEON_UV_OUTPUT_POST_SCALE_SHIFT 24 -#define RADEON_TV_VSCALER_CNTL2 0x0854 -# define RADEON_DITHER_MODE (1 << 0) -# define RADEON_Y_OUTPUT_DITHER_EN (1 << 1) -# define RADEON_UV_OUTPUT_DITHER_EN (1 << 2) -# define RADEON_UV_TO_BUF_DITHER_EN (1 << 3) -#define RADEON_TV_Y_FALL_CNTL 0x0858 -# define RADEON_Y_FALL_PING_PONG (1 << 16) -# define RADEON_Y_COEF_EN (1 << 17) -#define RADEON_TV_Y_RISE_CNTL 0x085c -# define RADEON_Y_RISE_PING_PONG (1 << 16) -#define RADEON_TV_Y_SAW_TOOTH_CNTL 0x0860 -#define RADEON_TV_UPSAMP_AND_GAIN_CNTL 0x0864 -# define RADEON_YUPSAMP_EN (1 << 0) -# define RADEON_UVUPSAMP_EN (1 << 2) -#define RADEON_TV_GAIN_LIMIT_SETTINGS 0x0868 -# define RADEON_Y_GAIN_LIMIT_SHIFT 0 -# define RADEON_UV_GAIN_LIMIT_SHIFT 16 -#define RADEON_TV_LINEAR_GAIN_SETTINGS 0x086c -# define RADEON_Y_GAIN_SHIFT 0 -# define RADEON_UV_GAIN_SHIFT 16 -#define RADEON_TV_MODULATOR_CNTL1 0x0870 -# define RADEON_YFLT_EN (1 << 2) -# define RADEON_UVFLT_EN (1 << 3) -# define RADEON_ALT_PHASE_EN (1 << 6) -# define RADEON_SYNC_TIP_LEVEL (1 << 7) -# define RADEON_BLANK_LEVEL_SHIFT 8 -# define RADEON_SET_UP_LEVEL_SHIFT 16 -# define RADEON_SLEW_RATE_LIMIT (1 << 23) -# define RADEON_CY_FILT_BLEND_SHIFT 28 -#define RADEON_TV_MODULATOR_CNTL2 0x0874 -# define RADEON_TV_U_BURST_LEVEL_MASK 0x1ff -# define RADEON_TV_V_BURST_LEVEL_MASK 0x1ff -# define RADEON_TV_V_BURST_LEVEL_SHIFT 16 -#define RADEON_TV_CRC_CNTL 0x0890 -#define RADEON_TV_UV_ADR 0x08ac -# define RADEON_MAX_UV_ADR_MASK 0x000000ff -# define RADEON_MAX_UV_ADR_SHIFT 0 -# define RADEON_TABLE1_BOT_ADR_MASK 0x0000ff00 -# define RADEON_TABLE1_BOT_ADR_SHIFT 8 -# define RADEON_TABLE3_TOP_ADR_MASK 0x00ff0000 -# define RADEON_TABLE3_TOP_ADR_SHIFT 16 -# define RADEON_HCODE_TABLE_SEL_MASK 0x06000000 -# define RADEON_HCODE_TABLE_SEL_SHIFT 25 -# define RADEON_VCODE_TABLE_SEL_MASK 0x18000000 -# define RADEON_VCODE_TABLE_SEL_SHIFT 27 -# define RADEON_TV_MAX_FIFO_ADDR 0x1a7 -# define RADEON_TV_MAX_FIFO_ADDR_INTERNAL 0x1ff -#define RADEON_TV_PLL_FINE_CNTL 0x0020 /* PLL */ -#define RADEON_TV_PLL_CNTL 0x0021 /* PLL */ -# define RADEON_TV_M0LO_MASK 0xff -# define RADEON_TV_M0HI_MASK 0x7 -# define RADEON_TV_M0HI_SHIFT 18 -# define RADEON_TV_N0LO_MASK 0x1ff -# define RADEON_TV_N0LO_SHIFT 8 -# define RADEON_TV_N0HI_MASK 0x3 -# define RADEON_TV_N0HI_SHIFT 21 -# define RADEON_TV_P_MASK 0xf -# define RADEON_TV_P_SHIFT 24 -# define RADEON_TV_SLIP_EN (1 << 23) -# define RADEON_TV_DTO_EN (1 << 28) -#define RADEON_TV_PLL_CNTL1 0x0022 /* PLL */ -# define RADEON_TVPLL_RESET (1 << 1) -# define RADEON_TVPLL_SLEEP (1 << 3) -# define RADEON_TVPLL_REFCLK_SEL (1 << 4) -# define RADEON_TVPCP_SHIFT 8 -# define RADEON_TVPCP_MASK (7 << 8) -# define RADEON_TVPVG_SHIFT 11 -# define RADEON_TVPVG_MASK (7 << 11) -# define RADEON_TVPDC_SHIFT 14 -# define RADEON_TVPDC_MASK (3 << 14) -# define RADEON_TVPLL_TEST_DIS (1 << 31) -# define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30) - -#define RS400_DISP2_REQ_CNTL1 0xe30 -# define RS400_DISP2_START_REQ_LEVEL_SHIFT 0 -# define RS400_DISP2_START_REQ_LEVEL_MASK 0x3ff -# define RS400_DISP2_STOP_REQ_LEVEL_SHIFT 12 -# define RS400_DISP2_STOP_REQ_LEVEL_MASK 0x3ff -# define RS400_DISP2_ALLOW_FID_LEVEL_SHIFT 22 -# define RS400_DISP2_ALLOW_FID_LEVEL_MASK 0x3ff -#define RS400_DISP2_REQ_CNTL2 0xe34 -# define RS400_DISP2_CRITICAL_POINT_START_SHIFT 12 -# define RS400_DISP2_CRITICAL_POINT_START_MASK 0x3ff -# define RS400_DISP2_CRITICAL_POINT_STOP_SHIFT 22 -# define RS400_DISP2_CRITICAL_POINT_STOP_MASK 0x3ff -#define RS400_DMIF_MEM_CNTL1 0xe38 -# define RS400_DISP2_START_ADR_SHIFT 0 -# define RS400_DISP2_START_ADR_MASK 0x3ff -# define RS400_DISP1_CRITICAL_POINT_START_SHIFT 12 -# define RS400_DISP1_CRITICAL_POINT_START_MASK 0x3ff -# define RS400_DISP1_CRITICAL_POINT_STOP_SHIFT 22 -# define RS400_DISP1_CRITICAL_POINT_STOP_MASK 0x3ff -#define RS400_DISP1_REQ_CNTL1 0xe3c -# define RS400_DISP1_START_REQ_LEVEL_SHIFT 0 -# define RS400_DISP1_START_REQ_LEVEL_MASK 0x3ff -# define RS400_DISP1_STOP_REQ_LEVEL_SHIFT 12 -# define RS400_DISP1_STOP_REQ_LEVEL_MASK 0x3ff -# define RS400_DISP1_ALLOW_FID_LEVEL_SHIFT 22 -# define RS400_DISP1_ALLOW_FID_LEVEL_MASK 0x3ff - -#define RADEON_PCIE_INDEX 0x0030 -#define RADEON_PCIE_DATA 0x0034 -#define RADEON_PCIE_TX_GART_CNTL 0x10 -# define RADEON_PCIE_TX_GART_EN (1 << 0) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0 << 1) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1 << 1) -# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3 << 1) -# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0 << 3) -# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1 << 3) -# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1 << 5) -# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1 << 8) -#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11 -#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12 -#define RADEON_PCIE_TX_GART_BASE 0x13 -#define RADEON_PCIE_TX_GART_START_LO 0x14 -#define RADEON_PCIE_TX_GART_START_HI 0x15 -#define RADEON_PCIE_TX_GART_END_LO 0x16 -#define RADEON_PCIE_TX_GART_END_HI 0x17 -#define RADEON_PCIE_TX_GART_ERROR 0x18 - -#define RADEON_SCRATCH_REG0 0x15e0 -#define RADEON_SCRATCH_REG1 0x15e4 -#define RADEON_SCRATCH_REG2 0x15e8 -#define RADEON_SCRATCH_REG3 0x15ec -#define RADEON_SCRATCH_REG4 0x15f0 -#define RADEON_SCRATCH_REG5 0x15f4 - -#define RV530_GB_PIPE_SELECT2 0x4124 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ring.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ring.c deleted file mode 100644 index cc33b3d7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ring.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include "drmP.h" -#include "radeon_drm.h" -#include "radeon_reg.h" -#include "radeon.h" -#include "atom.h" - -int radeon_debugfs_ib_init(struct radeon_device *rdev); -int radeon_debugfs_ring_init(struct radeon_device *rdev); - -u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) -{ - struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; - u32 pg_idx, pg_offset; - u32 idx_value = 0; - int new_page; - - pg_idx = (idx * 4) / PAGE_SIZE; - pg_offset = (idx * 4) % PAGE_SIZE; - - if (ibc->kpage_idx[0] == pg_idx) - return ibc->kpage[0][pg_offset/4]; - if (ibc->kpage_idx[1] == pg_idx) - return ibc->kpage[1][pg_offset/4]; - - new_page = radeon_cs_update_pages(p, pg_idx); - if (new_page < 0) { - p->parser_error = new_page; - return 0; - } - - idx_value = ibc->kpage[new_page][pg_offset/4]; - return idx_value; -} - -void radeon_ring_write(struct radeon_ring *ring, uint32_t v) -{ -#if DRM_DEBUG_CODE - if (ring->count_dw <= 0) { - DRM_ERROR("radeon: writting more dword to ring than expected !\n"); - } -#endif - ring->ring[ring->wptr++] = v; - ring->wptr &= ring->ptr_mask; - ring->count_dw--; - ring->ring_free_dw--; -} - -/* - * IB. - */ -bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib) -{ - bool done = false; - - /* only free ib which have been emited */ - if (ib->fence && ib->fence->emitted) { - if (radeon_fence_signaled(ib->fence)) { - radeon_fence_unref(&ib->fence); - radeon_sa_bo_free(rdev, &ib->sa_bo); - done = true; - } - } - return done; -} - -int radeon_ib_get(struct radeon_device *rdev, int ring, - struct radeon_ib **ib, unsigned size) -{ - struct radeon_fence *fence; - unsigned cretry = 0; - int r = 0, i, idx; - - *ib = NULL; - /* align size on 256 bytes */ - size = ALIGN(size, 256); - - r = radeon_fence_create(rdev, &fence, ring); - if (r) { - dev_err(rdev->dev, "failed to create fence for new IB\n"); - return r; - } - - radeon_mutex_lock(&rdev->ib_pool.mutex); - idx = rdev->ib_pool.head_id; -retry: - if (cretry > 5) { - dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); - radeon_mutex_unlock(&rdev->ib_pool.mutex); - radeon_fence_unref(&fence); - return -ENOMEM; - } - cretry++; - for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { - radeon_ib_try_free(rdev, &rdev->ib_pool.ibs[idx]); - if (rdev->ib_pool.ibs[idx].fence == NULL) { - r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager, - &rdev->ib_pool.ibs[idx].sa_bo, - size, 256); - if (!r) { - *ib = &rdev->ib_pool.ibs[idx]; - (*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr; - (*ib)->ptr += ((*ib)->sa_bo.offset >> 2); - (*ib)->gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; - (*ib)->gpu_addr += (*ib)->sa_bo.offset; - (*ib)->fence = fence; - (*ib)->vm_id = 0; - (*ib)->is_const_ib = false; - /* ib are most likely to be allocated in a ring fashion - * thus rdev->ib_pool.head_id should be the id of the - * oldest ib - */ - rdev->ib_pool.head_id = (1 + idx); - rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); - radeon_mutex_unlock(&rdev->ib_pool.mutex); - return 0; - } - } - idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); - } - /* this should be rare event, ie all ib scheduled none signaled yet. - */ - for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { - if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) { - r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false); - if (!r) { - goto retry; - } - /* an error happened */ - break; - } - idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); - } - radeon_mutex_unlock(&rdev->ib_pool.mutex); - radeon_fence_unref(&fence); - return r; -} - -void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) -{ - struct radeon_ib *tmp = *ib; - - *ib = NULL; - if (tmp == NULL) { - return; - } - radeon_mutex_lock(&rdev->ib_pool.mutex); - if (tmp->fence && !tmp->fence->emitted) { - radeon_sa_bo_free(rdev, &tmp->sa_bo); - radeon_fence_unref(&tmp->fence); - } - radeon_mutex_unlock(&rdev->ib_pool.mutex); -} - -int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) -{ - struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; - int r = 0; - - if (!ib->length_dw || !ring->ready) { - /* TODO: Nothings in the ib we should report. */ - DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); - return -EINVAL; - } - - /* 64 dwords should be enough for fence too */ - r = radeon_ring_lock(rdev, ring, 64); - if (r) { - DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); - return r; - } - radeon_ring_ib_execute(rdev, ib->fence->ring, ib); - radeon_fence_emit(rdev, ib->fence); - radeon_ring_unlock_commit(rdev, ring); - return 0; -} - -int radeon_ib_pool_init(struct radeon_device *rdev) -{ - struct radeon_sa_manager tmp; - int i, r; - - r = radeon_sa_bo_manager_init(rdev, &tmp, - RADEON_IB_POOL_SIZE*64*1024, - RADEON_GEM_DOMAIN_GTT); - if (r) { - return r; - } - - radeon_mutex_lock(&rdev->ib_pool.mutex); - if (rdev->ib_pool.ready) { - radeon_mutex_unlock(&rdev->ib_pool.mutex); - radeon_sa_bo_manager_fini(rdev, &tmp); - return 0; - } - - rdev->ib_pool.sa_manager = tmp; - INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo); - for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { - rdev->ib_pool.ibs[i].fence = NULL; - rdev->ib_pool.ibs[i].idx = i; - rdev->ib_pool.ibs[i].length_dw = 0; - INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list); - } - rdev->ib_pool.head_id = 0; - rdev->ib_pool.ready = true; - DRM_INFO("radeon: ib pool ready.\n"); - - if (radeon_debugfs_ib_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for IB !\n"); - } - if (radeon_debugfs_ring_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for rings !\n"); - } - radeon_mutex_unlock(&rdev->ib_pool.mutex); - return 0; -} - -void radeon_ib_pool_fini(struct radeon_device *rdev) -{ - unsigned i; - - radeon_mutex_lock(&rdev->ib_pool.mutex); - if (rdev->ib_pool.ready) { - for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { - radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); - radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); - } - radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); - rdev->ib_pool.ready = false; - } - radeon_mutex_unlock(&rdev->ib_pool.mutex); -} - -int radeon_ib_pool_start(struct radeon_device *rdev) -{ - return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager); -} - -int radeon_ib_pool_suspend(struct radeon_device *rdev) -{ - return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager); -} - -/* - * Ring. - */ -int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) -{ - /* r1xx-r5xx only has CP ring */ - if (rdev->family < CHIP_R600) - return RADEON_RING_TYPE_GFX_INDEX; - - if (rdev->family >= CHIP_CAYMAN) { - if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]) - return CAYMAN_RING_TYPE_CP1_INDEX; - else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]) - return CAYMAN_RING_TYPE_CP2_INDEX; - } - return RADEON_RING_TYPE_GFX_INDEX; -} - -void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 rptr; - - if (rdev->wb.enabled) - rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); - else - rptr = RREG32(ring->rptr_reg); - ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; - /* This works because ring_size is a power of 2 */ - ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); - ring->ring_free_dw -= ring->wptr; - ring->ring_free_dw &= ring->ptr_mask; - if (!ring->ring_free_dw) { - ring->ring_free_dw = ring->ring_size / 4; - } -} - - -int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) -{ - int r; - - /* Align requested size with padding so unlock_commit can - * pad safely */ - ndw = (ndw + ring->align_mask) & ~ring->align_mask; - while (ndw > (ring->ring_free_dw - 1)) { - radeon_ring_free_size(rdev, ring); - if (ndw < ring->ring_free_dw) { - break; - } - r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring)); - if (r) - return r; - } - ring->count_dw = ndw; - ring->wptr_old = ring->wptr; - return 0; -} - -int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) -{ - int r; - - mutex_lock(&ring->mutex); - r = radeon_ring_alloc(rdev, ring, ndw); - if (r) { - mutex_unlock(&ring->mutex); - return r; - } - return 0; -} - -void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) -{ - unsigned count_dw_pad; - unsigned i; - - /* We pad to match fetch size */ - count_dw_pad = (ring->align_mask + 1) - - (ring->wptr & ring->align_mask); - for (i = 0; i < count_dw_pad; i++) { - radeon_ring_write(ring, ring->nop); - } - DRM_MEMORYBARRIER(); - WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask); - (void)RREG32(ring->wptr_reg); -} - -void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) -{ - radeon_ring_commit(rdev, ring); - mutex_unlock(&ring->mutex); -} - -void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) -{ - ring->wptr = ring->wptr_old; - mutex_unlock(&ring->mutex); -} - -int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, - unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, - u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) -{ - int r; - - ring->ring_size = ring_size; - ring->rptr_offs = rptr_offs; - ring->rptr_reg = rptr_reg; - ring->wptr_reg = wptr_reg; - ring->ptr_reg_shift = ptr_reg_shift; - ring->ptr_reg_mask = ptr_reg_mask; - ring->nop = nop; - /* Allocate ring buffer */ - if (ring->ring_obj == NULL) { - r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_GTT, - &ring->ring_obj); - if (r) { - dev_err(rdev->dev, "(%d) ring create failed\n", r); - return r; - } - r = radeon_bo_reserve(ring->ring_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT, - &ring->gpu_addr); - if (r) { - radeon_bo_unreserve(ring->ring_obj); - dev_err(rdev->dev, "(%d) ring pin failed\n", r); - return r; - } - r = radeon_bo_kmap(ring->ring_obj, - (void **)&ring->ring); - radeon_bo_unreserve(ring->ring_obj); - if (r) { - dev_err(rdev->dev, "(%d) ring map failed\n", r); - return r; - } - } - ring->ptr_mask = (ring->ring_size / 4) - 1; - ring->ring_free_dw = ring->ring_size / 4; - return 0; -} - -void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) -{ - int r; - struct radeon_bo *ring_obj; - - mutex_lock(&ring->mutex); - ring_obj = ring->ring_obj; - ring->ring = NULL; - ring->ring_obj = NULL; - mutex_unlock(&ring->mutex); - - if (ring_obj) { - r = radeon_bo_reserve(ring_obj, false); - if (likely(r == 0)) { - radeon_bo_kunmap(ring_obj); - radeon_bo_unpin(ring_obj); - radeon_bo_unreserve(ring_obj); - } - radeon_bo_unref(&ring_obj); - } -} - -/* - * Debugfs info - */ -#if defined(CONFIG_DEBUG_FS) - -static int radeon_debugfs_ring_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - int ridx = *(int*)node->info_ent->data; - struct radeon_ring *ring = &rdev->ring[ridx]; - unsigned count, i, j; - - radeon_ring_free_size(rdev, ring); - count = (ring->ring_size / 4) - ring->ring_free_dw; - seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); - seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); - seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); - seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); - seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); - seq_printf(m, "%u dwords in ring\n", count); - i = ring->rptr; - for (j = 0; j <= count; j++) { - seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); - i = (i + 1) & ring->ptr_mask; - } - return 0; -} - -static int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX; -static int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX; -static int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX; - -static struct drm_info_list radeon_debugfs_ring_info_list[] = { - {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index}, - {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index}, - {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index}, -}; - -static int radeon_debugfs_ib_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_ib *ib = &rdev->ib_pool.ibs[*((unsigned*)node->info_ent->data)]; - unsigned i; - - if (ib == NULL) { - return 0; - } - seq_printf(m, "IB %04u\n", ib->idx); - seq_printf(m, "IB fence %p\n", ib->fence); - seq_printf(m, "IB size %05u dwords\n", ib->length_dw); - for (i = 0; i < ib->length_dw; i++) { - seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); - } - return 0; -} - -static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; -static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; -static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE]; -#endif - -int radeon_debugfs_ring_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - if (rdev->family >= CHIP_CAYMAN) - return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, - ARRAY_SIZE(radeon_debugfs_ring_info_list)); - else - return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1); -#else - return 0; -#endif -} - -int radeon_debugfs_ib_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - unsigned i; - - for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { - sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); - radeon_debugfs_ib_idx[i] = i; - radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; - radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info; - radeon_debugfs_ib_list[i].driver_features = 0; - radeon_debugfs_ib_list[i].data = &radeon_debugfs_ib_idx[i]; - } - return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list, - RADEON_IB_POOL_SIZE); -#else - return 0; -#endif -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_sa.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_sa.c deleted file mode 100644 index 4cce47e7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_sa.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2011 Red Hat Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: - * Jerome Glisse - */ -#include "drmP.h" -#include "drm.h" -#include "radeon.h" - -int radeon_sa_bo_manager_init(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager, - unsigned size, u32 domain) -{ - int r; - - sa_manager->bo = NULL; - sa_manager->size = size; - sa_manager->domain = domain; - INIT_LIST_HEAD(&sa_manager->sa_bo); - - r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true, - RADEON_GEM_DOMAIN_CPU, &sa_manager->bo); - if (r) { - dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r); - return r; - } - - return r; -} - -void radeon_sa_bo_manager_fini(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager) -{ - struct radeon_sa_bo *sa_bo, *tmp; - - if (!list_empty(&sa_manager->sa_bo)) { - dev_err(rdev->dev, "sa_manager is not empty, clearing anyway\n"); - } - list_for_each_entry_safe(sa_bo, tmp, &sa_manager->sa_bo, list) { - list_del_init(&sa_bo->list); - } - radeon_bo_unref(&sa_manager->bo); - sa_manager->size = 0; -} - -int radeon_sa_bo_manager_start(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager) -{ - int r; - - if (sa_manager->bo == NULL) { - dev_err(rdev->dev, "no bo for sa manager\n"); - return -EINVAL; - } - - /* map the buffer */ - r = radeon_bo_reserve(sa_manager->bo, false); - if (r) { - dev_err(rdev->dev, "(%d) failed to reserve manager bo\n", r); - return r; - } - r = radeon_bo_pin(sa_manager->bo, sa_manager->domain, &sa_manager->gpu_addr); - if (r) { - radeon_bo_unreserve(sa_manager->bo); - dev_err(rdev->dev, "(%d) failed to pin manager bo\n", r); - return r; - } - r = radeon_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); - radeon_bo_unreserve(sa_manager->bo); - return r; -} - -int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager) -{ - int r; - - if (sa_manager->bo == NULL) { - dev_err(rdev->dev, "no bo for sa manager\n"); - return -EINVAL; - } - - r = radeon_bo_reserve(sa_manager->bo, false); - if (!r) { - radeon_bo_kunmap(sa_manager->bo); - radeon_bo_unpin(sa_manager->bo); - radeon_bo_unreserve(sa_manager->bo); - } - return r; -} - -/* - * Principe is simple, we keep a list of sub allocation in offset - * order (first entry has offset == 0, last entry has the highest - * offset). - * - * When allocating new object we first check if there is room at - * the end total_size - (last_object_offset + last_object_size) >= - * alloc_size. If so we allocate new object there. - * - * When there is not enough room at the end, we start waiting for - * each sub object until we reach object_offset+object_size >= - * alloc_size, this object then become the sub object we return. - * - * Alignment can't be bigger than page size - */ -int radeon_sa_bo_new(struct radeon_device *rdev, - struct radeon_sa_manager *sa_manager, - struct radeon_sa_bo *sa_bo, - unsigned size, unsigned align) -{ - struct radeon_sa_bo *tmp; - struct list_head *head; - unsigned offset = 0, wasted = 0; - - BUG_ON(align > RADEON_GPU_PAGE_SIZE); - BUG_ON(size > sa_manager->size); - - /* no one ? */ - head = sa_manager->sa_bo.prev; - if (list_empty(&sa_manager->sa_bo)) { - goto out; - } - - /* look for a hole big enough */ - offset = 0; - list_for_each_entry(tmp, &sa_manager->sa_bo, list) { - /* room before this object ? */ - if ((tmp->offset - offset) >= size) { - head = tmp->list.prev; - goto out; - } - offset = tmp->offset + tmp->size; - wasted = offset % align; - if (wasted) { - wasted = align - wasted; - } - offset += wasted; - } - /* room at the end ? */ - head = sa_manager->sa_bo.prev; - tmp = list_entry(head, struct radeon_sa_bo, list); - offset = tmp->offset + tmp->size; - wasted = offset % align; - if (wasted) { - wasted = align - wasted; - } - offset += wasted; - if ((sa_manager->size - offset) < size) { - /* failed to find somethings big enough */ - return -ENOMEM; - } - -out: - sa_bo->manager = sa_manager; - sa_bo->offset = offset; - sa_bo->size = size; - list_add(&sa_bo->list, head); - return 0; -} - -void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo) -{ - list_del_init(&sa_bo->list); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_semaphore.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_semaphore.c deleted file mode 100644 index 61dd4e3c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_semaphore.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2011 Christian König. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: - * Christian König - */ -#include "drmP.h" -#include "drm.h" -#include "radeon.h" - -static int radeon_semaphore_add_bo(struct radeon_device *rdev) -{ - struct radeon_semaphore_bo *bo; - unsigned long irq_flags; - uint64_t gpu_addr; - uint32_t *cpu_ptr; - int r, i; - - - bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL); - if (bo == NULL) { - return -ENOMEM; - } - INIT_LIST_HEAD(&bo->free); - INIT_LIST_HEAD(&bo->list); - bo->nused = 0; - - r = radeon_ib_get(rdev, 0, &bo->ib, RADEON_SEMAPHORE_BO_SIZE); - if (r) { - dev_err(rdev->dev, "failed to get a bo after 5 retry\n"); - kfree(bo); - return r; - } - gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; - gpu_addr += bo->ib->sa_bo.offset; - cpu_ptr = rdev->ib_pool.sa_manager.cpu_ptr; - cpu_ptr += (bo->ib->sa_bo.offset >> 2); - for (i = 0; i < (RADEON_SEMAPHORE_BO_SIZE/8); i++) { - bo->semaphores[i].gpu_addr = gpu_addr; - bo->semaphores[i].cpu_ptr = cpu_ptr; - bo->semaphores[i].bo = bo; - list_add_tail(&bo->semaphores[i].list, &bo->free); - gpu_addr += 8; - cpu_ptr += 2; - } - write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); - list_add_tail(&bo->list, &rdev->semaphore_drv.bo); - write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); - return 0; -} - -static void radeon_semaphore_del_bo_locked(struct radeon_device *rdev, - struct radeon_semaphore_bo *bo) -{ - radeon_sa_bo_free(rdev, &bo->ib->sa_bo); - radeon_fence_unref(&bo->ib->fence); - list_del(&bo->list); - kfree(bo); -} - -void radeon_semaphore_shrink_locked(struct radeon_device *rdev) -{ - struct radeon_semaphore_bo *bo, *n; - - if (list_empty(&rdev->semaphore_drv.bo)) { - return; - } - /* only shrink if first bo has free semaphore */ - bo = list_first_entry(&rdev->semaphore_drv.bo, struct radeon_semaphore_bo, list); - if (list_empty(&bo->free)) { - return; - } - list_for_each_entry_safe_continue(bo, n, &rdev->semaphore_drv.bo, list) { - if (bo->nused) - continue; - radeon_semaphore_del_bo_locked(rdev, bo); - } -} - -int radeon_semaphore_create(struct radeon_device *rdev, - struct radeon_semaphore **semaphore) -{ - struct radeon_semaphore_bo *bo; - unsigned long irq_flags; - bool do_retry = true; - int r; - -retry: - *semaphore = NULL; - write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); - list_for_each_entry(bo, &rdev->semaphore_drv.bo, list) { - if (list_empty(&bo->free)) - continue; - *semaphore = list_first_entry(&bo->free, struct radeon_semaphore, list); - (*semaphore)->cpu_ptr[0] = 0; - (*semaphore)->cpu_ptr[1] = 0; - list_del(&(*semaphore)->list); - bo->nused++; - break; - } - write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); - - if (*semaphore == NULL) { - if (do_retry) { - do_retry = false; - r = radeon_semaphore_add_bo(rdev); - if (r) - return r; - goto retry; - } - return -ENOMEM; - } - - return 0; -} - -void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore) -{ - radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); -} - -void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore) -{ - radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); -} - -void radeon_semaphore_free(struct radeon_device *rdev, - struct radeon_semaphore *semaphore) -{ - unsigned long irq_flags; - - write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); - semaphore->bo->nused--; - list_add_tail(&semaphore->list, &semaphore->bo->free); - radeon_semaphore_shrink_locked(rdev); - write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); -} - -void radeon_semaphore_driver_fini(struct radeon_device *rdev) -{ - struct radeon_semaphore_bo *bo, *n; - unsigned long irq_flags; - - write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); - /* we force to free everything */ - list_for_each_entry_safe(bo, n, &rdev->semaphore_drv.bo, list) { - if (!list_empty(&bo->free)) { - dev_err(rdev->dev, "still in use semaphore\n"); - } - radeon_semaphore_del_bo_locked(rdev, bo); - } - write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_state.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_state.c deleted file mode 100644 index e8422ae7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_state.c +++ /dev/null @@ -1,3261 +0,0 @@ -/* radeon_state.c -- State support for Radeon -*- linux-c -*- */ -/* - * Copyright 2000 VA Linux Systems, Inc., Fremont, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Gareth Hughes - * Kevin E. Martin - */ - -#include "drmP.h" -#include "drm.h" -#include "drm_buffer.h" -#include "drm_sarea.h" -#include "radeon_drm.h" -#include "radeon_drv.h" - -/* ================================================================ - * Helper functions for client state checking and fixup - */ - -static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * - dev_priv, - struct drm_file * file_priv, - u32 *offset) -{ - u64 off = *offset; - u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1; - struct drm_radeon_driver_file_fields *radeon_priv; - - /* Hrm ... the story of the offset ... So this function converts - * the various ideas of what userland clients might have for an - * offset in the card address space into an offset into the card - * address space :) So with a sane client, it should just keep - * the value intact and just do some boundary checking. However, - * not all clients are sane. Some older clients pass us 0 based - * offsets relative to the start of the framebuffer and some may - * assume the AGP aperture it appended to the framebuffer, so we - * try to detect those cases and fix them up. - * - * Note: It might be a good idea here to make sure the offset lands - * in some "allowed" area to protect things like the PCIE GART... - */ - - /* First, the best case, the offset already lands in either the - * framebuffer or the GART mapped space - */ - if (radeon_check_offset(dev_priv, off)) - return 0; - - /* Ok, that didn't happen... now check if we have a zero based - * offset that fits in the framebuffer + gart space, apply the - * magic offset we get from SETPARAM or calculated from fb_location - */ - if (off < (dev_priv->fb_size + dev_priv->gart_size)) { - radeon_priv = file_priv->driver_priv; - off += radeon_priv->radeon_fb_delta; - } - - /* Finally, assume we aimed at a GART offset if beyond the fb */ - if (off > fb_end) - off = off - fb_end - 1 + dev_priv->gart_vm_start; - - /* Now recheck and fail if out of bounds */ - if (radeon_check_offset(dev_priv, off)) { - DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); - *offset = off; - return 0; - } - return -EINVAL; -} - -static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * - dev_priv, - struct drm_file *file_priv, - int id, struct drm_buffer *buf) -{ - u32 *data; - switch (id) { - - case RADEON_EMIT_PP_MISC: - data = drm_buffer_pointer_to_dword(buf, - (RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4); - - if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { - DRM_ERROR("Invalid depth buffer offset\n"); - return -EINVAL; - } - dev_priv->have_z_offset = 1; - break; - - case RADEON_EMIT_PP_CNTL: - data = drm_buffer_pointer_to_dword(buf, - (RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4); - - if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { - DRM_ERROR("Invalid colour buffer offset\n"); - return -EINVAL; - } - break; - - case R200_EMIT_PP_TXOFFSET_0: - case R200_EMIT_PP_TXOFFSET_1: - case R200_EMIT_PP_TXOFFSET_2: - case R200_EMIT_PP_TXOFFSET_3: - case R200_EMIT_PP_TXOFFSET_4: - case R200_EMIT_PP_TXOFFSET_5: - data = drm_buffer_pointer_to_dword(buf, 0); - if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { - DRM_ERROR("Invalid R200 texture offset\n"); - return -EINVAL; - } - break; - - case RADEON_EMIT_PP_TXFILTER_0: - case RADEON_EMIT_PP_TXFILTER_1: - case RADEON_EMIT_PP_TXFILTER_2: - data = drm_buffer_pointer_to_dword(buf, - (RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4); - if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) { - DRM_ERROR("Invalid R100 texture offset\n"); - return -EINVAL; - } - break; - - case R200_EMIT_PP_CUBIC_OFFSETS_0: - case R200_EMIT_PP_CUBIC_OFFSETS_1: - case R200_EMIT_PP_CUBIC_OFFSETS_2: - case R200_EMIT_PP_CUBIC_OFFSETS_3: - case R200_EMIT_PP_CUBIC_OFFSETS_4: - case R200_EMIT_PP_CUBIC_OFFSETS_5:{ - int i; - for (i = 0; i < 5; i++) { - data = drm_buffer_pointer_to_dword(buf, i); - if (radeon_check_and_fixup_offset(dev_priv, - file_priv, - data)) { - DRM_ERROR - ("Invalid R200 cubic texture offset\n"); - return -EINVAL; - } - } - break; - } - - case RADEON_EMIT_PP_CUBIC_OFFSETS_T0: - case RADEON_EMIT_PP_CUBIC_OFFSETS_T1: - case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{ - int i; - for (i = 0; i < 5; i++) { - data = drm_buffer_pointer_to_dword(buf, i); - if (radeon_check_and_fixup_offset(dev_priv, - file_priv, - data)) { - DRM_ERROR - ("Invalid R100 cubic texture offset\n"); - return -EINVAL; - } - } - } - break; - - case R200_EMIT_VAP_CTL:{ - RING_LOCALS; - BEGIN_RING(2); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - ADVANCE_RING(); - } - break; - - case RADEON_EMIT_RB3D_COLORPITCH: - case RADEON_EMIT_RE_LINE_PATTERN: - case RADEON_EMIT_SE_LINE_WIDTH: - case RADEON_EMIT_PP_LUM_MATRIX: - case RADEON_EMIT_PP_ROT_MATRIX_0: - case RADEON_EMIT_RB3D_STENCILREFMASK: - case RADEON_EMIT_SE_VPORT_XSCALE: - case RADEON_EMIT_SE_CNTL: - case RADEON_EMIT_SE_CNTL_STATUS: - case RADEON_EMIT_RE_MISC: - case RADEON_EMIT_PP_BORDER_COLOR_0: - case RADEON_EMIT_PP_BORDER_COLOR_1: - case RADEON_EMIT_PP_BORDER_COLOR_2: - case RADEON_EMIT_SE_ZBIAS_FACTOR: - case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT: - case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED: - case R200_EMIT_PP_TXCBLEND_0: - case R200_EMIT_PP_TXCBLEND_1: - case R200_EMIT_PP_TXCBLEND_2: - case R200_EMIT_PP_TXCBLEND_3: - case R200_EMIT_PP_TXCBLEND_4: - case R200_EMIT_PP_TXCBLEND_5: - case R200_EMIT_PP_TXCBLEND_6: - case R200_EMIT_PP_TXCBLEND_7: - case R200_EMIT_TCL_LIGHT_MODEL_CTL_0: - case R200_EMIT_TFACTOR_0: - case R200_EMIT_VTX_FMT_0: - case R200_EMIT_MATRIX_SELECT_0: - case R200_EMIT_TEX_PROC_CTL_2: - case R200_EMIT_TCL_UCP_VERT_BLEND_CTL: - case R200_EMIT_PP_TXFILTER_0: - case R200_EMIT_PP_TXFILTER_1: - case R200_EMIT_PP_TXFILTER_2: - case R200_EMIT_PP_TXFILTER_3: - case R200_EMIT_PP_TXFILTER_4: - case R200_EMIT_PP_TXFILTER_5: - case R200_EMIT_VTE_CNTL: - case R200_EMIT_OUTPUT_VTX_COMP_SEL: - case R200_EMIT_PP_TAM_DEBUG3: - case R200_EMIT_PP_CNTL_X: - case R200_EMIT_RB3D_DEPTHXY_OFFSET: - case R200_EMIT_RE_AUX_SCISSOR_CNTL: - case R200_EMIT_RE_SCISSOR_TL_0: - case R200_EMIT_RE_SCISSOR_TL_1: - case R200_EMIT_RE_SCISSOR_TL_2: - case R200_EMIT_SE_VAP_CNTL_STATUS: - case R200_EMIT_SE_VTX_STATE_CNTL: - case R200_EMIT_RE_POINTSIZE: - case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0: - case R200_EMIT_PP_CUBIC_FACES_0: - case R200_EMIT_PP_CUBIC_FACES_1: - case R200_EMIT_PP_CUBIC_FACES_2: - case R200_EMIT_PP_CUBIC_FACES_3: - case R200_EMIT_PP_CUBIC_FACES_4: - case R200_EMIT_PP_CUBIC_FACES_5: - case RADEON_EMIT_PP_TEX_SIZE_0: - case RADEON_EMIT_PP_TEX_SIZE_1: - case RADEON_EMIT_PP_TEX_SIZE_2: - case R200_EMIT_RB3D_BLENDCOLOR: - case R200_EMIT_TCL_POINT_SPRITE_CNTL: - case RADEON_EMIT_PP_CUBIC_FACES_0: - case RADEON_EMIT_PP_CUBIC_FACES_1: - case RADEON_EMIT_PP_CUBIC_FACES_2: - case R200_EMIT_PP_TRI_PERF_CNTL: - case R200_EMIT_PP_AFS_0: - case R200_EMIT_PP_AFS_1: - case R200_EMIT_ATF_TFACTOR: - case R200_EMIT_PP_TXCTLALL_0: - case R200_EMIT_PP_TXCTLALL_1: - case R200_EMIT_PP_TXCTLALL_2: - case R200_EMIT_PP_TXCTLALL_3: - case R200_EMIT_PP_TXCTLALL_4: - case R200_EMIT_PP_TXCTLALL_5: - case R200_EMIT_VAP_PVS_CNTL: - /* These packets don't contain memory offsets */ - break; - - default: - DRM_ERROR("Unknown state packet ID %d\n", id); - return -EINVAL; - } - - return 0; -} - -static int radeon_check_and_fixup_packet3(drm_radeon_private_t * - dev_priv, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t * - cmdbuf, - unsigned int *cmdsz) -{ - u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); - u32 offset, narrays; - int count, i, k; - - count = ((*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16); - *cmdsz = 2 + count; - - if ((*cmd & 0xc0000000) != RADEON_CP_PACKET3) { - DRM_ERROR("Not a type 3 packet\n"); - return -EINVAL; - } - - if (4 * *cmdsz > drm_buffer_unprocessed(cmdbuf->buffer)) { - DRM_ERROR("Packet size larger than size of data provided\n"); - return -EINVAL; - } - - switch (*cmd & 0xff00) { - /* XXX Are there old drivers needing other packets? */ - - case RADEON_3D_DRAW_IMMD: - case RADEON_3D_DRAW_VBUF: - case RADEON_3D_DRAW_INDX: - case RADEON_WAIT_FOR_IDLE: - case RADEON_CP_NOP: - case RADEON_3D_CLEAR_ZMASK: -/* case RADEON_CP_NEXT_CHAR: - case RADEON_CP_PLY_NEXTSCAN: - case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */ - /* these packets are safe */ - break; - - case RADEON_CP_3D_DRAW_IMMD_2: - case RADEON_CP_3D_DRAW_VBUF_2: - case RADEON_CP_3D_DRAW_INDX_2: - case RADEON_3D_CLEAR_HIZ: - /* safe but r200 only */ - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return -EINVAL; - } - break; - - case RADEON_3D_LOAD_VBPNTR: - - if (count > 18) { /* 12 arrays max */ - DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", - count); - return -EINVAL; - } - - /* carefully check packet contents */ - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - - narrays = *cmd & ~0xc000; - k = 0; - i = 2; - while ((k < narrays) && (i < (count + 2))) { - i++; /* skip attribute field */ - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - cmd)) { - DRM_ERROR - ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - if (k == narrays) - break; - /* have one more to process, they come in pairs */ - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i); - - if (radeon_check_and_fixup_offset(dev_priv, - file_priv, cmd)) - { - DRM_ERROR - ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n", - k, i); - return -EINVAL; - } - k++; - i++; - } - /* do the counts match what we expect ? */ - if ((k != narrays) || (i != (count + 2))) { - DRM_ERROR - ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", - k, i, narrays, count + 1); - return -EINVAL; - } - break; - - case RADEON_3D_RNDR_GEN_INDX_PRIM: - if (dev_priv->microcode_version != UCODE_R100) { - DRM_ERROR("Invalid 3d packet for r200-class chip\n"); - return -EINVAL; - } - - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) { - DRM_ERROR("Invalid rndr_gen_indx offset\n"); - return -EINVAL; - } - break; - - case RADEON_CP_INDX_BUFFER: - if (dev_priv->microcode_version != UCODE_R200) { - DRM_ERROR("Invalid 3d packet for r100-class chip\n"); - return -EINVAL; - } - - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - if ((*cmd & 0x8000ffff) != 0x80000810) { - DRM_ERROR("Invalid indx_buffer reg address %08X\n", *cmd); - return -EINVAL; - } - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2); - if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) { - DRM_ERROR("Invalid indx_buffer offset is %08X\n", *cmd); - return -EINVAL; - } - break; - - case RADEON_CNTL_HOSTDATA_BLT: - case RADEON_CNTL_PAINT_MULTI: - case RADEON_CNTL_BITBLT_MULTI: - /* MSB of opcode: next DWORD GUI_CNTL */ - cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1); - if (*cmd & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL - | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2); - offset = *cmd2 << 10; - if (radeon_check_and_fixup_offset - (dev_priv, file_priv, &offset)) { - DRM_ERROR("Invalid first packet offset\n"); - return -EINVAL; - } - *cmd2 = (*cmd2 & 0xffc00000) | offset >> 10; - } - - if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && - (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { - u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); - offset = *cmd3 << 10; - if (radeon_check_and_fixup_offset - (dev_priv, file_priv, &offset)) { - DRM_ERROR("Invalid second packet offset\n"); - return -EINVAL; - } - *cmd3 = (*cmd3 & 0xffc00000) | offset >> 10; - } - break; - - default: - DRM_ERROR("Invalid packet type %x\n", *cmd & 0xff00); - return -EINVAL; - } - - return 0; -} - -/* ================================================================ - * CP hardware state programming functions - */ - -static void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv, - struct drm_clip_rect * box) -{ - RING_LOCALS; - - DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n", - box->x1, box->y1, box->x2, box->y2); - - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0)); - OUT_RING((box->y1 << 16) | box->x1); - OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0)); - OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1)); - ADVANCE_RING(); -} - -/* Emit 1.1 state - */ -static int radeon_emit_state(drm_radeon_private_t * dev_priv, - struct drm_file *file_priv, - drm_radeon_context_regs_t * ctx, - drm_radeon_texture_regs_t * tex, - unsigned int dirty) -{ - RING_LOCALS; - DRM_DEBUG("dirty=0x%08x\n", dirty); - - if (dirty & RADEON_UPLOAD_CONTEXT) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &ctx->rb3d_depthoffset)) { - DRM_ERROR("Invalid depth buffer offset\n"); - return -EINVAL; - } - - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &ctx->rb3d_coloroffset)) { - DRM_ERROR("Invalid depth buffer offset\n"); - return -EINVAL; - } - - BEGIN_RING(14); - OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6)); - OUT_RING(ctx->pp_misc); - OUT_RING(ctx->pp_fog_color); - OUT_RING(ctx->re_solid_color); - OUT_RING(ctx->rb3d_blendcntl); - OUT_RING(ctx->rb3d_depthoffset); - OUT_RING(ctx->rb3d_depthpitch); - OUT_RING(ctx->rb3d_zstencilcntl); - OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2)); - OUT_RING(ctx->pp_cntl); - OUT_RING(ctx->rb3d_cntl); - OUT_RING(ctx->rb3d_coloroffset); - OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0)); - OUT_RING(ctx->rb3d_colorpitch); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_VERTFMT) { - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0)); - OUT_RING(ctx->se_coord_fmt); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_LINE) { - BEGIN_RING(5); - OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1)); - OUT_RING(ctx->re_line_pattern); - OUT_RING(ctx->re_line_state); - OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0)); - OUT_RING(ctx->se_line_width); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_BUMPMAP) { - BEGIN_RING(5); - OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0)); - OUT_RING(ctx->pp_lum_matrix); - OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1)); - OUT_RING(ctx->pp_rot_matrix_0); - OUT_RING(ctx->pp_rot_matrix_1); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_MASKS) { - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2)); - OUT_RING(ctx->rb3d_stencilrefmask); - OUT_RING(ctx->rb3d_ropcntl); - OUT_RING(ctx->rb3d_planemask); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_VIEWPORT) { - BEGIN_RING(7); - OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5)); - OUT_RING(ctx->se_vport_xscale); - OUT_RING(ctx->se_vport_xoffset); - OUT_RING(ctx->se_vport_yscale); - OUT_RING(ctx->se_vport_yoffset); - OUT_RING(ctx->se_vport_zscale); - OUT_RING(ctx->se_vport_zoffset); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_SETUP) { - BEGIN_RING(4); - OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0)); - OUT_RING(ctx->se_cntl); - OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0)); - OUT_RING(ctx->se_cntl_status); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_MISC) { - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0)); - OUT_RING(ctx->re_misc); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_TEX0) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &tex[0].pp_txoffset)) { - DRM_ERROR("Invalid texture offset for unit 0\n"); - return -EINVAL; - } - - BEGIN_RING(9); - OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5)); - OUT_RING(tex[0].pp_txfilter); - OUT_RING(tex[0].pp_txformat); - OUT_RING(tex[0].pp_txoffset); - OUT_RING(tex[0].pp_txcblend); - OUT_RING(tex[0].pp_txablend); - OUT_RING(tex[0].pp_tfactor); - OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0)); - OUT_RING(tex[0].pp_border_color); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_TEX1) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &tex[1].pp_txoffset)) { - DRM_ERROR("Invalid texture offset for unit 1\n"); - return -EINVAL; - } - - BEGIN_RING(9); - OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5)); - OUT_RING(tex[1].pp_txfilter); - OUT_RING(tex[1].pp_txformat); - OUT_RING(tex[1].pp_txoffset); - OUT_RING(tex[1].pp_txcblend); - OUT_RING(tex[1].pp_txablend); - OUT_RING(tex[1].pp_tfactor); - OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0)); - OUT_RING(tex[1].pp_border_color); - ADVANCE_RING(); - } - - if (dirty & RADEON_UPLOAD_TEX2) { - if (radeon_check_and_fixup_offset(dev_priv, file_priv, - &tex[2].pp_txoffset)) { - DRM_ERROR("Invalid texture offset for unit 2\n"); - return -EINVAL; - } - - BEGIN_RING(9); - OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5)); - OUT_RING(tex[2].pp_txfilter); - OUT_RING(tex[2].pp_txformat); - OUT_RING(tex[2].pp_txoffset); - OUT_RING(tex[2].pp_txcblend); - OUT_RING(tex[2].pp_txablend); - OUT_RING(tex[2].pp_tfactor); - OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0)); - OUT_RING(tex[2].pp_border_color); - ADVANCE_RING(); - } - - return 0; -} - -/* Emit 1.2 state - */ -static int radeon_emit_state2(drm_radeon_private_t * dev_priv, - struct drm_file *file_priv, - drm_radeon_state_t * state) -{ - RING_LOCALS; - - if (state->dirty & RADEON_UPLOAD_ZBIAS) { - BEGIN_RING(3); - OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1)); - OUT_RING(state->context2.se_zbias_factor); - OUT_RING(state->context2.se_zbias_constant); - ADVANCE_RING(); - } - - return radeon_emit_state(dev_priv, file_priv, &state->context, - state->tex, state->dirty); -} - -/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in - * 1.3 cmdbuffers allow all previous state to be updated as well as - * the tcl scalar and vector areas. - */ -static struct { - int start; - int len; - const char *name; -} packet[RADEON_MAX_STATE_PACKETS] = { - {RADEON_PP_MISC, 7, "RADEON_PP_MISC"}, - {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"}, - {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"}, - {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"}, - {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"}, - {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"}, - {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"}, - {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"}, - {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"}, - {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"}, - {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"}, - {RADEON_RE_MISC, 1, "RADEON_RE_MISC"}, - {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"}, - {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"}, - {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"}, - {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"}, - {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"}, - {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"}, - {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"}, - {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"}, - {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17, - "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"}, - {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"}, - {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"}, - {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"}, - {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"}, - {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"}, - {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"}, - {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"}, - {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"}, - {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"}, - {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"}, - {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"}, - {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"}, - {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"}, - {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"}, - {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"}, - {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"}, - {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"}, - {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"}, - {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"}, - {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"}, - {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"}, - {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"}, - {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"}, - {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"}, - {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"}, - {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"}, - {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"}, - {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"}, - {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, - "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"}, - {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"}, - {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"}, - {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"}, - {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"}, - {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"}, - {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"}, - {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"}, - {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"}, - {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"}, - {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"}, - {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, - "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"}, - {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */ - {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */ - {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"}, - {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"}, - {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"}, - {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"}, - {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"}, - {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"}, - {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"}, - {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"}, - {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"}, - {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"}, - {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"}, - {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"}, - {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"}, - {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"}, - {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"}, - {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"}, - {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"}, - {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"}, - {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"}, - {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"}, - {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"}, - {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"}, - {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */ - {R200_PP_AFS_1, 32, "R200_PP_AFS_1"}, - {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"}, - {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"}, - {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"}, - {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"}, - {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, - {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, - {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, - {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"}, -}; - -/* ================================================================ - * Performance monitoring functions - */ - -static void radeon_clear_box(drm_radeon_private_t * dev_priv, - struct drm_radeon_master_private *master_priv, - int x, int y, int w, int h, int r, int g, int b) -{ - u32 color; - RING_LOCALS; - - x += master_priv->sarea_priv->boxes[0].x1; - y += master_priv->sarea_priv->boxes[0].y1; - - switch (dev_priv->color_fmt) { - case RADEON_COLOR_FORMAT_RGB565: - color = (((r & 0xf8) << 8) | - ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); - break; - case RADEON_COLOR_FORMAT_ARGB8888: - default: - color = (((0xff) << 24) | (r << 16) | (g << 8) | b); - break; - } - - BEGIN_RING(4); - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0)); - OUT_RING(0xffffffff); - ADVANCE_RING(); - - BEGIN_RING(6); - - OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4)); - OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); - - if (master_priv->sarea_priv->pfCurrentPage == 1) { - OUT_RING(dev_priv->front_pitch_offset); - } else { - OUT_RING(dev_priv->back_pitch_offset); - } - - OUT_RING(color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); -} - -static void radeon_cp_performance_boxes(drm_radeon_private_t *dev_priv, struct drm_radeon_master_private *master_priv) -{ - /* Collapse various things into a wait flag -- trying to - * guess if userspase slept -- better just to have them tell us. - */ - if (dev_priv->stats.last_frame_reads > 1 || - dev_priv->stats.last_clear_reads > dev_priv->stats.clears) { - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - } - - if (dev_priv->stats.freelist_loops) { - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - } - - /* Purple box for page flipping - */ - if (dev_priv->stats.boxes & RADEON_BOX_FLIP) - radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255); - - /* Red box if we have to wait for idle at any point - */ - if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE) - radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0); - - /* Blue box: lost context? - */ - - /* Yellow box for texture swaps - */ - if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD) - radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0); - - /* Green box if hardware never idles (as far as we can tell) - */ - if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) - radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0); - - /* Draw bars indicating number of buffers allocated - * (not a great measure, easily confused) - */ - if (dev_priv->stats.requested_bufs) { - if (dev_priv->stats.requested_bufs > 100) - dev_priv->stats.requested_bufs = 100; - - radeon_clear_box(dev_priv, master_priv, 4, 16, - dev_priv->stats.requested_bufs, 4, - 196, 128, 128); - } - - memset(&dev_priv->stats, 0, sizeof(dev_priv->stats)); - -} - -/* ================================================================ - * CP command dispatch functions - */ - -static void radeon_cp_dispatch_clear(struct drm_device * dev, - struct drm_master *master, - drm_radeon_clear_t * clear, - drm_radeon_clear_rect_t * depth_boxes) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - unsigned int flags = clear->flags; - u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0; - int i; - RING_LOCALS; - DRM_DEBUG("flags = 0x%x\n", flags); - - dev_priv->stats.clears++; - - if (sarea_priv->pfCurrentPage == 1) { - unsigned int tmp = flags; - - flags &= ~(RADEON_FRONT | RADEON_BACK); - if (tmp & RADEON_FRONT) - flags |= RADEON_BACK; - if (tmp & RADEON_BACK) - flags |= RADEON_FRONT; - } - if (flags & (RADEON_DEPTH|RADEON_STENCIL)) { - if (!dev_priv->have_z_offset) { - printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n"); - flags &= ~(RADEON_DEPTH | RADEON_STENCIL); - } - } - - if (flags & (RADEON_FRONT | RADEON_BACK)) { - - BEGIN_RING(4); - - /* Ensure the 3D stream is idle before doing a - * 2D fill to clear the front or back buffer. - */ - RADEON_WAIT_UNTIL_3D_IDLE(); - - OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0)); - OUT_RING(clear->color_mask); - - ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->ctx_owner = 0; - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n", - x, y, w, h, flags); - - if (flags & RADEON_FRONT) { - BEGIN_RING(6); - - OUT_RING(CP_PACKET3 - (RADEON_CNTL_PAINT_MULTI, 4)); - OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv-> - color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS); - - OUT_RING(dev_priv->front_pitch_offset); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - if (flags & RADEON_BACK) { - BEGIN_RING(6); - - OUT_RING(CP_PACKET3 - (RADEON_CNTL_PAINT_MULTI, 4)); - OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dev_priv-> - color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS); - - OUT_RING(dev_priv->back_pitch_offset); - OUT_RING(clear->clear_color); - - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - } - } - - /* hyper z clear */ - /* no docs available, based on reverse engineering by Stephane Marchesin */ - if ((flags & (RADEON_DEPTH | RADEON_STENCIL)) - && (flags & RADEON_CLEAR_FASTZ)) { - - int i; - int depthpixperline = - dev_priv->depth_fmt == - RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch / - 2) : (dev_priv-> - depth_pitch / 4); - - u32 clearmask; - - u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth | - ((clear->depth_mask & 0xff) << 24); - - /* Make sure we restore the 3D state next time. - * we haven't touched any "normal" state - still need this? - */ - sarea_priv->ctx_owner = 0; - - if ((dev_priv->flags & RADEON_HAS_HIERZ) - && (flags & RADEON_USE_HIERZ)) { - /* FIXME : reverse engineer that for Rx00 cards */ - /* FIXME : the mask supposedly contains low-res z values. So can't set - just to the max (0xff? or actually 0x3fff?), need to take z clear - value into account? */ - /* pattern seems to work for r100, though get slight - rendering errors with glxgears. If hierz is not enabled for r100, - only 4 bits which indicate clear (15,16,31,32, all zero) matter, the - other ones are ignored, and the same clear mask can be used. That's - very different behaviour than R200 which needs different clear mask - and different number of tiles to clear if hierz is enabled or not !?! - */ - clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f; - } else { - /* clear mask : chooses the clearing pattern. - rv250: could be used to clear only parts of macrotiles - (but that would get really complicated...)? - bit 0 and 1 (either or both of them ?!?!) are used to - not clear tile (or maybe one of the bits indicates if the tile is - compressed or not), bit 2 and 3 to not clear tile 1,...,. - Pattern is as follows: - | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29| - bits ------------------------------------------------- - | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31| - rv100: clearmask covers 2x8 4x1 tiles, but one clear still - covers 256 pixels ?!? - */ - clearmask = 0x0; - } - - BEGIN_RING(8); - RADEON_WAIT_UNTIL_2D_IDLE(); - OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE, - tempRB3D_DEPTHCLEARVALUE); - /* what offset is this exactly ? */ - OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0); - /* need ctlstat, otherwise get some strange black flickering */ - OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT, - RADEON_RB3D_ZC_FLUSH_ALL); - ADVANCE_RING(); - - for (i = 0; i < nbox; i++) { - int tileoffset, nrtilesx, nrtilesy, j; - /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) - && !(dev_priv->microcode_version == UCODE_R200)) { - /* FIXME : figure this out for r200 (when hierz is enabled). Or - maybe r200 actually doesn't need to put the low-res z value into - the tile cache like r100, but just needs to clear the hi-level z-buffer? - Works for R100, both with hierz and without. - R100 seems to operate on 2x1 8x8 tiles, but... - odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially - problematic with resolutions which are not 64 pix aligned? */ - tileoffset = - ((pbox[i].y1 >> 3) * depthpixperline + - pbox[i].x1) >> 6; - nrtilesx = - ((pbox[i].x2 & ~63) - - (pbox[i].x1 & ~63)) >> 4; - nrtilesy = - (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); - for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING(4); - OUT_RING(CP_PACKET3 - (RADEON_3D_CLEAR_ZMASK, 2)); - /* first tile */ - OUT_RING(tileoffset * 8); - /* the number of tiles to clear */ - OUT_RING(nrtilesx + 4); - /* clear mask : chooses the clearing pattern. */ - OUT_RING(clearmask); - ADVANCE_RING(); - tileoffset += depthpixperline >> 6; - } - } else if (dev_priv->microcode_version == UCODE_R200) { - /* works for rv250. */ - /* find first macro tile (8x2 4x4 z-pixels on rv250) */ - tileoffset = - ((pbox[i].y1 >> 3) * depthpixperline + - pbox[i].x1) >> 5; - nrtilesx = - (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5); - nrtilesy = - (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3); - for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING(4); - OUT_RING(CP_PACKET3 - (RADEON_3D_CLEAR_ZMASK, 2)); - /* first tile */ - /* judging by the first tile offset needed, could possibly - directly address/clear 4x4 tiles instead of 8x2 * 4x4 - macro tiles, though would still need clear mask for - right/bottom if truly 4x4 granularity is desired ? */ - OUT_RING(tileoffset * 16); - /* the number of tiles to clear */ - OUT_RING(nrtilesx + 1); - /* clear mask : chooses the clearing pattern. */ - OUT_RING(clearmask); - ADVANCE_RING(); - tileoffset += depthpixperline >> 5; - } - } else { /* rv 100 */ - /* rv100 might not need 64 pix alignment, who knows */ - /* offsets are, hmm, weird */ - tileoffset = - ((pbox[i].y1 >> 4) * depthpixperline + - pbox[i].x1) >> 6; - nrtilesx = - ((pbox[i].x2 & ~63) - - (pbox[i].x1 & ~63)) >> 4; - nrtilesy = - (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4); - for (j = 0; j <= nrtilesy; j++) { - BEGIN_RING(4); - OUT_RING(CP_PACKET3 - (RADEON_3D_CLEAR_ZMASK, 2)); - OUT_RING(tileoffset * 128); - /* the number of tiles to clear */ - OUT_RING(nrtilesx + 4); - /* clear mask : chooses the clearing pattern. */ - OUT_RING(clearmask); - ADVANCE_RING(); - tileoffset += depthpixperline >> 6; - } - } - } - - /* TODO don't always clear all hi-level z tiles */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) - && (dev_priv->microcode_version == UCODE_R200) - && (flags & RADEON_USE_HIERZ)) - /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ - /* FIXME : the mask supposedly contains low-res z values. So can't set - just to the max (0xff? or actually 0x3fff?), need to take z clear - value into account? */ - { - BEGIN_RING(4); - OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2)); - OUT_RING(0x0); /* First tile */ - OUT_RING(0x3cc0); - OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f); - ADVANCE_RING(); - } - } - - /* We have to clear the depth and/or stencil buffers by - * rendering a quad into just those buffers. Thus, we have to - * make sure the 3D engine is configured correctly. - */ - else if ((dev_priv->microcode_version == UCODE_R200) && - (flags & (RADEON_DEPTH | RADEON_STENCIL))) { - - int tempPP_CNTL; - int tempRE_CNTL; - int tempRB3D_CNTL; - int tempRB3D_ZSTENCILCNTL; - int tempRB3D_STENCILREFMASK; - int tempRB3D_PLANEMASK; - int tempSE_CNTL; - int tempSE_VTE_CNTL; - int tempSE_VTX_FMT_0; - int tempSE_VTX_FMT_1; - int tempSE_VAP_CNTL; - int tempRE_AUX_SCISSOR_CNTL; - - tempPP_CNTL = 0; - tempRE_CNTL = 0; - - tempRB3D_CNTL = depth_clear->rb3d_cntl; - - tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; - tempRB3D_STENCILREFMASK = 0x0; - - tempSE_CNTL = depth_clear->se_cntl; - - /* Disable TCL */ - - tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */ - (0x9 << - SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT)); - - tempRB3D_PLANEMASK = 0x0; - - tempRE_AUX_SCISSOR_CNTL = 0x0; - - tempSE_VTE_CNTL = - SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK; - - /* Vertex format (X, Y, Z, W) */ - tempSE_VTX_FMT_0 = - SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK | - SE_VTX_FMT_0__VTX_W0_PRESENT_MASK; - tempSE_VTX_FMT_1 = 0x0; - - /* - * Depth buffer specific enables - */ - if (flags & RADEON_DEPTH) { - /* Enable depth buffer */ - tempRB3D_CNTL |= RADEON_Z_ENABLE; - } else { - /* Disable depth buffer */ - tempRB3D_CNTL &= ~RADEON_Z_ENABLE; - } - - /* - * Stencil buffer specific enables - */ - if (flags & RADEON_STENCIL) { - tempRB3D_CNTL |= RADEON_STENCIL_ENABLE; - tempRB3D_STENCILREFMASK = clear->depth_mask; - } else { - tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE; - tempRB3D_STENCILREFMASK = 0x00000000; - } - - if (flags & RADEON_USE_COMP_ZBUF) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | - RADEON_Z_DECOMPRESSION_ENABLE; - } - if (flags & RADEON_USE_HIERZ) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; - } - - BEGIN_RING(26); - RADEON_WAIT_UNTIL_2D_IDLE(); - - OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL); - OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL); - OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL); - OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL); - OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, - tempRB3D_STENCILREFMASK); - OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK); - OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL); - OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL); - OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0); - OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1); - OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL); - OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL); - ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->ctx_owner = 0; - - for (i = 0; i < nbox; i++) { - - /* Funny that this should be required -- - * sets top-left? - */ - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - - BEGIN_RING(14); - OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12)); - OUT_RING((RADEON_PRIM_TYPE_RECT_LIST | - RADEON_PRIM_WALK_RING | - (3 << RADEON_NUM_VERTICES_SHIFT))); - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y1]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x3f800000); - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x3f800000); - OUT_RING(depth_boxes[i].ui[CLEAR_X2]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x3f800000); - ADVANCE_RING(); - } - } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) { - - int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl; - - rb3d_cntl = depth_clear->rb3d_cntl; - - if (flags & RADEON_DEPTH) { - rb3d_cntl |= RADEON_Z_ENABLE; - } else { - rb3d_cntl &= ~RADEON_Z_ENABLE; - } - - if (flags & RADEON_STENCIL) { - rb3d_cntl |= RADEON_STENCIL_ENABLE; - rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */ - } else { - rb3d_cntl &= ~RADEON_STENCIL_ENABLE; - rb3d_stencilrefmask = 0x00000000; - } - - if (flags & RADEON_USE_COMP_ZBUF) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE | - RADEON_Z_DECOMPRESSION_ENABLE; - } - if (flags & RADEON_USE_HIERZ) { - tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE; - } - - BEGIN_RING(13); - RADEON_WAIT_UNTIL_2D_IDLE(); - - OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1)); - OUT_RING(0x00000000); - OUT_RING(rb3d_cntl); - - OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL); - OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask); - OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000); - OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl); - ADVANCE_RING(); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->ctx_owner = 0; - - for (i = 0; i < nbox; i++) { - - /* Funny that this should be required -- - * sets top-left? - */ - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - - BEGIN_RING(15); - - OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13)); - OUT_RING(RADEON_VTX_Z_PRESENT | - RADEON_VTX_PKCOLOR_PRESENT); - OUT_RING((RADEON_PRIM_TYPE_RECT_LIST | - RADEON_PRIM_WALK_RING | - RADEON_MAOS_ENABLE | - RADEON_VTX_FMT_RADEON_MODE | - (3 << RADEON_NUM_VERTICES_SHIFT))); - - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y1]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x0); - - OUT_RING(depth_boxes[i].ui[CLEAR_X1]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x0); - - OUT_RING(depth_boxes[i].ui[CLEAR_X2]); - OUT_RING(depth_boxes[i].ui[CLEAR_Y2]); - OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]); - OUT_RING(0x0); - - ADVANCE_RING(); - } - } - - /* Increment the clear counter. The client-side 3D driver must - * wait on this value before performing the clear ioctl. We - * need this because the card's so damned fast... - */ - sarea_priv->last_clear++; - - BEGIN_RING(4); - - RADEON_CLEAR_AGE(sarea_priv->last_clear); - RADEON_WAIT_UNTIL_IDLE(); - - ADVANCE_RING(); -} - -static void radeon_cp_dispatch_swap(struct drm_device *dev, struct drm_master *master) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - int nbox = sarea_priv->nbox; - struct drm_clip_rect *pbox = sarea_priv->boxes; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - /* Do some trivial performance monitoring... - */ - if (dev_priv->do_boxes) - radeon_cp_performance_boxes(dev_priv, master_priv); - - /* Wait for the 3D stream to idle before dispatching the bitblt. - * This will prevent data corruption between the two streams. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - - for (i = 0; i < nbox; i++) { - int x = pbox[i].x1; - int y = pbox[i].y1; - int w = pbox[i].x2 - x; - int h = pbox[i].y2 - y; - - DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h); - - BEGIN_RING(9); - - OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0)); - OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (dev_priv->color_fmt << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - - /* Make this work even if front & back are flipped: - */ - OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); - if (sarea_priv->pfCurrentPage == 0) { - OUT_RING(dev_priv->back_pitch_offset); - OUT_RING(dev_priv->front_pitch_offset); - } else { - OUT_RING(dev_priv->front_pitch_offset); - OUT_RING(dev_priv->back_pitch_offset); - } - - OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2)); - OUT_RING((x << 16) | y); - OUT_RING((x << 16) | y); - OUT_RING((w << 16) | h); - - ADVANCE_RING(); - } - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - sarea_priv->last_frame++; - - BEGIN_RING(4); - - RADEON_FRAME_AGE(sarea_priv->last_frame); - RADEON_WAIT_UNTIL_2D_IDLE(); - - ADVANCE_RING(); -} - -void radeon_cp_dispatch_flip(struct drm_device *dev, struct drm_master *master) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - struct drm_sarea *sarea = (struct drm_sarea *)master_priv->sarea->handle; - int offset = (master_priv->sarea_priv->pfCurrentPage == 1) - ? dev_priv->front_offset : dev_priv->back_offset; - RING_LOCALS; - DRM_DEBUG("pfCurrentPage=%d\n", - master_priv->sarea_priv->pfCurrentPage); - - /* Do some trivial performance monitoring... - */ - if (dev_priv->do_boxes) { - dev_priv->stats.boxes |= RADEON_BOX_FLIP; - radeon_cp_performance_boxes(dev_priv, master_priv); - } - - /* Update the frame offsets for both CRTCs - */ - BEGIN_RING(6); - - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING_REG(RADEON_CRTC_OFFSET, - ((sarea->frame.y * dev_priv->front_pitch + - sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7) - + offset); - OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base - + offset); - - ADVANCE_RING(); - - /* Increment the frame counter. The client-side 3D driver must - * throttle the framerate by waiting for this value before - * performing the swapbuffer ioctl. - */ - master_priv->sarea_priv->last_frame++; - master_priv->sarea_priv->pfCurrentPage = - 1 - master_priv->sarea_priv->pfCurrentPage; - - BEGIN_RING(2); - - RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame); - - ADVANCE_RING(); -} - -static int bad_prim_vertex_nr(int primitive, int nr) -{ - switch (primitive & RADEON_PRIM_TYPE_MASK) { - case RADEON_PRIM_TYPE_NONE: - case RADEON_PRIM_TYPE_POINT: - return nr < 1; - case RADEON_PRIM_TYPE_LINE: - return (nr & 1) || nr == 0; - case RADEON_PRIM_TYPE_LINE_STRIP: - return nr < 2; - case RADEON_PRIM_TYPE_TRI_LIST: - case RADEON_PRIM_TYPE_3VRT_POINT_LIST: - case RADEON_PRIM_TYPE_3VRT_LINE_LIST: - case RADEON_PRIM_TYPE_RECT_LIST: - return nr % 3 || nr == 0; - case RADEON_PRIM_TYPE_TRI_FAN: - case RADEON_PRIM_TYPE_TRI_STRIP: - return nr < 3; - default: - return 1; - } -} - -typedef struct { - unsigned int start; - unsigned int finish; - unsigned int prim; - unsigned int numverts; - unsigned int offset; - unsigned int vc_format; -} drm_radeon_tcl_prim_t; - -static void radeon_cp_dispatch_vertex(struct drm_device * dev, - struct drm_file *file_priv, - struct drm_buf * buf, - drm_radeon_tcl_prim_t * prim) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start; - int numverts = (int)prim->numverts; - int nbox = sarea_priv->nbox; - int i = 0; - RING_LOCALS; - - DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n", - prim->prim, - prim->vc_format, prim->start, prim->finish, prim->numverts); - - if (bad_prim_vertex_nr(prim->prim, prim->numverts)) { - DRM_ERROR("bad prim %x numverts %d\n", - prim->prim, prim->numverts); - return; - } - - do { - /* Emit the next cliprect */ - if (i < nbox) { - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - } - - /* Emit the vertex buffer rendering commands */ - BEGIN_RING(5); - - OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3)); - OUT_RING(offset); - OUT_RING(numverts); - OUT_RING(prim->vc_format); - OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (numverts << RADEON_NUM_VERTICES_SHIFT)); - - ADVANCE_RING(); - - i++; - } while (i < nbox); -} - -void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - drm_radeon_buf_priv_t *buf_priv = buf->dev_private; - RING_LOCALS; - - buf_priv->age = ++master_priv->sarea_priv->last_dispatch; - - /* Emit the vertex buffer age */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { - BEGIN_RING(3); - R600_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); - } else { - BEGIN_RING(2); - RADEON_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); - } - - buf->pending = 1; - buf->used = 0; -} - -static void radeon_cp_dispatch_indirect(struct drm_device * dev, - struct drm_buf * buf, int start, int end) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end); - - if (start != end) { - int offset = (dev_priv->gart_buffers_offset - + buf->offset + start); - int dwords = (end - start + 3) / sizeof(u32); - - /* Indirect buffer data must be an even number of - * dwords, so if we've been given an odd number we must - * pad the data with a Type-2 CP packet. - */ - if (dwords & 1) { - u32 *data = (u32 *) - ((char *)dev->agp_buffer_map->handle - + buf->offset + start); - data[dwords++] = RADEON_CP_PACKET2; - } - - /* Fire off the indirect buffer */ - BEGIN_RING(3); - - OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1)); - OUT_RING(offset); - OUT_RING(dwords); - - ADVANCE_RING(); - } -} - -static void radeon_cp_dispatch_indices(struct drm_device *dev, - struct drm_master *master, - struct drm_buf * elt_buf, - drm_radeon_tcl_prim_t * prim) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - int offset = dev_priv->gart_buffers_offset + prim->offset; - u32 *data; - int dwords; - int i = 0; - int start = prim->start + RADEON_INDEX_PRIM_OFFSET; - int count = (prim->finish - start) / sizeof(u16); - int nbox = sarea_priv->nbox; - - DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n", - prim->prim, - prim->vc_format, - prim->start, prim->finish, prim->offset, prim->numverts); - - if (bad_prim_vertex_nr(prim->prim, count)) { - DRM_ERROR("bad prim %x count %d\n", prim->prim, count); - return; - } - - if (start >= prim->finish || (prim->start & 0x7)) { - DRM_ERROR("buffer prim %d\n", prim->prim); - return; - } - - dwords = (prim->finish - prim->start + 3) / sizeof(u32); - - data = (u32 *) ((char *)dev->agp_buffer_map->handle + - elt_buf->offset + prim->start); - - data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2); - data[1] = offset; - data[2] = prim->numverts; - data[3] = prim->vc_format; - data[4] = (prim->prim | - RADEON_PRIM_WALK_IND | - RADEON_COLOR_ORDER_RGBA | - RADEON_VTX_FMT_RADEON_MODE | - (count << RADEON_NUM_VERTICES_SHIFT)); - - do { - if (i < nbox) - radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]); - - radeon_cp_dispatch_indirect(dev, elt_buf, - prim->start, prim->finish); - - i++; - } while (i < nbox); - -} - -#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE - -static int radeon_cp_dispatch_texture(struct drm_device * dev, - struct drm_file *file_priv, - drm_radeon_texture_t * tex, - drm_radeon_tex_image_t * image) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_buf *buf; - u32 format; - u32 *buffer; - const u8 __user *data; - int size, dwords, tex_width, blit_width, spitch; - u32 height; - int i; - u32 texpitch, microtile; - u32 offset, byte_offset; - RING_LOCALS; - - if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) { - DRM_ERROR("Invalid destination offset\n"); - return -EINVAL; - } - - dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD; - - /* Flush the pixel cache. This ensures no pixel data gets mixed - * up with the texture data from the host data blit, otherwise - * part of the texture image may be corrupted. - */ - BEGIN_RING(4); - RADEON_FLUSH_CACHE(); - RADEON_WAIT_UNTIL_IDLE(); - ADVANCE_RING(); - - /* The compiler won't optimize away a division by a variable, - * even if the only legal values are powers of two. Thus, we'll - * use a shift instead. - */ - switch (tex->format) { - case RADEON_TXFORMAT_ARGB8888: - case RADEON_TXFORMAT_RGBA8888: - format = RADEON_COLOR_FORMAT_ARGB8888; - tex_width = tex->width * 4; - blit_width = image->width * 4; - break; - case RADEON_TXFORMAT_AI88: - case RADEON_TXFORMAT_ARGB1555: - case RADEON_TXFORMAT_RGB565: - case RADEON_TXFORMAT_ARGB4444: - case RADEON_TXFORMAT_VYUY422: - case RADEON_TXFORMAT_YVYU422: - format = RADEON_COLOR_FORMAT_RGB565; - tex_width = tex->width * 2; - blit_width = image->width * 2; - break; - case RADEON_TXFORMAT_I8: - case RADEON_TXFORMAT_RGB332: - format = RADEON_COLOR_FORMAT_CI8; - tex_width = tex->width * 1; - blit_width = image->width * 1; - break; - default: - DRM_ERROR("invalid texture format %d\n", tex->format); - return -EINVAL; - } - spitch = blit_width >> 6; - if (spitch == 0 && image->height > 1) - return -EINVAL; - - texpitch = tex->pitch; - if ((texpitch << 22) & RADEON_DST_TILE_MICRO) { - microtile = 1; - if (tex_width < 64) { - texpitch &= ~(RADEON_DST_TILE_MICRO >> 22); - /* we got tiled coordinates, untile them */ - image->x *= 2; - } - } else - microtile = 0; - - /* this might fail for zero-sized uploads - are those illegal? */ - if (!radeon_check_offset(dev_priv, tex->offset + image->height * - blit_width - 1)) { - DRM_ERROR("Invalid final destination offset\n"); - return -EINVAL; - } - - DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width); - - do { - DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", - tex->offset >> 10, tex->pitch, tex->format, - image->x, image->y, image->width, image->height); - - /* Make a copy of some parameters in case we have to - * update them for a multi-pass texture blit. - */ - height = image->height; - data = (const u8 __user *)image->data; - - size = height * blit_width; - - if (size > RADEON_MAX_TEXTURE_SIZE) { - height = RADEON_MAX_TEXTURE_SIZE / blit_width; - size = height * blit_width; - } else if (size < 4 && size > 0) { - size = 4; - } else if (size == 0) { - return 0; - } - - buf = radeon_freelist_get(dev); - if (0 && !buf) { - radeon_do_cp_idle(dev_priv); - buf = radeon_freelist_get(dev); - } - if (!buf) { - DRM_DEBUG("EAGAIN\n"); - if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) - return -EFAULT; - return -EAGAIN; - } - - /* Dispatch the indirect buffer. - */ - buffer = - (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); - dwords = size / 4; - -#define RADEON_COPY_MT(_buf, _data, _width) \ - do { \ - if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\ - DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \ - return -EFAULT; \ - } \ - } while(0) - - if (microtile) { - /* texture micro tiling in use, minimum texture width is thus 16 bytes. - however, we cannot use blitter directly for texture width < 64 bytes, - since minimum tex pitch is 64 bytes and we need this to match - the texture width, otherwise the blitter will tile it wrong. - Thus, tiling manually in this case. Additionally, need to special - case tex height = 1, since our actual image will have height 2 - and we need to ensure we don't read beyond the texture size - from user space. */ - if (tex->height == 1) { - if (tex_width >= 64 || tex_width <= 16) { - RADEON_COPY_MT(buffer, data, - (int)(tex_width * sizeof(u32))); - } else if (tex_width == 32) { - RADEON_COPY_MT(buffer, data, 16); - RADEON_COPY_MT(buffer + 8, - data + 16, 16); - } - } else if (tex_width >= 64 || tex_width == 16) { - RADEON_COPY_MT(buffer, data, - (int)(dwords * sizeof(u32))); - } else if (tex_width < 16) { - for (i = 0; i < tex->height; i++) { - RADEON_COPY_MT(buffer, data, tex_width); - buffer += 4; - data += tex_width; - } - } else if (tex_width == 32) { - /* TODO: make sure this works when not fitting in one buffer - (i.e. 32bytes x 2048...) */ - for (i = 0; i < tex->height; i += 2) { - RADEON_COPY_MT(buffer, data, 16); - data += 16; - RADEON_COPY_MT(buffer + 8, data, 16); - data += 16; - RADEON_COPY_MT(buffer + 4, data, 16); - data += 16; - RADEON_COPY_MT(buffer + 12, data, 16); - data += 16; - buffer += 16; - } - } - } else { - if (tex_width >= 32) { - /* Texture image width is larger than the minimum, so we - * can upload it directly. - */ - RADEON_COPY_MT(buffer, data, - (int)(dwords * sizeof(u32))); - } else { - /* Texture image width is less than the minimum, so we - * need to pad out each image scanline to the minimum - * width. - */ - for (i = 0; i < tex->height; i++) { - RADEON_COPY_MT(buffer, data, tex_width); - buffer += 8; - data += tex_width; - } - } - } - -#undef RADEON_COPY_MT - byte_offset = (image->y & ~2047) * blit_width; - buf->file_priv = file_priv; - buf->used = size; - offset = dev_priv->gart_buffers_offset + buf->offset; - BEGIN_RING(9); - OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); - OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (format << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_MEMORY | - RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - OUT_RING((spitch << 22) | (offset >> 10)); - OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10))); - OUT_RING(0); - OUT_RING((image->x << 16) | (image->y % 2048)); - OUT_RING((image->width << 16) | height); - RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - COMMIT_RING(); - - radeon_cp_discard_buffer(dev, file_priv->master, buf); - - /* Update the input parameters for next time */ - image->y += height; - image->height -= height; - image->data = (const u8 __user *)image->data + size; - } while (image->height > 0); - - /* Flush the pixel cache after the blit completes. This ensures - * the texture data is written out to memory before rendering - * continues. - */ - BEGIN_RING(4); - RADEON_FLUSH_CACHE(); - RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - COMMIT_RING(); - - return 0; -} - -static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - int i; - RING_LOCALS; - DRM_DEBUG("\n"); - - BEGIN_RING(35); - - OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0)); - OUT_RING(0x00000000); - - OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31)); - for (i = 0; i < 32; i++) { - OUT_RING(stipple[i]); - } - - ADVANCE_RING(); -} - -static void radeon_apply_surface_regs(int surf_index, - drm_radeon_private_t *dev_priv) -{ - if (!dev_priv->mmio) - return; - - radeon_do_cp_idle(dev_priv); - - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index, - dev_priv->surfaces[surf_index].flags); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index, - dev_priv->surfaces[surf_index].lower); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index, - dev_priv->surfaces[surf_index].upper); -} - -/* Allocates a virtual surface - * doesn't always allocate a real surface, will stretch an existing - * surface when possible. - * - * Note that refcount can be at most 2, since during a free refcount=3 - * might mean we have to allocate a new surface which might not always - * be available. - * For example : we allocate three contiguous surfaces ABC. If B is - * freed, we suddenly need two surfaces to store A and C, which might - * not always be available. - */ -static int alloc_surface(drm_radeon_surface_alloc_t *new, - drm_radeon_private_t *dev_priv, - struct drm_file *file_priv) -{ - struct radeon_virt_surface *s; - int i; - int virt_surface_index; - uint32_t new_upper, new_lower; - - new_lower = new->address; - new_upper = new_lower + new->size - 1; - - /* sanity check */ - if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) || - ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) != - RADEON_SURF_ADDRESS_FIXED_MASK) - || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0)) - return -1; - - /* make sure there is no overlap with existing surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - if ((dev_priv->surfaces[i].refcount != 0) && - (((new_lower >= dev_priv->surfaces[i].lower) && - (new_lower < dev_priv->surfaces[i].upper)) || - ((new_lower < dev_priv->surfaces[i].lower) && - (new_upper > dev_priv->surfaces[i].lower)))) { - return -1; - } - } - - /* find a virtual surface */ - for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) - if (dev_priv->virt_surfaces[i].file_priv == NULL) - break; - if (i == 2 * RADEON_MAX_SURFACES) { - return -1; - } - virt_surface_index = i; - - /* try to reuse an existing surface */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - /* extend before */ - if ((dev_priv->surfaces[i].refcount == 1) && - (new->flags == dev_priv->surfaces[i].flags) && - (new_upper + 1 == dev_priv->surfaces[i].lower)) { - s = &(dev_priv->virt_surfaces[virt_surface_index]); - s->surface_index = i; - s->lower = new_lower; - s->upper = new_upper; - s->flags = new->flags; - s->file_priv = file_priv; - dev_priv->surfaces[i].refcount++; - dev_priv->surfaces[i].lower = s->lower; - radeon_apply_surface_regs(s->surface_index, dev_priv); - return virt_surface_index; - } - - /* extend after */ - if ((dev_priv->surfaces[i].refcount == 1) && - (new->flags == dev_priv->surfaces[i].flags) && - (new_lower == dev_priv->surfaces[i].upper + 1)) { - s = &(dev_priv->virt_surfaces[virt_surface_index]); - s->surface_index = i; - s->lower = new_lower; - s->upper = new_upper; - s->flags = new->flags; - s->file_priv = file_priv; - dev_priv->surfaces[i].refcount++; - dev_priv->surfaces[i].upper = s->upper; - radeon_apply_surface_regs(s->surface_index, dev_priv); - return virt_surface_index; - } - } - - /* okay, we need a new one */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - if (dev_priv->surfaces[i].refcount == 0) { - s = &(dev_priv->virt_surfaces[virt_surface_index]); - s->surface_index = i; - s->lower = new_lower; - s->upper = new_upper; - s->flags = new->flags; - s->file_priv = file_priv; - dev_priv->surfaces[i].refcount = 1; - dev_priv->surfaces[i].lower = s->lower; - dev_priv->surfaces[i].upper = s->upper; - dev_priv->surfaces[i].flags = s->flags; - radeon_apply_surface_regs(s->surface_index, dev_priv); - return virt_surface_index; - } - } - - /* we didn't find anything */ - return -1; -} - -static int free_surface(struct drm_file *file_priv, - drm_radeon_private_t * dev_priv, - int lower) -{ - struct radeon_virt_surface *s; - int i; - /* find the virtual surface */ - for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { - s = &(dev_priv->virt_surfaces[i]); - if (s->file_priv) { - if ((lower == s->lower) && (file_priv == s->file_priv)) - { - if (dev_priv->surfaces[s->surface_index]. - lower == s->lower) - dev_priv->surfaces[s->surface_index]. - lower = s->upper; - - if (dev_priv->surfaces[s->surface_index]. - upper == s->upper) - dev_priv->surfaces[s->surface_index]. - upper = s->lower; - - dev_priv->surfaces[s->surface_index].refcount--; - if (dev_priv->surfaces[s->surface_index]. - refcount == 0) - dev_priv->surfaces[s->surface_index]. - flags = 0; - s->file_priv = NULL; - radeon_apply_surface_regs(s->surface_index, - dev_priv); - return 0; - } - } - } - return 1; -} - -static void radeon_surfaces_release(struct drm_file *file_priv, - drm_radeon_private_t * dev_priv) -{ - int i; - for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) { - if (dev_priv->virt_surfaces[i].file_priv == file_priv) - free_surface(file_priv, dev_priv, - dev_priv->virt_surfaces[i].lower); - } -} - -/* ================================================================ - * IOCTL functions - */ -static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_surface_alloc_t *alloc = data; - - if (alloc_surface(alloc, dev_priv, file_priv) == -1) - return -EINVAL; - else - return 0; -} - -static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_surface_free_t *memfree = data; - - if (free_surface(file_priv, dev_priv, memfree->address)) - return -EINVAL; - else - return 0; -} - -static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - drm_radeon_clear_t *clear = data; - drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - - if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes, - sarea_priv->nbox * sizeof(depth_boxes[0]))) - return -EFAULT; - - radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes); - - COMMIT_RING(); - return 0; -} - -/* Not sure why this isn't set all the time: - */ -static int radeon_do_init_pageflip(struct drm_device *dev, struct drm_master *master) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; - RING_LOCALS; - - DRM_DEBUG("\n"); - - BEGIN_RING(6); - RADEON_WAIT_UNTIL_3D_IDLE(); - OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0)); - OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) | - RADEON_CRTC_OFFSET_FLIP_CNTL); - OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0)); - OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) | - RADEON_CRTC_OFFSET_FLIP_CNTL); - ADVANCE_RING(); - - dev_priv->page_flipping = 1; - - if (master_priv->sarea_priv->pfCurrentPage != 1) - master_priv->sarea_priv->pfCurrentPage = 0; - - return 0; -} - -/* Swapping and flipping are different operations, need different ioctls. - * They can & should be intermixed to support multiple 3d windows. - */ -static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (!dev_priv->page_flipping) - radeon_do_init_pageflip(dev, file_priv->master); - - radeon_cp_dispatch_flip(dev, file_priv->master); - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_cp_dispatch_swap(dev, file_priv); - else - radeon_cp_dispatch_swap(dev, file_priv->master); - sarea_priv->ctx_owner = 0; - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_sarea_t *sarea_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_vertex_t *vertex = data; - drm_radeon_tcl_prim_t prim; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - sarea_priv = master_priv->sarea_priv; - - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); - - if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - vertex->idx, dma->buf_count - 1); - return -EINVAL; - } - if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { - DRM_ERROR("buffer prim %d\n", vertex->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[vertex->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex->idx); - return -EINVAL; - } - - /* Build up a prim_t record: - */ - if (vertex->count) { - buf->used = vertex->count; /* not used? */ - - if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { - if (radeon_emit_state(dev_priv, file_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty)) { - DRM_ERROR("radeon_emit_state failed\n"); - return -EINVAL; - } - - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); - } - - prim.start = 0; - prim.finish = vertex->count; /* unused */ - prim.prim = vertex->prim; - prim.numverts = vertex->count; - prim.vc_format = sarea_priv->vc_format; - - radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim); - } - - if (vertex->discard) { - radeon_cp_discard_buffer(dev, file_priv->master, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_sarea_t *sarea_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_indices_t *elts = data; - drm_radeon_tcl_prim_t prim; - int count; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - sarea_priv = master_priv->sarea_priv; - - DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n", - DRM_CURRENTPID, elts->idx, elts->start, elts->end, - elts->discard); - - if (elts->idx < 0 || elts->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - elts->idx, dma->buf_count - 1); - return -EINVAL; - } - if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) { - DRM_ERROR("buffer prim %d\n", elts->prim); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[elts->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", elts->idx); - return -EINVAL; - } - - count = (elts->end - elts->start) / sizeof(u16); - elts->start -= RADEON_INDEX_PRIM_OFFSET; - - if (elts->start & 0x7) { - DRM_ERROR("misaligned buffer 0x%x\n", elts->start); - return -EINVAL; - } - if (elts->start < buf->used) { - DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used); - return -EINVAL; - } - - buf->used = elts->end; - - if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) { - if (radeon_emit_state(dev_priv, file_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty)) { - DRM_ERROR("radeon_emit_state failed\n"); - return -EINVAL; - } - - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); - } - - /* Build up a prim_t record: - */ - prim.start = elts->start; - prim.finish = elts->end; - prim.prim = elts->prim; - prim.offset = 0; /* offset from start of dma buffers */ - prim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - prim.vc_format = sarea_priv->vc_format; - - radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim); - if (elts->discard) { - radeon_cp_discard_buffer(dev, file_priv->master, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_texture_t *tex = data; - drm_radeon_tex_image_t image; - int ret; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (tex->image == NULL) { - DRM_ERROR("null texture image!\n"); - return -EINVAL; - } - - if (DRM_COPY_FROM_USER(&image, - (drm_radeon_tex_image_t __user *) tex->image, - sizeof(image))) - return -EFAULT; - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image); - else - ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); - - return ret; -} - -static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_stipple_t *stipple = data; - u32 mask[32]; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) - return -EFAULT; - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - radeon_cp_dispatch_stipple(dev, mask); - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_indirect_t *indirect = data; - RING_LOCALS; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", - indirect->idx, indirect->start, indirect->end, - indirect->discard); - - if (indirect->idx < 0 || indirect->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - indirect->idx, dma->buf_count - 1); - return -EINVAL; - } - - buf = dma->buflist[indirect->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", indirect->idx); - return -EINVAL; - } - - if (indirect->start < buf->used) { - DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n", - indirect->start, buf->used); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf->used = indirect->end; - - /* Dispatch the indirect buffer full of commands from the - * X server. This is insecure and is thus only available to - * privileged clients. - */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - else { - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - } - - if (indirect->discard) { - radeon_cp_discard_buffer(dev, file_priv->master, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_sarea_t *sarea_priv; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_radeon_vertex2_t *vertex = data; - int i; - unsigned char laststate; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - sarea_priv = master_priv->sarea_priv; - - DRM_DEBUG("pid=%d index=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->discard); - - if (vertex->idx < 0 || vertex->idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - vertex->idx, dma->buf_count - 1); - return -EINVAL; - } - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - buf = dma->buflist[vertex->idx]; - - if (buf->file_priv != file_priv) { - DRM_ERROR("process %d using buffer owned by %p\n", - DRM_CURRENTPID, buf->file_priv); - return -EINVAL; - } - - if (buf->pending) { - DRM_ERROR("sending pending buffer %d\n", vertex->idx); - return -EINVAL; - } - - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - return -EINVAL; - - for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) { - drm_radeon_prim_t prim; - drm_radeon_tcl_prim_t tclprim; - - if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim))) - return -EFAULT; - - if (prim.stateidx != laststate) { - drm_radeon_state_t state; - - if (DRM_COPY_FROM_USER(&state, - &vertex->state[prim.stateidx], - sizeof(state))) - return -EFAULT; - - if (radeon_emit_state2(dev_priv, file_priv, &state)) { - DRM_ERROR("radeon_emit_state2 failed\n"); - return -EINVAL; - } - - laststate = prim.stateidx; - } - - tclprim.start = prim.start; - tclprim.finish = prim.finish; - tclprim.prim = prim.prim; - tclprim.vc_format = prim.vc_format; - - if (prim.prim & RADEON_PRIM_WALK_IND) { - tclprim.offset = prim.numverts * 64; - tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */ - - radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim); - } else { - tclprim.numverts = prim.numverts; - tclprim.offset = 0; /* not used */ - - radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim); - } - - if (sarea_priv->nbox == 1) - sarea_priv->nbox = 0; - } - - if (vertex->discard) { - radeon_cp_discard_buffer(dev, file_priv->master, buf); - } - - COMMIT_RING(); - return 0; -} - -static int radeon_emit_packets(drm_radeon_private_t * dev_priv, - struct drm_file *file_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int id = (int)header.packet.packet_id; - int sz, reg; - RING_LOCALS; - - if (id >= RADEON_MAX_STATE_PACKETS) - return -EINVAL; - - sz = packet[id].len; - reg = packet[id].start; - - if (sz * sizeof(u32) > drm_buffer_unprocessed(cmdbuf->buffer)) { - DRM_ERROR("Packet size provided larger than data provided\n"); - return -EINVAL; - } - - if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, - cmdbuf->buffer)) { - DRM_ERROR("Packet verification failed\n"); - return -EINVAL; - } - - BEGIN_RING(sz + 1); - OUT_RING(CP_PACKET0(reg, (sz - 1))); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - - return 0; -} - -static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.scalars.count; - int start = header.scalars.offset; - int stride = header.scalars.stride; - RING_LOCALS; - - BEGIN_RING(3 + sz); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); - OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - return 0; -} - -/* God this is ugly - */ -static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.scalars.count; - int start = ((unsigned int)header.scalars.offset) + 0x100; - int stride = header.scalars.stride; - RING_LOCALS; - - BEGIN_RING(3 + sz); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0)); - OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1)); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - return 0; -} - -static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.vectors.count; - int start = header.vectors.offset; - int stride = header.vectors.stride; - RING_LOCALS; - - BEGIN_RING(5 + sz); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); - OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - - return 0; -} - -static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv, - drm_radeon_cmd_header_t header, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - int sz = header.veclinear.count * 4; - int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8); - RING_LOCALS; - - if (!sz) - return 0; - if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer)) - return -EINVAL; - - BEGIN_RING(5 + sz); - OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0); - OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); - OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz); - ADVANCE_RING(); - - return 0; -} - -static int radeon_emit_packet3(struct drm_device * dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - unsigned int cmdsz; - int ret; - RING_LOCALS; - - DRM_DEBUG("\n"); - - if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv, - cmdbuf, &cmdsz))) { - DRM_ERROR("Packet verification failed\n"); - return ret; - } - - BEGIN_RING(cmdsz); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz); - ADVANCE_RING(); - - return 0; -} - -static int radeon_emit_packet3_cliprect(struct drm_device *dev, - struct drm_file *file_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - int orig_nbox) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_clip_rect box; - unsigned int cmdsz; - int ret; - struct drm_clip_rect __user *boxes = cmdbuf->boxes; - int i = 0; - RING_LOCALS; - - DRM_DEBUG("\n"); - - if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv, - cmdbuf, &cmdsz))) { - DRM_ERROR("Packet verification failed\n"); - return ret; - } - - if (!orig_nbox) - goto out; - - do { - if (i < cmdbuf->nbox) { - if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box))) - return -EFAULT; - /* FIXME The second and subsequent times round - * this loop, send a WAIT_UNTIL_3D_IDLE before - * calling emit_clip_rect(). This fixes a - * lockup on fast machines when sending - * several cliprects with a cmdbuf, as when - * waving a 2D window over a 3D - * window. Something in the commands from user - * space seems to hang the card when they're - * sent several times in a row. That would be - * the correct place to fix it but this works - * around it until I can figure that out - Tim - * Smith */ - if (i) { - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); - } - radeon_emit_clip_rect(dev_priv, &box); - } - - BEGIN_RING(cmdsz); - OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz); - ADVANCE_RING(); - - } while (++i < cmdbuf->nbox); - if (cmdbuf->nbox == 1) - cmdbuf->nbox = 0; - - return 0; - out: - drm_buffer_advance(cmdbuf->buffer, cmdsz * 4); - return 0; -} - -static int radeon_emit_wait(struct drm_device * dev, int flags) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - RING_LOCALS; - - DRM_DEBUG("%x\n", flags); - switch (flags) { - case RADEON_WAIT_2D: - BEGIN_RING(2); - RADEON_WAIT_UNTIL_2D_IDLE(); - ADVANCE_RING(); - break; - case RADEON_WAIT_3D: - BEGIN_RING(2); - RADEON_WAIT_UNTIL_3D_IDLE(); - ADVANCE_RING(); - break; - case RADEON_WAIT_2D | RADEON_WAIT_3D: - BEGIN_RING(2); - RADEON_WAIT_UNTIL_IDLE(); - ADVANCE_RING(); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf = NULL; - drm_radeon_cmd_header_t stack_header; - int idx; - drm_radeon_kcmd_buffer_t *cmdbuf = data; - int orig_nbox; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - - if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) { - return -EINVAL; - } - - /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid - * races between checking values and using those values in other code, - * and simply to avoid a lot of function calls to copy in data. - */ - if (cmdbuf->bufsz != 0) { - int rv; - void __user *buffer = cmdbuf->buffer; - rv = drm_buffer_alloc(&cmdbuf->buffer, cmdbuf->bufsz); - if (rv) - return rv; - rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, - cmdbuf->bufsz); - if (rv) { - drm_buffer_free(cmdbuf->buffer); - return rv; - } - } else - goto done; - - orig_nbox = cmdbuf->nbox; - - if (dev_priv->microcode_version == UCODE_R300) { - int temp; - temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); - - drm_buffer_free(cmdbuf->buffer); - - return temp; - } - - /* microcode_version != r300 */ - while (drm_buffer_unprocessed(cmdbuf->buffer) >= sizeof(stack_header)) { - - drm_radeon_cmd_header_t *header; - header = drm_buffer_read_object(cmdbuf->buffer, - sizeof(stack_header), &stack_header); - - switch (header->header.cmd_type) { - case RADEON_CMD_PACKET: - DRM_DEBUG("RADEON_CMD_PACKET\n"); - if (radeon_emit_packets - (dev_priv, file_priv, *header, cmdbuf)) { - DRM_ERROR("radeon_emit_packets failed\n"); - goto err; - } - break; - - case RADEON_CMD_SCALARS: - DRM_DEBUG("RADEON_CMD_SCALARS\n"); - if (radeon_emit_scalars(dev_priv, *header, cmdbuf)) { - DRM_ERROR("radeon_emit_scalars failed\n"); - goto err; - } - break; - - case RADEON_CMD_VECTORS: - DRM_DEBUG("RADEON_CMD_VECTORS\n"); - if (radeon_emit_vectors(dev_priv, *header, cmdbuf)) { - DRM_ERROR("radeon_emit_vectors failed\n"); - goto err; - } - break; - - case RADEON_CMD_DMA_DISCARD: - DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n"); - idx = header->dma.buf_idx; - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("buffer index %d (of %d max)\n", - idx, dma->buf_count - 1); - goto err; - } - - buf = dma->buflist[idx]; - if (buf->file_priv != file_priv || buf->pending) { - DRM_ERROR("bad buffer %p %p %d\n", - buf->file_priv, file_priv, - buf->pending); - goto err; - } - - radeon_cp_discard_buffer(dev, file_priv->master, buf); - break; - - case RADEON_CMD_PACKET3: - DRM_DEBUG("RADEON_CMD_PACKET3\n"); - if (radeon_emit_packet3(dev, file_priv, cmdbuf)) { - DRM_ERROR("radeon_emit_packet3 failed\n"); - goto err; - } - break; - - case RADEON_CMD_PACKET3_CLIP: - DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); - if (radeon_emit_packet3_cliprect - (dev, file_priv, cmdbuf, orig_nbox)) { - DRM_ERROR("radeon_emit_packet3_clip failed\n"); - goto err; - } - break; - - case RADEON_CMD_SCALARS2: - DRM_DEBUG("RADEON_CMD_SCALARS2\n"); - if (radeon_emit_scalars2(dev_priv, *header, cmdbuf)) { - DRM_ERROR("radeon_emit_scalars2 failed\n"); - goto err; - } - break; - - case RADEON_CMD_WAIT: - DRM_DEBUG("RADEON_CMD_WAIT\n"); - if (radeon_emit_wait(dev, header->wait.flags)) { - DRM_ERROR("radeon_emit_wait failed\n"); - goto err; - } - break; - case RADEON_CMD_VECLINEAR: - DRM_DEBUG("RADEON_CMD_VECLINEAR\n"); - if (radeon_emit_veclinear(dev_priv, *header, cmdbuf)) { - DRM_ERROR("radeon_emit_veclinear failed\n"); - goto err; - } - break; - - default: - DRM_ERROR("bad cmd_type %d at byte %d\n", - header->header.cmd_type, - cmdbuf->buffer->iterator); - goto err; - } - } - - drm_buffer_free(cmdbuf->buffer); - - done: - DRM_DEBUG("DONE\n"); - COMMIT_RING(); - return 0; - - err: - drm_buffer_free(cmdbuf->buffer); - return -EINVAL; -} - -static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - drm_radeon_getparam_t *param = data; - int value; - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - - switch (param->param) { - case RADEON_PARAM_GART_BUFFER_OFFSET: - value = dev_priv->gart_buffers_offset; - break; - case RADEON_PARAM_LAST_FRAME: - dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH(dev_priv, 0); - break; - case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH(dev_priv, 1); - break; - case RADEON_PARAM_LAST_CLEAR: - dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH(dev_priv, 2); - break; - case RADEON_PARAM_IRQ_NR: - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - value = 0; - else - value = drm_dev_to_irq(dev); - break; - case RADEON_PARAM_GART_BASE: - value = dev_priv->gart_vm_start; - break; - case RADEON_PARAM_REGISTER_HANDLE: - value = dev_priv->mmio->offset; - break; - case RADEON_PARAM_STATUS_HANDLE: - value = dev_priv->ring_rptr_offset; - break; -#if BITS_PER_LONG == 32 - /* - * This ioctl() doesn't work on 64-bit platforms because hw_lock is a - * pointer which can't fit into an int-sized variable. According to - * Michel Dänzer, the ioctl() is only used on embedded platforms, so - * not supporting it shouldn't be a problem. If the same functionality - * is needed on 64-bit platforms, a new ioctl() would have to be added, - * so backwards-compatibility for the embedded platforms can be - * maintained. --davidm 4-Feb-2004. - */ - case RADEON_PARAM_SAREA_HANDLE: - /* The lock is the first dword in the sarea. */ - /* no users of this parameter */ - break; -#endif - case RADEON_PARAM_GART_TEX_HANDLE: - value = dev_priv->gart_textures_offset; - break; - case RADEON_PARAM_SCRATCH_OFFSET: - if (!dev_priv->writeback_works) - return -EINVAL; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) - value = R600_SCRATCH_REG_OFFSET; - else - value = RADEON_SCRATCH_REG_OFFSET; - break; - case RADEON_PARAM_CARD_TYPE: - if (dev_priv->flags & RADEON_IS_PCIE) - value = RADEON_CARD_PCIE; - else if (dev_priv->flags & RADEON_IS_AGP) - value = RADEON_CARD_AGP; - else - value = RADEON_CARD_PCI; - break; - case RADEON_PARAM_VBLANK_CRTC: - value = radeon_vblank_crtc_get(dev); - break; - case RADEON_PARAM_FB_LOCATION: - value = radeon_read_fb_location(dev_priv); - break; - case RADEON_PARAM_NUM_GB_PIPES: - value = dev_priv->num_gb_pipes; - break; - case RADEON_PARAM_NUM_Z_PIPES: - value = dev_priv->num_z_pipes; - break; - default: - DRM_DEBUG("Invalid parameter %d\n", param->param); - return -EINVAL; - } - - if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; - drm_radeon_setparam_t *sp = data; - struct drm_radeon_driver_file_fields *radeon_priv; - - switch (sp->param) { - case RADEON_SETPARAM_FB_LOCATION: - radeon_priv = file_priv->driver_priv; - radeon_priv->radeon_fb_delta = dev_priv->fb_location - - sp->value; - break; - case RADEON_SETPARAM_SWITCH_TILING: - if (sp->value == 0) { - DRM_DEBUG("color tiling disabled\n"); - dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO; - dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO; - if (master_priv->sarea_priv) - master_priv->sarea_priv->tiling_enabled = 0; - } else if (sp->value == 1) { - DRM_DEBUG("color tiling enabled\n"); - dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO; - dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO; - if (master_priv->sarea_priv) - master_priv->sarea_priv->tiling_enabled = 1; - } - break; - case RADEON_SETPARAM_PCIGART_LOCATION: - dev_priv->pcigart_offset = sp->value; - dev_priv->pcigart_offset_set = 1; - break; - case RADEON_SETPARAM_NEW_MEMMAP: - dev_priv->new_memmap = sp->value; - break; - case RADEON_SETPARAM_PCIGART_TABLE_SIZE: - dev_priv->gart_info.table_size = sp->value; - if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) - dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - break; - case RADEON_SETPARAM_VBLANK_CRTC: - return radeon_vblank_crtc_set(dev, sp->value); - break; - default: - DRM_DEBUG("Invalid parameter %d\n", sp->param); - return -EINVAL; - } - - return 0; -} - -/* When a client dies: - * - Check for and clean up flipped page state - * - Free any alloced GART memory. - * - Free any alloced radeon surfaces. - * - * DRM infrastructure takes care of reclaiming dma buffers. - */ -void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) -{ - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - dev_priv->page_flipping = 0; - radeon_mem_release(file_priv, dev_priv->gart_heap); - radeon_mem_release(file_priv, dev_priv->fb_heap); - radeon_surfaces_release(file_priv, dev_priv); - } -} - -void radeon_driver_lastclose(struct drm_device *dev) -{ - radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private); - radeon_do_release(dev); -} - -int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv) -{ - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_driver_file_fields *radeon_priv; - - DRM_DEBUG("\n"); - radeon_priv = kmalloc(sizeof(*radeon_priv), GFP_KERNEL); - - if (!radeon_priv) - return -ENOMEM; - - file_priv->driver_priv = radeon_priv; - - if (dev_priv) - radeon_priv->radeon_fb_delta = dev_priv->fb_location; - else - radeon_priv->radeon_fb_delta = 0; - return 0; -} - -void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_radeon_driver_file_fields *radeon_priv = - file_priv->driver_priv; - - kfree(radeon_priv); -} - -struct drm_ioctl_desc radeon_ioctls[] = { - DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), - DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) -}; - -int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_test.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_test.c deleted file mode 100644 index dc5dcf48..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_test.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright 2009 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Michel Dänzer - */ -#include -#include -#include "radeon_reg.h" -#include "radeon.h" - - -/* Test BO GTT->VRAM and VRAM->GTT GPU copies across the whole GTT aperture */ -void radeon_test_moves(struct radeon_device *rdev) -{ - struct radeon_bo *vram_obj = NULL; - struct radeon_bo **gtt_obj = NULL; - struct radeon_fence *fence = NULL; - uint64_t gtt_addr, vram_addr; - unsigned i, n, size; - int r; - - size = 1024 * 1024; - - /* Number of tests = - * (Total GTT - IB pool - writeback page - ring buffers) / test size - */ - n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024; - for (i = 0; i < RADEON_NUM_RINGS; ++i) - n -= rdev->ring[i].ring_size; - if (rdev->wb.wb_obj) - n -= RADEON_GPU_PAGE_SIZE; - if (rdev->ih.ring_obj) - n -= rdev->ih.ring_size; - n /= size; - - gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL); - if (!gtt_obj) { - DRM_ERROR("Failed to allocate %d pointers\n", n); - r = 1; - goto out_cleanup; - } - - r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, - &vram_obj); - if (r) { - DRM_ERROR("Failed to create VRAM object\n"); - goto out_cleanup; - } - r = radeon_bo_reserve(vram_obj, false); - if (unlikely(r != 0)) - goto out_cleanup; - r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); - if (r) { - DRM_ERROR("Failed to pin VRAM object\n"); - goto out_cleanup; - } - for (i = 0; i < n; i++) { - void *gtt_map, *vram_map; - void **gtt_start, **gtt_end; - void **vram_start, **vram_end; - - r = radeon_bo_create(rdev, size, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_GTT, gtt_obj + i); - if (r) { - DRM_ERROR("Failed to create GTT object %d\n", i); - goto out_cleanup; - } - - r = radeon_bo_reserve(gtt_obj[i], false); - if (unlikely(r != 0)) - goto out_cleanup; - r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); - if (r) { - DRM_ERROR("Failed to pin GTT object %d\n", i); - goto out_cleanup; - } - - r = radeon_bo_kmap(gtt_obj[i], >t_map); - if (r) { - DRM_ERROR("Failed to map GTT object %d\n", i); - goto out_cleanup; - } - - for (gtt_start = gtt_map, gtt_end = gtt_map + size; - gtt_start < gtt_end; - gtt_start++) - *gtt_start = gtt_start; - - radeon_bo_kunmap(gtt_obj[i]); - - r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - DRM_ERROR("Failed to create GTT->VRAM fence %d\n", i); - goto out_cleanup; - } - - r = radeon_copy(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, fence); - if (r) { - DRM_ERROR("Failed GTT->VRAM copy %d\n", i); - goto out_cleanup; - } - - r = radeon_fence_wait(fence, false); - if (r) { - DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i); - goto out_cleanup; - } - - radeon_fence_unref(&fence); - - r = radeon_bo_kmap(vram_obj, &vram_map); - if (r) { - DRM_ERROR("Failed to map VRAM object after copy %d\n", i); - goto out_cleanup; - } - - for (gtt_start = gtt_map, gtt_end = gtt_map + size, - vram_start = vram_map, vram_end = vram_map + size; - vram_start < vram_end; - gtt_start++, vram_start++) { - if (*vram_start != gtt_start) { - DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " - "expected 0x%p (GTT/VRAM offset " - "0x%16llx/0x%16llx)\n", - i, *vram_start, gtt_start, - (unsigned long long) - (gtt_addr - rdev->mc.gtt_start + - (void*)gtt_start - gtt_map), - (unsigned long long) - (vram_addr - rdev->mc.vram_start + - (void*)gtt_start - gtt_map)); - radeon_bo_kunmap(vram_obj); - goto out_cleanup; - } - *vram_start = vram_start; - } - - radeon_bo_kunmap(vram_obj); - - r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - DRM_ERROR("Failed to create VRAM->GTT fence %d\n", i); - goto out_cleanup; - } - - r = radeon_copy(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, fence); - if (r) { - DRM_ERROR("Failed VRAM->GTT copy %d\n", i); - goto out_cleanup; - } - - r = radeon_fence_wait(fence, false); - if (r) { - DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i); - goto out_cleanup; - } - - radeon_fence_unref(&fence); - - r = radeon_bo_kmap(gtt_obj[i], >t_map); - if (r) { - DRM_ERROR("Failed to map GTT object after copy %d\n", i); - goto out_cleanup; - } - - for (gtt_start = gtt_map, gtt_end = gtt_map + size, - vram_start = vram_map, vram_end = vram_map + size; - gtt_start < gtt_end; - gtt_start++, vram_start++) { - if (*gtt_start != vram_start) { - DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " - "expected 0x%p (VRAM/GTT offset " - "0x%16llx/0x%16llx)\n", - i, *gtt_start, vram_start, - (unsigned long long) - (vram_addr - rdev->mc.vram_start + - (void*)vram_start - vram_map), - (unsigned long long) - (gtt_addr - rdev->mc.gtt_start + - (void*)vram_start - vram_map)); - radeon_bo_kunmap(gtt_obj[i]); - goto out_cleanup; - } - } - - radeon_bo_kunmap(gtt_obj[i]); - - DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", - gtt_addr - rdev->mc.gtt_start); - } - -out_cleanup: - if (vram_obj) { - if (radeon_bo_is_reserved(vram_obj)) { - radeon_bo_unpin(vram_obj); - radeon_bo_unreserve(vram_obj); - } - radeon_bo_unref(&vram_obj); - } - if (gtt_obj) { - for (i = 0; i < n; i++) { - if (gtt_obj[i]) { - if (radeon_bo_is_reserved(gtt_obj[i])) { - radeon_bo_unpin(gtt_obj[i]); - radeon_bo_unreserve(gtt_obj[i]); - } - radeon_bo_unref(>t_obj[i]); - } - } - kfree(gtt_obj); - } - if (fence) { - radeon_fence_unref(&fence); - } - if (r) { - printk(KERN_WARNING "Error while testing BO move.\n"); - } -} - -void radeon_test_ring_sync(struct radeon_device *rdev, - struct radeon_ring *ringA, - struct radeon_ring *ringB) -{ - struct radeon_fence *fence1 = NULL, *fence2 = NULL; - struct radeon_semaphore *semaphore = NULL; - int ridxA = radeon_ring_index(rdev, ringA); - int ridxB = radeon_ring_index(rdev, ringB); - int r; - - r = radeon_fence_create(rdev, &fence1, ridxA); - if (r) { - DRM_ERROR("Failed to create sync fence 1\n"); - goto out_cleanup; - } - r = radeon_fence_create(rdev, &fence2, ridxA); - if (r) { - DRM_ERROR("Failed to create sync fence 2\n"); - goto out_cleanup; - } - - r = radeon_semaphore_create(rdev, &semaphore); - if (r) { - DRM_ERROR("Failed to create semaphore\n"); - goto out_cleanup; - } - - r = radeon_ring_lock(rdev, ringA, 64); - if (r) { - DRM_ERROR("Failed to lock ring A %d\n", ridxA); - goto out_cleanup; - } - radeon_semaphore_emit_wait(rdev, ridxA, semaphore); - radeon_fence_emit(rdev, fence1); - radeon_semaphore_emit_wait(rdev, ridxA, semaphore); - radeon_fence_emit(rdev, fence2); - radeon_ring_unlock_commit(rdev, ringA); - - mdelay(1000); - - if (radeon_fence_signaled(fence1)) { - DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - - r = radeon_ring_lock(rdev, ringB, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringB); - goto out_cleanup; - } - radeon_semaphore_emit_signal(rdev, ridxB, semaphore); - radeon_ring_unlock_commit(rdev, ringB); - - r = radeon_fence_wait(fence1, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence 1\n"); - goto out_cleanup; - } - - mdelay(1000); - - if (radeon_fence_signaled(fence2)) { - DRM_ERROR("Fence 2 signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - - r = radeon_ring_lock(rdev, ringB, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringB); - goto out_cleanup; - } - radeon_semaphore_emit_signal(rdev, ridxB, semaphore); - radeon_ring_unlock_commit(rdev, ringB); - - r = radeon_fence_wait(fence2, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence 1\n"); - goto out_cleanup; - } - -out_cleanup: - if (semaphore) - radeon_semaphore_free(rdev, semaphore); - - if (fence1) - radeon_fence_unref(&fence1); - - if (fence2) - radeon_fence_unref(&fence2); - - if (r) - printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); -} - -void radeon_test_ring_sync2(struct radeon_device *rdev, - struct radeon_ring *ringA, - struct radeon_ring *ringB, - struct radeon_ring *ringC) -{ - struct radeon_fence *fenceA = NULL, *fenceB = NULL; - struct radeon_semaphore *semaphore = NULL; - int ridxA = radeon_ring_index(rdev, ringA); - int ridxB = radeon_ring_index(rdev, ringB); - int ridxC = radeon_ring_index(rdev, ringC); - bool sigA, sigB; - int i, r; - - r = radeon_fence_create(rdev, &fenceA, ridxA); - if (r) { - DRM_ERROR("Failed to create sync fence 1\n"); - goto out_cleanup; - } - r = radeon_fence_create(rdev, &fenceB, ridxB); - if (r) { - DRM_ERROR("Failed to create sync fence 2\n"); - goto out_cleanup; - } - - r = radeon_semaphore_create(rdev, &semaphore); - if (r) { - DRM_ERROR("Failed to create semaphore\n"); - goto out_cleanup; - } - - r = radeon_ring_lock(rdev, ringA, 64); - if (r) { - DRM_ERROR("Failed to lock ring A %d\n", ridxA); - goto out_cleanup; - } - radeon_semaphore_emit_wait(rdev, ridxA, semaphore); - radeon_fence_emit(rdev, fenceA); - radeon_ring_unlock_commit(rdev, ringA); - - r = radeon_ring_lock(rdev, ringB, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %d\n", ridxB); - goto out_cleanup; - } - radeon_semaphore_emit_wait(rdev, ridxB, semaphore); - radeon_fence_emit(rdev, fenceB); - radeon_ring_unlock_commit(rdev, ringB); - - mdelay(1000); - - if (radeon_fence_signaled(fenceA)) { - DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - if (radeon_fence_signaled(fenceB)) { - DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - - r = radeon_ring_lock(rdev, ringC, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringC); - goto out_cleanup; - } - radeon_semaphore_emit_signal(rdev, ridxC, semaphore); - radeon_ring_unlock_commit(rdev, ringC); - - for (i = 0; i < 30; ++i) { - mdelay(100); - sigA = radeon_fence_signaled(fenceA); - sigB = radeon_fence_signaled(fenceB); - if (sigA || sigB) - break; - } - - if (!sigA && !sigB) { - DRM_ERROR("Neither fence A nor B has been signaled\n"); - goto out_cleanup; - } else if (sigA && sigB) { - DRM_ERROR("Both fence A and B has been signaled\n"); - goto out_cleanup; - } - - DRM_INFO("Fence %c was first signaled\n", sigA ? 'A' : 'B'); - - r = radeon_ring_lock(rdev, ringC, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringC); - goto out_cleanup; - } - radeon_semaphore_emit_signal(rdev, ridxC, semaphore); - radeon_ring_unlock_commit(rdev, ringC); - - mdelay(1000); - - r = radeon_fence_wait(fenceA, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence A\n"); - goto out_cleanup; - } - r = radeon_fence_wait(fenceB, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence B\n"); - goto out_cleanup; - } - -out_cleanup: - if (semaphore) - radeon_semaphore_free(rdev, semaphore); - - if (fenceA) - radeon_fence_unref(&fenceA); - - if (fenceB) - radeon_fence_unref(&fenceB); - - if (r) - printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); -} - -void radeon_test_syncing(struct radeon_device *rdev) -{ - int i, j, k; - - for (i = 1; i < RADEON_NUM_RINGS; ++i) { - struct radeon_ring *ringA = &rdev->ring[i]; - if (!ringA->ready) - continue; - - for (j = 0; j < i; ++j) { - struct radeon_ring *ringB = &rdev->ring[j]; - if (!ringB->ready) - continue; - - DRM_INFO("Testing syncing between rings %d and %d...\n", i, j); - radeon_test_ring_sync(rdev, ringA, ringB); - - DRM_INFO("Testing syncing between rings %d and %d...\n", j, i); - radeon_test_ring_sync(rdev, ringB, ringA); - - for (k = 0; k < j; ++k) { - struct radeon_ring *ringC = &rdev->ring[k]; - if (!ringC->ready) - continue; - - DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k); - radeon_test_ring_sync2(rdev, ringA, ringB, ringC); - - DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, k, j); - radeon_test_ring_sync2(rdev, ringA, ringC, ringB); - - DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, i, k); - radeon_test_ring_sync2(rdev, ringB, ringA, ringC); - - DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, k, i); - radeon_test_ring_sync2(rdev, ringB, ringC, ringA); - - DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, i, j); - radeon_test_ring_sync2(rdev, ringC, ringA, ringB); - - DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, j, i); - radeon_test_ring_sync2(rdev, ringC, ringB, ringA); - } - } - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace.h deleted file mode 100644 index eafd8160..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace.h +++ /dev/null @@ -1,82 +0,0 @@ -#if !defined(_RADEON_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -#define _RADEON_TRACE_H_ - -#include -#include -#include - -#include - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM radeon -#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) -#define TRACE_INCLUDE_FILE radeon_trace - -TRACE_EVENT(radeon_bo_create, - TP_PROTO(struct radeon_bo *bo), - TP_ARGS(bo), - TP_STRUCT__entry( - __field(struct radeon_bo *, bo) - __field(u32, pages) - ), - - TP_fast_assign( - __entry->bo = bo; - __entry->pages = bo->tbo.num_pages; - ), - TP_printk("bo=%p, pages=%u", __entry->bo, __entry->pages) -); - -DECLARE_EVENT_CLASS(radeon_fence_request, - - TP_PROTO(struct drm_device *dev, u32 seqno), - - TP_ARGS(dev, seqno), - - TP_STRUCT__entry( - __field(u32, dev) - __field(u32, seqno) - ), - - TP_fast_assign( - __entry->dev = dev->primary->index; - __entry->seqno = seqno; - ), - - TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) -); - -DEFINE_EVENT(radeon_fence_request, radeon_fence_emit, - - TP_PROTO(struct drm_device *dev, u32 seqno), - - TP_ARGS(dev, seqno) -); - -DEFINE_EVENT(radeon_fence_request, radeon_fence_retire, - - TP_PROTO(struct drm_device *dev, u32 seqno), - - TP_ARGS(dev, seqno) -); - -DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_begin, - - TP_PROTO(struct drm_device *dev, u32 seqno), - - TP_ARGS(dev, seqno) -); - -DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_end, - - TP_PROTO(struct drm_device *dev, u32 seqno), - - TP_ARGS(dev, seqno) -); - -#endif - -/* This part must be outside protection */ -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH . -#include diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace_points.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace_points.c deleted file mode 100644 index 8175993d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_trace_points.c +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright Red Hat Inc 2010. - * Author : Dave Airlie - */ -#include -#include "radeon_drm.h" -#include "radeon.h" - -#define CREATE_TRACE_POINTS -#include "radeon_trace.h" diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ttm.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ttm.c deleted file mode 100644 index f493c640..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/radeon_ttm.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Copyright 2009 Jerome Glisse. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: - * Jerome Glisse - * Thomas Hellstrom - * Dave Airlie - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "radeon_reg.h" -#include "radeon.h" - -#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - -static int radeon_ttm_debugfs_init(struct radeon_device *rdev); - -static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) -{ - struct radeon_mman *mman; - struct radeon_device *rdev; - - mman = container_of(bdev, struct radeon_mman, bdev); - rdev = container_of(mman, struct radeon_device, mman); - return rdev; -} - - -/* - * Global memory. - */ -static int radeon_ttm_mem_global_init(struct drm_global_reference *ref) -{ - return ttm_mem_global_init(ref->object); -} - -static void radeon_ttm_mem_global_release(struct drm_global_reference *ref) -{ - ttm_mem_global_release(ref->object); -} - -static int radeon_ttm_global_init(struct radeon_device *rdev) -{ - struct drm_global_reference *global_ref; - int r; - - rdev->mman.mem_global_referenced = false; - global_ref = &rdev->mman.mem_global_ref; - global_ref->global_type = DRM_GLOBAL_TTM_MEM; - global_ref->size = sizeof(struct ttm_mem_global); - global_ref->init = &radeon_ttm_mem_global_init; - global_ref->release = &radeon_ttm_mem_global_release; - r = drm_global_item_ref(global_ref); - if (r != 0) { - DRM_ERROR("Failed setting up TTM memory accounting " - "subsystem.\n"); - return r; - } - - rdev->mman.bo_global_ref.mem_glob = - rdev->mman.mem_global_ref.object; - global_ref = &rdev->mman.bo_global_ref.ref; - global_ref->global_type = DRM_GLOBAL_TTM_BO; - global_ref->size = sizeof(struct ttm_bo_global); - global_ref->init = &ttm_bo_global_init; - global_ref->release = &ttm_bo_global_release; - r = drm_global_item_ref(global_ref); - if (r != 0) { - DRM_ERROR("Failed setting up TTM BO subsystem.\n"); - drm_global_item_unref(&rdev->mman.mem_global_ref); - return r; - } - - rdev->mman.mem_global_referenced = true; - return 0; -} - -static void radeon_ttm_global_fini(struct radeon_device *rdev) -{ - if (rdev->mman.mem_global_referenced) { - drm_global_item_unref(&rdev->mman.bo_global_ref.ref); - drm_global_item_unref(&rdev->mman.mem_global_ref); - rdev->mman.mem_global_referenced = false; - } -} - -static int radeon_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags) -{ - return 0; -} - -static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ - struct radeon_device *rdev; - - rdev = radeon_get_rdev(bdev); - - switch (type) { - case TTM_PL_SYSTEM: - /* System memory */ - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_TT: - man->func = &ttm_bo_manager_func; - man->gpu_offset = rdev->mc.gtt_start; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; -#if __OS_HAS_AGP - if (rdev->flags & RADEON_IS_AGP) { - if (!(drm_core_has_AGP(rdev->ddev) && rdev->ddev->agp)) { - DRM_ERROR("AGP is not enabled for memory type %u\n", - (unsigned)type); - return -EINVAL; - } - if (!rdev->ddev->agp->cant_use_aperture) - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - } -#endif - break; - case TTM_PL_VRAM: - /* "On-card" video ram */ - man->func = &ttm_bo_manager_func; - man->gpu_offset = rdev->mc.vram_start; - man->flags = TTM_MEMTYPE_FLAG_FIXED | - TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); - return -EINVAL; - } - return 0; -} - -static void radeon_evict_flags(struct ttm_buffer_object *bo, - struct ttm_placement *placement) -{ - struct radeon_bo *rbo; - static u32 placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; - - if (!radeon_ttm_bo_is_radeon_bo(bo)) { - placement->fpfn = 0; - placement->lpfn = 0; - placement->placement = &placements; - placement->busy_placement = &placements; - placement->num_placement = 1; - placement->num_busy_placement = 1; - return; - } - rbo = container_of(bo, struct radeon_bo, tbo); - switch (bo->mem.mem_type) { - case TTM_PL_VRAM: - if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false) - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); - else - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); - break; - case TTM_PL_TT: - default: - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); - } - *placement = rbo->placement; -} - -static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) -{ - return 0; -} - -static void radeon_move_null(struct ttm_buffer_object *bo, - struct ttm_mem_reg *new_mem) -{ - struct ttm_mem_reg *old_mem = &bo->mem; - - BUG_ON(old_mem->mm_node != NULL); - *old_mem = *new_mem; - new_mem->mm_node = NULL; -} - -static int radeon_move_blit(struct ttm_buffer_object *bo, - bool evict, int no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem, - struct ttm_mem_reg *old_mem) -{ - struct radeon_device *rdev; - uint64_t old_start, new_start; - struct radeon_fence *fence; - int r, i; - - rdev = radeon_get_rdev(bo->bdev); - r = radeon_fence_create(rdev, &fence, radeon_copy_ring_index(rdev)); - if (unlikely(r)) { - return r; - } - old_start = old_mem->start << PAGE_SHIFT; - new_start = new_mem->start << PAGE_SHIFT; - - switch (old_mem->mem_type) { - case TTM_PL_VRAM: - old_start += rdev->mc.vram_start; - break; - case TTM_PL_TT: - old_start += rdev->mc.gtt_start; - break; - default: - DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); - return -EINVAL; - } - switch (new_mem->mem_type) { - case TTM_PL_VRAM: - new_start += rdev->mc.vram_start; - break; - case TTM_PL_TT: - new_start += rdev->mc.gtt_start; - break; - default: - DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); - return -EINVAL; - } - if (!rdev->ring[radeon_copy_ring_index(rdev)].ready) { - DRM_ERROR("Trying to move memory with ring turned off.\n"); - return -EINVAL; - } - - BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); - - /* sync other rings */ - if (rdev->family >= CHIP_R600) { - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - /* no need to sync to our own or unused rings */ - if (i == radeon_copy_ring_index(rdev) || !rdev->ring[i].ready) - continue; - - if (!fence->semaphore) { - r = radeon_semaphore_create(rdev, &fence->semaphore); - /* FIXME: handle semaphore error */ - if (r) - continue; - } - - r = radeon_ring_lock(rdev, &rdev->ring[i], 3); - /* FIXME: handle ring lock error */ - if (r) - continue; - radeon_semaphore_emit_signal(rdev, i, fence->semaphore); - radeon_ring_unlock_commit(rdev, &rdev->ring[i]); - - r = radeon_ring_lock(rdev, &rdev->ring[radeon_copy_ring_index(rdev)], 3); - /* FIXME: handle ring lock error */ - if (r) - continue; - radeon_semaphore_emit_wait(rdev, radeon_copy_ring_index(rdev), fence->semaphore); - radeon_ring_unlock_commit(rdev, &rdev->ring[radeon_copy_ring_index(rdev)]); - } - } - - r = radeon_copy(rdev, old_start, new_start, - new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ - fence); - /* FIXME: handle copy error */ - r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, - evict, no_wait_reserve, no_wait_gpu, new_mem); - radeon_fence_unref(&fence); - return r; -} - -static int radeon_move_vram_ram(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - struct radeon_device *rdev; - struct ttm_mem_reg *old_mem = &bo->mem; - struct ttm_mem_reg tmp_mem; - u32 placements; - struct ttm_placement placement; - int r; - - rdev = radeon_get_rdev(bo->bdev); - tmp_mem = *new_mem; - tmp_mem.mm_node = NULL; - placement.fpfn = 0; - placement.lpfn = 0; - placement.num_placement = 1; - placement.placement = &placements; - placement.num_busy_placement = 1; - placement.busy_placement = &placements; - placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; - r = ttm_bo_mem_space(bo, &placement, &tmp_mem, - interruptible, no_wait_reserve, no_wait_gpu); - if (unlikely(r)) { - return r; - } - - r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement); - if (unlikely(r)) { - goto out_cleanup; - } - - r = ttm_tt_bind(bo->ttm, &tmp_mem); - if (unlikely(r)) { - goto out_cleanup; - } - r = radeon_move_blit(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem, old_mem); - if (unlikely(r)) { - goto out_cleanup; - } - r = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, new_mem); -out_cleanup: - ttm_bo_mem_put(bo, &tmp_mem); - return r; -} - -static int radeon_move_ram_vram(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - struct radeon_device *rdev; - struct ttm_mem_reg *old_mem = &bo->mem; - struct ttm_mem_reg tmp_mem; - struct ttm_placement placement; - u32 placements; - int r; - - rdev = radeon_get_rdev(bo->bdev); - tmp_mem = *new_mem; - tmp_mem.mm_node = NULL; - placement.fpfn = 0; - placement.lpfn = 0; - placement.num_placement = 1; - placement.placement = &placements; - placement.num_busy_placement = 1; - placement.busy_placement = &placements; - placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; - r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait_reserve, no_wait_gpu); - if (unlikely(r)) { - return r; - } - r = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem); - if (unlikely(r)) { - goto out_cleanup; - } - r = radeon_move_blit(bo, true, no_wait_reserve, no_wait_gpu, new_mem, old_mem); - if (unlikely(r)) { - goto out_cleanup; - } -out_cleanup: - ttm_bo_mem_put(bo, &tmp_mem); - return r; -} - -static int radeon_bo_move(struct ttm_buffer_object *bo, - bool evict, bool interruptible, - bool no_wait_reserve, bool no_wait_gpu, - struct ttm_mem_reg *new_mem) -{ - struct radeon_device *rdev; - struct ttm_mem_reg *old_mem = &bo->mem; - int r; - - rdev = radeon_get_rdev(bo->bdev); - if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { - radeon_move_null(bo, new_mem); - return 0; - } - if ((old_mem->mem_type == TTM_PL_TT && - new_mem->mem_type == TTM_PL_SYSTEM) || - (old_mem->mem_type == TTM_PL_SYSTEM && - new_mem->mem_type == TTM_PL_TT)) { - /* bind is enough */ - radeon_move_null(bo, new_mem); - return 0; - } - if (!rdev->ring[radeon_copy_ring_index(rdev)].ready || - rdev->asic->copy.copy == NULL) { - /* use memcpy */ - goto memcpy; - } - - if (old_mem->mem_type == TTM_PL_VRAM && - new_mem->mem_type == TTM_PL_SYSTEM) { - r = radeon_move_vram_ram(bo, evict, interruptible, - no_wait_reserve, no_wait_gpu, new_mem); - } else if (old_mem->mem_type == TTM_PL_SYSTEM && - new_mem->mem_type == TTM_PL_VRAM) { - r = radeon_move_ram_vram(bo, evict, interruptible, - no_wait_reserve, no_wait_gpu, new_mem); - } else { - r = radeon_move_blit(bo, evict, no_wait_reserve, no_wait_gpu, new_mem, old_mem); - } - - if (r) { -memcpy: - r = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); - } - return r; -} - -static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct radeon_device *rdev = radeon_get_rdev(bdev); - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - return 0; - case TTM_PL_TT: -#if __OS_HAS_AGP - if (rdev->flags & RADEON_IS_AGP) { - /* RADEON_IS_AGP is set only if AGP is active */ - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = rdev->mc.agp_base; - mem->bus.is_iomem = !rdev->ddev->agp->cant_use_aperture; - } -#endif - break; - case TTM_PL_VRAM: - mem->bus.offset = mem->start << PAGE_SHIFT; - /* check if it's visible */ - if ((mem->bus.offset + mem->bus.size) > rdev->mc.visible_vram_size) - return -EINVAL; - mem->bus.base = rdev->mc.aper_base; - mem->bus.is_iomem = true; -#ifdef __alpha__ - /* - * Alpha: use bus.addr to hold the ioremap() return, - * so we can modify bus.base below. - */ - if (mem->placement & TTM_PL_FLAG_WC) - mem->bus.addr = - ioremap_wc(mem->bus.base + mem->bus.offset, - mem->bus.size); - else - mem->bus.addr = - ioremap_nocache(mem->bus.base + mem->bus.offset, - mem->bus.size); - - /* - * Alpha: Use just the bus offset plus - * the hose/domain memory base for bus.base. - * It then can be used to build PTEs for VRAM - * access, as done in ttm_bo_vm_fault(). - */ - mem->bus.base = (mem->bus.base & 0x0ffffffffUL) + - rdev->ddev->hose->dense_mem_base; -#endif - break; - default: - return -EINVAL; - } - return 0; -} - -static void radeon_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) -{ -} - -static int radeon_sync_obj_wait(void *sync_obj, void *sync_arg, - bool lazy, bool interruptible) -{ - return radeon_fence_wait((struct radeon_fence *)sync_obj, interruptible); -} - -static int radeon_sync_obj_flush(void *sync_obj, void *sync_arg) -{ - return 0; -} - -static void radeon_sync_obj_unref(void **sync_obj) -{ - radeon_fence_unref((struct radeon_fence **)sync_obj); -} - -static void *radeon_sync_obj_ref(void *sync_obj) -{ - return radeon_fence_ref((struct radeon_fence *)sync_obj); -} - -static bool radeon_sync_obj_signaled(void *sync_obj, void *sync_arg) -{ - return radeon_fence_signaled((struct radeon_fence *)sync_obj); -} - -/* - * TTM backend functions. - */ -struct radeon_ttm_tt { - struct ttm_dma_tt ttm; - struct radeon_device *rdev; - u64 offset; -}; - -static int radeon_ttm_backend_bind(struct ttm_tt *ttm, - struct ttm_mem_reg *bo_mem) -{ - struct radeon_ttm_tt *gtt = (void*)ttm; - int r; - - gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); - if (!ttm->num_pages) { - WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", - ttm->num_pages, bo_mem, ttm); - } - r = radeon_gart_bind(gtt->rdev, gtt->offset, - ttm->num_pages, ttm->pages, gtt->ttm.dma_address); - if (r) { - DRM_ERROR("failed to bind %lu pages at 0x%08X\n", - ttm->num_pages, (unsigned)gtt->offset); - return r; - } - return 0; -} - -static int radeon_ttm_backend_unbind(struct ttm_tt *ttm) -{ - struct radeon_ttm_tt *gtt = (void *)ttm; - - radeon_gart_unbind(gtt->rdev, gtt->offset, ttm->num_pages); - return 0; -} - -static void radeon_ttm_backend_destroy(struct ttm_tt *ttm) -{ - struct radeon_ttm_tt *gtt = (void *)ttm; - - ttm_dma_tt_fini(>t->ttm); - kfree(gtt); -} - -static struct ttm_backend_func radeon_backend_func = { - .bind = &radeon_ttm_backend_bind, - .unbind = &radeon_ttm_backend_unbind, - .destroy = &radeon_ttm_backend_destroy, -}; - -struct ttm_tt *radeon_ttm_tt_create(struct ttm_bo_device *bdev, - unsigned long size, uint32_t page_flags, - struct page *dummy_read_page) -{ - struct radeon_device *rdev; - struct radeon_ttm_tt *gtt; - - rdev = radeon_get_rdev(bdev); -#if __OS_HAS_AGP - if (rdev->flags & RADEON_IS_AGP) { - return ttm_agp_tt_create(bdev, rdev->ddev->agp->bridge, - size, page_flags, dummy_read_page); - } -#endif - - gtt = kzalloc(sizeof(struct radeon_ttm_tt), GFP_KERNEL); - if (gtt == NULL) { - return NULL; - } - gtt->ttm.ttm.func = &radeon_backend_func; - gtt->rdev = rdev; - if (ttm_dma_tt_init(>t->ttm, bdev, size, page_flags, dummy_read_page)) { - kfree(gtt); - return NULL; - } - return >t->ttm.ttm; -} - -static int radeon_ttm_tt_populate(struct ttm_tt *ttm) -{ - struct radeon_device *rdev; - struct radeon_ttm_tt *gtt = (void *)ttm; - unsigned i; - int r; - - if (ttm->state != tt_unpopulated) - return 0; - - rdev = radeon_get_rdev(ttm->bdev); -#if __OS_HAS_AGP - if (rdev->flags & RADEON_IS_AGP) { - return ttm_agp_tt_populate(ttm); - } -#endif - -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { - return ttm_dma_populate(>t->ttm, rdev->dev); - } -#endif - - r = ttm_pool_populate(ttm); - if (r) { - return r; - } - - for (i = 0; i < ttm->num_pages; i++) { - gtt->ttm.dma_address[i] = pci_map_page(rdev->pdev, ttm->pages[i], - 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(rdev->pdev, gtt->ttm.dma_address[i])) { - while (--i) { - pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - gtt->ttm.dma_address[i] = 0; - } - ttm_pool_unpopulate(ttm); - return -EFAULT; - } - } - return 0; -} - -static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm) -{ - struct radeon_device *rdev; - struct radeon_ttm_tt *gtt = (void *)ttm; - unsigned i; - - rdev = radeon_get_rdev(ttm->bdev); -#if __OS_HAS_AGP - if (rdev->flags & RADEON_IS_AGP) { - ttm_agp_tt_unpopulate(ttm); - return; - } -#endif - -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { - ttm_dma_unpopulate(>t->ttm, rdev->dev); - return; - } -#endif - - for (i = 0; i < ttm->num_pages; i++) { - if (gtt->ttm.dma_address[i]) { - pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - } - } - - ttm_pool_unpopulate(ttm); -} - -static struct ttm_bo_driver radeon_bo_driver = { - .ttm_tt_create = &radeon_ttm_tt_create, - .ttm_tt_populate = &radeon_ttm_tt_populate, - .ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate, - .invalidate_caches = &radeon_invalidate_caches, - .init_mem_type = &radeon_init_mem_type, - .evict_flags = &radeon_evict_flags, - .move = &radeon_bo_move, - .verify_access = &radeon_verify_access, - .sync_obj_signaled = &radeon_sync_obj_signaled, - .sync_obj_wait = &radeon_sync_obj_wait, - .sync_obj_flush = &radeon_sync_obj_flush, - .sync_obj_unref = &radeon_sync_obj_unref, - .sync_obj_ref = &radeon_sync_obj_ref, - .move_notify = &radeon_bo_move_notify, - .fault_reserve_notify = &radeon_bo_fault_reserve_notify, - .io_mem_reserve = &radeon_ttm_io_mem_reserve, - .io_mem_free = &radeon_ttm_io_mem_free, -}; - -int radeon_ttm_init(struct radeon_device *rdev) -{ - int r; - - r = radeon_ttm_global_init(rdev); - if (r) { - return r; - } - /* No others user of address space so set it to 0 */ - r = ttm_bo_device_init(&rdev->mman.bdev, - rdev->mman.bo_global_ref.ref.object, - &radeon_bo_driver, DRM_FILE_PAGE_OFFSET, - rdev->need_dma32); - if (r) { - DRM_ERROR("failed initializing buffer object driver(%d).\n", r); - return r; - } - rdev->mman.initialized = true; - r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM, - rdev->mc.real_vram_size >> PAGE_SHIFT); - if (r) { - DRM_ERROR("Failed initializing VRAM heap.\n"); - return r; - } - r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_VRAM, - &rdev->stollen_vga_memory); - if (r) { - return r; - } - r = radeon_bo_reserve(rdev->stollen_vga_memory, false); - if (r) - return r; - r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL); - radeon_bo_unreserve(rdev->stollen_vga_memory); - if (r) { - radeon_bo_unref(&rdev->stollen_vga_memory); - return r; - } - DRM_INFO("radeon: %uM of VRAM memory ready\n", - (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); - r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, - rdev->mc.gtt_size >> PAGE_SHIFT); - if (r) { - DRM_ERROR("Failed initializing GTT heap.\n"); - return r; - } - DRM_INFO("radeon: %uM of GTT memory ready.\n", - (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); - if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { - rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; - } - - r = radeon_ttm_debugfs_init(rdev); - if (r) { - DRM_ERROR("Failed to init debugfs\n"); - return r; - } - return 0; -} - -void radeon_ttm_fini(struct radeon_device *rdev) -{ - int r; - - if (!rdev->mman.initialized) - return; - if (rdev->stollen_vga_memory) { - r = radeon_bo_reserve(rdev->stollen_vga_memory, false); - if (r == 0) { - radeon_bo_unpin(rdev->stollen_vga_memory); - radeon_bo_unreserve(rdev->stollen_vga_memory); - } - radeon_bo_unref(&rdev->stollen_vga_memory); - } - ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM); - ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT); - ttm_bo_device_release(&rdev->mman.bdev); - radeon_gart_fini(rdev); - radeon_ttm_global_fini(rdev); - rdev->mman.initialized = false; - DRM_INFO("radeon: ttm finalized\n"); -} - -/* this should only be called at bootup or when userspace - * isn't running */ -void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) -{ - struct ttm_mem_type_manager *man; - - if (!rdev->mman.initialized) - return; - - man = &rdev->mman.bdev.man[TTM_PL_VRAM]; - /* this just adjusts TTM size idea, which sets lpfn to the correct value */ - man->size = size >> PAGE_SHIFT; -} - -static struct vm_operations_struct radeon_ttm_vm_ops; -static const struct vm_operations_struct *ttm_vm_ops = NULL; - -static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -{ - struct ttm_buffer_object *bo; - struct radeon_device *rdev; - int r; - - bo = (struct ttm_buffer_object *)vma->vm_private_data; - if (bo == NULL) { - return VM_FAULT_NOPAGE; - } - rdev = radeon_get_rdev(bo->bdev); - mutex_lock(&rdev->vram_mutex); - r = ttm_vm_ops->fault(vma, vmf); - mutex_unlock(&rdev->vram_mutex); - return r; -} - -int radeon_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv; - struct radeon_device *rdev; - int r; - - if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) { - return drm_mmap(filp, vma); - } - - file_priv = filp->private_data; - rdev = file_priv->minor->dev->dev_private; - if (rdev == NULL) { - return -EINVAL; - } - r = ttm_bo_mmap(filp, vma, &rdev->mman.bdev); - if (unlikely(r != 0)) { - return r; - } - if (unlikely(ttm_vm_ops == NULL)) { - ttm_vm_ops = vma->vm_ops; - radeon_ttm_vm_ops = *ttm_vm_ops; - radeon_ttm_vm_ops.fault = &radeon_ttm_fault; - } - vma->vm_ops = &radeon_ttm_vm_ops; - return 0; -} - - -#define RADEON_DEBUGFS_MEM_TYPES 2 - -#if defined(CONFIG_DEBUG_FS) -static int radeon_mm_dump_table(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *)m->private; - struct drm_mm *mm = (struct drm_mm *)node->info_ent->data; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - int ret; - struct ttm_bo_global *glob = rdev->mman.bdev.glob; - - spin_lock(&glob->lru_lock); - ret = drm_mm_dump_table(m, mm); - spin_unlock(&glob->lru_lock); - return ret; -} -#endif - -static int radeon_ttm_debugfs_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES+2]; - static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES+2][32]; - unsigned i; - - for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { - if (i == 0) - sprintf(radeon_mem_types_names[i], "radeon_vram_mm"); - else - sprintf(radeon_mem_types_names[i], "radeon_gtt_mm"); - radeon_mem_types_list[i].name = radeon_mem_types_names[i]; - radeon_mem_types_list[i].show = &radeon_mm_dump_table; - radeon_mem_types_list[i].driver_features = 0; - if (i == 0) - radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; - else - radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; - - } - /* Add ttm page pool to debugfs */ - sprintf(radeon_mem_types_names[i], "ttm_page_pool"); - radeon_mem_types_list[i].name = radeon_mem_types_names[i]; - radeon_mem_types_list[i].show = &ttm_page_alloc_debugfs; - radeon_mem_types_list[i].driver_features = 0; - radeon_mem_types_list[i++].data = NULL; -#ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { - sprintf(radeon_mem_types_names[i], "ttm_dma_page_pool"); - radeon_mem_types_list[i].name = radeon_mem_types_names[i]; - radeon_mem_types_list[i].show = &ttm_dma_page_alloc_debugfs; - radeon_mem_types_list[i].driver_features = 0; - radeon_mem_types_list[i++].data = NULL; - } -#endif - return radeon_debugfs_add_files(rdev, radeon_mem_types_list, i); - -#endif - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/cayman b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/cayman deleted file mode 100644 index 0f656b11..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/cayman +++ /dev/null @@ -1,641 +0,0 @@ -cayman 0x9400 -0x0000802C GRBM_GFX_INDEX -0x000084FC CP_STRMOUT_CNTL -0x000085F0 CP_COHER_CNTL -0x000085F4 CP_COHER_SIZE -0x000088B0 VGT_VTX_VECT_EJECT_REG -0x000088C4 VGT_CACHE_INVALIDATION -0x000088D4 VGT_GS_VERTEX_REUSE -0x00008958 VGT_PRIMITIVE_TYPE -0x0000895C VGT_INDEX_TYPE -0x00008970 VGT_NUM_INDICES -0x00008974 VGT_NUM_INSTANCES -0x00008990 VGT_COMPUTE_DIM_X -0x00008994 VGT_COMPUTE_DIM_Y -0x00008998 VGT_COMPUTE_DIM_Z -0x0000899C VGT_COMPUTE_START_X -0x000089A0 VGT_COMPUTE_START_Y -0x000089A4 VGT_COMPUTE_START_Z -0x000089A8 VGT_COMPUTE_INDEX -0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE -0x000089B0 VGT_HS_OFFCHIP_PARAM -0x00008A14 PA_CL_ENHANCE -0x00008A60 PA_SC_LINE_STIPPLE_VALUE -0x00008B10 PA_SC_LINE_STIPPLE_STATE -0x00008BF0 PA_SC_ENHANCE -0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ -0x00008D94 SQ_DYN_GPR_SIMD_LOCK_EN -0x00008C00 SQ_CONFIG -0x00008C04 SQ_GPR_RESOURCE_MGMT_1 -0x00008C10 SQ_GLOBAL_GPR_RESOURCE_MGMT_1 -0x00008C14 SQ_GLOBAL_GPR_RESOURCE_MGMT_2 -0x00008DF8 SQ_CONST_MEM_BASE -0x00008E20 SQ_STATIC_THREAD_MGMT_1 -0x00008E24 SQ_STATIC_THREAD_MGMT_2 -0x00008E28 SQ_STATIC_THREAD_MGMT_3 -0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS -0x00009100 SPI_CONFIG_CNTL -0x0000913C SPI_CONFIG_CNTL_1 -0x00009508 TA_CNTL_AUX -0x00009830 DB_DEBUG -0x00009834 DB_DEBUG2 -0x00009838 DB_DEBUG3 -0x0000983C DB_DEBUG4 -0x00009854 DB_WATERMARKS -0x0000A400 TD_PS_BORDER_COLOR_INDEX -0x0000A404 TD_PS_BORDER_COLOR_RED -0x0000A408 TD_PS_BORDER_COLOR_GREEN -0x0000A40C TD_PS_BORDER_COLOR_BLUE -0x0000A410 TD_PS_BORDER_COLOR_ALPHA -0x0000A414 TD_VS_BORDER_COLOR_INDEX -0x0000A418 TD_VS_BORDER_COLOR_RED -0x0000A41C TD_VS_BORDER_COLOR_GREEN -0x0000A420 TD_VS_BORDER_COLOR_BLUE -0x0000A424 TD_VS_BORDER_COLOR_ALPHA -0x0000A428 TD_GS_BORDER_COLOR_INDEX -0x0000A42C TD_GS_BORDER_COLOR_RED -0x0000A430 TD_GS_BORDER_COLOR_GREEN -0x0000A434 TD_GS_BORDER_COLOR_BLUE -0x0000A438 TD_GS_BORDER_COLOR_ALPHA -0x0000A43C TD_HS_BORDER_COLOR_INDEX -0x0000A440 TD_HS_BORDER_COLOR_RED -0x0000A444 TD_HS_BORDER_COLOR_GREEN -0x0000A448 TD_HS_BORDER_COLOR_BLUE -0x0000A44C TD_HS_BORDER_COLOR_ALPHA -0x0000A450 TD_LS_BORDER_COLOR_INDEX -0x0000A454 TD_LS_BORDER_COLOR_RED -0x0000A458 TD_LS_BORDER_COLOR_GREEN -0x0000A45C TD_LS_BORDER_COLOR_BLUE -0x0000A460 TD_LS_BORDER_COLOR_ALPHA -0x0000A464 TD_CS_BORDER_COLOR_INDEX -0x0000A468 TD_CS_BORDER_COLOR_RED -0x0000A46C TD_CS_BORDER_COLOR_GREEN -0x0000A470 TD_CS_BORDER_COLOR_BLUE -0x0000A474 TD_CS_BORDER_COLOR_ALPHA -0x00028000 DB_RENDER_CONTROL -0x00028004 DB_COUNT_CONTROL -0x0002800C DB_RENDER_OVERRIDE -0x00028010 DB_RENDER_OVERRIDE2 -0x00028028 DB_STENCIL_CLEAR -0x0002802C DB_DEPTH_CLEAR -0x00028030 PA_SC_SCREEN_SCISSOR_TL -0x00028034 PA_SC_SCREEN_SCISSOR_BR -0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 -0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 -0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 -0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3 -0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4 -0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5 -0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6 -0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7 -0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8 -0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9 -0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10 -0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11 -0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12 -0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13 -0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14 -0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15 -0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0 -0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1 -0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2 -0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3 -0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4 -0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5 -0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6 -0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7 -0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8 -0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9 -0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10 -0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11 -0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12 -0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13 -0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14 -0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15 -0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0 -0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1 -0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2 -0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3 -0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4 -0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5 -0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6 -0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7 -0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8 -0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9 -0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10 -0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11 -0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12 -0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13 -0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14 -0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15 -0x00028200 PA_SC_WINDOW_OFFSET -0x00028204 PA_SC_WINDOW_SCISSOR_TL -0x00028208 PA_SC_WINDOW_SCISSOR_BR -0x0002820C PA_SC_CLIPRECT_RULE -0x00028210 PA_SC_CLIPRECT_0_TL -0x00028214 PA_SC_CLIPRECT_0_BR -0x00028218 PA_SC_CLIPRECT_1_TL -0x0002821C PA_SC_CLIPRECT_1_BR -0x00028220 PA_SC_CLIPRECT_2_TL -0x00028224 PA_SC_CLIPRECT_2_BR -0x00028228 PA_SC_CLIPRECT_3_TL -0x0002822C PA_SC_CLIPRECT_3_BR -0x00028230 PA_SC_EDGERULE -0x00028234 PA_SU_HARDWARE_SCREEN_OFFSET -0x00028240 PA_SC_GENERIC_SCISSOR_TL -0x00028244 PA_SC_GENERIC_SCISSOR_BR -0x00028250 PA_SC_VPORT_SCISSOR_0_TL -0x00028254 PA_SC_VPORT_SCISSOR_0_BR -0x00028258 PA_SC_VPORT_SCISSOR_1_TL -0x0002825C PA_SC_VPORT_SCISSOR_1_BR -0x00028260 PA_SC_VPORT_SCISSOR_2_TL -0x00028264 PA_SC_VPORT_SCISSOR_2_BR -0x00028268 PA_SC_VPORT_SCISSOR_3_TL -0x0002826C PA_SC_VPORT_SCISSOR_3_BR -0x00028270 PA_SC_VPORT_SCISSOR_4_TL -0x00028274 PA_SC_VPORT_SCISSOR_4_BR -0x00028278 PA_SC_VPORT_SCISSOR_5_TL -0x0002827C PA_SC_VPORT_SCISSOR_5_BR -0x00028280 PA_SC_VPORT_SCISSOR_6_TL -0x00028284 PA_SC_VPORT_SCISSOR_6_BR -0x00028288 PA_SC_VPORT_SCISSOR_7_TL -0x0002828C PA_SC_VPORT_SCISSOR_7_BR -0x00028290 PA_SC_VPORT_SCISSOR_8_TL -0x00028294 PA_SC_VPORT_SCISSOR_8_BR -0x00028298 PA_SC_VPORT_SCISSOR_9_TL -0x0002829C PA_SC_VPORT_SCISSOR_9_BR -0x000282A0 PA_SC_VPORT_SCISSOR_10_TL -0x000282A4 PA_SC_VPORT_SCISSOR_10_BR -0x000282A8 PA_SC_VPORT_SCISSOR_11_TL -0x000282AC PA_SC_VPORT_SCISSOR_11_BR -0x000282B0 PA_SC_VPORT_SCISSOR_12_TL -0x000282B4 PA_SC_VPORT_SCISSOR_12_BR -0x000282B8 PA_SC_VPORT_SCISSOR_13_TL -0x000282BC PA_SC_VPORT_SCISSOR_13_BR -0x000282C0 PA_SC_VPORT_SCISSOR_14_TL -0x000282C4 PA_SC_VPORT_SCISSOR_14_BR -0x000282C8 PA_SC_VPORT_SCISSOR_15_TL -0x000282CC PA_SC_VPORT_SCISSOR_15_BR -0x000282D0 PA_SC_VPORT_ZMIN_0 -0x000282D4 PA_SC_VPORT_ZMAX_0 -0x000282D8 PA_SC_VPORT_ZMIN_1 -0x000282DC PA_SC_VPORT_ZMAX_1 -0x000282E0 PA_SC_VPORT_ZMIN_2 -0x000282E4 PA_SC_VPORT_ZMAX_2 -0x000282E8 PA_SC_VPORT_ZMIN_3 -0x000282EC PA_SC_VPORT_ZMAX_3 -0x000282F0 PA_SC_VPORT_ZMIN_4 -0x000282F4 PA_SC_VPORT_ZMAX_4 -0x000282F8 PA_SC_VPORT_ZMIN_5 -0x000282FC PA_SC_VPORT_ZMAX_5 -0x00028300 PA_SC_VPORT_ZMIN_6 -0x00028304 PA_SC_VPORT_ZMAX_6 -0x00028308 PA_SC_VPORT_ZMIN_7 -0x0002830C PA_SC_VPORT_ZMAX_7 -0x00028310 PA_SC_VPORT_ZMIN_8 -0x00028314 PA_SC_VPORT_ZMAX_8 -0x00028318 PA_SC_VPORT_ZMIN_9 -0x0002831C PA_SC_VPORT_ZMAX_9 -0x00028320 PA_SC_VPORT_ZMIN_10 -0x00028324 PA_SC_VPORT_ZMAX_10 -0x00028328 PA_SC_VPORT_ZMIN_11 -0x0002832C PA_SC_VPORT_ZMAX_11 -0x00028330 PA_SC_VPORT_ZMIN_12 -0x00028334 PA_SC_VPORT_ZMAX_12 -0x00028338 PA_SC_VPORT_ZMIN_13 -0x0002833C PA_SC_VPORT_ZMAX_13 -0x00028340 PA_SC_VPORT_ZMIN_14 -0x00028344 PA_SC_VPORT_ZMAX_14 -0x00028348 PA_SC_VPORT_ZMIN_15 -0x0002834C PA_SC_VPORT_ZMAX_15 -0x00028354 SX_SURFACE_SYNC -0x0002835C SX_SCATTER_EXPORT_SIZE -0x00028380 SQ_VTX_SEMANTIC_0 -0x00028384 SQ_VTX_SEMANTIC_1 -0x00028388 SQ_VTX_SEMANTIC_2 -0x0002838C SQ_VTX_SEMANTIC_3 -0x00028390 SQ_VTX_SEMANTIC_4 -0x00028394 SQ_VTX_SEMANTIC_5 -0x00028398 SQ_VTX_SEMANTIC_6 -0x0002839C SQ_VTX_SEMANTIC_7 -0x000283A0 SQ_VTX_SEMANTIC_8 -0x000283A4 SQ_VTX_SEMANTIC_9 -0x000283A8 SQ_VTX_SEMANTIC_10 -0x000283AC SQ_VTX_SEMANTIC_11 -0x000283B0 SQ_VTX_SEMANTIC_12 -0x000283B4 SQ_VTX_SEMANTIC_13 -0x000283B8 SQ_VTX_SEMANTIC_14 -0x000283BC SQ_VTX_SEMANTIC_15 -0x000283C0 SQ_VTX_SEMANTIC_16 -0x000283C4 SQ_VTX_SEMANTIC_17 -0x000283C8 SQ_VTX_SEMANTIC_18 -0x000283CC SQ_VTX_SEMANTIC_19 -0x000283D0 SQ_VTX_SEMANTIC_20 -0x000283D4 SQ_VTX_SEMANTIC_21 -0x000283D8 SQ_VTX_SEMANTIC_22 -0x000283DC SQ_VTX_SEMANTIC_23 -0x000283E0 SQ_VTX_SEMANTIC_24 -0x000283E4 SQ_VTX_SEMANTIC_25 -0x000283E8 SQ_VTX_SEMANTIC_26 -0x000283EC SQ_VTX_SEMANTIC_27 -0x000283F0 SQ_VTX_SEMANTIC_28 -0x000283F4 SQ_VTX_SEMANTIC_29 -0x000283F8 SQ_VTX_SEMANTIC_30 -0x000283FC SQ_VTX_SEMANTIC_31 -0x00028400 VGT_MAX_VTX_INDX -0x00028404 VGT_MIN_VTX_INDX -0x00028408 VGT_INDX_OFFSET -0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX -0x00028410 SX_ALPHA_TEST_CONTROL -0x00028414 CB_BLEND_RED -0x00028418 CB_BLEND_GREEN -0x0002841C CB_BLEND_BLUE -0x00028420 CB_BLEND_ALPHA -0x00028430 DB_STENCILREFMASK -0x00028434 DB_STENCILREFMASK_BF -0x00028438 SX_ALPHA_REF -0x0002843C PA_CL_VPORT_XSCALE_0 -0x00028440 PA_CL_VPORT_XOFFSET_0 -0x00028444 PA_CL_VPORT_YSCALE_0 -0x00028448 PA_CL_VPORT_YOFFSET_0 -0x0002844C PA_CL_VPORT_ZSCALE_0 -0x00028450 PA_CL_VPORT_ZOFFSET_0 -0x00028454 PA_CL_VPORT_XSCALE_1 -0x00028458 PA_CL_VPORT_XOFFSET_1 -0x0002845C PA_CL_VPORT_YSCALE_1 -0x00028460 PA_CL_VPORT_YOFFSET_1 -0x00028464 PA_CL_VPORT_ZSCALE_1 -0x00028468 PA_CL_VPORT_ZOFFSET_1 -0x0002846C PA_CL_VPORT_XSCALE_2 -0x00028470 PA_CL_VPORT_XOFFSET_2 -0x00028474 PA_CL_VPORT_YSCALE_2 -0x00028478 PA_CL_VPORT_YOFFSET_2 -0x0002847C PA_CL_VPORT_ZSCALE_2 -0x00028480 PA_CL_VPORT_ZOFFSET_2 -0x00028484 PA_CL_VPORT_XSCALE_3 -0x00028488 PA_CL_VPORT_XOFFSET_3 -0x0002848C PA_CL_VPORT_YSCALE_3 -0x00028490 PA_CL_VPORT_YOFFSET_3 -0x00028494 PA_CL_VPORT_ZSCALE_3 -0x00028498 PA_CL_VPORT_ZOFFSET_3 -0x0002849C PA_CL_VPORT_XSCALE_4 -0x000284A0 PA_CL_VPORT_XOFFSET_4 -0x000284A4 PA_CL_VPORT_YSCALE_4 -0x000284A8 PA_CL_VPORT_YOFFSET_4 -0x000284AC PA_CL_VPORT_ZSCALE_4 -0x000284B0 PA_CL_VPORT_ZOFFSET_4 -0x000284B4 PA_CL_VPORT_XSCALE_5 -0x000284B8 PA_CL_VPORT_XOFFSET_5 -0x000284BC PA_CL_VPORT_YSCALE_5 -0x000284C0 PA_CL_VPORT_YOFFSET_5 -0x000284C4 PA_CL_VPORT_ZSCALE_5 -0x000284C8 PA_CL_VPORT_ZOFFSET_5 -0x000284CC PA_CL_VPORT_XSCALE_6 -0x000284D0 PA_CL_VPORT_XOFFSET_6 -0x000284D4 PA_CL_VPORT_YSCALE_6 -0x000284D8 PA_CL_VPORT_YOFFSET_6 -0x000284DC PA_CL_VPORT_ZSCALE_6 -0x000284E0 PA_CL_VPORT_ZOFFSET_6 -0x000284E4 PA_CL_VPORT_XSCALE_7 -0x000284E8 PA_CL_VPORT_XOFFSET_7 -0x000284EC PA_CL_VPORT_YSCALE_7 -0x000284F0 PA_CL_VPORT_YOFFSET_7 -0x000284F4 PA_CL_VPORT_ZSCALE_7 -0x000284F8 PA_CL_VPORT_ZOFFSET_7 -0x000284FC PA_CL_VPORT_XSCALE_8 -0x00028500 PA_CL_VPORT_XOFFSET_8 -0x00028504 PA_CL_VPORT_YSCALE_8 -0x00028508 PA_CL_VPORT_YOFFSET_8 -0x0002850C PA_CL_VPORT_ZSCALE_8 -0x00028510 PA_CL_VPORT_ZOFFSET_8 -0x00028514 PA_CL_VPORT_XSCALE_9 -0x00028518 PA_CL_VPORT_XOFFSET_9 -0x0002851C PA_CL_VPORT_YSCALE_9 -0x00028520 PA_CL_VPORT_YOFFSET_9 -0x00028524 PA_CL_VPORT_ZSCALE_9 -0x00028528 PA_CL_VPORT_ZOFFSET_9 -0x0002852C PA_CL_VPORT_XSCALE_10 -0x00028530 PA_CL_VPORT_XOFFSET_10 -0x00028534 PA_CL_VPORT_YSCALE_10 -0x00028538 PA_CL_VPORT_YOFFSET_10 -0x0002853C PA_CL_VPORT_ZSCALE_10 -0x00028540 PA_CL_VPORT_ZOFFSET_10 -0x00028544 PA_CL_VPORT_XSCALE_11 -0x00028548 PA_CL_VPORT_XOFFSET_11 -0x0002854C PA_CL_VPORT_YSCALE_11 -0x00028550 PA_CL_VPORT_YOFFSET_11 -0x00028554 PA_CL_VPORT_ZSCALE_11 -0x00028558 PA_CL_VPORT_ZOFFSET_11 -0x0002855C PA_CL_VPORT_XSCALE_12 -0x00028560 PA_CL_VPORT_XOFFSET_12 -0x00028564 PA_CL_VPORT_YSCALE_12 -0x00028568 PA_CL_VPORT_YOFFSET_12 -0x0002856C PA_CL_VPORT_ZSCALE_12 -0x00028570 PA_CL_VPORT_ZOFFSET_12 -0x00028574 PA_CL_VPORT_XSCALE_13 -0x00028578 PA_CL_VPORT_XOFFSET_13 -0x0002857C PA_CL_VPORT_YSCALE_13 -0x00028580 PA_CL_VPORT_YOFFSET_13 -0x00028584 PA_CL_VPORT_ZSCALE_13 -0x00028588 PA_CL_VPORT_ZOFFSET_13 -0x0002858C PA_CL_VPORT_XSCALE_14 -0x00028590 PA_CL_VPORT_XOFFSET_14 -0x00028594 PA_CL_VPORT_YSCALE_14 -0x00028598 PA_CL_VPORT_YOFFSET_14 -0x0002859C PA_CL_VPORT_ZSCALE_14 -0x000285A0 PA_CL_VPORT_ZOFFSET_14 -0x000285A4 PA_CL_VPORT_XSCALE_15 -0x000285A8 PA_CL_VPORT_XOFFSET_15 -0x000285AC PA_CL_VPORT_YSCALE_15 -0x000285B0 PA_CL_VPORT_YOFFSET_15 -0x000285B4 PA_CL_VPORT_ZSCALE_15 -0x000285B8 PA_CL_VPORT_ZOFFSET_15 -0x000285BC PA_CL_UCP_0_X -0x000285C0 PA_CL_UCP_0_Y -0x000285C4 PA_CL_UCP_0_Z -0x000285C8 PA_CL_UCP_0_W -0x000285CC PA_CL_UCP_1_X -0x000285D0 PA_CL_UCP_1_Y -0x000285D4 PA_CL_UCP_1_Z -0x000285D8 PA_CL_UCP_1_W -0x000285DC PA_CL_UCP_2_X -0x000285E0 PA_CL_UCP_2_Y -0x000285E4 PA_CL_UCP_2_Z -0x000285E8 PA_CL_UCP_2_W -0x000285EC PA_CL_UCP_3_X -0x000285F0 PA_CL_UCP_3_Y -0x000285F4 PA_CL_UCP_3_Z -0x000285F8 PA_CL_UCP_3_W -0x000285FC PA_CL_UCP_4_X -0x00028600 PA_CL_UCP_4_Y -0x00028604 PA_CL_UCP_4_Z -0x00028608 PA_CL_UCP_4_W -0x0002860C PA_CL_UCP_5_X -0x00028610 PA_CL_UCP_5_Y -0x00028614 PA_CL_UCP_5_Z -0x00028618 PA_CL_UCP_5_W -0x0002861C SPI_VS_OUT_ID_0 -0x00028620 SPI_VS_OUT_ID_1 -0x00028624 SPI_VS_OUT_ID_2 -0x00028628 SPI_VS_OUT_ID_3 -0x0002862C SPI_VS_OUT_ID_4 -0x00028630 SPI_VS_OUT_ID_5 -0x00028634 SPI_VS_OUT_ID_6 -0x00028638 SPI_VS_OUT_ID_7 -0x0002863C SPI_VS_OUT_ID_8 -0x00028640 SPI_VS_OUT_ID_9 -0x00028644 SPI_PS_INPUT_CNTL_0 -0x00028648 SPI_PS_INPUT_CNTL_1 -0x0002864C SPI_PS_INPUT_CNTL_2 -0x00028650 SPI_PS_INPUT_CNTL_3 -0x00028654 SPI_PS_INPUT_CNTL_4 -0x00028658 SPI_PS_INPUT_CNTL_5 -0x0002865C SPI_PS_INPUT_CNTL_6 -0x00028660 SPI_PS_INPUT_CNTL_7 -0x00028664 SPI_PS_INPUT_CNTL_8 -0x00028668 SPI_PS_INPUT_CNTL_9 -0x0002866C SPI_PS_INPUT_CNTL_10 -0x00028670 SPI_PS_INPUT_CNTL_11 -0x00028674 SPI_PS_INPUT_CNTL_12 -0x00028678 SPI_PS_INPUT_CNTL_13 -0x0002867C SPI_PS_INPUT_CNTL_14 -0x00028680 SPI_PS_INPUT_CNTL_15 -0x00028684 SPI_PS_INPUT_CNTL_16 -0x00028688 SPI_PS_INPUT_CNTL_17 -0x0002868C SPI_PS_INPUT_CNTL_18 -0x00028690 SPI_PS_INPUT_CNTL_19 -0x00028694 SPI_PS_INPUT_CNTL_20 -0x00028698 SPI_PS_INPUT_CNTL_21 -0x0002869C SPI_PS_INPUT_CNTL_22 -0x000286A0 SPI_PS_INPUT_CNTL_23 -0x000286A4 SPI_PS_INPUT_CNTL_24 -0x000286A8 SPI_PS_INPUT_CNTL_25 -0x000286AC SPI_PS_INPUT_CNTL_26 -0x000286B0 SPI_PS_INPUT_CNTL_27 -0x000286B4 SPI_PS_INPUT_CNTL_28 -0x000286B8 SPI_PS_INPUT_CNTL_29 -0x000286BC SPI_PS_INPUT_CNTL_30 -0x000286C0 SPI_PS_INPUT_CNTL_31 -0x000286C4 SPI_VS_OUT_CONFIG -0x000286C8 SPI_THREAD_GROUPING -0x000286CC SPI_PS_IN_CONTROL_0 -0x000286D0 SPI_PS_IN_CONTROL_1 -0x000286D4 SPI_INTERP_CONTROL_0 -0x000286D8 SPI_INPUT_Z -0x000286DC SPI_FOG_CNTL -0x000286E0 SPI_BARYC_CNTL -0x000286E4 SPI_PS_IN_CONTROL_2 -0x000286E8 SPI_COMPUTE_INPUT_CNTL -0x000286EC SPI_COMPUTE_NUM_THREAD_X -0x000286F0 SPI_COMPUTE_NUM_THREAD_Y -0x000286F4 SPI_COMPUTE_NUM_THREAD_Z -0x000286F8 SPI_GPR_MGMT -0x000286FC SPI_LDS_MGMT -0x00028700 SPI_STACK_MGMT -0x00028704 SPI_WAVE_MGMT_1 -0x00028708 SPI_WAVE_MGMT_2 -0x00028720 GDS_ADDR_BASE -0x00028724 GDS_ADDR_SIZE -0x00028780 CB_BLEND0_CONTROL -0x00028784 CB_BLEND1_CONTROL -0x00028788 CB_BLEND2_CONTROL -0x0002878C CB_BLEND3_CONTROL -0x00028790 CB_BLEND4_CONTROL -0x00028794 CB_BLEND5_CONTROL -0x00028798 CB_BLEND6_CONTROL -0x0002879C CB_BLEND7_CONTROL -0x000287CC CS_COPY_STATE -0x000287D0 GFX_COPY_STATE -0x000287D4 PA_CL_POINT_X_RAD -0x000287D8 PA_CL_POINT_Y_RAD -0x000287DC PA_CL_POINT_SIZE -0x000287E0 PA_CL_POINT_CULL_RAD -0x00028808 CB_COLOR_CONTROL -0x0002880C DB_SHADER_CONTROL -0x00028810 PA_CL_CLIP_CNTL -0x00028814 PA_SU_SC_MODE_CNTL -0x00028818 PA_CL_VTE_CNTL -0x0002881C PA_CL_VS_OUT_CNTL -0x00028820 PA_CL_NANINF_CNTL -0x00028824 PA_SU_LINE_STIPPLE_CNTL -0x00028828 PA_SU_LINE_STIPPLE_SCALE -0x0002882C PA_SU_PRIM_FILTER_CNTL -0x00028844 SQ_PGM_RESOURCES_PS -0x00028848 SQ_PGM_RESOURCES_2_PS -0x0002884C SQ_PGM_EXPORTS_PS -0x00028860 SQ_PGM_RESOURCES_VS -0x00028864 SQ_PGM_RESOURCES_2_VS -0x00028878 SQ_PGM_RESOURCES_GS -0x0002887C SQ_PGM_RESOURCES_2_GS -0x00028890 SQ_PGM_RESOURCES_ES -0x00028894 SQ_PGM_RESOURCES_2_ES -0x000288A8 SQ_PGM_RESOURCES_FS -0x000288BC SQ_PGM_RESOURCES_HS -0x000288C0 SQ_PGM_RESOURCES_2_HS -0x000288D4 SQ_PGM_RESOURCES_LS -0x000288D8 SQ_PGM_RESOURCES_2_LS -0x000288E8 SQ_LDS_ALLOC -0x000288EC SQ_LDS_ALLOC_PS -0x000288F0 SQ_VTX_SEMANTIC_CLEAR -0x00028A00 PA_SU_POINT_SIZE -0x00028A04 PA_SU_POINT_MINMAX -0x00028A08 PA_SU_LINE_CNTL -0x00028A0C PA_SC_LINE_STIPPLE -0x00028A10 VGT_OUTPUT_PATH_CNTL -0x00028A14 VGT_HOS_CNTL -0x00028A18 VGT_HOS_MAX_TESS_LEVEL -0x00028A1C VGT_HOS_MIN_TESS_LEVEL -0x00028A20 VGT_HOS_REUSE_DEPTH -0x00028A24 VGT_GROUP_PRIM_TYPE -0x00028A28 VGT_GROUP_FIRST_DECR -0x00028A2C VGT_GROUP_DECR -0x00028A30 VGT_GROUP_VECT_0_CNTL -0x00028A34 VGT_GROUP_VECT_1_CNTL -0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL -0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL -0x00028A40 VGT_GS_MODE -0x00028A48 PA_SC_MODE_CNTL_0 -0x00028A4C PA_SC_MODE_CNTL_1 -0x00028A50 VGT_ENHANCE -0x00028A54 VGT_GS_PER_ES -0x00028A58 VGT_ES_PER_GS -0x00028A5C VGT_GS_PER_VS -0x00028A6C VGT_GS_OUT_PRIM_TYPE -0x00028A70 IA_ENHANCE -0x00028A84 VGT_PRIMITIVEID_EN -0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN -0x00028AA0 VGT_INSTANCE_STEP_RATE_0 -0x00028AA4 VGT_INSTANCE_STEP_RATE_1 -0x00028AA8 IA_MULTI_VGT_PARAM -0x00028AB4 VGT_REUSE_OFF -0x00028AB8 VGT_VTX_CNT_EN -0x00028AC0 DB_SRESULTS_COMPARE_STATE0 -0x00028AC4 DB_SRESULTS_COMPARE_STATE1 -0x00028AC8 DB_PRELOAD_CONTROL -0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0 -0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1 -0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2 -0x00028B04 VGT_STRMOUT_VTX_STRIDE_3 -0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET -0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE -0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE -0x00028B38 VGT_GS_MAX_VERT_OUT -0x00028B54 VGT_SHADER_STAGES_EN -0x00028B58 VGT_LS_HS_CONFIG -0x00028B6C VGT_TF_PARAM -0x00028B70 DB_ALPHA_TO_MASK -0x00028B74 VGT_DISPATCH_INITIATOR -0x00028B78 PA_SU_POLY_OFFSET_DB_FMT_CNTL -0x00028B7C PA_SU_POLY_OFFSET_CLAMP -0x00028B80 PA_SU_POLY_OFFSET_FRONT_SCALE -0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET -0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE -0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET -0x00028B74 VGT_GS_INSTANCE_CNT -0x00028BD4 PA_SC_CENTROID_PRIORITY_0 -0x00028BD8 PA_SC_CENTROID_PRIORITY_1 -0x00028BDC PA_SC_LINE_CNTL -0x00028BE4 PA_SU_VTX_CNTL -0x00028BE8 PA_CL_GB_VERT_CLIP_ADJ -0x00028BEC PA_CL_GB_VERT_DISC_ADJ -0x00028BF0 PA_CL_GB_HORZ_CLIP_ADJ -0x00028BF4 PA_CL_GB_HORZ_DISC_ADJ -0x00028BF8 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_0 -0x00028BFC PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_1 -0x00028C00 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_2 -0x00028C04 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y0_3 -0x00028C08 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_0 -0x00028C0C PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_1 -0x00028C10 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_2 -0x00028C14 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y0_3 -0x00028C18 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_0 -0x00028C1C PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_1 -0x00028C20 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_2 -0x00028C24 PA_SC_AA_SAMPLE_LOCS_PIXEL_X0_Y1_3 -0x00028C28 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_0 -0x00028C2C PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_1 -0x00028C30 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_2 -0x00028C34 PA_SC_AA_SAMPLE_LOCS_PIXEL_X1_Y1_3 -0x00028C38 PA_SC_AA_MASK_X0_Y0_X1_Y0 -0x00028C3C PA_SC_AA_MASK_X0_Y1_X1_Y1 -0x00028C78 CB_COLOR0_DIM -0x00028CB4 CB_COLOR1_DIM -0x00028CF0 CB_COLOR2_DIM -0x00028D2C CB_COLOR3_DIM -0x00028D68 CB_COLOR4_DIM -0x00028DA4 CB_COLOR5_DIM -0x00028DE0 CB_COLOR6_DIM -0x00028E1C CB_COLOR7_DIM -0x00028E58 CB_COLOR8_DIM -0x00028E74 CB_COLOR9_DIM -0x00028E90 CB_COLOR10_DIM -0x00028EAC CB_COLOR11_DIM -0x00028C8C CB_COLOR0_CLEAR_WORD0 -0x00028C90 CB_COLOR0_CLEAR_WORD1 -0x00028C94 CB_COLOR0_CLEAR_WORD2 -0x00028C98 CB_COLOR0_CLEAR_WORD3 -0x00028CC8 CB_COLOR1_CLEAR_WORD0 -0x00028CCC CB_COLOR1_CLEAR_WORD1 -0x00028CD0 CB_COLOR1_CLEAR_WORD2 -0x00028CD4 CB_COLOR1_CLEAR_WORD3 -0x00028D04 CB_COLOR2_CLEAR_WORD0 -0x00028D08 CB_COLOR2_CLEAR_WORD1 -0x00028D0C CB_COLOR2_CLEAR_WORD2 -0x00028D10 CB_COLOR2_CLEAR_WORD3 -0x00028D40 CB_COLOR3_CLEAR_WORD0 -0x00028D44 CB_COLOR3_CLEAR_WORD1 -0x00028D48 CB_COLOR3_CLEAR_WORD2 -0x00028D4C CB_COLOR3_CLEAR_WORD3 -0x00028D7C CB_COLOR4_CLEAR_WORD0 -0x00028D80 CB_COLOR4_CLEAR_WORD1 -0x00028D84 CB_COLOR4_CLEAR_WORD2 -0x00028D88 CB_COLOR4_CLEAR_WORD3 -0x00028DB8 CB_COLOR5_CLEAR_WORD0 -0x00028DBC CB_COLOR5_CLEAR_WORD1 -0x00028DC0 CB_COLOR5_CLEAR_WORD2 -0x00028DC4 CB_COLOR5_CLEAR_WORD3 -0x00028DF4 CB_COLOR6_CLEAR_WORD0 -0x00028DF8 CB_COLOR6_CLEAR_WORD1 -0x00028DFC CB_COLOR6_CLEAR_WORD2 -0x00028E00 CB_COLOR6_CLEAR_WORD3 -0x00028E30 CB_COLOR7_CLEAR_WORD0 -0x00028E34 CB_COLOR7_CLEAR_WORD1 -0x00028E38 CB_COLOR7_CLEAR_WORD2 -0x00028E3C CB_COLOR7_CLEAR_WORD3 -0x00028F80 SQ_ALU_CONST_BUFFER_SIZE_HS_0 -0x00028F84 SQ_ALU_CONST_BUFFER_SIZE_HS_1 -0x00028F88 SQ_ALU_CONST_BUFFER_SIZE_HS_2 -0x00028F8C SQ_ALU_CONST_BUFFER_SIZE_HS_3 -0x00028F90 SQ_ALU_CONST_BUFFER_SIZE_HS_4 -0x00028F94 SQ_ALU_CONST_BUFFER_SIZE_HS_5 -0x00028F98 SQ_ALU_CONST_BUFFER_SIZE_HS_6 -0x00028F9C SQ_ALU_CONST_BUFFER_SIZE_HS_7 -0x00028FA0 SQ_ALU_CONST_BUFFER_SIZE_HS_8 -0x00028FA4 SQ_ALU_CONST_BUFFER_SIZE_HS_9 -0x00028FA8 SQ_ALU_CONST_BUFFER_SIZE_HS_10 -0x00028FAC SQ_ALU_CONST_BUFFER_SIZE_HS_11 -0x00028FB0 SQ_ALU_CONST_BUFFER_SIZE_HS_12 -0x00028FB4 SQ_ALU_CONST_BUFFER_SIZE_HS_13 -0x00028FB8 SQ_ALU_CONST_BUFFER_SIZE_HS_14 -0x00028FBC SQ_ALU_CONST_BUFFER_SIZE_HS_15 -0x00028FC0 SQ_ALU_CONST_BUFFER_SIZE_LS_0 -0x00028FC4 SQ_ALU_CONST_BUFFER_SIZE_LS_1 -0x00028FC8 SQ_ALU_CONST_BUFFER_SIZE_LS_2 -0x00028FCC SQ_ALU_CONST_BUFFER_SIZE_LS_3 -0x00028FD0 SQ_ALU_CONST_BUFFER_SIZE_LS_4 -0x00028FD4 SQ_ALU_CONST_BUFFER_SIZE_LS_5 -0x00028FD8 SQ_ALU_CONST_BUFFER_SIZE_LS_6 -0x00028FDC SQ_ALU_CONST_BUFFER_SIZE_LS_7 -0x00028FE0 SQ_ALU_CONST_BUFFER_SIZE_LS_8 -0x00028FE4 SQ_ALU_CONST_BUFFER_SIZE_LS_9 -0x00028FE8 SQ_ALU_CONST_BUFFER_SIZE_LS_10 -0x00028FEC SQ_ALU_CONST_BUFFER_SIZE_LS_11 -0x00028FF0 SQ_ALU_CONST_BUFFER_SIZE_LS_12 -0x00028FF4 SQ_ALU_CONST_BUFFER_SIZE_LS_13 -0x00028FF8 SQ_ALU_CONST_BUFFER_SIZE_LS_14 -0x00028FFC SQ_ALU_CONST_BUFFER_SIZE_LS_15 -0x0003CFF0 SQ_VTX_BASE_VTX_LOC -0x0003CFF4 SQ_VTX_START_INST_LOC -0x0003FF00 SQ_TEX_SAMPLER_CLEAR -0x0003FF04 SQ_TEX_RESOURCE_CLEAR -0x0003FF08 SQ_LOOP_BOOL_CLEAR diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/evergreen b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/evergreen deleted file mode 100644 index b912a376..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/evergreen +++ /dev/null @@ -1,644 +0,0 @@ -evergreen 0x9400 -0x0000802C GRBM_GFX_INDEX -0x00008040 WAIT_UNTIL -0x00008044 WAIT_UNTIL_POLL_CNTL -0x00008048 WAIT_UNTIL_POLL_MASK -0x0000804c WAIT_UNTIL_POLL_REFDATA -0x000084FC CP_STRMOUT_CNTL -0x000085F0 CP_COHER_CNTL -0x000085F4 CP_COHER_SIZE -0x000088B0 VGT_VTX_VECT_EJECT_REG -0x000088C4 VGT_CACHE_INVALIDATION -0x000088D4 VGT_GS_VERTEX_REUSE -0x00008958 VGT_PRIMITIVE_TYPE -0x0000895C VGT_INDEX_TYPE -0x00008970 VGT_NUM_INDICES -0x00008974 VGT_NUM_INSTANCES -0x00008990 VGT_COMPUTE_DIM_X -0x00008994 VGT_COMPUTE_DIM_Y -0x00008998 VGT_COMPUTE_DIM_Z -0x0000899C VGT_COMPUTE_START_X -0x000089A0 VGT_COMPUTE_START_Y -0x000089A4 VGT_COMPUTE_START_Z -0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE -0x00008A14 PA_CL_ENHANCE -0x00008A60 PA_SC_LINE_STIPPLE_VALUE -0x00008B10 PA_SC_LINE_STIPPLE_STATE -0x00008BF0 PA_SC_ENHANCE -0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ -0x00008D90 SQ_DYN_GPR_OPTIMIZATION -0x00008D94 SQ_DYN_GPR_SIMD_LOCK_EN -0x00008D98 SQ_DYN_GPR_THREAD_LIMIT -0x00008D9C SQ_DYN_GPR_LDS_LIMIT -0x00008C00 SQ_CONFIG -0x00008C04 SQ_GPR_RESOURCE_MGMT_1 -0x00008C08 SQ_GPR_RESOURCE_MGMT_2 -0x00008C0C SQ_GPR_RESOURCE_MGMT_3 -0x00008C10 SQ_GLOBAL_GPR_RESOURCE_MGMT_1 -0x00008C14 SQ_GLOBAL_GPR_RESOURCE_MGMT_2 -0x00008C18 SQ_THREAD_RESOURCE_MGMT -0x00008C1C SQ_THREAD_RESOURCE_MGMT_2 -0x00008C20 SQ_STACK_RESOURCE_MGMT_1 -0x00008C24 SQ_STACK_RESOURCE_MGMT_2 -0x00008C28 SQ_STACK_RESOURCE_MGMT_3 -0x00008DF8 SQ_CONST_MEM_BASE -0x00008E20 SQ_STATIC_THREAD_MGMT_1 -0x00008E24 SQ_STATIC_THREAD_MGMT_2 -0x00008E28 SQ_STATIC_THREAD_MGMT_3 -0x00008E2C SQ_LDS_RESOURCE_MGMT -0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS -0x00009014 SX_MEMORY_EXPORT_SIZE -0x00009100 SPI_CONFIG_CNTL -0x0000913C SPI_CONFIG_CNTL_1 -0x00009508 TA_CNTL_AUX -0x00009700 VC_CNTL -0x00009714 VC_ENHANCE -0x00009830 DB_DEBUG -0x00009834 DB_DEBUG2 -0x00009838 DB_DEBUG3 -0x0000983C DB_DEBUG4 -0x00009854 DB_WATERMARKS -0x0000A400 TD_PS_BORDER_COLOR_INDEX -0x0000A404 TD_PS_BORDER_COLOR_RED -0x0000A408 TD_PS_BORDER_COLOR_GREEN -0x0000A40C TD_PS_BORDER_COLOR_BLUE -0x0000A410 TD_PS_BORDER_COLOR_ALPHA -0x0000A414 TD_VS_BORDER_COLOR_INDEX -0x0000A418 TD_VS_BORDER_COLOR_RED -0x0000A41C TD_VS_BORDER_COLOR_GREEN -0x0000A420 TD_VS_BORDER_COLOR_BLUE -0x0000A424 TD_VS_BORDER_COLOR_ALPHA -0x0000A428 TD_GS_BORDER_COLOR_INDEX -0x0000A42C TD_GS_BORDER_COLOR_RED -0x0000A430 TD_GS_BORDER_COLOR_GREEN -0x0000A434 TD_GS_BORDER_COLOR_BLUE -0x0000A438 TD_GS_BORDER_COLOR_ALPHA -0x0000A43C TD_HS_BORDER_COLOR_INDEX -0x0000A440 TD_HS_BORDER_COLOR_RED -0x0000A444 TD_HS_BORDER_COLOR_GREEN -0x0000A448 TD_HS_BORDER_COLOR_BLUE -0x0000A44C TD_HS_BORDER_COLOR_ALPHA -0x0000A450 TD_LS_BORDER_COLOR_INDEX -0x0000A454 TD_LS_BORDER_COLOR_RED -0x0000A458 TD_LS_BORDER_COLOR_GREEN -0x0000A45C TD_LS_BORDER_COLOR_BLUE -0x0000A460 TD_LS_BORDER_COLOR_ALPHA -0x0000A464 TD_CS_BORDER_COLOR_INDEX -0x0000A468 TD_CS_BORDER_COLOR_RED -0x0000A46C TD_CS_BORDER_COLOR_GREEN -0x0000A470 TD_CS_BORDER_COLOR_BLUE -0x0000A474 TD_CS_BORDER_COLOR_ALPHA -0x00028000 DB_RENDER_CONTROL -0x00028004 DB_COUNT_CONTROL -0x0002800C DB_RENDER_OVERRIDE -0x00028010 DB_RENDER_OVERRIDE2 -0x00028028 DB_STENCIL_CLEAR -0x0002802C DB_DEPTH_CLEAR -0x00028030 PA_SC_SCREEN_SCISSOR_TL -0x00028034 PA_SC_SCREEN_SCISSOR_BR -0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 -0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 -0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 -0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3 -0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4 -0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5 -0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6 -0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7 -0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8 -0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9 -0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10 -0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11 -0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12 -0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13 -0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14 -0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15 -0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0 -0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1 -0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2 -0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3 -0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4 -0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5 -0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6 -0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7 -0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8 -0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9 -0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10 -0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11 -0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12 -0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13 -0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14 -0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15 -0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0 -0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1 -0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2 -0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3 -0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4 -0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5 -0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6 -0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7 -0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8 -0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9 -0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10 -0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11 -0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12 -0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13 -0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14 -0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15 -0x00028200 PA_SC_WINDOW_OFFSET -0x00028204 PA_SC_WINDOW_SCISSOR_TL -0x00028208 PA_SC_WINDOW_SCISSOR_BR -0x0002820C PA_SC_CLIPRECT_RULE -0x00028210 PA_SC_CLIPRECT_0_TL -0x00028214 PA_SC_CLIPRECT_0_BR -0x00028218 PA_SC_CLIPRECT_1_TL -0x0002821C PA_SC_CLIPRECT_1_BR -0x00028220 PA_SC_CLIPRECT_2_TL -0x00028224 PA_SC_CLIPRECT_2_BR -0x00028228 PA_SC_CLIPRECT_3_TL -0x0002822C PA_SC_CLIPRECT_3_BR -0x00028230 PA_SC_EDGERULE -0x00028234 PA_SU_HARDWARE_SCREEN_OFFSET -0x00028240 PA_SC_GENERIC_SCISSOR_TL -0x00028244 PA_SC_GENERIC_SCISSOR_BR -0x00028250 PA_SC_VPORT_SCISSOR_0_TL -0x00028254 PA_SC_VPORT_SCISSOR_0_BR -0x00028258 PA_SC_VPORT_SCISSOR_1_TL -0x0002825C PA_SC_VPORT_SCISSOR_1_BR -0x00028260 PA_SC_VPORT_SCISSOR_2_TL -0x00028264 PA_SC_VPORT_SCISSOR_2_BR -0x00028268 PA_SC_VPORT_SCISSOR_3_TL -0x0002826C PA_SC_VPORT_SCISSOR_3_BR -0x00028270 PA_SC_VPORT_SCISSOR_4_TL -0x00028274 PA_SC_VPORT_SCISSOR_4_BR -0x00028278 PA_SC_VPORT_SCISSOR_5_TL -0x0002827C PA_SC_VPORT_SCISSOR_5_BR -0x00028280 PA_SC_VPORT_SCISSOR_6_TL -0x00028284 PA_SC_VPORT_SCISSOR_6_BR -0x00028288 PA_SC_VPORT_SCISSOR_7_TL -0x0002828C PA_SC_VPORT_SCISSOR_7_BR -0x00028290 PA_SC_VPORT_SCISSOR_8_TL -0x00028294 PA_SC_VPORT_SCISSOR_8_BR -0x00028298 PA_SC_VPORT_SCISSOR_9_TL -0x0002829C PA_SC_VPORT_SCISSOR_9_BR -0x000282A0 PA_SC_VPORT_SCISSOR_10_TL -0x000282A4 PA_SC_VPORT_SCISSOR_10_BR -0x000282A8 PA_SC_VPORT_SCISSOR_11_TL -0x000282AC PA_SC_VPORT_SCISSOR_11_BR -0x000282B0 PA_SC_VPORT_SCISSOR_12_TL -0x000282B4 PA_SC_VPORT_SCISSOR_12_BR -0x000282B8 PA_SC_VPORT_SCISSOR_13_TL -0x000282BC PA_SC_VPORT_SCISSOR_13_BR -0x000282C0 PA_SC_VPORT_SCISSOR_14_TL -0x000282C4 PA_SC_VPORT_SCISSOR_14_BR -0x000282C8 PA_SC_VPORT_SCISSOR_15_TL -0x000282CC PA_SC_VPORT_SCISSOR_15_BR -0x000282D0 PA_SC_VPORT_ZMIN_0 -0x000282D4 PA_SC_VPORT_ZMAX_0 -0x000282D8 PA_SC_VPORT_ZMIN_1 -0x000282DC PA_SC_VPORT_ZMAX_1 -0x000282E0 PA_SC_VPORT_ZMIN_2 -0x000282E4 PA_SC_VPORT_ZMAX_2 -0x000282E8 PA_SC_VPORT_ZMIN_3 -0x000282EC PA_SC_VPORT_ZMAX_3 -0x000282F0 PA_SC_VPORT_ZMIN_4 -0x000282F4 PA_SC_VPORT_ZMAX_4 -0x000282F8 PA_SC_VPORT_ZMIN_5 -0x000282FC PA_SC_VPORT_ZMAX_5 -0x00028300 PA_SC_VPORT_ZMIN_6 -0x00028304 PA_SC_VPORT_ZMAX_6 -0x00028308 PA_SC_VPORT_ZMIN_7 -0x0002830C PA_SC_VPORT_ZMAX_7 -0x00028310 PA_SC_VPORT_ZMIN_8 -0x00028314 PA_SC_VPORT_ZMAX_8 -0x00028318 PA_SC_VPORT_ZMIN_9 -0x0002831C PA_SC_VPORT_ZMAX_9 -0x00028320 PA_SC_VPORT_ZMIN_10 -0x00028324 PA_SC_VPORT_ZMAX_10 -0x00028328 PA_SC_VPORT_ZMIN_11 -0x0002832C PA_SC_VPORT_ZMAX_11 -0x00028330 PA_SC_VPORT_ZMIN_12 -0x00028334 PA_SC_VPORT_ZMAX_12 -0x00028338 PA_SC_VPORT_ZMIN_13 -0x0002833C PA_SC_VPORT_ZMAX_13 -0x00028340 PA_SC_VPORT_ZMIN_14 -0x00028344 PA_SC_VPORT_ZMAX_14 -0x00028348 PA_SC_VPORT_ZMIN_15 -0x0002834C PA_SC_VPORT_ZMAX_15 -0x00028354 SX_SURFACE_SYNC -0x00028380 SQ_VTX_SEMANTIC_0 -0x00028384 SQ_VTX_SEMANTIC_1 -0x00028388 SQ_VTX_SEMANTIC_2 -0x0002838C SQ_VTX_SEMANTIC_3 -0x00028390 SQ_VTX_SEMANTIC_4 -0x00028394 SQ_VTX_SEMANTIC_5 -0x00028398 SQ_VTX_SEMANTIC_6 -0x0002839C SQ_VTX_SEMANTIC_7 -0x000283A0 SQ_VTX_SEMANTIC_8 -0x000283A4 SQ_VTX_SEMANTIC_9 -0x000283A8 SQ_VTX_SEMANTIC_10 -0x000283AC SQ_VTX_SEMANTIC_11 -0x000283B0 SQ_VTX_SEMANTIC_12 -0x000283B4 SQ_VTX_SEMANTIC_13 -0x000283B8 SQ_VTX_SEMANTIC_14 -0x000283BC SQ_VTX_SEMANTIC_15 -0x000283C0 SQ_VTX_SEMANTIC_16 -0x000283C4 SQ_VTX_SEMANTIC_17 -0x000283C8 SQ_VTX_SEMANTIC_18 -0x000283CC SQ_VTX_SEMANTIC_19 -0x000283D0 SQ_VTX_SEMANTIC_20 -0x000283D4 SQ_VTX_SEMANTIC_21 -0x000283D8 SQ_VTX_SEMANTIC_22 -0x000283DC SQ_VTX_SEMANTIC_23 -0x000283E0 SQ_VTX_SEMANTIC_24 -0x000283E4 SQ_VTX_SEMANTIC_25 -0x000283E8 SQ_VTX_SEMANTIC_26 -0x000283EC SQ_VTX_SEMANTIC_27 -0x000283F0 SQ_VTX_SEMANTIC_28 -0x000283F4 SQ_VTX_SEMANTIC_29 -0x000283F8 SQ_VTX_SEMANTIC_30 -0x000283FC SQ_VTX_SEMANTIC_31 -0x00028400 VGT_MAX_VTX_INDX -0x00028404 VGT_MIN_VTX_INDX -0x00028408 VGT_INDX_OFFSET -0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX -0x00028410 SX_ALPHA_TEST_CONTROL -0x00028414 CB_BLEND_RED -0x00028418 CB_BLEND_GREEN -0x0002841C CB_BLEND_BLUE -0x00028420 CB_BLEND_ALPHA -0x00028430 DB_STENCILREFMASK -0x00028434 DB_STENCILREFMASK_BF -0x00028438 SX_ALPHA_REF -0x0002843C PA_CL_VPORT_XSCALE_0 -0x00028440 PA_CL_VPORT_XOFFSET_0 -0x00028444 PA_CL_VPORT_YSCALE_0 -0x00028448 PA_CL_VPORT_YOFFSET_0 -0x0002844C PA_CL_VPORT_ZSCALE_0 -0x00028450 PA_CL_VPORT_ZOFFSET_0 -0x00028454 PA_CL_VPORT_XSCALE_1 -0x00028458 PA_CL_VPORT_XOFFSET_1 -0x0002845C PA_CL_VPORT_YSCALE_1 -0x00028460 PA_CL_VPORT_YOFFSET_1 -0x00028464 PA_CL_VPORT_ZSCALE_1 -0x00028468 PA_CL_VPORT_ZOFFSET_1 -0x0002846C PA_CL_VPORT_XSCALE_2 -0x00028470 PA_CL_VPORT_XOFFSET_2 -0x00028474 PA_CL_VPORT_YSCALE_2 -0x00028478 PA_CL_VPORT_YOFFSET_2 -0x0002847C PA_CL_VPORT_ZSCALE_2 -0x00028480 PA_CL_VPORT_ZOFFSET_2 -0x00028484 PA_CL_VPORT_XSCALE_3 -0x00028488 PA_CL_VPORT_XOFFSET_3 -0x0002848C PA_CL_VPORT_YSCALE_3 -0x00028490 PA_CL_VPORT_YOFFSET_3 -0x00028494 PA_CL_VPORT_ZSCALE_3 -0x00028498 PA_CL_VPORT_ZOFFSET_3 -0x0002849C PA_CL_VPORT_XSCALE_4 -0x000284A0 PA_CL_VPORT_XOFFSET_4 -0x000284A4 PA_CL_VPORT_YSCALE_4 -0x000284A8 PA_CL_VPORT_YOFFSET_4 -0x000284AC PA_CL_VPORT_ZSCALE_4 -0x000284B0 PA_CL_VPORT_ZOFFSET_4 -0x000284B4 PA_CL_VPORT_XSCALE_5 -0x000284B8 PA_CL_VPORT_XOFFSET_5 -0x000284BC PA_CL_VPORT_YSCALE_5 -0x000284C0 PA_CL_VPORT_YOFFSET_5 -0x000284C4 PA_CL_VPORT_ZSCALE_5 -0x000284C8 PA_CL_VPORT_ZOFFSET_5 -0x000284CC PA_CL_VPORT_XSCALE_6 -0x000284D0 PA_CL_VPORT_XOFFSET_6 -0x000284D4 PA_CL_VPORT_YSCALE_6 -0x000284D8 PA_CL_VPORT_YOFFSET_6 -0x000284DC PA_CL_VPORT_ZSCALE_6 -0x000284E0 PA_CL_VPORT_ZOFFSET_6 -0x000284E4 PA_CL_VPORT_XSCALE_7 -0x000284E8 PA_CL_VPORT_XOFFSET_7 -0x000284EC PA_CL_VPORT_YSCALE_7 -0x000284F0 PA_CL_VPORT_YOFFSET_7 -0x000284F4 PA_CL_VPORT_ZSCALE_7 -0x000284F8 PA_CL_VPORT_ZOFFSET_7 -0x000284FC PA_CL_VPORT_XSCALE_8 -0x00028500 PA_CL_VPORT_XOFFSET_8 -0x00028504 PA_CL_VPORT_YSCALE_8 -0x00028508 PA_CL_VPORT_YOFFSET_8 -0x0002850C PA_CL_VPORT_ZSCALE_8 -0x00028510 PA_CL_VPORT_ZOFFSET_8 -0x00028514 PA_CL_VPORT_XSCALE_9 -0x00028518 PA_CL_VPORT_XOFFSET_9 -0x0002851C PA_CL_VPORT_YSCALE_9 -0x00028520 PA_CL_VPORT_YOFFSET_9 -0x00028524 PA_CL_VPORT_ZSCALE_9 -0x00028528 PA_CL_VPORT_ZOFFSET_9 -0x0002852C PA_CL_VPORT_XSCALE_10 -0x00028530 PA_CL_VPORT_XOFFSET_10 -0x00028534 PA_CL_VPORT_YSCALE_10 -0x00028538 PA_CL_VPORT_YOFFSET_10 -0x0002853C PA_CL_VPORT_ZSCALE_10 -0x00028540 PA_CL_VPORT_ZOFFSET_10 -0x00028544 PA_CL_VPORT_XSCALE_11 -0x00028548 PA_CL_VPORT_XOFFSET_11 -0x0002854C PA_CL_VPORT_YSCALE_11 -0x00028550 PA_CL_VPORT_YOFFSET_11 -0x00028554 PA_CL_VPORT_ZSCALE_11 -0x00028558 PA_CL_VPORT_ZOFFSET_11 -0x0002855C PA_CL_VPORT_XSCALE_12 -0x00028560 PA_CL_VPORT_XOFFSET_12 -0x00028564 PA_CL_VPORT_YSCALE_12 -0x00028568 PA_CL_VPORT_YOFFSET_12 -0x0002856C PA_CL_VPORT_ZSCALE_12 -0x00028570 PA_CL_VPORT_ZOFFSET_12 -0x00028574 PA_CL_VPORT_XSCALE_13 -0x00028578 PA_CL_VPORT_XOFFSET_13 -0x0002857C PA_CL_VPORT_YSCALE_13 -0x00028580 PA_CL_VPORT_YOFFSET_13 -0x00028584 PA_CL_VPORT_ZSCALE_13 -0x00028588 PA_CL_VPORT_ZOFFSET_13 -0x0002858C PA_CL_VPORT_XSCALE_14 -0x00028590 PA_CL_VPORT_XOFFSET_14 -0x00028594 PA_CL_VPORT_YSCALE_14 -0x00028598 PA_CL_VPORT_YOFFSET_14 -0x0002859C PA_CL_VPORT_ZSCALE_14 -0x000285A0 PA_CL_VPORT_ZOFFSET_14 -0x000285A4 PA_CL_VPORT_XSCALE_15 -0x000285A8 PA_CL_VPORT_XOFFSET_15 -0x000285AC PA_CL_VPORT_YSCALE_15 -0x000285B0 PA_CL_VPORT_YOFFSET_15 -0x000285B4 PA_CL_VPORT_ZSCALE_15 -0x000285B8 PA_CL_VPORT_ZOFFSET_15 -0x000285BC PA_CL_UCP_0_X -0x000285C0 PA_CL_UCP_0_Y -0x000285C4 PA_CL_UCP_0_Z -0x000285C8 PA_CL_UCP_0_W -0x000285CC PA_CL_UCP_1_X -0x000285D0 PA_CL_UCP_1_Y -0x000285D4 PA_CL_UCP_1_Z -0x000285D8 PA_CL_UCP_1_W -0x000285DC PA_CL_UCP_2_X -0x000285E0 PA_CL_UCP_2_Y -0x000285E4 PA_CL_UCP_2_Z -0x000285E8 PA_CL_UCP_2_W -0x000285EC PA_CL_UCP_3_X -0x000285F0 PA_CL_UCP_3_Y -0x000285F4 PA_CL_UCP_3_Z -0x000285F8 PA_CL_UCP_3_W -0x000285FC PA_CL_UCP_4_X -0x00028600 PA_CL_UCP_4_Y -0x00028604 PA_CL_UCP_4_Z -0x00028608 PA_CL_UCP_4_W -0x0002860C PA_CL_UCP_5_X -0x00028610 PA_CL_UCP_5_Y -0x00028614 PA_CL_UCP_5_Z -0x00028618 PA_CL_UCP_5_W -0x0002861C SPI_VS_OUT_ID_0 -0x00028620 SPI_VS_OUT_ID_1 -0x00028624 SPI_VS_OUT_ID_2 -0x00028628 SPI_VS_OUT_ID_3 -0x0002862C SPI_VS_OUT_ID_4 -0x00028630 SPI_VS_OUT_ID_5 -0x00028634 SPI_VS_OUT_ID_6 -0x00028638 SPI_VS_OUT_ID_7 -0x0002863C SPI_VS_OUT_ID_8 -0x00028640 SPI_VS_OUT_ID_9 -0x00028644 SPI_PS_INPUT_CNTL_0 -0x00028648 SPI_PS_INPUT_CNTL_1 -0x0002864C SPI_PS_INPUT_CNTL_2 -0x00028650 SPI_PS_INPUT_CNTL_3 -0x00028654 SPI_PS_INPUT_CNTL_4 -0x00028658 SPI_PS_INPUT_CNTL_5 -0x0002865C SPI_PS_INPUT_CNTL_6 -0x00028660 SPI_PS_INPUT_CNTL_7 -0x00028664 SPI_PS_INPUT_CNTL_8 -0x00028668 SPI_PS_INPUT_CNTL_9 -0x0002866C SPI_PS_INPUT_CNTL_10 -0x00028670 SPI_PS_INPUT_CNTL_11 -0x00028674 SPI_PS_INPUT_CNTL_12 -0x00028678 SPI_PS_INPUT_CNTL_13 -0x0002867C SPI_PS_INPUT_CNTL_14 -0x00028680 SPI_PS_INPUT_CNTL_15 -0x00028684 SPI_PS_INPUT_CNTL_16 -0x00028688 SPI_PS_INPUT_CNTL_17 -0x0002868C SPI_PS_INPUT_CNTL_18 -0x00028690 SPI_PS_INPUT_CNTL_19 -0x00028694 SPI_PS_INPUT_CNTL_20 -0x00028698 SPI_PS_INPUT_CNTL_21 -0x0002869C SPI_PS_INPUT_CNTL_22 -0x000286A0 SPI_PS_INPUT_CNTL_23 -0x000286A4 SPI_PS_INPUT_CNTL_24 -0x000286A8 SPI_PS_INPUT_CNTL_25 -0x000286AC SPI_PS_INPUT_CNTL_26 -0x000286B0 SPI_PS_INPUT_CNTL_27 -0x000286B4 SPI_PS_INPUT_CNTL_28 -0x000286B8 SPI_PS_INPUT_CNTL_29 -0x000286BC SPI_PS_INPUT_CNTL_30 -0x000286C0 SPI_PS_INPUT_CNTL_31 -0x000286C4 SPI_VS_OUT_CONFIG -0x000286C8 SPI_THREAD_GROUPING -0x000286CC SPI_PS_IN_CONTROL_0 -0x000286D0 SPI_PS_IN_CONTROL_1 -0x000286D4 SPI_INTERP_CONTROL_0 -0x000286D8 SPI_INPUT_Z -0x000286DC SPI_FOG_CNTL -0x000286E0 SPI_BARYC_CNTL -0x000286E4 SPI_PS_IN_CONTROL_2 -0x000286E8 SPI_COMPUTE_INPUT_CNTL -0x000286EC SPI_COMPUTE_NUM_THREAD_X -0x000286F0 SPI_COMPUTE_NUM_THREAD_Y -0x000286F4 SPI_COMPUTE_NUM_THREAD_Z -0x00028720 GDS_ADDR_BASE -0x00028724 GDS_ADDR_SIZE -0x00028728 GDS_ORDERED_WAVE_PER_SE -0x00028780 CB_BLEND0_CONTROL -0x00028784 CB_BLEND1_CONTROL -0x00028788 CB_BLEND2_CONTROL -0x0002878C CB_BLEND3_CONTROL -0x00028790 CB_BLEND4_CONTROL -0x00028794 CB_BLEND5_CONTROL -0x00028798 CB_BLEND6_CONTROL -0x0002879C CB_BLEND7_CONTROL -0x000287CC CS_COPY_STATE -0x000287D0 GFX_COPY_STATE -0x000287D4 PA_CL_POINT_X_RAD -0x000287D8 PA_CL_POINT_Y_RAD -0x000287DC PA_CL_POINT_SIZE -0x000287E0 PA_CL_POINT_CULL_RAD -0x00028808 CB_COLOR_CONTROL -0x0002880C DB_SHADER_CONTROL -0x00028810 PA_CL_CLIP_CNTL -0x00028814 PA_SU_SC_MODE_CNTL -0x00028818 PA_CL_VTE_CNTL -0x0002881C PA_CL_VS_OUT_CNTL -0x00028820 PA_CL_NANINF_CNTL -0x00028824 PA_SU_LINE_STIPPLE_CNTL -0x00028828 PA_SU_LINE_STIPPLE_SCALE -0x0002882C PA_SU_PRIM_FILTER_CNTL -0x00028838 SQ_DYN_GPR_RESOURCE_LIMIT_1 -0x00028844 SQ_PGM_RESOURCES_PS -0x00028848 SQ_PGM_RESOURCES_2_PS -0x0002884C SQ_PGM_EXPORTS_PS -0x00028860 SQ_PGM_RESOURCES_VS -0x00028864 SQ_PGM_RESOURCES_2_VS -0x00028878 SQ_PGM_RESOURCES_GS -0x0002887C SQ_PGM_RESOURCES_2_GS -0x00028890 SQ_PGM_RESOURCES_ES -0x00028894 SQ_PGM_RESOURCES_2_ES -0x000288A8 SQ_PGM_RESOURCES_FS -0x000288BC SQ_PGM_RESOURCES_HS -0x000288C0 SQ_PGM_RESOURCES_2_HS -0x000288D4 SQ_PGM_RESOURCES_LS -0x000288D8 SQ_PGM_RESOURCES_2_LS -0x000288E8 SQ_LDS_ALLOC -0x000288EC SQ_LDS_ALLOC_PS -0x000288F0 SQ_VTX_SEMANTIC_CLEAR -0x00028A00 PA_SU_POINT_SIZE -0x00028A04 PA_SU_POINT_MINMAX -0x00028A08 PA_SU_LINE_CNTL -0x00028A0C PA_SC_LINE_STIPPLE -0x00028A10 VGT_OUTPUT_PATH_CNTL -0x00028A14 VGT_HOS_CNTL -0x00028A18 VGT_HOS_MAX_TESS_LEVEL -0x00028A1C VGT_HOS_MIN_TESS_LEVEL -0x00028A20 VGT_HOS_REUSE_DEPTH -0x00028A24 VGT_GROUP_PRIM_TYPE -0x00028A28 VGT_GROUP_FIRST_DECR -0x00028A2C VGT_GROUP_DECR -0x00028A30 VGT_GROUP_VECT_0_CNTL -0x00028A34 VGT_GROUP_VECT_1_CNTL -0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL -0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL -0x00028A40 VGT_GS_MODE -0x00028A48 PA_SC_MODE_CNTL_0 -0x00028A4C PA_SC_MODE_CNTL_1 -0x00028A50 VGT_ENHANCE -0x00028A54 VGT_GS_PER_ES -0x00028A58 VGT_ES_PER_GS -0x00028A5C VGT_GS_PER_VS -0x00028A6C VGT_GS_OUT_PRIM_TYPE -0x00028A84 VGT_PRIMITIVEID_EN -0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN -0x00028AA0 VGT_INSTANCE_STEP_RATE_0 -0x00028AA4 VGT_INSTANCE_STEP_RATE_1 -0x00028AB4 VGT_REUSE_OFF -0x00028AB8 VGT_VTX_CNT_EN -0x00028AC0 DB_SRESULTS_COMPARE_STATE0 -0x00028AC4 DB_SRESULTS_COMPARE_STATE1 -0x00028AC8 DB_PRELOAD_CONTROL -0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0 -0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1 -0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2 -0x00028B04 VGT_STRMOUT_VTX_STRIDE_3 -0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET -0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE -0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE -0x00028B38 VGT_GS_MAX_VERT_OUT -0x00028B54 VGT_SHADER_STAGES_EN -0x00028B58 VGT_LS_HS_CONFIG -0x00028B5C VGT_LS_SIZE -0x00028B60 VGT_HS_SIZE -0x00028B64 VGT_LS_HS_ALLOC -0x00028B68 VGT_HS_PATCH_CONST -0x00028B6C VGT_TF_PARAM -0x00028B70 DB_ALPHA_TO_MASK -0x00028B74 VGT_DISPATCH_INITIATOR -0x00028B78 PA_SU_POLY_OFFSET_DB_FMT_CNTL -0x00028B7C PA_SU_POLY_OFFSET_CLAMP -0x00028B80 PA_SU_POLY_OFFSET_FRONT_SCALE -0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET -0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE -0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET -0x00028B74 VGT_GS_INSTANCE_CNT -0x00028C00 PA_SC_LINE_CNTL -0x00028C08 PA_SU_VTX_CNTL -0x00028C0C PA_CL_GB_VERT_CLIP_ADJ -0x00028C10 PA_CL_GB_VERT_DISC_ADJ -0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ -0x00028C18 PA_CL_GB_HORZ_DISC_ADJ -0x00028C1C PA_SC_AA_SAMPLE_LOCS_0 -0x00028C20 PA_SC_AA_SAMPLE_LOCS_1 -0x00028C24 PA_SC_AA_SAMPLE_LOCS_2 -0x00028C28 PA_SC_AA_SAMPLE_LOCS_3 -0x00028C2C PA_SC_AA_SAMPLE_LOCS_4 -0x00028C30 PA_SC_AA_SAMPLE_LOCS_5 -0x00028C34 PA_SC_AA_SAMPLE_LOCS_6 -0x00028C38 PA_SC_AA_SAMPLE_LOCS_7 -0x00028C3C PA_SC_AA_MASK -0x00028C78 CB_COLOR0_DIM -0x00028CB4 CB_COLOR1_DIM -0x00028CF0 CB_COLOR2_DIM -0x00028D2C CB_COLOR3_DIM -0x00028D68 CB_COLOR4_DIM -0x00028DA4 CB_COLOR5_DIM -0x00028DE0 CB_COLOR6_DIM -0x00028E1C CB_COLOR7_DIM -0x00028E58 CB_COLOR8_DIM -0x00028E74 CB_COLOR9_DIM -0x00028E90 CB_COLOR10_DIM -0x00028EAC CB_COLOR11_DIM -0x00028C8C CB_COLOR0_CLEAR_WORD0 -0x00028C90 CB_COLOR0_CLEAR_WORD1 -0x00028C94 CB_COLOR0_CLEAR_WORD2 -0x00028C98 CB_COLOR0_CLEAR_WORD3 -0x00028CC8 CB_COLOR1_CLEAR_WORD0 -0x00028CCC CB_COLOR1_CLEAR_WORD1 -0x00028CD0 CB_COLOR1_CLEAR_WORD2 -0x00028CD4 CB_COLOR1_CLEAR_WORD3 -0x00028D04 CB_COLOR2_CLEAR_WORD0 -0x00028D08 CB_COLOR2_CLEAR_WORD1 -0x00028D0C CB_COLOR2_CLEAR_WORD2 -0x00028D10 CB_COLOR2_CLEAR_WORD3 -0x00028D40 CB_COLOR3_CLEAR_WORD0 -0x00028D44 CB_COLOR3_CLEAR_WORD1 -0x00028D48 CB_COLOR3_CLEAR_WORD2 -0x00028D4C CB_COLOR3_CLEAR_WORD3 -0x00028D7C CB_COLOR4_CLEAR_WORD0 -0x00028D80 CB_COLOR4_CLEAR_WORD1 -0x00028D84 CB_COLOR4_CLEAR_WORD2 -0x00028D88 CB_COLOR4_CLEAR_WORD3 -0x00028DB8 CB_COLOR5_CLEAR_WORD0 -0x00028DBC CB_COLOR5_CLEAR_WORD1 -0x00028DC0 CB_COLOR5_CLEAR_WORD2 -0x00028DC4 CB_COLOR5_CLEAR_WORD3 -0x00028DF4 CB_COLOR6_CLEAR_WORD0 -0x00028DF8 CB_COLOR6_CLEAR_WORD1 -0x00028DFC CB_COLOR6_CLEAR_WORD2 -0x00028E00 CB_COLOR6_CLEAR_WORD3 -0x00028E30 CB_COLOR7_CLEAR_WORD0 -0x00028E34 CB_COLOR7_CLEAR_WORD1 -0x00028E38 CB_COLOR7_CLEAR_WORD2 -0x00028E3C CB_COLOR7_CLEAR_WORD3 -0x00028F80 SQ_ALU_CONST_BUFFER_SIZE_HS_0 -0x00028F84 SQ_ALU_CONST_BUFFER_SIZE_HS_1 -0x00028F88 SQ_ALU_CONST_BUFFER_SIZE_HS_2 -0x00028F8C SQ_ALU_CONST_BUFFER_SIZE_HS_3 -0x00028F90 SQ_ALU_CONST_BUFFER_SIZE_HS_4 -0x00028F94 SQ_ALU_CONST_BUFFER_SIZE_HS_5 -0x00028F98 SQ_ALU_CONST_BUFFER_SIZE_HS_6 -0x00028F9C SQ_ALU_CONST_BUFFER_SIZE_HS_7 -0x00028FA0 SQ_ALU_CONST_BUFFER_SIZE_HS_8 -0x00028FA4 SQ_ALU_CONST_BUFFER_SIZE_HS_9 -0x00028FA8 SQ_ALU_CONST_BUFFER_SIZE_HS_10 -0x00028FAC SQ_ALU_CONST_BUFFER_SIZE_HS_11 -0x00028FB0 SQ_ALU_CONST_BUFFER_SIZE_HS_12 -0x00028FB4 SQ_ALU_CONST_BUFFER_SIZE_HS_13 -0x00028FB8 SQ_ALU_CONST_BUFFER_SIZE_HS_14 -0x00028FBC SQ_ALU_CONST_BUFFER_SIZE_HS_15 -0x00028FC0 SQ_ALU_CONST_BUFFER_SIZE_LS_0 -0x00028FC4 SQ_ALU_CONST_BUFFER_SIZE_LS_1 -0x00028FC8 SQ_ALU_CONST_BUFFER_SIZE_LS_2 -0x00028FCC SQ_ALU_CONST_BUFFER_SIZE_LS_3 -0x00028FD0 SQ_ALU_CONST_BUFFER_SIZE_LS_4 -0x00028FD4 SQ_ALU_CONST_BUFFER_SIZE_LS_5 -0x00028FD8 SQ_ALU_CONST_BUFFER_SIZE_LS_6 -0x00028FDC SQ_ALU_CONST_BUFFER_SIZE_LS_7 -0x00028FE0 SQ_ALU_CONST_BUFFER_SIZE_LS_8 -0x00028FE4 SQ_ALU_CONST_BUFFER_SIZE_LS_9 -0x00028FE8 SQ_ALU_CONST_BUFFER_SIZE_LS_10 -0x00028FEC SQ_ALU_CONST_BUFFER_SIZE_LS_11 -0x00028FF0 SQ_ALU_CONST_BUFFER_SIZE_LS_12 -0x00028FF4 SQ_ALU_CONST_BUFFER_SIZE_LS_13 -0x00028FF8 SQ_ALU_CONST_BUFFER_SIZE_LS_14 -0x00028FFC SQ_ALU_CONST_BUFFER_SIZE_LS_15 -0x0003CFF0 SQ_VTX_BASE_VTX_LOC -0x0003CFF4 SQ_VTX_START_INST_LOC -0x0003FF00 SQ_TEX_SAMPLER_CLEAR -0x0003FF04 SQ_TEX_RESOURCE_CLEAR -0x0003FF08 SQ_LOOP_BOOL_CLEAR diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r100 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r100 deleted file mode 100644 index f7ee062f..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r100 +++ /dev/null @@ -1,105 +0,0 @@ -r100 0x3294 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL -0x1810 FOG_3D_TABLE_START -0x1814 FOG_3D_TABLE_END -0x1a14 FOG_TABLE_INDEX -0x1a18 FOG_TABLE_DATA -0x1c14 PP_MISC -0x1c18 PP_FOG_COLOR -0x1c1c RE_SOLID_COLOR -0x1c20 RB3D_BLENDCNTL -0x1c4c SE_CNTL -0x1c50 SE_COORD_FMT -0x1c60 PP_TXCBLEND_0 -0x1c64 PP_TXABLEND_0 -0x1c68 PP_TFACTOR_0 -0x1c78 PP_TXCBLEND_1 -0x1c7c PP_TXABLEND_1 -0x1c80 PP_TFACTOR_1 -0x1c90 PP_TXCBLEND_2 -0x1c94 PP_TXABLEND_2 -0x1c98 PP_TFACTOR_2 -0x1cc8 RE_STIPPLE_ADDR -0x1ccc RE_STIPPLE_DATA -0x1cd0 RE_LINE_PATTERN -0x1cd4 RE_LINE_STATE -0x1d40 PP_BORDER_COLOR0 -0x1d44 PP_BORDER_COLOR1 -0x1d48 PP_BORDER_COLOR2 -0x1d7c RB3D_STENCILREFMASK -0x1d80 RB3D_ROPCNTL -0x1d84 RB3D_PLANEMASK -0x1d98 VAP_VPORT_XSCALE -0x1d9C VAP_VPORT_XOFFSET -0x1da0 VAP_VPORT_YSCALE -0x1da4 VAP_VPORT_YOFFSET -0x1da8 VAP_VPORT_ZSCALE -0x1dac VAP_VPORT_ZOFFSET -0x1db0 SE_ZBIAS_FACTOR -0x1db4 SE_ZBIAS_CONSTANT -0x1db8 SE_LINE_WIDTH -0x2140 SE_CNTL_STATUS -0x2200 SE_TCL_VECTOR_INDX_REG -0x2204 SE_TCL_VECTOR_DATA_REG -0x2208 SE_TCL_SCALAR_INDX_REG -0x220c SE_TCL_SCALAR_DATA_REG -0x2210 SE_TCL_MATERIAL_EMISSIVE_RED -0x2214 SE_TCL_MATERIAL_EMISSIVE_GREEN -0x2218 SE_TCL_MATERIAL_EMISSIVE_BLUE -0x221c SE_TCL_MATERIAL_EMISSIVE_ALPHA -0x2220 SE_TCL_MATERIAL_AMBIENT_RED -0x2224 SE_TCL_MATERIAL_AMBIENT_GREEN -0x2228 SE_TCL_MATERIAL_AMBIENT_BLUE -0x222c SE_TCL_MATERIAL_AMBIENT_ALPHA -0x2230 SE_TCL_MATERIAL_DIFFUSE_RED -0x2234 SE_TCL_MATERIAL_DIFFUSE_GREEN -0x2238 SE_TCL_MATERIAL_DIFFUSE_BLUE -0x223c SE_TCL_MATERIAL_DIFFUSE_ALPHA -0x2240 SE_TCL_MATERIAL_SPECULAR_RED -0x2244 SE_TCL_MATERIAL_SPECULAR_GREEN -0x2248 SE_TCL_MATERIAL_SPECULAR_BLUE -0x224c SE_TCL_MATERIAL_SPECULAR_ALPHA -0x2250 SE_TCL_SHININESS -0x2254 SE_TCL_OUTPUT_VTX_FMT -0x2258 SE_TCL_OUTPUT_VTX_SEL -0x225c SE_TCL_MATRIX_SELECT_0 -0x2260 SE_TCL_MATRIX_SELECT_1 -0x2264 SE_TCL_UCP_VERT_BLEND_CNTL -0x2268 SE_TCL_TEXTURE_PROC_CTL -0x226c SE_TCL_LIGHT_MODEL_CTL -0x2270 SE_TCL_PER_LIGHT_CTL_0 -0x2274 SE_TCL_PER_LIGHT_CTL_1 -0x2278 SE_TCL_PER_LIGHT_CTL_2 -0x227c SE_TCL_PER_LIGHT_CTL_3 -0x2284 SE_TCL_STATE_FLUSH -0x26c0 RE_TOP_LEFT -0x26c4 RE_MISC -0x3290 RB3D_ZPASS_DATA diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r200 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r200 deleted file mode 100644 index c29ac434..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r200 +++ /dev/null @@ -1,186 +0,0 @@ -r200 0x3294 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL -0x1c14 PP_MISC -0x1c18 PP_FOG_COLOR -0x1c1c RE_SOLID_COLOR -0x1c20 RB3D_BLENDCNTL -0x1c4c SE_CNTL -0x1c50 RE_CNTL -0x1cc8 RE_STIPPLE_ADDR -0x1ccc RE_STIPPLE_DATA -0x1cd0 RE_LINE_PATTERN -0x1cd4 RE_LINE_STATE -0x1cd8 RE_SCISSOR_TL_0 -0x1cdc RE_SCISSOR_BR_0 -0x1ce0 RE_SCISSOR_TL_1 -0x1ce4 RE_SCISSOR_BR_1 -0x1ce8 RE_SCISSOR_TL_2 -0x1cec RE_SCISSOR_BR_2 -0x1d60 RB3D_DEPTHXY_OFFSET -0x1d7c RB3D_STENCILREFMASK -0x1d80 RB3D_ROPCNTL -0x1d84 RB3D_PLANEMASK -0x1d98 VAP_VPORT_XSCALE -0x1d9c VAP_VPORT_XOFFSET -0x1da0 VAP_VPORT_YSCALE -0x1da4 VAP_VPORT_YOFFSET -0x1da8 VAP_VPORT_ZSCALE -0x1dac VAP_VPORT_ZOFFSET -0x1db0 SE_ZBIAS_FACTOR -0x1db4 SE_ZBIAS_CONSTANT -0x1db8 SE_LINE_WIDTH -0x2080 SE_VAP_CNTL -0x2090 SE_TCL_OUTPUT_VTX_FMT_0 -0x2094 SE_TCL_OUTPUT_VTX_FMT_1 -0x20b0 SE_VTE_CNTL -0x2140 SE_CNTL_STATUS -0x2180 SE_VTX_STATE_CNTL -0x2200 SE_TCL_VECTOR_INDX_REG -0x2204 SE_TCL_VECTOR_DATA_REG -0x2208 SE_TCL_SCALAR_INDX_REG -0x220c SE_TCL_SCALAR_DATA_REG -0x2230 SE_TCL_MATRIX_SEL_0 -0x2234 SE_TCL_MATRIX_SEL_1 -0x2238 SE_TCL_MATRIX_SEL_2 -0x223c SE_TCL_MATRIX_SEL_3 -0x2240 SE_TCL_MATRIX_SEL_4 -0x2250 SE_TCL_OUTPUT_VTX_COMP_SEL -0x2254 SE_TCL_INPUT_VTX_VECTOR_ADDR_0 -0x2258 SE_TCL_INPUT_VTX_VECTOR_ADDR_1 -0x225c SE_TCL_INPUT_VTX_VECTOR_ADDR_2 -0x2260 SE_TCL_INPUT_VTX_VECTOR_ADDR_3 -0x2268 SE_TCL_LIGHT_MODEL_CTL_0 -0x226c SE_TCL_LIGHT_MODEL_CTL_1 -0x2270 SE_TCL_PER_LIGHT_CTL_0 -0x2274 SE_TCL_PER_LIGHT_CTL_1 -0x2278 SE_TCL_PER_LIGHT_CTL_2 -0x227c SE_TCL_PER_LIGHT_CTL_3 -0x2284 VAP_PVS_STATE_FLUSH_REG -0x22a8 SE_TCL_TEX_PROC_CTL_2 -0x22ac SE_TCL_TEX_PROC_CTL_3 -0x22b0 SE_TCL_TEX_PROC_CTL_0 -0x22b4 SE_TCL_TEX_PROC_CTL_1 -0x22b8 SE_TCL_TEX_CYL_WRAP_CTL -0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL -0x22c4 SE_TCL_POINT_SPRITE_CNTL -0x22d0 SE_PVS_CNTL -0x22d4 SE_PVS_CONST_CNTL -0x2648 RE_POINTSIZE -0x26c0 RE_TOP_LEFT -0x26c4 RE_MISC -0x26f0 RE_AUX_SCISSOR_CNTL -0x2c14 PP_BORDER_COLOR_0 -0x2c34 PP_BORDER_COLOR_1 -0x2c54 PP_BORDER_COLOR_2 -0x2c74 PP_BORDER_COLOR_3 -0x2c94 PP_BORDER_COLOR_4 -0x2cb4 PP_BORDER_COLOR_5 -0x2cc4 PP_CNTL_X -0x2cf8 PP_TRI_PERF -0x2cfc PP_PERF_CNTL -0x2d9c PP_TAM_DEBUG3 -0x2ee0 PP_TFACTOR_0 -0x2ee4 PP_TFACTOR_1 -0x2ee8 PP_TFACTOR_2 -0x2eec PP_TFACTOR_3 -0x2ef0 PP_TFACTOR_4 -0x2ef4 PP_TFACTOR_5 -0x2ef8 PP_TFACTOR_6 -0x2efc PP_TFACTOR_7 -0x2f00 PP_TXCBLEND_0 -0x2f04 PP_TXCBLEND2_0 -0x2f08 PP_TXABLEND_0 -0x2f0c PP_TXABLEND2_0 -0x2f10 PP_TXCBLEND_1 -0x2f14 PP_TXCBLEND2_1 -0x2f18 PP_TXABLEND_1 -0x2f1c PP_TXABLEND2_1 -0x2f20 PP_TXCBLEND_2 -0x2f24 PP_TXCBLEND2_2 -0x2f28 PP_TXABLEND_2 -0x2f2c PP_TXABLEND2_2 -0x2f30 PP_TXCBLEND_3 -0x2f34 PP_TXCBLEND2_3 -0x2f38 PP_TXABLEND_3 -0x2f3c PP_TXABLEND2_3 -0x2f40 PP_TXCBLEND_4 -0x2f44 PP_TXCBLEND2_4 -0x2f48 PP_TXABLEND_4 -0x2f4c PP_TXABLEND2_4 -0x2f50 PP_TXCBLEND_5 -0x2f54 PP_TXCBLEND2_5 -0x2f58 PP_TXABLEND_5 -0x2f5c PP_TXABLEND2_5 -0x2f60 PP_TXCBLEND_6 -0x2f64 PP_TXCBLEND2_6 -0x2f68 PP_TXABLEND_6 -0x2f6c PP_TXABLEND2_6 -0x2f70 PP_TXCBLEND_7 -0x2f74 PP_TXCBLEND2_7 -0x2f78 PP_TXABLEND_7 -0x2f7c PP_TXABLEND2_7 -0x2f80 PP_TXCBLEND_8 -0x2f84 PP_TXCBLEND2_8 -0x2f88 PP_TXABLEND_8 -0x2f8c PP_TXABLEND2_8 -0x2f90 PP_TXCBLEND_9 -0x2f94 PP_TXCBLEND2_9 -0x2f98 PP_TXABLEND_9 -0x2f9c PP_TXABLEND2_9 -0x2fa0 PP_TXCBLEND_10 -0x2fa4 PP_TXCBLEND2_10 -0x2fa8 PP_TXABLEND_10 -0x2fac PP_TXABLEND2_10 -0x2fb0 PP_TXCBLEND_11 -0x2fb4 PP_TXCBLEND2_11 -0x2fb8 PP_TXABLEND_11 -0x2fbc PP_TXABLEND2_11 -0x2fc0 PP_TXCBLEND_12 -0x2fc4 PP_TXCBLEND2_12 -0x2fc8 PP_TXABLEND_12 -0x2fcc PP_TXABLEND2_12 -0x2fd0 PP_TXCBLEND_13 -0x2fd4 PP_TXCBLEND2_13 -0x2fd8 PP_TXABLEND_13 -0x2fdc PP_TXABLEND2_13 -0x2fe0 PP_TXCBLEND_14 -0x2fe4 PP_TXCBLEND2_14 -0x2fe8 PP_TXABLEND_14 -0x2fec PP_TXABLEND2_14 -0x2ff0 PP_TXCBLEND_15 -0x2ff4 PP_TXCBLEND2_15 -0x2ff8 PP_TXABLEND_15 -0x2ffc PP_TXABLEND2_15 -0x3218 RB3D_BLENCOLOR -0x321c RB3D_ABLENDCNTL -0x3220 RB3D_CBLENDCNTL -0x3290 RB3D_ZPASS_DATA - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r300 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r300 deleted file mode 100644 index e8a1786b..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r300 +++ /dev/null @@ -1,714 +0,0 @@ -r300 0x4f60 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL -0x1D98 VAP_VPORT_XSCALE -0x1D9C VAP_VPORT_XOFFSET -0x1DA0 VAP_VPORT_YSCALE -0x1DA4 VAP_VPORT_YOFFSET -0x1DA8 VAP_VPORT_ZSCALE -0x1DAC VAP_VPORT_ZOFFSET -0x2080 VAP_CNTL -0x2090 VAP_OUT_VTX_FMT_0 -0x2094 VAP_OUT_VTX_FMT_1 -0x20B0 VAP_VTE_CNTL -0x2138 VAP_VF_MIN_VTX_INDX -0x2140 VAP_CNTL_STATUS -0x2150 VAP_PROG_STREAM_CNTL_0 -0x2154 VAP_PROG_STREAM_CNTL_1 -0x2158 VAP_PROG_STREAM_CNTL_2 -0x215C VAP_PROG_STREAM_CNTL_3 -0x2160 VAP_PROG_STREAM_CNTL_4 -0x2164 VAP_PROG_STREAM_CNTL_5 -0x2168 VAP_PROG_STREAM_CNTL_6 -0x216C VAP_PROG_STREAM_CNTL_7 -0x2180 VAP_VTX_STATE_CNTL -0x2184 VAP_VSM_VTX_ASSM -0x2188 VAP_VTX_STATE_IND_REG_0 -0x218C VAP_VTX_STATE_IND_REG_1 -0x2190 VAP_VTX_STATE_IND_REG_2 -0x2194 VAP_VTX_STATE_IND_REG_3 -0x2198 VAP_VTX_STATE_IND_REG_4 -0x219C VAP_VTX_STATE_IND_REG_5 -0x21A0 VAP_VTX_STATE_IND_REG_6 -0x21A4 VAP_VTX_STATE_IND_REG_7 -0x21A8 VAP_VTX_STATE_IND_REG_8 -0x21AC VAP_VTX_STATE_IND_REG_9 -0x21B0 VAP_VTX_STATE_IND_REG_10 -0x21B4 VAP_VTX_STATE_IND_REG_11 -0x21B8 VAP_VTX_STATE_IND_REG_12 -0x21BC VAP_VTX_STATE_IND_REG_13 -0x21C0 VAP_VTX_STATE_IND_REG_14 -0x21C4 VAP_VTX_STATE_IND_REG_15 -0x21DC VAP_PSC_SGN_NORM_CNTL -0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -0x2200 VAP_PVS_VECTOR_INDX_REG -0x2204 VAP_PVS_VECTOR_DATA_REG -0x2208 VAP_PVS_VECTOR_DATA_REG_128 -0x221C VAP_CLIP_CNTL -0x2220 VAP_GB_VERT_CLIP_ADJ -0x2224 VAP_GB_VERT_DISC_ADJ -0x2228 VAP_GB_HORZ_CLIP_ADJ -0x222C VAP_GB_HORZ_DISC_ADJ -0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -0x2284 VAP_PVS_STATE_FLUSH_REG -0x2288 VAP_PVS_VTX_TIMEOUT_REG -0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -0x22D0 VAP_PVS_CODE_CNTL_0 -0x22D4 VAP_PVS_CONST_CNTL -0x22D8 VAP_PVS_CODE_CNTL_1 -0x22DC VAP_PVS_FLOW_CNTL_OPC -0x342C RB2D_DSTCACHE_CTLSTAT -0x4000 GB_VAP_RASTER_VTX_FMT_0 -0x4004 GB_VAP_RASTER_VTX_FMT_1 -0x4008 GB_ENABLE -0x4010 GB_MSPOS0 -0x4014 GB_MSPOS1 -0x401C GB_SELECT -0x4020 GB_AA_CONFIG -0x4024 GB_FIFO_SIZE -0x4100 TX_INVALTAGS -0x4200 GA_POINT_S0 -0x4204 GA_POINT_T0 -0x4208 GA_POINT_S1 -0x420C GA_POINT_T1 -0x4214 GA_TRIANGLE_STIPPLE -0x421C GA_POINT_SIZE -0x4230 GA_POINT_MINMAX -0x4234 GA_LINE_CNTL -0x4238 GA_LINE_STIPPLE_CONFIG -0x4260 GA_LINE_STIPPLE_VALUE -0x4264 GA_LINE_S0 -0x4268 GA_LINE_S1 -0x4278 GA_COLOR_CONTROL -0x427C GA_SOLID_RG -0x4280 GA_SOLID_BA -0x4288 GA_POLY_MODE -0x428C GA_ROUND_MODE -0x4290 GA_OFFSET -0x4294 GA_FOG_SCALE -0x4298 GA_FOG_OFFSET -0x42A0 SU_TEX_WRAP -0x42A4 SU_POLY_OFFSET_FRONT_SCALE -0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -0x42AC SU_POLY_OFFSET_BACK_SCALE -0x42B0 SU_POLY_OFFSET_BACK_OFFSET -0x42B4 SU_POLY_OFFSET_ENABLE -0x42B8 SU_CULL_MODE -0x42C0 SU_DEPTH_SCALE -0x42C4 SU_DEPTH_OFFSET -0x42C8 SU_REG_DEST -0x4300 RS_COUNT -0x4304 RS_INST_COUNT -0x4310 RS_IP_0 -0x4314 RS_IP_1 -0x4318 RS_IP_2 -0x431C RS_IP_3 -0x4320 RS_IP_4 -0x4324 RS_IP_5 -0x4328 RS_IP_6 -0x432C RS_IP_7 -0x4330 RS_INST_0 -0x4334 RS_INST_1 -0x4338 RS_INST_2 -0x433C RS_INST_3 -0x4340 RS_INST_4 -0x4344 RS_INST_5 -0x4348 RS_INST_6 -0x434C RS_INST_7 -0x4350 RS_INST_8 -0x4354 RS_INST_9 -0x4358 RS_INST_10 -0x435C RS_INST_11 -0x4360 RS_INST_12 -0x4364 RS_INST_13 -0x4368 RS_INST_14 -0x436C RS_INST_15 -0x43A8 SC_EDGERULE -0x43B0 SC_CLIP_0_A -0x43B4 SC_CLIP_0_B -0x43B8 SC_CLIP_1_A -0x43BC SC_CLIP_1_B -0x43C0 SC_CLIP_2_A -0x43C4 SC_CLIP_2_B -0x43C8 SC_CLIP_3_A -0x43CC SC_CLIP_3_B -0x43D0 SC_CLIP_RULE -0x43E0 SC_SCISSOR0 -0x43E8 SC_SCREENDOOR -0x4440 TX_FILTER1_0 -0x4444 TX_FILTER1_1 -0x4448 TX_FILTER1_2 -0x444C TX_FILTER1_3 -0x4450 TX_FILTER1_4 -0x4454 TX_FILTER1_5 -0x4458 TX_FILTER1_6 -0x445C TX_FILTER1_7 -0x4460 TX_FILTER1_8 -0x4464 TX_FILTER1_9 -0x4468 TX_FILTER1_10 -0x446C TX_FILTER1_11 -0x4470 TX_FILTER1_12 -0x4474 TX_FILTER1_13 -0x4478 TX_FILTER1_14 -0x447C TX_FILTER1_15 -0x4580 TX_CHROMA_KEY_0 -0x4584 TX_CHROMA_KEY_1 -0x4588 TX_CHROMA_KEY_2 -0x458C TX_CHROMA_KEY_3 -0x4590 TX_CHROMA_KEY_4 -0x4594 TX_CHROMA_KEY_5 -0x4598 TX_CHROMA_KEY_6 -0x459C TX_CHROMA_KEY_7 -0x45A0 TX_CHROMA_KEY_8 -0x45A4 TX_CHROMA_KEY_9 -0x45A8 TX_CHROMA_KEY_10 -0x45AC TX_CHROMA_KEY_11 -0x45B0 TX_CHROMA_KEY_12 -0x45B4 TX_CHROMA_KEY_13 -0x45B8 TX_CHROMA_KEY_14 -0x45BC TX_CHROMA_KEY_15 -0x45C0 TX_BORDER_COLOR_0 -0x45C4 TX_BORDER_COLOR_1 -0x45C8 TX_BORDER_COLOR_2 -0x45CC TX_BORDER_COLOR_3 -0x45D0 TX_BORDER_COLOR_4 -0x45D4 TX_BORDER_COLOR_5 -0x45D8 TX_BORDER_COLOR_6 -0x45DC TX_BORDER_COLOR_7 -0x45E0 TX_BORDER_COLOR_8 -0x45E4 TX_BORDER_COLOR_9 -0x45E8 TX_BORDER_COLOR_10 -0x45EC TX_BORDER_COLOR_11 -0x45F0 TX_BORDER_COLOR_12 -0x45F4 TX_BORDER_COLOR_13 -0x45F8 TX_BORDER_COLOR_14 -0x45FC TX_BORDER_COLOR_15 -0x4600 US_CONFIG -0x4604 US_PIXSIZE -0x4608 US_CODE_OFFSET -0x460C US_RESET -0x4610 US_CODE_ADDR_0 -0x4614 US_CODE_ADDR_1 -0x4618 US_CODE_ADDR_2 -0x461C US_CODE_ADDR_3 -0x4620 US_TEX_INST_0 -0x4624 US_TEX_INST_1 -0x4628 US_TEX_INST_2 -0x462C US_TEX_INST_3 -0x4630 US_TEX_INST_4 -0x4634 US_TEX_INST_5 -0x4638 US_TEX_INST_6 -0x463C US_TEX_INST_7 -0x4640 US_TEX_INST_8 -0x4644 US_TEX_INST_9 -0x4648 US_TEX_INST_10 -0x464C US_TEX_INST_11 -0x4650 US_TEX_INST_12 -0x4654 US_TEX_INST_13 -0x4658 US_TEX_INST_14 -0x465C US_TEX_INST_15 -0x4660 US_TEX_INST_16 -0x4664 US_TEX_INST_17 -0x4668 US_TEX_INST_18 -0x466C US_TEX_INST_19 -0x4670 US_TEX_INST_20 -0x4674 US_TEX_INST_21 -0x4678 US_TEX_INST_22 -0x467C US_TEX_INST_23 -0x4680 US_TEX_INST_24 -0x4684 US_TEX_INST_25 -0x4688 US_TEX_INST_26 -0x468C US_TEX_INST_27 -0x4690 US_TEX_INST_28 -0x4694 US_TEX_INST_29 -0x4698 US_TEX_INST_30 -0x469C US_TEX_INST_31 -0x46A4 US_OUT_FMT_0 -0x46A8 US_OUT_FMT_1 -0x46AC US_OUT_FMT_2 -0x46B0 US_OUT_FMT_3 -0x46B4 US_W_FMT -0x46C0 US_ALU_RGB_ADDR_0 -0x46C4 US_ALU_RGB_ADDR_1 -0x46C8 US_ALU_RGB_ADDR_2 -0x46CC US_ALU_RGB_ADDR_3 -0x46D0 US_ALU_RGB_ADDR_4 -0x46D4 US_ALU_RGB_ADDR_5 -0x46D8 US_ALU_RGB_ADDR_6 -0x46DC US_ALU_RGB_ADDR_7 -0x46E0 US_ALU_RGB_ADDR_8 -0x46E4 US_ALU_RGB_ADDR_9 -0x46E8 US_ALU_RGB_ADDR_10 -0x46EC US_ALU_RGB_ADDR_11 -0x46F0 US_ALU_RGB_ADDR_12 -0x46F4 US_ALU_RGB_ADDR_13 -0x46F8 US_ALU_RGB_ADDR_14 -0x46FC US_ALU_RGB_ADDR_15 -0x4700 US_ALU_RGB_ADDR_16 -0x4704 US_ALU_RGB_ADDR_17 -0x4708 US_ALU_RGB_ADDR_18 -0x470C US_ALU_RGB_ADDR_19 -0x4710 US_ALU_RGB_ADDR_20 -0x4714 US_ALU_RGB_ADDR_21 -0x4718 US_ALU_RGB_ADDR_22 -0x471C US_ALU_RGB_ADDR_23 -0x4720 US_ALU_RGB_ADDR_24 -0x4724 US_ALU_RGB_ADDR_25 -0x4728 US_ALU_RGB_ADDR_26 -0x472C US_ALU_RGB_ADDR_27 -0x4730 US_ALU_RGB_ADDR_28 -0x4734 US_ALU_RGB_ADDR_29 -0x4738 US_ALU_RGB_ADDR_30 -0x473C US_ALU_RGB_ADDR_31 -0x4740 US_ALU_RGB_ADDR_32 -0x4744 US_ALU_RGB_ADDR_33 -0x4748 US_ALU_RGB_ADDR_34 -0x474C US_ALU_RGB_ADDR_35 -0x4750 US_ALU_RGB_ADDR_36 -0x4754 US_ALU_RGB_ADDR_37 -0x4758 US_ALU_RGB_ADDR_38 -0x475C US_ALU_RGB_ADDR_39 -0x4760 US_ALU_RGB_ADDR_40 -0x4764 US_ALU_RGB_ADDR_41 -0x4768 US_ALU_RGB_ADDR_42 -0x476C US_ALU_RGB_ADDR_43 -0x4770 US_ALU_RGB_ADDR_44 -0x4774 US_ALU_RGB_ADDR_45 -0x4778 US_ALU_RGB_ADDR_46 -0x477C US_ALU_RGB_ADDR_47 -0x4780 US_ALU_RGB_ADDR_48 -0x4784 US_ALU_RGB_ADDR_49 -0x4788 US_ALU_RGB_ADDR_50 -0x478C US_ALU_RGB_ADDR_51 -0x4790 US_ALU_RGB_ADDR_52 -0x4794 US_ALU_RGB_ADDR_53 -0x4798 US_ALU_RGB_ADDR_54 -0x479C US_ALU_RGB_ADDR_55 -0x47A0 US_ALU_RGB_ADDR_56 -0x47A4 US_ALU_RGB_ADDR_57 -0x47A8 US_ALU_RGB_ADDR_58 -0x47AC US_ALU_RGB_ADDR_59 -0x47B0 US_ALU_RGB_ADDR_60 -0x47B4 US_ALU_RGB_ADDR_61 -0x47B8 US_ALU_RGB_ADDR_62 -0x47BC US_ALU_RGB_ADDR_63 -0x47C0 US_ALU_ALPHA_ADDR_0 -0x47C4 US_ALU_ALPHA_ADDR_1 -0x47C8 US_ALU_ALPHA_ADDR_2 -0x47CC US_ALU_ALPHA_ADDR_3 -0x47D0 US_ALU_ALPHA_ADDR_4 -0x47D4 US_ALU_ALPHA_ADDR_5 -0x47D8 US_ALU_ALPHA_ADDR_6 -0x47DC US_ALU_ALPHA_ADDR_7 -0x47E0 US_ALU_ALPHA_ADDR_8 -0x47E4 US_ALU_ALPHA_ADDR_9 -0x47E8 US_ALU_ALPHA_ADDR_10 -0x47EC US_ALU_ALPHA_ADDR_11 -0x47F0 US_ALU_ALPHA_ADDR_12 -0x47F4 US_ALU_ALPHA_ADDR_13 -0x47F8 US_ALU_ALPHA_ADDR_14 -0x47FC US_ALU_ALPHA_ADDR_15 -0x4800 US_ALU_ALPHA_ADDR_16 -0x4804 US_ALU_ALPHA_ADDR_17 -0x4808 US_ALU_ALPHA_ADDR_18 -0x480C US_ALU_ALPHA_ADDR_19 -0x4810 US_ALU_ALPHA_ADDR_20 -0x4814 US_ALU_ALPHA_ADDR_21 -0x4818 US_ALU_ALPHA_ADDR_22 -0x481C US_ALU_ALPHA_ADDR_23 -0x4820 US_ALU_ALPHA_ADDR_24 -0x4824 US_ALU_ALPHA_ADDR_25 -0x4828 US_ALU_ALPHA_ADDR_26 -0x482C US_ALU_ALPHA_ADDR_27 -0x4830 US_ALU_ALPHA_ADDR_28 -0x4834 US_ALU_ALPHA_ADDR_29 -0x4838 US_ALU_ALPHA_ADDR_30 -0x483C US_ALU_ALPHA_ADDR_31 -0x4840 US_ALU_ALPHA_ADDR_32 -0x4844 US_ALU_ALPHA_ADDR_33 -0x4848 US_ALU_ALPHA_ADDR_34 -0x484C US_ALU_ALPHA_ADDR_35 -0x4850 US_ALU_ALPHA_ADDR_36 -0x4854 US_ALU_ALPHA_ADDR_37 -0x4858 US_ALU_ALPHA_ADDR_38 -0x485C US_ALU_ALPHA_ADDR_39 -0x4860 US_ALU_ALPHA_ADDR_40 -0x4864 US_ALU_ALPHA_ADDR_41 -0x4868 US_ALU_ALPHA_ADDR_42 -0x486C US_ALU_ALPHA_ADDR_43 -0x4870 US_ALU_ALPHA_ADDR_44 -0x4874 US_ALU_ALPHA_ADDR_45 -0x4878 US_ALU_ALPHA_ADDR_46 -0x487C US_ALU_ALPHA_ADDR_47 -0x4880 US_ALU_ALPHA_ADDR_48 -0x4884 US_ALU_ALPHA_ADDR_49 -0x4888 US_ALU_ALPHA_ADDR_50 -0x488C US_ALU_ALPHA_ADDR_51 -0x4890 US_ALU_ALPHA_ADDR_52 -0x4894 US_ALU_ALPHA_ADDR_53 -0x4898 US_ALU_ALPHA_ADDR_54 -0x489C US_ALU_ALPHA_ADDR_55 -0x48A0 US_ALU_ALPHA_ADDR_56 -0x48A4 US_ALU_ALPHA_ADDR_57 -0x48A8 US_ALU_ALPHA_ADDR_58 -0x48AC US_ALU_ALPHA_ADDR_59 -0x48B0 US_ALU_ALPHA_ADDR_60 -0x48B4 US_ALU_ALPHA_ADDR_61 -0x48B8 US_ALU_ALPHA_ADDR_62 -0x48BC US_ALU_ALPHA_ADDR_63 -0x48C0 US_ALU_RGB_INST_0 -0x48C4 US_ALU_RGB_INST_1 -0x48C8 US_ALU_RGB_INST_2 -0x48CC US_ALU_RGB_INST_3 -0x48D0 US_ALU_RGB_INST_4 -0x48D4 US_ALU_RGB_INST_5 -0x48D8 US_ALU_RGB_INST_6 -0x48DC US_ALU_RGB_INST_7 -0x48E0 US_ALU_RGB_INST_8 -0x48E4 US_ALU_RGB_INST_9 -0x48E8 US_ALU_RGB_INST_10 -0x48EC US_ALU_RGB_INST_11 -0x48F0 US_ALU_RGB_INST_12 -0x48F4 US_ALU_RGB_INST_13 -0x48F8 US_ALU_RGB_INST_14 -0x48FC US_ALU_RGB_INST_15 -0x4900 US_ALU_RGB_INST_16 -0x4904 US_ALU_RGB_INST_17 -0x4908 US_ALU_RGB_INST_18 -0x490C US_ALU_RGB_INST_19 -0x4910 US_ALU_RGB_INST_20 -0x4914 US_ALU_RGB_INST_21 -0x4918 US_ALU_RGB_INST_22 -0x491C US_ALU_RGB_INST_23 -0x4920 US_ALU_RGB_INST_24 -0x4924 US_ALU_RGB_INST_25 -0x4928 US_ALU_RGB_INST_26 -0x492C US_ALU_RGB_INST_27 -0x4930 US_ALU_RGB_INST_28 -0x4934 US_ALU_RGB_INST_29 -0x4938 US_ALU_RGB_INST_30 -0x493C US_ALU_RGB_INST_31 -0x4940 US_ALU_RGB_INST_32 -0x4944 US_ALU_RGB_INST_33 -0x4948 US_ALU_RGB_INST_34 -0x494C US_ALU_RGB_INST_35 -0x4950 US_ALU_RGB_INST_36 -0x4954 US_ALU_RGB_INST_37 -0x4958 US_ALU_RGB_INST_38 -0x495C US_ALU_RGB_INST_39 -0x4960 US_ALU_RGB_INST_40 -0x4964 US_ALU_RGB_INST_41 -0x4968 US_ALU_RGB_INST_42 -0x496C US_ALU_RGB_INST_43 -0x4970 US_ALU_RGB_INST_44 -0x4974 US_ALU_RGB_INST_45 -0x4978 US_ALU_RGB_INST_46 -0x497C US_ALU_RGB_INST_47 -0x4980 US_ALU_RGB_INST_48 -0x4984 US_ALU_RGB_INST_49 -0x4988 US_ALU_RGB_INST_50 -0x498C US_ALU_RGB_INST_51 -0x4990 US_ALU_RGB_INST_52 -0x4994 US_ALU_RGB_INST_53 -0x4998 US_ALU_RGB_INST_54 -0x499C US_ALU_RGB_INST_55 -0x49A0 US_ALU_RGB_INST_56 -0x49A4 US_ALU_RGB_INST_57 -0x49A8 US_ALU_RGB_INST_58 -0x49AC US_ALU_RGB_INST_59 -0x49B0 US_ALU_RGB_INST_60 -0x49B4 US_ALU_RGB_INST_61 -0x49B8 US_ALU_RGB_INST_62 -0x49BC US_ALU_RGB_INST_63 -0x49C0 US_ALU_ALPHA_INST_0 -0x49C4 US_ALU_ALPHA_INST_1 -0x49C8 US_ALU_ALPHA_INST_2 -0x49CC US_ALU_ALPHA_INST_3 -0x49D0 US_ALU_ALPHA_INST_4 -0x49D4 US_ALU_ALPHA_INST_5 -0x49D8 US_ALU_ALPHA_INST_6 -0x49DC US_ALU_ALPHA_INST_7 -0x49E0 US_ALU_ALPHA_INST_8 -0x49E4 US_ALU_ALPHA_INST_9 -0x49E8 US_ALU_ALPHA_INST_10 -0x49EC US_ALU_ALPHA_INST_11 -0x49F0 US_ALU_ALPHA_INST_12 -0x49F4 US_ALU_ALPHA_INST_13 -0x49F8 US_ALU_ALPHA_INST_14 -0x49FC US_ALU_ALPHA_INST_15 -0x4A00 US_ALU_ALPHA_INST_16 -0x4A04 US_ALU_ALPHA_INST_17 -0x4A08 US_ALU_ALPHA_INST_18 -0x4A0C US_ALU_ALPHA_INST_19 -0x4A10 US_ALU_ALPHA_INST_20 -0x4A14 US_ALU_ALPHA_INST_21 -0x4A18 US_ALU_ALPHA_INST_22 -0x4A1C US_ALU_ALPHA_INST_23 -0x4A20 US_ALU_ALPHA_INST_24 -0x4A24 US_ALU_ALPHA_INST_25 -0x4A28 US_ALU_ALPHA_INST_26 -0x4A2C US_ALU_ALPHA_INST_27 -0x4A30 US_ALU_ALPHA_INST_28 -0x4A34 US_ALU_ALPHA_INST_29 -0x4A38 US_ALU_ALPHA_INST_30 -0x4A3C US_ALU_ALPHA_INST_31 -0x4A40 US_ALU_ALPHA_INST_32 -0x4A44 US_ALU_ALPHA_INST_33 -0x4A48 US_ALU_ALPHA_INST_34 -0x4A4C US_ALU_ALPHA_INST_35 -0x4A50 US_ALU_ALPHA_INST_36 -0x4A54 US_ALU_ALPHA_INST_37 -0x4A58 US_ALU_ALPHA_INST_38 -0x4A5C US_ALU_ALPHA_INST_39 -0x4A60 US_ALU_ALPHA_INST_40 -0x4A64 US_ALU_ALPHA_INST_41 -0x4A68 US_ALU_ALPHA_INST_42 -0x4A6C US_ALU_ALPHA_INST_43 -0x4A70 US_ALU_ALPHA_INST_44 -0x4A74 US_ALU_ALPHA_INST_45 -0x4A78 US_ALU_ALPHA_INST_46 -0x4A7C US_ALU_ALPHA_INST_47 -0x4A80 US_ALU_ALPHA_INST_48 -0x4A84 US_ALU_ALPHA_INST_49 -0x4A88 US_ALU_ALPHA_INST_50 -0x4A8C US_ALU_ALPHA_INST_51 -0x4A90 US_ALU_ALPHA_INST_52 -0x4A94 US_ALU_ALPHA_INST_53 -0x4A98 US_ALU_ALPHA_INST_54 -0x4A9C US_ALU_ALPHA_INST_55 -0x4AA0 US_ALU_ALPHA_INST_56 -0x4AA4 US_ALU_ALPHA_INST_57 -0x4AA8 US_ALU_ALPHA_INST_58 -0x4AAC US_ALU_ALPHA_INST_59 -0x4AB0 US_ALU_ALPHA_INST_60 -0x4AB4 US_ALU_ALPHA_INST_61 -0x4AB8 US_ALU_ALPHA_INST_62 -0x4ABC US_ALU_ALPHA_INST_63 -0x4BC0 FG_FOG_BLEND -0x4BC4 FG_FOG_FACTOR -0x4BC8 FG_FOG_COLOR_R -0x4BCC FG_FOG_COLOR_G -0x4BD0 FG_FOG_COLOR_B -0x4BD4 FG_ALPHA_FUNC -0x4BD8 FG_DEPTH_SRC -0x4C00 US_ALU_CONST_R_0 -0x4C04 US_ALU_CONST_G_0 -0x4C08 US_ALU_CONST_B_0 -0x4C0C US_ALU_CONST_A_0 -0x4C10 US_ALU_CONST_R_1 -0x4C14 US_ALU_CONST_G_1 -0x4C18 US_ALU_CONST_B_1 -0x4C1C US_ALU_CONST_A_1 -0x4C20 US_ALU_CONST_R_2 -0x4C24 US_ALU_CONST_G_2 -0x4C28 US_ALU_CONST_B_2 -0x4C2C US_ALU_CONST_A_2 -0x4C30 US_ALU_CONST_R_3 -0x4C34 US_ALU_CONST_G_3 -0x4C38 US_ALU_CONST_B_3 -0x4C3C US_ALU_CONST_A_3 -0x4C40 US_ALU_CONST_R_4 -0x4C44 US_ALU_CONST_G_4 -0x4C48 US_ALU_CONST_B_4 -0x4C4C US_ALU_CONST_A_4 -0x4C50 US_ALU_CONST_R_5 -0x4C54 US_ALU_CONST_G_5 -0x4C58 US_ALU_CONST_B_5 -0x4C5C US_ALU_CONST_A_5 -0x4C60 US_ALU_CONST_R_6 -0x4C64 US_ALU_CONST_G_6 -0x4C68 US_ALU_CONST_B_6 -0x4C6C US_ALU_CONST_A_6 -0x4C70 US_ALU_CONST_R_7 -0x4C74 US_ALU_CONST_G_7 -0x4C78 US_ALU_CONST_B_7 -0x4C7C US_ALU_CONST_A_7 -0x4C80 US_ALU_CONST_R_8 -0x4C84 US_ALU_CONST_G_8 -0x4C88 US_ALU_CONST_B_8 -0x4C8C US_ALU_CONST_A_8 -0x4C90 US_ALU_CONST_R_9 -0x4C94 US_ALU_CONST_G_9 -0x4C98 US_ALU_CONST_B_9 -0x4C9C US_ALU_CONST_A_9 -0x4CA0 US_ALU_CONST_R_10 -0x4CA4 US_ALU_CONST_G_10 -0x4CA8 US_ALU_CONST_B_10 -0x4CAC US_ALU_CONST_A_10 -0x4CB0 US_ALU_CONST_R_11 -0x4CB4 US_ALU_CONST_G_11 -0x4CB8 US_ALU_CONST_B_11 -0x4CBC US_ALU_CONST_A_11 -0x4CC0 US_ALU_CONST_R_12 -0x4CC4 US_ALU_CONST_G_12 -0x4CC8 US_ALU_CONST_B_12 -0x4CCC US_ALU_CONST_A_12 -0x4CD0 US_ALU_CONST_R_13 -0x4CD4 US_ALU_CONST_G_13 -0x4CD8 US_ALU_CONST_B_13 -0x4CDC US_ALU_CONST_A_13 -0x4CE0 US_ALU_CONST_R_14 -0x4CE4 US_ALU_CONST_G_14 -0x4CE8 US_ALU_CONST_B_14 -0x4CEC US_ALU_CONST_A_14 -0x4CF0 US_ALU_CONST_R_15 -0x4CF4 US_ALU_CONST_G_15 -0x4CF8 US_ALU_CONST_B_15 -0x4CFC US_ALU_CONST_A_15 -0x4D00 US_ALU_CONST_R_16 -0x4D04 US_ALU_CONST_G_16 -0x4D08 US_ALU_CONST_B_16 -0x4D0C US_ALU_CONST_A_16 -0x4D10 US_ALU_CONST_R_17 -0x4D14 US_ALU_CONST_G_17 -0x4D18 US_ALU_CONST_B_17 -0x4D1C US_ALU_CONST_A_17 -0x4D20 US_ALU_CONST_R_18 -0x4D24 US_ALU_CONST_G_18 -0x4D28 US_ALU_CONST_B_18 -0x4D2C US_ALU_CONST_A_18 -0x4D30 US_ALU_CONST_R_19 -0x4D34 US_ALU_CONST_G_19 -0x4D38 US_ALU_CONST_B_19 -0x4D3C US_ALU_CONST_A_19 -0x4D40 US_ALU_CONST_R_20 -0x4D44 US_ALU_CONST_G_20 -0x4D48 US_ALU_CONST_B_20 -0x4D4C US_ALU_CONST_A_20 -0x4D50 US_ALU_CONST_R_21 -0x4D54 US_ALU_CONST_G_21 -0x4D58 US_ALU_CONST_B_21 -0x4D5C US_ALU_CONST_A_21 -0x4D60 US_ALU_CONST_R_22 -0x4D64 US_ALU_CONST_G_22 -0x4D68 US_ALU_CONST_B_22 -0x4D6C US_ALU_CONST_A_22 -0x4D70 US_ALU_CONST_R_23 -0x4D74 US_ALU_CONST_G_23 -0x4D78 US_ALU_CONST_B_23 -0x4D7C US_ALU_CONST_A_23 -0x4D80 US_ALU_CONST_R_24 -0x4D84 US_ALU_CONST_G_24 -0x4D88 US_ALU_CONST_B_24 -0x4D8C US_ALU_CONST_A_24 -0x4D90 US_ALU_CONST_R_25 -0x4D94 US_ALU_CONST_G_25 -0x4D98 US_ALU_CONST_B_25 -0x4D9C US_ALU_CONST_A_25 -0x4DA0 US_ALU_CONST_R_26 -0x4DA4 US_ALU_CONST_G_26 -0x4DA8 US_ALU_CONST_B_26 -0x4DAC US_ALU_CONST_A_26 -0x4DB0 US_ALU_CONST_R_27 -0x4DB4 US_ALU_CONST_G_27 -0x4DB8 US_ALU_CONST_B_27 -0x4DBC US_ALU_CONST_A_27 -0x4DC0 US_ALU_CONST_R_28 -0x4DC4 US_ALU_CONST_G_28 -0x4DC8 US_ALU_CONST_B_28 -0x4DCC US_ALU_CONST_A_28 -0x4DD0 US_ALU_CONST_R_29 -0x4DD4 US_ALU_CONST_G_29 -0x4DD8 US_ALU_CONST_B_29 -0x4DDC US_ALU_CONST_A_29 -0x4DE0 US_ALU_CONST_R_30 -0x4DE4 US_ALU_CONST_G_30 -0x4DE8 US_ALU_CONST_B_30 -0x4DEC US_ALU_CONST_A_30 -0x4DF0 US_ALU_CONST_R_31 -0x4DF4 US_ALU_CONST_G_31 -0x4DF8 US_ALU_CONST_B_31 -0x4DFC US_ALU_CONST_A_31 -0x4E08 RB3D_ABLENDCNTL_R3 -0x4E10 RB3D_CONSTANT_COLOR -0x4E14 RB3D_COLOR_CLEAR_VALUE -0x4E18 RB3D_ROPCNTL_R3 -0x4E1C RB3D_CLRCMP_FLIPE_R3 -0x4E20 RB3D_CLRCMP_CLR_R3 -0x4E24 RB3D_CLRCMP_MSK_R3 -0x4E48 RB3D_DEBUG_CTL -0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -0x4E50 RB3D_DITHER_CTL -0x4E54 RB3D_CMASK_OFFSET0 -0x4E58 RB3D_CMASK_OFFSET1 -0x4E5C RB3D_CMASK_OFFSET2 -0x4E60 RB3D_CMASK_OFFSET3 -0x4E64 RB3D_CMASK_PITCH0 -0x4E68 RB3D_CMASK_PITCH1 -0x4E6C RB3D_CMASK_PITCH2 -0x4E70 RB3D_CMASK_PITCH3 -0x4E74 RB3D_CMASK_WRINDEX -0x4E78 RB3D_CMASK_DWORD -0x4E7C RB3D_CMASK_RDINDEX -0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -0x4F04 ZB_ZSTENCILCNTL -0x4F08 ZB_STENCILREFMASK -0x4F14 ZB_ZTOP -0x4F18 ZB_ZCACHE_CTLSTAT -0x4F28 ZB_DEPTHCLEARVALUE -0x4F58 ZB_ZPASS_DATA diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r420 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r420 deleted file mode 100644 index 722074e2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r420 +++ /dev/null @@ -1,780 +0,0 @@ -r420 0x4f60 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL -0x1D98 VAP_VPORT_XSCALE -0x1D9C VAP_VPORT_XOFFSET -0x1DA0 VAP_VPORT_YSCALE -0x1DA4 VAP_VPORT_YOFFSET -0x1DA8 VAP_VPORT_ZSCALE -0x1DAC VAP_VPORT_ZOFFSET -0x2080 VAP_CNTL -0x2090 VAP_OUT_VTX_FMT_0 -0x2094 VAP_OUT_VTX_FMT_1 -0x20B0 VAP_VTE_CNTL -0x2138 VAP_VF_MIN_VTX_INDX -0x2140 VAP_CNTL_STATUS -0x2150 VAP_PROG_STREAM_CNTL_0 -0x2154 VAP_PROG_STREAM_CNTL_1 -0x2158 VAP_PROG_STREAM_CNTL_2 -0x215C VAP_PROG_STREAM_CNTL_3 -0x2160 VAP_PROG_STREAM_CNTL_4 -0x2164 VAP_PROG_STREAM_CNTL_5 -0x2168 VAP_PROG_STREAM_CNTL_6 -0x216C VAP_PROG_STREAM_CNTL_7 -0x2180 VAP_VTX_STATE_CNTL -0x2184 VAP_VSM_VTX_ASSM -0x2188 VAP_VTX_STATE_IND_REG_0 -0x218C VAP_VTX_STATE_IND_REG_1 -0x2190 VAP_VTX_STATE_IND_REG_2 -0x2194 VAP_VTX_STATE_IND_REG_3 -0x2198 VAP_VTX_STATE_IND_REG_4 -0x219C VAP_VTX_STATE_IND_REG_5 -0x21A0 VAP_VTX_STATE_IND_REG_6 -0x21A4 VAP_VTX_STATE_IND_REG_7 -0x21A8 VAP_VTX_STATE_IND_REG_8 -0x21AC VAP_VTX_STATE_IND_REG_9 -0x21B0 VAP_VTX_STATE_IND_REG_10 -0x21B4 VAP_VTX_STATE_IND_REG_11 -0x21B8 VAP_VTX_STATE_IND_REG_12 -0x21BC VAP_VTX_STATE_IND_REG_13 -0x21C0 VAP_VTX_STATE_IND_REG_14 -0x21C4 VAP_VTX_STATE_IND_REG_15 -0x21DC VAP_PSC_SGN_NORM_CNTL -0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -0x2200 VAP_PVS_VECTOR_INDX_REG -0x2204 VAP_PVS_VECTOR_DATA_REG -0x2208 VAP_PVS_VECTOR_DATA_REG_128 -0x221C VAP_CLIP_CNTL -0x2220 VAP_GB_VERT_CLIP_ADJ -0x2224 VAP_GB_VERT_DISC_ADJ -0x2228 VAP_GB_HORZ_CLIP_ADJ -0x222C VAP_GB_HORZ_DISC_ADJ -0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -0x2284 VAP_PVS_STATE_FLUSH_REG -0x2288 VAP_PVS_VTX_TIMEOUT_REG -0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -0x22D0 VAP_PVS_CODE_CNTL_0 -0x22D4 VAP_PVS_CONST_CNTL -0x22D8 VAP_PVS_CODE_CNTL_1 -0x22DC VAP_PVS_FLOW_CNTL_OPC -0x342C RB2D_DSTCACHE_CTLSTAT -0x4000 GB_VAP_RASTER_VTX_FMT_0 -0x4004 GB_VAP_RASTER_VTX_FMT_1 -0x4008 GB_ENABLE -0x4010 GB_MSPOS0 -0x4014 GB_MSPOS1 -0x401C GB_SELECT -0x4020 GB_AA_CONFIG -0x4024 GB_FIFO_SIZE -0x4100 TX_INVALTAGS -0x4200 GA_POINT_S0 -0x4204 GA_POINT_T0 -0x4208 GA_POINT_S1 -0x420C GA_POINT_T1 -0x4214 GA_TRIANGLE_STIPPLE -0x421C GA_POINT_SIZE -0x4230 GA_POINT_MINMAX -0x4234 GA_LINE_CNTL -0x4238 GA_LINE_STIPPLE_CONFIG -0x4260 GA_LINE_STIPPLE_VALUE -0x4264 GA_LINE_S0 -0x4268 GA_LINE_S1 -0x4278 GA_COLOR_CONTROL -0x427C GA_SOLID_RG -0x4280 GA_SOLID_BA -0x4288 GA_POLY_MODE -0x428C GA_ROUND_MODE -0x4290 GA_OFFSET -0x4294 GA_FOG_SCALE -0x4298 GA_FOG_OFFSET -0x42A0 SU_TEX_WRAP -0x42A4 SU_POLY_OFFSET_FRONT_SCALE -0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -0x42AC SU_POLY_OFFSET_BACK_SCALE -0x42B0 SU_POLY_OFFSET_BACK_OFFSET -0x42B4 SU_POLY_OFFSET_ENABLE -0x42B8 SU_CULL_MODE -0x42C0 SU_DEPTH_SCALE -0x42C4 SU_DEPTH_OFFSET -0x42C8 SU_REG_DEST -0x4300 RS_COUNT -0x4304 RS_INST_COUNT -0x4310 RS_IP_0 -0x4314 RS_IP_1 -0x4318 RS_IP_2 -0x431C RS_IP_3 -0x4320 RS_IP_4 -0x4324 RS_IP_5 -0x4328 RS_IP_6 -0x432C RS_IP_7 -0x4330 RS_INST_0 -0x4334 RS_INST_1 -0x4338 RS_INST_2 -0x433C RS_INST_3 -0x4340 RS_INST_4 -0x4344 RS_INST_5 -0x4348 RS_INST_6 -0x434C RS_INST_7 -0x4350 RS_INST_8 -0x4354 RS_INST_9 -0x4358 RS_INST_10 -0x435C RS_INST_11 -0x4360 RS_INST_12 -0x4364 RS_INST_13 -0x4368 RS_INST_14 -0x436C RS_INST_15 -0x43A8 SC_EDGERULE -0x43B0 SC_CLIP_0_A -0x43B4 SC_CLIP_0_B -0x43B8 SC_CLIP_1_A -0x43BC SC_CLIP_1_B -0x43C0 SC_CLIP_2_A -0x43C4 SC_CLIP_2_B -0x43C8 SC_CLIP_3_A -0x43CC SC_CLIP_3_B -0x43D0 SC_CLIP_RULE -0x43E0 SC_SCISSOR0 -0x43E8 SC_SCREENDOOR -0x4440 TX_FILTER1_0 -0x4444 TX_FILTER1_1 -0x4448 TX_FILTER1_2 -0x444C TX_FILTER1_3 -0x4450 TX_FILTER1_4 -0x4454 TX_FILTER1_5 -0x4458 TX_FILTER1_6 -0x445C TX_FILTER1_7 -0x4460 TX_FILTER1_8 -0x4464 TX_FILTER1_9 -0x4468 TX_FILTER1_10 -0x446C TX_FILTER1_11 -0x4470 TX_FILTER1_12 -0x4474 TX_FILTER1_13 -0x4478 TX_FILTER1_14 -0x447C TX_FILTER1_15 -0x4580 TX_CHROMA_KEY_0 -0x4584 TX_CHROMA_KEY_1 -0x4588 TX_CHROMA_KEY_2 -0x458C TX_CHROMA_KEY_3 -0x4590 TX_CHROMA_KEY_4 -0x4594 TX_CHROMA_KEY_5 -0x4598 TX_CHROMA_KEY_6 -0x459C TX_CHROMA_KEY_7 -0x45A0 TX_CHROMA_KEY_8 -0x45A4 TX_CHROMA_KEY_9 -0x45A8 TX_CHROMA_KEY_10 -0x45AC TX_CHROMA_KEY_11 -0x45B0 TX_CHROMA_KEY_12 -0x45B4 TX_CHROMA_KEY_13 -0x45B8 TX_CHROMA_KEY_14 -0x45BC TX_CHROMA_KEY_15 -0x45C0 TX_BORDER_COLOR_0 -0x45C4 TX_BORDER_COLOR_1 -0x45C8 TX_BORDER_COLOR_2 -0x45CC TX_BORDER_COLOR_3 -0x45D0 TX_BORDER_COLOR_4 -0x45D4 TX_BORDER_COLOR_5 -0x45D8 TX_BORDER_COLOR_6 -0x45DC TX_BORDER_COLOR_7 -0x45E0 TX_BORDER_COLOR_8 -0x45E4 TX_BORDER_COLOR_9 -0x45E8 TX_BORDER_COLOR_10 -0x45EC TX_BORDER_COLOR_11 -0x45F0 TX_BORDER_COLOR_12 -0x45F4 TX_BORDER_COLOR_13 -0x45F8 TX_BORDER_COLOR_14 -0x45FC TX_BORDER_COLOR_15 -0x4600 US_CONFIG -0x4604 US_PIXSIZE -0x4608 US_CODE_OFFSET -0x460C US_RESET -0x4610 US_CODE_ADDR_0 -0x4614 US_CODE_ADDR_1 -0x4618 US_CODE_ADDR_2 -0x461C US_CODE_ADDR_3 -0x4620 US_TEX_INST_0 -0x4624 US_TEX_INST_1 -0x4628 US_TEX_INST_2 -0x462C US_TEX_INST_3 -0x4630 US_TEX_INST_4 -0x4634 US_TEX_INST_5 -0x4638 US_TEX_INST_6 -0x463C US_TEX_INST_7 -0x4640 US_TEX_INST_8 -0x4644 US_TEX_INST_9 -0x4648 US_TEX_INST_10 -0x464C US_TEX_INST_11 -0x4650 US_TEX_INST_12 -0x4654 US_TEX_INST_13 -0x4658 US_TEX_INST_14 -0x465C US_TEX_INST_15 -0x4660 US_TEX_INST_16 -0x4664 US_TEX_INST_17 -0x4668 US_TEX_INST_18 -0x466C US_TEX_INST_19 -0x4670 US_TEX_INST_20 -0x4674 US_TEX_INST_21 -0x4678 US_TEX_INST_22 -0x467C US_TEX_INST_23 -0x4680 US_TEX_INST_24 -0x4684 US_TEX_INST_25 -0x4688 US_TEX_INST_26 -0x468C US_TEX_INST_27 -0x4690 US_TEX_INST_28 -0x4694 US_TEX_INST_29 -0x4698 US_TEX_INST_30 -0x469C US_TEX_INST_31 -0x46A4 US_OUT_FMT_0 -0x46A8 US_OUT_FMT_1 -0x46AC US_OUT_FMT_2 -0x46B0 US_OUT_FMT_3 -0x46B4 US_W_FMT -0x46B8 US_CODE_BANK -0x46BC US_CODE_EXT -0x46C0 US_ALU_RGB_ADDR_0 -0x46C4 US_ALU_RGB_ADDR_1 -0x46C8 US_ALU_RGB_ADDR_2 -0x46CC US_ALU_RGB_ADDR_3 -0x46D0 US_ALU_RGB_ADDR_4 -0x46D4 US_ALU_RGB_ADDR_5 -0x46D8 US_ALU_RGB_ADDR_6 -0x46DC US_ALU_RGB_ADDR_7 -0x46E0 US_ALU_RGB_ADDR_8 -0x46E4 US_ALU_RGB_ADDR_9 -0x46E8 US_ALU_RGB_ADDR_10 -0x46EC US_ALU_RGB_ADDR_11 -0x46F0 US_ALU_RGB_ADDR_12 -0x46F4 US_ALU_RGB_ADDR_13 -0x46F8 US_ALU_RGB_ADDR_14 -0x46FC US_ALU_RGB_ADDR_15 -0x4700 US_ALU_RGB_ADDR_16 -0x4704 US_ALU_RGB_ADDR_17 -0x4708 US_ALU_RGB_ADDR_18 -0x470C US_ALU_RGB_ADDR_19 -0x4710 US_ALU_RGB_ADDR_20 -0x4714 US_ALU_RGB_ADDR_21 -0x4718 US_ALU_RGB_ADDR_22 -0x471C US_ALU_RGB_ADDR_23 -0x4720 US_ALU_RGB_ADDR_24 -0x4724 US_ALU_RGB_ADDR_25 -0x4728 US_ALU_RGB_ADDR_26 -0x472C US_ALU_RGB_ADDR_27 -0x4730 US_ALU_RGB_ADDR_28 -0x4734 US_ALU_RGB_ADDR_29 -0x4738 US_ALU_RGB_ADDR_30 -0x473C US_ALU_RGB_ADDR_31 -0x4740 US_ALU_RGB_ADDR_32 -0x4744 US_ALU_RGB_ADDR_33 -0x4748 US_ALU_RGB_ADDR_34 -0x474C US_ALU_RGB_ADDR_35 -0x4750 US_ALU_RGB_ADDR_36 -0x4754 US_ALU_RGB_ADDR_37 -0x4758 US_ALU_RGB_ADDR_38 -0x475C US_ALU_RGB_ADDR_39 -0x4760 US_ALU_RGB_ADDR_40 -0x4764 US_ALU_RGB_ADDR_41 -0x4768 US_ALU_RGB_ADDR_42 -0x476C US_ALU_RGB_ADDR_43 -0x4770 US_ALU_RGB_ADDR_44 -0x4774 US_ALU_RGB_ADDR_45 -0x4778 US_ALU_RGB_ADDR_46 -0x477C US_ALU_RGB_ADDR_47 -0x4780 US_ALU_RGB_ADDR_48 -0x4784 US_ALU_RGB_ADDR_49 -0x4788 US_ALU_RGB_ADDR_50 -0x478C US_ALU_RGB_ADDR_51 -0x4790 US_ALU_RGB_ADDR_52 -0x4794 US_ALU_RGB_ADDR_53 -0x4798 US_ALU_RGB_ADDR_54 -0x479C US_ALU_RGB_ADDR_55 -0x47A0 US_ALU_RGB_ADDR_56 -0x47A4 US_ALU_RGB_ADDR_57 -0x47A8 US_ALU_RGB_ADDR_58 -0x47AC US_ALU_RGB_ADDR_59 -0x47B0 US_ALU_RGB_ADDR_60 -0x47B4 US_ALU_RGB_ADDR_61 -0x47B8 US_ALU_RGB_ADDR_62 -0x47BC US_ALU_RGB_ADDR_63 -0x47C0 US_ALU_ALPHA_ADDR_0 -0x47C4 US_ALU_ALPHA_ADDR_1 -0x47C8 US_ALU_ALPHA_ADDR_2 -0x47CC US_ALU_ALPHA_ADDR_3 -0x47D0 US_ALU_ALPHA_ADDR_4 -0x47D4 US_ALU_ALPHA_ADDR_5 -0x47D8 US_ALU_ALPHA_ADDR_6 -0x47DC US_ALU_ALPHA_ADDR_7 -0x47E0 US_ALU_ALPHA_ADDR_8 -0x47E4 US_ALU_ALPHA_ADDR_9 -0x47E8 US_ALU_ALPHA_ADDR_10 -0x47EC US_ALU_ALPHA_ADDR_11 -0x47F0 US_ALU_ALPHA_ADDR_12 -0x47F4 US_ALU_ALPHA_ADDR_13 -0x47F8 US_ALU_ALPHA_ADDR_14 -0x47FC US_ALU_ALPHA_ADDR_15 -0x4800 US_ALU_ALPHA_ADDR_16 -0x4804 US_ALU_ALPHA_ADDR_17 -0x4808 US_ALU_ALPHA_ADDR_18 -0x480C US_ALU_ALPHA_ADDR_19 -0x4810 US_ALU_ALPHA_ADDR_20 -0x4814 US_ALU_ALPHA_ADDR_21 -0x4818 US_ALU_ALPHA_ADDR_22 -0x481C US_ALU_ALPHA_ADDR_23 -0x4820 US_ALU_ALPHA_ADDR_24 -0x4824 US_ALU_ALPHA_ADDR_25 -0x4828 US_ALU_ALPHA_ADDR_26 -0x482C US_ALU_ALPHA_ADDR_27 -0x4830 US_ALU_ALPHA_ADDR_28 -0x4834 US_ALU_ALPHA_ADDR_29 -0x4838 US_ALU_ALPHA_ADDR_30 -0x483C US_ALU_ALPHA_ADDR_31 -0x4840 US_ALU_ALPHA_ADDR_32 -0x4844 US_ALU_ALPHA_ADDR_33 -0x4848 US_ALU_ALPHA_ADDR_34 -0x484C US_ALU_ALPHA_ADDR_35 -0x4850 US_ALU_ALPHA_ADDR_36 -0x4854 US_ALU_ALPHA_ADDR_37 -0x4858 US_ALU_ALPHA_ADDR_38 -0x485C US_ALU_ALPHA_ADDR_39 -0x4860 US_ALU_ALPHA_ADDR_40 -0x4864 US_ALU_ALPHA_ADDR_41 -0x4868 US_ALU_ALPHA_ADDR_42 -0x486C US_ALU_ALPHA_ADDR_43 -0x4870 US_ALU_ALPHA_ADDR_44 -0x4874 US_ALU_ALPHA_ADDR_45 -0x4878 US_ALU_ALPHA_ADDR_46 -0x487C US_ALU_ALPHA_ADDR_47 -0x4880 US_ALU_ALPHA_ADDR_48 -0x4884 US_ALU_ALPHA_ADDR_49 -0x4888 US_ALU_ALPHA_ADDR_50 -0x488C US_ALU_ALPHA_ADDR_51 -0x4890 US_ALU_ALPHA_ADDR_52 -0x4894 US_ALU_ALPHA_ADDR_53 -0x4898 US_ALU_ALPHA_ADDR_54 -0x489C US_ALU_ALPHA_ADDR_55 -0x48A0 US_ALU_ALPHA_ADDR_56 -0x48A4 US_ALU_ALPHA_ADDR_57 -0x48A8 US_ALU_ALPHA_ADDR_58 -0x48AC US_ALU_ALPHA_ADDR_59 -0x48B0 US_ALU_ALPHA_ADDR_60 -0x48B4 US_ALU_ALPHA_ADDR_61 -0x48B8 US_ALU_ALPHA_ADDR_62 -0x48BC US_ALU_ALPHA_ADDR_63 -0x48C0 US_ALU_RGB_INST_0 -0x48C4 US_ALU_RGB_INST_1 -0x48C8 US_ALU_RGB_INST_2 -0x48CC US_ALU_RGB_INST_3 -0x48D0 US_ALU_RGB_INST_4 -0x48D4 US_ALU_RGB_INST_5 -0x48D8 US_ALU_RGB_INST_6 -0x48DC US_ALU_RGB_INST_7 -0x48E0 US_ALU_RGB_INST_8 -0x48E4 US_ALU_RGB_INST_9 -0x48E8 US_ALU_RGB_INST_10 -0x48EC US_ALU_RGB_INST_11 -0x48F0 US_ALU_RGB_INST_12 -0x48F4 US_ALU_RGB_INST_13 -0x48F8 US_ALU_RGB_INST_14 -0x48FC US_ALU_RGB_INST_15 -0x4900 US_ALU_RGB_INST_16 -0x4904 US_ALU_RGB_INST_17 -0x4908 US_ALU_RGB_INST_18 -0x490C US_ALU_RGB_INST_19 -0x4910 US_ALU_RGB_INST_20 -0x4914 US_ALU_RGB_INST_21 -0x4918 US_ALU_RGB_INST_22 -0x491C US_ALU_RGB_INST_23 -0x4920 US_ALU_RGB_INST_24 -0x4924 US_ALU_RGB_INST_25 -0x4928 US_ALU_RGB_INST_26 -0x492C US_ALU_RGB_INST_27 -0x4930 US_ALU_RGB_INST_28 -0x4934 US_ALU_RGB_INST_29 -0x4938 US_ALU_RGB_INST_30 -0x493C US_ALU_RGB_INST_31 -0x4940 US_ALU_RGB_INST_32 -0x4944 US_ALU_RGB_INST_33 -0x4948 US_ALU_RGB_INST_34 -0x494C US_ALU_RGB_INST_35 -0x4950 US_ALU_RGB_INST_36 -0x4954 US_ALU_RGB_INST_37 -0x4958 US_ALU_RGB_INST_38 -0x495C US_ALU_RGB_INST_39 -0x4960 US_ALU_RGB_INST_40 -0x4964 US_ALU_RGB_INST_41 -0x4968 US_ALU_RGB_INST_42 -0x496C US_ALU_RGB_INST_43 -0x4970 US_ALU_RGB_INST_44 -0x4974 US_ALU_RGB_INST_45 -0x4978 US_ALU_RGB_INST_46 -0x497C US_ALU_RGB_INST_47 -0x4980 US_ALU_RGB_INST_48 -0x4984 US_ALU_RGB_INST_49 -0x4988 US_ALU_RGB_INST_50 -0x498C US_ALU_RGB_INST_51 -0x4990 US_ALU_RGB_INST_52 -0x4994 US_ALU_RGB_INST_53 -0x4998 US_ALU_RGB_INST_54 -0x499C US_ALU_RGB_INST_55 -0x49A0 US_ALU_RGB_INST_56 -0x49A4 US_ALU_RGB_INST_57 -0x49A8 US_ALU_RGB_INST_58 -0x49AC US_ALU_RGB_INST_59 -0x49B0 US_ALU_RGB_INST_60 -0x49B4 US_ALU_RGB_INST_61 -0x49B8 US_ALU_RGB_INST_62 -0x49BC US_ALU_RGB_INST_63 -0x49C0 US_ALU_ALPHA_INST_0 -0x49C4 US_ALU_ALPHA_INST_1 -0x49C8 US_ALU_ALPHA_INST_2 -0x49CC US_ALU_ALPHA_INST_3 -0x49D0 US_ALU_ALPHA_INST_4 -0x49D4 US_ALU_ALPHA_INST_5 -0x49D8 US_ALU_ALPHA_INST_6 -0x49DC US_ALU_ALPHA_INST_7 -0x49E0 US_ALU_ALPHA_INST_8 -0x49E4 US_ALU_ALPHA_INST_9 -0x49E8 US_ALU_ALPHA_INST_10 -0x49EC US_ALU_ALPHA_INST_11 -0x49F0 US_ALU_ALPHA_INST_12 -0x49F4 US_ALU_ALPHA_INST_13 -0x49F8 US_ALU_ALPHA_INST_14 -0x49FC US_ALU_ALPHA_INST_15 -0x4A00 US_ALU_ALPHA_INST_16 -0x4A04 US_ALU_ALPHA_INST_17 -0x4A08 US_ALU_ALPHA_INST_18 -0x4A0C US_ALU_ALPHA_INST_19 -0x4A10 US_ALU_ALPHA_INST_20 -0x4A14 US_ALU_ALPHA_INST_21 -0x4A18 US_ALU_ALPHA_INST_22 -0x4A1C US_ALU_ALPHA_INST_23 -0x4A20 US_ALU_ALPHA_INST_24 -0x4A24 US_ALU_ALPHA_INST_25 -0x4A28 US_ALU_ALPHA_INST_26 -0x4A2C US_ALU_ALPHA_INST_27 -0x4A30 US_ALU_ALPHA_INST_28 -0x4A34 US_ALU_ALPHA_INST_29 -0x4A38 US_ALU_ALPHA_INST_30 -0x4A3C US_ALU_ALPHA_INST_31 -0x4A40 US_ALU_ALPHA_INST_32 -0x4A44 US_ALU_ALPHA_INST_33 -0x4A48 US_ALU_ALPHA_INST_34 -0x4A4C US_ALU_ALPHA_INST_35 -0x4A50 US_ALU_ALPHA_INST_36 -0x4A54 US_ALU_ALPHA_INST_37 -0x4A58 US_ALU_ALPHA_INST_38 -0x4A5C US_ALU_ALPHA_INST_39 -0x4A60 US_ALU_ALPHA_INST_40 -0x4A64 US_ALU_ALPHA_INST_41 -0x4A68 US_ALU_ALPHA_INST_42 -0x4A6C US_ALU_ALPHA_INST_43 -0x4A70 US_ALU_ALPHA_INST_44 -0x4A74 US_ALU_ALPHA_INST_45 -0x4A78 US_ALU_ALPHA_INST_46 -0x4A7C US_ALU_ALPHA_INST_47 -0x4A80 US_ALU_ALPHA_INST_48 -0x4A84 US_ALU_ALPHA_INST_49 -0x4A88 US_ALU_ALPHA_INST_50 -0x4A8C US_ALU_ALPHA_INST_51 -0x4A90 US_ALU_ALPHA_INST_52 -0x4A94 US_ALU_ALPHA_INST_53 -0x4A98 US_ALU_ALPHA_INST_54 -0x4A9C US_ALU_ALPHA_INST_55 -0x4AA0 US_ALU_ALPHA_INST_56 -0x4AA4 US_ALU_ALPHA_INST_57 -0x4AA8 US_ALU_ALPHA_INST_58 -0x4AAC US_ALU_ALPHA_INST_59 -0x4AB0 US_ALU_ALPHA_INST_60 -0x4AB4 US_ALU_ALPHA_INST_61 -0x4AB8 US_ALU_ALPHA_INST_62 -0x4ABC US_ALU_ALPHA_INST_63 -0x4AC0 US_ALU_EXT_ADDR_0 -0x4AC4 US_ALU_EXT_ADDR_1 -0x4AC8 US_ALU_EXT_ADDR_2 -0x4ACC US_ALU_EXT_ADDR_3 -0x4AD0 US_ALU_EXT_ADDR_4 -0x4AD4 US_ALU_EXT_ADDR_5 -0x4AD8 US_ALU_EXT_ADDR_6 -0x4ADC US_ALU_EXT_ADDR_7 -0x4AE0 US_ALU_EXT_ADDR_8 -0x4AE4 US_ALU_EXT_ADDR_9 -0x4AE8 US_ALU_EXT_ADDR_10 -0x4AEC US_ALU_EXT_ADDR_11 -0x4AF0 US_ALU_EXT_ADDR_12 -0x4AF4 US_ALU_EXT_ADDR_13 -0x4AF8 US_ALU_EXT_ADDR_14 -0x4AFC US_ALU_EXT_ADDR_15 -0x4B00 US_ALU_EXT_ADDR_16 -0x4B04 US_ALU_EXT_ADDR_17 -0x4B08 US_ALU_EXT_ADDR_18 -0x4B0C US_ALU_EXT_ADDR_19 -0x4B10 US_ALU_EXT_ADDR_20 -0x4B14 US_ALU_EXT_ADDR_21 -0x4B18 US_ALU_EXT_ADDR_22 -0x4B1C US_ALU_EXT_ADDR_23 -0x4B20 US_ALU_EXT_ADDR_24 -0x4B24 US_ALU_EXT_ADDR_25 -0x4B28 US_ALU_EXT_ADDR_26 -0x4B2C US_ALU_EXT_ADDR_27 -0x4B30 US_ALU_EXT_ADDR_28 -0x4B34 US_ALU_EXT_ADDR_29 -0x4B38 US_ALU_EXT_ADDR_30 -0x4B3C US_ALU_EXT_ADDR_31 -0x4B40 US_ALU_EXT_ADDR_32 -0x4B44 US_ALU_EXT_ADDR_33 -0x4B48 US_ALU_EXT_ADDR_34 -0x4B4C US_ALU_EXT_ADDR_35 -0x4B50 US_ALU_EXT_ADDR_36 -0x4B54 US_ALU_EXT_ADDR_37 -0x4B58 US_ALU_EXT_ADDR_38 -0x4B5C US_ALU_EXT_ADDR_39 -0x4B60 US_ALU_EXT_ADDR_40 -0x4B64 US_ALU_EXT_ADDR_41 -0x4B68 US_ALU_EXT_ADDR_42 -0x4B6C US_ALU_EXT_ADDR_43 -0x4B70 US_ALU_EXT_ADDR_44 -0x4B74 US_ALU_EXT_ADDR_45 -0x4B78 US_ALU_EXT_ADDR_46 -0x4B7C US_ALU_EXT_ADDR_47 -0x4B80 US_ALU_EXT_ADDR_48 -0x4B84 US_ALU_EXT_ADDR_49 -0x4B88 US_ALU_EXT_ADDR_50 -0x4B8C US_ALU_EXT_ADDR_51 -0x4B90 US_ALU_EXT_ADDR_52 -0x4B94 US_ALU_EXT_ADDR_53 -0x4B98 US_ALU_EXT_ADDR_54 -0x4B9C US_ALU_EXT_ADDR_55 -0x4BA0 US_ALU_EXT_ADDR_56 -0x4BA4 US_ALU_EXT_ADDR_57 -0x4BA8 US_ALU_EXT_ADDR_58 -0x4BAC US_ALU_EXT_ADDR_59 -0x4BB0 US_ALU_EXT_ADDR_60 -0x4BB4 US_ALU_EXT_ADDR_61 -0x4BB8 US_ALU_EXT_ADDR_62 -0x4BBC US_ALU_EXT_ADDR_63 -0x4BC0 FG_FOG_BLEND -0x4BC4 FG_FOG_FACTOR -0x4BC8 FG_FOG_COLOR_R -0x4BCC FG_FOG_COLOR_G -0x4BD0 FG_FOG_COLOR_B -0x4BD4 FG_ALPHA_FUNC -0x4BD8 FG_DEPTH_SRC -0x4C00 US_ALU_CONST_R_0 -0x4C04 US_ALU_CONST_G_0 -0x4C08 US_ALU_CONST_B_0 -0x4C0C US_ALU_CONST_A_0 -0x4C10 US_ALU_CONST_R_1 -0x4C14 US_ALU_CONST_G_1 -0x4C18 US_ALU_CONST_B_1 -0x4C1C US_ALU_CONST_A_1 -0x4C20 US_ALU_CONST_R_2 -0x4C24 US_ALU_CONST_G_2 -0x4C28 US_ALU_CONST_B_2 -0x4C2C US_ALU_CONST_A_2 -0x4C30 US_ALU_CONST_R_3 -0x4C34 US_ALU_CONST_G_3 -0x4C38 US_ALU_CONST_B_3 -0x4C3C US_ALU_CONST_A_3 -0x4C40 US_ALU_CONST_R_4 -0x4C44 US_ALU_CONST_G_4 -0x4C48 US_ALU_CONST_B_4 -0x4C4C US_ALU_CONST_A_4 -0x4C50 US_ALU_CONST_R_5 -0x4C54 US_ALU_CONST_G_5 -0x4C58 US_ALU_CONST_B_5 -0x4C5C US_ALU_CONST_A_5 -0x4C60 US_ALU_CONST_R_6 -0x4C64 US_ALU_CONST_G_6 -0x4C68 US_ALU_CONST_B_6 -0x4C6C US_ALU_CONST_A_6 -0x4C70 US_ALU_CONST_R_7 -0x4C74 US_ALU_CONST_G_7 -0x4C78 US_ALU_CONST_B_7 -0x4C7C US_ALU_CONST_A_7 -0x4C80 US_ALU_CONST_R_8 -0x4C84 US_ALU_CONST_G_8 -0x4C88 US_ALU_CONST_B_8 -0x4C8C US_ALU_CONST_A_8 -0x4C90 US_ALU_CONST_R_9 -0x4C94 US_ALU_CONST_G_9 -0x4C98 US_ALU_CONST_B_9 -0x4C9C US_ALU_CONST_A_9 -0x4CA0 US_ALU_CONST_R_10 -0x4CA4 US_ALU_CONST_G_10 -0x4CA8 US_ALU_CONST_B_10 -0x4CAC US_ALU_CONST_A_10 -0x4CB0 US_ALU_CONST_R_11 -0x4CB4 US_ALU_CONST_G_11 -0x4CB8 US_ALU_CONST_B_11 -0x4CBC US_ALU_CONST_A_11 -0x4CC0 US_ALU_CONST_R_12 -0x4CC4 US_ALU_CONST_G_12 -0x4CC8 US_ALU_CONST_B_12 -0x4CCC US_ALU_CONST_A_12 -0x4CD0 US_ALU_CONST_R_13 -0x4CD4 US_ALU_CONST_G_13 -0x4CD8 US_ALU_CONST_B_13 -0x4CDC US_ALU_CONST_A_13 -0x4CE0 US_ALU_CONST_R_14 -0x4CE4 US_ALU_CONST_G_14 -0x4CE8 US_ALU_CONST_B_14 -0x4CEC US_ALU_CONST_A_14 -0x4CF0 US_ALU_CONST_R_15 -0x4CF4 US_ALU_CONST_G_15 -0x4CF8 US_ALU_CONST_B_15 -0x4CFC US_ALU_CONST_A_15 -0x4D00 US_ALU_CONST_R_16 -0x4D04 US_ALU_CONST_G_16 -0x4D08 US_ALU_CONST_B_16 -0x4D0C US_ALU_CONST_A_16 -0x4D10 US_ALU_CONST_R_17 -0x4D14 US_ALU_CONST_G_17 -0x4D18 US_ALU_CONST_B_17 -0x4D1C US_ALU_CONST_A_17 -0x4D20 US_ALU_CONST_R_18 -0x4D24 US_ALU_CONST_G_18 -0x4D28 US_ALU_CONST_B_18 -0x4D2C US_ALU_CONST_A_18 -0x4D30 US_ALU_CONST_R_19 -0x4D34 US_ALU_CONST_G_19 -0x4D38 US_ALU_CONST_B_19 -0x4D3C US_ALU_CONST_A_19 -0x4D40 US_ALU_CONST_R_20 -0x4D44 US_ALU_CONST_G_20 -0x4D48 US_ALU_CONST_B_20 -0x4D4C US_ALU_CONST_A_20 -0x4D50 US_ALU_CONST_R_21 -0x4D54 US_ALU_CONST_G_21 -0x4D58 US_ALU_CONST_B_21 -0x4D5C US_ALU_CONST_A_21 -0x4D60 US_ALU_CONST_R_22 -0x4D64 US_ALU_CONST_G_22 -0x4D68 US_ALU_CONST_B_22 -0x4D6C US_ALU_CONST_A_22 -0x4D70 US_ALU_CONST_R_23 -0x4D74 US_ALU_CONST_G_23 -0x4D78 US_ALU_CONST_B_23 -0x4D7C US_ALU_CONST_A_23 -0x4D80 US_ALU_CONST_R_24 -0x4D84 US_ALU_CONST_G_24 -0x4D88 US_ALU_CONST_B_24 -0x4D8C US_ALU_CONST_A_24 -0x4D90 US_ALU_CONST_R_25 -0x4D94 US_ALU_CONST_G_25 -0x4D98 US_ALU_CONST_B_25 -0x4D9C US_ALU_CONST_A_25 -0x4DA0 US_ALU_CONST_R_26 -0x4DA4 US_ALU_CONST_G_26 -0x4DA8 US_ALU_CONST_B_26 -0x4DAC US_ALU_CONST_A_26 -0x4DB0 US_ALU_CONST_R_27 -0x4DB4 US_ALU_CONST_G_27 -0x4DB8 US_ALU_CONST_B_27 -0x4DBC US_ALU_CONST_A_27 -0x4DC0 US_ALU_CONST_R_28 -0x4DC4 US_ALU_CONST_G_28 -0x4DC8 US_ALU_CONST_B_28 -0x4DCC US_ALU_CONST_A_28 -0x4DD0 US_ALU_CONST_R_29 -0x4DD4 US_ALU_CONST_G_29 -0x4DD8 US_ALU_CONST_B_29 -0x4DDC US_ALU_CONST_A_29 -0x4DE0 US_ALU_CONST_R_30 -0x4DE4 US_ALU_CONST_G_30 -0x4DE8 US_ALU_CONST_B_30 -0x4DEC US_ALU_CONST_A_30 -0x4DF0 US_ALU_CONST_R_31 -0x4DF4 US_ALU_CONST_G_31 -0x4DF8 US_ALU_CONST_B_31 -0x4DFC US_ALU_CONST_A_31 -0x4E08 RB3D_ABLENDCNTL_R3 -0x4E10 RB3D_CONSTANT_COLOR -0x4E14 RB3D_COLOR_CLEAR_VALUE -0x4E18 RB3D_ROPCNTL_R3 -0x4E1C RB3D_CLRCMP_FLIPE_R3 -0x4E20 RB3D_CLRCMP_CLR_R3 -0x4E24 RB3D_CLRCMP_MSK_R3 -0x4E48 RB3D_DEBUG_CTL -0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -0x4E50 RB3D_DITHER_CTL -0x4E54 RB3D_CMASK_OFFSET0 -0x4E58 RB3D_CMASK_OFFSET1 -0x4E5C RB3D_CMASK_OFFSET2 -0x4E60 RB3D_CMASK_OFFSET3 -0x4E64 RB3D_CMASK_PITCH0 -0x4E68 RB3D_CMASK_PITCH1 -0x4E6C RB3D_CMASK_PITCH2 -0x4E70 RB3D_CMASK_PITCH3 -0x4E74 RB3D_CMASK_WRINDEX -0x4E78 RB3D_CMASK_DWORD -0x4E7C RB3D_CMASK_RDINDEX -0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -0x4F04 ZB_ZSTENCILCNTL -0x4F08 ZB_STENCILREFMASK -0x4F14 ZB_ZTOP -0x4F18 ZB_ZCACHE_CTLSTAT -0x4F28 ZB_DEPTHCLEARVALUE -0x4F58 ZB_ZPASS_DATA diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r600 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r600 deleted file mode 100644 index 5e659b03..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/r600 +++ /dev/null @@ -1,764 +0,0 @@ -r600 0x9400 -0x000287A0 R7xx_CB_SHADER_CONTROL -0x00028230 R7xx_PA_SC_EDGERULE -0x000286C8 R7xx_SPI_THREAD_GROUPING -0x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ -0x00008490 CP_STRMOUT_CNTL -0x000085F0 CP_COHER_CNTL -0x000085F4 CP_COHER_SIZE -0x000088C4 VGT_CACHE_INVALIDATION -0x00028A50 VGT_ENHANCE -0x000088CC VGT_ES_PER_GS -0x00028A2C VGT_GROUP_DECR -0x00028A28 VGT_GROUP_FIRST_DECR -0x00028A24 VGT_GROUP_PRIM_TYPE -0x00028A30 VGT_GROUP_VECT_0_CNTL -0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL -0x00028A34 VGT_GROUP_VECT_1_CNTL -0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL -0x00028A40 VGT_GS_MODE -0x00028A6C VGT_GS_OUT_PRIM_TYPE -0x000088C8 VGT_GS_PER_ES -0x000088E8 VGT_GS_PER_VS -0x000088D4 VGT_GS_VERTEX_REUSE -0x00028A14 VGT_HOS_CNTL -0x00028A18 VGT_HOS_MAX_TESS_LEVEL -0x00028A1C VGT_HOS_MIN_TESS_LEVEL -0x00028A20 VGT_HOS_REUSE_DEPTH -0x0000895C VGT_INDEX_TYPE -0x00028408 VGT_INDX_OFFSET -0x00028AA0 VGT_INSTANCE_STEP_RATE_0 -0x00028AA4 VGT_INSTANCE_STEP_RATE_1 -0x00028400 VGT_MAX_VTX_INDX -0x00028404 VGT_MIN_VTX_INDX -0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN -0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX -0x00008970 VGT_NUM_INDICES -0x00008974 VGT_NUM_INSTANCES -0x00028A10 VGT_OUTPUT_PATH_CNTL -0x00028A84 VGT_PRIMITIVEID_EN -0x00008958 VGT_PRIMITIVE_TYPE -0x00028AB4 VGT_REUSE_OFF -0x00028AB8 VGT_VTX_CNT_EN -0x000088B0 VGT_VTX_VECT_EJECT_REG -0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0 -0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1 -0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2 -0x00028B04 VGT_STRMOUT_VTX_STRIDE_3 -0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET -0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE -0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE -0x00028810 PA_CL_CLIP_CNTL -0x00008A14 PA_CL_ENHANCE -0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ -0x00028C18 PA_CL_GB_HORZ_DISC_ADJ -0x00028C0C PA_CL_GB_VERT_CLIP_ADJ -0x00028C10 PA_CL_GB_VERT_DISC_ADJ -0x00028820 PA_CL_NANINF_CNTL -0x00028E1C PA_CL_POINT_CULL_RAD -0x00028E18 PA_CL_POINT_SIZE -0x00028E10 PA_CL_POINT_X_RAD -0x00028E14 PA_CL_POINT_Y_RAD -0x00028E2C PA_CL_UCP_0_W -0x00028E3C PA_CL_UCP_1_W -0x00028E4C PA_CL_UCP_2_W -0x00028E5C PA_CL_UCP_3_W -0x00028E6C PA_CL_UCP_4_W -0x00028E7C PA_CL_UCP_5_W -0x00028E20 PA_CL_UCP_0_X -0x00028E30 PA_CL_UCP_1_X -0x00028E40 PA_CL_UCP_2_X -0x00028E50 PA_CL_UCP_3_X -0x00028E60 PA_CL_UCP_4_X -0x00028E70 PA_CL_UCP_5_X -0x00028E24 PA_CL_UCP_0_Y -0x00028E34 PA_CL_UCP_1_Y -0x00028E44 PA_CL_UCP_2_Y -0x00028E54 PA_CL_UCP_3_Y -0x00028E64 PA_CL_UCP_4_Y -0x00028E74 PA_CL_UCP_5_Y -0x00028E28 PA_CL_UCP_0_Z -0x00028E38 PA_CL_UCP_1_Z -0x00028E48 PA_CL_UCP_2_Z -0x00028E58 PA_CL_UCP_3_Z -0x00028E68 PA_CL_UCP_4_Z -0x00028E78 PA_CL_UCP_5_Z -0x00028440 PA_CL_VPORT_XOFFSET_0 -0x00028458 PA_CL_VPORT_XOFFSET_1 -0x00028470 PA_CL_VPORT_XOFFSET_2 -0x00028488 PA_CL_VPORT_XOFFSET_3 -0x000284A0 PA_CL_VPORT_XOFFSET_4 -0x000284B8 PA_CL_VPORT_XOFFSET_5 -0x000284D0 PA_CL_VPORT_XOFFSET_6 -0x000284E8 PA_CL_VPORT_XOFFSET_7 -0x00028500 PA_CL_VPORT_XOFFSET_8 -0x00028518 PA_CL_VPORT_XOFFSET_9 -0x00028530 PA_CL_VPORT_XOFFSET_10 -0x00028548 PA_CL_VPORT_XOFFSET_11 -0x00028560 PA_CL_VPORT_XOFFSET_12 -0x00028578 PA_CL_VPORT_XOFFSET_13 -0x00028590 PA_CL_VPORT_XOFFSET_14 -0x000285A8 PA_CL_VPORT_XOFFSET_15 -0x0002843C PA_CL_VPORT_XSCALE_0 -0x00028454 PA_CL_VPORT_XSCALE_1 -0x0002846C PA_CL_VPORT_XSCALE_2 -0x00028484 PA_CL_VPORT_XSCALE_3 -0x0002849C PA_CL_VPORT_XSCALE_4 -0x000284B4 PA_CL_VPORT_XSCALE_5 -0x000284CC PA_CL_VPORT_XSCALE_6 -0x000284E4 PA_CL_VPORT_XSCALE_7 -0x000284FC PA_CL_VPORT_XSCALE_8 -0x00028514 PA_CL_VPORT_XSCALE_9 -0x0002852C PA_CL_VPORT_XSCALE_10 -0x00028544 PA_CL_VPORT_XSCALE_11 -0x0002855C PA_CL_VPORT_XSCALE_12 -0x00028574 PA_CL_VPORT_XSCALE_13 -0x0002858C PA_CL_VPORT_XSCALE_14 -0x000285A4 PA_CL_VPORT_XSCALE_15 -0x00028448 PA_CL_VPORT_YOFFSET_0 -0x00028460 PA_CL_VPORT_YOFFSET_1 -0x00028478 PA_CL_VPORT_YOFFSET_2 -0x00028490 PA_CL_VPORT_YOFFSET_3 -0x000284A8 PA_CL_VPORT_YOFFSET_4 -0x000284C0 PA_CL_VPORT_YOFFSET_5 -0x000284D8 PA_CL_VPORT_YOFFSET_6 -0x000284F0 PA_CL_VPORT_YOFFSET_7 -0x00028508 PA_CL_VPORT_YOFFSET_8 -0x00028520 PA_CL_VPORT_YOFFSET_9 -0x00028538 PA_CL_VPORT_YOFFSET_10 -0x00028550 PA_CL_VPORT_YOFFSET_11 -0x00028568 PA_CL_VPORT_YOFFSET_12 -0x00028580 PA_CL_VPORT_YOFFSET_13 -0x00028598 PA_CL_VPORT_YOFFSET_14 -0x000285B0 PA_CL_VPORT_YOFFSET_15 -0x00028444 PA_CL_VPORT_YSCALE_0 -0x0002845C PA_CL_VPORT_YSCALE_1 -0x00028474 PA_CL_VPORT_YSCALE_2 -0x0002848C PA_CL_VPORT_YSCALE_3 -0x000284A4 PA_CL_VPORT_YSCALE_4 -0x000284BC PA_CL_VPORT_YSCALE_5 -0x000284D4 PA_CL_VPORT_YSCALE_6 -0x000284EC PA_CL_VPORT_YSCALE_7 -0x00028504 PA_CL_VPORT_YSCALE_8 -0x0002851C PA_CL_VPORT_YSCALE_9 -0x00028534 PA_CL_VPORT_YSCALE_10 -0x0002854C PA_CL_VPORT_YSCALE_11 -0x00028564 PA_CL_VPORT_YSCALE_12 -0x0002857C PA_CL_VPORT_YSCALE_13 -0x00028594 PA_CL_VPORT_YSCALE_14 -0x000285AC PA_CL_VPORT_YSCALE_15 -0x00028450 PA_CL_VPORT_ZOFFSET_0 -0x00028468 PA_CL_VPORT_ZOFFSET_1 -0x00028480 PA_CL_VPORT_ZOFFSET_2 -0x00028498 PA_CL_VPORT_ZOFFSET_3 -0x000284B0 PA_CL_VPORT_ZOFFSET_4 -0x000284C8 PA_CL_VPORT_ZOFFSET_5 -0x000284E0 PA_CL_VPORT_ZOFFSET_6 -0x000284F8 PA_CL_VPORT_ZOFFSET_7 -0x00028510 PA_CL_VPORT_ZOFFSET_8 -0x00028528 PA_CL_VPORT_ZOFFSET_9 -0x00028540 PA_CL_VPORT_ZOFFSET_10 -0x00028558 PA_CL_VPORT_ZOFFSET_11 -0x00028570 PA_CL_VPORT_ZOFFSET_12 -0x00028588 PA_CL_VPORT_ZOFFSET_13 -0x000285A0 PA_CL_VPORT_ZOFFSET_14 -0x000285B8 PA_CL_VPORT_ZOFFSET_15 -0x0002844C PA_CL_VPORT_ZSCALE_0 -0x00028464 PA_CL_VPORT_ZSCALE_1 -0x0002847C PA_CL_VPORT_ZSCALE_2 -0x00028494 PA_CL_VPORT_ZSCALE_3 -0x000284AC PA_CL_VPORT_ZSCALE_4 -0x000284C4 PA_CL_VPORT_ZSCALE_5 -0x000284DC PA_CL_VPORT_ZSCALE_6 -0x000284F4 PA_CL_VPORT_ZSCALE_7 -0x0002850C PA_CL_VPORT_ZSCALE_8 -0x00028524 PA_CL_VPORT_ZSCALE_9 -0x0002853C PA_CL_VPORT_ZSCALE_10 -0x00028554 PA_CL_VPORT_ZSCALE_11 -0x0002856C PA_CL_VPORT_ZSCALE_12 -0x00028584 PA_CL_VPORT_ZSCALE_13 -0x0002859C PA_CL_VPORT_ZSCALE_14 -0x000285B4 PA_CL_VPORT_ZSCALE_15 -0x0002881C PA_CL_VS_OUT_CNTL -0x00028818 PA_CL_VTE_CNTL -0x00028C48 PA_SC_AA_MASK -0x00008B40 PA_SC_AA_SAMPLE_LOCS_2S -0x00008B44 PA_SC_AA_SAMPLE_LOCS_4S -0x00008B48 PA_SC_AA_SAMPLE_LOCS_8S_WD0 -0x00008B4C PA_SC_AA_SAMPLE_LOCS_8S_WD1 -0x00028C20 PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX -0x00028C1C PA_SC_AA_SAMPLE_LOCS_MCTX -0x00028214 PA_SC_CLIPRECT_0_BR -0x0002821C PA_SC_CLIPRECT_1_BR -0x00028224 PA_SC_CLIPRECT_2_BR -0x0002822C PA_SC_CLIPRECT_3_BR -0x00028210 PA_SC_CLIPRECT_0_TL -0x00028218 PA_SC_CLIPRECT_1_TL -0x00028220 PA_SC_CLIPRECT_2_TL -0x00028228 PA_SC_CLIPRECT_3_TL -0x0002820C PA_SC_CLIPRECT_RULE -0x00008BF0 PA_SC_ENHANCE -0x00028244 PA_SC_GENERIC_SCISSOR_BR -0x00028240 PA_SC_GENERIC_SCISSOR_TL -0x00028C00 PA_SC_LINE_CNTL -0x00028A0C PA_SC_LINE_STIPPLE -0x00008B10 PA_SC_LINE_STIPPLE_STATE -0x00028A4C PA_SC_MODE_CNTL -0x00028A48 PA_SC_MPASS_PS_CNTL -0x00008B20 PA_SC_MULTI_CHIP_CNTL -0x00028034 PA_SC_SCREEN_SCISSOR_BR -0x00028030 PA_SC_SCREEN_SCISSOR_TL -0x00028254 PA_SC_VPORT_SCISSOR_0_BR -0x0002825C PA_SC_VPORT_SCISSOR_1_BR -0x00028264 PA_SC_VPORT_SCISSOR_2_BR -0x0002826C PA_SC_VPORT_SCISSOR_3_BR -0x00028274 PA_SC_VPORT_SCISSOR_4_BR -0x0002827C PA_SC_VPORT_SCISSOR_5_BR -0x00028284 PA_SC_VPORT_SCISSOR_6_BR -0x0002828C PA_SC_VPORT_SCISSOR_7_BR -0x00028294 PA_SC_VPORT_SCISSOR_8_BR -0x0002829C PA_SC_VPORT_SCISSOR_9_BR -0x000282A4 PA_SC_VPORT_SCISSOR_10_BR -0x000282AC PA_SC_VPORT_SCISSOR_11_BR -0x000282B4 PA_SC_VPORT_SCISSOR_12_BR -0x000282BC PA_SC_VPORT_SCISSOR_13_BR -0x000282C4 PA_SC_VPORT_SCISSOR_14_BR -0x000282CC PA_SC_VPORT_SCISSOR_15_BR -0x00028250 PA_SC_VPORT_SCISSOR_0_TL -0x00028258 PA_SC_VPORT_SCISSOR_1_TL -0x00028260 PA_SC_VPORT_SCISSOR_2_TL -0x00028268 PA_SC_VPORT_SCISSOR_3_TL -0x00028270 PA_SC_VPORT_SCISSOR_4_TL -0x00028278 PA_SC_VPORT_SCISSOR_5_TL -0x00028280 PA_SC_VPORT_SCISSOR_6_TL -0x00028288 PA_SC_VPORT_SCISSOR_7_TL -0x00028290 PA_SC_VPORT_SCISSOR_8_TL -0x00028298 PA_SC_VPORT_SCISSOR_9_TL -0x000282A0 PA_SC_VPORT_SCISSOR_10_TL -0x000282A8 PA_SC_VPORT_SCISSOR_11_TL -0x000282B0 PA_SC_VPORT_SCISSOR_12_TL -0x000282B8 PA_SC_VPORT_SCISSOR_13_TL -0x000282C0 PA_SC_VPORT_SCISSOR_14_TL -0x000282C8 PA_SC_VPORT_SCISSOR_15_TL -0x000282D4 PA_SC_VPORT_ZMAX_0 -0x000282DC PA_SC_VPORT_ZMAX_1 -0x000282E4 PA_SC_VPORT_ZMAX_2 -0x000282EC PA_SC_VPORT_ZMAX_3 -0x000282F4 PA_SC_VPORT_ZMAX_4 -0x000282FC PA_SC_VPORT_ZMAX_5 -0x00028304 PA_SC_VPORT_ZMAX_6 -0x0002830C PA_SC_VPORT_ZMAX_7 -0x00028314 PA_SC_VPORT_ZMAX_8 -0x0002831C PA_SC_VPORT_ZMAX_9 -0x00028324 PA_SC_VPORT_ZMAX_10 -0x0002832C PA_SC_VPORT_ZMAX_11 -0x00028334 PA_SC_VPORT_ZMAX_12 -0x0002833C PA_SC_VPORT_ZMAX_13 -0x00028344 PA_SC_VPORT_ZMAX_14 -0x0002834C PA_SC_VPORT_ZMAX_15 -0x000282D0 PA_SC_VPORT_ZMIN_0 -0x000282D8 PA_SC_VPORT_ZMIN_1 -0x000282E0 PA_SC_VPORT_ZMIN_2 -0x000282E8 PA_SC_VPORT_ZMIN_3 -0x000282F0 PA_SC_VPORT_ZMIN_4 -0x000282F8 PA_SC_VPORT_ZMIN_5 -0x00028300 PA_SC_VPORT_ZMIN_6 -0x00028308 PA_SC_VPORT_ZMIN_7 -0x00028310 PA_SC_VPORT_ZMIN_8 -0x00028318 PA_SC_VPORT_ZMIN_9 -0x00028320 PA_SC_VPORT_ZMIN_10 -0x00028328 PA_SC_VPORT_ZMIN_11 -0x00028330 PA_SC_VPORT_ZMIN_12 -0x00028338 PA_SC_VPORT_ZMIN_13 -0x00028340 PA_SC_VPORT_ZMIN_14 -0x00028348 PA_SC_VPORT_ZMIN_15 -0x00028200 PA_SC_WINDOW_OFFSET -0x00028208 PA_SC_WINDOW_SCISSOR_BR -0x00028204 PA_SC_WINDOW_SCISSOR_TL -0x00028A08 PA_SU_LINE_CNTL -0x00028A04 PA_SU_POINT_MINMAX -0x00028A00 PA_SU_POINT_SIZE -0x00028E0C PA_SU_POLY_OFFSET_BACK_OFFSET -0x00028E08 PA_SU_POLY_OFFSET_BACK_SCALE -0x00028DFC PA_SU_POLY_OFFSET_CLAMP -0x00028DF8 PA_SU_POLY_OFFSET_DB_FMT_CNTL -0x00028E04 PA_SU_POLY_OFFSET_FRONT_OFFSET -0x00028E00 PA_SU_POLY_OFFSET_FRONT_SCALE -0x00028814 PA_SU_SC_MODE_CNTL -0x00028C08 PA_SU_VTX_CNTL -0x00008C04 SQ_GPR_RESOURCE_MGMT_1 -0x00008C08 SQ_GPR_RESOURCE_MGMT_2 -0x00008C10 SQ_STACK_RESOURCE_MGMT_1 -0x00008C14 SQ_STACK_RESOURCE_MGMT_2 -0x00008C0C SQ_THREAD_RESOURCE_MGMT -0x00028380 SQ_VTX_SEMANTIC_0 -0x00028384 SQ_VTX_SEMANTIC_1 -0x00028388 SQ_VTX_SEMANTIC_2 -0x0002838C SQ_VTX_SEMANTIC_3 -0x00028390 SQ_VTX_SEMANTIC_4 -0x00028394 SQ_VTX_SEMANTIC_5 -0x00028398 SQ_VTX_SEMANTIC_6 -0x0002839C SQ_VTX_SEMANTIC_7 -0x000283A0 SQ_VTX_SEMANTIC_8 -0x000283A4 SQ_VTX_SEMANTIC_9 -0x000283A8 SQ_VTX_SEMANTIC_10 -0x000283AC SQ_VTX_SEMANTIC_11 -0x000283B0 SQ_VTX_SEMANTIC_12 -0x000283B4 SQ_VTX_SEMANTIC_13 -0x000283B8 SQ_VTX_SEMANTIC_14 -0x000283BC SQ_VTX_SEMANTIC_15 -0x000283C0 SQ_VTX_SEMANTIC_16 -0x000283C4 SQ_VTX_SEMANTIC_17 -0x000283C8 SQ_VTX_SEMANTIC_18 -0x000283CC SQ_VTX_SEMANTIC_19 -0x000283D0 SQ_VTX_SEMANTIC_20 -0x000283D4 SQ_VTX_SEMANTIC_21 -0x000283D8 SQ_VTX_SEMANTIC_22 -0x000283DC SQ_VTX_SEMANTIC_23 -0x000283E0 SQ_VTX_SEMANTIC_24 -0x000283E4 SQ_VTX_SEMANTIC_25 -0x000283E8 SQ_VTX_SEMANTIC_26 -0x000283EC SQ_VTX_SEMANTIC_27 -0x000283F0 SQ_VTX_SEMANTIC_28 -0x000283F4 SQ_VTX_SEMANTIC_29 -0x000283F8 SQ_VTX_SEMANTIC_30 -0x000283FC SQ_VTX_SEMANTIC_31 -0x000288E0 SQ_VTX_SEMANTIC_CLEAR -0x0003CFF4 SQ_VTX_START_INST_LOC -0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0 -0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1 -0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2 -0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3 -0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4 -0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5 -0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6 -0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7 -0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8 -0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9 -0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10 -0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11 -0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12 -0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13 -0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14 -0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15 -0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 -0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 -0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 -0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3 -0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4 -0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5 -0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6 -0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7 -0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8 -0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9 -0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10 -0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11 -0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12 -0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13 -0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14 -0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15 -0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0 -0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1 -0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2 -0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3 -0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4 -0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5 -0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6 -0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7 -0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8 -0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9 -0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10 -0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11 -0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12 -0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13 -0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14 -0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15 -0x000288D8 SQ_PGM_CF_OFFSET_ES -0x000288DC SQ_PGM_CF_OFFSET_FS -0x000288D4 SQ_PGM_CF_OFFSET_GS -0x000288CC SQ_PGM_CF_OFFSET_PS -0x000288D0 SQ_PGM_CF_OFFSET_VS -0x00028854 SQ_PGM_EXPORTS_PS -0x00028890 SQ_PGM_RESOURCES_ES -0x000288A4 SQ_PGM_RESOURCES_FS -0x0002887C SQ_PGM_RESOURCES_GS -0x00028850 SQ_PGM_RESOURCES_PS -0x00028868 SQ_PGM_RESOURCES_VS -0x00009100 SPI_CONFIG_CNTL -0x0000913C SPI_CONFIG_CNTL_1 -0x000286DC SPI_FOG_CNTL -0x000286E4 SPI_FOG_FUNC_BIAS -0x000286E0 SPI_FOG_FUNC_SCALE -0x000286D8 SPI_INPUT_Z -0x000286D4 SPI_INTERP_CONTROL_0 -0x00028644 SPI_PS_INPUT_CNTL_0 -0x00028648 SPI_PS_INPUT_CNTL_1 -0x0002864C SPI_PS_INPUT_CNTL_2 -0x00028650 SPI_PS_INPUT_CNTL_3 -0x00028654 SPI_PS_INPUT_CNTL_4 -0x00028658 SPI_PS_INPUT_CNTL_5 -0x0002865C SPI_PS_INPUT_CNTL_6 -0x00028660 SPI_PS_INPUT_CNTL_7 -0x00028664 SPI_PS_INPUT_CNTL_8 -0x00028668 SPI_PS_INPUT_CNTL_9 -0x0002866C SPI_PS_INPUT_CNTL_10 -0x00028670 SPI_PS_INPUT_CNTL_11 -0x00028674 SPI_PS_INPUT_CNTL_12 -0x00028678 SPI_PS_INPUT_CNTL_13 -0x0002867C SPI_PS_INPUT_CNTL_14 -0x00028680 SPI_PS_INPUT_CNTL_15 -0x00028684 SPI_PS_INPUT_CNTL_16 -0x00028688 SPI_PS_INPUT_CNTL_17 -0x0002868C SPI_PS_INPUT_CNTL_18 -0x00028690 SPI_PS_INPUT_CNTL_19 -0x00028694 SPI_PS_INPUT_CNTL_20 -0x00028698 SPI_PS_INPUT_CNTL_21 -0x0002869C SPI_PS_INPUT_CNTL_22 -0x000286A0 SPI_PS_INPUT_CNTL_23 -0x000286A4 SPI_PS_INPUT_CNTL_24 -0x000286A8 SPI_PS_INPUT_CNTL_25 -0x000286AC SPI_PS_INPUT_CNTL_26 -0x000286B0 SPI_PS_INPUT_CNTL_27 -0x000286B4 SPI_PS_INPUT_CNTL_28 -0x000286B8 SPI_PS_INPUT_CNTL_29 -0x000286BC SPI_PS_INPUT_CNTL_30 -0x000286C0 SPI_PS_INPUT_CNTL_31 -0x000286CC SPI_PS_IN_CONTROL_0 -0x000286D0 SPI_PS_IN_CONTROL_1 -0x000286C4 SPI_VS_OUT_CONFIG -0x00028614 SPI_VS_OUT_ID_0 -0x00028618 SPI_VS_OUT_ID_1 -0x0002861C SPI_VS_OUT_ID_2 -0x00028620 SPI_VS_OUT_ID_3 -0x00028624 SPI_VS_OUT_ID_4 -0x00028628 SPI_VS_OUT_ID_5 -0x0002862C SPI_VS_OUT_ID_6 -0x00028630 SPI_VS_OUT_ID_7 -0x00028634 SPI_VS_OUT_ID_8 -0x00028638 SPI_VS_OUT_ID_9 -0x00028438 SX_ALPHA_REF -0x00028410 SX_ALPHA_TEST_CONTROL -0x00028354 SX_SURFACE_SYNC -0x00009014 SX_MEMORY_EXPORT_SIZE -0x00009604 TC_INVALIDATE -0x00009400 TD_FILTER4 -0x00009404 TD_FILTER4_1 -0x00009408 TD_FILTER4_2 -0x0000940C TD_FILTER4_3 -0x00009410 TD_FILTER4_4 -0x00009414 TD_FILTER4_5 -0x00009418 TD_FILTER4_6 -0x0000941C TD_FILTER4_7 -0x00009420 TD_FILTER4_8 -0x00009424 TD_FILTER4_9 -0x00009428 TD_FILTER4_10 -0x0000942C TD_FILTER4_11 -0x00009430 TD_FILTER4_12 -0x00009434 TD_FILTER4_13 -0x00009438 TD_FILTER4_14 -0x0000943C TD_FILTER4_15 -0x00009440 TD_FILTER4_16 -0x00009444 TD_FILTER4_17 -0x00009448 TD_FILTER4_18 -0x0000944C TD_FILTER4_19 -0x00009450 TD_FILTER4_20 -0x00009454 TD_FILTER4_21 -0x00009458 TD_FILTER4_22 -0x0000945C TD_FILTER4_23 -0x00009460 TD_FILTER4_24 -0x00009464 TD_FILTER4_25 -0x00009468 TD_FILTER4_26 -0x0000946C TD_FILTER4_27 -0x00009470 TD_FILTER4_28 -0x00009474 TD_FILTER4_29 -0x00009478 TD_FILTER4_30 -0x0000947C TD_FILTER4_31 -0x00009480 TD_FILTER4_32 -0x00009484 TD_FILTER4_33 -0x00009488 TD_FILTER4_34 -0x0000948C TD_FILTER4_35 -0x0000A80C TD_GS_SAMPLER0_BORDER_ALPHA -0x0000A81C TD_GS_SAMPLER1_BORDER_ALPHA -0x0000A82C TD_GS_SAMPLER2_BORDER_ALPHA -0x0000A83C TD_GS_SAMPLER3_BORDER_ALPHA -0x0000A84C TD_GS_SAMPLER4_BORDER_ALPHA -0x0000A85C TD_GS_SAMPLER5_BORDER_ALPHA -0x0000A86C TD_GS_SAMPLER6_BORDER_ALPHA -0x0000A87C TD_GS_SAMPLER7_BORDER_ALPHA -0x0000A88C TD_GS_SAMPLER8_BORDER_ALPHA -0x0000A89C TD_GS_SAMPLER9_BORDER_ALPHA -0x0000A8AC TD_GS_SAMPLER10_BORDER_ALPHA -0x0000A8BC TD_GS_SAMPLER11_BORDER_ALPHA -0x0000A8CC TD_GS_SAMPLER12_BORDER_ALPHA -0x0000A8DC TD_GS_SAMPLER13_BORDER_ALPHA -0x0000A8EC TD_GS_SAMPLER14_BORDER_ALPHA -0x0000A8FC TD_GS_SAMPLER15_BORDER_ALPHA -0x0000A90C TD_GS_SAMPLER16_BORDER_ALPHA -0x0000A91C TD_GS_SAMPLER17_BORDER_ALPHA -0x0000A808 TD_GS_SAMPLER0_BORDER_BLUE -0x0000A818 TD_GS_SAMPLER1_BORDER_BLUE -0x0000A828 TD_GS_SAMPLER2_BORDER_BLUE -0x0000A838 TD_GS_SAMPLER3_BORDER_BLUE -0x0000A848 TD_GS_SAMPLER4_BORDER_BLUE -0x0000A858 TD_GS_SAMPLER5_BORDER_BLUE -0x0000A868 TD_GS_SAMPLER6_BORDER_BLUE -0x0000A878 TD_GS_SAMPLER7_BORDER_BLUE -0x0000A888 TD_GS_SAMPLER8_BORDER_BLUE -0x0000A898 TD_GS_SAMPLER9_BORDER_BLUE -0x0000A8A8 TD_GS_SAMPLER10_BORDER_BLUE -0x0000A8B8 TD_GS_SAMPLER11_BORDER_BLUE -0x0000A8C8 TD_GS_SAMPLER12_BORDER_BLUE -0x0000A8D8 TD_GS_SAMPLER13_BORDER_BLUE -0x0000A8E8 TD_GS_SAMPLER14_BORDER_BLUE -0x0000A8F8 TD_GS_SAMPLER15_BORDER_BLUE -0x0000A908 TD_GS_SAMPLER16_BORDER_BLUE -0x0000A918 TD_GS_SAMPLER17_BORDER_BLUE -0x0000A804 TD_GS_SAMPLER0_BORDER_GREEN -0x0000A814 TD_GS_SAMPLER1_BORDER_GREEN -0x0000A824 TD_GS_SAMPLER2_BORDER_GREEN -0x0000A834 TD_GS_SAMPLER3_BORDER_GREEN -0x0000A844 TD_GS_SAMPLER4_BORDER_GREEN -0x0000A854 TD_GS_SAMPLER5_BORDER_GREEN -0x0000A864 TD_GS_SAMPLER6_BORDER_GREEN -0x0000A874 TD_GS_SAMPLER7_BORDER_GREEN -0x0000A884 TD_GS_SAMPLER8_BORDER_GREEN -0x0000A894 TD_GS_SAMPLER9_BORDER_GREEN -0x0000A8A4 TD_GS_SAMPLER10_BORDER_GREEN -0x0000A8B4 TD_GS_SAMPLER11_BORDER_GREEN -0x0000A8C4 TD_GS_SAMPLER12_BORDER_GREEN -0x0000A8D4 TD_GS_SAMPLER13_BORDER_GREEN -0x0000A8E4 TD_GS_SAMPLER14_BORDER_GREEN -0x0000A8F4 TD_GS_SAMPLER15_BORDER_GREEN -0x0000A904 TD_GS_SAMPLER16_BORDER_GREEN -0x0000A914 TD_GS_SAMPLER17_BORDER_GREEN -0x0000A800 TD_GS_SAMPLER0_BORDER_RED -0x0000A810 TD_GS_SAMPLER1_BORDER_RED -0x0000A820 TD_GS_SAMPLER2_BORDER_RED -0x0000A830 TD_GS_SAMPLER3_BORDER_RED -0x0000A840 TD_GS_SAMPLER4_BORDER_RED -0x0000A850 TD_GS_SAMPLER5_BORDER_RED -0x0000A860 TD_GS_SAMPLER6_BORDER_RED -0x0000A870 TD_GS_SAMPLER7_BORDER_RED -0x0000A880 TD_GS_SAMPLER8_BORDER_RED -0x0000A890 TD_GS_SAMPLER9_BORDER_RED -0x0000A8A0 TD_GS_SAMPLER10_BORDER_RED -0x0000A8B0 TD_GS_SAMPLER11_BORDER_RED -0x0000A8C0 TD_GS_SAMPLER12_BORDER_RED -0x0000A8D0 TD_GS_SAMPLER13_BORDER_RED -0x0000A8E0 TD_GS_SAMPLER14_BORDER_RED -0x0000A8F0 TD_GS_SAMPLER15_BORDER_RED -0x0000A900 TD_GS_SAMPLER16_BORDER_RED -0x0000A910 TD_GS_SAMPLER17_BORDER_RED -0x0000A40C TD_PS_SAMPLER0_BORDER_ALPHA -0x0000A41C TD_PS_SAMPLER1_BORDER_ALPHA -0x0000A42C TD_PS_SAMPLER2_BORDER_ALPHA -0x0000A43C TD_PS_SAMPLER3_BORDER_ALPHA -0x0000A44C TD_PS_SAMPLER4_BORDER_ALPHA -0x0000A45C TD_PS_SAMPLER5_BORDER_ALPHA -0x0000A46C TD_PS_SAMPLER6_BORDER_ALPHA -0x0000A47C TD_PS_SAMPLER7_BORDER_ALPHA -0x0000A48C TD_PS_SAMPLER8_BORDER_ALPHA -0x0000A49C TD_PS_SAMPLER9_BORDER_ALPHA -0x0000A4AC TD_PS_SAMPLER10_BORDER_ALPHA -0x0000A4BC TD_PS_SAMPLER11_BORDER_ALPHA -0x0000A4CC TD_PS_SAMPLER12_BORDER_ALPHA -0x0000A4DC TD_PS_SAMPLER13_BORDER_ALPHA -0x0000A4EC TD_PS_SAMPLER14_BORDER_ALPHA -0x0000A4FC TD_PS_SAMPLER15_BORDER_ALPHA -0x0000A50C TD_PS_SAMPLER16_BORDER_ALPHA -0x0000A51C TD_PS_SAMPLER17_BORDER_ALPHA -0x0000A408 TD_PS_SAMPLER0_BORDER_BLUE -0x0000A418 TD_PS_SAMPLER1_BORDER_BLUE -0x0000A428 TD_PS_SAMPLER2_BORDER_BLUE -0x0000A438 TD_PS_SAMPLER3_BORDER_BLUE -0x0000A448 TD_PS_SAMPLER4_BORDER_BLUE -0x0000A458 TD_PS_SAMPLER5_BORDER_BLUE -0x0000A468 TD_PS_SAMPLER6_BORDER_BLUE -0x0000A478 TD_PS_SAMPLER7_BORDER_BLUE -0x0000A488 TD_PS_SAMPLER8_BORDER_BLUE -0x0000A498 TD_PS_SAMPLER9_BORDER_BLUE -0x0000A4A8 TD_PS_SAMPLER10_BORDER_BLUE -0x0000A4B8 TD_PS_SAMPLER11_BORDER_BLUE -0x0000A4C8 TD_PS_SAMPLER12_BORDER_BLUE -0x0000A4D8 TD_PS_SAMPLER13_BORDER_BLUE -0x0000A4E8 TD_PS_SAMPLER14_BORDER_BLUE -0x0000A4F8 TD_PS_SAMPLER15_BORDER_BLUE -0x0000A508 TD_PS_SAMPLER16_BORDER_BLUE -0x0000A518 TD_PS_SAMPLER17_BORDER_BLUE -0x0000A404 TD_PS_SAMPLER0_BORDER_GREEN -0x0000A414 TD_PS_SAMPLER1_BORDER_GREEN -0x0000A424 TD_PS_SAMPLER2_BORDER_GREEN -0x0000A434 TD_PS_SAMPLER3_BORDER_GREEN -0x0000A444 TD_PS_SAMPLER4_BORDER_GREEN -0x0000A454 TD_PS_SAMPLER5_BORDER_GREEN -0x0000A464 TD_PS_SAMPLER6_BORDER_GREEN -0x0000A474 TD_PS_SAMPLER7_BORDER_GREEN -0x0000A484 TD_PS_SAMPLER8_BORDER_GREEN -0x0000A494 TD_PS_SAMPLER9_BORDER_GREEN -0x0000A4A4 TD_PS_SAMPLER10_BORDER_GREEN -0x0000A4B4 TD_PS_SAMPLER11_BORDER_GREEN -0x0000A4C4 TD_PS_SAMPLER12_BORDER_GREEN -0x0000A4D4 TD_PS_SAMPLER13_BORDER_GREEN -0x0000A4E4 TD_PS_SAMPLER14_BORDER_GREEN -0x0000A4F4 TD_PS_SAMPLER15_BORDER_GREEN -0x0000A504 TD_PS_SAMPLER16_BORDER_GREEN -0x0000A514 TD_PS_SAMPLER17_BORDER_GREEN -0x0000A400 TD_PS_SAMPLER0_BORDER_RED -0x0000A410 TD_PS_SAMPLER1_BORDER_RED -0x0000A420 TD_PS_SAMPLER2_BORDER_RED -0x0000A430 TD_PS_SAMPLER3_BORDER_RED -0x0000A440 TD_PS_SAMPLER4_BORDER_RED -0x0000A450 TD_PS_SAMPLER5_BORDER_RED -0x0000A460 TD_PS_SAMPLER6_BORDER_RED -0x0000A470 TD_PS_SAMPLER7_BORDER_RED -0x0000A480 TD_PS_SAMPLER8_BORDER_RED -0x0000A490 TD_PS_SAMPLER9_BORDER_RED -0x0000A4A0 TD_PS_SAMPLER10_BORDER_RED -0x0000A4B0 TD_PS_SAMPLER11_BORDER_RED -0x0000A4C0 TD_PS_SAMPLER12_BORDER_RED -0x0000A4D0 TD_PS_SAMPLER13_BORDER_RED -0x0000A4E0 TD_PS_SAMPLER14_BORDER_RED -0x0000A4F0 TD_PS_SAMPLER15_BORDER_RED -0x0000A500 TD_PS_SAMPLER16_BORDER_RED -0x0000A510 TD_PS_SAMPLER17_BORDER_RED -0x0000AA00 TD_PS_SAMPLER0_CLEARTYPE_KERNEL -0x0000AA04 TD_PS_SAMPLER1_CLEARTYPE_KERNEL -0x0000AA08 TD_PS_SAMPLER2_CLEARTYPE_KERNEL -0x0000AA0C TD_PS_SAMPLER3_CLEARTYPE_KERNEL -0x0000AA10 TD_PS_SAMPLER4_CLEARTYPE_KERNEL -0x0000AA14 TD_PS_SAMPLER5_CLEARTYPE_KERNEL -0x0000AA18 TD_PS_SAMPLER6_CLEARTYPE_KERNEL -0x0000AA1C TD_PS_SAMPLER7_CLEARTYPE_KERNEL -0x0000AA20 TD_PS_SAMPLER8_CLEARTYPE_KERNEL -0x0000AA24 TD_PS_SAMPLER9_CLEARTYPE_KERNEL -0x0000AA28 TD_PS_SAMPLER10_CLEARTYPE_KERNEL -0x0000AA2C TD_PS_SAMPLER11_CLEARTYPE_KERNEL -0x0000AA30 TD_PS_SAMPLER12_CLEARTYPE_KERNEL -0x0000AA34 TD_PS_SAMPLER13_CLEARTYPE_KERNEL -0x0000AA38 TD_PS_SAMPLER14_CLEARTYPE_KERNEL -0x0000AA3C TD_PS_SAMPLER15_CLEARTYPE_KERNEL -0x0000AA40 TD_PS_SAMPLER16_CLEARTYPE_KERNEL -0x0000AA44 TD_PS_SAMPLER17_CLEARTYPE_KERNEL -0x0000A60C TD_VS_SAMPLER0_BORDER_ALPHA -0x0000A61C TD_VS_SAMPLER1_BORDER_ALPHA -0x0000A62C TD_VS_SAMPLER2_BORDER_ALPHA -0x0000A63C TD_VS_SAMPLER3_BORDER_ALPHA -0x0000A64C TD_VS_SAMPLER4_BORDER_ALPHA -0x0000A65C TD_VS_SAMPLER5_BORDER_ALPHA -0x0000A66C TD_VS_SAMPLER6_BORDER_ALPHA -0x0000A67C TD_VS_SAMPLER7_BORDER_ALPHA -0x0000A68C TD_VS_SAMPLER8_BORDER_ALPHA -0x0000A69C TD_VS_SAMPLER9_BORDER_ALPHA -0x0000A6AC TD_VS_SAMPLER10_BORDER_ALPHA -0x0000A6BC TD_VS_SAMPLER11_BORDER_ALPHA -0x0000A6CC TD_VS_SAMPLER12_BORDER_ALPHA -0x0000A6DC TD_VS_SAMPLER13_BORDER_ALPHA -0x0000A6EC TD_VS_SAMPLER14_BORDER_ALPHA -0x0000A6FC TD_VS_SAMPLER15_BORDER_ALPHA -0x0000A70C TD_VS_SAMPLER16_BORDER_ALPHA -0x0000A71C TD_VS_SAMPLER17_BORDER_ALPHA -0x0000A608 TD_VS_SAMPLER0_BORDER_BLUE -0x0000A618 TD_VS_SAMPLER1_BORDER_BLUE -0x0000A628 TD_VS_SAMPLER2_BORDER_BLUE -0x0000A638 TD_VS_SAMPLER3_BORDER_BLUE -0x0000A648 TD_VS_SAMPLER4_BORDER_BLUE -0x0000A658 TD_VS_SAMPLER5_BORDER_BLUE -0x0000A668 TD_VS_SAMPLER6_BORDER_BLUE -0x0000A678 TD_VS_SAMPLER7_BORDER_BLUE -0x0000A688 TD_VS_SAMPLER8_BORDER_BLUE -0x0000A698 TD_VS_SAMPLER9_BORDER_BLUE -0x0000A6A8 TD_VS_SAMPLER10_BORDER_BLUE -0x0000A6B8 TD_VS_SAMPLER11_BORDER_BLUE -0x0000A6C8 TD_VS_SAMPLER12_BORDER_BLUE -0x0000A6D8 TD_VS_SAMPLER13_BORDER_BLUE -0x0000A6E8 TD_VS_SAMPLER14_BORDER_BLUE -0x0000A6F8 TD_VS_SAMPLER15_BORDER_BLUE -0x0000A708 TD_VS_SAMPLER16_BORDER_BLUE -0x0000A718 TD_VS_SAMPLER17_BORDER_BLUE -0x0000A604 TD_VS_SAMPLER0_BORDER_GREEN -0x0000A614 TD_VS_SAMPLER1_BORDER_GREEN -0x0000A624 TD_VS_SAMPLER2_BORDER_GREEN -0x0000A634 TD_VS_SAMPLER3_BORDER_GREEN -0x0000A644 TD_VS_SAMPLER4_BORDER_GREEN -0x0000A654 TD_VS_SAMPLER5_BORDER_GREEN -0x0000A664 TD_VS_SAMPLER6_BORDER_GREEN -0x0000A674 TD_VS_SAMPLER7_BORDER_GREEN -0x0000A684 TD_VS_SAMPLER8_BORDER_GREEN -0x0000A694 TD_VS_SAMPLER9_BORDER_GREEN -0x0000A6A4 TD_VS_SAMPLER10_BORDER_GREEN -0x0000A6B4 TD_VS_SAMPLER11_BORDER_GREEN -0x0000A6C4 TD_VS_SAMPLER12_BORDER_GREEN -0x0000A6D4 TD_VS_SAMPLER13_BORDER_GREEN -0x0000A6E4 TD_VS_SAMPLER14_BORDER_GREEN -0x0000A6F4 TD_VS_SAMPLER15_BORDER_GREEN -0x0000A704 TD_VS_SAMPLER16_BORDER_GREEN -0x0000A714 TD_VS_SAMPLER17_BORDER_GREEN -0x0000A600 TD_VS_SAMPLER0_BORDER_RED -0x0000A610 TD_VS_SAMPLER1_BORDER_RED -0x0000A620 TD_VS_SAMPLER2_BORDER_RED -0x0000A630 TD_VS_SAMPLER3_BORDER_RED -0x0000A640 TD_VS_SAMPLER4_BORDER_RED -0x0000A650 TD_VS_SAMPLER5_BORDER_RED -0x0000A660 TD_VS_SAMPLER6_BORDER_RED -0x0000A670 TD_VS_SAMPLER7_BORDER_RED -0x0000A680 TD_VS_SAMPLER8_BORDER_RED -0x0000A690 TD_VS_SAMPLER9_BORDER_RED -0x0000A6A0 TD_VS_SAMPLER10_BORDER_RED -0x0000A6B0 TD_VS_SAMPLER11_BORDER_RED -0x0000A6C0 TD_VS_SAMPLER12_BORDER_RED -0x0000A6D0 TD_VS_SAMPLER13_BORDER_RED -0x0000A6E0 TD_VS_SAMPLER14_BORDER_RED -0x0000A6F0 TD_VS_SAMPLER15_BORDER_RED -0x0000A700 TD_VS_SAMPLER16_BORDER_RED -0x0000A710 TD_VS_SAMPLER17_BORDER_RED -0x00009508 TA_CNTL_AUX -0x0002802C DB_DEPTH_CLEAR -0x00028D34 DB_PREFETCH_LIMIT -0x00028D30 DB_PRELOAD_CONTROL -0x00028D0C DB_RENDER_CONTROL -0x00028D10 DB_RENDER_OVERRIDE -0x0002880C DB_SHADER_CONTROL -0x00028D28 DB_SRESULTS_COMPARE_STATE0 -0x00028D2C DB_SRESULTS_COMPARE_STATE1 -0x00028430 DB_STENCILREFMASK -0x00028434 DB_STENCILREFMASK_BF -0x00028028 DB_STENCIL_CLEAR -0x00028780 CB_BLEND0_CONTROL -0x00028784 CB_BLEND1_CONTROL -0x00028788 CB_BLEND2_CONTROL -0x0002878C CB_BLEND3_CONTROL -0x00028790 CB_BLEND4_CONTROL -0x00028794 CB_BLEND5_CONTROL -0x00028798 CB_BLEND6_CONTROL -0x0002879C CB_BLEND7_CONTROL -0x00028804 CB_BLEND_CONTROL -0x00028420 CB_BLEND_ALPHA -0x0002841C CB_BLEND_BLUE -0x00028418 CB_BLEND_GREEN -0x00028414 CB_BLEND_RED -0x0002812C CB_CLEAR_ALPHA -0x00028128 CB_CLEAR_BLUE -0x00028124 CB_CLEAR_GREEN -0x00028120 CB_CLEAR_RED -0x00028C30 CB_CLRCMP_CONTROL -0x00028C38 CB_CLRCMP_DST -0x00028C3C CB_CLRCMP_MSK -0x00028C34 CB_CLRCMP_SRC -0x00028100 CB_COLOR0_MASK -0x00028104 CB_COLOR1_MASK -0x00028108 CB_COLOR2_MASK -0x0002810C CB_COLOR3_MASK -0x00028110 CB_COLOR4_MASK -0x00028114 CB_COLOR5_MASK -0x00028118 CB_COLOR6_MASK -0x0002811C CB_COLOR7_MASK -0x00028808 CB_COLOR_CONTROL -0x0002842C CB_FOG_BLUE -0x00028428 CB_FOG_GREEN -0x00028424 CB_FOG_RED -0x00008040 WAIT_UNTIL -0x00009714 VC_ENHANCE -0x00009830 DB_DEBUG -0x00009838 DB_WATERMARKS -0x00028D44 DB_ALPHA_TO_MASK -0x00009700 VC_CNTL diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rn50 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rn50 deleted file mode 100644 index 2687b630..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rn50 +++ /dev/null @@ -1,30 +0,0 @@ -rn50 0x3294 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rs600 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rs600 deleted file mode 100644 index d9f62866..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ /dev/null @@ -1,780 +0,0 @@ -rs600 0x6d40 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL -0x1D98 VAP_VPORT_XSCALE -0x1D9C VAP_VPORT_XOFFSET -0x1DA0 VAP_VPORT_YSCALE -0x1DA4 VAP_VPORT_YOFFSET -0x1DA8 VAP_VPORT_ZSCALE -0x1DAC VAP_VPORT_ZOFFSET -0x2080 VAP_CNTL -0x2090 VAP_OUT_VTX_FMT_0 -0x2094 VAP_OUT_VTX_FMT_1 -0x20B0 VAP_VTE_CNTL -0x2138 VAP_VF_MIN_VTX_INDX -0x2140 VAP_CNTL_STATUS -0x2150 VAP_PROG_STREAM_CNTL_0 -0x2154 VAP_PROG_STREAM_CNTL_1 -0x2158 VAP_PROG_STREAM_CNTL_2 -0x215C VAP_PROG_STREAM_CNTL_3 -0x2160 VAP_PROG_STREAM_CNTL_4 -0x2164 VAP_PROG_STREAM_CNTL_5 -0x2168 VAP_PROG_STREAM_CNTL_6 -0x216C VAP_PROG_STREAM_CNTL_7 -0x2180 VAP_VTX_STATE_CNTL -0x2184 VAP_VSM_VTX_ASSM -0x2188 VAP_VTX_STATE_IND_REG_0 -0x218C VAP_VTX_STATE_IND_REG_1 -0x2190 VAP_VTX_STATE_IND_REG_2 -0x2194 VAP_VTX_STATE_IND_REG_3 -0x2198 VAP_VTX_STATE_IND_REG_4 -0x219C VAP_VTX_STATE_IND_REG_5 -0x21A0 VAP_VTX_STATE_IND_REG_6 -0x21A4 VAP_VTX_STATE_IND_REG_7 -0x21A8 VAP_VTX_STATE_IND_REG_8 -0x21AC VAP_VTX_STATE_IND_REG_9 -0x21B0 VAP_VTX_STATE_IND_REG_10 -0x21B4 VAP_VTX_STATE_IND_REG_11 -0x21B8 VAP_VTX_STATE_IND_REG_12 -0x21BC VAP_VTX_STATE_IND_REG_13 -0x21C0 VAP_VTX_STATE_IND_REG_14 -0x21C4 VAP_VTX_STATE_IND_REG_15 -0x21DC VAP_PSC_SGN_NORM_CNTL -0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -0x2200 VAP_PVS_VECTOR_INDX_REG -0x2204 VAP_PVS_VECTOR_DATA_REG -0x2208 VAP_PVS_VECTOR_DATA_REG_128 -0x221C VAP_CLIP_CNTL -0x2220 VAP_GB_VERT_CLIP_ADJ -0x2224 VAP_GB_VERT_DISC_ADJ -0x2228 VAP_GB_HORZ_CLIP_ADJ -0x222C VAP_GB_HORZ_DISC_ADJ -0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -0x2284 VAP_PVS_STATE_FLUSH_REG -0x2288 VAP_PVS_VTX_TIMEOUT_REG -0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -0x22D0 VAP_PVS_CODE_CNTL_0 -0x22D4 VAP_PVS_CONST_CNTL -0x22D8 VAP_PVS_CODE_CNTL_1 -0x22DC VAP_PVS_FLOW_CNTL_OPC -0x342C RB2D_DSTCACHE_CTLSTAT -0x4000 GB_VAP_RASTER_VTX_FMT_0 -0x4004 GB_VAP_RASTER_VTX_FMT_1 -0x4008 GB_ENABLE -0x4010 GB_MSPOS0 -0x4014 GB_MSPOS1 -0x401C GB_SELECT -0x4020 GB_AA_CONFIG -0x4024 GB_FIFO_SIZE -0x4100 TX_INVALTAGS -0x4200 GA_POINT_S0 -0x4204 GA_POINT_T0 -0x4208 GA_POINT_S1 -0x420C GA_POINT_T1 -0x4214 GA_TRIANGLE_STIPPLE -0x421C GA_POINT_SIZE -0x4230 GA_POINT_MINMAX -0x4234 GA_LINE_CNTL -0x4238 GA_LINE_STIPPLE_CONFIG -0x4260 GA_LINE_STIPPLE_VALUE -0x4264 GA_LINE_S0 -0x4268 GA_LINE_S1 -0x4278 GA_COLOR_CONTROL -0x427C GA_SOLID_RG -0x4280 GA_SOLID_BA -0x4288 GA_POLY_MODE -0x428C GA_ROUND_MODE -0x4290 GA_OFFSET -0x4294 GA_FOG_SCALE -0x4298 GA_FOG_OFFSET -0x42A0 SU_TEX_WRAP -0x42A4 SU_POLY_OFFSET_FRONT_SCALE -0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -0x42AC SU_POLY_OFFSET_BACK_SCALE -0x42B0 SU_POLY_OFFSET_BACK_OFFSET -0x42B4 SU_POLY_OFFSET_ENABLE -0x42B8 SU_CULL_MODE -0x42C0 SU_DEPTH_SCALE -0x42C4 SU_DEPTH_OFFSET -0x42C8 SU_REG_DEST -0x4300 RS_COUNT -0x4304 RS_INST_COUNT -0x4310 RS_IP_0 -0x4314 RS_IP_1 -0x4318 RS_IP_2 -0x431C RS_IP_3 -0x4320 RS_IP_4 -0x4324 RS_IP_5 -0x4328 RS_IP_6 -0x432C RS_IP_7 -0x4330 RS_INST_0 -0x4334 RS_INST_1 -0x4338 RS_INST_2 -0x433C RS_INST_3 -0x4340 RS_INST_4 -0x4344 RS_INST_5 -0x4348 RS_INST_6 -0x434C RS_INST_7 -0x4350 RS_INST_8 -0x4354 RS_INST_9 -0x4358 RS_INST_10 -0x435C RS_INST_11 -0x4360 RS_INST_12 -0x4364 RS_INST_13 -0x4368 RS_INST_14 -0x436C RS_INST_15 -0x43A8 SC_EDGERULE -0x43B0 SC_CLIP_0_A -0x43B4 SC_CLIP_0_B -0x43B8 SC_CLIP_1_A -0x43BC SC_CLIP_1_B -0x43C0 SC_CLIP_2_A -0x43C4 SC_CLIP_2_B -0x43C8 SC_CLIP_3_A -0x43CC SC_CLIP_3_B -0x43D0 SC_CLIP_RULE -0x43E0 SC_SCISSOR0 -0x43E8 SC_SCREENDOOR -0x4440 TX_FILTER1_0 -0x4444 TX_FILTER1_1 -0x4448 TX_FILTER1_2 -0x444C TX_FILTER1_3 -0x4450 TX_FILTER1_4 -0x4454 TX_FILTER1_5 -0x4458 TX_FILTER1_6 -0x445C TX_FILTER1_7 -0x4460 TX_FILTER1_8 -0x4464 TX_FILTER1_9 -0x4468 TX_FILTER1_10 -0x446C TX_FILTER1_11 -0x4470 TX_FILTER1_12 -0x4474 TX_FILTER1_13 -0x4478 TX_FILTER1_14 -0x447C TX_FILTER1_15 -0x4580 TX_CHROMA_KEY_0 -0x4584 TX_CHROMA_KEY_1 -0x4588 TX_CHROMA_KEY_2 -0x458C TX_CHROMA_KEY_3 -0x4590 TX_CHROMA_KEY_4 -0x4594 TX_CHROMA_KEY_5 -0x4598 TX_CHROMA_KEY_6 -0x459C TX_CHROMA_KEY_7 -0x45A0 TX_CHROMA_KEY_8 -0x45A4 TX_CHROMA_KEY_9 -0x45A8 TX_CHROMA_KEY_10 -0x45AC TX_CHROMA_KEY_11 -0x45B0 TX_CHROMA_KEY_12 -0x45B4 TX_CHROMA_KEY_13 -0x45B8 TX_CHROMA_KEY_14 -0x45BC TX_CHROMA_KEY_15 -0x45C0 TX_BORDER_COLOR_0 -0x45C4 TX_BORDER_COLOR_1 -0x45C8 TX_BORDER_COLOR_2 -0x45CC TX_BORDER_COLOR_3 -0x45D0 TX_BORDER_COLOR_4 -0x45D4 TX_BORDER_COLOR_5 -0x45D8 TX_BORDER_COLOR_6 -0x45DC TX_BORDER_COLOR_7 -0x45E0 TX_BORDER_COLOR_8 -0x45E4 TX_BORDER_COLOR_9 -0x45E8 TX_BORDER_COLOR_10 -0x45EC TX_BORDER_COLOR_11 -0x45F0 TX_BORDER_COLOR_12 -0x45F4 TX_BORDER_COLOR_13 -0x45F8 TX_BORDER_COLOR_14 -0x45FC TX_BORDER_COLOR_15 -0x4600 US_CONFIG -0x4604 US_PIXSIZE -0x4608 US_CODE_OFFSET -0x460C US_RESET -0x4610 US_CODE_ADDR_0 -0x4614 US_CODE_ADDR_1 -0x4618 US_CODE_ADDR_2 -0x461C US_CODE_ADDR_3 -0x4620 US_TEX_INST_0 -0x4624 US_TEX_INST_1 -0x4628 US_TEX_INST_2 -0x462C US_TEX_INST_3 -0x4630 US_TEX_INST_4 -0x4634 US_TEX_INST_5 -0x4638 US_TEX_INST_6 -0x463C US_TEX_INST_7 -0x4640 US_TEX_INST_8 -0x4644 US_TEX_INST_9 -0x4648 US_TEX_INST_10 -0x464C US_TEX_INST_11 -0x4650 US_TEX_INST_12 -0x4654 US_TEX_INST_13 -0x4658 US_TEX_INST_14 -0x465C US_TEX_INST_15 -0x4660 US_TEX_INST_16 -0x4664 US_TEX_INST_17 -0x4668 US_TEX_INST_18 -0x466C US_TEX_INST_19 -0x4670 US_TEX_INST_20 -0x4674 US_TEX_INST_21 -0x4678 US_TEX_INST_22 -0x467C US_TEX_INST_23 -0x4680 US_TEX_INST_24 -0x4684 US_TEX_INST_25 -0x4688 US_TEX_INST_26 -0x468C US_TEX_INST_27 -0x4690 US_TEX_INST_28 -0x4694 US_TEX_INST_29 -0x4698 US_TEX_INST_30 -0x469C US_TEX_INST_31 -0x46A4 US_OUT_FMT_0 -0x46A8 US_OUT_FMT_1 -0x46AC US_OUT_FMT_2 -0x46B0 US_OUT_FMT_3 -0x46B4 US_W_FMT -0x46B8 US_CODE_BANK -0x46BC US_CODE_EXT -0x46C0 US_ALU_RGB_ADDR_0 -0x46C4 US_ALU_RGB_ADDR_1 -0x46C8 US_ALU_RGB_ADDR_2 -0x46CC US_ALU_RGB_ADDR_3 -0x46D0 US_ALU_RGB_ADDR_4 -0x46D4 US_ALU_RGB_ADDR_5 -0x46D8 US_ALU_RGB_ADDR_6 -0x46DC US_ALU_RGB_ADDR_7 -0x46E0 US_ALU_RGB_ADDR_8 -0x46E4 US_ALU_RGB_ADDR_9 -0x46E8 US_ALU_RGB_ADDR_10 -0x46EC US_ALU_RGB_ADDR_11 -0x46F0 US_ALU_RGB_ADDR_12 -0x46F4 US_ALU_RGB_ADDR_13 -0x46F8 US_ALU_RGB_ADDR_14 -0x46FC US_ALU_RGB_ADDR_15 -0x4700 US_ALU_RGB_ADDR_16 -0x4704 US_ALU_RGB_ADDR_17 -0x4708 US_ALU_RGB_ADDR_18 -0x470C US_ALU_RGB_ADDR_19 -0x4710 US_ALU_RGB_ADDR_20 -0x4714 US_ALU_RGB_ADDR_21 -0x4718 US_ALU_RGB_ADDR_22 -0x471C US_ALU_RGB_ADDR_23 -0x4720 US_ALU_RGB_ADDR_24 -0x4724 US_ALU_RGB_ADDR_25 -0x4728 US_ALU_RGB_ADDR_26 -0x472C US_ALU_RGB_ADDR_27 -0x4730 US_ALU_RGB_ADDR_28 -0x4734 US_ALU_RGB_ADDR_29 -0x4738 US_ALU_RGB_ADDR_30 -0x473C US_ALU_RGB_ADDR_31 -0x4740 US_ALU_RGB_ADDR_32 -0x4744 US_ALU_RGB_ADDR_33 -0x4748 US_ALU_RGB_ADDR_34 -0x474C US_ALU_RGB_ADDR_35 -0x4750 US_ALU_RGB_ADDR_36 -0x4754 US_ALU_RGB_ADDR_37 -0x4758 US_ALU_RGB_ADDR_38 -0x475C US_ALU_RGB_ADDR_39 -0x4760 US_ALU_RGB_ADDR_40 -0x4764 US_ALU_RGB_ADDR_41 -0x4768 US_ALU_RGB_ADDR_42 -0x476C US_ALU_RGB_ADDR_43 -0x4770 US_ALU_RGB_ADDR_44 -0x4774 US_ALU_RGB_ADDR_45 -0x4778 US_ALU_RGB_ADDR_46 -0x477C US_ALU_RGB_ADDR_47 -0x4780 US_ALU_RGB_ADDR_48 -0x4784 US_ALU_RGB_ADDR_49 -0x4788 US_ALU_RGB_ADDR_50 -0x478C US_ALU_RGB_ADDR_51 -0x4790 US_ALU_RGB_ADDR_52 -0x4794 US_ALU_RGB_ADDR_53 -0x4798 US_ALU_RGB_ADDR_54 -0x479C US_ALU_RGB_ADDR_55 -0x47A0 US_ALU_RGB_ADDR_56 -0x47A4 US_ALU_RGB_ADDR_57 -0x47A8 US_ALU_RGB_ADDR_58 -0x47AC US_ALU_RGB_ADDR_59 -0x47B0 US_ALU_RGB_ADDR_60 -0x47B4 US_ALU_RGB_ADDR_61 -0x47B8 US_ALU_RGB_ADDR_62 -0x47BC US_ALU_RGB_ADDR_63 -0x47C0 US_ALU_ALPHA_ADDR_0 -0x47C4 US_ALU_ALPHA_ADDR_1 -0x47C8 US_ALU_ALPHA_ADDR_2 -0x47CC US_ALU_ALPHA_ADDR_3 -0x47D0 US_ALU_ALPHA_ADDR_4 -0x47D4 US_ALU_ALPHA_ADDR_5 -0x47D8 US_ALU_ALPHA_ADDR_6 -0x47DC US_ALU_ALPHA_ADDR_7 -0x47E0 US_ALU_ALPHA_ADDR_8 -0x47E4 US_ALU_ALPHA_ADDR_9 -0x47E8 US_ALU_ALPHA_ADDR_10 -0x47EC US_ALU_ALPHA_ADDR_11 -0x47F0 US_ALU_ALPHA_ADDR_12 -0x47F4 US_ALU_ALPHA_ADDR_13 -0x47F8 US_ALU_ALPHA_ADDR_14 -0x47FC US_ALU_ALPHA_ADDR_15 -0x4800 US_ALU_ALPHA_ADDR_16 -0x4804 US_ALU_ALPHA_ADDR_17 -0x4808 US_ALU_ALPHA_ADDR_18 -0x480C US_ALU_ALPHA_ADDR_19 -0x4810 US_ALU_ALPHA_ADDR_20 -0x4814 US_ALU_ALPHA_ADDR_21 -0x4818 US_ALU_ALPHA_ADDR_22 -0x481C US_ALU_ALPHA_ADDR_23 -0x4820 US_ALU_ALPHA_ADDR_24 -0x4824 US_ALU_ALPHA_ADDR_25 -0x4828 US_ALU_ALPHA_ADDR_26 -0x482C US_ALU_ALPHA_ADDR_27 -0x4830 US_ALU_ALPHA_ADDR_28 -0x4834 US_ALU_ALPHA_ADDR_29 -0x4838 US_ALU_ALPHA_ADDR_30 -0x483C US_ALU_ALPHA_ADDR_31 -0x4840 US_ALU_ALPHA_ADDR_32 -0x4844 US_ALU_ALPHA_ADDR_33 -0x4848 US_ALU_ALPHA_ADDR_34 -0x484C US_ALU_ALPHA_ADDR_35 -0x4850 US_ALU_ALPHA_ADDR_36 -0x4854 US_ALU_ALPHA_ADDR_37 -0x4858 US_ALU_ALPHA_ADDR_38 -0x485C US_ALU_ALPHA_ADDR_39 -0x4860 US_ALU_ALPHA_ADDR_40 -0x4864 US_ALU_ALPHA_ADDR_41 -0x4868 US_ALU_ALPHA_ADDR_42 -0x486C US_ALU_ALPHA_ADDR_43 -0x4870 US_ALU_ALPHA_ADDR_44 -0x4874 US_ALU_ALPHA_ADDR_45 -0x4878 US_ALU_ALPHA_ADDR_46 -0x487C US_ALU_ALPHA_ADDR_47 -0x4880 US_ALU_ALPHA_ADDR_48 -0x4884 US_ALU_ALPHA_ADDR_49 -0x4888 US_ALU_ALPHA_ADDR_50 -0x488C US_ALU_ALPHA_ADDR_51 -0x4890 US_ALU_ALPHA_ADDR_52 -0x4894 US_ALU_ALPHA_ADDR_53 -0x4898 US_ALU_ALPHA_ADDR_54 -0x489C US_ALU_ALPHA_ADDR_55 -0x48A0 US_ALU_ALPHA_ADDR_56 -0x48A4 US_ALU_ALPHA_ADDR_57 -0x48A8 US_ALU_ALPHA_ADDR_58 -0x48AC US_ALU_ALPHA_ADDR_59 -0x48B0 US_ALU_ALPHA_ADDR_60 -0x48B4 US_ALU_ALPHA_ADDR_61 -0x48B8 US_ALU_ALPHA_ADDR_62 -0x48BC US_ALU_ALPHA_ADDR_63 -0x48C0 US_ALU_RGB_INST_0 -0x48C4 US_ALU_RGB_INST_1 -0x48C8 US_ALU_RGB_INST_2 -0x48CC US_ALU_RGB_INST_3 -0x48D0 US_ALU_RGB_INST_4 -0x48D4 US_ALU_RGB_INST_5 -0x48D8 US_ALU_RGB_INST_6 -0x48DC US_ALU_RGB_INST_7 -0x48E0 US_ALU_RGB_INST_8 -0x48E4 US_ALU_RGB_INST_9 -0x48E8 US_ALU_RGB_INST_10 -0x48EC US_ALU_RGB_INST_11 -0x48F0 US_ALU_RGB_INST_12 -0x48F4 US_ALU_RGB_INST_13 -0x48F8 US_ALU_RGB_INST_14 -0x48FC US_ALU_RGB_INST_15 -0x4900 US_ALU_RGB_INST_16 -0x4904 US_ALU_RGB_INST_17 -0x4908 US_ALU_RGB_INST_18 -0x490C US_ALU_RGB_INST_19 -0x4910 US_ALU_RGB_INST_20 -0x4914 US_ALU_RGB_INST_21 -0x4918 US_ALU_RGB_INST_22 -0x491C US_ALU_RGB_INST_23 -0x4920 US_ALU_RGB_INST_24 -0x4924 US_ALU_RGB_INST_25 -0x4928 US_ALU_RGB_INST_26 -0x492C US_ALU_RGB_INST_27 -0x4930 US_ALU_RGB_INST_28 -0x4934 US_ALU_RGB_INST_29 -0x4938 US_ALU_RGB_INST_30 -0x493C US_ALU_RGB_INST_31 -0x4940 US_ALU_RGB_INST_32 -0x4944 US_ALU_RGB_INST_33 -0x4948 US_ALU_RGB_INST_34 -0x494C US_ALU_RGB_INST_35 -0x4950 US_ALU_RGB_INST_36 -0x4954 US_ALU_RGB_INST_37 -0x4958 US_ALU_RGB_INST_38 -0x495C US_ALU_RGB_INST_39 -0x4960 US_ALU_RGB_INST_40 -0x4964 US_ALU_RGB_INST_41 -0x4968 US_ALU_RGB_INST_42 -0x496C US_ALU_RGB_INST_43 -0x4970 US_ALU_RGB_INST_44 -0x4974 US_ALU_RGB_INST_45 -0x4978 US_ALU_RGB_INST_46 -0x497C US_ALU_RGB_INST_47 -0x4980 US_ALU_RGB_INST_48 -0x4984 US_ALU_RGB_INST_49 -0x4988 US_ALU_RGB_INST_50 -0x498C US_ALU_RGB_INST_51 -0x4990 US_ALU_RGB_INST_52 -0x4994 US_ALU_RGB_INST_53 -0x4998 US_ALU_RGB_INST_54 -0x499C US_ALU_RGB_INST_55 -0x49A0 US_ALU_RGB_INST_56 -0x49A4 US_ALU_RGB_INST_57 -0x49A8 US_ALU_RGB_INST_58 -0x49AC US_ALU_RGB_INST_59 -0x49B0 US_ALU_RGB_INST_60 -0x49B4 US_ALU_RGB_INST_61 -0x49B8 US_ALU_RGB_INST_62 -0x49BC US_ALU_RGB_INST_63 -0x49C0 US_ALU_ALPHA_INST_0 -0x49C4 US_ALU_ALPHA_INST_1 -0x49C8 US_ALU_ALPHA_INST_2 -0x49CC US_ALU_ALPHA_INST_3 -0x49D0 US_ALU_ALPHA_INST_4 -0x49D4 US_ALU_ALPHA_INST_5 -0x49D8 US_ALU_ALPHA_INST_6 -0x49DC US_ALU_ALPHA_INST_7 -0x49E0 US_ALU_ALPHA_INST_8 -0x49E4 US_ALU_ALPHA_INST_9 -0x49E8 US_ALU_ALPHA_INST_10 -0x49EC US_ALU_ALPHA_INST_11 -0x49F0 US_ALU_ALPHA_INST_12 -0x49F4 US_ALU_ALPHA_INST_13 -0x49F8 US_ALU_ALPHA_INST_14 -0x49FC US_ALU_ALPHA_INST_15 -0x4A00 US_ALU_ALPHA_INST_16 -0x4A04 US_ALU_ALPHA_INST_17 -0x4A08 US_ALU_ALPHA_INST_18 -0x4A0C US_ALU_ALPHA_INST_19 -0x4A10 US_ALU_ALPHA_INST_20 -0x4A14 US_ALU_ALPHA_INST_21 -0x4A18 US_ALU_ALPHA_INST_22 -0x4A1C US_ALU_ALPHA_INST_23 -0x4A20 US_ALU_ALPHA_INST_24 -0x4A24 US_ALU_ALPHA_INST_25 -0x4A28 US_ALU_ALPHA_INST_26 -0x4A2C US_ALU_ALPHA_INST_27 -0x4A30 US_ALU_ALPHA_INST_28 -0x4A34 US_ALU_ALPHA_INST_29 -0x4A38 US_ALU_ALPHA_INST_30 -0x4A3C US_ALU_ALPHA_INST_31 -0x4A40 US_ALU_ALPHA_INST_32 -0x4A44 US_ALU_ALPHA_INST_33 -0x4A48 US_ALU_ALPHA_INST_34 -0x4A4C US_ALU_ALPHA_INST_35 -0x4A50 US_ALU_ALPHA_INST_36 -0x4A54 US_ALU_ALPHA_INST_37 -0x4A58 US_ALU_ALPHA_INST_38 -0x4A5C US_ALU_ALPHA_INST_39 -0x4A60 US_ALU_ALPHA_INST_40 -0x4A64 US_ALU_ALPHA_INST_41 -0x4A68 US_ALU_ALPHA_INST_42 -0x4A6C US_ALU_ALPHA_INST_43 -0x4A70 US_ALU_ALPHA_INST_44 -0x4A74 US_ALU_ALPHA_INST_45 -0x4A78 US_ALU_ALPHA_INST_46 -0x4A7C US_ALU_ALPHA_INST_47 -0x4A80 US_ALU_ALPHA_INST_48 -0x4A84 US_ALU_ALPHA_INST_49 -0x4A88 US_ALU_ALPHA_INST_50 -0x4A8C US_ALU_ALPHA_INST_51 -0x4A90 US_ALU_ALPHA_INST_52 -0x4A94 US_ALU_ALPHA_INST_53 -0x4A98 US_ALU_ALPHA_INST_54 -0x4A9C US_ALU_ALPHA_INST_55 -0x4AA0 US_ALU_ALPHA_INST_56 -0x4AA4 US_ALU_ALPHA_INST_57 -0x4AA8 US_ALU_ALPHA_INST_58 -0x4AAC US_ALU_ALPHA_INST_59 -0x4AB0 US_ALU_ALPHA_INST_60 -0x4AB4 US_ALU_ALPHA_INST_61 -0x4AB8 US_ALU_ALPHA_INST_62 -0x4ABC US_ALU_ALPHA_INST_63 -0x4AC0 US_ALU_EXT_ADDR_0 -0x4AC4 US_ALU_EXT_ADDR_1 -0x4AC8 US_ALU_EXT_ADDR_2 -0x4ACC US_ALU_EXT_ADDR_3 -0x4AD0 US_ALU_EXT_ADDR_4 -0x4AD4 US_ALU_EXT_ADDR_5 -0x4AD8 US_ALU_EXT_ADDR_6 -0x4ADC US_ALU_EXT_ADDR_7 -0x4AE0 US_ALU_EXT_ADDR_8 -0x4AE4 US_ALU_EXT_ADDR_9 -0x4AE8 US_ALU_EXT_ADDR_10 -0x4AEC US_ALU_EXT_ADDR_11 -0x4AF0 US_ALU_EXT_ADDR_12 -0x4AF4 US_ALU_EXT_ADDR_13 -0x4AF8 US_ALU_EXT_ADDR_14 -0x4AFC US_ALU_EXT_ADDR_15 -0x4B00 US_ALU_EXT_ADDR_16 -0x4B04 US_ALU_EXT_ADDR_17 -0x4B08 US_ALU_EXT_ADDR_18 -0x4B0C US_ALU_EXT_ADDR_19 -0x4B10 US_ALU_EXT_ADDR_20 -0x4B14 US_ALU_EXT_ADDR_21 -0x4B18 US_ALU_EXT_ADDR_22 -0x4B1C US_ALU_EXT_ADDR_23 -0x4B20 US_ALU_EXT_ADDR_24 -0x4B24 US_ALU_EXT_ADDR_25 -0x4B28 US_ALU_EXT_ADDR_26 -0x4B2C US_ALU_EXT_ADDR_27 -0x4B30 US_ALU_EXT_ADDR_28 -0x4B34 US_ALU_EXT_ADDR_29 -0x4B38 US_ALU_EXT_ADDR_30 -0x4B3C US_ALU_EXT_ADDR_31 -0x4B40 US_ALU_EXT_ADDR_32 -0x4B44 US_ALU_EXT_ADDR_33 -0x4B48 US_ALU_EXT_ADDR_34 -0x4B4C US_ALU_EXT_ADDR_35 -0x4B50 US_ALU_EXT_ADDR_36 -0x4B54 US_ALU_EXT_ADDR_37 -0x4B58 US_ALU_EXT_ADDR_38 -0x4B5C US_ALU_EXT_ADDR_39 -0x4B60 US_ALU_EXT_ADDR_40 -0x4B64 US_ALU_EXT_ADDR_41 -0x4B68 US_ALU_EXT_ADDR_42 -0x4B6C US_ALU_EXT_ADDR_43 -0x4B70 US_ALU_EXT_ADDR_44 -0x4B74 US_ALU_EXT_ADDR_45 -0x4B78 US_ALU_EXT_ADDR_46 -0x4B7C US_ALU_EXT_ADDR_47 -0x4B80 US_ALU_EXT_ADDR_48 -0x4B84 US_ALU_EXT_ADDR_49 -0x4B88 US_ALU_EXT_ADDR_50 -0x4B8C US_ALU_EXT_ADDR_51 -0x4B90 US_ALU_EXT_ADDR_52 -0x4B94 US_ALU_EXT_ADDR_53 -0x4B98 US_ALU_EXT_ADDR_54 -0x4B9C US_ALU_EXT_ADDR_55 -0x4BA0 US_ALU_EXT_ADDR_56 -0x4BA4 US_ALU_EXT_ADDR_57 -0x4BA8 US_ALU_EXT_ADDR_58 -0x4BAC US_ALU_EXT_ADDR_59 -0x4BB0 US_ALU_EXT_ADDR_60 -0x4BB4 US_ALU_EXT_ADDR_61 -0x4BB8 US_ALU_EXT_ADDR_62 -0x4BBC US_ALU_EXT_ADDR_63 -0x4BC0 FG_FOG_BLEND -0x4BC4 FG_FOG_FACTOR -0x4BC8 FG_FOG_COLOR_R -0x4BCC FG_FOG_COLOR_G -0x4BD0 FG_FOG_COLOR_B -0x4BD4 FG_ALPHA_FUNC -0x4BD8 FG_DEPTH_SRC -0x4C00 US_ALU_CONST_R_0 -0x4C04 US_ALU_CONST_G_0 -0x4C08 US_ALU_CONST_B_0 -0x4C0C US_ALU_CONST_A_0 -0x4C10 US_ALU_CONST_R_1 -0x4C14 US_ALU_CONST_G_1 -0x4C18 US_ALU_CONST_B_1 -0x4C1C US_ALU_CONST_A_1 -0x4C20 US_ALU_CONST_R_2 -0x4C24 US_ALU_CONST_G_2 -0x4C28 US_ALU_CONST_B_2 -0x4C2C US_ALU_CONST_A_2 -0x4C30 US_ALU_CONST_R_3 -0x4C34 US_ALU_CONST_G_3 -0x4C38 US_ALU_CONST_B_3 -0x4C3C US_ALU_CONST_A_3 -0x4C40 US_ALU_CONST_R_4 -0x4C44 US_ALU_CONST_G_4 -0x4C48 US_ALU_CONST_B_4 -0x4C4C US_ALU_CONST_A_4 -0x4C50 US_ALU_CONST_R_5 -0x4C54 US_ALU_CONST_G_5 -0x4C58 US_ALU_CONST_B_5 -0x4C5C US_ALU_CONST_A_5 -0x4C60 US_ALU_CONST_R_6 -0x4C64 US_ALU_CONST_G_6 -0x4C68 US_ALU_CONST_B_6 -0x4C6C US_ALU_CONST_A_6 -0x4C70 US_ALU_CONST_R_7 -0x4C74 US_ALU_CONST_G_7 -0x4C78 US_ALU_CONST_B_7 -0x4C7C US_ALU_CONST_A_7 -0x4C80 US_ALU_CONST_R_8 -0x4C84 US_ALU_CONST_G_8 -0x4C88 US_ALU_CONST_B_8 -0x4C8C US_ALU_CONST_A_8 -0x4C90 US_ALU_CONST_R_9 -0x4C94 US_ALU_CONST_G_9 -0x4C98 US_ALU_CONST_B_9 -0x4C9C US_ALU_CONST_A_9 -0x4CA0 US_ALU_CONST_R_10 -0x4CA4 US_ALU_CONST_G_10 -0x4CA8 US_ALU_CONST_B_10 -0x4CAC US_ALU_CONST_A_10 -0x4CB0 US_ALU_CONST_R_11 -0x4CB4 US_ALU_CONST_G_11 -0x4CB8 US_ALU_CONST_B_11 -0x4CBC US_ALU_CONST_A_11 -0x4CC0 US_ALU_CONST_R_12 -0x4CC4 US_ALU_CONST_G_12 -0x4CC8 US_ALU_CONST_B_12 -0x4CCC US_ALU_CONST_A_12 -0x4CD0 US_ALU_CONST_R_13 -0x4CD4 US_ALU_CONST_G_13 -0x4CD8 US_ALU_CONST_B_13 -0x4CDC US_ALU_CONST_A_13 -0x4CE0 US_ALU_CONST_R_14 -0x4CE4 US_ALU_CONST_G_14 -0x4CE8 US_ALU_CONST_B_14 -0x4CEC US_ALU_CONST_A_14 -0x4CF0 US_ALU_CONST_R_15 -0x4CF4 US_ALU_CONST_G_15 -0x4CF8 US_ALU_CONST_B_15 -0x4CFC US_ALU_CONST_A_15 -0x4D00 US_ALU_CONST_R_16 -0x4D04 US_ALU_CONST_G_16 -0x4D08 US_ALU_CONST_B_16 -0x4D0C US_ALU_CONST_A_16 -0x4D10 US_ALU_CONST_R_17 -0x4D14 US_ALU_CONST_G_17 -0x4D18 US_ALU_CONST_B_17 -0x4D1C US_ALU_CONST_A_17 -0x4D20 US_ALU_CONST_R_18 -0x4D24 US_ALU_CONST_G_18 -0x4D28 US_ALU_CONST_B_18 -0x4D2C US_ALU_CONST_A_18 -0x4D30 US_ALU_CONST_R_19 -0x4D34 US_ALU_CONST_G_19 -0x4D38 US_ALU_CONST_B_19 -0x4D3C US_ALU_CONST_A_19 -0x4D40 US_ALU_CONST_R_20 -0x4D44 US_ALU_CONST_G_20 -0x4D48 US_ALU_CONST_B_20 -0x4D4C US_ALU_CONST_A_20 -0x4D50 US_ALU_CONST_R_21 -0x4D54 US_ALU_CONST_G_21 -0x4D58 US_ALU_CONST_B_21 -0x4D5C US_ALU_CONST_A_21 -0x4D60 US_ALU_CONST_R_22 -0x4D64 US_ALU_CONST_G_22 -0x4D68 US_ALU_CONST_B_22 -0x4D6C US_ALU_CONST_A_22 -0x4D70 US_ALU_CONST_R_23 -0x4D74 US_ALU_CONST_G_23 -0x4D78 US_ALU_CONST_B_23 -0x4D7C US_ALU_CONST_A_23 -0x4D80 US_ALU_CONST_R_24 -0x4D84 US_ALU_CONST_G_24 -0x4D88 US_ALU_CONST_B_24 -0x4D8C US_ALU_CONST_A_24 -0x4D90 US_ALU_CONST_R_25 -0x4D94 US_ALU_CONST_G_25 -0x4D98 US_ALU_CONST_B_25 -0x4D9C US_ALU_CONST_A_25 -0x4DA0 US_ALU_CONST_R_26 -0x4DA4 US_ALU_CONST_G_26 -0x4DA8 US_ALU_CONST_B_26 -0x4DAC US_ALU_CONST_A_26 -0x4DB0 US_ALU_CONST_R_27 -0x4DB4 US_ALU_CONST_G_27 -0x4DB8 US_ALU_CONST_B_27 -0x4DBC US_ALU_CONST_A_27 -0x4DC0 US_ALU_CONST_R_28 -0x4DC4 US_ALU_CONST_G_28 -0x4DC8 US_ALU_CONST_B_28 -0x4DCC US_ALU_CONST_A_28 -0x4DD0 US_ALU_CONST_R_29 -0x4DD4 US_ALU_CONST_G_29 -0x4DD8 US_ALU_CONST_B_29 -0x4DDC US_ALU_CONST_A_29 -0x4DE0 US_ALU_CONST_R_30 -0x4DE4 US_ALU_CONST_G_30 -0x4DE8 US_ALU_CONST_B_30 -0x4DEC US_ALU_CONST_A_30 -0x4DF0 US_ALU_CONST_R_31 -0x4DF4 US_ALU_CONST_G_31 -0x4DF8 US_ALU_CONST_B_31 -0x4DFC US_ALU_CONST_A_31 -0x4E08 RB3D_ABLENDCNTL_R3 -0x4E10 RB3D_CONSTANT_COLOR -0x4E14 RB3D_COLOR_CLEAR_VALUE -0x4E18 RB3D_ROPCNTL_R3 -0x4E1C RB3D_CLRCMP_FLIPE_R3 -0x4E20 RB3D_CLRCMP_CLR_R3 -0x4E24 RB3D_CLRCMP_MSK_R3 -0x4E48 RB3D_DEBUG_CTL -0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -0x4E50 RB3D_DITHER_CTL -0x4E54 RB3D_CMASK_OFFSET0 -0x4E58 RB3D_CMASK_OFFSET1 -0x4E5C RB3D_CMASK_OFFSET2 -0x4E60 RB3D_CMASK_OFFSET3 -0x4E64 RB3D_CMASK_PITCH0 -0x4E68 RB3D_CMASK_PITCH1 -0x4E6C RB3D_CMASK_PITCH2 -0x4E70 RB3D_CMASK_PITCH3 -0x4E74 RB3D_CMASK_WRINDEX -0x4E78 RB3D_CMASK_DWORD -0x4E7C RB3D_CMASK_RDINDEX -0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -0x4F04 ZB_ZSTENCILCNTL -0x4F08 ZB_STENCILREFMASK -0x4F14 ZB_ZTOP -0x4F18 ZB_ZCACHE_CTLSTAT -0x4F28 ZB_DEPTHCLEARVALUE -0x4F58 ZB_ZPASS_DATA diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rv515 b/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rv515 deleted file mode 100644 index 911a8fbd..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ /dev/null @@ -1,494 +0,0 @@ -rv515 0x6d40 -0x1434 SRC_Y_X -0x1438 DST_Y_X -0x143C DST_HEIGHT_WIDTH -0x146C DP_GUI_MASTER_CNTL -0x1474 BRUSH_Y_X -0x1478 DP_BRUSH_BKGD_CLR -0x147C DP_BRUSH_FRGD_CLR -0x1480 BRUSH_DATA0 -0x1484 BRUSH_DATA1 -0x1598 DST_WIDTH_HEIGHT -0x15C0 CLR_CMP_CNTL -0x15C4 CLR_CMP_CLR_SRC -0x15C8 CLR_CMP_CLR_DST -0x15CC CLR_CMP_MSK -0x15D8 DP_SRC_FRGD_CLR -0x15DC DP_SRC_BKGD_CLR -0x1600 DST_LINE_START -0x1604 DST_LINE_END -0x1608 DST_LINE_PATCOUNT -0x16C0 DP_CNTL -0x16CC DP_WRITE_MSK -0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -0x16E8 DEFAULT_SC_BOTTOM_RIGHT -0x16EC SC_TOP_LEFT -0x16F0 SC_BOTTOM_RIGHT -0x16F4 SRC_SC_BOTTOM_RIGHT -0x1714 DSTCACHE_CTLSTAT -0x1720 WAIT_UNTIL -0x172C RBBM_GUICNTL -0x1D98 VAP_VPORT_XSCALE -0x1D9C VAP_VPORT_XOFFSET -0x1DA0 VAP_VPORT_YSCALE -0x1DA4 VAP_VPORT_YOFFSET -0x1DA8 VAP_VPORT_ZSCALE -0x1DAC VAP_VPORT_ZOFFSET -0x2080 VAP_CNTL -0x208C VAP_INDEX_OFFSET -0x2090 VAP_OUT_VTX_FMT_0 -0x2094 VAP_OUT_VTX_FMT_1 -0x20B0 VAP_VTE_CNTL -0x2138 VAP_VF_MIN_VTX_INDX -0x2140 VAP_CNTL_STATUS -0x2150 VAP_PROG_STREAM_CNTL_0 -0x2154 VAP_PROG_STREAM_CNTL_1 -0x2158 VAP_PROG_STREAM_CNTL_2 -0x215C VAP_PROG_STREAM_CNTL_3 -0x2160 VAP_PROG_STREAM_CNTL_4 -0x2164 VAP_PROG_STREAM_CNTL_5 -0x2168 VAP_PROG_STREAM_CNTL_6 -0x216C VAP_PROG_STREAM_CNTL_7 -0x2180 VAP_VTX_STATE_CNTL -0x2184 VAP_VSM_VTX_ASSM -0x2188 VAP_VTX_STATE_IND_REG_0 -0x218C VAP_VTX_STATE_IND_REG_1 -0x2190 VAP_VTX_STATE_IND_REG_2 -0x2194 VAP_VTX_STATE_IND_REG_3 -0x2198 VAP_VTX_STATE_IND_REG_4 -0x219C VAP_VTX_STATE_IND_REG_5 -0x21A0 VAP_VTX_STATE_IND_REG_6 -0x21A4 VAP_VTX_STATE_IND_REG_7 -0x21A8 VAP_VTX_STATE_IND_REG_8 -0x21AC VAP_VTX_STATE_IND_REG_9 -0x21B0 VAP_VTX_STATE_IND_REG_10 -0x21B4 VAP_VTX_STATE_IND_REG_11 -0x21B8 VAP_VTX_STATE_IND_REG_12 -0x21BC VAP_VTX_STATE_IND_REG_13 -0x21C0 VAP_VTX_STATE_IND_REG_14 -0x21C4 VAP_VTX_STATE_IND_REG_15 -0x21DC VAP_PSC_SGN_NORM_CNTL -0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -0x2200 VAP_PVS_VECTOR_INDX_REG -0x2204 VAP_PVS_VECTOR_DATA_REG -0x2208 VAP_PVS_VECTOR_DATA_REG_128 -0x2218 VAP_TEX_TO_COLOR_CNTL -0x221C VAP_CLIP_CNTL -0x2220 VAP_GB_VERT_CLIP_ADJ -0x2224 VAP_GB_VERT_DISC_ADJ -0x2228 VAP_GB_HORZ_CLIP_ADJ -0x222C VAP_GB_HORZ_DISC_ADJ -0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -0x2284 VAP_PVS_STATE_FLUSH_REG -0x2288 VAP_PVS_VTX_TIMEOUT_REG -0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -0x22D0 VAP_PVS_CODE_CNTL_0 -0x22D4 VAP_PVS_CONST_CNTL -0x22D8 VAP_PVS_CODE_CNTL_1 -0x22DC VAP_PVS_FLOW_CNTL_OPC -0x2500 VAP_PVS_FLOW_CNTL_ADDRS_LW_0 -0x2504 VAP_PVS_FLOW_CNTL_ADDRS_UW_0 -0x2508 VAP_PVS_FLOW_CNTL_ADDRS_LW_1 -0x250C VAP_PVS_FLOW_CNTL_ADDRS_UW_1 -0x2510 VAP_PVS_FLOW_CNTL_ADDRS_LW_2 -0x2514 VAP_PVS_FLOW_CNTL_ADDRS_UW_2 -0x2518 VAP_PVS_FLOW_CNTL_ADDRS_LW_3 -0x251C VAP_PVS_FLOW_CNTL_ADDRS_UW_3 -0x2520 VAP_PVS_FLOW_CNTL_ADDRS_LW_4 -0x2524 VAP_PVS_FLOW_CNTL_ADDRS_UW_4 -0x2528 VAP_PVS_FLOW_CNTL_ADDRS_LW_5 -0x252C VAP_PVS_FLOW_CNTL_ADDRS_UW_5 -0x2530 VAP_PVS_FLOW_CNTL_ADDRS_LW_6 -0x2534 VAP_PVS_FLOW_CNTL_ADDRS_UW_6 -0x2538 VAP_PVS_FLOW_CNTL_ADDRS_LW_7 -0x253C VAP_PVS_FLOW_CNTL_ADDRS_UW_7 -0x2540 VAP_PVS_FLOW_CNTL_ADDRS_LW_8 -0x2544 VAP_PVS_FLOW_CNTL_ADDRS_UW_8 -0x2548 VAP_PVS_FLOW_CNTL_ADDRS_LW_9 -0x254C VAP_PVS_FLOW_CNTL_ADDRS_UW_9 -0x2550 VAP_PVS_FLOW_CNTL_ADDRS_LW_10 -0x2554 VAP_PVS_FLOW_CNTL_ADDRS_UW_10 -0x2558 VAP_PVS_FLOW_CNTL_ADDRS_LW_11 -0x255C VAP_PVS_FLOW_CNTL_ADDRS_UW_11 -0x2560 VAP_PVS_FLOW_CNTL_ADDRS_LW_12 -0x2564 VAP_PVS_FLOW_CNTL_ADDRS_UW_12 -0x2568 VAP_PVS_FLOW_CNTL_ADDRS_LW_13 -0x256C VAP_PVS_FLOW_CNTL_ADDRS_UW_13 -0x2570 VAP_PVS_FLOW_CNTL_ADDRS_LW_14 -0x2574 VAP_PVS_FLOW_CNTL_ADDRS_UW_14 -0x2578 VAP_PVS_FLOW_CNTL_ADDRS_LW_15 -0x257C VAP_PVS_FLOW_CNTL_ADDRS_UW_15 -0x342C RB2D_DSTCACHE_CTLSTAT -0x4000 GB_VAP_RASTER_VTX_FMT_0 -0x4004 GB_VAP_RASTER_VTX_FMT_1 -0x4008 GB_ENABLE -0x4010 GB_MSPOS0 -0x4014 GB_MSPOS1 -0x401C GB_SELECT -0x4020 GB_AA_CONFIG -0x4024 GB_FIFO_SIZE -0x4100 TX_INVALTAGS -0x4114 SU_TEX_WRAP_PS3 -0x4118 PS3_ENABLE -0x411c PS3_VTX_FMT -0x4120 PS3_TEX_SOURCE -0x4200 GA_POINT_S0 -0x4204 GA_POINT_T0 -0x4208 GA_POINT_S1 -0x420C GA_POINT_T1 -0x4214 GA_TRIANGLE_STIPPLE -0x421C GA_POINT_SIZE -0x4230 GA_POINT_MINMAX -0x4234 GA_LINE_CNTL -0x4238 GA_LINE_STIPPLE_CONFIG -0x4258 GA_COLOR_CONTROL_PS3 -0x4260 GA_LINE_STIPPLE_VALUE -0x4264 GA_LINE_S0 -0x4268 GA_LINE_S1 -0x4278 GA_COLOR_CONTROL -0x427C GA_SOLID_RG -0x4280 GA_SOLID_BA -0x4288 GA_POLY_MODE -0x428C GA_ROUND_MODE -0x4290 GA_OFFSET -0x4294 GA_FOG_SCALE -0x4298 GA_FOG_OFFSET -0x42A0 SU_TEX_WRAP -0x42A4 SU_POLY_OFFSET_FRONT_SCALE -0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -0x42AC SU_POLY_OFFSET_BACK_SCALE -0x42B0 SU_POLY_OFFSET_BACK_OFFSET -0x42B4 SU_POLY_OFFSET_ENABLE -0x42B8 SU_CULL_MODE -0x42C0 SU_DEPTH_SCALE -0x42C4 SU_DEPTH_OFFSET -0x42C8 SU_REG_DEST -0x4300 RS_COUNT -0x4304 RS_INST_COUNT -0x4074 RS_IP_0 -0x4078 RS_IP_1 -0x407C RS_IP_2 -0x4080 RS_IP_3 -0x4084 RS_IP_4 -0x4088 RS_IP_5 -0x408C RS_IP_6 -0x4090 RS_IP_7 -0x4094 RS_IP_8 -0x4098 RS_IP_9 -0x409C RS_IP_10 -0x40A0 RS_IP_11 -0x40A4 RS_IP_12 -0x40A8 RS_IP_13 -0x40AC RS_IP_14 -0x40B0 RS_IP_15 -0x4320 RS_INST_0 -0x4324 RS_INST_1 -0x4328 RS_INST_2 -0x432C RS_INST_3 -0x4330 RS_INST_4 -0x4334 RS_INST_5 -0x4338 RS_INST_6 -0x433C RS_INST_7 -0x4340 RS_INST_8 -0x4344 RS_INST_9 -0x4348 RS_INST_10 -0x434C RS_INST_11 -0x4350 RS_INST_12 -0x4354 RS_INST_13 -0x4358 RS_INST_14 -0x435C RS_INST_15 -0x43A8 SC_EDGERULE -0x43B0 SC_CLIP_0_A -0x43B4 SC_CLIP_0_B -0x43B8 SC_CLIP_1_A -0x43BC SC_CLIP_1_B -0x43C0 SC_CLIP_2_A -0x43C4 SC_CLIP_2_B -0x43C8 SC_CLIP_3_A -0x43CC SC_CLIP_3_B -0x43D0 SC_CLIP_RULE -0x43E0 SC_SCISSOR0 -0x43E8 SC_SCREENDOOR -0x4440 TX_FILTER1_0 -0x4444 TX_FILTER1_1 -0x4448 TX_FILTER1_2 -0x444C TX_FILTER1_3 -0x4450 TX_FILTER1_4 -0x4454 TX_FILTER1_5 -0x4458 TX_FILTER1_6 -0x445C TX_FILTER1_7 -0x4460 TX_FILTER1_8 -0x4464 TX_FILTER1_9 -0x4468 TX_FILTER1_10 -0x446C TX_FILTER1_11 -0x4470 TX_FILTER1_12 -0x4474 TX_FILTER1_13 -0x4478 TX_FILTER1_14 -0x447C TX_FILTER1_15 -0x4580 TX_CHROMA_KEY_0 -0x4584 TX_CHROMA_KEY_1 -0x4588 TX_CHROMA_KEY_2 -0x458C TX_CHROMA_KEY_3 -0x4590 TX_CHROMA_KEY_4 -0x4594 TX_CHROMA_KEY_5 -0x4598 TX_CHROMA_KEY_6 -0x459C TX_CHROMA_KEY_7 -0x45A0 TX_CHROMA_KEY_8 -0x45A4 TX_CHROMA_KEY_9 -0x45A8 TX_CHROMA_KEY_10 -0x45AC TX_CHROMA_KEY_11 -0x45B0 TX_CHROMA_KEY_12 -0x45B4 TX_CHROMA_KEY_13 -0x45B8 TX_CHROMA_KEY_14 -0x45BC TX_CHROMA_KEY_15 -0x45C0 TX_BORDER_COLOR_0 -0x45C4 TX_BORDER_COLOR_1 -0x45C8 TX_BORDER_COLOR_2 -0x45CC TX_BORDER_COLOR_3 -0x45D0 TX_BORDER_COLOR_4 -0x45D4 TX_BORDER_COLOR_5 -0x45D8 TX_BORDER_COLOR_6 -0x45DC TX_BORDER_COLOR_7 -0x45E0 TX_BORDER_COLOR_8 -0x45E4 TX_BORDER_COLOR_9 -0x45E8 TX_BORDER_COLOR_10 -0x45EC TX_BORDER_COLOR_11 -0x45F0 TX_BORDER_COLOR_12 -0x45F4 TX_BORDER_COLOR_13 -0x45F8 TX_BORDER_COLOR_14 -0x45FC TX_BORDER_COLOR_15 -0x4250 GA_US_VECTOR_INDEX -0x4254 GA_US_VECTOR_DATA -0x4600 US_CONFIG -0x4604 US_PIXSIZE -0x4620 US_FC_BOOL_CONST -0x4624 US_FC_CTRL -0x4630 US_CODE_ADDR -0x4634 US_CODE_RANGE -0x4638 US_CODE_OFFSET -0x4640 US_FORMAT0_0 -0x4644 US_FORMAT0_1 -0x4648 US_FORMAT0_2 -0x464C US_FORMAT0_3 -0x4650 US_FORMAT0_4 -0x4654 US_FORMAT0_5 -0x4658 US_FORMAT0_6 -0x465C US_FORMAT0_7 -0x4660 US_FORMAT0_8 -0x4664 US_FORMAT0_9 -0x4668 US_FORMAT0_10 -0x466C US_FORMAT0_11 -0x4670 US_FORMAT0_12 -0x4674 US_FORMAT0_13 -0x4678 US_FORMAT0_14 -0x467C US_FORMAT0_15 -0x46A4 US_OUT_FMT_0 -0x46A8 US_OUT_FMT_1 -0x46AC US_OUT_FMT_2 -0x46B0 US_OUT_FMT_3 -0x46B4 US_W_FMT -0x4BC0 FG_FOG_BLEND -0x4BC4 FG_FOG_FACTOR -0x4BC8 FG_FOG_COLOR_R -0x4BCC FG_FOG_COLOR_G -0x4BD0 FG_FOG_COLOR_B -0x4BD4 FG_ALPHA_FUNC -0x4BD8 FG_DEPTH_SRC -0x4BE0 FG_ALPHA_VALUE -0x4C00 US_ALU_CONST_R_0 -0x4C04 US_ALU_CONST_G_0 -0x4C08 US_ALU_CONST_B_0 -0x4C0C US_ALU_CONST_A_0 -0x4C10 US_ALU_CONST_R_1 -0x4C14 US_ALU_CONST_G_1 -0x4C18 US_ALU_CONST_B_1 -0x4C1C US_ALU_CONST_A_1 -0x4C20 US_ALU_CONST_R_2 -0x4C24 US_ALU_CONST_G_2 -0x4C28 US_ALU_CONST_B_2 -0x4C2C US_ALU_CONST_A_2 -0x4C30 US_ALU_CONST_R_3 -0x4C34 US_ALU_CONST_G_3 -0x4C38 US_ALU_CONST_B_3 -0x4C3C US_ALU_CONST_A_3 -0x4C40 US_ALU_CONST_R_4 -0x4C44 US_ALU_CONST_G_4 -0x4C48 US_ALU_CONST_B_4 -0x4C4C US_ALU_CONST_A_4 -0x4C50 US_ALU_CONST_R_5 -0x4C54 US_ALU_CONST_G_5 -0x4C58 US_ALU_CONST_B_5 -0x4C5C US_ALU_CONST_A_5 -0x4C60 US_ALU_CONST_R_6 -0x4C64 US_ALU_CONST_G_6 -0x4C68 US_ALU_CONST_B_6 -0x4C6C US_ALU_CONST_A_6 -0x4C70 US_ALU_CONST_R_7 -0x4C74 US_ALU_CONST_G_7 -0x4C78 US_ALU_CONST_B_7 -0x4C7C US_ALU_CONST_A_7 -0x4C80 US_ALU_CONST_R_8 -0x4C84 US_ALU_CONST_G_8 -0x4C88 US_ALU_CONST_B_8 -0x4C8C US_ALU_CONST_A_8 -0x4C90 US_ALU_CONST_R_9 -0x4C94 US_ALU_CONST_G_9 -0x4C98 US_ALU_CONST_B_9 -0x4C9C US_ALU_CONST_A_9 -0x4CA0 US_ALU_CONST_R_10 -0x4CA4 US_ALU_CONST_G_10 -0x4CA8 US_ALU_CONST_B_10 -0x4CAC US_ALU_CONST_A_10 -0x4CB0 US_ALU_CONST_R_11 -0x4CB4 US_ALU_CONST_G_11 -0x4CB8 US_ALU_CONST_B_11 -0x4CBC US_ALU_CONST_A_11 -0x4CC0 US_ALU_CONST_R_12 -0x4CC4 US_ALU_CONST_G_12 -0x4CC8 US_ALU_CONST_B_12 -0x4CCC US_ALU_CONST_A_12 -0x4CD0 US_ALU_CONST_R_13 -0x4CD4 US_ALU_CONST_G_13 -0x4CD8 US_ALU_CONST_B_13 -0x4CDC US_ALU_CONST_A_13 -0x4CE0 US_ALU_CONST_R_14 -0x4CE4 US_ALU_CONST_G_14 -0x4CE8 US_ALU_CONST_B_14 -0x4CEC US_ALU_CONST_A_14 -0x4CF0 US_ALU_CONST_R_15 -0x4CF4 US_ALU_CONST_G_15 -0x4CF8 US_ALU_CONST_B_15 -0x4CFC US_ALU_CONST_A_15 -0x4D00 US_ALU_CONST_R_16 -0x4D04 US_ALU_CONST_G_16 -0x4D08 US_ALU_CONST_B_16 -0x4D0C US_ALU_CONST_A_16 -0x4D10 US_ALU_CONST_R_17 -0x4D14 US_ALU_CONST_G_17 -0x4D18 US_ALU_CONST_B_17 -0x4D1C US_ALU_CONST_A_17 -0x4D20 US_ALU_CONST_R_18 -0x4D24 US_ALU_CONST_G_18 -0x4D28 US_ALU_CONST_B_18 -0x4D2C US_ALU_CONST_A_18 -0x4D30 US_ALU_CONST_R_19 -0x4D34 US_ALU_CONST_G_19 -0x4D38 US_ALU_CONST_B_19 -0x4D3C US_ALU_CONST_A_19 -0x4D40 US_ALU_CONST_R_20 -0x4D44 US_ALU_CONST_G_20 -0x4D48 US_ALU_CONST_B_20 -0x4D4C US_ALU_CONST_A_20 -0x4D50 US_ALU_CONST_R_21 -0x4D54 US_ALU_CONST_G_21 -0x4D58 US_ALU_CONST_B_21 -0x4D5C US_ALU_CONST_A_21 -0x4D60 US_ALU_CONST_R_22 -0x4D64 US_ALU_CONST_G_22 -0x4D68 US_ALU_CONST_B_22 -0x4D6C US_ALU_CONST_A_22 -0x4D70 US_ALU_CONST_R_23 -0x4D74 US_ALU_CONST_G_23 -0x4D78 US_ALU_CONST_B_23 -0x4D7C US_ALU_CONST_A_23 -0x4D80 US_ALU_CONST_R_24 -0x4D84 US_ALU_CONST_G_24 -0x4D88 US_ALU_CONST_B_24 -0x4D8C US_ALU_CONST_A_24 -0x4D90 US_ALU_CONST_R_25 -0x4D94 US_ALU_CONST_G_25 -0x4D98 US_ALU_CONST_B_25 -0x4D9C US_ALU_CONST_A_25 -0x4DA0 US_ALU_CONST_R_26 -0x4DA4 US_ALU_CONST_G_26 -0x4DA8 US_ALU_CONST_B_26 -0x4DAC US_ALU_CONST_A_26 -0x4DB0 US_ALU_CONST_R_27 -0x4DB4 US_ALU_CONST_G_27 -0x4DB8 US_ALU_CONST_B_27 -0x4DBC US_ALU_CONST_A_27 -0x4DC0 US_ALU_CONST_R_28 -0x4DC4 US_ALU_CONST_G_28 -0x4DC8 US_ALU_CONST_B_28 -0x4DCC US_ALU_CONST_A_28 -0x4DD0 US_ALU_CONST_R_29 -0x4DD4 US_ALU_CONST_G_29 -0x4DD8 US_ALU_CONST_B_29 -0x4DDC US_ALU_CONST_A_29 -0x4DE0 US_ALU_CONST_R_30 -0x4DE4 US_ALU_CONST_G_30 -0x4DE8 US_ALU_CONST_B_30 -0x4DEC US_ALU_CONST_A_30 -0x4DF0 US_ALU_CONST_R_31 -0x4DF4 US_ALU_CONST_G_31 -0x4DF8 US_ALU_CONST_B_31 -0x4DFC US_ALU_CONST_A_31 -0x4E08 RB3D_ABLENDCNTL_R3 -0x4E10 RB3D_CONSTANT_COLOR -0x4E14 RB3D_COLOR_CLEAR_VALUE -0x4E18 RB3D_ROPCNTL_R3 -0x4E1C RB3D_CLRCMP_FLIPE_R3 -0x4E20 RB3D_CLRCMP_CLR_R3 -0x4E24 RB3D_CLRCMP_MSK_R3 -0x4E48 RB3D_DEBUG_CTL -0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -0x4E50 RB3D_DITHER_CTL -0x4E54 RB3D_CMASK_OFFSET0 -0x4E58 RB3D_CMASK_OFFSET1 -0x4E5C RB3D_CMASK_OFFSET2 -0x4E60 RB3D_CMASK_OFFSET3 -0x4E64 RB3D_CMASK_PITCH0 -0x4E68 RB3D_CMASK_PITCH1 -0x4E6C RB3D_CMASK_PITCH2 -0x4E70 RB3D_CMASK_PITCH3 -0x4E74 RB3D_CMASK_WRINDEX -0x4E78 RB3D_CMASK_DWORD -0x4E7C RB3D_CMASK_RDINDEX -0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -0x4EF8 RB3D_CONSTANT_COLOR_AR -0x4EFC RB3D_CONSTANT_COLOR_GB -0x4F04 ZB_ZSTENCILCNTL -0x4F08 ZB_STENCILREFMASK -0x4F14 ZB_ZTOP -0x4F18 ZB_ZCACHE_CTLSTAT -0x4F58 ZB_ZPASS_DATA -0x4F28 ZB_DEPTHCLEARVALUE -0x4FD4 ZB_STENCILREFMASK_BF diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs100d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs100d.h deleted file mode 100644 index 48a913a0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs100d.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RS100D_H__ -#define __RS100D_H__ - -/* Registers */ -#define R_00015C_NB_TOM 0x00015C -#define S_00015C_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_00015C_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_00015C_MC_FB_START 0xFFFF0000 -#define S_00015C_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_00015C_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_00015C_MC_FB_TOP 0x0000FFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400.c deleted file mode 100644 index 4cf381b3..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include -#include "radeon.h" -#include "radeon_asic.h" -#include "rs400d.h" - -/* This files gather functions specifics to : rs400,rs480 */ -static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev); - -void rs400_gart_adjust_size(struct radeon_device *rdev) -{ - /* Check gart size */ - switch (rdev->mc.gtt_size/(1024*1024)) { - case 32: - case 64: - case 128: - case 256: - case 512: - case 1024: - case 2048: - break; - default: - DRM_ERROR("Unable to use IGP GART size %uM\n", - (unsigned)(rdev->mc.gtt_size >> 20)); - DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n"); - DRM_ERROR("Forcing to 32M GART size\n"); - rdev->mc.gtt_size = 32 * 1024 * 1024; - return; - } -} - -void rs400_gart_tlb_flush(struct radeon_device *rdev) -{ - uint32_t tmp; - unsigned int timeout = rdev->usec_timeout; - - WREG32_MC(RS480_GART_CACHE_CNTRL, RS480_GART_CACHE_INVALIDATE); - do { - tmp = RREG32_MC(RS480_GART_CACHE_CNTRL); - if ((tmp & RS480_GART_CACHE_INVALIDATE) == 0) - break; - DRM_UDELAY(1); - timeout--; - } while (timeout > 0); - WREG32_MC(RS480_GART_CACHE_CNTRL, 0); -} - -int rs400_gart_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.ptr) { - WARN(1, "RS400 GART already initialized\n"); - return 0; - } - /* Check gart size */ - switch(rdev->mc.gtt_size / (1024 * 1024)) { - case 32: - case 64: - case 128: - case 256: - case 512: - case 1024: - case 2048: - break; - default: - return -EINVAL; - } - /* Initialize common gart structure */ - r = radeon_gart_init(rdev); - if (r) - return r; - if (rs400_debugfs_pcie_gart_info_init(rdev)) - DRM_ERROR("Failed to register debugfs file for RS400 GART !\n"); - rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; - return radeon_gart_table_ram_alloc(rdev); -} - -int rs400_gart_enable(struct radeon_device *rdev) -{ - uint32_t size_reg; - uint32_t tmp; - - radeon_gart_restore(rdev); - tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH); - tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS; - WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp); - /* Check gart size */ - switch(rdev->mc.gtt_size / (1024 * 1024)) { - case 32: - size_reg = RS480_VA_SIZE_32MB; - break; - case 64: - size_reg = RS480_VA_SIZE_64MB; - break; - case 128: - size_reg = RS480_VA_SIZE_128MB; - break; - case 256: - size_reg = RS480_VA_SIZE_256MB; - break; - case 512: - size_reg = RS480_VA_SIZE_512MB; - break; - case 1024: - size_reg = RS480_VA_SIZE_1GB; - break; - case 2048: - size_reg = RS480_VA_SIZE_2GB; - break; - default: - return -EINVAL; - } - /* It should be fine to program it to max value */ - if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) { - WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF); - WREG32_MC(RS690_MCCFG_AGP_BASE_2, 0); - } else { - WREG32(RADEON_AGP_BASE, 0xFFFFFFFF); - WREG32(RS480_AGP_BASE_2, 0); - } - tmp = REG_SET(RS690_MC_AGP_TOP, rdev->mc.gtt_end >> 16); - tmp |= REG_SET(RS690_MC_AGP_START, rdev->mc.gtt_start >> 16); - if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { - WREG32_MC(RS690_MCCFG_AGP_LOCATION, tmp); - tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; - WREG32(RADEON_BUS_CNTL, tmp); - } else { - WREG32(RADEON_MC_AGP_LOCATION, tmp); - tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - WREG32(RADEON_BUS_CNTL, tmp); - } - /* Table should be in 32bits address space so ignore bits above. */ - tmp = (u32)rdev->gart.table_addr & 0xfffff000; - tmp |= (upper_32_bits(rdev->gart.table_addr) & 0xff) << 4; - - WREG32_MC(RS480_GART_BASE, tmp); - /* TODO: more tweaking here */ - WREG32_MC(RS480_GART_FEATURE_ID, - (RS480_TLB_ENABLE | - RS480_GTW_LAC_EN | RS480_1LEVEL_GART)); - /* Disable snooping */ - WREG32_MC(RS480_AGP_MODE_CNTL, - (1 << RS480_REQ_TYPE_SNOOP_SHIFT) | RS480_REQ_TYPE_SNOOP_DIS); - /* Disable AGP mode */ - /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0, - * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */ - if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { - WREG32_MC(RS480_MC_MISC_CNTL, - (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); - } else { - WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); - } - /* Enable gart */ - WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); - rs400_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void rs400_gart_disable(struct radeon_device *rdev) -{ - uint32_t tmp; - - tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH); - tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS; - WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp); - WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0); -} - -void rs400_gart_fini(struct radeon_device *rdev) -{ - radeon_gart_fini(rdev); - rs400_gart_disable(rdev); - radeon_gart_table_ram_free(rdev); -} - -#define RS400_PTE_WRITEABLE (1 << 2) -#define RS400_PTE_READABLE (1 << 3) - -int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) -{ - uint32_t entry; - u32 *gtt = rdev->gart.ptr; - - if (i < 0 || i > rdev->gart.num_gpu_pages) { - return -EINVAL; - } - - entry = (lower_32_bits(addr) & PAGE_MASK) | - ((upper_32_bits(addr) & 0xff) << 4) | - RS400_PTE_WRITEABLE | RS400_PTE_READABLE; - entry = cpu_to_le32(entry); - gtt[i] = entry; - return 0; -} - -int rs400_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32(RADEON_MC_STATUS); - if (tmp & RADEON_MC_IDLE) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -void rs400_gpu_init(struct radeon_device *rdev) -{ - /* FIXME: is this correct ? */ - r420_pipes_init(rdev); - if (rs400_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "rs400: Failed to wait MC idle while " - "programming pipes. Bad things might happen. %08x\n", RREG32(RADEON_MC_STATUS)); - } -} - -void rs400_mc_init(struct radeon_device *rdev) -{ - u64 base; - - rs400_gart_adjust_size(rdev); - rdev->mc.igp_sideport_enabled = radeon_combios_sideport_present(rdev); - /* DDR for all card after R300 & IGP */ - rdev->mc.vram_is_ddr = true; - rdev->mc.vram_width = 128; - r100_vram_init_sizes(rdev); - base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; - radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - -uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg) -{ - uint32_t r; - - WREG32(RS480_NB_MC_INDEX, reg & 0xff); - r = RREG32(RS480_NB_MC_DATA); - WREG32(RS480_NB_MC_INDEX, 0xff); - return r; -} - -void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - WREG32(RS480_NB_MC_INDEX, ((reg) & 0xff) | RS480_NB_MC_IND_WR_EN); - WREG32(RS480_NB_MC_DATA, (v)); - WREG32(RS480_NB_MC_INDEX, 0xff); -} - -#if defined(CONFIG_DEBUG_FS) -static int rs400_debugfs_gart_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - tmp = RREG32(RADEON_HOST_PATH_CNTL); - seq_printf(m, "HOST_PATH_CNTL 0x%08x\n", tmp); - tmp = RREG32(RADEON_BUS_CNTL); - seq_printf(m, "BUS_CNTL 0x%08x\n", tmp); - tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH); - seq_printf(m, "AIC_CTRL_SCRATCH 0x%08x\n", tmp); - if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) { - tmp = RREG32_MC(RS690_MCCFG_AGP_BASE); - seq_printf(m, "MCCFG_AGP_BASE 0x%08x\n", tmp); - tmp = RREG32_MC(RS690_MCCFG_AGP_BASE_2); - seq_printf(m, "MCCFG_AGP_BASE_2 0x%08x\n", tmp); - tmp = RREG32_MC(RS690_MCCFG_AGP_LOCATION); - seq_printf(m, "MCCFG_AGP_LOCATION 0x%08x\n", tmp); - tmp = RREG32_MC(RS690_MCCFG_FB_LOCATION); - seq_printf(m, "MCCFG_FB_LOCATION 0x%08x\n", tmp); - tmp = RREG32(RS690_HDP_FB_LOCATION); - seq_printf(m, "HDP_FB_LOCATION 0x%08x\n", tmp); - } else { - tmp = RREG32(RADEON_AGP_BASE); - seq_printf(m, "AGP_BASE 0x%08x\n", tmp); - tmp = RREG32(RS480_AGP_BASE_2); - seq_printf(m, "AGP_BASE_2 0x%08x\n", tmp); - tmp = RREG32(RADEON_MC_AGP_LOCATION); - seq_printf(m, "MC_AGP_LOCATION 0x%08x\n", tmp); - } - tmp = RREG32_MC(RS480_GART_BASE); - seq_printf(m, "GART_BASE 0x%08x\n", tmp); - tmp = RREG32_MC(RS480_GART_FEATURE_ID); - seq_printf(m, "GART_FEATURE_ID 0x%08x\n", tmp); - tmp = RREG32_MC(RS480_AGP_MODE_CNTL); - seq_printf(m, "AGP_MODE_CONTROL 0x%08x\n", tmp); - tmp = RREG32_MC(RS480_MC_MISC_CNTL); - seq_printf(m, "MC_MISC_CNTL 0x%08x\n", tmp); - tmp = RREG32_MC(0x5F); - seq_printf(m, "MC_MISC_UMA_CNTL 0x%08x\n", tmp); - tmp = RREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE); - seq_printf(m, "AGP_ADDRESS_SPACE_SIZE 0x%08x\n", tmp); - tmp = RREG32_MC(RS480_GART_CACHE_CNTRL); - seq_printf(m, "GART_CACHE_CNTRL 0x%08x\n", tmp); - tmp = RREG32_MC(0x3B); - seq_printf(m, "MC_GART_ERROR_ADDRESS 0x%08x\n", tmp); - tmp = RREG32_MC(0x3C); - seq_printf(m, "MC_GART_ERROR_ADDRESS_HI 0x%08x\n", tmp); - tmp = RREG32_MC(0x30); - seq_printf(m, "GART_ERROR_0 0x%08x\n", tmp); - tmp = RREG32_MC(0x31); - seq_printf(m, "GART_ERROR_1 0x%08x\n", tmp); - tmp = RREG32_MC(0x32); - seq_printf(m, "GART_ERROR_2 0x%08x\n", tmp); - tmp = RREG32_MC(0x33); - seq_printf(m, "GART_ERROR_3 0x%08x\n", tmp); - tmp = RREG32_MC(0x34); - seq_printf(m, "GART_ERROR_4 0x%08x\n", tmp); - tmp = RREG32_MC(0x35); - seq_printf(m, "GART_ERROR_5 0x%08x\n", tmp); - tmp = RREG32_MC(0x36); - seq_printf(m, "GART_ERROR_6 0x%08x\n", tmp); - tmp = RREG32_MC(0x37); - seq_printf(m, "GART_ERROR_7 0x%08x\n", tmp); - return 0; -} - -static struct drm_info_list rs400_gart_info_list[] = { - {"rs400_gart_info", rs400_debugfs_gart_info, 0, NULL}, -}; -#endif - -static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, rs400_gart_info_list, 1); -#else - return 0; -#endif -} - -void rs400_mc_program(struct radeon_device *rdev) -{ - struct r100_mc_save save; - - /* Stops all mc clients */ - r100_mc_stop(rdev, &save); - - /* Wait for mc idle */ - if (rs400_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n"); - WREG32(R_000148_MC_FB_LOCATION, - S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); - - r100_mc_resume(rdev, &save); -} - -static int rs400_startup(struct radeon_device *rdev) -{ - int r; - - r100_set_common_regs(rdev); - - rs400_mc_program(rdev); - /* Resume clock */ - r300_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ - rs400_gpu_init(rdev); - r100_enable_bm(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - r = rs400_gart_enable(rdev); - if (r) - return r; - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r100_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int rs400_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - rs400_gart_disable(rdev); - /* Resume clock before doing reset */ - r300_clock_startup(rdev); - /* setup MC before calling post tables */ - rs400_mc_program(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - radeon_combios_asic_init(rdev->ddev); - /* Resume clock after posting */ - r300_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = rs400_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int rs400_suspend(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - r100_irq_disable(rdev); - rs400_gart_disable(rdev); - return 0; -} - -void rs400_fini(struct radeon_device *rdev) -{ - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - rs400_gart_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -int rs400_init(struct radeon_device *rdev) -{ - int r; - - /* Disable VGA */ - r100_vga_render_disable(rdev); - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* TODO: disable VGA need to use VGA request */ - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); - return -EINVAL; - } else { - r = radeon_combios_init(rdev); - if (r) - return r; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize memory controller */ - rs400_mc_init(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - r = rs400_gart_init(rdev); - if (r) - return r; - r300_set_reg_safe(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = rs400_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - rs400_gart_fini(rdev); - radeon_irq_kms_fini(rdev); - rdev->accel_working = false; - } - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400d.h deleted file mode 100644 index 6d8bac58..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs400d.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RS400D_H__ -#define __RS400D_H__ - -/* Registers */ -#define R_000148_MC_FB_LOCATION 0x000148 -#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000148_MC_FB_START 0xFFFF0000 -#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000148_MC_FB_TOP 0x0000FFFF -#define R_00015C_NB_TOM 0x00015C -#define S_00015C_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_00015C_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_00015C_MC_FB_START 0xFFFF0000 -#define S_00015C_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_00015C_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_00015C_MC_FB_TOP 0x0000FFFF -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600.c deleted file mode 100644 index d25cf869..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -/* RS600 / Radeon X1250/X1270 integrated GPU - * - * This file gather function specific to RS600 which is the IGP of - * the X1250/X1270 family supporting intel CPU (while RS690/RS740 - * is the X1250/X1270 supporting AMD CPU). The display engine are - * the avivo one, bios is an atombios, 3D block are the one of the - * R4XX family. The GART is different from the RS400 one and is very - * close to the one of the R600 family (R600 likely being an evolution - * of the RS600 GART block). - */ -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" -#include "rs600d.h" - -#include "rs600_reg_safe.h" - -void rs600_gpu_init(struct radeon_device *rdev); -int rs600_mc_wait_for_idle(struct radeon_device *rdev); - -void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - int i; - - if (RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset) & AVIVO_CRTC_EN) { - for (i = 0; i < rdev->usec_timeout; i++) { - if (!(RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK)) - break; - udelay(1); - } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(AVIVO_D1CRTC_STATUS + radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK) - break; - udelay(1); - } - } -} - -void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) -{ - /* enable the pflip int */ - radeon_irq_kms_pflip_irq_get(rdev, crtc); -} - -void rs600_post_page_flip(struct radeon_device *rdev, int crtc) -{ - /* disable the pflip int */ - radeon_irq_kms_pflip_irq_put(rdev, crtc); -} - -u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; - u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); - int i; - - /* Lock the graphics update lock */ - tmp |= AVIVO_D1GRPH_UPDATE_LOCK; - WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); - - /* update the scanout addresses */ - WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)crtc_base); - WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)crtc_base); - - /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) - break; - udelay(1); - } - DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); - - /* Unlock the lock, so double-buffering can take place inside vblank */ - tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; - WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); - - /* Return current update_pending status: */ - return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; -} - -void rs600_pm_misc(struct radeon_device *rdev) -{ - int requested_index = rdev->pm.requested_power_state_index; - struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; - struct radeon_voltage *voltage = &ps->clock_info[0].voltage; - u32 tmp, dyn_pwrmgt_sclk_length, dyn_sclk_vol_cntl; - u32 hdp_dyn_cntl, /*mc_host_dyn_cntl,*/ dyn_backbias_cntl; - - if ((voltage->type == VOLTAGE_GPIO) && (voltage->gpio.valid)) { - if (ps->misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp |= voltage->gpio.mask; - else - tmp &= ~(voltage->gpio.mask); - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } else { - tmp = RREG32(voltage->gpio.reg); - if (voltage->active_high) - tmp &= ~voltage->gpio.mask; - else - tmp |= voltage->gpio.mask; - WREG32(voltage->gpio.reg, tmp); - if (voltage->delay) - udelay(voltage->delay); - } - } else if (voltage->type == VOLTAGE_VDDC) - radeon_atom_set_voltage(rdev, voltage->vddc_id, SET_VOLTAGE_TYPE_ASIC_VDDC); - - dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); - dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); - dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_LOLEN(0xf); - if (ps->misc & ATOM_PM_MISCINFO_ASIC_REDUCED_SPEED_SCLK_EN) { - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_2) { - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(2); - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(2); - } else if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_CLOCK_DIVIDER_BY_4) { - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(4); - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(4); - } - } else { - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_HILEN(1); - dyn_pwrmgt_sclk_length |= REDUCED_POWER_SCLK_LOLEN(1); - } - WREG32_PLL(DYN_PWRMGT_SCLK_LENGTH, dyn_pwrmgt_sclk_length); - - dyn_sclk_vol_cntl = RREG32_PLL(DYN_SCLK_VOL_CNTL); - if (ps->misc & ATOM_PM_MISCINFO_ASIC_DYNAMIC_VOLTAGE_EN) { - dyn_sclk_vol_cntl |= IO_CG_VOLTAGE_DROP; - if (voltage->delay) { - dyn_sclk_vol_cntl |= VOLTAGE_DROP_SYNC; - dyn_sclk_vol_cntl |= VOLTAGE_DELAY_SEL(voltage->delay); - } else - dyn_sclk_vol_cntl &= ~VOLTAGE_DROP_SYNC; - } else - dyn_sclk_vol_cntl &= ~IO_CG_VOLTAGE_DROP; - WREG32_PLL(DYN_SCLK_VOL_CNTL, dyn_sclk_vol_cntl); - - hdp_dyn_cntl = RREG32_PLL(HDP_DYN_CNTL); - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_HDP_BLOCK_EN) - hdp_dyn_cntl &= ~HDP_FORCEON; - else - hdp_dyn_cntl |= HDP_FORCEON; - WREG32_PLL(HDP_DYN_CNTL, hdp_dyn_cntl); -#if 0 - /* mc_host_dyn seems to cause hangs from time to time */ - mc_host_dyn_cntl = RREG32_PLL(MC_HOST_DYN_CNTL); - if (ps->misc & ATOM_PM_MISCINFO_DYNAMIC_MC_HOST_BLOCK_EN) - mc_host_dyn_cntl &= ~MC_HOST_FORCEON; - else - mc_host_dyn_cntl |= MC_HOST_FORCEON; - WREG32_PLL(MC_HOST_DYN_CNTL, mc_host_dyn_cntl); -#endif - dyn_backbias_cntl = RREG32_PLL(DYN_BACKBIAS_CNTL); - if (ps->misc & ATOM_PM_MISCINFO2_DYNAMIC_BACK_BIAS_EN) - dyn_backbias_cntl |= IO_CG_BACKBIAS_EN; - else - dyn_backbias_cntl &= ~IO_CG_BACKBIAS_EN; - WREG32_PLL(DYN_BACKBIAS_CNTL, dyn_backbias_cntl); - - /* set pcie lanes */ - if ((rdev->flags & RADEON_IS_PCIE) && - !(rdev->flags & RADEON_IS_IGP) && - rdev->asic->pm.set_pcie_lanes && - (ps->pcie_lanes != - rdev->pm.power_state[rdev->pm.current_power_state_index].pcie_lanes)) { - radeon_set_pcie_lanes(rdev, - ps->pcie_lanes); - DRM_DEBUG("Setting: p: %d\n", ps->pcie_lanes); - } -} - -void rs600_pm_prepare(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* disable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - -void rs600_pm_finish(struct radeon_device *rdev) -{ - struct drm_device *ddev = rdev->ddev; - struct drm_crtc *crtc; - struct radeon_crtc *radeon_crtc; - u32 tmp; - - /* enable any active CRTCs */ - list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - tmp = RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; - WREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); - } - } -} - -/* hpd for digital panel detect/disconnect */ -bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) -{ - u32 tmp; - bool connected = false; - - switch (hpd) { - case RADEON_HPD_1: - tmp = RREG32(R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS); - if (G_007D04_DC_HOT_PLUG_DETECT1_SENSE(tmp)) - connected = true; - break; - case RADEON_HPD_2: - tmp = RREG32(R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS); - if (G_007D14_DC_HOT_PLUG_DETECT2_SENSE(tmp)) - connected = true; - break; - default: - break; - } - return connected; -} - -void rs600_hpd_set_polarity(struct radeon_device *rdev, - enum radeon_hpd_id hpd) -{ - u32 tmp; - bool connected = rs600_hpd_sense(rdev, hpd); - - switch (hpd) { - case RADEON_HPD_1: - tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); - if (connected) - tmp &= ~S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); - else - tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(1); - WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); - break; - case RADEON_HPD_2: - tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); - if (connected) - tmp &= ~S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); - else - tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(1); - WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); - break; - default: - break; - } -} - -void rs600_hpd_init(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, - S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); - rdev->irq.hpd[0] = true; - break; - case RADEON_HPD_2: - WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, - S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); - rdev->irq.hpd[1] = true; - break; - default: - break; - } - radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); - } - if (rdev->irq.installed) - rs600_irq_set(rdev); -} - -void rs600_hpd_fini(struct radeon_device *rdev) -{ - struct drm_device *dev = rdev->ddev; - struct drm_connector *connector; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - switch (radeon_connector->hpd.hpd) { - case RADEON_HPD_1: - WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, - S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); - rdev->irq.hpd[0] = false; - break; - case RADEON_HPD_2: - WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, - S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); - rdev->irq.hpd[1] = false; - break; - default: - break; - } - } -} - -int rs600_asic_reset(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - u32 status, tmp; - int ret = 0; - - status = RREG32(R_000E40_RBBM_STATUS); - if (!G_000E40_GUI_ACTIVE(status)) { - return 0; - } - /* Stops all mc clients */ - rv515_mc_stop(rdev, &save); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* stop CP */ - WREG32(RADEON_CP_CSQ_CNTL, 0); - tmp = RREG32(RADEON_CP_RB_CNTL); - WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); - WREG32(RADEON_CP_RB_RPTR_WR, 0); - WREG32(RADEON_CP_RB_WPTR, 0); - WREG32(RADEON_CP_RB_CNTL, tmp); - pci_save_state(rdev->pdev); - /* disable bus mastering */ - pci_clear_master(rdev->pdev); - mdelay(1); - /* reset GA+VAP */ - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | - S_0000F0_SOFT_RESET_GA(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* reset CP */ - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* reset MC */ - WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_MC(1)); - RREG32(R_0000F0_RBBM_SOFT_RESET); - mdelay(500); - WREG32(R_0000F0_RBBM_SOFT_RESET, 0); - mdelay(1); - status = RREG32(R_000E40_RBBM_STATUS); - dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); - /* restore PCI & busmastering */ - pci_restore_state(rdev->pdev); - /* Check if GPU is idle */ - if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { - dev_err(rdev->dev, "failed to reset GPU\n"); - rdev->gpu_lockup = true; - ret = -1; - } else - dev_info(rdev->dev, "GPU reset succeed\n"); - rv515_mc_resume(rdev, &save); - return ret; -} - -/* - * GART. - */ -void rs600_gart_tlb_flush(struct radeon_device *rdev) -{ - uint32_t tmp; - - tmp = RREG32_MC(R_000100_MC_PT0_CNTL); - tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE; - WREG32_MC(R_000100_MC_PT0_CNTL, tmp); - - tmp = RREG32_MC(R_000100_MC_PT0_CNTL); - tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1); - WREG32_MC(R_000100_MC_PT0_CNTL, tmp); - - tmp = RREG32_MC(R_000100_MC_PT0_CNTL); - tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE; - WREG32_MC(R_000100_MC_PT0_CNTL, tmp); - tmp = RREG32_MC(R_000100_MC_PT0_CNTL); -} - -int rs600_gart_init(struct radeon_device *rdev) -{ - int r; - - if (rdev->gart.robj) { - WARN(1, "RS600 GART already initialized\n"); - return 0; - } - /* Initialize common gart structure */ - r = radeon_gart_init(rdev); - if (r) { - return r; - } - rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; - return radeon_gart_table_vram_alloc(rdev); -} - -static int rs600_gart_enable(struct radeon_device *rdev) -{ - u32 tmp; - int r, i; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - /* Enable bus master */ - tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; - WREG32(RADEON_BUS_CNTL, tmp); - /* FIXME: setup default page */ - WREG32_MC(R_000100_MC_PT0_CNTL, - (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | - S_000100_EFFECTIVE_L2_QUEUE_SIZE(6))); - - for (i = 0; i < 19; i++) { - WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i, - S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) | - S_00016C_SYSTEM_ACCESS_MODE_MASK( - V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS) | - S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS( - V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH) | - S_00016C_EFFECTIVE_L1_CACHE_SIZE(3) | - S_00016C_ENABLE_FRAGMENT_PROCESSING(1) | - S_00016C_EFFECTIVE_L1_QUEUE_SIZE(3)); - } - /* enable first context */ - WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL, - S_000102_ENABLE_PAGE_TABLE(1) | - S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT)); - - /* disable all other contexts */ - for (i = 1; i < 8; i++) - WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0); - - /* setup the page table */ - WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, - rdev->gart.table_addr); - WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start); - WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end); - WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); - - /* System context maps to VRAM space */ - WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start); - WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end); - - /* enable page tables */ - tmp = RREG32_MC(R_000100_MC_PT0_CNTL); - WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1))); - tmp = RREG32_MC(R_000009_MC_CNTL1); - WREG32_MC(R_000009_MC_CNTL1, (tmp | S_000009_ENABLE_PAGE_TABLES(1))); - rs600_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void rs600_gart_disable(struct radeon_device *rdev) -{ - u32 tmp; - - /* FIXME: disable out of gart access */ - WREG32_MC(R_000100_MC_PT0_CNTL, 0); - tmp = RREG32_MC(R_000009_MC_CNTL1); - WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); - radeon_gart_table_vram_unpin(rdev); -} - -void rs600_gart_fini(struct radeon_device *rdev) -{ - radeon_gart_fini(rdev); - rs600_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); -} - -#define R600_PTE_VALID (1 << 0) -#define R600_PTE_SYSTEM (1 << 1) -#define R600_PTE_SNOOPED (1 << 2) -#define R600_PTE_READABLE (1 << 5) -#define R600_PTE_WRITEABLE (1 << 6) - -int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) -{ - void __iomem *ptr = (void *)rdev->gart.ptr; - - if (i < 0 || i > rdev->gart.num_gpu_pages) { - return -EINVAL; - } - addr = addr & 0xFFFFFFFFFFFFF000ULL; - addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; - addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE; - writeq(addr, ptr + (i * 8)); - return 0; -} - -int rs600_irq_set(struct radeon_device *rdev) -{ - uint32_t tmp = 0; - uint32_t mode_int = 0; - u32 hpd1 = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL) & - ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); - u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & - ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); - - if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); - WREG32(R_000040_GEN_INT_CNTL, 0); - return -EINVAL; - } - if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { - tmp |= S_000040_SW_INT_EN(1); - } - if (rdev->irq.gui_idle) { - tmp |= S_000040_GUI_IDLE(1); - } - if (rdev->irq.crtc_vblank_int[0] || - rdev->irq.pflip[0]) { - mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); - } - if (rdev->irq.crtc_vblank_int[1] || - rdev->irq.pflip[1]) { - mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); - } - if (rdev->irq.hpd[0]) { - hpd1 |= S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); - } - if (rdev->irq.hpd[1]) { - hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); - } - WREG32(R_000040_GEN_INT_CNTL, tmp); - WREG32(R_006540_DxMODE_INT_MASK, mode_int); - WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); - WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); - return 0; -} - -static inline u32 rs600_irq_ack(struct radeon_device *rdev) -{ - uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); - uint32_t irq_mask = S_000044_SW_INT(1); - u32 tmp; - - /* the interrupt works, but the status bit is permanently asserted */ - if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { - if (!rdev->irq.gui_idle_acked) - irq_mask |= S_000044_GUI_IDLE_STAT(1); - } - - if (G_000044_DISPLAY_INT_STAT(irqs)) { - rdev->irq.stat_regs.r500.disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); - if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - WREG32(R_006534_D1MODE_VBLANK_STATUS, - S_006534_D1MODE_VBLANK_ACK(1)); - } - if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - WREG32(R_006D34_D2MODE_VBLANK_STATUS, - S_006D34_D2MODE_VBLANK_ACK(1)); - } - if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); - tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); - WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); - } - if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); - tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); - WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); - } - } else { - rdev->irq.stat_regs.r500.disp_int = 0; - } - - if (irqs) { - WREG32(R_000044_GEN_INT_STATUS, irqs); - } - return irqs & irq_mask; -} - -void rs600_irq_disable(struct radeon_device *rdev) -{ - WREG32(R_000040_GEN_INT_CNTL, 0); - WREG32(R_006540_DxMODE_INT_MASK, 0); - /* Wait and acknowledge irq */ - mdelay(1); - rs600_irq_ack(rdev); -} - -int rs600_irq_process(struct radeon_device *rdev) -{ - u32 status, msi_rearm; - bool queue_hotplug = false; - - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; - - status = rs600_irq_ack(rdev); - if (!status && !rdev->irq.stat_regs.r500.disp_int) { - return IRQ_NONE; - } - while (status || rdev->irq.stat_regs.r500.disp_int) { - /* SW interrupt */ - if (G_000044_SW_INT(status)) { - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - } - /* GUI idle */ - if (G_000040_GUI_IDLE(status)) { - rdev->irq.gui_idle_acked = true; - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - } - /* Vertical blank interrupts */ - if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); - } - if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); - } - if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - queue_hotplug = true; - DRM_DEBUG("HPD1\n"); - } - if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - queue_hotplug = true; - DRM_DEBUG("HPD2\n"); - } - status = rs600_irq_ack(rdev); - } - /* reset gui idle ack. the status bit is broken */ - rdev->irq.gui_idle_acked = false; - if (queue_hotplug) - schedule_work(&rdev->hotplug_work); - if (rdev->msi_enabled) { - switch (rdev->family) { - case CHIP_RS600: - case CHIP_RS690: - case CHIP_RS740: - msi_rearm = RREG32(RADEON_BUS_CNTL) & ~RS600_MSI_REARM; - WREG32(RADEON_BUS_CNTL, msi_rearm); - WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); - break; - default: - WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); - break; - } - } - return IRQ_HANDLED; -} - -u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc) -{ - if (crtc == 0) - return RREG32(R_0060A4_D1CRTC_STATUS_FRAME_COUNT); - else - return RREG32(R_0068A4_D2CRTC_STATUS_FRAME_COUNT); -} - -int rs600_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - - for (i = 0; i < rdev->usec_timeout; i++) { - if (G_000000_MC_IDLE(RREG32_MC(R_000000_MC_STATUS))) - return 0; - udelay(1); - } - return -1; -} - -void rs600_gpu_init(struct radeon_device *rdev) -{ - r420_pipes_init(rdev); - /* Wait for mc idle */ - if (rs600_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); -} - -void rs600_mc_init(struct radeon_device *rdev) -{ - u64 base; - - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - rdev->mc.vram_is_ddr = true; - rdev->mc.vram_width = 128; - rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); - rdev->mc.mc_vram_size = rdev->mc.real_vram_size; - rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - base = RREG32_MC(R_000004_MC_FB_LOCATION); - base = G_000004_MC_FB_START(base) << 16; - radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - -void rs600_bandwidth_update(struct radeon_device *rdev) -{ - struct drm_display_mode *mode0 = NULL; - struct drm_display_mode *mode1 = NULL; - u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt; - /* FIXME: implement full support */ - - radeon_update_display_priority(rdev); - - if (rdev->mode_info.crtcs[0]->base.enabled) - mode0 = &rdev->mode_info.crtcs[0]->base.mode; - if (rdev->mode_info.crtcs[1]->base.enabled) - mode1 = &rdev->mode_info.crtcs[1]->base.mode; - - rs690_line_buffer_adjust(rdev, mode0, mode1); - - if (rdev->disp_priority == 2) { - d1mode_priority_a_cnt = RREG32(R_006548_D1MODE_PRIORITY_A_CNT); - d2mode_priority_a_cnt = RREG32(R_006D48_D2MODE_PRIORITY_A_CNT); - d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); - d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); - WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); - } -} - -uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) -{ - WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) | - S_000070_MC_IND_CITF_ARB0(1)); - return RREG32(R_000074_MC_IND_DATA); -} - -void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) | - S_000070_MC_IND_CITF_ARB0(1) | S_000070_MC_IND_WR_EN(1)); - WREG32(R_000074_MC_IND_DATA, v); -} - -void rs600_debugfs(struct radeon_device *rdev) -{ - if (r100_debugfs_rbbm_init(rdev)) - DRM_ERROR("Failed to register debugfs file for RBBM !\n"); -} - -void rs600_set_safe_registers(struct radeon_device *rdev) -{ - rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm; - rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm); -} - -static void rs600_mc_program(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - - /* Stops all mc clients */ - rv515_mc_stop(rdev, &save); - - /* Wait for mc idle */ - if (rs600_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); - - /* FIXME: What does AGP means for such chipset ? */ - WREG32_MC(R_000005_MC_AGP_LOCATION, 0x0FFFFFFF); - WREG32_MC(R_000006_AGP_BASE, 0); - WREG32_MC(R_000007_AGP_BASE_2, 0); - /* Program MC */ - WREG32_MC(R_000004_MC_FB_LOCATION, - S_000004_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16)); - WREG32(R_000134_HDP_FB_LOCATION, - S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); - - rv515_mc_resume(rdev, &save); -} - -static int rs600_startup(struct radeon_device *rdev) -{ - int r; - - rs600_mc_program(rdev); - /* Resume clock */ - rv515_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ - rs600_gpu_init(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - r = rs600_gart_enable(rdev); - if (r) - return r; - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - rs600_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int rs600_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - rs600_gart_disable(rdev); - /* Resume clock before doing reset */ - rv515_clock_startup(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - atom_asic_init(rdev->mode_info.atom_context); - /* Resume clock after posting */ - rv515_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = rs600_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int rs600_suspend(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - r600_audio_fini(rdev); - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - rs600_irq_disable(rdev); - rs600_gart_disable(rdev); - return 0; -} - -void rs600_fini(struct radeon_device *rdev) -{ - r600_audio_fini(rdev); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - rs600_gart_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -int rs600_init(struct radeon_device *rdev) -{ - int r; - - /* Disable VGA */ - rv515_vga_render_disable(rdev); - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* BIOS */ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - r = radeon_atombios_init(rdev); - if (r) - return r; - } else { - dev_err(rdev->dev, "Expecting atombios for RS600 GPU\n"); - return -EINVAL; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize memory controller */ - rs600_mc_init(rdev); - rs600_debugfs(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - r = rs600_gart_init(rdev); - if (r) - return r; - rs600_set_safe_registers(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = rs600_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - rs600_gart_fini(rdev); - radeon_irq_kms_fini(rdev); - rdev->accel_working = false; - } - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600d.h deleted file mode 100644 index a27c13ac..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs600d.h +++ /dev/null @@ -1,671 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RS600D_H__ -#define __RS600D_H__ - -/* Registers */ -#define R_000040_GEN_INT_CNTL 0x000040 -#define S_000040_SCRATCH_INT_MASK(x) (((x) & 0x1) << 18) -#define G_000040_SCRATCH_INT_MASK(x) (((x) >> 18) & 0x1) -#define C_000040_SCRATCH_INT_MASK 0xFFFBFFFF -#define S_000040_GUI_IDLE_MASK(x) (((x) & 0x1) << 19) -#define G_000040_GUI_IDLE_MASK(x) (((x) >> 19) & 0x1) -#define C_000040_GUI_IDLE_MASK 0xFFF7FFFF -#define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13) -#define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1) -#define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF -#define S_000040_DMA_VIPH2_INT_EN(x) (((x) & 0x1) << 14) -#define G_000040_DMA_VIPH2_INT_EN(x) (((x) >> 14) & 0x1) -#define C_000040_DMA_VIPH2_INT_EN 0xFFFFBFFF -#define S_000040_DMA_VIPH3_INT_EN(x) (((x) & 0x1) << 15) -#define G_000040_DMA_VIPH3_INT_EN(x) (((x) >> 15) & 0x1) -#define C_000040_DMA_VIPH3_INT_EN 0xFFFF7FFF -#define S_000040_I2C_INT_EN(x) (((x) & 0x1) << 17) -#define G_000040_I2C_INT_EN(x) (((x) >> 17) & 0x1) -#define C_000040_I2C_INT_EN 0xFFFDFFFF -#define S_000040_GUI_IDLE(x) (((x) & 0x1) << 19) -#define G_000040_GUI_IDLE(x) (((x) >> 19) & 0x1) -#define C_000040_GUI_IDLE 0xFFF7FFFF -#define S_000040_VIPH_INT_EN(x) (((x) & 0x1) << 24) -#define G_000040_VIPH_INT_EN(x) (((x) >> 24) & 0x1) -#define C_000040_VIPH_INT_EN 0xFEFFFFFF -#define S_000040_SW_INT_EN(x) (((x) & 0x1) << 25) -#define G_000040_SW_INT_EN(x) (((x) >> 25) & 0x1) -#define C_000040_SW_INT_EN 0xFDFFFFFF -#define S_000040_GEYSERVILLE(x) (((x) & 0x1) << 27) -#define G_000040_GEYSERVILLE(x) (((x) >> 27) & 0x1) -#define C_000040_GEYSERVILLE 0xF7FFFFFF -#define S_000040_HDCP_AUTHORIZED_INT(x) (((x) & 0x1) << 28) -#define G_000040_HDCP_AUTHORIZED_INT(x) (((x) >> 28) & 0x1) -#define C_000040_HDCP_AUTHORIZED_INT 0xEFFFFFFF -#define S_000040_DVI_I2C_INT(x) (((x) & 0x1) << 29) -#define G_000040_DVI_I2C_INT(x) (((x) >> 29) & 0x1) -#define C_000040_DVI_I2C_INT 0xDFFFFFFF -#define S_000040_GUIDMA(x) (((x) & 0x1) << 30) -#define G_000040_GUIDMA(x) (((x) >> 30) & 0x1) -#define C_000040_GUIDMA 0xBFFFFFFF -#define S_000040_VIDDMA(x) (((x) & 0x1) << 31) -#define G_000040_VIDDMA(x) (((x) >> 31) & 0x1) -#define C_000040_VIDDMA 0x7FFFFFFF -#define R_000044_GEN_INT_STATUS 0x000044 -#define S_000044_DISPLAY_INT_STAT(x) (((x) & 0x1) << 0) -#define G_000044_DISPLAY_INT_STAT(x) (((x) >> 0) & 0x1) -#define C_000044_DISPLAY_INT_STAT 0xFFFFFFFE -#define S_000044_VGA_INT_STAT(x) (((x) & 0x1) << 1) -#define G_000044_VGA_INT_STAT(x) (((x) >> 1) & 0x1) -#define C_000044_VGA_INT_STAT 0xFFFFFFFD -#define S_000044_CAP0_INT_ACTIVE(x) (((x) & 0x1) << 8) -#define G_000044_CAP0_INT_ACTIVE(x) (((x) >> 8) & 0x1) -#define C_000044_CAP0_INT_ACTIVE 0xFFFFFEFF -#define S_000044_DMA_VIPH0_INT(x) (((x) & 0x1) << 12) -#define G_000044_DMA_VIPH0_INT(x) (((x) >> 12) & 0x1) -#define C_000044_DMA_VIPH0_INT 0xFFFFEFFF -#define S_000044_DMA_VIPH1_INT(x) (((x) & 0x1) << 13) -#define G_000044_DMA_VIPH1_INT(x) (((x) >> 13) & 0x1) -#define C_000044_DMA_VIPH1_INT 0xFFFFDFFF -#define S_000044_DMA_VIPH2_INT(x) (((x) & 0x1) << 14) -#define G_000044_DMA_VIPH2_INT(x) (((x) >> 14) & 0x1) -#define C_000044_DMA_VIPH2_INT 0xFFFFBFFF -#define S_000044_DMA_VIPH3_INT(x) (((x) & 0x1) << 15) -#define G_000044_DMA_VIPH3_INT(x) (((x) >> 15) & 0x1) -#define C_000044_DMA_VIPH3_INT 0xFFFF7FFF -#define S_000044_MC_PROBE_FAULT_STAT(x) (((x) & 0x1) << 16) -#define G_000044_MC_PROBE_FAULT_STAT(x) (((x) >> 16) & 0x1) -#define C_000044_MC_PROBE_FAULT_STAT 0xFFFEFFFF -#define S_000044_I2C_INT(x) (((x) & 0x1) << 17) -#define G_000044_I2C_INT(x) (((x) >> 17) & 0x1) -#define C_000044_I2C_INT 0xFFFDFFFF -#define S_000044_SCRATCH_INT_STAT(x) (((x) & 0x1) << 18) -#define G_000044_SCRATCH_INT_STAT(x) (((x) >> 18) & 0x1) -#define C_000044_SCRATCH_INT_STAT 0xFFFBFFFF -#define S_000044_GUI_IDLE_STAT(x) (((x) & 0x1) << 19) -#define G_000044_GUI_IDLE_STAT(x) (((x) >> 19) & 0x1) -#define C_000044_GUI_IDLE_STAT 0xFFF7FFFF -#define S_000044_ATI_OVERDRIVE_INT_STAT(x) (((x) & 0x1) << 20) -#define G_000044_ATI_OVERDRIVE_INT_STAT(x) (((x) >> 20) & 0x1) -#define C_000044_ATI_OVERDRIVE_INT_STAT 0xFFEFFFFF -#define S_000044_MC_PROTECTION_FAULT_STAT(x) (((x) & 0x1) << 21) -#define G_000044_MC_PROTECTION_FAULT_STAT(x) (((x) >> 21) & 0x1) -#define C_000044_MC_PROTECTION_FAULT_STAT 0xFFDFFFFF -#define S_000044_RBBM_READ_INT_STAT(x) (((x) & 0x1) << 22) -#define G_000044_RBBM_READ_INT_STAT(x) (((x) >> 22) & 0x1) -#define C_000044_RBBM_READ_INT_STAT 0xFFBFFFFF -#define S_000044_CB_CONTEXT_SWITCH_STAT(x) (((x) & 0x1) << 23) -#define G_000044_CB_CONTEXT_SWITCH_STAT(x) (((x) >> 23) & 0x1) -#define C_000044_CB_CONTEXT_SWITCH_STAT 0xFF7FFFFF -#define S_000044_VIPH_INT(x) (((x) & 0x1) << 24) -#define G_000044_VIPH_INT(x) (((x) >> 24) & 0x1) -#define C_000044_VIPH_INT 0xFEFFFFFF -#define S_000044_SW_INT(x) (((x) & 0x1) << 25) -#define G_000044_SW_INT(x) (((x) >> 25) & 0x1) -#define C_000044_SW_INT 0xFDFFFFFF -#define S_000044_SW_INT_SET(x) (((x) & 0x1) << 26) -#define G_000044_SW_INT_SET(x) (((x) >> 26) & 0x1) -#define C_000044_SW_INT_SET 0xFBFFFFFF -#define S_000044_IDCT_INT_STAT(x) (((x) & 0x1) << 27) -#define G_000044_IDCT_INT_STAT(x) (((x) >> 27) & 0x1) -#define C_000044_IDCT_INT_STAT 0xF7FFFFFF -#define S_000044_GUIDMA_STAT(x) (((x) & 0x1) << 30) -#define G_000044_GUIDMA_STAT(x) (((x) >> 30) & 0x1) -#define C_000044_GUIDMA_STAT 0xBFFFFFFF -#define S_000044_VIDDMA_STAT(x) (((x) & 0x1) << 31) -#define G_000044_VIDDMA_STAT(x) (((x) >> 31) & 0x1) -#define C_000044_VIDDMA_STAT 0x7FFFFFFF -#define R_00004C_BUS_CNTL 0x00004C -#define S_00004C_BUS_MASTER_DIS(x) (((x) & 0x1) << 14) -#define G_00004C_BUS_MASTER_DIS(x) (((x) >> 14) & 0x1) -#define C_00004C_BUS_MASTER_DIS 0xFFFFBFFF -#define S_00004C_BUS_MSI_REARM(x) (((x) & 0x1) << 20) -#define G_00004C_BUS_MSI_REARM(x) (((x) >> 20) & 0x1) -#define C_00004C_BUS_MSI_REARM 0xFFEFFFFF -#define R_000070_MC_IND_INDEX 0x000070 -#define S_000070_MC_IND_ADDR(x) (((x) & 0xFFFF) << 0) -#define G_000070_MC_IND_ADDR(x) (((x) >> 0) & 0xFFFF) -#define C_000070_MC_IND_ADDR 0xFFFF0000 -#define S_000070_MC_IND_SEQ_RBS_0(x) (((x) & 0x1) << 16) -#define G_000070_MC_IND_SEQ_RBS_0(x) (((x) >> 16) & 0x1) -#define C_000070_MC_IND_SEQ_RBS_0 0xFFFEFFFF -#define S_000070_MC_IND_SEQ_RBS_1(x) (((x) & 0x1) << 17) -#define G_000070_MC_IND_SEQ_RBS_1(x) (((x) >> 17) & 0x1) -#define C_000070_MC_IND_SEQ_RBS_1 0xFFFDFFFF -#define S_000070_MC_IND_SEQ_RBS_2(x) (((x) & 0x1) << 18) -#define G_000070_MC_IND_SEQ_RBS_2(x) (((x) >> 18) & 0x1) -#define C_000070_MC_IND_SEQ_RBS_2 0xFFFBFFFF -#define S_000070_MC_IND_SEQ_RBS_3(x) (((x) & 0x1) << 19) -#define G_000070_MC_IND_SEQ_RBS_3(x) (((x) >> 19) & 0x1) -#define C_000070_MC_IND_SEQ_RBS_3 0xFFF7FFFF -#define S_000070_MC_IND_AIC_RBS(x) (((x) & 0x1) << 20) -#define G_000070_MC_IND_AIC_RBS(x) (((x) >> 20) & 0x1) -#define C_000070_MC_IND_AIC_RBS 0xFFEFFFFF -#define S_000070_MC_IND_CITF_ARB0(x) (((x) & 0x1) << 21) -#define G_000070_MC_IND_CITF_ARB0(x) (((x) >> 21) & 0x1) -#define C_000070_MC_IND_CITF_ARB0 0xFFDFFFFF -#define S_000070_MC_IND_CITF_ARB1(x) (((x) & 0x1) << 22) -#define G_000070_MC_IND_CITF_ARB1(x) (((x) >> 22) & 0x1) -#define C_000070_MC_IND_CITF_ARB1 0xFFBFFFFF -#define S_000070_MC_IND_WR_EN(x) (((x) & 0x1) << 23) -#define G_000070_MC_IND_WR_EN(x) (((x) >> 23) & 0x1) -#define C_000070_MC_IND_WR_EN 0xFF7FFFFF -#define S_000070_MC_IND_RD_INV(x) (((x) & 0x1) << 24) -#define G_000070_MC_IND_RD_INV(x) (((x) >> 24) & 0x1) -#define C_000070_MC_IND_RD_INV 0xFEFFFFFF -#define R_000074_MC_IND_DATA 0x000074 -#define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000074_MC_IND_DATA 0x00000000 -#define R_0000F0_RBBM_SOFT_RESET 0x0000F0 -#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) -#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) -#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE -#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) -#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) -#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD -#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2) -#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1) -#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB -#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) -#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) -#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 -#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) -#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) -#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF -#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) -#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) -#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF -#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) -#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) -#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF -#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) -#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) -#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F -#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) -#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) -#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF -#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) -#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) -#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF -#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) -#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) -#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF -#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) -#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) -#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF -#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) -#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) -#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF -#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13) -#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1) -#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF -#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14) -#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1) -#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF -#define R_000134_HDP_FB_LOCATION 0x000134 -#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000134_HDP_FB_START 0xFFFF0000 -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF -#define R_0060A4_D1CRTC_STATUS_FRAME_COUNT 0x0060A4 -#define S_0060A4_D1CRTC_FRAME_COUNT(x) (((x) & 0xFFFFFF) << 0) -#define G_0060A4_D1CRTC_FRAME_COUNT(x) (((x) >> 0) & 0xFFFFFF) -#define C_0060A4_D1CRTC_FRAME_COUNT 0xFF000000 -#define R_006534_D1MODE_VBLANK_STATUS 0x006534 -#define S_006534_D1MODE_VBLANK_OCCURRED(x) (((x) & 0x1) << 0) -#define G_006534_D1MODE_VBLANK_OCCURRED(x) (((x) >> 0) & 0x1) -#define C_006534_D1MODE_VBLANK_OCCURRED 0xFFFFFFFE -#define S_006534_D1MODE_VBLANK_ACK(x) (((x) & 0x1) << 4) -#define G_006534_D1MODE_VBLANK_ACK(x) (((x) >> 4) & 0x1) -#define C_006534_D1MODE_VBLANK_ACK 0xFFFFFFEF -#define S_006534_D1MODE_VBLANK_STAT(x) (((x) & 0x1) << 12) -#define G_006534_D1MODE_VBLANK_STAT(x) (((x) >> 12) & 0x1) -#define C_006534_D1MODE_VBLANK_STAT 0xFFFFEFFF -#define S_006534_D1MODE_VBLANK_INTERRUPT(x) (((x) & 0x1) << 16) -#define G_006534_D1MODE_VBLANK_INTERRUPT(x) (((x) >> 16) & 0x1) -#define C_006534_D1MODE_VBLANK_INTERRUPT 0xFFFEFFFF -#define R_006540_DxMODE_INT_MASK 0x006540 -#define S_006540_D1MODE_VBLANK_INT_MASK(x) (((x) & 0x1) << 0) -#define G_006540_D1MODE_VBLANK_INT_MASK(x) (((x) >> 0) & 0x1) -#define C_006540_D1MODE_VBLANK_INT_MASK 0xFFFFFFFE -#define S_006540_D1MODE_VLINE_INT_MASK(x) (((x) & 0x1) << 4) -#define G_006540_D1MODE_VLINE_INT_MASK(x) (((x) >> 4) & 0x1) -#define C_006540_D1MODE_VLINE_INT_MASK 0xFFFFFFEF -#define S_006540_D2MODE_VBLANK_INT_MASK(x) (((x) & 0x1) << 8) -#define G_006540_D2MODE_VBLANK_INT_MASK(x) (((x) >> 8) & 0x1) -#define C_006540_D2MODE_VBLANK_INT_MASK 0xFFFFFEFF -#define S_006540_D2MODE_VLINE_INT_MASK(x) (((x) & 0x1) << 12) -#define G_006540_D2MODE_VLINE_INT_MASK(x) (((x) >> 12) & 0x1) -#define C_006540_D2MODE_VLINE_INT_MASK 0xFFFFEFFF -#define S_006540_D1MODE_VBLANK_CP_SEL(x) (((x) & 0x1) << 30) -#define G_006540_D1MODE_VBLANK_CP_SEL(x) (((x) >> 30) & 0x1) -#define C_006540_D1MODE_VBLANK_CP_SEL 0xBFFFFFFF -#define S_006540_D2MODE_VBLANK_CP_SEL(x) (((x) & 0x1) << 31) -#define G_006540_D2MODE_VBLANK_CP_SEL(x) (((x) >> 31) & 0x1) -#define C_006540_D2MODE_VBLANK_CP_SEL 0x7FFFFFFF -#define R_0068A4_D2CRTC_STATUS_FRAME_COUNT 0x0068A4 -#define S_0068A4_D2CRTC_FRAME_COUNT(x) (((x) & 0xFFFFFF) << 0) -#define G_0068A4_D2CRTC_FRAME_COUNT(x) (((x) >> 0) & 0xFFFFFF) -#define C_0068A4_D2CRTC_FRAME_COUNT 0xFF000000 -#define R_006D34_D2MODE_VBLANK_STATUS 0x006D34 -#define S_006D34_D2MODE_VBLANK_OCCURRED(x) (((x) & 0x1) << 0) -#define G_006D34_D2MODE_VBLANK_OCCURRED(x) (((x) >> 0) & 0x1) -#define C_006D34_D2MODE_VBLANK_OCCURRED 0xFFFFFFFE -#define S_006D34_D2MODE_VBLANK_ACK(x) (((x) & 0x1) << 4) -#define G_006D34_D2MODE_VBLANK_ACK(x) (((x) >> 4) & 0x1) -#define C_006D34_D2MODE_VBLANK_ACK 0xFFFFFFEF -#define S_006D34_D2MODE_VBLANK_STAT(x) (((x) & 0x1) << 12) -#define G_006D34_D2MODE_VBLANK_STAT(x) (((x) >> 12) & 0x1) -#define C_006D34_D2MODE_VBLANK_STAT 0xFFFFEFFF -#define S_006D34_D2MODE_VBLANK_INTERRUPT(x) (((x) & 0x1) << 16) -#define G_006D34_D2MODE_VBLANK_INTERRUPT(x) (((x) >> 16) & 0x1) -#define C_006D34_D2MODE_VBLANK_INTERRUPT 0xFFFEFFFF -#define R_007EDC_DISP_INTERRUPT_STATUS 0x007EDC -#define S_007EDC_LB_D1_VBLANK_INTERRUPT(x) (((x) & 0x1) << 4) -#define G_007EDC_LB_D1_VBLANK_INTERRUPT(x) (((x) >> 4) & 0x1) -#define C_007EDC_LB_D1_VBLANK_INTERRUPT 0xFFFFFFEF -#define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5) -#define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1) -#define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF -#define S_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 16) -#define G_007EDC_DACA_AUTODETECT_INTERRUPT(x) (((x) >> 16) & 0x1) -#define C_007EDC_DACA_AUTODETECT_INTERRUPT 0xFFFEFFFF -#define S_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) & 0x1) << 17) -#define G_007EDC_DACB_AUTODETECT_INTERRUPT(x) (((x) >> 17) & 0x1) -#define C_007EDC_DACB_AUTODETECT_INTERRUPT 0xFFFDFFFF -#define S_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) & 0x1) << 18) -#define G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(x) (((x) >> 18) & 0x1) -#define C_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT 0xFFFBFFFF -#define S_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) & 0x1) << 19) -#define G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(x) (((x) >> 19) & 0x1) -#define C_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT 0xFFF7FFFF -#define R_007828_DACA_AUTODETECT_CONTROL 0x007828 -#define S_007828_DACA_AUTODETECT_MODE(x) (((x) & 0x3) << 0) -#define G_007828_DACA_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) -#define C_007828_DACA_AUTODETECT_MODE 0xFFFFFFFC -#define S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) -#define G_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) -#define C_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF -#define S_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) -#define G_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) -#define C_007828_DACA_AUTODETECT_CHECK_MASK 0xFFFCFFFF -#define R_007838_DACA_AUTODETECT_INT_CONTROL 0x007838 -#define S_007838_DACA_AUTODETECT_ACK(x) (((x) & 0x1) << 0) -#define C_007838_DACA_DACA_AUTODETECT_ACK 0xFFFFFFFE -#define S_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) -#define G_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) -#define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFCFFFF -#define R_007A28_DACB_AUTODETECT_CONTROL 0x007A28 -#define S_007A28_DACB_AUTODETECT_MODE(x) (((x) & 0x3) << 0) -#define G_007A28_DACB_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) -#define C_007A28_DACB_AUTODETECT_MODE 0xFFFFFFFC -#define S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) & 0xff) << 8) -#define G_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(x) (((x) >> 8) & 0xff) -#define C_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER 0xFFFF00FF -#define S_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) -#define G_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) -#define C_007A28_DACB_AUTODETECT_CHECK_MASK 0xFFFCFFFF -#define R_007A38_DACB_AUTODETECT_INT_CONTROL 0x007A38 -#define S_007A38_DACB_AUTODETECT_ACK(x) (((x) & 0x1) << 0) -#define C_007A38_DACB_DACA_AUTODETECT_ACK 0xFFFFFFFE -#define S_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) -#define G_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) -#define C_007A38_DACB_AUTODETECT_INT_ENABLE 0xFFFCFFFF -#define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL 0x007D00 -#define S_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) & 0x1) << 0) -#define G_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) >> 0) & 0x1) -#define C_007D00_DC_HOT_PLUG_DETECT1_EN 0xFFFFFFFE -#define R_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0x007D04 -#define S_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) & 0x1) << 0) -#define G_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS(x) (((x) >> 0) & 0x1) -#define C_007D04_DC_HOT_PLUG_DETECT1_INT_STATUS 0xFFFFFFFE -#define S_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) & 0x1) << 1) -#define G_007D04_DC_HOT_PLUG_DETECT1_SENSE(x) (((x) >> 1) & 0x1) -#define C_007D04_DC_HOT_PLUG_DETECT1_SENSE 0xFFFFFFFD -#define R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL 0x007D08 -#define S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(x) (((x) & 0x1) << 0) -#define C_007D08_DC_HOT_PLUG_DETECT1_INT_ACK 0xFFFFFFFE -#define S_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) & 0x1) << 8) -#define G_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY(x) (((x) >> 8) & 0x1) -#define C_007D08_DC_HOT_PLUG_DETECT1_INT_POLARITY 0xFFFFFEFF -#define S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) & 0x1) << 16) -#define G_007D08_DC_HOT_PLUG_DETECT1_INT_EN(x) (((x) >> 16) & 0x1) -#define C_007D08_DC_HOT_PLUG_DETECT1_INT_EN 0xFFFEFFFF -#define R_007D10_DC_HOT_PLUG_DETECT2_CONTROL 0x007D10 -#define S_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) & 0x1) << 0) -#define G_007D10_DC_HOT_PLUG_DETECT2_EN(x) (((x) >> 0) & 0x1) -#define C_007D10_DC_HOT_PLUG_DETECT2_EN 0xFFFFFFFE -#define R_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0x007D14 -#define S_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) & 0x1) << 0) -#define G_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS(x) (((x) >> 0) & 0x1) -#define C_007D14_DC_HOT_PLUG_DETECT2_INT_STATUS 0xFFFFFFFE -#define S_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) & 0x1) << 1) -#define G_007D14_DC_HOT_PLUG_DETECT2_SENSE(x) (((x) >> 1) & 0x1) -#define C_007D14_DC_HOT_PLUG_DETECT2_SENSE 0xFFFFFFFD -#define R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL 0x007D18 -#define S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(x) (((x) & 0x1) << 0) -#define C_007D18_DC_HOT_PLUG_DETECT2_INT_ACK 0xFFFFFFFE -#define S_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) & 0x1) << 8) -#define G_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY(x) (((x) >> 8) & 0x1) -#define C_007D18_DC_HOT_PLUG_DETECT2_INT_POLARITY 0xFFFFFEFF -#define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16) -#define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1) -#define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF - -/* MC registers */ -#define R_000000_MC_STATUS 0x000000 -#define S_000000_MC_IDLE(x) (((x) & 0x1) << 0) -#define G_000000_MC_IDLE(x) (((x) >> 0) & 0x1) -#define C_000000_MC_IDLE 0xFFFFFFFE -#define R_000004_MC_FB_LOCATION 0x000004 -#define S_000004_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000004_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000004_MC_FB_START 0xFFFF0000 -#define S_000004_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000004_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000004_MC_FB_TOP 0x0000FFFF -#define R_000005_MC_AGP_LOCATION 0x000005 -#define S_000005_MC_AGP_START(x) (((x) & 0xFFFF) << 0) -#define G_000005_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) -#define C_000005_MC_AGP_START 0xFFFF0000 -#define S_000005_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000005_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000005_MC_AGP_TOP 0x0000FFFF -#define R_000006_AGP_BASE 0x000006 -#define S_000006_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000006_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000006_AGP_BASE_ADDR 0x00000000 -#define R_000007_AGP_BASE_2 0x000007 -#define S_000007_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) -#define G_000007_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) -#define C_000007_AGP_BASE_ADDR_2 0xFFFFFFF0 -#define R_000009_MC_CNTL1 0x000009 -#define S_000009_ENABLE_PAGE_TABLES(x) (((x) & 0x1) << 26) -#define G_000009_ENABLE_PAGE_TABLES(x) (((x) >> 26) & 0x1) -#define C_000009_ENABLE_PAGE_TABLES 0xFBFFFFFF -/* FIXME don't know the various field size need feedback from AMD */ -#define R_000100_MC_PT0_CNTL 0x000100 -#define S_000100_ENABLE_PT(x) (((x) & 0x1) << 0) -#define G_000100_ENABLE_PT(x) (((x) >> 0) & 0x1) -#define C_000100_ENABLE_PT 0xFFFFFFFE -#define S_000100_EFFECTIVE_L2_CACHE_SIZE(x) (((x) & 0x7) << 15) -#define G_000100_EFFECTIVE_L2_CACHE_SIZE(x) (((x) >> 15) & 0x7) -#define C_000100_EFFECTIVE_L2_CACHE_SIZE 0xFFFC7FFF -#define S_000100_EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 0x7) << 21) -#define G_000100_EFFECTIVE_L2_QUEUE_SIZE(x) (((x) >> 21) & 0x7) -#define C_000100_EFFECTIVE_L2_QUEUE_SIZE 0xFF1FFFFF -#define S_000100_INVALIDATE_ALL_L1_TLBS(x) (((x) & 0x1) << 28) -#define G_000100_INVALIDATE_ALL_L1_TLBS(x) (((x) >> 28) & 0x1) -#define C_000100_INVALIDATE_ALL_L1_TLBS 0xEFFFFFFF -#define S_000100_INVALIDATE_L2_CACHE(x) (((x) & 0x1) << 29) -#define G_000100_INVALIDATE_L2_CACHE(x) (((x) >> 29) & 0x1) -#define C_000100_INVALIDATE_L2_CACHE 0xDFFFFFFF -#define R_000102_MC_PT0_CONTEXT0_CNTL 0x000102 -#define S_000102_ENABLE_PAGE_TABLE(x) (((x) & 0x1) << 0) -#define G_000102_ENABLE_PAGE_TABLE(x) (((x) >> 0) & 0x1) -#define C_000102_ENABLE_PAGE_TABLE 0xFFFFFFFE -#define S_000102_PAGE_TABLE_DEPTH(x) (((x) & 0x3) << 1) -#define G_000102_PAGE_TABLE_DEPTH(x) (((x) >> 1) & 0x3) -#define C_000102_PAGE_TABLE_DEPTH 0xFFFFFFF9 -#define V_000102_PAGE_TABLE_FLAT 0 -/* R600 documentation suggest that this should be a number of pages */ -#define R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x000112 -#define R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x000114 -#define R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x00011C -#define R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x00012C -#define R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x00013C -#define R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x00014C -#define R_00016C_MC_PT0_CLIENT0_CNTL 0x00016C -#define S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(x) (((x) & 0x1) << 0) -#define G_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(x) (((x) >> 0) & 0x1) -#define C_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE 0xFFFFFFFE -#define S_00016C_TRANSLATION_MODE_OVERRIDE(x) (((x) & 0x1) << 1) -#define G_00016C_TRANSLATION_MODE_OVERRIDE(x) (((x) >> 1) & 0x1) -#define C_00016C_TRANSLATION_MODE_OVERRIDE 0xFFFFFFFD -#define S_00016C_SYSTEM_ACCESS_MODE_MASK(x) (((x) & 0x3) << 8) -#define G_00016C_SYSTEM_ACCESS_MODE_MASK(x) (((x) >> 8) & 0x3) -#define C_00016C_SYSTEM_ACCESS_MODE_MASK 0xFFFFFCFF -#define V_00016C_SYSTEM_ACCESS_MODE_PA_ONLY 0 -#define V_00016C_SYSTEM_ACCESS_MODE_USE_SYS_MAP 1 -#define V_00016C_SYSTEM_ACCESS_MODE_IN_SYS 2 -#define V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS 3 -#define S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(x) (((x) & 0x1) << 10) -#define G_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(x) (((x) >> 10) & 0x1) -#define C_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS 0xFFFFFBFF -#define V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH 0 -#define V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE 1 -#define S_00016C_EFFECTIVE_L1_CACHE_SIZE(x) (((x) & 0x7) << 11) -#define G_00016C_EFFECTIVE_L1_CACHE_SIZE(x) (((x) >> 11) & 0x7) -#define C_00016C_EFFECTIVE_L1_CACHE_SIZE 0xFFFFC7FF -#define S_00016C_ENABLE_FRAGMENT_PROCESSING(x) (((x) & 0x1) << 14) -#define G_00016C_ENABLE_FRAGMENT_PROCESSING(x) (((x) >> 14) & 0x1) -#define C_00016C_ENABLE_FRAGMENT_PROCESSING 0xFFFFBFFF -#define S_00016C_EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 0x7) << 15) -#define G_00016C_EFFECTIVE_L1_QUEUE_SIZE(x) (((x) >> 15) & 0x7) -#define C_00016C_EFFECTIVE_L1_QUEUE_SIZE 0xFFFC7FFF -#define S_00016C_INVALIDATE_L1_TLB(x) (((x) & 0x1) << 20) -#define G_00016C_INVALIDATE_L1_TLB(x) (((x) >> 20) & 0x1) -#define C_00016C_INVALIDATE_L1_TLB 0xFFEFFFFF - -#define R_006548_D1MODE_PRIORITY_A_CNT 0x006548 -#define S_006548_D1MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0) -#define G_006548_D1MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF) -#define C_006548_D1MODE_PRIORITY_MARK_A 0xFFFF8000 -#define S_006548_D1MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16) -#define G_006548_D1MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1) -#define C_006548_D1MODE_PRIORITY_A_OFF 0xFFFEFFFF -#define S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_006548_D1MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF -#define S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_006548_D1MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF -#define R_00654C_D1MODE_PRIORITY_B_CNT 0x00654C -#define S_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0) -#define G_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF) -#define C_00654C_D1MODE_PRIORITY_MARK_B 0xFFFF8000 -#define S_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16) -#define G_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1) -#define C_00654C_D1MODE_PRIORITY_B_OFF 0xFFFEFFFF -#define S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF -#define S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_00654C_D1MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF -#define R_006D48_D2MODE_PRIORITY_A_CNT 0x006D48 -#define S_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0) -#define G_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF) -#define C_006D48_D2MODE_PRIORITY_MARK_A 0xFFFF8000 -#define S_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16) -#define G_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1) -#define C_006D48_D2MODE_PRIORITY_A_OFF 0xFFFEFFFF -#define S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF -#define S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_006D48_D2MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF -#define R_006D4C_D2MODE_PRIORITY_B_CNT 0x006D4C -#define S_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0) -#define G_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF) -#define C_006D4C_D2MODE_PRIORITY_MARK_B 0xFFFF8000 -#define S_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16) -#define G_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1) -#define C_006D4C_D2MODE_PRIORITY_B_OFF 0xFFFEFFFF -#define S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF -#define S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF - -/* PLL regs */ -#define GENERAL_PWRMGT 0x8 -#define GLOBAL_PWRMGT_EN (1 << 0) -#define MOBILE_SU (1 << 2) -#define DYN_PWRMGT_SCLK_LENGTH 0xc -#define NORMAL_POWER_SCLK_HILEN(x) ((x) << 0) -#define NORMAL_POWER_SCLK_LOLEN(x) ((x) << 4) -#define REDUCED_POWER_SCLK_HILEN(x) ((x) << 8) -#define REDUCED_POWER_SCLK_LOLEN(x) ((x) << 12) -#define POWER_D1_SCLK_HILEN(x) ((x) << 16) -#define POWER_D1_SCLK_LOLEN(x) ((x) << 20) -#define STATIC_SCREEN_HILEN(x) ((x) << 24) -#define STATIC_SCREEN_LOLEN(x) ((x) << 28) -#define DYN_SCLK_VOL_CNTL 0xe -#define IO_CG_VOLTAGE_DROP (1 << 0) -#define VOLTAGE_DROP_SYNC (1 << 2) -#define VOLTAGE_DELAY_SEL(x) ((x) << 3) -#define HDP_DYN_CNTL 0x10 -#define HDP_FORCEON (1 << 0) -#define MC_HOST_DYN_CNTL 0x1e -#define MC_HOST_FORCEON (1 << 0) -#define DYN_BACKBIAS_CNTL 0x29 -#define IO_CG_BACKBIAS_EN (1 << 0) - -/* mmreg */ -#define DOUT_POWER_MANAGEMENT_CNTL 0x7ee0 -#define PWRDN_WAIT_BUSY_OFF (1 << 0) -#define PWRDN_WAIT_PWRSEQ_OFF (1 << 4) -#define PWRDN_WAIT_PPLL_OFF (1 << 8) -#define PWRUP_WAIT_PPLL_ON (1 << 12) -#define PWRUP_WAIT_MEM_INIT_DONE (1 << 16) -#define PM_ASSERT_RESET (1 << 20) -#define PM_PWRDN_PPLL (1 << 24) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690.c deleted file mode 100644 index f2c3b9d7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690.c +++ /dev/null @@ -1,793 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" -#include "rs690d.h" - -int rs690_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32_MC(R_000090_MC_SYSTEM_STATUS); - if (G_000090_MC_SYSTEM_IDLE(tmp)) - return 0; - udelay(1); - } - return -1; -} - -static void rs690_gpu_init(struct radeon_device *rdev) -{ - /* FIXME: is this correct ? */ - r420_pipes_init(rdev); - if (rs690_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait MC idle while " - "programming pipes. Bad things might happen.\n"); - } -} - -union igp_info { - struct _ATOM_INTEGRATED_SYSTEM_INFO info; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2; -}; - -void rs690_pm_info(struct radeon_device *rdev) -{ - int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); - union igp_info *info; - uint16_t data_offset; - uint8_t frev, crev; - fixed20_12 tmp; - - if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL, - &frev, &crev, &data_offset)) { - info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset); - - /* Get various system informations from bios */ - switch (crev) { - case 1: - tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info.ulBootUpMemoryClock)); - rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (le16_to_cpu(info->info.usK8MemoryClock)) - rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); - else if (rdev->clock.default_mclk) { - rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); - rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - } else - rdev->pm.igp_system_mclk.full = dfixed_const(400); - rdev->pm.igp_ht_link_clk.full = dfixed_const(le16_to_cpu(info->info.usFSBClock)); - rdev->pm.igp_ht_link_width.full = dfixed_const(info->info.ucHTLinkWidth); - break; - case 2: - tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpSidePortClock)); - rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (le32_to_cpu(info->info_v2.ulBootUpUMAClock)) - rdev->pm.igp_system_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpUMAClock)); - else if (rdev->clock.default_mclk) - rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); - else - rdev->pm.igp_system_mclk.full = dfixed_const(66700); - rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = dfixed_const(le32_to_cpu(info->info_v2.ulHTLinkFreq)); - rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); - rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); - break; - default: - /* We assume the slower possible clock ie worst case */ - rdev->pm.igp_sideport_mclk.full = dfixed_const(200); - rdev->pm.igp_system_mclk.full = dfixed_const(200); - rdev->pm.igp_ht_link_clk.full = dfixed_const(1000); - rdev->pm.igp_ht_link_width.full = dfixed_const(8); - DRM_ERROR("No integrated system info for your GPU, using safe default\n"); - break; - } - } else { - /* We assume the slower possible clock ie worst case */ - rdev->pm.igp_sideport_mclk.full = dfixed_const(200); - rdev->pm.igp_system_mclk.full = dfixed_const(200); - rdev->pm.igp_ht_link_clk.full = dfixed_const(1000); - rdev->pm.igp_ht_link_width.full = dfixed_const(8); - DRM_ERROR("No integrated system info for your GPU, using safe default\n"); - } - /* Compute various bandwidth */ - /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */ - tmp.full = dfixed_const(4); - rdev->pm.k8_bandwidth.full = dfixed_mul(rdev->pm.igp_system_mclk, tmp); - /* ht_bandwidth = ht_clk * 2 * ht_width / 8 * 0.8 - * = ht_clk * ht_width / 5 - */ - tmp.full = dfixed_const(5); - rdev->pm.ht_bandwidth.full = dfixed_mul(rdev->pm.igp_ht_link_clk, - rdev->pm.igp_ht_link_width); - rdev->pm.ht_bandwidth.full = dfixed_div(rdev->pm.ht_bandwidth, tmp); - if (tmp.full < rdev->pm.max_bandwidth.full) { - /* HT link is a limiting factor */ - rdev->pm.max_bandwidth.full = tmp.full; - } - /* sideport_bandwidth = (sideport_clk / 2) * 2 * 2 * 0.7 - * = (sideport_clk * 14) / 10 - */ - tmp.full = dfixed_const(14); - rdev->pm.sideport_bandwidth.full = dfixed_mul(rdev->pm.igp_sideport_mclk, tmp); - tmp.full = dfixed_const(10); - rdev->pm.sideport_bandwidth.full = dfixed_div(rdev->pm.sideport_bandwidth, tmp); -} - -void rs690_mc_init(struct radeon_device *rdev) -{ - u64 base; - - rs400_gart_adjust_size(rdev); - rdev->mc.vram_is_ddr = true; - rdev->mc.vram_width = 128; - rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); - rdev->mc.mc_vram_size = rdev->mc.real_vram_size; - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - rdev->mc.visible_vram_size = rdev->mc.aper_size; - base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); - base = G_000100_MC_FB_START(base) << 16; - rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); - rs690_pm_info(rdev); - radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - -void rs690_line_buffer_adjust(struct radeon_device *rdev, - struct drm_display_mode *mode1, - struct drm_display_mode *mode2) -{ - u32 tmp; - - /* - * Line Buffer Setup - * There is a single line buffer shared by both display controllers. - * R_006520_DC_LB_MEMORY_SPLIT controls how that line buffer is shared between - * the display controllers. The paritioning can either be done - * manually or via one of four preset allocations specified in bits 1:0: - * 0 - line buffer is divided in half and shared between crtc - * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4 - * 2 - D1 gets the whole buffer - * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4 - * Setting bit 2 of R_006520_DC_LB_MEMORY_SPLIT controls switches to manual - * allocation mode. In manual allocation mode, D1 always starts at 0, - * D1 end/2 is specified in bits 14:4; D2 allocation follows D1. - */ - tmp = RREG32(R_006520_DC_LB_MEMORY_SPLIT) & C_006520_DC_LB_MEMORY_SPLIT; - tmp &= ~C_006520_DC_LB_MEMORY_SPLIT_MODE; - /* auto */ - if (mode1 && mode2) { - if (mode1->hdisplay > mode2->hdisplay) { - if (mode1->hdisplay > 2560) - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q; - else - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; - } else if (mode2->hdisplay > mode1->hdisplay) { - if (mode2->hdisplay > 2560) - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; - else - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; - } else - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; - } else if (mode1) { - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_ONLY; - } else if (mode2) { - tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; - } - WREG32(R_006520_DC_LB_MEMORY_SPLIT, tmp); -} - -struct rs690_watermark { - u32 lb_request_fifo_depth; - fixed20_12 num_line_pair; - fixed20_12 estimated_width; - fixed20_12 worst_case_latency; - fixed20_12 consumption_rate; - fixed20_12 active_time; - fixed20_12 dbpp; - fixed20_12 priority_mark_max; - fixed20_12 priority_mark; - fixed20_12 sclk; -}; - -void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, - struct radeon_crtc *crtc, - struct rs690_watermark *wm) -{ - struct drm_display_mode *mode = &crtc->base.mode; - fixed20_12 a, b, c; - fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width; - fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency; - - if (!crtc->base.enabled) { - /* FIXME: wouldn't it better to set priority mark to maximum */ - wm->lb_request_fifo_depth = 4; - return; - } - - if (crtc->vsc.full > dfixed_const(2)) - wm->num_line_pair.full = dfixed_const(2); - else - wm->num_line_pair.full = dfixed_const(1); - - b.full = dfixed_const(mode->crtc_hdisplay); - c.full = dfixed_const(256); - a.full = dfixed_div(b, c); - request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); - request_fifo_depth.full = dfixed_ceil(request_fifo_depth); - if (a.full < dfixed_const(4)) { - wm->lb_request_fifo_depth = 4; - } else { - wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); - } - - /* Determine consumption rate - * pclk = pixel clock period(ns) = 1000 / (mode.clock / 1000) - * vtaps = number of vertical taps, - * vsc = vertical scaling ratio, defined as source/destination - * hsc = horizontal scaling ration, defined as source/destination - */ - a.full = dfixed_const(mode->clock); - b.full = dfixed_const(1000); - a.full = dfixed_div(a, b); - pclk.full = dfixed_div(b, a); - if (crtc->rmx_type != RMX_OFF) { - b.full = dfixed_const(2); - if (crtc->vsc.full > b.full) - b.full = crtc->vsc.full; - b.full = dfixed_mul(b, crtc->hsc); - c.full = dfixed_const(2); - b.full = dfixed_div(b, c); - consumption_time.full = dfixed_div(pclk, b); - } else { - consumption_time.full = pclk.full; - } - a.full = dfixed_const(1); - wm->consumption_rate.full = dfixed_div(a, consumption_time); - - - /* Determine line time - * LineTime = total time for one line of displayhtotal - * LineTime = total number of horizontal pixels - * pclk = pixel clock period(ns) - */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - line_time.full = dfixed_mul(a, pclk); - - /* Determine active time - * ActiveTime = time of active region of display within one line, - * hactive = total number of horizontal active pixels - * htotal = total number of horizontal pixels - */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->active_time.full = dfixed_mul(line_time, b); - wm->active_time.full = dfixed_div(wm->active_time, a); - - /* Maximun bandwidth is the minimun bandwidth of all component */ - rdev->pm.max_bandwidth = rdev->pm.core_bandwidth; - if (rdev->mc.igp_sideport_enabled) { - if (rdev->pm.max_bandwidth.full > rdev->pm.sideport_bandwidth.full && - rdev->pm.sideport_bandwidth.full) - rdev->pm.max_bandwidth = rdev->pm.sideport_bandwidth; - read_delay_latency.full = dfixed_const(370 * 800 * 1000); - read_delay_latency.full = dfixed_div(read_delay_latency, - rdev->pm.igp_sideport_mclk); - } else { - if (rdev->pm.max_bandwidth.full > rdev->pm.k8_bandwidth.full && - rdev->pm.k8_bandwidth.full) - rdev->pm.max_bandwidth = rdev->pm.k8_bandwidth; - if (rdev->pm.max_bandwidth.full > rdev->pm.ht_bandwidth.full && - rdev->pm.ht_bandwidth.full) - rdev->pm.max_bandwidth = rdev->pm.ht_bandwidth; - read_delay_latency.full = dfixed_const(5000); - } - - /* sclk = system clocks(ns) = 1000 / max_bandwidth / 16 */ - a.full = dfixed_const(16); - rdev->pm.sclk.full = dfixed_mul(rdev->pm.max_bandwidth, a); - a.full = dfixed_const(1000); - rdev->pm.sclk.full = dfixed_div(a, rdev->pm.sclk); - /* Determine chunk time - * ChunkTime = the time it takes the DCP to send one chunk of data - * to the LB which consists of pipeline delay and inter chunk gap - * sclk = system clock(ns) - */ - a.full = dfixed_const(256 * 13); - chunk_time.full = dfixed_mul(rdev->pm.sclk, a); - a.full = dfixed_const(10); - chunk_time.full = dfixed_div(chunk_time, a); - - /* Determine the worst case latency - * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) - * WorstCaseLatency = worst case time from urgent to when the MC starts - * to return data - * READ_DELAY_IDLE_MAX = constant of 1us - * ChunkTime = time it takes the DCP to send one chunk of data to the LB - * which consists of pipeline delay and inter chunk gap - */ - if (dfixed_trunc(wm->num_line_pair) > 1) { - a.full = dfixed_const(3); - wm->worst_case_latency.full = dfixed_mul(a, chunk_time); - wm->worst_case_latency.full += read_delay_latency.full; - } else { - a.full = dfixed_const(2); - wm->worst_case_latency.full = dfixed_mul(a, chunk_time); - wm->worst_case_latency.full += read_delay_latency.full; - } - - /* Determine the tolerable latency - * TolerableLatency = Any given request has only 1 line time - * for the data to be returned - * LBRequestFifoDepth = Number of chunk requests the LB can - * put into the request FIFO for a display - * LineTime = total time for one line of display - * ChunkTime = the time it takes the DCP to send one chunk - * of data to the LB which consists of - * pipeline delay and inter chunk gap - */ - if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { - tolerable_latency.full = line_time.full; - } else { - tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); - tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; - tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); - tolerable_latency.full = line_time.full - tolerable_latency.full; - } - /* We assume worst case 32bits (4 bytes) */ - wm->dbpp.full = dfixed_const(4 * 8); - - /* Determine the maximum priority mark - * width = viewport width in pixels - */ - a.full = dfixed_const(16); - wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); - wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); - - /* Determine estimated width */ - estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; - estimated_width.full = dfixed_div(estimated_width, consumption_time); - if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { - wm->priority_mark.full = dfixed_const(10); - } else { - a.full = dfixed_const(16); - wm->priority_mark.full = dfixed_div(estimated_width, a); - wm->priority_mark.full = dfixed_ceil(wm->priority_mark); - wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; - } -} - -void rs690_bandwidth_update(struct radeon_device *rdev) -{ - struct drm_display_mode *mode0 = NULL; - struct drm_display_mode *mode1 = NULL; - struct rs690_watermark wm0; - struct rs690_watermark wm1; - u32 tmp; - u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); - u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); - fixed20_12 priority_mark02, priority_mark12, fill_rate; - fixed20_12 a, b; - - radeon_update_display_priority(rdev); - - if (rdev->mode_info.crtcs[0]->base.enabled) - mode0 = &rdev->mode_info.crtcs[0]->base.mode; - if (rdev->mode_info.crtcs[1]->base.enabled) - mode1 = &rdev->mode_info.crtcs[1]->base.mode; - /* - * Set display0/1 priority up in the memory controller for - * modes if the user specifies HIGH for displaypriority - * option. - */ - if ((rdev->disp_priority == 2) && - ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) { - tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER); - tmp &= C_000104_MC_DISP0R_INIT_LAT; - tmp &= C_000104_MC_DISP1R_INIT_LAT; - if (mode0) - tmp |= S_000104_MC_DISP0R_INIT_LAT(1); - if (mode1) - tmp |= S_000104_MC_DISP1R_INIT_LAT(1); - WREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER, tmp); - } - rs690_line_buffer_adjust(rdev, mode0, mode1); - - if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) - WREG32(R_006C9C_DCP_CONTROL, 0); - if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) - WREG32(R_006C9C_DCP_CONTROL, 2); - - rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0); - rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1); - - tmp = (wm0.lb_request_fifo_depth - 1); - tmp |= (wm1.lb_request_fifo_depth - 1) << 16; - WREG32(R_006D58_LB_MAX_REQ_OUTSTANDING, tmp); - - if (mode0 && mode1) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); - else - a.full = wm0.num_line_pair.full; - if (dfixed_trunc(wm1.dbpp) > 64) - b.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); - else - b.full = wm1.num_line_pair.full; - a.full += b.full; - fill_rate.full = dfixed_div(wm0.sclk, a); - if (wm0.consumption_rate.full > fill_rate.full) { - b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); - } else { - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); - } - if (wm1.consumption_rate.full > fill_rate.full) { - b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); - } else { - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); - } - if (wm0.priority_mark.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; - if (wm0.priority_mark_max.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark_max.full; - if (wm1.priority_mark.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; - if (wm1.priority_mark_max.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); - if (rdev->disp_priority == 2) { - d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); - d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); - } - } else if (mode0) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); - else - a.full = wm0.num_line_pair.full; - fill_rate.full = dfixed_div(wm0.sclk, a); - if (wm0.consumption_rate.full > fill_rate.full) { - b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); - } else { - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); - } - if (wm0.priority_mark.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; - if (wm0.priority_mark_max.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); - if (rdev->disp_priority == 2) - d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); - } else if (mode1) { - if (dfixed_trunc(wm1.dbpp) > 64) - a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); - else - a.full = wm1.num_line_pair.full; - fill_rate.full = dfixed_div(wm1.sclk, a); - if (wm1.consumption_rate.full > fill_rate.full) { - b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - a.full = a.full + b.full; - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); - } else { - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); - } - if (wm1.priority_mark.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; - if (wm1.priority_mark_max.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark_max.full; - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); - if (rdev->disp_priority == 2) - d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); - } - - WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); -} - -uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg) -{ - uint32_t r; - - WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg)); - r = RREG32(R_00007C_MC_DATA); - WREG32(R_000078_MC_INDEX, ~C_000078_MC_IND_ADDR); - return r; -} - -void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg) | - S_000078_MC_IND_WR_EN(1)); - WREG32(R_00007C_MC_DATA, v); - WREG32(R_000078_MC_INDEX, 0x7F); -} - -void rs690_mc_program(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - - /* Stops all mc clients */ - rv515_mc_stop(rdev, &save); - - /* Wait for mc idle */ - if (rs690_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); - /* Program MC, should be a 32bits limited address space */ - WREG32_MC(R_000100_MCCFG_FB_LOCATION, - S_000100_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000100_MC_FB_TOP(rdev->mc.vram_end >> 16)); - WREG32(R_000134_HDP_FB_LOCATION, - S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); - - rv515_mc_resume(rdev, &save); -} - -static int rs690_startup(struct radeon_device *rdev) -{ - int r; - - rs690_mc_program(rdev); - /* Resume clock */ - rv515_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ - rs690_gpu_init(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - r = rs400_gart_enable(rdev); - if (r) - return r; - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - rs600_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int rs690_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - rs400_gart_disable(rdev); - /* Resume clock before doing reset */ - rv515_clock_startup(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - atom_asic_init(rdev->mode_info.atom_context); - /* Resume clock after posting */ - rv515_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = rs690_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int rs690_suspend(struct radeon_device *rdev) -{ - radeon_ib_pool_suspend(rdev); - r600_audio_fini(rdev); - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - rs600_irq_disable(rdev); - rs400_gart_disable(rdev); - return 0; -} - -void rs690_fini(struct radeon_device *rdev) -{ - r600_audio_fini(rdev); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - rs400_gart_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -int rs690_init(struct radeon_device *rdev) -{ - int r; - - /* Disable VGA */ - rv515_vga_render_disable(rdev); - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* TODO: disable VGA need to use VGA request */ - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - r = radeon_atombios_init(rdev); - if (r) - return r; - } else { - dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); - return -EINVAL; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize memory controller */ - rs690_mc_init(rdev); - rv515_debugfs(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - r = rs400_gart_init(rdev); - if (r) - return r; - rs600_set_safe_registers(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = rs690_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - rs400_gart_fini(rdev); - radeon_irq_kms_fini(rdev); - rdev->accel_working = false; - } - return 0; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690d.h deleted file mode 100644 index 36e6398a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rs690d.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RS690D_H__ -#define __RS690D_H__ - -/* Registers */ -#define R_000078_MC_INDEX 0x000078 -#define S_000078_MC_IND_ADDR(x) (((x) & 0x1FF) << 0) -#define G_000078_MC_IND_ADDR(x) (((x) >> 0) & 0x1FF) -#define C_000078_MC_IND_ADDR 0xFFFFFE00 -#define S_000078_MC_IND_WR_EN(x) (((x) & 0x1) << 9) -#define G_000078_MC_IND_WR_EN(x) (((x) >> 9) & 0x1) -#define C_000078_MC_IND_WR_EN 0xFFFFFDFF -#define R_00007C_MC_DATA 0x00007C -#define S_00007C_MC_DATA(x) (((x) & 0xFFFFFFFF) << 0) -#define G_00007C_MC_DATA(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_00007C_MC_DATA 0x00000000 -#define R_0000F8_CONFIG_MEMSIZE 0x0000F8 -#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_0000F8_CONFIG_MEMSIZE 0x00000000 -#define R_000134_HDP_FB_LOCATION 0x000134 -#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000134_HDP_FB_START 0xFFFF0000 -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF -#define R_006520_DC_LB_MEMORY_SPLIT 0x006520 -#define S_006520_DC_LB_MEMORY_SPLIT(x) (((x) & 0x3) << 0) -#define G_006520_DC_LB_MEMORY_SPLIT(x) (((x) >> 0) & 0x3) -#define C_006520_DC_LB_MEMORY_SPLIT 0xFFFFFFFC -#define S_006520_DC_LB_MEMORY_SPLIT_MODE(x) (((x) & 0x1) << 2) -#define G_006520_DC_LB_MEMORY_SPLIT_MODE(x) (((x) >> 2) & 0x1) -#define C_006520_DC_LB_MEMORY_SPLIT_MODE 0xFFFFFFFB -#define V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0 -#define V_006520_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1 -#define V_006520_DC_LB_MEMORY_SPLIT_D1_ONLY 2 -#define V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3 -#define S_006520_DC_LB_DISP1_END_ADR(x) (((x) & 0x7FF) << 4) -#define G_006520_DC_LB_DISP1_END_ADR(x) (((x) >> 4) & 0x7FF) -#define C_006520_DC_LB_DISP1_END_ADR 0xFFFF800F -#define R_006548_D1MODE_PRIORITY_A_CNT 0x006548 -#define S_006548_D1MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0) -#define G_006548_D1MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF) -#define C_006548_D1MODE_PRIORITY_MARK_A 0xFFFF8000 -#define S_006548_D1MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16) -#define G_006548_D1MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1) -#define C_006548_D1MODE_PRIORITY_A_OFF 0xFFFEFFFF -#define S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_006548_D1MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF -#define S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_006548_D1MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF -#define R_00654C_D1MODE_PRIORITY_B_CNT 0x00654C -#define S_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0) -#define G_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF) -#define C_00654C_D1MODE_PRIORITY_MARK_B 0xFFFF8000 -#define S_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16) -#define G_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1) -#define C_00654C_D1MODE_PRIORITY_B_OFF 0xFFFEFFFF -#define S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF -#define S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_00654C_D1MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF -#define R_006C9C_DCP_CONTROL 0x006C9C -#define R_006D48_D2MODE_PRIORITY_A_CNT 0x006D48 -#define S_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0) -#define G_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF) -#define C_006D48_D2MODE_PRIORITY_MARK_A 0xFFFF8000 -#define S_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16) -#define G_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1) -#define C_006D48_D2MODE_PRIORITY_A_OFF 0xFFFEFFFF -#define S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF -#define S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_006D48_D2MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF -#define R_006D4C_D2MODE_PRIORITY_B_CNT 0x006D4C -#define S_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0) -#define G_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF) -#define C_006D4C_D2MODE_PRIORITY_MARK_B 0xFFFF8000 -#define S_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16) -#define G_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1) -#define C_006D4C_D2MODE_PRIORITY_B_OFF 0xFFFEFFFF -#define S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20) -#define G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1) -#define C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF -#define S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24) -#define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1) -#define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF -#define R_006D58_LB_MAX_REQ_OUTSTANDING 0x006D58 -#define S_006D58_LB_D1_MAX_REQ_OUTSTANDING(x) (((x) & 0xF) << 0) -#define G_006D58_LB_D1_MAX_REQ_OUTSTANDING(x) (((x) >> 0) & 0xF) -#define C_006D58_LB_D1_MAX_REQ_OUTSTANDING 0xFFFFFFF0 -#define S_006D58_LB_D2_MAX_REQ_OUTSTANDING(x) (((x) & 0xF) << 16) -#define G_006D58_LB_D2_MAX_REQ_OUTSTANDING(x) (((x) >> 16) & 0xF) -#define C_006D58_LB_D2_MAX_REQ_OUTSTANDING 0xFFF0FFFF - - -#define R_000090_MC_SYSTEM_STATUS 0x000090 -#define S_000090_MC_SYSTEM_IDLE(x) (((x) & 0x1) << 0) -#define G_000090_MC_SYSTEM_IDLE(x) (((x) >> 0) & 0x1) -#define C_000090_MC_SYSTEM_IDLE 0xFFFFFFFE -#define S_000090_MC_SEQUENCER_IDLE(x) (((x) & 0x1) << 1) -#define G_000090_MC_SEQUENCER_IDLE(x) (((x) >> 1) & 0x1) -#define C_000090_MC_SEQUENCER_IDLE 0xFFFFFFFD -#define S_000090_MC_ARBITER_IDLE(x) (((x) & 0x1) << 2) -#define G_000090_MC_ARBITER_IDLE(x) (((x) >> 2) & 0x1) -#define C_000090_MC_ARBITER_IDLE 0xFFFFFFFB -#define S_000090_MC_SELECT_PM(x) (((x) & 0x1) << 3) -#define G_000090_MC_SELECT_PM(x) (((x) >> 3) & 0x1) -#define C_000090_MC_SELECT_PM 0xFFFFFFF7 -#define S_000090_RESERVED4(x) (((x) & 0xF) << 4) -#define G_000090_RESERVED4(x) (((x) >> 4) & 0xF) -#define C_000090_RESERVED4 0xFFFFFF0F -#define S_000090_RESERVED8(x) (((x) & 0xF) << 8) -#define G_000090_RESERVED8(x) (((x) >> 8) & 0xF) -#define C_000090_RESERVED8 0xFFFFF0FF -#define S_000090_RESERVED12(x) (((x) & 0xF) << 12) -#define G_000090_RESERVED12(x) (((x) >> 12) & 0xF) -#define C_000090_RESERVED12 0xFFFF0FFF -#define S_000090_MCA_INIT_EXECUTED(x) (((x) & 0x1) << 16) -#define G_000090_MCA_INIT_EXECUTED(x) (((x) >> 16) & 0x1) -#define C_000090_MCA_INIT_EXECUTED 0xFFFEFFFF -#define S_000090_MCA_IDLE(x) (((x) & 0x1) << 17) -#define G_000090_MCA_IDLE(x) (((x) >> 17) & 0x1) -#define C_000090_MCA_IDLE 0xFFFDFFFF -#define S_000090_MCA_SEQ_IDLE(x) (((x) & 0x1) << 18) -#define G_000090_MCA_SEQ_IDLE(x) (((x) >> 18) & 0x1) -#define C_000090_MCA_SEQ_IDLE 0xFFFBFFFF -#define S_000090_MCA_ARB_IDLE(x) (((x) & 0x1) << 19) -#define G_000090_MCA_ARB_IDLE(x) (((x) >> 19) & 0x1) -#define C_000090_MCA_ARB_IDLE 0xFFF7FFFF -#define S_000090_RESERVED20(x) (((x) & 0xFFF) << 20) -#define G_000090_RESERVED20(x) (((x) >> 20) & 0xFFF) -#define C_000090_RESERVED20 0x000FFFFF -#define R_000100_MCCFG_FB_LOCATION 0x000100 -#define S_000100_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000100_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000100_MC_FB_START 0xFFFF0000 -#define S_000100_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000100_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000100_MC_FB_TOP 0x0000FFFF -#define R_000104_MC_INIT_MISC_LAT_TIMER 0x000104 -#define S_000104_MC_CPR_INIT_LAT(x) (((x) & 0xF) << 0) -#define G_000104_MC_CPR_INIT_LAT(x) (((x) >> 0) & 0xF) -#define C_000104_MC_CPR_INIT_LAT 0xFFFFFFF0 -#define S_000104_MC_VF_INIT_LAT(x) (((x) & 0xF) << 4) -#define G_000104_MC_VF_INIT_LAT(x) (((x) >> 4) & 0xF) -#define C_000104_MC_VF_INIT_LAT 0xFFFFFF0F -#define S_000104_MC_DISP0R_INIT_LAT(x) (((x) & 0xF) << 8) -#define G_000104_MC_DISP0R_INIT_LAT(x) (((x) >> 8) & 0xF) -#define C_000104_MC_DISP0R_INIT_LAT 0xFFFFF0FF -#define S_000104_MC_DISP1R_INIT_LAT(x) (((x) & 0xF) << 12) -#define G_000104_MC_DISP1R_INIT_LAT(x) (((x) >> 12) & 0xF) -#define C_000104_MC_DISP1R_INIT_LAT 0xFFFF0FFF -#define S_000104_MC_FIXED_INIT_LAT(x) (((x) & 0xF) << 16) -#define G_000104_MC_FIXED_INIT_LAT(x) (((x) >> 16) & 0xF) -#define C_000104_MC_FIXED_INIT_LAT 0xFFF0FFFF -#define S_000104_MC_E2R_INIT_LAT(x) (((x) & 0xF) << 20) -#define G_000104_MC_E2R_INIT_LAT(x) (((x) >> 20) & 0xF) -#define C_000104_MC_E2R_INIT_LAT 0xFF0FFFFF -#define S_000104_SAME_PAGE_PRIO(x) (((x) & 0xF) << 24) -#define G_000104_SAME_PAGE_PRIO(x) (((x) >> 24) & 0xF) -#define C_000104_SAME_PAGE_PRIO 0xF0FFFFFF -#define S_000104_MC_GLOBW_INIT_LAT(x) (((x) & 0xF) << 28) -#define G_000104_MC_GLOBW_INIT_LAT(x) (((x) >> 28) & 0xF) -#define C_000104_MC_GLOBW_INIT_LAT 0x0FFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv200d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv200d.h deleted file mode 100644 index c5b39833..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv200d.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RV200D_H__ -#define __RV200D_H__ - -#define R_00015C_AGP_BASE_2 0x00015C -#define S_00015C_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) -#define G_00015C_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) -#define C_00015C_AGP_BASE_ADDR_2 0xFFFFFFF0 - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv250d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv250d.h deleted file mode 100644 index e5a70b06..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv250d.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RV250D_H__ -#define __RV250D_H__ - -#define R_00000D_SCLK_CNTL_M6 0x00000D -#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0) -#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7) -#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8 -#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3) -#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1) -#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7 -#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4) -#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1) -#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF -#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5) -#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1) -#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF -#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6) -#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1) -#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF -#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7) -#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1) -#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F -#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8) -#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1) -#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF -#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9) -#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1) -#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF -#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10) -#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1) -#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF -#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11) -#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1) -#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF -#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12) -#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1) -#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF -#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13) -#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1) -#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF -#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14) -#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1) -#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF -#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15) -#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1) -#define C_00000D_FORCE_DISP2 0xFFFF7FFF -#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16) -#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1) -#define C_00000D_FORCE_CP 0xFFFEFFFF -#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17) -#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1) -#define C_00000D_FORCE_HDP 0xFFFDFFFF -#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18) -#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1) -#define C_00000D_FORCE_DISP1 0xFFFBFFFF -#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19) -#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1) -#define C_00000D_FORCE_TOP 0xFFF7FFFF -#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20) -#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1) -#define C_00000D_FORCE_E2 0xFFEFFFFF -#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21) -#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1) -#define C_00000D_FORCE_SE 0xFFDFFFFF -#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22) -#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1) -#define C_00000D_FORCE_IDCT 0xFFBFFFFF -#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23) -#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1) -#define C_00000D_FORCE_VIP 0xFF7FFFFF -#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24) -#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1) -#define C_00000D_FORCE_RE 0xFEFFFFFF -#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25) -#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1) -#define C_00000D_FORCE_PB 0xFDFFFFFF -#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26) -#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1) -#define C_00000D_FORCE_TAM 0xFBFFFFFF -#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27) -#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1) -#define C_00000D_FORCE_TDM 0xF7FFFFFF -#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28) -#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1) -#define C_00000D_FORCE_RB 0xEFFFFFFF -#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29) -#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1) -#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF -#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30) -#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1) -#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF -#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31) -#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1) -#define C_00000D_FORCE_OV0 0x7FFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv350d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv350d.h deleted file mode 100644 index c75c5ed9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv350d.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RV350D_H__ -#define __RV350D_H__ - -/* RV350, RV380 registers */ -/* #define R_00000D_SCLK_CNTL 0x00000D */ -#define S_00000D_FORCE_VAP(x) (((x) & 0x1) << 21) -#define G_00000D_FORCE_VAP(x) (((x) >> 21) & 0x1) -#define C_00000D_FORCE_VAP 0xFFDFFFFF -#define S_00000D_FORCE_SR(x) (((x) & 0x1) << 25) -#define G_00000D_FORCE_SR(x) (((x) >> 25) & 0x1) -#define C_00000D_FORCE_SR 0xFDFFFFFF -#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26) -#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1) -#define C_00000D_FORCE_PX 0xFBFFFFFF -#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27) -#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1) -#define C_00000D_FORCE_TX 0xF7FFFFFF -#define S_00000D_FORCE_US(x) (((x) & 0x1) << 28) -#define G_00000D_FORCE_US(x) (((x) >> 28) & 0x1) -#define C_00000D_FORCE_US 0xEFFFFFFF -#define S_00000D_FORCE_SU(x) (((x) & 0x1) << 30) -#define G_00000D_FORCE_SU(x) (((x) >> 30) & 0x1) -#define C_00000D_FORCE_SU 0xBFFFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515.c deleted file mode 100644 index d8d78fe1..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515.c +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include "drmP.h" -#include "rv515d.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "atom.h" -#include "rv515_reg_safe.h" - -/* This files gather functions specifics to: rv515 */ -int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); -int rv515_debugfs_ga_info_init(struct radeon_device *rdev); -void rv515_gpu_init(struct radeon_device *rdev); -int rv515_mc_wait_for_idle(struct radeon_device *rdev); - -void rv515_debugfs(struct radeon_device *rdev) -{ - if (r100_debugfs_rbbm_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for RBBM !\n"); - } - if (rv515_debugfs_pipes_info_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for pipes !\n"); - } - if (rv515_debugfs_ga_info_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for pipes !\n"); - } -} - -void rv515_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) -{ - int r; - - r = radeon_ring_lock(rdev, ring, 64); - if (r) { - return; - } - radeon_ring_write(ring, PACKET0(ISYNC_CNTL, 0)); - radeon_ring_write(ring, - ISYNC_ANY2D_IDLE3D | - ISYNC_ANY3D_IDLE2D | - ISYNC_WAIT_IDLEGUI | - ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); - radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); - radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); - radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); - radeon_ring_write(ring, PACKET0(GB_SELECT, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(GB_ENABLE, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(R500_SU_REG_DEST, 0)); - radeon_ring_write(ring, (1 << rdev->num_gb_pipes) - 1); - radeon_ring_write(ring, PACKET0(VAP_INDEX_OFFSET, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); - radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); - radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); - radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); - radeon_ring_write(ring, PACKET0(GB_AA_CONFIG, 0)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); - radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); - radeon_ring_write(ring, PACKET0(GB_MSPOS0, 0)); - radeon_ring_write(ring, - ((6 << MS_X0_SHIFT) | - (6 << MS_Y0_SHIFT) | - (6 << MS_X1_SHIFT) | - (6 << MS_Y1_SHIFT) | - (6 << MS_X2_SHIFT) | - (6 << MS_Y2_SHIFT) | - (6 << MSBD0_Y_SHIFT) | - (6 << MSBD0_X_SHIFT))); - radeon_ring_write(ring, PACKET0(GB_MSPOS1, 0)); - radeon_ring_write(ring, - ((6 << MS_X3_SHIFT) | - (6 << MS_Y3_SHIFT) | - (6 << MS_X4_SHIFT) | - (6 << MS_Y4_SHIFT) | - (6 << MS_X5_SHIFT) | - (6 << MS_Y5_SHIFT) | - (6 << MSBD1_SHIFT))); - radeon_ring_write(ring, PACKET0(GA_ENHANCE, 0)); - radeon_ring_write(ring, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); - radeon_ring_write(ring, PACKET0(GA_POLY_MODE, 0)); - radeon_ring_write(ring, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); - radeon_ring_write(ring, PACKET0(GA_ROUND_MODE, 0)); - radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); - radeon_ring_write(ring, PACKET0(0x20C8, 0)); - radeon_ring_write(ring, 0); - radeon_ring_unlock_commit(rdev, ring); -} - -int rv515_mc_wait_for_idle(struct radeon_device *rdev) -{ - unsigned i; - uint32_t tmp; - - for (i = 0; i < rdev->usec_timeout; i++) { - /* read MC_STATUS */ - tmp = RREG32_MC(MC_STATUS); - if (tmp & MC_STATUS_IDLE) { - return 0; - } - DRM_UDELAY(1); - } - return -1; -} - -void rv515_vga_render_disable(struct radeon_device *rdev) -{ - WREG32(R_000300_VGA_RENDER_CONTROL, - RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); -} - -void rv515_gpu_init(struct radeon_device *rdev) -{ - unsigned pipe_select_current, gb_pipe_select, tmp; - - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "resetting GPU. Bad things might happen.\n"); - } - rv515_vga_render_disable(rdev); - r420_pipes_init(rdev); - gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); - tmp = RREG32(R300_DST_PIPE_CONFIG); - pipe_select_current = (tmp >> 2) & 3; - tmp = (1 << pipe_select_current) | - (((gb_pipe_select >> 8) & 0xF) << 4); - WREG32_PLL(0x000D, tmp); - if (r100_gui_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait GUI idle while " - "resetting GPU. Bad things might happen.\n"); - } - if (rv515_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait MC idle while " - "programming pipes. Bad things might happen.\n"); - } -} - -static void rv515_vram_get_type(struct radeon_device *rdev) -{ - uint32_t tmp; - - rdev->mc.vram_width = 128; - rdev->mc.vram_is_ddr = true; - tmp = RREG32_MC(RV515_MC_CNTL) & MEM_NUM_CHANNELS_MASK; - switch (tmp) { - case 0: - rdev->mc.vram_width = 64; - break; - case 1: - rdev->mc.vram_width = 128; - break; - default: - rdev->mc.vram_width = 128; - break; - } -} - -void rv515_mc_init(struct radeon_device *rdev) -{ - - rv515_vram_get_type(rdev); - r100_vram_init_sizes(rdev); - radeon_vram_location(rdev, &rdev->mc, 0); - rdev->mc.gtt_base_align = 0; - if (!(rdev->flags & RADEON_IS_AGP)) - radeon_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); -} - -uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) -{ - uint32_t r; - - WREG32(MC_IND_INDEX, 0x7f0000 | (reg & 0xffff)); - r = RREG32(MC_IND_DATA); - WREG32(MC_IND_INDEX, 0); - return r; -} - -void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - WREG32(MC_IND_INDEX, 0xff0000 | ((reg) & 0xffff)); - WREG32(MC_IND_DATA, (v)); - WREG32(MC_IND_INDEX, 0); -} - -#if defined(CONFIG_DEBUG_FS) -static int rv515_debugfs_pipes_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - tmp = RREG32(GB_PIPE_SELECT); - seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp); - tmp = RREG32(SU_REG_DEST); - seq_printf(m, "SU_REG_DEST 0x%08x\n", tmp); - tmp = RREG32(GB_TILE_CONFIG); - seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp); - tmp = RREG32(DST_PIPE_CONFIG); - seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp); - return 0; -} - -static int rv515_debugfs_ga_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t tmp; - - tmp = RREG32(0x2140); - seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); - radeon_asic_reset(rdev); - tmp = RREG32(0x425C); - seq_printf(m, "GA_IDLE 0x%08x\n", tmp); - return 0; -} - -static struct drm_info_list rv515_pipes_info_list[] = { - {"rv515_pipes_info", rv515_debugfs_pipes_info, 0, NULL}, -}; - -static struct drm_info_list rv515_ga_info_list[] = { - {"rv515_ga_info", rv515_debugfs_ga_info, 0, NULL}, -}; -#endif - -int rv515_debugfs_pipes_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, rv515_pipes_info_list, 1); -#else - return 0; -#endif -} - -int rv515_debugfs_ga_info_init(struct radeon_device *rdev) -{ -#if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, rv515_ga_info_list, 1); -#else - return 0; -#endif -} - -void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) -{ - save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); - save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); - save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); - save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); - save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); - save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); - - /* Stop all video */ - WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); - WREG32(R_000300_VGA_RENDER_CONTROL, 0); - WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); - WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); - WREG32(R_006080_D1CRTC_CONTROL, 0); - WREG32(R_006880_D2CRTC_CONTROL, 0); - WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); - WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); - WREG32(R_000330_D1VGA_CONTROL, 0); - WREG32(R_000338_D2VGA_CONTROL, 0); -} - -void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) -{ - WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start); - WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start); - WREG32(R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start); - WREG32(R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start); - WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); - /* Unlock host access */ - WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); - mdelay(1); - /* Restore video state */ - WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); - WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); - WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); - WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); - WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); - WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); - WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); - WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); - WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); -} - -void rv515_mc_program(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - - /* Stops all mc clients */ - rv515_mc_stop(rdev, &save); - - /* Wait for mc idle */ - if (rv515_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); - /* Write VRAM size in case we are limiting it */ - WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); - /* Program MC, should be a 32bits limited address space */ - WREG32_MC(R_000001_MC_FB_LOCATION, - S_000001_MC_FB_START(rdev->mc.vram_start >> 16) | - S_000001_MC_FB_TOP(rdev->mc.vram_end >> 16)); - WREG32(R_000134_HDP_FB_LOCATION, - S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); - if (rdev->flags & RADEON_IS_AGP) { - WREG32_MC(R_000002_MC_AGP_LOCATION, - S_000002_MC_AGP_START(rdev->mc.gtt_start >> 16) | - S_000002_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); - WREG32_MC(R_000003_MC_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); - WREG32_MC(R_000004_MC_AGP_BASE_2, - S_000004_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); - } else { - WREG32_MC(R_000002_MC_AGP_LOCATION, 0xFFFFFFFF); - WREG32_MC(R_000003_MC_AGP_BASE, 0); - WREG32_MC(R_000004_MC_AGP_BASE_2, 0); - } - - rv515_mc_resume(rdev, &save); -} - -void rv515_clock_startup(struct radeon_device *rdev) -{ - if (radeon_dynclks != -1 && radeon_dynclks) - radeon_atom_set_clock_gating(rdev, 1); - /* We need to force on some of the block */ - WREG32_PLL(R_00000F_CP_DYN_CNTL, - RREG32_PLL(R_00000F_CP_DYN_CNTL) | S_00000F_CP_FORCEON(1)); - WREG32_PLL(R_000011_E2_DYN_CNTL, - RREG32_PLL(R_000011_E2_DYN_CNTL) | S_000011_E2_FORCEON(1)); - WREG32_PLL(R_000013_IDCT_DYN_CNTL, - RREG32_PLL(R_000013_IDCT_DYN_CNTL) | S_000013_IDCT_FORCEON(1)); -} - -static int rv515_startup(struct radeon_device *rdev) -{ - int r; - - rv515_mc_program(rdev); - /* Resume clock */ - rv515_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ - rv515_gpu_init(rdev); - /* Initialize GART (initialize after TTM so we can allocate - * memory through TTM but finalize after TTM) */ - if (rdev->flags & RADEON_IS_PCIE) { - r = rv370_pcie_gart_enable(rdev); - if (r) - return r; - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - rs600_irq_set(rdev); - rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); - /* 1M ring buffer */ - r = r100_cp_init(rdev, 1024 * 1024); - if (r) { - dev_err(rdev->dev, "failed initializing CP (%d).\n", r); - return r; - } - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - rdev->accel_working = false; - return r; - } - return 0; -} - -int rv515_resume(struct radeon_device *rdev) -{ - int r; - - /* Make sur GART are not working */ - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - /* Resume clock before doing reset */ - rv515_clock_startup(rdev); - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* post */ - atom_asic_init(rdev->mode_info.atom_context); - /* Resume clock after posting */ - rv515_clock_startup(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - - rdev->accel_working = true; - r = rv515_startup(rdev); - if (r) { - rdev->accel_working = false; - } - return r; -} - -int rv515_suspend(struct radeon_device *rdev) -{ - r100_cp_disable(rdev); - radeon_wb_disable(rdev); - rs600_irq_disable(rdev); - if (rdev->flags & RADEON_IS_PCIE) - rv370_pcie_gart_disable(rdev); - return 0; -} - -void rv515_set_safe_registers(struct radeon_device *rdev) -{ - rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; - rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm); -} - -void rv515_fini(struct radeon_device *rdev) -{ - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_gem_fini(rdev); - rv370_pcie_gart_fini(rdev); - radeon_agp_fini(rdev); - radeon_irq_kms_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -int rv515_init(struct radeon_device *rdev) -{ - int r; - - /* Initialize scratch registers */ - radeon_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* TODO: disable VGA need to use VGA request */ - /* restore some register to sane defaults */ - r100_restore_sanity(rdev); - /* BIOS*/ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - if (rdev->is_atom_bios) { - r = radeon_atombios_init(rdev); - if (r) - return r; - } else { - dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); - return -EINVAL; - } - /* Reset gpu before posting otherwise ATOM will enter infinite loop */ - if (radeon_asic_reset(rdev)) { - dev_warn(rdev->dev, - "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", - RREG32(R_000E40_RBBM_STATUS), - RREG32(R_0007C0_CP_STAT)); - } - /* check if cards are posted or not */ - if (radeon_boot_test_post_card(rdev) == false) - return -EINVAL; - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) { - radeon_agp_disable(rdev); - } - } - /* initialize memory controller */ - rv515_mc_init(rdev); - rv515_debugfs(rdev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - r = radeon_irq_kms_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - r = rv370_pcie_gart_init(rdev); - if (r) - return r; - rv515_set_safe_registers(rdev); - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = rv515_startup(rdev); - if (r) { - /* Somethings want wront with the accel init stop accel */ - dev_err(rdev->dev, "Disabling GPU acceleration\n"); - r100_cp_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - rv370_pcie_gart_fini(rdev); - radeon_agp_fini(rdev); - rdev->accel_working = false; - } - return 0; -} - -void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc) -{ - int index_reg = 0x6578 + crtc->crtc_offset; - int data_reg = 0x657c + crtc->crtc_offset; - - WREG32(0x659C + crtc->crtc_offset, 0x0); - WREG32(0x6594 + crtc->crtc_offset, 0x705); - WREG32(0x65A4 + crtc->crtc_offset, 0x10001); - WREG32(0x65D8 + crtc->crtc_offset, 0x0); - WREG32(0x65B0 + crtc->crtc_offset, 0x0); - WREG32(0x65C0 + crtc->crtc_offset, 0x0); - WREG32(0x65D4 + crtc->crtc_offset, 0x0); - WREG32(index_reg, 0x0); - WREG32(data_reg, 0x841880A8); - WREG32(index_reg, 0x1); - WREG32(data_reg, 0x84208680); - WREG32(index_reg, 0x2); - WREG32(data_reg, 0xBFF880B0); - WREG32(index_reg, 0x100); - WREG32(data_reg, 0x83D88088); - WREG32(index_reg, 0x101); - WREG32(data_reg, 0x84608680); - WREG32(index_reg, 0x102); - WREG32(data_reg, 0xBFF080D0); - WREG32(index_reg, 0x200); - WREG32(data_reg, 0x83988068); - WREG32(index_reg, 0x201); - WREG32(data_reg, 0x84A08680); - WREG32(index_reg, 0x202); - WREG32(data_reg, 0xBFF080F8); - WREG32(index_reg, 0x300); - WREG32(data_reg, 0x83588058); - WREG32(index_reg, 0x301); - WREG32(data_reg, 0x84E08660); - WREG32(index_reg, 0x302); - WREG32(data_reg, 0xBFF88120); - WREG32(index_reg, 0x400); - WREG32(data_reg, 0x83188040); - WREG32(index_reg, 0x401); - WREG32(data_reg, 0x85008660); - WREG32(index_reg, 0x402); - WREG32(data_reg, 0xBFF88150); - WREG32(index_reg, 0x500); - WREG32(data_reg, 0x82D88030); - WREG32(index_reg, 0x501); - WREG32(data_reg, 0x85408640); - WREG32(index_reg, 0x502); - WREG32(data_reg, 0xBFF88180); - WREG32(index_reg, 0x600); - WREG32(data_reg, 0x82A08018); - WREG32(index_reg, 0x601); - WREG32(data_reg, 0x85808620); - WREG32(index_reg, 0x602); - WREG32(data_reg, 0xBFF081B8); - WREG32(index_reg, 0x700); - WREG32(data_reg, 0x82608010); - WREG32(index_reg, 0x701); - WREG32(data_reg, 0x85A08600); - WREG32(index_reg, 0x702); - WREG32(data_reg, 0x800081F0); - WREG32(index_reg, 0x800); - WREG32(data_reg, 0x8228BFF8); - WREG32(index_reg, 0x801); - WREG32(data_reg, 0x85E085E0); - WREG32(index_reg, 0x802); - WREG32(data_reg, 0xBFF88228); - WREG32(index_reg, 0x10000); - WREG32(data_reg, 0x82A8BF00); - WREG32(index_reg, 0x10001); - WREG32(data_reg, 0x82A08CC0); - WREG32(index_reg, 0x10002); - WREG32(data_reg, 0x8008BEF8); - WREG32(index_reg, 0x10100); - WREG32(data_reg, 0x81F0BF28); - WREG32(index_reg, 0x10101); - WREG32(data_reg, 0x83608CA0); - WREG32(index_reg, 0x10102); - WREG32(data_reg, 0x8018BED0); - WREG32(index_reg, 0x10200); - WREG32(data_reg, 0x8148BF38); - WREG32(index_reg, 0x10201); - WREG32(data_reg, 0x84408C80); - WREG32(index_reg, 0x10202); - WREG32(data_reg, 0x8008BEB8); - WREG32(index_reg, 0x10300); - WREG32(data_reg, 0x80B0BF78); - WREG32(index_reg, 0x10301); - WREG32(data_reg, 0x85008C20); - WREG32(index_reg, 0x10302); - WREG32(data_reg, 0x8020BEA0); - WREG32(index_reg, 0x10400); - WREG32(data_reg, 0x8028BF90); - WREG32(index_reg, 0x10401); - WREG32(data_reg, 0x85E08BC0); - WREG32(index_reg, 0x10402); - WREG32(data_reg, 0x8018BE90); - WREG32(index_reg, 0x10500); - WREG32(data_reg, 0xBFB8BFB0); - WREG32(index_reg, 0x10501); - WREG32(data_reg, 0x86C08B40); - WREG32(index_reg, 0x10502); - WREG32(data_reg, 0x8010BE90); - WREG32(index_reg, 0x10600); - WREG32(data_reg, 0xBF58BFC8); - WREG32(index_reg, 0x10601); - WREG32(data_reg, 0x87A08AA0); - WREG32(index_reg, 0x10602); - WREG32(data_reg, 0x8010BE98); - WREG32(index_reg, 0x10700); - WREG32(data_reg, 0xBF10BFF0); - WREG32(index_reg, 0x10701); - WREG32(data_reg, 0x886089E0); - WREG32(index_reg, 0x10702); - WREG32(data_reg, 0x8018BEB0); - WREG32(index_reg, 0x10800); - WREG32(data_reg, 0xBED8BFE8); - WREG32(index_reg, 0x10801); - WREG32(data_reg, 0x89408940); - WREG32(index_reg, 0x10802); - WREG32(data_reg, 0xBFE8BED8); - WREG32(index_reg, 0x20000); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x20001); - WREG32(data_reg, 0x90008000); - WREG32(index_reg, 0x20002); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x20003); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x20100); - WREG32(data_reg, 0x80108000); - WREG32(index_reg, 0x20101); - WREG32(data_reg, 0x8FE0BF70); - WREG32(index_reg, 0x20102); - WREG32(data_reg, 0xBFE880C0); - WREG32(index_reg, 0x20103); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x20200); - WREG32(data_reg, 0x8018BFF8); - WREG32(index_reg, 0x20201); - WREG32(data_reg, 0x8F80BF08); - WREG32(index_reg, 0x20202); - WREG32(data_reg, 0xBFD081A0); - WREG32(index_reg, 0x20203); - WREG32(data_reg, 0xBFF88000); - WREG32(index_reg, 0x20300); - WREG32(data_reg, 0x80188000); - WREG32(index_reg, 0x20301); - WREG32(data_reg, 0x8EE0BEC0); - WREG32(index_reg, 0x20302); - WREG32(data_reg, 0xBFB082A0); - WREG32(index_reg, 0x20303); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x20400); - WREG32(data_reg, 0x80188000); - WREG32(index_reg, 0x20401); - WREG32(data_reg, 0x8E00BEA0); - WREG32(index_reg, 0x20402); - WREG32(data_reg, 0xBF8883C0); - WREG32(index_reg, 0x20403); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x20500); - WREG32(data_reg, 0x80188000); - WREG32(index_reg, 0x20501); - WREG32(data_reg, 0x8D00BE90); - WREG32(index_reg, 0x20502); - WREG32(data_reg, 0xBF588500); - WREG32(index_reg, 0x20503); - WREG32(data_reg, 0x80008008); - WREG32(index_reg, 0x20600); - WREG32(data_reg, 0x80188000); - WREG32(index_reg, 0x20601); - WREG32(data_reg, 0x8BC0BE98); - WREG32(index_reg, 0x20602); - WREG32(data_reg, 0xBF308660); - WREG32(index_reg, 0x20603); - WREG32(data_reg, 0x80008008); - WREG32(index_reg, 0x20700); - WREG32(data_reg, 0x80108000); - WREG32(index_reg, 0x20701); - WREG32(data_reg, 0x8A80BEB0); - WREG32(index_reg, 0x20702); - WREG32(data_reg, 0xBF0087C0); - WREG32(index_reg, 0x20703); - WREG32(data_reg, 0x80008008); - WREG32(index_reg, 0x20800); - WREG32(data_reg, 0x80108000); - WREG32(index_reg, 0x20801); - WREG32(data_reg, 0x8920BED0); - WREG32(index_reg, 0x20802); - WREG32(data_reg, 0xBED08920); - WREG32(index_reg, 0x20803); - WREG32(data_reg, 0x80008010); - WREG32(index_reg, 0x30000); - WREG32(data_reg, 0x90008000); - WREG32(index_reg, 0x30001); - WREG32(data_reg, 0x80008000); - WREG32(index_reg, 0x30100); - WREG32(data_reg, 0x8FE0BF90); - WREG32(index_reg, 0x30101); - WREG32(data_reg, 0xBFF880A0); - WREG32(index_reg, 0x30200); - WREG32(data_reg, 0x8F60BF40); - WREG32(index_reg, 0x30201); - WREG32(data_reg, 0xBFE88180); - WREG32(index_reg, 0x30300); - WREG32(data_reg, 0x8EC0BF00); - WREG32(index_reg, 0x30301); - WREG32(data_reg, 0xBFC88280); - WREG32(index_reg, 0x30400); - WREG32(data_reg, 0x8DE0BEE0); - WREG32(index_reg, 0x30401); - WREG32(data_reg, 0xBFA083A0); - WREG32(index_reg, 0x30500); - WREG32(data_reg, 0x8CE0BED0); - WREG32(index_reg, 0x30501); - WREG32(data_reg, 0xBF7884E0); - WREG32(index_reg, 0x30600); - WREG32(data_reg, 0x8BA0BED8); - WREG32(index_reg, 0x30601); - WREG32(data_reg, 0xBF508640); - WREG32(index_reg, 0x30700); - WREG32(data_reg, 0x8A60BEE8); - WREG32(index_reg, 0x30701); - WREG32(data_reg, 0xBF2087A0); - WREG32(index_reg, 0x30800); - WREG32(data_reg, 0x8900BF00); - WREG32(index_reg, 0x30801); - WREG32(data_reg, 0xBF008900); -} - -struct rv515_watermark { - u32 lb_request_fifo_depth; - fixed20_12 num_line_pair; - fixed20_12 estimated_width; - fixed20_12 worst_case_latency; - fixed20_12 consumption_rate; - fixed20_12 active_time; - fixed20_12 dbpp; - fixed20_12 priority_mark_max; - fixed20_12 priority_mark; - fixed20_12 sclk; -}; - -void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, - struct radeon_crtc *crtc, - struct rv515_watermark *wm) -{ - struct drm_display_mode *mode = &crtc->base.mode; - fixed20_12 a, b, c; - fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width; - fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency; - - if (!crtc->base.enabled) { - /* FIXME: wouldn't it better to set priority mark to maximum */ - wm->lb_request_fifo_depth = 4; - return; - } - - if (crtc->vsc.full > dfixed_const(2)) - wm->num_line_pair.full = dfixed_const(2); - else - wm->num_line_pair.full = dfixed_const(1); - - b.full = dfixed_const(mode->crtc_hdisplay); - c.full = dfixed_const(256); - a.full = dfixed_div(b, c); - request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); - request_fifo_depth.full = dfixed_ceil(request_fifo_depth); - if (a.full < dfixed_const(4)) { - wm->lb_request_fifo_depth = 4; - } else { - wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); - } - - /* Determine consumption rate - * pclk = pixel clock period(ns) = 1000 / (mode.clock / 1000) - * vtaps = number of vertical taps, - * vsc = vertical scaling ratio, defined as source/destination - * hsc = horizontal scaling ration, defined as source/destination - */ - a.full = dfixed_const(mode->clock); - b.full = dfixed_const(1000); - a.full = dfixed_div(a, b); - pclk.full = dfixed_div(b, a); - if (crtc->rmx_type != RMX_OFF) { - b.full = dfixed_const(2); - if (crtc->vsc.full > b.full) - b.full = crtc->vsc.full; - b.full = dfixed_mul(b, crtc->hsc); - c.full = dfixed_const(2); - b.full = dfixed_div(b, c); - consumption_time.full = dfixed_div(pclk, b); - } else { - consumption_time.full = pclk.full; - } - a.full = dfixed_const(1); - wm->consumption_rate.full = dfixed_div(a, consumption_time); - - - /* Determine line time - * LineTime = total time for one line of displayhtotal - * LineTime = total number of horizontal pixels - * pclk = pixel clock period(ns) - */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - line_time.full = dfixed_mul(a, pclk); - - /* Determine active time - * ActiveTime = time of active region of display within one line, - * hactive = total number of horizontal active pixels - * htotal = total number of horizontal pixels - */ - a.full = dfixed_const(crtc->base.mode.crtc_htotal); - b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->active_time.full = dfixed_mul(line_time, b); - wm->active_time.full = dfixed_div(wm->active_time, a); - - /* Determine chunk time - * ChunkTime = the time it takes the DCP to send one chunk of data - * to the LB which consists of pipeline delay and inter chunk gap - * sclk = system clock(Mhz) - */ - a.full = dfixed_const(600 * 1000); - chunk_time.full = dfixed_div(a, rdev->pm.sclk); - read_delay_latency.full = dfixed_const(1000); - - /* Determine the worst case latency - * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) - * WorstCaseLatency = worst case time from urgent to when the MC starts - * to return data - * READ_DELAY_IDLE_MAX = constant of 1us - * ChunkTime = time it takes the DCP to send one chunk of data to the LB - * which consists of pipeline delay and inter chunk gap - */ - if (dfixed_trunc(wm->num_line_pair) > 1) { - a.full = dfixed_const(3); - wm->worst_case_latency.full = dfixed_mul(a, chunk_time); - wm->worst_case_latency.full += read_delay_latency.full; - } else { - wm->worst_case_latency.full = chunk_time.full + read_delay_latency.full; - } - - /* Determine the tolerable latency - * TolerableLatency = Any given request has only 1 line time - * for the data to be returned - * LBRequestFifoDepth = Number of chunk requests the LB can - * put into the request FIFO for a display - * LineTime = total time for one line of display - * ChunkTime = the time it takes the DCP to send one chunk - * of data to the LB which consists of - * pipeline delay and inter chunk gap - */ - if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { - tolerable_latency.full = line_time.full; - } else { - tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); - tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; - tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); - tolerable_latency.full = line_time.full - tolerable_latency.full; - } - /* We assume worst case 32bits (4 bytes) */ - wm->dbpp.full = dfixed_const(2 * 16); - - /* Determine the maximum priority mark - * width = viewport width in pixels - */ - a.full = dfixed_const(16); - wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); - wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); - wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); - - /* Determine estimated width */ - estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; - estimated_width.full = dfixed_div(estimated_width, consumption_time); - if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { - wm->priority_mark.full = wm->priority_mark_max.full; - } else { - a.full = dfixed_const(16); - wm->priority_mark.full = dfixed_div(estimated_width, a); - wm->priority_mark.full = dfixed_ceil(wm->priority_mark); - wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; - } -} - -void rv515_bandwidth_avivo_update(struct radeon_device *rdev) -{ - struct drm_display_mode *mode0 = NULL; - struct drm_display_mode *mode1 = NULL; - struct rv515_watermark wm0; - struct rv515_watermark wm1; - u32 tmp; - u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; - u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; - fixed20_12 priority_mark02, priority_mark12, fill_rate; - fixed20_12 a, b; - - if (rdev->mode_info.crtcs[0]->base.enabled) - mode0 = &rdev->mode_info.crtcs[0]->base.mode; - if (rdev->mode_info.crtcs[1]->base.enabled) - mode1 = &rdev->mode_info.crtcs[1]->base.mode; - rs690_line_buffer_adjust(rdev, mode0, mode1); - - rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0); - rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1); - - tmp = wm0.lb_request_fifo_depth; - tmp |= wm1.lb_request_fifo_depth << 16; - WREG32(LB_MAX_REQ_OUTSTANDING, tmp); - - if (mode0 && mode1) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); - else - a.full = wm0.num_line_pair.full; - if (dfixed_trunc(wm1.dbpp) > 64) - b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); - else - b.full = wm1.num_line_pair.full; - a.full += b.full; - fill_rate.full = dfixed_div(wm0.sclk, a); - if (wm0.consumption_rate.full > fill_rate.full) { - b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - priority_mark02.full = a.full + b.full; - } else { - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark02.full = dfixed_div(a, b); - } - if (wm1.consumption_rate.full > fill_rate.full) { - b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - priority_mark12.full = a.full + b.full; - } else { - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); - } - if (wm0.priority_mark.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; - if (wm0.priority_mark_max.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark_max.full; - if (wm1.priority_mark.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; - if (wm1.priority_mark_max.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); - if (rdev->disp_priority == 2) { - d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; - d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; - } - } else if (mode0) { - if (dfixed_trunc(wm0.dbpp) > 64) - a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); - else - a.full = wm0.num_line_pair.full; - fill_rate.full = dfixed_div(wm0.sclk, a); - if (wm0.consumption_rate.full > fill_rate.full) { - b.full = wm0.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm0.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - priority_mark02.full = a.full + b.full; - } else { - a.full = dfixed_mul(wm0.worst_case_latency, - wm0.consumption_rate); - b.full = dfixed_const(16); - priority_mark02.full = dfixed_div(a, b); - } - if (wm0.priority_mark.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark.full; - if (dfixed_trunc(priority_mark02) < 0) - priority_mark02.full = 0; - if (wm0.priority_mark_max.full > priority_mark02.full) - priority_mark02.full = wm0.priority_mark_max.full; - d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); - if (rdev->disp_priority == 2) - d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; - } else if (mode1) { - if (dfixed_trunc(wm1.dbpp) > 64) - a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); - else - a.full = wm1.num_line_pair.full; - fill_rate.full = dfixed_div(wm1.sclk, a); - if (wm1.consumption_rate.full > fill_rate.full) { - b.full = wm1.consumption_rate.full - fill_rate.full; - b.full = dfixed_mul(b, wm1.active_time); - a.full = dfixed_const(16); - b.full = dfixed_div(b, a); - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - priority_mark12.full = a.full + b.full; - } else { - a.full = dfixed_mul(wm1.worst_case_latency, - wm1.consumption_rate); - b.full = dfixed_const(16 * 1000); - priority_mark12.full = dfixed_div(a, b); - } - if (wm1.priority_mark.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark.full; - if (dfixed_trunc(priority_mark12) < 0) - priority_mark12.full = 0; - if (wm1.priority_mark_max.full > priority_mark12.full) - priority_mark12.full = wm1.priority_mark_max.full; - d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); - if (rdev->disp_priority == 2) - d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; - } - - WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); - WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); - WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); - WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); -} - -void rv515_bandwidth_update(struct radeon_device *rdev) -{ - uint32_t tmp; - struct drm_display_mode *mode0 = NULL; - struct drm_display_mode *mode1 = NULL; - - radeon_update_display_priority(rdev); - - if (rdev->mode_info.crtcs[0]->base.enabled) - mode0 = &rdev->mode_info.crtcs[0]->base.mode; - if (rdev->mode_info.crtcs[1]->base.enabled) - mode1 = &rdev->mode_info.crtcs[1]->base.mode; - /* - * Set display0/1 priority up in the memory controller for - * modes if the user specifies HIGH for displaypriority - * option. - */ - if ((rdev->disp_priority == 2) && - (rdev->family == CHIP_RV515)) { - tmp = RREG32_MC(MC_MISC_LAT_TIMER); - tmp &= ~MC_DISP1R_INIT_LAT_MASK; - tmp &= ~MC_DISP0R_INIT_LAT_MASK; - if (mode1) - tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT); - if (mode0) - tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT); - WREG32_MC(MC_MISC_LAT_TIMER, tmp); - } - rv515_bandwidth_avivo_update(rdev); -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515d.h deleted file mode 100644 index 590309a7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv515d.h +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef __RV515D_H__ -#define __RV515D_H__ - -/* - * RV515 registers - */ -#define PCIE_INDEX 0x0030 -#define PCIE_DATA 0x0034 -#define MC_IND_INDEX 0x0070 -#define MC_IND_WR_EN (1 << 24) -#define MC_IND_DATA 0x0074 -#define RBBM_SOFT_RESET 0x00F0 -#define CONFIG_MEMSIZE 0x00F8 -#define HDP_FB_LOCATION 0x0134 -#define CP_CSQ_CNTL 0x0740 -#define CP_CSQ_MODE 0x0744 -#define CP_CSQ_ADDR 0x07F0 -#define CP_CSQ_DATA 0x07F4 -#define CP_CSQ_STAT 0x07F8 -#define CP_CSQ2_STAT 0x07FC -#define RBBM_STATUS 0x0E40 -#define DST_PIPE_CONFIG 0x170C -#define WAIT_UNTIL 0x1720 -#define WAIT_2D_IDLE (1 << 14) -#define WAIT_3D_IDLE (1 << 15) -#define WAIT_2D_IDLECLEAN (1 << 16) -#define WAIT_3D_IDLECLEAN (1 << 17) -#define ISYNC_CNTL 0x1724 -#define ISYNC_ANY2D_IDLE3D (1 << 0) -#define ISYNC_ANY3D_IDLE2D (1 << 1) -#define ISYNC_TRIG2D_IDLE3D (1 << 2) -#define ISYNC_TRIG3D_IDLE2D (1 << 3) -#define ISYNC_WAIT_IDLEGUI (1 << 4) -#define ISYNC_CPSCRATCH_IDLEGUI (1 << 5) -#define VAP_INDEX_OFFSET 0x208C -#define VAP_PVS_STATE_FLUSH_REG 0x2284 -#define GB_ENABLE 0x4008 -#define GB_MSPOS0 0x4010 -#define MS_X0_SHIFT 0 -#define MS_Y0_SHIFT 4 -#define MS_X1_SHIFT 8 -#define MS_Y1_SHIFT 12 -#define MS_X2_SHIFT 16 -#define MS_Y2_SHIFT 20 -#define MSBD0_Y_SHIFT 24 -#define MSBD0_X_SHIFT 28 -#define GB_MSPOS1 0x4014 -#define MS_X3_SHIFT 0 -#define MS_Y3_SHIFT 4 -#define MS_X4_SHIFT 8 -#define MS_Y4_SHIFT 12 -#define MS_X5_SHIFT 16 -#define MS_Y5_SHIFT 20 -#define MSBD1_SHIFT 24 -#define GB_TILE_CONFIG 0x4018 -#define ENABLE_TILING (1 << 0) -#define PIPE_COUNT_MASK 0x0000000E -#define PIPE_COUNT_SHIFT 1 -#define TILE_SIZE_8 (0 << 4) -#define TILE_SIZE_16 (1 << 4) -#define TILE_SIZE_32 (2 << 4) -#define SUBPIXEL_1_12 (0 << 16) -#define SUBPIXEL_1_16 (1 << 16) -#define GB_SELECT 0x401C -#define GB_AA_CONFIG 0x4020 -#define GB_PIPE_SELECT 0x402C -#define GA_ENHANCE 0x4274 -#define GA_DEADLOCK_CNTL (1 << 0) -#define GA_FASTSYNC_CNTL (1 << 1) -#define GA_POLY_MODE 0x4288 -#define FRONT_PTYPE_POINT (0 << 4) -#define FRONT_PTYPE_LINE (1 << 4) -#define FRONT_PTYPE_TRIANGE (2 << 4) -#define BACK_PTYPE_POINT (0 << 7) -#define BACK_PTYPE_LINE (1 << 7) -#define BACK_PTYPE_TRIANGE (2 << 7) -#define GA_ROUND_MODE 0x428C -#define GEOMETRY_ROUND_TRUNC (0 << 0) -#define GEOMETRY_ROUND_NEAREST (1 << 0) -#define COLOR_ROUND_TRUNC (0 << 2) -#define COLOR_ROUND_NEAREST (1 << 2) -#define SU_REG_DEST 0x42C8 -#define RB3D_DSTCACHE_CTLSTAT 0x4E4C -#define RB3D_DC_FLUSH (2 << 0) -#define RB3D_DC_FREE (2 << 2) -#define RB3D_DC_FINISH (1 << 4) -#define ZB_ZCACHE_CTLSTAT 0x4F18 -#define ZC_FLUSH (1 << 0) -#define ZC_FREE (1 << 1) -#define DC_LB_MEMORY_SPLIT 0x6520 -#define DC_LB_MEMORY_SPLIT_MASK 0x00000003 -#define DC_LB_MEMORY_SPLIT_SHIFT 0 -#define DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0 -#define DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1 -#define DC_LB_MEMORY_SPLIT_D1_ONLY 2 -#define DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3 -#define DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2) -#define DC_LB_DISP1_END_ADR_SHIFT 4 -#define DC_LB_DISP1_END_ADR_MASK 0x00007FF0 -#define D1MODE_PRIORITY_A_CNT 0x6548 -#define MODE_PRIORITY_MARK_MASK 0x00007FFF -#define MODE_PRIORITY_OFF (1 << 16) -#define MODE_PRIORITY_ALWAYS_ON (1 << 20) -#define MODE_PRIORITY_FORCE_MASK (1 << 24) -#define D1MODE_PRIORITY_B_CNT 0x654C -#define LB_MAX_REQ_OUTSTANDING 0x6D58 -#define LB_D1_MAX_REQ_OUTSTANDING_MASK 0x0000000F -#define LB_D1_MAX_REQ_OUTSTANDING_SHIFT 0 -#define LB_D2_MAX_REQ_OUTSTANDING_MASK 0x000F0000 -#define LB_D2_MAX_REQ_OUTSTANDING_SHIFT 16 -#define D2MODE_PRIORITY_A_CNT 0x6D48 -#define D2MODE_PRIORITY_B_CNT 0x6D4C - -/* ix[MC] registers */ -#define MC_FB_LOCATION 0x01 -#define MC_FB_START_MASK 0x0000FFFF -#define MC_FB_START_SHIFT 0 -#define MC_FB_TOP_MASK 0xFFFF0000 -#define MC_FB_TOP_SHIFT 16 -#define MC_AGP_LOCATION 0x02 -#define MC_AGP_START_MASK 0x0000FFFF -#define MC_AGP_START_SHIFT 0 -#define MC_AGP_TOP_MASK 0xFFFF0000 -#define MC_AGP_TOP_SHIFT 16 -#define MC_AGP_BASE 0x03 -#define MC_AGP_BASE_2 0x04 -#define MC_CNTL 0x5 -#define MEM_NUM_CHANNELS_MASK 0x00000003 -#define MC_STATUS 0x08 -#define MC_STATUS_IDLE (1 << 4) -#define MC_MISC_LAT_TIMER 0x09 -#define MC_CPR_INIT_LAT_MASK 0x0000000F -#define MC_VF_INIT_LAT_MASK 0x000000F0 -#define MC_DISP0R_INIT_LAT_MASK 0x00000F00 -#define MC_DISP0R_INIT_LAT_SHIFT 8 -#define MC_DISP1R_INIT_LAT_MASK 0x0000F000 -#define MC_DISP1R_INIT_LAT_SHIFT 12 -#define MC_FIXED_INIT_LAT_MASK 0x000F0000 -#define MC_E2R_INIT_LAT_MASK 0x00F00000 -#define SAME_PAGE_PRIO_MASK 0x0F000000 -#define MC_GLOBW_INIT_LAT_MASK 0xF0000000 - - -/* - * PM4 packet - */ -#define CP_PACKET0 0x00000000 -#define PACKET0_BASE_INDEX_SHIFT 0 -#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) -#define PACKET0_COUNT_SHIFT 16 -#define PACKET0_COUNT_MASK (0x3fff << 16) -#define CP_PACKET1 0x40000000 -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) -#define CP_PACKET3 0xC0000000 -#define PACKET3_IT_OPCODE_SHIFT 8 -#define PACKET3_IT_OPCODE_MASK (0xff << 8) -#define PACKET3_COUNT_SHIFT 16 -#define PACKET3_COUNT_MASK (0x3fff << 16) -/* PACKET3 op code */ -#define PACKET3_NOP 0x10 -#define PACKET3_3D_DRAW_VBUF 0x28 -#define PACKET3_3D_DRAW_IMMD 0x29 -#define PACKET3_3D_DRAW_INDX 0x2A -#define PACKET3_3D_LOAD_VBPNTR 0x2F -#define PACKET3_INDX_BUFFER 0x33 -#define PACKET3_3D_DRAW_VBUF_2 0x34 -#define PACKET3_3D_DRAW_IMMD_2 0x35 -#define PACKET3_3D_DRAW_INDX_2 0x36 -#define PACKET3_BITBLT_MULTI 0x9B - -#define PACKET0(reg, n) (CP_PACKET0 | \ - REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ - REG_SET(PACKET0_COUNT, (n))) -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -#define PACKET3(op, n) (CP_PACKET3 | \ - REG_SET(PACKET3_IT_OPCODE, (op)) | \ - REG_SET(PACKET3_COUNT, (n))) - -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) - -/* Registers */ -#define R_0000F0_RBBM_SOFT_RESET 0x0000F0 -#define S_0000F0_SOFT_RESET_CP(x) (((x) & 0x1) << 0) -#define G_0000F0_SOFT_RESET_CP(x) (((x) >> 0) & 0x1) -#define C_0000F0_SOFT_RESET_CP 0xFFFFFFFE -#define S_0000F0_SOFT_RESET_HI(x) (((x) & 0x1) << 1) -#define G_0000F0_SOFT_RESET_HI(x) (((x) >> 1) & 0x1) -#define C_0000F0_SOFT_RESET_HI 0xFFFFFFFD -#define S_0000F0_SOFT_RESET_VAP(x) (((x) & 0x1) << 2) -#define G_0000F0_SOFT_RESET_VAP(x) (((x) >> 2) & 0x1) -#define C_0000F0_SOFT_RESET_VAP 0xFFFFFFFB -#define S_0000F0_SOFT_RESET_RE(x) (((x) & 0x1) << 3) -#define G_0000F0_SOFT_RESET_RE(x) (((x) >> 3) & 0x1) -#define C_0000F0_SOFT_RESET_RE 0xFFFFFFF7 -#define S_0000F0_SOFT_RESET_PP(x) (((x) & 0x1) << 4) -#define G_0000F0_SOFT_RESET_PP(x) (((x) >> 4) & 0x1) -#define C_0000F0_SOFT_RESET_PP 0xFFFFFFEF -#define S_0000F0_SOFT_RESET_E2(x) (((x) & 0x1) << 5) -#define G_0000F0_SOFT_RESET_E2(x) (((x) >> 5) & 0x1) -#define C_0000F0_SOFT_RESET_E2 0xFFFFFFDF -#define S_0000F0_SOFT_RESET_RB(x) (((x) & 0x1) << 6) -#define G_0000F0_SOFT_RESET_RB(x) (((x) >> 6) & 0x1) -#define C_0000F0_SOFT_RESET_RB 0xFFFFFFBF -#define S_0000F0_SOFT_RESET_HDP(x) (((x) & 0x1) << 7) -#define G_0000F0_SOFT_RESET_HDP(x) (((x) >> 7) & 0x1) -#define C_0000F0_SOFT_RESET_HDP 0xFFFFFF7F -#define S_0000F0_SOFT_RESET_MC(x) (((x) & 0x1) << 8) -#define G_0000F0_SOFT_RESET_MC(x) (((x) >> 8) & 0x1) -#define C_0000F0_SOFT_RESET_MC 0xFFFFFEFF -#define S_0000F0_SOFT_RESET_AIC(x) (((x) & 0x1) << 9) -#define G_0000F0_SOFT_RESET_AIC(x) (((x) >> 9) & 0x1) -#define C_0000F0_SOFT_RESET_AIC 0xFFFFFDFF -#define S_0000F0_SOFT_RESET_VIP(x) (((x) & 0x1) << 10) -#define G_0000F0_SOFT_RESET_VIP(x) (((x) >> 10) & 0x1) -#define C_0000F0_SOFT_RESET_VIP 0xFFFFFBFF -#define S_0000F0_SOFT_RESET_DISP(x) (((x) & 0x1) << 11) -#define G_0000F0_SOFT_RESET_DISP(x) (((x) >> 11) & 0x1) -#define C_0000F0_SOFT_RESET_DISP 0xFFFFF7FF -#define S_0000F0_SOFT_RESET_CG(x) (((x) & 0x1) << 12) -#define G_0000F0_SOFT_RESET_CG(x) (((x) >> 12) & 0x1) -#define C_0000F0_SOFT_RESET_CG 0xFFFFEFFF -#define S_0000F0_SOFT_RESET_GA(x) (((x) & 0x1) << 13) -#define G_0000F0_SOFT_RESET_GA(x) (((x) >> 13) & 0x1) -#define C_0000F0_SOFT_RESET_GA 0xFFFFDFFF -#define S_0000F0_SOFT_RESET_IDCT(x) (((x) & 0x1) << 14) -#define G_0000F0_SOFT_RESET_IDCT(x) (((x) >> 14) & 0x1) -#define C_0000F0_SOFT_RESET_IDCT 0xFFFFBFFF -#define R_0000F8_CONFIG_MEMSIZE 0x0000F8 -#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) -#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_0000F8_CONFIG_MEMSIZE 0x00000000 -#define R_000134_HDP_FB_LOCATION 0x000134 -#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000134_HDP_FB_START 0xFFFF0000 -#define R_000300_VGA_RENDER_CONTROL 0x000300 -#define S_000300_VGA_BLINK_RATE(x) (((x) & 0x1F) << 0) -#define G_000300_VGA_BLINK_RATE(x) (((x) >> 0) & 0x1F) -#define C_000300_VGA_BLINK_RATE 0xFFFFFFE0 -#define S_000300_VGA_BLINK_MODE(x) (((x) & 0x3) << 5) -#define G_000300_VGA_BLINK_MODE(x) (((x) >> 5) & 0x3) -#define C_000300_VGA_BLINK_MODE 0xFFFFFF9F -#define S_000300_VGA_CURSOR_BLINK_INVERT(x) (((x) & 0x1) << 7) -#define G_000300_VGA_CURSOR_BLINK_INVERT(x) (((x) >> 7) & 0x1) -#define C_000300_VGA_CURSOR_BLINK_INVERT 0xFFFFFF7F -#define S_000300_VGA_EXTD_ADDR_COUNT_ENABLE(x) (((x) & 0x1) << 8) -#define G_000300_VGA_EXTD_ADDR_COUNT_ENABLE(x) (((x) >> 8) & 0x1) -#define C_000300_VGA_EXTD_ADDR_COUNT_ENABLE 0xFFFFFEFF -#define S_000300_VGA_VSTATUS_CNTL(x) (((x) & 0x3) << 16) -#define G_000300_VGA_VSTATUS_CNTL(x) (((x) >> 16) & 0x3) -#define C_000300_VGA_VSTATUS_CNTL 0xFFFCFFFF -#define S_000300_VGA_LOCK_8DOT(x) (((x) & 0x1) << 24) -#define G_000300_VGA_LOCK_8DOT(x) (((x) >> 24) & 0x1) -#define C_000300_VGA_LOCK_8DOT 0xFEFFFFFF -#define S_000300_VGAREG_LINECMP_COMPATIBILITY_SEL(x) (((x) & 0x1) << 25) -#define G_000300_VGAREG_LINECMP_COMPATIBILITY_SEL(x) (((x) >> 25) & 0x1) -#define C_000300_VGAREG_LINECMP_COMPATIBILITY_SEL 0xFDFFFFFF -#define R_000310_VGA_MEMORY_BASE_ADDRESS 0x000310 -#define S_000310_VGA_MEMORY_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000310_VGA_MEMORY_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000310_VGA_MEMORY_BASE_ADDRESS 0x00000000 -#define R_000328_VGA_HDP_CONTROL 0x000328 -#define S_000328_VGA_MEM_PAGE_SELECT_EN(x) (((x) & 0x1) << 0) -#define G_000328_VGA_MEM_PAGE_SELECT_EN(x) (((x) >> 0) & 0x1) -#define C_000328_VGA_MEM_PAGE_SELECT_EN 0xFFFFFFFE -#define S_000328_VGA_RBBM_LOCK_DISABLE(x) (((x) & 0x1) << 8) -#define G_000328_VGA_RBBM_LOCK_DISABLE(x) (((x) >> 8) & 0x1) -#define C_000328_VGA_RBBM_LOCK_DISABLE 0xFFFFFEFF -#define S_000328_VGA_SOFT_RESET(x) (((x) & 0x1) << 16) -#define G_000328_VGA_SOFT_RESET(x) (((x) >> 16) & 0x1) -#define C_000328_VGA_SOFT_RESET 0xFFFEFFFF -#define S_000328_VGA_TEST_RESET_CONTROL(x) (((x) & 0x1) << 24) -#define G_000328_VGA_TEST_RESET_CONTROL(x) (((x) >> 24) & 0x1) -#define C_000328_VGA_TEST_RESET_CONTROL 0xFEFFFFFF -#define R_000330_D1VGA_CONTROL 0x000330 -#define S_000330_D1VGA_MODE_ENABLE(x) (((x) & 0x1) << 0) -#define G_000330_D1VGA_MODE_ENABLE(x) (((x) >> 0) & 0x1) -#define C_000330_D1VGA_MODE_ENABLE 0xFFFFFFFE -#define S_000330_D1VGA_TIMING_SELECT(x) (((x) & 0x1) << 8) -#define G_000330_D1VGA_TIMING_SELECT(x) (((x) >> 8) & 0x1) -#define C_000330_D1VGA_TIMING_SELECT 0xFFFFFEFF -#define S_000330_D1VGA_SYNC_POLARITY_SELECT(x) (((x) & 0x1) << 9) -#define G_000330_D1VGA_SYNC_POLARITY_SELECT(x) (((x) >> 9) & 0x1) -#define C_000330_D1VGA_SYNC_POLARITY_SELECT 0xFFFFFDFF -#define S_000330_D1VGA_OVERSCAN_TIMING_SELECT(x) (((x) & 0x1) << 10) -#define G_000330_D1VGA_OVERSCAN_TIMING_SELECT(x) (((x) >> 10) & 0x1) -#define C_000330_D1VGA_OVERSCAN_TIMING_SELECT 0xFFFFFBFF -#define S_000330_D1VGA_OVERSCAN_COLOR_EN(x) (((x) & 0x1) << 16) -#define G_000330_D1VGA_OVERSCAN_COLOR_EN(x) (((x) >> 16) & 0x1) -#define C_000330_D1VGA_OVERSCAN_COLOR_EN 0xFFFEFFFF -#define S_000330_D1VGA_ROTATE(x) (((x) & 0x3) << 24) -#define G_000330_D1VGA_ROTATE(x) (((x) >> 24) & 0x3) -#define C_000330_D1VGA_ROTATE 0xFCFFFFFF -#define R_000338_D2VGA_CONTROL 0x000338 -#define S_000338_D2VGA_MODE_ENABLE(x) (((x) & 0x1) << 0) -#define G_000338_D2VGA_MODE_ENABLE(x) (((x) >> 0) & 0x1) -#define C_000338_D2VGA_MODE_ENABLE 0xFFFFFFFE -#define S_000338_D2VGA_TIMING_SELECT(x) (((x) & 0x1) << 8) -#define G_000338_D2VGA_TIMING_SELECT(x) (((x) >> 8) & 0x1) -#define C_000338_D2VGA_TIMING_SELECT 0xFFFFFEFF -#define S_000338_D2VGA_SYNC_POLARITY_SELECT(x) (((x) & 0x1) << 9) -#define G_000338_D2VGA_SYNC_POLARITY_SELECT(x) (((x) >> 9) & 0x1) -#define C_000338_D2VGA_SYNC_POLARITY_SELECT 0xFFFFFDFF -#define S_000338_D2VGA_OVERSCAN_TIMING_SELECT(x) (((x) & 0x1) << 10) -#define G_000338_D2VGA_OVERSCAN_TIMING_SELECT(x) (((x) >> 10) & 0x1) -#define C_000338_D2VGA_OVERSCAN_TIMING_SELECT 0xFFFFFBFF -#define S_000338_D2VGA_OVERSCAN_COLOR_EN(x) (((x) & 0x1) << 16) -#define G_000338_D2VGA_OVERSCAN_COLOR_EN(x) (((x) >> 16) & 0x1) -#define C_000338_D2VGA_OVERSCAN_COLOR_EN 0xFFFEFFFF -#define S_000338_D2VGA_ROTATE(x) (((x) & 0x3) << 24) -#define G_000338_D2VGA_ROTATE(x) (((x) >> 24) & 0x3) -#define C_000338_D2VGA_ROTATE 0xFCFFFFFF -#define R_0007C0_CP_STAT 0x0007C0 -#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) -#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) -#define C_0007C0_MRU_BUSY 0xFFFFFFFE -#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) -#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) -#define C_0007C0_MWU_BUSY 0xFFFFFFFD -#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) -#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) -#define C_0007C0_RSIU_BUSY 0xFFFFFFFB -#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) -#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) -#define C_0007C0_RCIU_BUSY 0xFFFFFFF7 -#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) -#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) -#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF -#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) -#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) -#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF -#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) -#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) -#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF -#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) -#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) -#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF -#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) -#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) -#define C_0007C0_CSI_BUSY 0xFFFFDFFF -#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) -#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) -#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF -#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) -#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) -#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF -#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) -#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) -#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF -#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) -#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) -#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF -#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) -#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) -#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF -#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) -#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) -#define C_0007C0_CP_BUSY 0x7FFFFFFF -#define R_000E40_RBBM_STATUS 0x000E40 -#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) -#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) -#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 -#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) -#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) -#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF -#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) -#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) -#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF -#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) -#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) -#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF -#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) -#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) -#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF -#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) -#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) -#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF -#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) -#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) -#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF -#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) -#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) -#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF -#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) -#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) -#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF -#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) -#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) -#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF -#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) -#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) -#define C_000E40_E2_BUSY 0xFFFDFFFF -#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) -#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) -#define C_000E40_RB2D_BUSY 0xFFFBFFFF -#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) -#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) -#define C_000E40_RB3D_BUSY 0xFFF7FFFF -#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) -#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) -#define C_000E40_VAP_BUSY 0xFFEFFFFF -#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) -#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) -#define C_000E40_RE_BUSY 0xFFDFFFFF -#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) -#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) -#define C_000E40_TAM_BUSY 0xFFBFFFFF -#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) -#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) -#define C_000E40_TDM_BUSY 0xFF7FFFFF -#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) -#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) -#define C_000E40_PB_BUSY 0xFEFFFFFF -#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) -#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) -#define C_000E40_TIM_BUSY 0xFDFFFFFF -#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) -#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) -#define C_000E40_GA_BUSY 0xFBFFFFFF -#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) -#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) -#define C_000E40_CBA2D_BUSY 0xF7FFFFFF -#define S_000E40_RBBM_HIBUSY(x) (((x) & 0x1) << 28) -#define G_000E40_RBBM_HIBUSY(x) (((x) >> 28) & 0x1) -#define C_000E40_RBBM_HIBUSY 0xEFFFFFFF -#define S_000E40_SKID_CFBUSY(x) (((x) & 0x1) << 29) -#define G_000E40_SKID_CFBUSY(x) (((x) >> 29) & 0x1) -#define C_000E40_SKID_CFBUSY 0xDFFFFFFF -#define S_000E40_VAP_VF_BUSY(x) (((x) & 0x1) << 30) -#define G_000E40_VAP_VF_BUSY(x) (((x) >> 30) & 0x1) -#define C_000E40_VAP_VF_BUSY 0xBFFFFFFF -#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) -#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) -#define C_000E40_GUI_ACTIVE 0x7FFFFFFF -#define R_006080_D1CRTC_CONTROL 0x006080 -#define S_006080_D1CRTC_MASTER_EN(x) (((x) & 0x1) << 0) -#define G_006080_D1CRTC_MASTER_EN(x) (((x) >> 0) & 0x1) -#define C_006080_D1CRTC_MASTER_EN 0xFFFFFFFE -#define S_006080_D1CRTC_SYNC_RESET_SEL(x) (((x) & 0x1) << 4) -#define G_006080_D1CRTC_SYNC_RESET_SEL(x) (((x) >> 4) & 0x1) -#define C_006080_D1CRTC_SYNC_RESET_SEL 0xFFFFFFEF -#define S_006080_D1CRTC_DISABLE_POINT_CNTL(x) (((x) & 0x3) << 8) -#define G_006080_D1CRTC_DISABLE_POINT_CNTL(x) (((x) >> 8) & 0x3) -#define C_006080_D1CRTC_DISABLE_POINT_CNTL 0xFFFFFCFF -#define S_006080_D1CRTC_CURRENT_MASTER_EN_STATE(x) (((x) & 0x1) << 16) -#define G_006080_D1CRTC_CURRENT_MASTER_EN_STATE(x) (((x) >> 16) & 0x1) -#define C_006080_D1CRTC_CURRENT_MASTER_EN_STATE 0xFFFEFFFF -#define S_006080_D1CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) & 0x1) << 24) -#define G_006080_D1CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) >> 24) & 0x1) -#define C_006080_D1CRTC_DISP_READ_REQUEST_DISABLE 0xFEFFFFFF -#define R_0060E8_D1CRTC_UPDATE_LOCK 0x0060E8 -#define S_0060E8_D1CRTC_UPDATE_LOCK(x) (((x) & 0x1) << 0) -#define G_0060E8_D1CRTC_UPDATE_LOCK(x) (((x) >> 0) & 0x1) -#define C_0060E8_D1CRTC_UPDATE_LOCK 0xFFFFFFFE -#define R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x006110 -#define S_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x00000000 -#define R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x006118 -#define S_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x00000000 -#define R_006880_D2CRTC_CONTROL 0x006880 -#define S_006880_D2CRTC_MASTER_EN(x) (((x) & 0x1) << 0) -#define G_006880_D2CRTC_MASTER_EN(x) (((x) >> 0) & 0x1) -#define C_006880_D2CRTC_MASTER_EN 0xFFFFFFFE -#define S_006880_D2CRTC_SYNC_RESET_SEL(x) (((x) & 0x1) << 4) -#define G_006880_D2CRTC_SYNC_RESET_SEL(x) (((x) >> 4) & 0x1) -#define C_006880_D2CRTC_SYNC_RESET_SEL 0xFFFFFFEF -#define S_006880_D2CRTC_DISABLE_POINT_CNTL(x) (((x) & 0x3) << 8) -#define G_006880_D2CRTC_DISABLE_POINT_CNTL(x) (((x) >> 8) & 0x3) -#define C_006880_D2CRTC_DISABLE_POINT_CNTL 0xFFFFFCFF -#define S_006880_D2CRTC_CURRENT_MASTER_EN_STATE(x) (((x) & 0x1) << 16) -#define G_006880_D2CRTC_CURRENT_MASTER_EN_STATE(x) (((x) >> 16) & 0x1) -#define C_006880_D2CRTC_CURRENT_MASTER_EN_STATE 0xFFFEFFFF -#define S_006880_D2CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) & 0x1) << 24) -#define G_006880_D2CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) >> 24) & 0x1) -#define C_006880_D2CRTC_DISP_READ_REQUEST_DISABLE 0xFEFFFFFF -#define R_0068E8_D2CRTC_UPDATE_LOCK 0x0068E8 -#define S_0068E8_D2CRTC_UPDATE_LOCK(x) (((x) & 0x1) << 0) -#define G_0068E8_D2CRTC_UPDATE_LOCK(x) (((x) >> 0) & 0x1) -#define C_0068E8_D2CRTC_UPDATE_LOCK 0xFFFFFFFE -#define R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x006910 -#define S_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x00000000 -#define R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x006918 -#define S_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) -#define G_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x00000000 - - -#define R_000001_MC_FB_LOCATION 0x000001 -#define S_000001_MC_FB_START(x) (((x) & 0xFFFF) << 0) -#define G_000001_MC_FB_START(x) (((x) >> 0) & 0xFFFF) -#define C_000001_MC_FB_START 0xFFFF0000 -#define S_000001_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000001_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000001_MC_FB_TOP 0x0000FFFF -#define R_000002_MC_AGP_LOCATION 0x000002 -#define S_000002_MC_AGP_START(x) (((x) & 0xFFFF) << 0) -#define G_000002_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) -#define C_000002_MC_AGP_START 0xFFFF0000 -#define S_000002_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) -#define G_000002_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) -#define C_000002_MC_AGP_TOP 0x0000FFFF -#define R_000003_MC_AGP_BASE 0x000003 -#define S_000003_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) -#define G_000003_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) -#define C_000003_AGP_BASE_ADDR 0x00000000 -#define R_000004_MC_AGP_BASE_2 0x000004 -#define S_000004_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) -#define G_000004_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) -#define C_000004_AGP_BASE_ADDR_2 0xFFFFFFF0 - - -#define R_00000F_CP_DYN_CNTL 0x00000F -#define S_00000F_CP_FORCEON(x) (((x) & 0x1) << 0) -#define G_00000F_CP_FORCEON(x) (((x) >> 0) & 0x1) -#define C_00000F_CP_FORCEON 0xFFFFFFFE -#define S_00000F_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1) -#define G_00000F_CP_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1) -#define C_00000F_CP_MAX_DYN_STOP_LAT 0xFFFFFFFD -#define S_00000F_CP_CLOCK_STATUS(x) (((x) & 0x1) << 2) -#define G_00000F_CP_CLOCK_STATUS(x) (((x) >> 2) & 0x1) -#define C_00000F_CP_CLOCK_STATUS 0xFFFFFFFB -#define S_00000F_CP_PROG_SHUTOFF(x) (((x) & 0x1) << 3) -#define G_00000F_CP_PROG_SHUTOFF(x) (((x) >> 3) & 0x1) -#define C_00000F_CP_PROG_SHUTOFF 0xFFFFFFF7 -#define S_00000F_CP_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4) -#define G_00000F_CP_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF) -#define C_00000F_CP_PROG_DELAY_VALUE 0xFFFFF00F -#define S_00000F_CP_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12) -#define G_00000F_CP_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF) -#define C_00000F_CP_LOWER_POWER_IDLE 0xFFF00FFF -#define S_00000F_CP_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20) -#define G_00000F_CP_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1) -#define C_00000F_CP_LOWER_POWER_IGNORE 0xFFEFFFFF -#define S_00000F_CP_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21) -#define G_00000F_CP_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1) -#define C_00000F_CP_NORMAL_POWER_IGNORE 0xFFDFFFFF -#define S_00000F_SPARE(x) (((x) & 0x3) << 22) -#define G_00000F_SPARE(x) (((x) >> 22) & 0x3) -#define C_00000F_SPARE 0xFF3FFFFF -#define S_00000F_CP_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24) -#define G_00000F_CP_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF) -#define C_00000F_CP_NORMAL_POWER_BUSY 0x00FFFFFF -#define R_000011_E2_DYN_CNTL 0x000011 -#define S_000011_E2_FORCEON(x) (((x) & 0x1) << 0) -#define G_000011_E2_FORCEON(x) (((x) >> 0) & 0x1) -#define C_000011_E2_FORCEON 0xFFFFFFFE -#define S_000011_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1) -#define G_000011_E2_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1) -#define C_000011_E2_MAX_DYN_STOP_LAT 0xFFFFFFFD -#define S_000011_E2_CLOCK_STATUS(x) (((x) & 0x1) << 2) -#define G_000011_E2_CLOCK_STATUS(x) (((x) >> 2) & 0x1) -#define C_000011_E2_CLOCK_STATUS 0xFFFFFFFB -#define S_000011_E2_PROG_SHUTOFF(x) (((x) & 0x1) << 3) -#define G_000011_E2_PROG_SHUTOFF(x) (((x) >> 3) & 0x1) -#define C_000011_E2_PROG_SHUTOFF 0xFFFFFFF7 -#define S_000011_E2_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4) -#define G_000011_E2_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF) -#define C_000011_E2_PROG_DELAY_VALUE 0xFFFFF00F -#define S_000011_E2_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12) -#define G_000011_E2_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF) -#define C_000011_E2_LOWER_POWER_IDLE 0xFFF00FFF -#define S_000011_E2_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20) -#define G_000011_E2_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1) -#define C_000011_E2_LOWER_POWER_IGNORE 0xFFEFFFFF -#define S_000011_E2_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21) -#define G_000011_E2_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1) -#define C_000011_E2_NORMAL_POWER_IGNORE 0xFFDFFFFF -#define S_000011_SPARE(x) (((x) & 0x3) << 22) -#define G_000011_SPARE(x) (((x) >> 22) & 0x3) -#define C_000011_SPARE 0xFF3FFFFF -#define S_000011_E2_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24) -#define G_000011_E2_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF) -#define C_000011_E2_NORMAL_POWER_BUSY 0x00FFFFFF -#define R_000013_IDCT_DYN_CNTL 0x000013 -#define S_000013_IDCT_FORCEON(x) (((x) & 0x1) << 0) -#define G_000013_IDCT_FORCEON(x) (((x) >> 0) & 0x1) -#define C_000013_IDCT_FORCEON 0xFFFFFFFE -#define S_000013_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1) -#define G_000013_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1) -#define C_000013_IDCT_MAX_DYN_STOP_LAT 0xFFFFFFFD -#define S_000013_IDCT_CLOCK_STATUS(x) (((x) & 0x1) << 2) -#define G_000013_IDCT_CLOCK_STATUS(x) (((x) >> 2) & 0x1) -#define C_000013_IDCT_CLOCK_STATUS 0xFFFFFFFB -#define S_000013_IDCT_PROG_SHUTOFF(x) (((x) & 0x1) << 3) -#define G_000013_IDCT_PROG_SHUTOFF(x) (((x) >> 3) & 0x1) -#define C_000013_IDCT_PROG_SHUTOFF 0xFFFFFFF7 -#define S_000013_IDCT_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4) -#define G_000013_IDCT_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF) -#define C_000013_IDCT_PROG_DELAY_VALUE 0xFFFFF00F -#define S_000013_IDCT_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12) -#define G_000013_IDCT_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF) -#define C_000013_IDCT_LOWER_POWER_IDLE 0xFFF00FFF -#define S_000013_IDCT_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20) -#define G_000013_IDCT_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1) -#define C_000013_IDCT_LOWER_POWER_IGNORE 0xFFEFFFFF -#define S_000013_IDCT_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21) -#define G_000013_IDCT_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1) -#define C_000013_IDCT_NORMAL_POWER_IGNORE 0xFFDFFFFF -#define S_000013_SPARE(x) (((x) & 0x3) << 22) -#define G_000013_SPARE(x) (((x) >> 22) & 0x3) -#define C_000013_SPARE 0xFF3FFFFF -#define S_000013_IDCT_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24) -#define G_000013_IDCT_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF) -#define C_000013_IDCT_NORMAL_POWER_BUSY 0x00FFFFFF - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770.c deleted file mode 100644 index 591040b9..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770.c +++ /dev/null @@ -1,1375 +0,0 @@ -/* - * Copyright 2008 Advanced Micro Devices, Inc. - * Copyright 2008 Red Hat Inc. - * Copyright 2009 Jerome Glisse. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#include -#include -#include -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "radeon_drm.h" -#include "rv770d.h" -#include "atom.h" -#include "avivod.h" - -#define R700_PFP_UCODE_SIZE 848 -#define R700_PM4_UCODE_SIZE 1360 - -static void rv770_gpu_init(struct radeon_device *rdev); -void rv770_fini(struct radeon_device *rdev); -static void rv770_pcie_gen2_enable(struct radeon_device *rdev); - -u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) -{ - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; - u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); - int i; - - /* Lock the graphics update lock */ - tmp |= AVIVO_D1GRPH_UPDATE_LOCK; - WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); - - /* update the scanout addresses */ - if (radeon_crtc->crtc_id) { - WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); - WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); - } else { - WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); - WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); - } - WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)crtc_base); - WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, - (u32)crtc_base); - - /* Wait for update_pending to go high. */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) - break; - udelay(1); - } - DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); - - /* Unlock the lock, so double-buffering can take place inside vblank */ - tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; - WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); - - /* Return current update_pending status: */ - return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; -} - -/* get temperature in millidegrees */ -int rv770_get_temp(struct radeon_device *rdev) -{ - u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> - ASIC_T_SHIFT; - int actual_temp; - - if (temp & 0x400) - actual_temp = -256; - else if (temp & 0x200) - actual_temp = 255; - else if (temp & 0x100) { - actual_temp = temp & 0x1ff; - actual_temp |= ~0x1ff; - } else - actual_temp = temp & 0xff; - - return (actual_temp * 1000) / 2; -} - -void rv770_pm_misc(struct radeon_device *rdev) -{ - int req_ps_idx = rdev->pm.requested_power_state_index; - int req_cm_idx = rdev->pm.requested_clock_mode_index; - struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; - struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; - - if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { - /* 0xff01 is a flag rather then an actual voltage */ - if (voltage->voltage == 0xff01) - return; - if (voltage->voltage != rdev->pm.current_vddc) { - radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); - rdev->pm.current_vddc = voltage->voltage; - DRM_DEBUG("Setting: v: %d\n", voltage->voltage); - } - } -} - -/* - * GART - */ -int rv770_pcie_gart_enable(struct radeon_device *rdev) -{ - u32 tmp; - int r, i; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); - /* Setup TLB control */ - tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - if (rdev->family == CHIP_RV740) - WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); - WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - for (i = 1; i < 7; i++) - WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - - r600_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void rv770_pcie_gart_disable(struct radeon_device *rdev) -{ - u32 tmp; - int i; - - /* Disable all tables */ - for (i = 0; i < 7; i++) - WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); - /* Setup TLB control */ - tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - radeon_gart_table_vram_unpin(rdev); -} - -void rv770_pcie_gart_fini(struct radeon_device *rdev) -{ - radeon_gart_fini(rdev); - rv770_pcie_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); -} - - -void rv770_agp_enable(struct radeon_device *rdev) -{ - u32 tmp; - int i; - - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); - /* Setup TLB control */ - tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | - EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); - WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); - WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - for (i = 0; i < 7; i++) - WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); -} - -static void rv770_mc_program(struct radeon_device *rdev) -{ - struct rv515_mc_save save; - u32 tmp; - int i, j; - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - /* r7xx hw bug. Read from HDP_DEBUG1 rather - * than writing to HDP_REG_COHERENCY_FLUSH_CNTL - */ - tmp = RREG32(HDP_DEBUG1); - - rv515_mc_stop(rdev, &save); - if (r600_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Lockout access through VGA aperture*/ - WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); - /* Update configuration */ - if (rdev->flags & RADEON_IS_AGP) { - if (rdev->mc.vram_start < rdev->mc.gtt_start) { - /* VRAM before AGP */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.gtt_end >> 12); - } else { - /* VRAM after AGP */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.gtt_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.vram_end >> 12); - } - } else { - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.vram_end >> 12); - } - WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); - tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; - tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); - WREG32(MC_VM_FB_LOCATION, tmp); - WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); - WREG32(HDP_NONSURFACE_INFO, (2 << 7)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); - if (rdev->flags & RADEON_IS_AGP) { - WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); - WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); - WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); - } else { - WREG32(MC_VM_AGP_BASE, 0); - WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); - WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); - } - if (r600_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - rv515_mc_resume(rdev, &save); - /* we need to own VRAM, so turn off the VGA renderer here - * to stop it overwriting our objects */ - rv515_vga_render_disable(rdev); -} - - -/* - * CP. - */ -void r700_cp_stop(struct radeon_device *rdev) -{ - radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); - WREG32(SCRATCH_UMSK, 0); -} - -static int rv770_cp_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - int i; - - if (!rdev->me_fw || !rdev->pfp_fw) - return -EINVAL; - - r700_cp_stop(rdev); - WREG32(CP_RB_CNTL, -#ifdef __BIG_ENDIAN - BUF_SWAP_32BIT | -#endif - RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); - - /* Reset cp */ - WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); - RREG32(GRBM_SOFT_RESET); - mdelay(15); - WREG32(GRBM_SOFT_RESET, 0); - - fw_data = (const __be32 *)rdev->pfp_fw->data; - WREG32(CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < R700_PFP_UCODE_SIZE; i++) - WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_PFP_UCODE_ADDR, 0); - - fw_data = (const __be32 *)rdev->me_fw->data; - WREG32(CP_ME_RAM_WADDR, 0); - for (i = 0; i < R700_PM4_UCODE_SIZE; i++) - WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); - - WREG32(CP_PFP_UCODE_ADDR, 0); - WREG32(CP_ME_RAM_WADDR, 0); - WREG32(CP_ME_RAM_RADDR, 0); - return 0; -} - -void r700_cp_fini(struct radeon_device *rdev) -{ - r700_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); -} - -/* - * Core functions - */ -static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends, - u32 backend_disable_mask) -{ - u32 backend_map = 0; - u32 enabled_backends_mask; - u32 enabled_backends_count; - u32 cur_pipe; - u32 swizzle_pipe[R7XX_MAX_PIPES]; - u32 cur_backend; - u32 i; - bool force_no_swizzle; - - if (num_tile_pipes > R7XX_MAX_PIPES) - num_tile_pipes = R7XX_MAX_PIPES; - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_backends > R7XX_MAX_BACKENDS) - num_backends = R7XX_MAX_BACKENDS; - if (num_backends < 1) - num_backends = 1; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { - if (((backend_disable_mask >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends) - break; - } - - if (enabled_backends_count == 0) { - enabled_backends_mask = 1; - enabled_backends_count = 1; - } - - if (enabled_backends_count != num_backends) - num_backends = enabled_backends_count; - - switch (rdev->family) { - case CHIP_RV770: - case CHIP_RV730: - force_no_swizzle = false; - break; - case CHIP_RV710: - case CHIP_RV740: - default: - force_no_swizzle = true; - break; - } - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); - switch (num_tile_pipes) { - case 1: - swizzle_pipe[0] = 0; - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 3: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - } - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 3; - swizzle_pipe[3] = 1; - } - break; - case 5: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 5; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - } - break; - case 7: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 1; - swizzle_pipe[6] = 7; - swizzle_pipe[7] = 5; - } - break; - } - - cur_backend = 0; - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - - backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); - - cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; - } - - return backend_map; -} - -static void rv770_gpu_init(struct radeon_device *rdev) -{ - int i, j, num_qd_pipes; - u32 ta_aux_cntl; - u32 sx_debug_1; - u32 smx_dc_ctl0; - u32 db_debug3; - u32 num_gs_verts_per_thread; - u32 vgt_gs_per_es; - u32 gs_prim_buffer_depth = 0; - u32 sq_ms_fifo_sizes; - u32 sq_config; - u32 sq_thread_resource_mgmt; - u32 hdp_host_path_cntl; - u32 sq_dyn_gpr_size_simd_ab_0; - u32 backend_map; - u32 gb_tiling_config = 0; - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_pipe_config = 0; - u32 mc_arb_ramcfg; - u32 db_debug4; - - /* setup chip specs */ - switch (rdev->family) { - case CHIP_RV770: - rdev->config.rv770.max_pipes = 4; - rdev->config.rv770.max_tile_pipes = 8; - rdev->config.rv770.max_simds = 10; - rdev->config.rv770.max_backends = 4; - rdev->config.rv770.max_gprs = 256; - rdev->config.rv770.max_threads = 248; - rdev->config.rv770.max_stack_entries = 512; - rdev->config.rv770.max_hw_contexts = 8; - rdev->config.rv770.max_gs_threads = 16 * 2; - rdev->config.rv770.sx_max_export_size = 128; - rdev->config.rv770.sx_max_export_pos_size = 16; - rdev->config.rv770.sx_max_export_smx_size = 112; - rdev->config.rv770.sq_num_cf_insts = 2; - - rdev->config.rv770.sx_num_of_sets = 7; - rdev->config.rv770.sc_prim_fifo_size = 0xF9; - rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; - rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; - break; - case CHIP_RV730: - rdev->config.rv770.max_pipes = 2; - rdev->config.rv770.max_tile_pipes = 4; - rdev->config.rv770.max_simds = 8; - rdev->config.rv770.max_backends = 2; - rdev->config.rv770.max_gprs = 128; - rdev->config.rv770.max_threads = 248; - rdev->config.rv770.max_stack_entries = 256; - rdev->config.rv770.max_hw_contexts = 8; - rdev->config.rv770.max_gs_threads = 16 * 2; - rdev->config.rv770.sx_max_export_size = 256; - rdev->config.rv770.sx_max_export_pos_size = 32; - rdev->config.rv770.sx_max_export_smx_size = 224; - rdev->config.rv770.sq_num_cf_insts = 2; - - rdev->config.rv770.sx_num_of_sets = 7; - rdev->config.rv770.sc_prim_fifo_size = 0xf9; - rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; - rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; - if (rdev->config.rv770.sx_max_export_pos_size > 16) { - rdev->config.rv770.sx_max_export_pos_size -= 16; - rdev->config.rv770.sx_max_export_smx_size += 16; - } - break; - case CHIP_RV710: - rdev->config.rv770.max_pipes = 2; - rdev->config.rv770.max_tile_pipes = 2; - rdev->config.rv770.max_simds = 2; - rdev->config.rv770.max_backends = 1; - rdev->config.rv770.max_gprs = 256; - rdev->config.rv770.max_threads = 192; - rdev->config.rv770.max_stack_entries = 256; - rdev->config.rv770.max_hw_contexts = 4; - rdev->config.rv770.max_gs_threads = 8 * 2; - rdev->config.rv770.sx_max_export_size = 128; - rdev->config.rv770.sx_max_export_pos_size = 16; - rdev->config.rv770.sx_max_export_smx_size = 112; - rdev->config.rv770.sq_num_cf_insts = 1; - - rdev->config.rv770.sx_num_of_sets = 7; - rdev->config.rv770.sc_prim_fifo_size = 0x40; - rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; - rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; - break; - case CHIP_RV740: - rdev->config.rv770.max_pipes = 4; - rdev->config.rv770.max_tile_pipes = 4; - rdev->config.rv770.max_simds = 8; - rdev->config.rv770.max_backends = 4; - rdev->config.rv770.max_gprs = 256; - rdev->config.rv770.max_threads = 248; - rdev->config.rv770.max_stack_entries = 512; - rdev->config.rv770.max_hw_contexts = 8; - rdev->config.rv770.max_gs_threads = 16 * 2; - rdev->config.rv770.sx_max_export_size = 256; - rdev->config.rv770.sx_max_export_pos_size = 32; - rdev->config.rv770.sx_max_export_smx_size = 224; - rdev->config.rv770.sq_num_cf_insts = 2; - - rdev->config.rv770.sx_num_of_sets = 7; - rdev->config.rv770.sc_prim_fifo_size = 0x100; - rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; - rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; - - if (rdev->config.rv770.sx_max_export_pos_size > 16) { - rdev->config.rv770.sx_max_export_pos_size -= 16; - rdev->config.rv770.sx_max_export_smx_size += 16; - } - break; - default: - break; - } - - /* Initialize HDP */ - j = 0; - for (i = 0; i < 32; i++) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - j += 0x18; - } - - WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - - /* setup tiling, simd, pipe config */ - mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - - switch (rdev->config.rv770.max_tile_pipes) { - case 1: - default: - gb_tiling_config |= PIPE_TILING(0); - break; - case 2: - gb_tiling_config |= PIPE_TILING(1); - break; - case 4: - gb_tiling_config |= PIPE_TILING(2); - break; - case 8: - gb_tiling_config |= PIPE_TILING(3); - break; - } - rdev->config.rv770.tiling_npipes = rdev->config.rv770.max_tile_pipes; - - if (rdev->family == CHIP_RV770) - gb_tiling_config |= BANK_TILING(1); - else { - if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) - gb_tiling_config |= BANK_TILING(1); - else - gb_tiling_config |= BANK_TILING(0); - } - rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); - gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); - if ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) - rdev->config.rv770.tiling_group_size = 512; - else - rdev->config.rv770.tiling_group_size = 256; - if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { - gb_tiling_config |= ROW_TILING(3); - gb_tiling_config |= SAMPLE_SPLIT(3); - } else { - gb_tiling_config |= - ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT)); - gb_tiling_config |= - SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT)); - } - - gb_tiling_config |= BANK_SWAPS(1); - - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; - cc_rb_backend_disable |= - BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK); - - cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; - cc_gc_shader_pipe_config |= - INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK); - cc_gc_shader_pipe_config |= - INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK); - - if (rdev->family == CHIP_RV740) - backend_map = 0x28; - else - backend_map = r700_get_tile_pipe_to_backend_map(rdev, - rdev->config.rv770.max_tile_pipes, - (R7XX_MAX_BACKENDS - - r600_count_pipe_bits((cc_rb_backend_disable & - R7XX_MAX_BACKENDS_MASK) >> 16)), - (cc_rb_backend_disable >> 16)); - - rdev->config.rv770.tile_config = gb_tiling_config; - rdev->config.rv770.backend_map = backend_map; - gb_tiling_config |= BACKEND_MAP(backend_map); - - WREG32(GB_TILING_CONFIG, gb_tiling_config); - WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); - - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - - WREG32(CGTS_SYS_TCC_DISABLE, 0); - WREG32(CGTS_TCC_DISABLE, 0); - WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); - WREG32(CGTS_USER_TCC_DISABLE, 0); - - num_qd_pipes = - R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); - WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK); - WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK); - - /* set HW defaults for 3D engine */ - WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | - ROQ_IB2_START(0x2b))); - - WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); - - ta_aux_cntl = RREG32(TA_CNTL_AUX); - WREG32(TA_CNTL_AUX, ta_aux_cntl | DISABLE_CUBE_ANISO); - - sx_debug_1 = RREG32(SX_DEBUG_1); - sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; - WREG32(SX_DEBUG_1, sx_debug_1); - - smx_dc_ctl0 = RREG32(SMX_DC_CTL0); - smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff); - smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1); - WREG32(SMX_DC_CTL0, smx_dc_ctl0); - - if (rdev->family != CHIP_RV740) - WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | - GS_FLUSH_CTL(4) | - ACK_FLUSH_CTL(3) | - SYNC_FLUSH_CTL)); - - if (rdev->family != CHIP_RV770) - WREG32(SMX_SAR_CTL0, 0x00003f3f); - - db_debug3 = RREG32(DB_DEBUG3); - db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); - switch (rdev->family) { - case CHIP_RV770: - case CHIP_RV740: - db_debug3 |= DB_CLK_OFF_DELAY(0x1f); - break; - case CHIP_RV710: - case CHIP_RV730: - default: - db_debug3 |= DB_CLK_OFF_DELAY(2); - break; - } - WREG32(DB_DEBUG3, db_debug3); - - if (rdev->family != CHIP_RV770) { - db_debug4 = RREG32(DB_DEBUG4); - db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER; - WREG32(DB_DEBUG4, db_debug4); - } - - WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | - POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | - SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); - - WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | - SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | - SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); - - WREG32(PA_SC_MULTI_CHIP_CNTL, 0); - - WREG32(VGT_NUM_INSTANCES, 1); - - WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); - - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); - - WREG32(CP_PERFMON_CNTL, 0); - - sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) | - DONE_FIFO_HIWATER(0xe0) | - ALU_UPDATE_FIFO_HIWATER(0x8)); - switch (rdev->family) { - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1); - break; - case CHIP_RV740: - default: - sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4); - break; - } - WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); - - /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT - * should be adjusted as needed by the 2D/3D drivers. This just sets default values - */ - sq_config = RREG32(SQ_CONFIG); - sq_config &= ~(PS_PRIO(3) | - VS_PRIO(3) | - GS_PRIO(3) | - ES_PRIO(3)); - sq_config |= (DX9_CONSTS | - VC_ENABLE | - EXPORT_SRC_C | - PS_PRIO(0) | - VS_PRIO(1) | - GS_PRIO(2) | - ES_PRIO(3)); - if (rdev->family == CHIP_RV710) - /* no vertex cache */ - sq_config &= ~VC_ENABLE; - - WREG32(SQ_CONFIG, sq_config); - - WREG32(SQ_GPR_RESOURCE_MGMT_1, (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) | - NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) | - NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2))); - - WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) | - NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64))); - - sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) | - NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) | - NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8)); - if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads) - sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads); - else - sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8); - WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); - - WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) | - NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4))); - - WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) | - NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4))); - - sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) | - SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) | - SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) | - SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64)); - - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); - WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); - - WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | - FORCE_EOV_MAX_REZ_CNT(255))); - - if (rdev->family == CHIP_RV710) - WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) | - AUTO_INVLD_EN(ES_AND_GS_AUTO))); - else - WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) | - AUTO_INVLD_EN(ES_AND_GS_AUTO))); - - switch (rdev->family) { - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV740: - gs_prim_buffer_depth = 384; - break; - case CHIP_RV710: - gs_prim_buffer_depth = 128; - break; - default: - break; - } - - num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16; - vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; - /* Max value for this is 256 */ - if (vgt_gs_per_es > 256) - vgt_gs_per_es = 256; - - WREG32(VGT_ES_PER_GS, 128); - WREG32(VGT_GS_PER_ES, vgt_gs_per_es); - WREG32(VGT_GS_PER_VS, 2); - - /* more default values. 2D/3D driver should adjust as needed */ - WREG32(VGT_GS_VERTEX_REUSE, 16); - WREG32(PA_SC_LINE_STIPPLE_STATE, 0); - WREG32(VGT_STRMOUT_EN, 0); - WREG32(SX_MISC, 0); - WREG32(PA_SC_MODE_CNTL, 0); - WREG32(PA_SC_EDGERULE, 0xaaaaaaaa); - WREG32(PA_SC_AA_CONFIG, 0); - WREG32(PA_SC_CLIPRECT_RULE, 0xffff); - WREG32(PA_SC_LINE_STIPPLE, 0); - WREG32(SPI_INPUT_Z, 0); - WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2)); - WREG32(CB_COLOR7_FRAG, 0); - - /* clear render buffer base addresses */ - WREG32(CB_COLOR0_BASE, 0); - WREG32(CB_COLOR1_BASE, 0); - WREG32(CB_COLOR2_BASE, 0); - WREG32(CB_COLOR3_BASE, 0); - WREG32(CB_COLOR4_BASE, 0); - WREG32(CB_COLOR5_BASE, 0); - WREG32(CB_COLOR6_BASE, 0); - WREG32(CB_COLOR7_BASE, 0); - - WREG32(TCP_CNTL, 0); - - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - WREG32(PA_SC_MULTI_CHIP_CNTL, 0); - - WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | - NUM_CLIP_SEQ(3))); - WREG32(VC_ENHANCE, 0); -} - -void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) -{ - u64 size_bf, size_af; - - if (mc->mc_vram_size > 0xE0000000) { - /* leave room for at least 512M GTT */ - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = 0xE0000000; - mc->mc_vram_size = 0xE0000000; - } - if (rdev->flags & RADEON_IS_AGP) { - size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; - if (size_bf > size_af) { - if (mc->mc_vram_size > size_bf) { - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = size_bf; - mc->mc_vram_size = size_bf; - } - mc->vram_start = mc->gtt_start - mc->mc_vram_size; - } else { - if (mc->mc_vram_size > size_af) { - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = size_af; - mc->mc_vram_size = size_af; - } - mc->vram_start = mc->gtt_end + 1; - } - mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", - mc->mc_vram_size >> 20, mc->vram_start, - mc->vram_end, mc->real_vram_size >> 20); - } else { - radeon_vram_location(rdev, &rdev->mc, 0); - rdev->mc.gtt_base_align = 0; - radeon_gtt_location(rdev, mc); - } -} - -int rv770_mc_init(struct radeon_device *rdev) -{ - u32 tmp; - int chansize, numchan; - - /* Get VRAM informations */ - rdev->mc.vram_is_ddr = true; - tmp = RREG32(MC_ARB_RAMCFG); - if (tmp & CHANSIZE_OVERRIDE) { - chansize = 16; - } else if (tmp & CHANSIZE_MASK) { - chansize = 64; - } else { - chansize = 32; - } - tmp = RREG32(MC_SHARED_CHMAP); - switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { - case 0: - default: - numchan = 1; - break; - case 1: - numchan = 2; - break; - case 2: - numchan = 4; - break; - case 3: - numchan = 8; - break; - } - rdev->mc.vram_width = numchan * chansize; - /* Could aper size report 0 ? */ - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - /* Setup GPU memory space */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); - rdev->mc.visible_vram_size = rdev->mc.aper_size; - r700_vram_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); - - return 0; -} - -static int rv770_startup(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - - /* enable pcie gen2 link */ - rv770_pcie_gen2_enable(rdev); - - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = r600_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - - r = r600_vram_scratch_init(rdev); - if (r) - return r; - - rv770_mc_program(rdev); - if (rdev->flags & RADEON_IS_AGP) { - rv770_agp_enable(rdev); - } else { - r = rv770_pcie_gart_enable(rdev); - if (r) - return r; - } - - rv770_gpu_init(rdev); - r = r600_blit_init(rdev); - if (r) { - r600_blit_fini(rdev); - rdev->asic->copy.copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r = r600_irq_init(rdev); - if (r) { - DRM_ERROR("radeon: IH init failed (%d).\n", r); - radeon_irq_kms_fini(rdev); - return r; - } - r600_irq_set(rdev); - - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (r) - return r; - r = rv770_cp_load_microcode(rdev); - if (r) - return r; - r = r600_cp_resume(rdev); - if (r) - return r; - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - dev_err(rdev->dev, "IB test failed (%d).\n", r); - rdev->accel_working = false; - return r; - } - - return 0; -} - -int rv770_resume(struct radeon_device *rdev) -{ - int r; - - /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, - * posting will perform necessary task to bring back GPU into good - * shape. - */ - /* post card */ - atom_asic_init(rdev->mode_info.atom_context); - - rdev->accel_working = true; - r = rv770_startup(rdev); - if (r) { - DRM_ERROR("r600 startup failed on resume\n"); - rdev->accel_working = false; - return r; - } - - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "radeon: audio init failed\n"); - return r; - } - - return r; - -} - -int rv770_suspend(struct radeon_device *rdev) -{ - r600_audio_fini(rdev); - radeon_ib_pool_suspend(rdev); - r600_blit_suspend(rdev); - /* FIXME: we should wait for ring to be empty */ - r700_cp_stop(rdev); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - r600_irq_suspend(rdev); - radeon_wb_disable(rdev); - rv770_pcie_gart_disable(rdev); - - return 0; -} - -/* Plan is to move initialization in that function and use - * helper function so that radeon_device_init pretty much - * do nothing more than calling asic specific function. This - * should also allow to remove a bunch of callback function - * like vram_info. - */ -int rv770_init(struct radeon_device *rdev) -{ - int r; - - /* This don't do much */ - r = radeon_gem_init(rdev); - if (r) - return r; - /* Read BIOS */ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting atombios for R600 GPU\n"); - return -EINVAL; - } - r = radeon_atombios_init(rdev); - if (r) - return r; - /* Post card if necessary */ - if (!radeon_card_posted(rdev)) { - if (!rdev->bios) { - dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); - return -EINVAL; - } - DRM_INFO("GPU not posted. posting now...\n"); - atom_asic_init(rdev->mode_info.atom_context); - } - /* Initialize scratch registers */ - r600_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - /* initialize AGP */ - if (rdev->flags & RADEON_IS_AGP) { - r = radeon_agp_init(rdev); - if (r) - radeon_agp_disable(rdev); - } - r = rv770_mc_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - - r = radeon_irq_kms_init(rdev); - if (r) - return r; - - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); - - rdev->ih.ring_obj = NULL; - r600_ih_ring_init(rdev, 64 * 1024); - - r = r600_pcie_gart_init(rdev); - if (r) - return r; - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - - r = rv770_startup(rdev); - if (r) { - dev_err(rdev->dev, "disabling GPU acceleration\n"); - r700_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - rv770_pcie_gart_fini(rdev); - rdev->accel_working = false; - } - - r = r600_audio_init(rdev); - if (r) { - dev_err(rdev->dev, "radeon: audio init failed\n"); - return r; - } - - return 0; -} - -void rv770_fini(struct radeon_device *rdev) -{ - r600_blit_fini(rdev); - r700_cp_fini(rdev); - r600_irq_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - rv770_pcie_gart_fini(rdev); - r600_vram_scratch_fini(rdev); - radeon_gem_fini(rdev); - radeon_semaphore_driver_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_agp_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - -static void rv770_pcie_gen2_enable(struct radeon_device *rdev) -{ - u32 link_width_cntl, lanes, speed_cntl, tmp; - u16 link_cntl2; - - if (radeon_pcie_gen2 == 0) - return; - - if (rdev->flags & RADEON_IS_IGP) - return; - - if (!(rdev->flags & RADEON_IS_PCIE)) - return; - - /* x2 cards have a special sequence */ - if (ASIC_IS_X2(rdev)) - return; - - /* advertise upconfig capability */ - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - link_width_cntl &= ~LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { - lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; - link_width_cntl &= ~(LC_LINK_WIDTH_MASK | - LC_RECONFIG_ARC_MISSING_ESCAPE); - link_width_cntl |= lanes | LC_RECONFIG_NOW | - LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } else { - link_width_cntl |= LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && - (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { - - tmp = RREG32(0x541c); - WREG32(0x541c, tmp | 0x8); - WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); - link_cntl2 = RREG16(0x4088); - link_cntl2 &= ~TARGET_LINK_SPEED_MASK; - link_cntl2 |= 0x2; - WREG16(0x4088, link_cntl2); - WREG32(MM_CFGREGS_CNTL, 0); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); - speed_cntl |= LC_GEN2_EN_STRAP; - WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); - - } else { - link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); - /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ - if (1) - link_width_cntl |= LC_UPCONFIGURE_DIS; - else - link_width_cntl &= ~LC_UPCONFIGURE_DIS; - WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); - } -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770d.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770d.h deleted file mode 100644 index 7095a713..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/rv770d.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright 2009 Advanced Micro Devices, Inc. - * Copyright 2009 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Dave Airlie - * Alex Deucher - * Jerome Glisse - */ -#ifndef RV770_H -#define RV770_H - -#define R7XX_MAX_SH_GPRS 256 -#define R7XX_MAX_TEMP_GPRS 16 -#define R7XX_MAX_SH_THREADS 256 -#define R7XX_MAX_SH_STACK_ENTRIES 4096 -#define R7XX_MAX_BACKENDS 8 -#define R7XX_MAX_BACKENDS_MASK 0xff -#define R7XX_MAX_SIMDS 16 -#define R7XX_MAX_SIMDS_MASK 0xffff -#define R7XX_MAX_PIPES 8 -#define R7XX_MAX_PIPES_MASK 0xff - -/* Registers */ -#define CB_COLOR0_BASE 0x28040 -#define CB_COLOR1_BASE 0x28044 -#define CB_COLOR2_BASE 0x28048 -#define CB_COLOR3_BASE 0x2804C -#define CB_COLOR4_BASE 0x28050 -#define CB_COLOR5_BASE 0x28054 -#define CB_COLOR6_BASE 0x28058 -#define CB_COLOR7_BASE 0x2805C -#define CB_COLOR7_FRAG 0x280FC - -#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -#define CC_RB_BACKEND_DISABLE 0x98F4 -#define BACKEND_DISABLE(x) ((x) << 16) -#define CC_SYS_RB_BACKEND_DISABLE 0x3F88 - -#define CGTS_SYS_TCC_DISABLE 0x3F90 -#define CGTS_TCC_DISABLE 0x9148 -#define CGTS_USER_SYS_TCC_DISABLE 0x3F94 -#define CGTS_USER_TCC_DISABLE 0x914C - -#define CONFIG_MEMSIZE 0x5428 - -#define CP_ME_CNTL 0x86D8 -#define CP_ME_HALT (1<<28) -#define CP_PFP_HALT (1<<26) -#define CP_ME_RAM_DATA 0xC160 -#define CP_ME_RAM_RADDR 0xC158 -#define CP_ME_RAM_WADDR 0xC15C -#define CP_MEQ_THRESHOLDS 0x8764 -#define STQ_SPLIT(x) ((x) << 0) -#define CP_PERFMON_CNTL 0x87FC -#define CP_PFP_UCODE_ADDR 0xC150 -#define CP_PFP_UCODE_DATA 0xC154 -#define CP_QUEUE_THRESHOLDS 0x8760 -#define ROQ_IB1_START(x) ((x) << 0) -#define ROQ_IB2_START(x) ((x) << 8) -#define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) -#define BUF_SWAP_32BIT (2 << 16) -#define CP_RB_RPTR 0x8700 -#define CP_RB_RPTR_ADDR 0xC10C -#define CP_RB_RPTR_ADDR_HI 0xC110 -#define CP_RB_RPTR_WR 0xC108 -#define CP_RB_WPTR 0xC114 -#define CP_RB_WPTR_ADDR 0xC118 -#define CP_RB_WPTR_ADDR_HI 0xC11C -#define CP_RB_WPTR_DELAY 0x8704 -#define CP_SEM_WAIT_TIMER 0x85BC - -#define DB_DEBUG3 0x98B0 -#define DB_CLK_OFF_DELAY(x) ((x) << 11) -#define DB_DEBUG4 0x9B8C -#define DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) - -#define DCP_TILING_CONFIG 0x6CA0 -#define PIPE_TILING(x) ((x) << 1) -#define BANK_TILING(x) ((x) << 4) -#define GROUP_SIZE(x) ((x) << 6) -#define ROW_TILING(x) ((x) << 8) -#define BANK_SWAPS(x) ((x) << 11) -#define SAMPLE_SPLIT(x) ((x) << 14) -#define BACKEND_MAP(x) ((x) << 16) - -#define GB_TILING_CONFIG 0x98F0 - -#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -#define INACTIVE_QD_PIPES(x) ((x) << 8) -#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -#define INACTIVE_SIMDS(x) ((x) << 16) -#define INACTIVE_SIMDS_MASK 0x00FF0000 - -#define GRBM_CNTL 0x8000 -#define GRBM_READ_TIMEOUT(x) ((x) << 0) -#define GRBM_SOFT_RESET 0x8020 -#define SOFT_RESET_CP (1<<0) -#define GRBM_STATUS 0x8010 -#define CMDFIFO_AVAIL_MASK 0x0000000F -#define GUI_ACTIVE (1<<31) -#define GRBM_STATUS2 0x8014 - -#define CG_MULT_THERMAL_STATUS 0x740 -#define ASIC_T(x) ((x) << 16) -#define ASIC_T_MASK 0x3FF0000 -#define ASIC_T_SHIFT 16 - -#define HDP_HOST_PATH_CNTL 0x2C00 -#define HDP_NONSURFACE_BASE 0x2C04 -#define HDP_NONSURFACE_INFO 0x2C08 -#define HDP_NONSURFACE_SIZE 0x2C0C -#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 -#define HDP_TILING_CONFIG 0x2F3C -#define HDP_DEBUG1 0x2F34 - -#define MC_SHARED_CHMAP 0x2004 -#define NOOFCHAN_SHIFT 12 -#define NOOFCHAN_MASK 0x00003000 -#define MC_SHARED_CHREMAP 0x2008 - -#define MC_ARB_RAMCFG 0x2760 -#define NOOFBANK_SHIFT 0 -#define NOOFBANK_MASK 0x00000003 -#define NOOFRANK_SHIFT 2 -#define NOOFRANK_MASK 0x00000004 -#define NOOFROWS_SHIFT 3 -#define NOOFROWS_MASK 0x00000038 -#define NOOFCOLS_SHIFT 6 -#define NOOFCOLS_MASK 0x000000C0 -#define CHANSIZE_SHIFT 8 -#define CHANSIZE_MASK 0x00000100 -#define BURSTLENGTH_SHIFT 9 -#define BURSTLENGTH_MASK 0x00000200 -#define CHANSIZE_OVERRIDE (1 << 11) -#define MC_VM_AGP_TOP 0x2028 -#define MC_VM_AGP_BOT 0x202C -#define MC_VM_AGP_BASE 0x2030 -#define MC_VM_FB_LOCATION 0x2024 -#define MC_VM_MB_L1_TLB0_CNTL 0x2234 -#define MC_VM_MB_L1_TLB1_CNTL 0x2238 -#define MC_VM_MB_L1_TLB2_CNTL 0x223C -#define MC_VM_MB_L1_TLB3_CNTL 0x2240 -#define ENABLE_L1_TLB (1 << 0) -#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) -#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) -#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) -#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -#define EFFECTIVE_L1_TLB_SIZE(x) ((x)<<15) -#define EFFECTIVE_L1_QUEUE_SIZE(x) ((x)<<18) -#define MC_VM_MD_L1_TLB0_CNTL 0x2654 -#define MC_VM_MD_L1_TLB1_CNTL 0x2658 -#define MC_VM_MD_L1_TLB2_CNTL 0x265C -#define MC_VM_MD_L1_TLB3_CNTL 0x2698 -#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C -#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 - -#define PA_CL_ENHANCE 0x8A14 -#define CLIP_VTX_REORDER_ENA (1 << 0) -#define NUM_CLIP_SEQ(x) ((x) << 1) -#define PA_SC_AA_CONFIG 0x28C04 -#define PA_SC_CLIPRECT_RULE 0x2820C -#define PA_SC_EDGERULE 0x28230 -#define PA_SC_FIFO_SIZE 0x8BCC -#define SC_PRIM_FIFO_SIZE(x) ((x) << 0) -#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 -#define FORCE_EOV_MAX_CLK_CNT(x) ((x)<<0) -#define FORCE_EOV_MAX_REZ_CNT(x) ((x)<<16) -#define PA_SC_LINE_STIPPLE 0x28A0C -#define PA_SC_LINE_STIPPLE_STATE 0x8B10 -#define PA_SC_MODE_CNTL 0x28A4C -#define PA_SC_MULTI_CHIP_CNTL 0x8B20 -#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) - -#define SCRATCH_REG0 0x8500 -#define SCRATCH_REG1 0x8504 -#define SCRATCH_REG2 0x8508 -#define SCRATCH_REG3 0x850C -#define SCRATCH_REG4 0x8510 -#define SCRATCH_REG5 0x8514 -#define SCRATCH_REG6 0x8518 -#define SCRATCH_REG7 0x851C -#define SCRATCH_UMSK 0x8540 -#define SCRATCH_ADDR 0x8544 - -#define SMX_SAR_CTL0 0xA008 -#define SMX_DC_CTL0 0xA020 -#define USE_HASH_FUNCTION (1 << 0) -#define CACHE_DEPTH(x) ((x) << 1) -#define FLUSH_ALL_ON_EVENT (1 << 10) -#define STALL_ON_EVENT (1 << 11) -#define SMX_EVENT_CTL 0xA02C -#define ES_FLUSH_CTL(x) ((x) << 0) -#define GS_FLUSH_CTL(x) ((x) << 3) -#define ACK_FLUSH_CTL(x) ((x) << 6) -#define SYNC_FLUSH_CTL (1 << 8) - -#define SPI_CONFIG_CNTL 0x9100 -#define GPR_WRITE_PRIORITY(x) ((x) << 0) -#define DISABLE_INTERP_1 (1 << 5) -#define SPI_CONFIG_CNTL_1 0x913C -#define VTX_DONE_DELAY(x) ((x) << 0) -#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -#define SPI_INPUT_Z 0x286D8 -#define SPI_PS_IN_CONTROL_0 0x286CC -#define NUM_INTERP(x) ((x)<<0) -#define POSITION_ENA (1<<8) -#define POSITION_CENTROID (1<<9) -#define POSITION_ADDR(x) ((x)<<10) -#define PARAM_GEN(x) ((x)<<15) -#define PARAM_GEN_ADDR(x) ((x)<<19) -#define BARYC_SAMPLE_CNTL(x) ((x)<<26) -#define PERSP_GRADIENT_ENA (1<<28) -#define LINEAR_GRADIENT_ENA (1<<29) -#define POSITION_SAMPLE (1<<30) -#define BARYC_AT_SAMPLE_ENA (1<<31) - -#define SQ_CONFIG 0x8C00 -#define VC_ENABLE (1 << 0) -#define EXPORT_SRC_C (1 << 1) -#define DX9_CONSTS (1 << 2) -#define ALU_INST_PREFER_VECTOR (1 << 3) -#define DX10_CLAMP (1 << 4) -#define CLAUSE_SEQ_PRIO(x) ((x) << 8) -#define PS_PRIO(x) ((x) << 24) -#define VS_PRIO(x) ((x) << 26) -#define GS_PRIO(x) ((x) << 28) -#define SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8DB0 -#define SIMDA_RING0(x) ((x)<<0) -#define SIMDA_RING1(x) ((x)<<8) -#define SIMDB_RING0(x) ((x)<<16) -#define SIMDB_RING1(x) ((x)<<24) -#define SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8DB4 -#define SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8DB8 -#define SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8DBC -#define SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8DC0 -#define SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8DC4 -#define SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8DC8 -#define SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8DCC -#define ES_PRIO(x) ((x) << 30) -#define SQ_GPR_RESOURCE_MGMT_1 0x8C04 -#define NUM_PS_GPRS(x) ((x) << 0) -#define NUM_VS_GPRS(x) ((x) << 16) -#define DYN_GPR_ENABLE (1 << 27) -#define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -#define SQ_GPR_RESOURCE_MGMT_2 0x8C08 -#define NUM_GS_GPRS(x) ((x) << 0) -#define NUM_ES_GPRS(x) ((x) << 16) -#define SQ_MS_FIFO_SIZES 0x8CF0 -#define CACHE_FIFO_SIZE(x) ((x) << 0) -#define FETCH_FIFO_HIWATER(x) ((x) << 8) -#define DONE_FIFO_HIWATER(x) ((x) << 16) -#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -#define SQ_STACK_RESOURCE_MGMT_1 0x8C10 -#define NUM_PS_STACK_ENTRIES(x) ((x) << 0) -#define NUM_VS_STACK_ENTRIES(x) ((x) << 16) -#define SQ_STACK_RESOURCE_MGMT_2 0x8C14 -#define NUM_GS_STACK_ENTRIES(x) ((x) << 0) -#define NUM_ES_STACK_ENTRIES(x) ((x) << 16) -#define SQ_THREAD_RESOURCE_MGMT 0x8C0C -#define NUM_PS_THREADS(x) ((x) << 0) -#define NUM_VS_THREADS(x) ((x) << 8) -#define NUM_GS_THREADS(x) ((x) << 16) -#define NUM_ES_THREADS(x) ((x) << 24) - -#define SX_DEBUG_1 0x9058 -#define ENABLE_NEW_SMX_ADDRESS (1 << 16) -#define SX_EXPORT_BUFFER_SIZES 0x900C -#define COLOR_BUFFER_SIZE(x) ((x) << 0) -#define POSITION_BUFFER_SIZE(x) ((x) << 8) -#define SMX_BUFFER_SIZE(x) ((x) << 16) -#define SX_MISC 0x28350 - -#define TA_CNTL_AUX 0x9508 -#define DISABLE_CUBE_WRAP (1 << 0) -#define DISABLE_CUBE_ANISO (1 << 1) -#define SYNC_GRADIENT (1 << 24) -#define SYNC_WALKER (1 << 25) -#define SYNC_ALIGNER (1 << 26) -#define BILINEAR_PRECISION_6_BIT (0 << 31) -#define BILINEAR_PRECISION_8_BIT (1 << 31) - -#define TCP_CNTL 0x9610 -#define TCP_CHAN_STEER 0x9614 - -#define VC_ENHANCE 0x9714 - -#define VGT_CACHE_INVALIDATION 0x88C4 -#define CACHE_INVALIDATION(x) ((x)<<0) -#define VC_ONLY 0 -#define TC_ONLY 1 -#define VC_AND_TC 2 -#define AUTO_INVLD_EN(x) ((x) << 6) -#define NO_AUTO 0 -#define ES_AUTO 1 -#define GS_AUTO 2 -#define ES_AND_GS_AUTO 3 -#define VGT_ES_PER_GS 0x88CC -#define VGT_GS_PER_ES 0x88C8 -#define VGT_GS_PER_VS 0x88E8 -#define VGT_GS_VERTEX_REUSE 0x88D4 -#define VGT_NUM_INSTANCES 0x8974 -#define VGT_OUT_DEALLOC_CNTL 0x28C5C -#define DEALLOC_DIST_MASK 0x0000007F -#define VGT_STRMOUT_EN 0x28AB0 -#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 -#define VTX_REUSE_DEPTH_MASK 0x000000FF - -#define VM_CONTEXT0_CNTL 0x1410 -#define ENABLE_CONTEXT (1 << 0) -#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C -#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C -#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C -#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 -#define VM_L2_CNTL 0x1400 -#define ENABLE_L2_CACHE (1 << 0) -#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14) -#define VM_L2_CNTL2 0x1404 -#define INVALIDATE_ALL_L1_TLBS (1 << 0) -#define INVALIDATE_L2_CACHE (1 << 1) -#define VM_L2_CNTL3 0x1408 -#define BANK_SELECT(x) ((x) << 0) -#define CACHE_UPDATE_MODE(x) ((x) << 6) -#define VM_L2_STATUS 0x140C -#define L2_BUSY (1 << 0) - -#define WAIT_UNTIL 0x8040 - -#define SRBM_STATUS 0x0E50 - -#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 -#define D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 -#define D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 -#define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 -#define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c -#define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c - -/* PCIE link stuff */ -#define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ -#define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ -# define LC_LINK_WIDTH_SHIFT 0 -# define LC_LINK_WIDTH_MASK 0x7 -# define LC_LINK_WIDTH_X0 0 -# define LC_LINK_WIDTH_X1 1 -# define LC_LINK_WIDTH_X2 2 -# define LC_LINK_WIDTH_X4 3 -# define LC_LINK_WIDTH_X8 4 -# define LC_LINK_WIDTH_X16 6 -# define LC_LINK_WIDTH_RD_SHIFT 4 -# define LC_LINK_WIDTH_RD_MASK 0x70 -# define LC_RECONFIG_ARC_MISSING_ESCAPE (1 << 7) -# define LC_RECONFIG_NOW (1 << 8) -# define LC_RENEGOTIATION_SUPPORT (1 << 9) -# define LC_RENEGOTIATE_EN (1 << 10) -# define LC_SHORT_RECONFIG_EN (1 << 11) -# define LC_UPCONFIGURE_SUPPORT (1 << 12) -# define LC_UPCONFIGURE_DIS (1 << 13) -#define PCIE_LC_SPEED_CNTL 0xa4 /* PCIE_P */ -# define LC_GEN2_EN_STRAP (1 << 0) -# define LC_TARGET_LINK_SPEED_OVERRIDE_EN (1 << 1) -# define LC_FORCE_EN_HW_SPEED_CHANGE (1 << 5) -# define LC_FORCE_DIS_HW_SPEED_CHANGE (1 << 6) -# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) -# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 -# define LC_CURRENT_DATA_RATE (1 << 11) -# define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) -# define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) -# define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) -# define LC_OTHER_SIDE_SUPPORTS_GEN2 (1 << 24) -#define MM_CFGREGS_CNTL 0x544c -# define MM_WR_TO_CFG_EN (1 << 3) -#define LINK_CNTL2 0x88 /* F0 */ -# define TARGET_LINK_SPEED_MASK (0xf << 0) -# define SELECTABLE_DEEMPHASIS (1 << 6) - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/si.c deleted file mode 100644 index 2af1ce69..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si.c +++ /dev/null @@ -1,4127 +0,0 @@ -/* - * Copyright 2011 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#include -#include -#include -#include -#include "drmP.h" -#include "radeon.h" -#include "radeon_asic.h" -#include "radeon_drm.h" -#include "sid.h" -#include "atom.h" -#include "si_blit_shaders.h" - -#define SI_PFP_UCODE_SIZE 2144 -#define SI_PM4_UCODE_SIZE 2144 -#define SI_CE_UCODE_SIZE 2144 -#define SI_RLC_UCODE_SIZE 2048 -#define SI_MC_UCODE_SIZE 7769 - -MODULE_FIRMWARE("radeon/TAHITI_pfp.bin"); -MODULE_FIRMWARE("radeon/TAHITI_me.bin"); -MODULE_FIRMWARE("radeon/TAHITI_ce.bin"); -MODULE_FIRMWARE("radeon/TAHITI_mc.bin"); -MODULE_FIRMWARE("radeon/TAHITI_rlc.bin"); -MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); -MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); -MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin"); -MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin"); -MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin"); -MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); -MODULE_FIRMWARE("radeon/VERDE_me.bin"); -MODULE_FIRMWARE("radeon/VERDE_ce.bin"); -MODULE_FIRMWARE("radeon/VERDE_mc.bin"); -MODULE_FIRMWARE("radeon/VERDE_rlc.bin"); - -extern int r600_ih_ring_alloc(struct radeon_device *rdev); -extern void r600_ih_ring_fini(struct radeon_device *rdev); -extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev); -extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); -extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); -extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); - -/* get temperature in millidegrees */ -int si_get_temp(struct radeon_device *rdev) -{ - u32 temp; - int actual_temp = 0; - - temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >> - CTF_TEMP_SHIFT; - - if (temp & 0x200) - actual_temp = 255; - else - actual_temp = temp & 0x1ff; - - actual_temp = (actual_temp * 1000); - - return actual_temp; -} - -#define TAHITI_IO_MC_REGS_SIZE 36 - -static const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { - {0x0000006f, 0x03044000}, - {0x00000070, 0x0480c018}, - {0x00000071, 0x00000040}, - {0x00000072, 0x01000000}, - {0x00000074, 0x000000ff}, - {0x00000075, 0x00143400}, - {0x00000076, 0x08ec0800}, - {0x00000077, 0x040000cc}, - {0x00000079, 0x00000000}, - {0x0000007a, 0x21000409}, - {0x0000007c, 0x00000000}, - {0x0000007d, 0xe8000000}, - {0x0000007e, 0x044408a8}, - {0x0000007f, 0x00000003}, - {0x00000080, 0x00000000}, - {0x00000081, 0x01000000}, - {0x00000082, 0x02000000}, - {0x00000083, 0x00000000}, - {0x00000084, 0xe3f3e4f4}, - {0x00000085, 0x00052024}, - {0x00000087, 0x00000000}, - {0x00000088, 0x66036603}, - {0x00000089, 0x01000000}, - {0x0000008b, 0x1c0a0000}, - {0x0000008c, 0xff010000}, - {0x0000008e, 0xffffefff}, - {0x0000008f, 0xfff3efff}, - {0x00000090, 0xfff3efbf}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00a77400} -}; - -static const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { - {0x0000006f, 0x03044000}, - {0x00000070, 0x0480c018}, - {0x00000071, 0x00000040}, - {0x00000072, 0x01000000}, - {0x00000074, 0x000000ff}, - {0x00000075, 0x00143400}, - {0x00000076, 0x08ec0800}, - {0x00000077, 0x040000cc}, - {0x00000079, 0x00000000}, - {0x0000007a, 0x21000409}, - {0x0000007c, 0x00000000}, - {0x0000007d, 0xe8000000}, - {0x0000007e, 0x044408a8}, - {0x0000007f, 0x00000003}, - {0x00000080, 0x00000000}, - {0x00000081, 0x01000000}, - {0x00000082, 0x02000000}, - {0x00000083, 0x00000000}, - {0x00000084, 0xe3f3e4f4}, - {0x00000085, 0x00052024}, - {0x00000087, 0x00000000}, - {0x00000088, 0x66036603}, - {0x00000089, 0x01000000}, - {0x0000008b, 0x1c0a0000}, - {0x0000008c, 0xff010000}, - {0x0000008e, 0xffffefff}, - {0x0000008f, 0xfff3efff}, - {0x00000090, 0xfff3efbf}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00a47400} -}; - -static const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { - {0x0000006f, 0x03044000}, - {0x00000070, 0x0480c018}, - {0x00000071, 0x00000040}, - {0x00000072, 0x01000000}, - {0x00000074, 0x000000ff}, - {0x00000075, 0x00143400}, - {0x00000076, 0x08ec0800}, - {0x00000077, 0x040000cc}, - {0x00000079, 0x00000000}, - {0x0000007a, 0x21000409}, - {0x0000007c, 0x00000000}, - {0x0000007d, 0xe8000000}, - {0x0000007e, 0x044408a8}, - {0x0000007f, 0x00000003}, - {0x00000080, 0x00000000}, - {0x00000081, 0x01000000}, - {0x00000082, 0x02000000}, - {0x00000083, 0x00000000}, - {0x00000084, 0xe3f3e4f4}, - {0x00000085, 0x00052024}, - {0x00000087, 0x00000000}, - {0x00000088, 0x66036603}, - {0x00000089, 0x01000000}, - {0x0000008b, 0x1c0a0000}, - {0x0000008c, 0xff010000}, - {0x0000008e, 0xffffefff}, - {0x0000008f, 0xfff3efff}, - {0x00000090, 0xfff3efbf}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00a37400} -}; - -/* ucode loading */ -static int si_mc_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - u32 running, blackout = 0; - u32 *io_mc_regs; - int i, ucode_size, regs_size; - - if (!rdev->mc_fw) - return -EINVAL; - - switch (rdev->family) { - case CHIP_TAHITI: - io_mc_regs = (u32 *)&tahiti_io_mc_regs; - ucode_size = SI_MC_UCODE_SIZE; - regs_size = TAHITI_IO_MC_REGS_SIZE; - break; - case CHIP_PITCAIRN: - io_mc_regs = (u32 *)&pitcairn_io_mc_regs; - ucode_size = SI_MC_UCODE_SIZE; - regs_size = TAHITI_IO_MC_REGS_SIZE; - break; - case CHIP_VERDE: - default: - io_mc_regs = (u32 *)&verde_io_mc_regs; - ucode_size = SI_MC_UCODE_SIZE; - regs_size = TAHITI_IO_MC_REGS_SIZE; - break; - } - - running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; - - if (running == 0) { - if (running) { - blackout = RREG32(MC_SHARED_BLACKOUT_CNTL); - WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1); - } - - /* reset the engine and set to writable */ - WREG32(MC_SEQ_SUP_CNTL, 0x00000008); - WREG32(MC_SEQ_SUP_CNTL, 0x00000010); - - /* load mc io regs */ - for (i = 0; i < regs_size; i++) { - WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); - WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); - } - /* load the MC ucode */ - fw_data = (const __be32 *)rdev->mc_fw->data; - for (i = 0; i < ucode_size; i++) - WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); - - /* put the engine back into the active state */ - WREG32(MC_SEQ_SUP_CNTL, 0x00000008); - WREG32(MC_SEQ_SUP_CNTL, 0x00000004); - WREG32(MC_SEQ_SUP_CNTL, 0x00000001); - - /* wait for training to complete */ - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0) - break; - udelay(1); - } - for (i = 0; i < rdev->usec_timeout; i++) { - if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1) - break; - udelay(1); - } - - if (running) - WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); - } - - return 0; -} - -static int si_init_microcode(struct radeon_device *rdev) -{ - struct platform_device *pdev; - const char *chip_name; - const char *rlc_chip_name; - size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; - char fw_name[30]; - int err; - - DRM_DEBUG("\n"); - - pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); - err = IS_ERR(pdev); - if (err) { - printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); - return -EINVAL; - } - - switch (rdev->family) { - case CHIP_TAHITI: - chip_name = "TAHITI"; - rlc_chip_name = "TAHITI"; - pfp_req_size = SI_PFP_UCODE_SIZE * 4; - me_req_size = SI_PM4_UCODE_SIZE * 4; - ce_req_size = SI_CE_UCODE_SIZE * 4; - rlc_req_size = SI_RLC_UCODE_SIZE * 4; - mc_req_size = SI_MC_UCODE_SIZE * 4; - break; - case CHIP_PITCAIRN: - chip_name = "PITCAIRN"; - rlc_chip_name = "PITCAIRN"; - pfp_req_size = SI_PFP_UCODE_SIZE * 4; - me_req_size = SI_PM4_UCODE_SIZE * 4; - ce_req_size = SI_CE_UCODE_SIZE * 4; - rlc_req_size = SI_RLC_UCODE_SIZE * 4; - mc_req_size = SI_MC_UCODE_SIZE * 4; - break; - case CHIP_VERDE: - chip_name = "VERDE"; - rlc_chip_name = "VERDE"; - pfp_req_size = SI_PFP_UCODE_SIZE * 4; - me_req_size = SI_PM4_UCODE_SIZE * 4; - ce_req_size = SI_CE_UCODE_SIZE * 4; - rlc_req_size = SI_RLC_UCODE_SIZE * 4; - mc_req_size = SI_MC_UCODE_SIZE * 4; - break; - default: BUG(); - } - - DRM_INFO("Loading %s Microcode\n", chip_name); - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); - err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->pfp_fw->size != pfp_req_size) { - printk(KERN_ERR - "si_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->pfp_fw->size, fw_name); - err = -EINVAL; - goto out; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); - err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->me_fw->size != me_req_size) { - printk(KERN_ERR - "si_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->me_fw->size, fw_name); - err = -EINVAL; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); - err = request_firmware(&rdev->ce_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->ce_fw->size != ce_req_size) { - printk(KERN_ERR - "si_cp: Bogus length %zu in firmware \"%s\"\n", - rdev->ce_fw->size, fw_name); - err = -EINVAL; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); - err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->rlc_fw->size != rlc_req_size) { - printk(KERN_ERR - "si_rlc: Bogus length %zu in firmware \"%s\"\n", - rdev->rlc_fw->size, fw_name); - err = -EINVAL; - } - - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); - err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev); - if (err) - goto out; - if (rdev->mc_fw->size != mc_req_size) { - printk(KERN_ERR - "si_mc: Bogus length %zu in firmware \"%s\"\n", - rdev->mc_fw->size, fw_name); - err = -EINVAL; - } - -out: - platform_device_unregister(pdev); - - if (err) { - if (err != -EINVAL) - printk(KERN_ERR - "si_cp: Failed to load firmware \"%s\"\n", - fw_name); - release_firmware(rdev->pfp_fw); - rdev->pfp_fw = NULL; - release_firmware(rdev->me_fw); - rdev->me_fw = NULL; - release_firmware(rdev->ce_fw); - rdev->ce_fw = NULL; - release_firmware(rdev->rlc_fw); - rdev->rlc_fw = NULL; - release_firmware(rdev->mc_fw); - rdev->mc_fw = NULL; - } - return err; -} - -/* watermark setup */ -static u32 dce6_line_buffer_adjust(struct radeon_device *rdev, - struct radeon_crtc *radeon_crtc, - struct drm_display_mode *mode, - struct drm_display_mode *other_mode) -{ - u32 tmp; - /* - * Line Buffer Setup - * There are 3 line buffers, each one shared by 2 display controllers. - * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between - * the display controllers. The paritioning is done via one of four - * preset allocations specified in bits 21:20: - * 0 - half lb - * 2 - whole lb, other crtc must be disabled - */ - /* this can get tricky if we have two large displays on a paired group - * of crtcs. Ideally for multiple large displays we'd assign them to - * non-linked crtcs for maximum line buffer allocation. - */ - if (radeon_crtc->base.enabled && mode) { - if (other_mode) - tmp = 0; /* 1/2 */ - else - tmp = 2; /* whole */ - } else - tmp = 0; - - WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, - DC_LB_MEMORY_CONFIG(tmp)); - - if (radeon_crtc->base.enabled && mode) { - switch (tmp) { - case 0: - default: - return 4096 * 2; - case 2: - return 8192 * 2; - } - } - - /* controller not enabled, so no lb used */ - return 0; -} - -static u32 si_get_number_of_dram_channels(struct radeon_device *rdev) -{ - u32 tmp = RREG32(MC_SHARED_CHMAP); - - switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { - case 0: - default: - return 1; - case 1: - return 2; - case 2: - return 4; - case 3: - return 8; - case 4: - return 3; - case 5: - return 6; - case 6: - return 10; - case 7: - return 12; - case 8: - return 16; - } -} - -struct dce6_wm_params { - u32 dram_channels; /* number of dram channels */ - u32 yclk; /* bandwidth per dram data pin in kHz */ - u32 sclk; /* engine clock in kHz */ - u32 disp_clk; /* display clock in kHz */ - u32 src_width; /* viewport width */ - u32 active_time; /* active display time in ns */ - u32 blank_time; /* blank time in ns */ - bool interlaced; /* mode is interlaced */ - fixed20_12 vsc; /* vertical scale ratio */ - u32 num_heads; /* number of active crtcs */ - u32 bytes_per_pixel; /* bytes per pixel display + overlay */ - u32 lb_size; /* line buffer allocated to pipe */ - u32 vtaps; /* vertical scaler taps */ -}; - -static u32 dce6_dram_bandwidth(struct dce6_wm_params *wm) -{ - /* Calculate raw DRAM Bandwidth */ - fixed20_12 dram_efficiency; /* 0.7 */ - fixed20_12 yclk, dram_channels, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - yclk.full = dfixed_const(wm->yclk); - yclk.full = dfixed_div(yclk, a); - dram_channels.full = dfixed_const(wm->dram_channels * 4); - a.full = dfixed_const(10); - dram_efficiency.full = dfixed_const(7); - dram_efficiency.full = dfixed_div(dram_efficiency, a); - bandwidth.full = dfixed_mul(dram_channels, yclk); - bandwidth.full = dfixed_mul(bandwidth, dram_efficiency); - - return dfixed_trunc(bandwidth); -} - -static u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm) -{ - /* Calculate DRAM Bandwidth and the part allocated to display. */ - fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */ - fixed20_12 yclk, dram_channels, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - yclk.full = dfixed_const(wm->yclk); - yclk.full = dfixed_div(yclk, a); - dram_channels.full = dfixed_const(wm->dram_channels * 4); - a.full = dfixed_const(10); - disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */ - disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a); - bandwidth.full = dfixed_mul(dram_channels, yclk); - bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation); - - return dfixed_trunc(bandwidth); -} - -static u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm) -{ - /* Calculate the display Data return Bandwidth */ - fixed20_12 return_efficiency; /* 0.8 */ - fixed20_12 sclk, bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - sclk.full = dfixed_const(wm->sclk); - sclk.full = dfixed_div(sclk, a); - a.full = dfixed_const(10); - return_efficiency.full = dfixed_const(8); - return_efficiency.full = dfixed_div(return_efficiency, a); - a.full = dfixed_const(32); - bandwidth.full = dfixed_mul(a, sclk); - bandwidth.full = dfixed_mul(bandwidth, return_efficiency); - - return dfixed_trunc(bandwidth); -} - -static u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm) -{ - return 32; -} - -static u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm) -{ - /* Calculate the DMIF Request Bandwidth */ - fixed20_12 disp_clk_request_efficiency; /* 0.8 */ - fixed20_12 disp_clk, sclk, bandwidth; - fixed20_12 a, b1, b2; - u32 min_bandwidth; - - a.full = dfixed_const(1000); - disp_clk.full = dfixed_const(wm->disp_clk); - disp_clk.full = dfixed_div(disp_clk, a); - a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2); - b1.full = dfixed_mul(a, disp_clk); - - a.full = dfixed_const(1000); - sclk.full = dfixed_const(wm->sclk); - sclk.full = dfixed_div(sclk, a); - a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm)); - b2.full = dfixed_mul(a, sclk); - - a.full = dfixed_const(10); - disp_clk_request_efficiency.full = dfixed_const(8); - disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a); - - min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2)); - - a.full = dfixed_const(min_bandwidth); - bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency); - - return dfixed_trunc(bandwidth); -} - -static u32 dce6_available_bandwidth(struct dce6_wm_params *wm) -{ - /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */ - u32 dram_bandwidth = dce6_dram_bandwidth(wm); - u32 data_return_bandwidth = dce6_data_return_bandwidth(wm); - u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm); - - return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth)); -} - -static u32 dce6_average_bandwidth(struct dce6_wm_params *wm) -{ - /* Calculate the display mode Average Bandwidth - * DisplayMode should contain the source and destination dimensions, - * timing, etc. - */ - fixed20_12 bpp; - fixed20_12 line_time; - fixed20_12 src_width; - fixed20_12 bandwidth; - fixed20_12 a; - - a.full = dfixed_const(1000); - line_time.full = dfixed_const(wm->active_time + wm->blank_time); - line_time.full = dfixed_div(line_time, a); - bpp.full = dfixed_const(wm->bytes_per_pixel); - src_width.full = dfixed_const(wm->src_width); - bandwidth.full = dfixed_mul(src_width, bpp); - bandwidth.full = dfixed_mul(bandwidth, wm->vsc); - bandwidth.full = dfixed_div(bandwidth, line_time); - - return dfixed_trunc(bandwidth); -} - -static u32 dce6_latency_watermark(struct dce6_wm_params *wm) -{ - /* First calcualte the latency in ns */ - u32 mc_latency = 2000; /* 2000 ns. */ - u32 available_bandwidth = dce6_available_bandwidth(wm); - u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; - u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; - u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ - u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + - (wm->num_heads * cursor_line_pair_return_time); - u32 latency = mc_latency + other_heads_data_return_time + dc_latency; - u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; - u32 tmp, dmif_size = 12288; - fixed20_12 a, b, c; - - if (wm->num_heads == 0) - return 0; - - a.full = dfixed_const(2); - b.full = dfixed_const(1); - if ((wm->vsc.full > a.full) || - ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) || - (wm->vtaps >= 5) || - ((wm->vsc.full >= a.full) && wm->interlaced)) - max_src_lines_per_dst_line = 4; - else - max_src_lines_per_dst_line = 2; - - a.full = dfixed_const(available_bandwidth); - b.full = dfixed_const(wm->num_heads); - a.full = dfixed_div(a, b); - - b.full = dfixed_const(mc_latency + 512); - c.full = dfixed_const(wm->disp_clk); - b.full = dfixed_div(b, c); - - c.full = dfixed_const(dmif_size); - b.full = dfixed_div(c, b); - - tmp = min(dfixed_trunc(a), dfixed_trunc(b)); - - b.full = dfixed_const(1000); - c.full = dfixed_const(wm->disp_clk); - b.full = dfixed_div(c, b); - c.full = dfixed_const(wm->bytes_per_pixel); - b.full = dfixed_mul(b, c); - - lb_fill_bw = min(tmp, dfixed_trunc(b)); - - a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); - b.full = dfixed_const(1000); - c.full = dfixed_const(lb_fill_bw); - b.full = dfixed_div(c, b); - a.full = dfixed_div(a, b); - line_fill_time = dfixed_trunc(a); - - if (line_fill_time < wm->active_time) - return latency; - else - return latency + (line_fill_time - wm->active_time); - -} - -static bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm) -{ - if (dce6_average_bandwidth(wm) <= - (dce6_dram_bandwidth_for_display(wm) / wm->num_heads)) - return true; - else - return false; -}; - -static bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm) -{ - if (dce6_average_bandwidth(wm) <= - (dce6_available_bandwidth(wm) / wm->num_heads)) - return true; - else - return false; -}; - -static bool dce6_check_latency_hiding(struct dce6_wm_params *wm) -{ - u32 lb_partitions = wm->lb_size / wm->src_width; - u32 line_time = wm->active_time + wm->blank_time; - u32 latency_tolerant_lines; - u32 latency_hiding; - fixed20_12 a; - - a.full = dfixed_const(1); - if (wm->vsc.full > a.full) - latency_tolerant_lines = 1; - else { - if (lb_partitions <= (wm->vtaps + 1)) - latency_tolerant_lines = 1; - else - latency_tolerant_lines = 2; - } - - latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time); - - if (dce6_latency_watermark(wm) <= latency_hiding) - return true; - else - return false; -} - -static void dce6_program_watermarks(struct radeon_device *rdev, - struct radeon_crtc *radeon_crtc, - u32 lb_size, u32 num_heads) -{ - struct drm_display_mode *mode = &radeon_crtc->base.mode; - struct dce6_wm_params wm; - u32 pixel_period; - u32 line_time = 0; - u32 latency_watermark_a = 0, latency_watermark_b = 0; - u32 priority_a_mark = 0, priority_b_mark = 0; - u32 priority_a_cnt = PRIORITY_OFF; - u32 priority_b_cnt = PRIORITY_OFF; - u32 tmp, arb_control3; - fixed20_12 a, b, c; - - if (radeon_crtc->base.enabled && num_heads && mode) { - pixel_period = 1000000 / (u32)mode->clock; - line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535); - priority_a_cnt = 0; - priority_b_cnt = 0; - - wm.yclk = rdev->pm.current_mclk * 10; - wm.sclk = rdev->pm.current_sclk * 10; - wm.disp_clk = mode->clock; - wm.src_width = mode->crtc_hdisplay; - wm.active_time = mode->crtc_hdisplay * pixel_period; - wm.blank_time = line_time - wm.active_time; - wm.interlaced = false; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - wm.interlaced = true; - wm.vsc = radeon_crtc->vsc; - wm.vtaps = 1; - if (radeon_crtc->rmx_type != RMX_OFF) - wm.vtaps = 2; - wm.bytes_per_pixel = 4; /* XXX: get this from fb config */ - wm.lb_size = lb_size; - if (rdev->family == CHIP_ARUBA) - wm.dram_channels = evergreen_get_number_of_dram_channels(rdev); - else - wm.dram_channels = si_get_number_of_dram_channels(rdev); - wm.num_heads = num_heads; - - /* set for high clocks */ - latency_watermark_a = min(dce6_latency_watermark(&wm), (u32)65535); - /* set for low clocks */ - /* wm.yclk = low clk; wm.sclk = low clk */ - latency_watermark_b = min(dce6_latency_watermark(&wm), (u32)65535); - - /* possibly force display priority to high */ - /* should really do this at mode validation time... */ - if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm) || - !dce6_average_bandwidth_vs_available_bandwidth(&wm) || - !dce6_check_latency_hiding(&wm) || - (rdev->disp_priority == 2)) { - DRM_DEBUG_KMS("force priority to high\n"); - priority_a_cnt |= PRIORITY_ALWAYS_ON; - priority_b_cnt |= PRIORITY_ALWAYS_ON; - } - - a.full = dfixed_const(1000); - b.full = dfixed_const(mode->clock); - b.full = dfixed_div(b, a); - c.full = dfixed_const(latency_watermark_a); - c.full = dfixed_mul(c, b); - c.full = dfixed_mul(c, radeon_crtc->hsc); - c.full = dfixed_div(c, a); - a.full = dfixed_const(16); - c.full = dfixed_div(c, a); - priority_a_mark = dfixed_trunc(c); - priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK; - - a.full = dfixed_const(1000); - b.full = dfixed_const(mode->clock); - b.full = dfixed_div(b, a); - c.full = dfixed_const(latency_watermark_b); - c.full = dfixed_mul(c, b); - c.full = dfixed_mul(c, radeon_crtc->hsc); - c.full = dfixed_div(c, a); - a.full = dfixed_const(16); - c.full = dfixed_div(c, a); - priority_b_mark = dfixed_trunc(c); - priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; - } - - /* select wm A */ - arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset); - tmp = arb_control3; - tmp &= ~LATENCY_WATERMARK_MASK(3); - tmp |= LATENCY_WATERMARK_MASK(1); - WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp); - WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset, - (LATENCY_LOW_WATERMARK(latency_watermark_a) | - LATENCY_HIGH_WATERMARK(line_time))); - /* select wm B */ - tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset); - tmp &= ~LATENCY_WATERMARK_MASK(3); - tmp |= LATENCY_WATERMARK_MASK(2); - WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp); - WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset, - (LATENCY_LOW_WATERMARK(latency_watermark_b) | - LATENCY_HIGH_WATERMARK(line_time))); - /* restore original selection */ - WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3); - - /* write the priority marks */ - WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt); - WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt); - -} - -void dce6_bandwidth_update(struct radeon_device *rdev) -{ - struct drm_display_mode *mode0 = NULL; - struct drm_display_mode *mode1 = NULL; - u32 num_heads = 0, lb_size; - int i; - - radeon_update_display_priority(rdev); - - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->mode_info.crtcs[i]->base.enabled) - num_heads++; - } - for (i = 0; i < rdev->num_crtc; i += 2) { - mode0 = &rdev->mode_info.crtcs[i]->base.mode; - mode1 = &rdev->mode_info.crtcs[i+1]->base.mode; - lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1); - dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads); - lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0); - dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads); - } -} - -/* - * Core functions - */ -static u32 si_get_tile_pipe_to_backend_map(struct radeon_device *rdev, - u32 num_tile_pipes, - u32 num_backends_per_asic, - u32 *backend_disable_mask_per_asic, - u32 num_shader_engines) -{ - u32 backend_map = 0; - u32 enabled_backends_mask = 0; - u32 enabled_backends_count = 0; - u32 num_backends_per_se; - u32 cur_pipe; - u32 swizzle_pipe[SI_MAX_PIPES]; - u32 cur_backend = 0; - u32 i; - bool force_no_swizzle; - - /* force legal values */ - if (num_tile_pipes < 1) - num_tile_pipes = 1; - if (num_tile_pipes > rdev->config.si.max_tile_pipes) - num_tile_pipes = rdev->config.si.max_tile_pipes; - if (num_shader_engines < 1) - num_shader_engines = 1; - if (num_shader_engines > rdev->config.si.max_shader_engines) - num_shader_engines = rdev->config.si.max_shader_engines; - if (num_backends_per_asic < num_shader_engines) - num_backends_per_asic = num_shader_engines; - if (num_backends_per_asic > (rdev->config.si.max_backends_per_se * num_shader_engines)) - num_backends_per_asic = rdev->config.si.max_backends_per_se * num_shader_engines; - - /* make sure we have the same number of backends per se */ - num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines); - /* set up the number of backends per se */ - num_backends_per_se = num_backends_per_asic / num_shader_engines; - if (num_backends_per_se > rdev->config.si.max_backends_per_se) { - num_backends_per_se = rdev->config.si.max_backends_per_se; - num_backends_per_asic = num_backends_per_se * num_shader_engines; - } - - /* create enable mask and count for enabled backends */ - for (i = 0; i < SI_MAX_BACKENDS; ++i) { - if (((*backend_disable_mask_per_asic >> i) & 1) == 0) { - enabled_backends_mask |= (1 << i); - ++enabled_backends_count; - } - if (enabled_backends_count == num_backends_per_asic) - break; - } - - /* force the backends mask to match the current number of backends */ - if (enabled_backends_count != num_backends_per_asic) { - u32 this_backend_enabled; - u32 shader_engine; - u32 backend_per_se; - - enabled_backends_mask = 0; - enabled_backends_count = 0; - *backend_disable_mask_per_asic = SI_MAX_BACKENDS_MASK; - for (i = 0; i < SI_MAX_BACKENDS; ++i) { - /* calc the current se */ - shader_engine = i / rdev->config.si.max_backends_per_se; - /* calc the backend per se */ - backend_per_se = i % rdev->config.si.max_backends_per_se; - /* default to not enabled */ - this_backend_enabled = 0; - if ((shader_engine < num_shader_engines) && - (backend_per_se < num_backends_per_se)) - this_backend_enabled = 1; - if (this_backend_enabled) { - enabled_backends_mask |= (1 << i); - *backend_disable_mask_per_asic &= ~(1 << i); - ++enabled_backends_count; - } - } - } - - - memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * SI_MAX_PIPES); - switch (rdev->family) { - case CHIP_TAHITI: - case CHIP_PITCAIRN: - case CHIP_VERDE: - force_no_swizzle = true; - break; - default: - force_no_swizzle = false; - break; - } - if (force_no_swizzle) { - bool last_backend_enabled = false; - - force_no_swizzle = false; - for (i = 0; i < SI_MAX_BACKENDS; ++i) { - if (((enabled_backends_mask >> i) & 1) == 1) { - if (last_backend_enabled) - force_no_swizzle = true; - last_backend_enabled = true; - } else - last_backend_enabled = false; - } - } - - switch (num_tile_pipes) { - case 1: - case 3: - case 5: - case 7: - DRM_ERROR("odd number of pipes!\n"); - break; - case 2: - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - break; - case 4: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 1; - swizzle_pipe[3] = 3; - } - break; - case 6: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 1; - swizzle_pipe[4] = 3; - swizzle_pipe[5] = 5; - } - break; - case 8: - if (force_no_swizzle) { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 1; - swizzle_pipe[2] = 2; - swizzle_pipe[3] = 3; - swizzle_pipe[4] = 4; - swizzle_pipe[5] = 5; - swizzle_pipe[6] = 6; - swizzle_pipe[7] = 7; - } else { - swizzle_pipe[0] = 0; - swizzle_pipe[1] = 2; - swizzle_pipe[2] = 4; - swizzle_pipe[3] = 6; - swizzle_pipe[4] = 1; - swizzle_pipe[5] = 3; - swizzle_pipe[6] = 5; - swizzle_pipe[7] = 7; - } - break; - } - - for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { - while (((1 << cur_backend) & enabled_backends_mask) == 0) - cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS; - - backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4))); - - cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS; - } - - return backend_map; -} - -static u32 si_get_disable_mask_per_asic(struct radeon_device *rdev, - u32 disable_mask_per_se, - u32 max_disable_mask_per_se, - u32 num_shader_engines) -{ - u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se); - u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se; - - if (num_shader_engines == 1) - return disable_mask_per_asic; - else if (num_shader_engines == 2) - return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se); - else - return 0xffffffff; -} - -static void si_tiling_mode_table_init(struct radeon_device *rdev) -{ - const u32 num_tile_mode_states = 32; - u32 reg_offset, gb_tile_moden, split_equal_to_row_size; - - switch (rdev->config.si.mem_row_size_in_kb) { - case 1: - split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB; - break; - case 2: - default: - split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB; - break; - case 4: - split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB; - break; - } - - if ((rdev->family == CHIP_TAHITI) || - (rdev->family == CHIP_PITCAIRN)) { - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: /* non-AA compressed depth or any compressed stencil */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 1: /* 2xAA/4xAA compressed depth only */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 2: /* 8xAA compressed depth only */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 3: /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 4: /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */ - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 5: /* Uncompressed 16bpp depth - and stencil buffer allocated with it */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 6: /* Uncompressed 32bpp depth - and stencil buffer allocated with it */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - case 7: /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 8: /* 1D and 1D Array Surfaces */ - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 9: /* Displayable maps. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 10: /* Display 8bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 11: /* Display 16bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 12: /* Display 32bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - case 13: /* Thin. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 14: /* Thin 8 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - case 15: /* Thin 16 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - case 16: /* Thin 32 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - case 17: /* Thin 64 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - case 21: /* 8 bpp PRT. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 22: /* 16 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 23: /* 32 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 24: /* 64 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 25: /* 128 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) | - NUM_BANKS(ADDR_SURF_8_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - default: - gb_tile_moden = 0; - break; - } - WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); - } - } else if (rdev->family == CHIP_VERDE) { - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: /* non-AA compressed depth or any compressed stencil */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 1: /* 2xAA/4xAA compressed depth only */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 2: /* 8xAA compressed depth only */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 3: /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 4: /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */ - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 5: /* Uncompressed 16bpp depth - and stencil buffer allocated with it */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 6: /* Uncompressed 32bpp depth - and stencil buffer allocated with it */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 7: /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 8: /* 1D and 1D Array Surfaces */ - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 9: /* Displayable maps. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 10: /* Display 8bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 11: /* Display 16bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 12: /* Display 32bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 13: /* Thin. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 14: /* Thin 8 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 15: /* Thin 16 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 16: /* Thin 32 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 17: /* Thin 64 bpp. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P4_8x16) | - TILE_SPLIT(split_equal_to_row_size) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 21: /* 8 bpp PRT. */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 22: /* 16 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); - break; - case 23: /* 32 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 24: /* 64 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - NUM_BANKS(ADDR_SURF_16_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); - break; - case 25: /* 128 bpp PRT */ - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | - PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) | - NUM_BANKS(ADDR_SURF_8_BANK) | - BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); - break; - default: - gb_tile_moden = 0; - break; - } - WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); - } - } else - DRM_ERROR("unknown asic: 0x%x\n", rdev->family); -} - -static void si_gpu_init(struct radeon_device *rdev) -{ - u32 cc_rb_backend_disable = 0; - u32 cc_gc_shader_array_config; - u32 gb_addr_config = 0; - u32 mc_shared_chmap, mc_arb_ramcfg; - u32 gb_backend_map; - u32 cgts_tcc_disable; - u32 sx_debug_1; - u32 gc_user_shader_array_config; - u32 gc_user_rb_backend_disable; - u32 cgts_user_tcc_disable; - u32 hdp_host_path_cntl; - u32 tmp; - int i, j; - - switch (rdev->family) { - case CHIP_TAHITI: - rdev->config.si.max_shader_engines = 2; - rdev->config.si.max_pipes_per_simd = 4; - rdev->config.si.max_tile_pipes = 12; - rdev->config.si.max_simds_per_se = 8; - rdev->config.si.max_backends_per_se = 4; - rdev->config.si.max_texture_channel_caches = 12; - rdev->config.si.max_gprs = 256; - rdev->config.si.max_gs_threads = 32; - rdev->config.si.max_hw_contexts = 8; - - rdev->config.si.sc_prim_fifo_size_frontend = 0x20; - rdev->config.si.sc_prim_fifo_size_backend = 0x100; - rdev->config.si.sc_hiz_tile_fifo_size = 0x30; - rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_PITCAIRN: - rdev->config.si.max_shader_engines = 2; - rdev->config.si.max_pipes_per_simd = 4; - rdev->config.si.max_tile_pipes = 8; - rdev->config.si.max_simds_per_se = 5; - rdev->config.si.max_backends_per_se = 4; - rdev->config.si.max_texture_channel_caches = 8; - rdev->config.si.max_gprs = 256; - rdev->config.si.max_gs_threads = 32; - rdev->config.si.max_hw_contexts = 8; - - rdev->config.si.sc_prim_fifo_size_frontend = 0x20; - rdev->config.si.sc_prim_fifo_size_backend = 0x100; - rdev->config.si.sc_hiz_tile_fifo_size = 0x30; - rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - break; - case CHIP_VERDE: - default: - rdev->config.si.max_shader_engines = 1; - rdev->config.si.max_pipes_per_simd = 4; - rdev->config.si.max_tile_pipes = 4; - rdev->config.si.max_simds_per_se = 2; - rdev->config.si.max_backends_per_se = 4; - rdev->config.si.max_texture_channel_caches = 4; - rdev->config.si.max_gprs = 256; - rdev->config.si.max_gs_threads = 32; - rdev->config.si.max_hw_contexts = 8; - - rdev->config.si.sc_prim_fifo_size_frontend = 0x20; - rdev->config.si.sc_prim_fifo_size_backend = 0x40; - rdev->config.si.sc_hiz_tile_fifo_size = 0x30; - rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - break; - } - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - - WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); - - evergreen_fix_pci_max_read_req_size(rdev); - - WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); - - mc_shared_chmap = RREG32(MC_SHARED_CHMAP); - mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); - - cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); - cc_gc_shader_array_config = RREG32(CC_GC_SHADER_ARRAY_CONFIG); - cgts_tcc_disable = 0xffff0000; - for (i = 0; i < rdev->config.si.max_texture_channel_caches; i++) - cgts_tcc_disable &= ~(1 << (16 + i)); - gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); - gc_user_shader_array_config = RREG32(GC_USER_SHADER_ARRAY_CONFIG); - cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); - - rdev->config.si.num_shader_engines = rdev->config.si.max_shader_engines; - rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes; - tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.si.num_backends_per_se = r600_count_pipe_bits(tmp); - tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT; - rdev->config.si.backend_disable_mask_per_asic = - si_get_disable_mask_per_asic(rdev, tmp, SI_MAX_BACKENDS_PER_SE_MASK, - rdev->config.si.num_shader_engines); - rdev->config.si.backend_map = - si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes, - rdev->config.si.num_backends_per_se * - rdev->config.si.num_shader_engines, - &rdev->config.si.backend_disable_mask_per_asic, - rdev->config.si.num_shader_engines); - tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT; - rdev->config.si.num_texture_channel_caches = r600_count_pipe_bits(tmp); - rdev->config.si.mem_max_burst_length_bytes = 256; - tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; - rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; - if (rdev->config.si.mem_row_size_in_kb > 4) - rdev->config.si.mem_row_size_in_kb = 4; - /* XXX use MC settings? */ - rdev->config.si.shader_engine_tile_size = 32; - rdev->config.si.num_gpus = 1; - rdev->config.si.multi_gpu_tile_size = 64; - - gb_addr_config = 0; - switch (rdev->config.si.num_tile_pipes) { - case 1: - gb_addr_config |= NUM_PIPES(0); - break; - case 2: - gb_addr_config |= NUM_PIPES(1); - break; - case 4: - gb_addr_config |= NUM_PIPES(2); - break; - case 8: - default: - gb_addr_config |= NUM_PIPES(3); - break; - } - - tmp = (rdev->config.si.mem_max_burst_length_bytes / 256) - 1; - gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp); - gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.si.num_shader_engines - 1); - tmp = (rdev->config.si.shader_engine_tile_size / 16) - 1; - gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp); - switch (rdev->config.si.num_gpus) { - case 1: - default: - gb_addr_config |= NUM_GPUS(0); - break; - case 2: - gb_addr_config |= NUM_GPUS(1); - break; - case 4: - gb_addr_config |= NUM_GPUS(2); - break; - } - switch (rdev->config.si.multi_gpu_tile_size) { - case 16: - gb_addr_config |= MULTI_GPU_TILE_SIZE(0); - break; - case 32: - default: - gb_addr_config |= MULTI_GPU_TILE_SIZE(1); - break; - case 64: - gb_addr_config |= MULTI_GPU_TILE_SIZE(2); - break; - case 128: - gb_addr_config |= MULTI_GPU_TILE_SIZE(3); - break; - } - switch (rdev->config.si.mem_row_size_in_kb) { - case 1: - default: - gb_addr_config |= ROW_SIZE(0); - break; - case 2: - gb_addr_config |= ROW_SIZE(1); - break; - case 4: - gb_addr_config |= ROW_SIZE(2); - break; - } - - tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; - rdev->config.si.num_tile_pipes = (1 << tmp); - tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; - rdev->config.si.mem_max_burst_length_bytes = (tmp + 1) * 256; - tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT; - rdev->config.si.num_shader_engines = tmp + 1; - tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT; - rdev->config.si.num_gpus = tmp + 1; - tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT; - rdev->config.si.multi_gpu_tile_size = 1 << tmp; - tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; - rdev->config.si.mem_row_size_in_kb = 1 << tmp; - - gb_backend_map = - si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes, - rdev->config.si.num_backends_per_se * - rdev->config.si.num_shader_engines, - &rdev->config.si.backend_disable_mask_per_asic, - rdev->config.si.num_shader_engines); - - /* setup tiling info dword. gb_addr_config is not adequate since it does - * not have bank info, so create a custom tiling dword. - * bits 3:0 num_pipes - * bits 7:4 num_banks - * bits 11:8 group_size - * bits 15:12 row_size - */ - rdev->config.si.tile_config = 0; - switch (rdev->config.si.num_tile_pipes) { - case 1: - rdev->config.si.tile_config |= (0 << 0); - break; - case 2: - rdev->config.si.tile_config |= (1 << 0); - break; - case 4: - rdev->config.si.tile_config |= (2 << 0); - break; - case 8: - default: - /* XXX what about 12? */ - rdev->config.si.tile_config |= (3 << 0); - break; - } - rdev->config.si.tile_config |= - ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; - rdev->config.si.tile_config |= - ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; - rdev->config.si.tile_config |= - ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; - - rdev->config.si.backend_map = gb_backend_map; - WREG32(GB_ADDR_CONFIG, gb_addr_config); - WREG32(DMIF_ADDR_CONFIG, gb_addr_config); - WREG32(HDP_ADDR_CONFIG, gb_addr_config); - - /* primary versions */ - WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(CC_GC_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config); - - WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); - - /* user versions */ - WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); - WREG32(GC_USER_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config); - - WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); - - si_tiling_mode_table_init(rdev); - - /* set HW defaults for 3D engine */ - WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | - ROQ_IB2_START(0x2b))); - WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); - - sx_debug_1 = RREG32(SX_DEBUG_1); - WREG32(SX_DEBUG_1, sx_debug_1); - - WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); - - WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) | - SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) | - SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) | - SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size))); - - WREG32(VGT_NUM_INSTANCES, 1); - - WREG32(CP_PERFMON_CNTL, 0); - - WREG32(SQ_CONFIG, 0); - - WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | - FORCE_EOV_MAX_REZ_CNT(255))); - - WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) | - AUTO_INVLD_EN(ES_AND_GS_AUTO)); - - WREG32(VGT_GS_VERTEX_REUSE, 16); - WREG32(PA_SC_LINE_STIPPLE_STATE, 0); - - WREG32(CB_PERFCOUNTER0_SELECT0, 0); - WREG32(CB_PERFCOUNTER0_SELECT1, 0); - WREG32(CB_PERFCOUNTER1_SELECT0, 0); - WREG32(CB_PERFCOUNTER1_SELECT1, 0); - WREG32(CB_PERFCOUNTER2_SELECT0, 0); - WREG32(CB_PERFCOUNTER2_SELECT1, 0); - WREG32(CB_PERFCOUNTER3_SELECT0, 0); - WREG32(CB_PERFCOUNTER3_SELECT1, 0); - - tmp = RREG32(HDP_MISC_CNTL); - tmp |= HDP_FLUSH_INVALIDATE_CACHE; - WREG32(HDP_MISC_CNTL, tmp); - - hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); - WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); - - WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); - - udelay(50); -} - -/* - * GPU scratch registers helpers function. - */ -static void si_scratch_init(struct radeon_device *rdev) -{ - int i; - - rdev->scratch.num_reg = 7; - rdev->scratch.reg_base = SCRATCH_REG0; - for (i = 0; i < rdev->scratch.num_reg; i++) { - rdev->scratch.free[i] = true; - rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); - } -} - -void si_fence_ring_emit(struct radeon_device *rdev, - struct radeon_fence *fence) -{ - struct radeon_ring *ring = &rdev->ring[fence->ring]; - u64 addr = rdev->fence_drv[fence->ring].gpu_addr; - - /* flush read cache over gart */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | - PACKET3_TC_ACTION_ENA | - PACKET3_SH_KCACHE_ACTION_ENA | - PACKET3_SH_ICACHE_ACTION_ENA); - radeon_ring_write(ring, 0xFFFFFFFF); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ - /* EVENT_WRITE_EOP - flush caches, send int */ - radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); - radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5)); - radeon_ring_write(ring, addr & 0xffffffff); - radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); - radeon_ring_write(ring, fence->seq); - radeon_ring_write(ring, 0); -} - -/* - * IB stuff - */ -void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -{ - struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; - u32 header; - - if (ib->is_const_ib) - header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); - else - header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); - - radeon_ring_write(ring, header); - radeon_ring_write(ring, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (ib->gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); - radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); - - /* flush read cache over gart for this vmid */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(ring, ib->vm_id); - radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | - PACKET3_TC_ACTION_ENA | - PACKET3_SH_KCACHE_ACTION_ENA | - PACKET3_SH_ICACHE_ACTION_ENA); - radeon_ring_write(ring, 0xFFFFFFFF); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 10); /* poll interval */ -} - -/* - * CP. - */ -static void si_cp_enable(struct radeon_device *rdev, bool enable) -{ - if (enable) - WREG32(CP_ME_CNTL, 0); - else { - radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT)); - WREG32(SCRATCH_UMSK, 0); - } - udelay(50); -} - -static int si_cp_load_microcode(struct radeon_device *rdev) -{ - const __be32 *fw_data; - int i; - - if (!rdev->me_fw || !rdev->pfp_fw) - return -EINVAL; - - si_cp_enable(rdev, false); - - /* PFP */ - fw_data = (const __be32 *)rdev->pfp_fw->data; - WREG32(CP_PFP_UCODE_ADDR, 0); - for (i = 0; i < SI_PFP_UCODE_SIZE; i++) - WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_PFP_UCODE_ADDR, 0); - - /* CE */ - fw_data = (const __be32 *)rdev->ce_fw->data; - WREG32(CP_CE_UCODE_ADDR, 0); - for (i = 0; i < SI_CE_UCODE_SIZE; i++) - WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_CE_UCODE_ADDR, 0); - - /* ME */ - fw_data = (const __be32 *)rdev->me_fw->data; - WREG32(CP_ME_RAM_WADDR, 0); - for (i = 0; i < SI_PM4_UCODE_SIZE; i++) - WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); - WREG32(CP_ME_RAM_WADDR, 0); - - WREG32(CP_PFP_UCODE_ADDR, 0); - WREG32(CP_CE_UCODE_ADDR, 0); - WREG32(CP_ME_RAM_WADDR, 0); - WREG32(CP_ME_RAM_RADDR, 0); - return 0; -} - -static int si_cp_start(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r, i; - - r = radeon_ring_lock(rdev, ring, 7 + 4); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - /* init the CP */ - radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); - radeon_ring_write(ring, 0x1); - radeon_ring_write(ring, 0x0); - radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1); - radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); - radeon_ring_write(ring, 0); - radeon_ring_write(ring, 0); - - /* init the CE partitions */ - radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2)); - radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); - radeon_ring_write(ring, 0xc000); - radeon_ring_write(ring, 0xe000); - radeon_ring_unlock_commit(rdev, ring); - - si_cp_enable(rdev, true); - - r = radeon_ring_lock(rdev, ring, si_default_size + 10); - if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); - return r; - } - - /* setup clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); - - for (i = 0; i < si_default_size; i++) - radeon_ring_write(ring, si_default_state[i]); - - radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); - - /* set clear context state */ - radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(ring, 0); - - radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(ring, 0x00000316); - radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ - - radeon_ring_unlock_commit(rdev, ring); - - for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { - ring = &rdev->ring[i]; - r = radeon_ring_lock(rdev, ring, 2); - - /* clear the compute context state */ - radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(ring, 0); - - radeon_ring_unlock_commit(rdev, ring); - } - - return 0; -} - -static void si_cp_fini(struct radeon_device *rdev) -{ - si_cp_enable(rdev, false); - radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); - radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); -} - -static int si_cp_resume(struct radeon_device *rdev) -{ - struct radeon_ring *ring; - u32 tmp; - u32 rb_bufsz; - int r; - - /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ - WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | - SOFT_RESET_PA | - SOFT_RESET_VGT | - SOFT_RESET_SPI | - SOFT_RESET_SX)); - RREG32(GRBM_SOFT_RESET); - mdelay(15); - WREG32(GRBM_SOFT_RESET, 0); - RREG32(GRBM_SOFT_RESET); - - WREG32(CP_SEM_WAIT_TIMER, 0x0); - WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); - - /* Set the write pointer delay */ - WREG32(CP_RB_WPTR_DELAY, 0); - - WREG32(CP_DEBUG, 0); - WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); - - /* ring 0 - compute and gfx */ - /* Set ring buffer size */ - ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB0_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB0_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); - WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); - - if (rdev->wb.enabled) - WREG32(SCRATCH_UMSK, 0xff); - else { - tmp |= RB_NO_UPDATE; - WREG32(SCRATCH_UMSK, 0); - } - - mdelay(1); - WREG32(CP_RB0_CNTL, tmp); - - WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB0_RPTR); - - /* ring1 - compute only */ - /* Set ring buffer size */ - ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB1_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB1_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); - WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); - - mdelay(1); - WREG32(CP_RB1_CNTL, tmp); - - WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB1_RPTR); - - /* ring2 - compute only */ - /* Set ring buffer size */ - ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB2_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB2_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); - WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF); - - mdelay(1); - WREG32(CP_RB2_CNTL, tmp); - - WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB2_RPTR); - - /* start the rings */ - si_cp_start(rdev); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; - rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true; - rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true; - r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; - return r; - } - r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); - if (r) { - rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - } - r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); - if (r) { - rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; - } - - return 0; -} - -bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - u32 srbm_status; - u32 grbm_status, grbm_status2; - u32 grbm_status_se0, grbm_status_se1; - struct r100_gpu_lockup *lockup = &rdev->config.si.lockup; - int r; - - srbm_status = RREG32(SRBM_STATUS); - grbm_status = RREG32(GRBM_STATUS); - grbm_status2 = RREG32(GRBM_STATUS2); - grbm_status_se0 = RREG32(GRBM_STATUS_SE0); - grbm_status_se1 = RREG32(GRBM_STATUS_SE1); - if (!(grbm_status & GUI_ACTIVE)) { - r100_gpu_lockup_update(lockup, ring); - return false; - } - /* force CP activities */ - r = radeon_ring_lock(rdev, ring, 2); - if (!r) { - /* PACKET2 NOP */ - radeon_ring_write(ring, 0x80000000); - radeon_ring_write(ring, 0x80000000); - radeon_ring_unlock_commit(rdev, ring); - } - /* XXX deal with CP0,1,2 */ - ring->rptr = RREG32(ring->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, lockup, ring); -} - -static int si_gpu_soft_reset(struct radeon_device *rdev) -{ - struct evergreen_mc_save save; - u32 grbm_reset = 0; - - if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) - return 0; - - dev_info(rdev->dev, "GPU softreset \n"); - dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(GRBM_STATUS)); - dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", - RREG32(GRBM_STATUS2)); - dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(GRBM_STATUS_SE0)); - dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(GRBM_STATUS_SE1)); - dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(SRBM_STATUS)); - evergreen_mc_stop(rdev, &save); - if (radeon_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Disable CP parsing/prefetching */ - WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); - - /* reset all the gfx blocks */ - grbm_reset = (SOFT_RESET_CP | - SOFT_RESET_CB | - SOFT_RESET_DB | - SOFT_RESET_GDS | - SOFT_RESET_PA | - SOFT_RESET_SC | - SOFT_RESET_SPI | - SOFT_RESET_SX | - SOFT_RESET_TC | - SOFT_RESET_TA | - SOFT_RESET_VGT | - SOFT_RESET_IA); - - dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset); - WREG32(GRBM_SOFT_RESET, grbm_reset); - (void)RREG32(GRBM_SOFT_RESET); - udelay(50); - WREG32(GRBM_SOFT_RESET, 0); - (void)RREG32(GRBM_SOFT_RESET); - /* Wait a little for things to settle down */ - udelay(50); - dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(GRBM_STATUS)); - dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", - RREG32(GRBM_STATUS2)); - dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(GRBM_STATUS_SE0)); - dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(GRBM_STATUS_SE1)); - dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(SRBM_STATUS)); - evergreen_mc_resume(rdev, &save); - return 0; -} - -int si_asic_reset(struct radeon_device *rdev) -{ - return si_gpu_soft_reset(rdev); -} - -/* MC */ -static void si_mc_program(struct radeon_device *rdev) -{ - struct evergreen_mc_save save; - u32 tmp; - int i, j; - - /* Initialize HDP */ - for (i = 0, j = 0; i < 32; i++, j += 0x18) { - WREG32((0x2c14 + j), 0x00000000); - WREG32((0x2c18 + j), 0x00000000); - WREG32((0x2c1c + j), 0x00000000); - WREG32((0x2c20 + j), 0x00000000); - WREG32((0x2c24 + j), 0x00000000); - } - WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); - - evergreen_mc_stop(rdev, &save); - if (radeon_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - /* Lockout access through VGA aperture*/ - WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); - /* Update configuration */ - WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, - rdev->mc.vram_start >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, - rdev->mc.vram_end >> 12); - WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, - rdev->vram_scratch.gpu_addr >> 12); - tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; - tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); - WREG32(MC_VM_FB_LOCATION, tmp); - /* XXX double check these! */ - WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); - WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); - WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); - WREG32(MC_VM_AGP_BASE, 0); - WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); - WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); - if (radeon_mc_wait_for_idle(rdev)) { - dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); - } - evergreen_mc_resume(rdev, &save); - /* we need to own VRAM, so turn off the VGA renderer here - * to stop it overwriting our objects */ - rv515_vga_render_disable(rdev); -} - -/* SI MC address space is 40 bits */ -static void si_vram_location(struct radeon_device *rdev, - struct radeon_mc *mc, u64 base) -{ - mc->vram_start = base; - if (mc->mc_vram_size > (0xFFFFFFFFFFULL - base + 1)) { - dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); - mc->real_vram_size = mc->aper_size; - mc->mc_vram_size = mc->aper_size; - } - mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", - mc->mc_vram_size >> 20, mc->vram_start, - mc->vram_end, mc->real_vram_size >> 20); -} - -static void si_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) -{ - u64 size_af, size_bf; - - size_af = ((0xFFFFFFFFFFULL - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align; - size_bf = mc->vram_start & ~mc->gtt_base_align; - if (size_bf > size_af) { - if (mc->gtt_size > size_bf) { - dev_warn(rdev->dev, "limiting GTT\n"); - mc->gtt_size = size_bf; - } - mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size; - } else { - if (mc->gtt_size > size_af) { - dev_warn(rdev->dev, "limiting GTT\n"); - mc->gtt_size = size_af; - } - mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; - } - mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; - dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", - mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); -} - -static void si_vram_gtt_location(struct radeon_device *rdev, - struct radeon_mc *mc) -{ - if (mc->mc_vram_size > 0xFFC0000000ULL) { - /* leave room for at least 1024M GTT */ - dev_warn(rdev->dev, "limiting VRAM\n"); - mc->real_vram_size = 0xFFC0000000ULL; - mc->mc_vram_size = 0xFFC0000000ULL; - } - si_vram_location(rdev, &rdev->mc, 0); - rdev->mc.gtt_base_align = 0; - si_gtt_location(rdev, mc); -} - -static int si_mc_init(struct radeon_device *rdev) -{ - u32 tmp; - int chansize, numchan; - - /* Get VRAM informations */ - rdev->mc.vram_is_ddr = true; - tmp = RREG32(MC_ARB_RAMCFG); - if (tmp & CHANSIZE_OVERRIDE) { - chansize = 16; - } else if (tmp & CHANSIZE_MASK) { - chansize = 64; - } else { - chansize = 32; - } - tmp = RREG32(MC_SHARED_CHMAP); - switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { - case 0: - default: - numchan = 1; - break; - case 1: - numchan = 2; - break; - case 2: - numchan = 4; - break; - case 3: - numchan = 8; - break; - case 4: - numchan = 3; - break; - case 5: - numchan = 6; - break; - case 6: - numchan = 10; - break; - case 7: - numchan = 12; - break; - case 8: - numchan = 16; - break; - } - rdev->mc.vram_width = numchan * chansize; - /* Could aper size report 0 ? */ - rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); - rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); - /* size in MB on si */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; - rdev->mc.visible_vram_size = rdev->mc.aper_size; - si_vram_gtt_location(rdev, &rdev->mc); - radeon_update_bandwidth_info(rdev); - - return 0; -} - -/* - * GART - */ -void si_pcie_gart_tlb_flush(struct radeon_device *rdev) -{ - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - - /* bits 0-15 are the VM contexts0-15 */ - WREG32(VM_INVALIDATE_REQUEST, 1); -} - -int si_pcie_gart_enable(struct radeon_device *rdev) -{ - int r, i; - - if (rdev->gart.robj == NULL) { - dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); - return -EINVAL; - } - r = radeon_gart_table_vram_pin(rdev); - if (r) - return r; - radeon_gart_restore(rdev); - /* Setup TLB control */ - WREG32(MC_VM_MX_L1_TLB_CNTL, - (0xA << 7) | - ENABLE_L1_TLB | - SYSTEM_ACCESS_MODE_NOT_IN_SYS | - ENABLE_ADVANCED_DRIVER_MODEL | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | - ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7) | - CONTEXT1_IDENTITY_ACCESS_MODE(1)); - WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); - WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | - L2_CACHE_BIGK_FRAGMENT_SIZE(0)); - /* setup context0 */ - WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); - WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - WREG32(VM_CONTEXT0_CNTL2, 0); - WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT)); - - WREG32(0x15D4, 0); - WREG32(0x15D8, 0); - WREG32(0x15DC, 0); - - /* empty context1-15 */ - /* FIXME start with 4G, once using 2 level pt switch to full - * vm size space - */ - /* set vm size, must be a multiple of 4 */ - WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); - for (i = 1; i < 16; i++) { - if (i < 8) - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), - rdev->gart.table_addr >> 12); - else - WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), - rdev->gart.table_addr >> 12); - } - - /* enable context1-15 */ - WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, - (u32)(rdev->dummy_page.addr >> 12)); - WREG32(VM_CONTEXT1_CNTL2, 0); - WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | - RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - - si_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", - (unsigned)(rdev->mc.gtt_size >> 20), - (unsigned long long)rdev->gart.table_addr); - rdev->gart.ready = true; - return 0; -} - -void si_pcie_gart_disable(struct radeon_device *rdev) -{ - /* Disable all tables */ - WREG32(VM_CONTEXT0_CNTL, 0); - WREG32(VM_CONTEXT1_CNTL, 0); - /* Setup TLB control */ - WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS | - SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); - /* Setup L2 cache */ - WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | - ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | - EFFECTIVE_L2_QUEUE_SIZE(7) | - CONTEXT1_IDENTITY_ACCESS_MODE(1)); - WREG32(VM_L2_CNTL2, 0); - WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | - L2_CACHE_BIGK_FRAGMENT_SIZE(0)); - radeon_gart_table_vram_unpin(rdev); -} - -void si_pcie_gart_fini(struct radeon_device *rdev) -{ - si_pcie_gart_disable(rdev); - radeon_gart_table_vram_free(rdev); - radeon_gart_fini(rdev); -} - -/* vm parser */ -static bool si_vm_reg_valid(u32 reg) -{ - /* context regs are fine */ - if (reg >= 0x28000) - return true; - - /* check config regs */ - switch (reg) { - case GRBM_GFX_INDEX: - case VGT_VTX_VECT_EJECT_REG: - case VGT_CACHE_INVALIDATION: - case VGT_ESGS_RING_SIZE: - case VGT_GSVS_RING_SIZE: - case VGT_GS_VERTEX_REUSE: - case VGT_PRIMITIVE_TYPE: - case VGT_INDEX_TYPE: - case VGT_NUM_INDICES: - case VGT_NUM_INSTANCES: - case VGT_TF_RING_SIZE: - case VGT_HS_OFFCHIP_PARAM: - case VGT_TF_MEMORY_BASE: - case PA_CL_ENHANCE: - case PA_SU_LINE_STIPPLE_VALUE: - case PA_SC_LINE_STIPPLE_STATE: - case PA_SC_ENHANCE: - case SQC_CACHES: - case SPI_STATIC_THREAD_MGMT_1: - case SPI_STATIC_THREAD_MGMT_2: - case SPI_STATIC_THREAD_MGMT_3: - case SPI_PS_MAX_WAVE_ID: - case SPI_CONFIG_CNTL: - case SPI_CONFIG_CNTL_1: - case TA_CNTL_AUX: - return true; - default: - DRM_ERROR("Invalid register 0x%x in CS\n", reg); - return false; - } -} - -static int si_vm_packet3_ce_check(struct radeon_device *rdev, - u32 *ib, struct radeon_cs_packet *pkt) -{ - switch (pkt->opcode) { - case PACKET3_NOP: - case PACKET3_SET_BASE: - case PACKET3_SET_CE_DE_COUNTERS: - case PACKET3_LOAD_CONST_RAM: - case PACKET3_WRITE_CONST_RAM: - case PACKET3_WRITE_CONST_RAM_OFFSET: - case PACKET3_DUMP_CONST_RAM: - case PACKET3_INCREMENT_CE_COUNTER: - case PACKET3_WAIT_ON_DE_COUNTER: - case PACKET3_CE_WRITE: - break; - default: - DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -static int si_vm_packet3_gfx_check(struct radeon_device *rdev, - u32 *ib, struct radeon_cs_packet *pkt) -{ - u32 idx = pkt->idx + 1; - u32 idx_value = ib[idx]; - u32 start_reg, end_reg, reg, i; - - switch (pkt->opcode) { - case PACKET3_NOP: - case PACKET3_SET_BASE: - case PACKET3_CLEAR_STATE: - case PACKET3_INDEX_BUFFER_SIZE: - case PACKET3_DISPATCH_DIRECT: - case PACKET3_DISPATCH_INDIRECT: - case PACKET3_ALLOC_GDS: - case PACKET3_WRITE_GDS_RAM: - case PACKET3_ATOMIC_GDS: - case PACKET3_ATOMIC: - case PACKET3_OCCLUSION_QUERY: - case PACKET3_SET_PREDICATION: - case PACKET3_COND_EXEC: - case PACKET3_PRED_EXEC: - case PACKET3_DRAW_INDIRECT: - case PACKET3_DRAW_INDEX_INDIRECT: - case PACKET3_INDEX_BASE: - case PACKET3_DRAW_INDEX_2: - case PACKET3_CONTEXT_CONTROL: - case PACKET3_INDEX_TYPE: - case PACKET3_DRAW_INDIRECT_MULTI: - case PACKET3_DRAW_INDEX_AUTO: - case PACKET3_DRAW_INDEX_IMMD: - case PACKET3_NUM_INSTANCES: - case PACKET3_DRAW_INDEX_MULTI_AUTO: - case PACKET3_STRMOUT_BUFFER_UPDATE: - case PACKET3_DRAW_INDEX_OFFSET_2: - case PACKET3_DRAW_INDEX_MULTI_ELEMENT: - case PACKET3_DRAW_INDEX_INDIRECT_MULTI: - case PACKET3_MPEG_INDEX: - case PACKET3_WAIT_REG_MEM: - case PACKET3_MEM_WRITE: - case PACKET3_PFP_SYNC_ME: - case PACKET3_SURFACE_SYNC: - case PACKET3_EVENT_WRITE: - case PACKET3_EVENT_WRITE_EOP: - case PACKET3_EVENT_WRITE_EOS: - case PACKET3_SET_CONTEXT_REG: - case PACKET3_SET_CONTEXT_REG_INDIRECT: - case PACKET3_SET_SH_REG: - case PACKET3_SET_SH_REG_OFFSET: - case PACKET3_INCREMENT_DE_COUNTER: - case PACKET3_WAIT_ON_CE_COUNTER: - case PACKET3_WAIT_ON_AVAIL_BUFFER: - case PACKET3_ME_WRITE: - break; - case PACKET3_COPY_DATA: - if ((idx_value & 0xf00) == 0) { - reg = ib[idx + 3] * 4; - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_WRITE_DATA: - if ((idx_value & 0xf00) == 0) { - start_reg = ib[idx + 1] * 4; - if (idx_value & 0x10000) { - if (!si_vm_reg_valid(start_reg)) - return -EINVAL; - } else { - for (i = 0; i < (pkt->count - 2); i++) { - reg = start_reg + (4 * i); - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - } - } - break; - case PACKET3_COND_WRITE: - if (idx_value & 0x100) { - reg = ib[idx + 5] * 4; - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_COPY_DW: - if (idx_value & 0x2) { - reg = ib[idx + 3] * 4; - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_SET_CONFIG_REG: - start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; - end_reg = 4 * pkt->count + start_reg - 4; - if ((start_reg < PACKET3_SET_CONFIG_REG_START) || - (start_reg >= PACKET3_SET_CONFIG_REG_END) || - (end_reg >= PACKET3_SET_CONFIG_REG_END)) { - DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); - return -EINVAL; - } - for (i = 0; i < pkt->count; i++) { - reg = start_reg + (4 * i); - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - default: - DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -static int si_vm_packet3_compute_check(struct radeon_device *rdev, - u32 *ib, struct radeon_cs_packet *pkt) -{ - u32 idx = pkt->idx + 1; - u32 idx_value = ib[idx]; - u32 start_reg, reg, i; - - switch (pkt->opcode) { - case PACKET3_NOP: - case PACKET3_SET_BASE: - case PACKET3_CLEAR_STATE: - case PACKET3_DISPATCH_DIRECT: - case PACKET3_DISPATCH_INDIRECT: - case PACKET3_ALLOC_GDS: - case PACKET3_WRITE_GDS_RAM: - case PACKET3_ATOMIC_GDS: - case PACKET3_ATOMIC: - case PACKET3_OCCLUSION_QUERY: - case PACKET3_SET_PREDICATION: - case PACKET3_COND_EXEC: - case PACKET3_PRED_EXEC: - case PACKET3_CONTEXT_CONTROL: - case PACKET3_STRMOUT_BUFFER_UPDATE: - case PACKET3_WAIT_REG_MEM: - case PACKET3_MEM_WRITE: - case PACKET3_PFP_SYNC_ME: - case PACKET3_SURFACE_SYNC: - case PACKET3_EVENT_WRITE: - case PACKET3_EVENT_WRITE_EOP: - case PACKET3_EVENT_WRITE_EOS: - case PACKET3_SET_CONTEXT_REG: - case PACKET3_SET_CONTEXT_REG_INDIRECT: - case PACKET3_SET_SH_REG: - case PACKET3_SET_SH_REG_OFFSET: - case PACKET3_INCREMENT_DE_COUNTER: - case PACKET3_WAIT_ON_CE_COUNTER: - case PACKET3_WAIT_ON_AVAIL_BUFFER: - case PACKET3_ME_WRITE: - break; - case PACKET3_COPY_DATA: - if ((idx_value & 0xf00) == 0) { - reg = ib[idx + 3] * 4; - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_WRITE_DATA: - if ((idx_value & 0xf00) == 0) { - start_reg = ib[idx + 1] * 4; - if (idx_value & 0x10000) { - if (!si_vm_reg_valid(start_reg)) - return -EINVAL; - } else { - for (i = 0; i < (pkt->count - 2); i++) { - reg = start_reg + (4 * i); - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - } - } - break; - case PACKET3_COND_WRITE: - if (idx_value & 0x100) { - reg = ib[idx + 5] * 4; - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - case PACKET3_COPY_DW: - if (idx_value & 0x2) { - reg = ib[idx + 3] * 4; - if (!si_vm_reg_valid(reg)) - return -EINVAL; - } - break; - default: - DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode); - return -EINVAL; - } - return 0; -} - -int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) -{ - int ret = 0; - u32 idx = 0; - struct radeon_cs_packet pkt; - - do { - pkt.idx = idx; - pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]); - pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]); - pkt.one_reg_wr = 0; - switch (pkt.type) { - case PACKET_TYPE0: - dev_err(rdev->dev, "Packet0 not allowed!\n"); - ret = -EINVAL; - break; - case PACKET_TYPE2: - idx += 1; - break; - case PACKET_TYPE3: - pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); - if (ib->is_const_ib) - ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt); - else { - switch (ib->fence->ring) { - case RADEON_RING_TYPE_GFX_INDEX: - ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt); - break; - case CAYMAN_RING_TYPE_CP1_INDEX: - case CAYMAN_RING_TYPE_CP2_INDEX: - ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt); - break; - default: - dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->fence->ring); - ret = -EINVAL; - break; - } - } - idx += pkt.count + 2; - break; - default: - dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type); - ret = -EINVAL; - break; - } - if (ret) - break; - } while (idx < ib->length_dw); - - return ret; -} - -/* - * vm - */ -int si_vm_init(struct radeon_device *rdev) -{ - /* number of VMs */ - rdev->vm_manager.nvm = 16; - /* base offset of vram pages */ - rdev->vm_manager.vram_base_offset = 0; - - return 0; -} - -void si_vm_fini(struct radeon_device *rdev) -{ -} - -int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id) -{ - if (id < 8) - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12); - else - WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((id - 8) << 2), - vm->pt_gpu_addr >> 12); - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - /* bits 0-15 are the VM contexts0-15 */ - WREG32(VM_INVALIDATE_REQUEST, 1 << id); - return 0; -} - -void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) -{ - if (vm->id < 8) - WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0); - else - WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2), 0); - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - /* bits 0-15 are the VM contexts0-15 */ - WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); -} - -void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm) -{ - if (vm->id == -1) - return; - - /* flush hdp cache */ - WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); - /* bits 0-15 are the VM contexts0-15 */ - WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); -} - -/* - * RLC - */ -void si_rlc_fini(struct radeon_device *rdev) -{ - int r; - - /* save restore block */ - if (rdev->rlc.save_restore_obj) { - r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false); - if (unlikely(r != 0)) - dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r); - radeon_bo_unpin(rdev->rlc.save_restore_obj); - radeon_bo_unreserve(rdev->rlc.save_restore_obj); - - radeon_bo_unref(&rdev->rlc.save_restore_obj); - rdev->rlc.save_restore_obj = NULL; - } - - /* clear state block */ - if (rdev->rlc.clear_state_obj) { - r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false); - if (unlikely(r != 0)) - dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r); - radeon_bo_unpin(rdev->rlc.clear_state_obj); - radeon_bo_unreserve(rdev->rlc.clear_state_obj); - - radeon_bo_unref(&rdev->rlc.clear_state_obj); - rdev->rlc.clear_state_obj = NULL; - } -} - -int si_rlc_init(struct radeon_device *rdev) -{ - int r; - - /* save restore block */ - if (rdev->rlc.save_restore_obj == NULL) { - r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_obj); - if (r) { - dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r); - return r; - } - } - - r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false); - if (unlikely(r != 0)) { - si_rlc_fini(rdev); - return r; - } - r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, - &rdev->rlc.save_restore_gpu_addr); - radeon_bo_unreserve(rdev->rlc.save_restore_obj); - if (r) { - dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); - si_rlc_fini(rdev); - return r; - } - - /* clear state block */ - if (rdev->rlc.clear_state_obj == NULL) { - r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, - RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_obj); - if (r) { - dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r); - si_rlc_fini(rdev); - return r; - } - } - r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false); - if (unlikely(r != 0)) { - si_rlc_fini(rdev); - return r; - } - r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, - &rdev->rlc.clear_state_gpu_addr); - radeon_bo_unreserve(rdev->rlc.clear_state_obj); - if (r) { - dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); - si_rlc_fini(rdev); - return r; - } - - return 0; -} - -static void si_rlc_stop(struct radeon_device *rdev) -{ - WREG32(RLC_CNTL, 0); -} - -static void si_rlc_start(struct radeon_device *rdev) -{ - WREG32(RLC_CNTL, RLC_ENABLE); -} - -static int si_rlc_resume(struct radeon_device *rdev) -{ - u32 i; - const __be32 *fw_data; - - if (!rdev->rlc_fw) - return -EINVAL; - - si_rlc_stop(rdev); - - WREG32(RLC_RL_BASE, 0); - WREG32(RLC_RL_SIZE, 0); - WREG32(RLC_LB_CNTL, 0); - WREG32(RLC_LB_CNTR_MAX, 0xffffffff); - WREG32(RLC_LB_CNTR_INIT, 0); - - WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); - WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); - - WREG32(RLC_MC_CNTL, 0); - WREG32(RLC_UCODE_CNTL, 0); - - fw_data = (const __be32 *)rdev->rlc_fw->data; - for (i = 0; i < SI_RLC_UCODE_SIZE; i++) { - WREG32(RLC_UCODE_ADDR, i); - WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); - } - WREG32(RLC_UCODE_ADDR, 0); - - si_rlc_start(rdev); - - return 0; -} - -static void si_enable_interrupts(struct radeon_device *rdev) -{ - u32 ih_cntl = RREG32(IH_CNTL); - u32 ih_rb_cntl = RREG32(IH_RB_CNTL); - - ih_cntl |= ENABLE_INTR; - ih_rb_cntl |= IH_RB_ENABLE; - WREG32(IH_CNTL, ih_cntl); - WREG32(IH_RB_CNTL, ih_rb_cntl); - rdev->ih.enabled = true; -} - -static void si_disable_interrupts(struct radeon_device *rdev) -{ - u32 ih_rb_cntl = RREG32(IH_RB_CNTL); - u32 ih_cntl = RREG32(IH_CNTL); - - ih_rb_cntl &= ~IH_RB_ENABLE; - ih_cntl &= ~ENABLE_INTR; - WREG32(IH_RB_CNTL, ih_rb_cntl); - WREG32(IH_CNTL, ih_cntl); - /* set rptr, wptr to 0 */ - WREG32(IH_RB_RPTR, 0); - WREG32(IH_RB_WPTR, 0); - rdev->ih.enabled = false; - rdev->ih.wptr = 0; - rdev->ih.rptr = 0; -} - -static void si_disable_interrupt_state(struct radeon_device *rdev) -{ - u32 tmp; - - WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); - WREG32(CP_INT_CNTL_RING1, 0); - WREG32(CP_INT_CNTL_RING2, 0); - WREG32(GRBM_INT_CNTL, 0); - WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - if (rdev->num_crtc >= 4) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - } - if (rdev->num_crtc >= 6) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); - } - - WREG32(DACA_AUTODETECT_INT_CONTROL, 0); - - tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD1_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD2_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD3_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD4_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, tmp); - -} - -static int si_irq_init(struct radeon_device *rdev) -{ - int ret = 0; - int rb_bufsz; - u32 interrupt_cntl, ih_cntl, ih_rb_cntl; - - /* allocate ring */ - ret = r600_ih_ring_alloc(rdev); - if (ret) - return ret; - - /* disable irqs */ - si_disable_interrupts(rdev); - - /* init rlc */ - ret = si_rlc_resume(rdev); - if (ret) { - r600_ih_ring_fini(rdev); - return ret; - } - - /* setup interrupt control */ - /* set dummy read address to ring address */ - WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); - interrupt_cntl = RREG32(INTERRUPT_CNTL); - /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi - * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN - */ - interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; - /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ - interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; - WREG32(INTERRUPT_CNTL, interrupt_cntl); - - WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); - rb_bufsz = drm_order(rdev->ih.ring_size / 4); - - ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | - IH_WPTR_OVERFLOW_CLEAR | - (rb_bufsz << 1)); - - if (rdev->wb.enabled) - ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; - - /* set the writeback address whether it's enabled or not */ - WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); - WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); - - WREG32(IH_RB_CNTL, ih_rb_cntl); - - /* set rptr, wptr to 0 */ - WREG32(IH_RB_RPTR, 0); - WREG32(IH_RB_WPTR, 0); - - /* Default settings for IH_CNTL (disabled at first) */ - ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0); - /* RPTR_REARM only works if msi's are enabled */ - if (rdev->msi_enabled) - ih_cntl |= RPTR_REARM; - WREG32(IH_CNTL, ih_cntl); - - /* force the active interrupt state to all disabled */ - si_disable_interrupt_state(rdev); - - /* enable irqs */ - si_enable_interrupts(rdev); - - return ret; -} - -int si_irq_set(struct radeon_device *rdev) -{ - u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; - u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; - u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; - u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; - u32 grbm_int_cntl = 0; - u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; - - if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); - return -EINVAL; - } - /* don't enable anything if the ih is disabled */ - if (!rdev->ih.enabled) { - si_disable_interrupts(rdev); - /* force the active interrupt state to all disabled */ - si_disable_interrupt_state(rdev); - return 0; - } - - hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; - - /* enable CP interrupts on all rings */ - if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { - DRM_DEBUG("si_irq_set: sw int gfx\n"); - cp_int_cntl |= TIME_STAMP_INT_ENABLE; - } - if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) { - DRM_DEBUG("si_irq_set: sw int cp1\n"); - cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; - } - if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) { - DRM_DEBUG("si_irq_set: sw int cp2\n"); - cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; - } - if (rdev->irq.crtc_vblank_int[0] || - rdev->irq.pflip[0]) { - DRM_DEBUG("si_irq_set: vblank 0\n"); - crtc1 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[1] || - rdev->irq.pflip[1]) { - DRM_DEBUG("si_irq_set: vblank 1\n"); - crtc2 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[2] || - rdev->irq.pflip[2]) { - DRM_DEBUG("si_irq_set: vblank 2\n"); - crtc3 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[3] || - rdev->irq.pflip[3]) { - DRM_DEBUG("si_irq_set: vblank 3\n"); - crtc4 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[4] || - rdev->irq.pflip[4]) { - DRM_DEBUG("si_irq_set: vblank 4\n"); - crtc5 |= VBLANK_INT_MASK; - } - if (rdev->irq.crtc_vblank_int[5] || - rdev->irq.pflip[5]) { - DRM_DEBUG("si_irq_set: vblank 5\n"); - crtc6 |= VBLANK_INT_MASK; - } - if (rdev->irq.hpd[0]) { - DRM_DEBUG("si_irq_set: hpd 1\n"); - hpd1 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[1]) { - DRM_DEBUG("si_irq_set: hpd 2\n"); - hpd2 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[2]) { - DRM_DEBUG("si_irq_set: hpd 3\n"); - hpd3 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[3]) { - DRM_DEBUG("si_irq_set: hpd 4\n"); - hpd4 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[4]) { - DRM_DEBUG("si_irq_set: hpd 5\n"); - hpd5 |= DC_HPDx_INT_EN; - } - if (rdev->irq.hpd[5]) { - DRM_DEBUG("si_irq_set: hpd 6\n"); - hpd6 |= DC_HPDx_INT_EN; - } - if (rdev->irq.gui_idle) { - DRM_DEBUG("gui idle\n"); - grbm_int_cntl |= GUI_IDLE_INT_ENABLE; - } - - WREG32(CP_INT_CNTL_RING0, cp_int_cntl); - WREG32(CP_INT_CNTL_RING1, cp_int_cntl1); - WREG32(CP_INT_CNTL_RING2, cp_int_cntl2); - - WREG32(GRBM_INT_CNTL, grbm_int_cntl); - - WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); - WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); - if (rdev->num_crtc >= 4) { - WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); - WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); - } - if (rdev->num_crtc >= 6) { - WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); - WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); - } - - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); - if (rdev->num_crtc >= 4) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); - } - if (rdev->num_crtc >= 6) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); - } - - WREG32(DC_HPD1_INT_CONTROL, hpd1); - WREG32(DC_HPD2_INT_CONTROL, hpd2); - WREG32(DC_HPD3_INT_CONTROL, hpd3); - WREG32(DC_HPD4_INT_CONTROL, hpd4); - WREG32(DC_HPD5_INT_CONTROL, hpd5); - WREG32(DC_HPD6_INT_CONTROL, hpd6); - - return 0; -} - -static inline void si_irq_ack(struct radeon_device *rdev) -{ - u32 tmp; - - rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); - rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); - rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); - rdev->irq.stat_regs.evergreen.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); - rdev->irq.stat_regs.evergreen.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); - rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); - rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); - rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); - if (rdev->num_crtc >= 4) { - rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); - rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); - } - if (rdev->num_crtc >= 6) { - rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); - rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); - } - - if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); - - if (rdev->num_crtc >= 4) { - if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); - } - - if (rdev->num_crtc >= 6) { - if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) - WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) - WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) - WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); - } - - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { - tmp = RREG32(DC_HPD1_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD1_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { - tmp = RREG32(DC_HPD2_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD2_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { - tmp = RREG32(DC_HPD3_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD3_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { - tmp = RREG32(DC_HPD4_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD4_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { - tmp = RREG32(DC_HPD5_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD5_INT_CONTROL, tmp); - } - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { - tmp = RREG32(DC_HPD5_INT_CONTROL); - tmp |= DC_HPDx_INT_ACK; - WREG32(DC_HPD6_INT_CONTROL, tmp); - } -} - -static void si_irq_disable(struct radeon_device *rdev) -{ - si_disable_interrupts(rdev); - /* Wait and acknowledge irq */ - mdelay(1); - si_irq_ack(rdev); - si_disable_interrupt_state(rdev); -} - -static void si_irq_suspend(struct radeon_device *rdev) -{ - si_irq_disable(rdev); - si_rlc_stop(rdev); -} - -static void si_irq_fini(struct radeon_device *rdev) -{ - si_irq_suspend(rdev); - r600_ih_ring_fini(rdev); -} - -static inline u32 si_get_ih_wptr(struct radeon_device *rdev) -{ - u32 wptr, tmp; - - if (rdev->wb.enabled) - wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); - else - wptr = RREG32(IH_RB_WPTR); - - if (wptr & RB_OVERFLOW) { - /* When a ring buffer overflow happen start parsing interrupt - * from the last not overwritten vector (wptr + 16). Hopefully - * this should allow us to catchup. - */ - dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", - wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); - rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; - tmp = RREG32(IH_RB_CNTL); - tmp |= IH_WPTR_OVERFLOW_CLEAR; - WREG32(IH_RB_CNTL, tmp); - } - return (wptr & rdev->ih.ptr_mask); -} - -/* SI IV Ring - * Each IV ring entry is 128 bits: - * [7:0] - interrupt source id - * [31:8] - reserved - * [59:32] - interrupt source data - * [63:60] - reserved - * [71:64] - RINGID - * [79:72] - VMID - * [127:80] - reserved - */ -int si_irq_process(struct radeon_device *rdev) -{ - u32 wptr; - u32 rptr; - u32 src_id, src_data, ring_id; - u32 ring_index; - unsigned long flags; - bool queue_hotplug = false; - - if (!rdev->ih.enabled || rdev->shutdown) - return IRQ_NONE; - - wptr = si_get_ih_wptr(rdev); - rptr = rdev->ih.rptr; - DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - - spin_lock_irqsave(&rdev->ih.lock, flags); - if (rptr == wptr) { - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_NONE; - } -restart_ih: - /* Order reading of wptr vs. reading of IH ring data */ - rmb(); - - /* display interrupts */ - si_irq_ack(rdev); - - rdev->ih.wptr = wptr; - while (rptr != wptr) { - /* wptr/rptr are in bytes! */ - ring_index = rptr / 4; - src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; - src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; - ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff; - - switch (src_id) { - case 1: /* D1 vblank/vline */ - switch (src_data) { - case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); - } - break; - case 1: /* D1 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 2: /* D2 vblank/vline */ - switch (src_data) { - case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); - } - break; - case 1: /* D2 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 3: /* D3 vblank/vline */ - switch (src_data) { - case 0: /* D3 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[2]) { - drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[2]) - radeon_crtc_handle_flip(rdev, 2); - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D3 vblank\n"); - } - break; - case 1: /* D3 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; - DRM_DEBUG("IH: D3 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 4: /* D4 vblank/vline */ - switch (src_data) { - case 0: /* D4 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[3]) { - drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[3]) - radeon_crtc_handle_flip(rdev, 3); - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D4 vblank\n"); - } - break; - case 1: /* D4 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; - DRM_DEBUG("IH: D4 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 5: /* D5 vblank/vline */ - switch (src_data) { - case 0: /* D5 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[4]) { - drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[4]) - radeon_crtc_handle_flip(rdev, 4); - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D5 vblank\n"); - } - break; - case 1: /* D5 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; - DRM_DEBUG("IH: D5 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 6: /* D6 vblank/vline */ - switch (src_data) { - case 0: /* D6 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[5]) { - drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (rdev->irq.pflip[5]) - radeon_crtc_handle_flip(rdev, 5); - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D6 vblank\n"); - } - break; - case 1: /* D6 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; - DRM_DEBUG("IH: D6 vline\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 42: /* HPD hotplug */ - switch (src_data) { - case 0: - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } - break; - case 1: - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } - break; - case 2: - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } - break; - case 3: - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } - break; - case 4: - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } - break; - case 5: - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - break; - case 176: /* RINGID0 CP_INT */ - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 177: /* RINGID1 CP_INT */ - radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); - break; - case 178: /* RINGID2 CP_INT */ - radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); - break; - case 181: /* CP EOP event */ - DRM_DEBUG("IH: CP EOP\n"); - switch (ring_id) { - case 0: - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); - break; - case 1: - radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); - break; - case 2: - radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); - break; - } - break; - case 233: /* GUI IDLE */ - DRM_DEBUG("IH: GUI idle\n"); - rdev->pm.gui_idle = true; - wake_up(&rdev->irq.idle_queue); - break; - default: - DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); - break; - } - - /* wptr/rptr are in bytes! */ - rptr += 16; - rptr &= rdev->ih.ptr_mask; - } - /* make sure wptr hasn't changed while processing */ - wptr = si_get_ih_wptr(rdev); - if (wptr != rdev->ih.wptr) - goto restart_ih; - if (queue_hotplug) - schedule_work(&rdev->hotplug_work); - rdev->ih.rptr = rptr; - WREG32(IH_RB_RPTR, rdev->ih.rptr); - spin_unlock_irqrestore(&rdev->ih.lock, flags); - return IRQ_HANDLED; -} - -/* - * startup/shutdown callbacks - */ -static int si_startup(struct radeon_device *rdev) -{ - struct radeon_ring *ring; - int r; - - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || - !rdev->rlc_fw || !rdev->mc_fw) { - r = si_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - - r = si_mc_load_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load MC firmware!\n"); - return r; - } - - r = r600_vram_scratch_init(rdev); - if (r) - return r; - - si_mc_program(rdev); - r = si_pcie_gart_enable(rdev); - if (r) - return r; - si_gpu_init(rdev); - -#if 0 - r = evergreen_blit_init(rdev); - if (r) { - r600_blit_fini(rdev); - rdev->asic->copy = NULL; - dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); - } -#endif - /* allocate rlc buffers */ - r = si_rlc_init(rdev); - if (r) { - DRM_ERROR("Failed to init rlc BOs!\n"); - return r; - } - - /* allocate wb buffer */ - r = radeon_wb_init(rdev); - if (r) - return r; - - r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX); - if (r) { - dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); - return r; - } - - /* Enable IRQ */ - r = si_irq_init(rdev); - if (r) { - DRM_ERROR("radeon: IH init failed (%d).\n", r); - radeon_irq_kms_fini(rdev); - return r; - } - si_irq_set(rdev); - - ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - CP_RB0_RPTR, CP_RB0_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (r) - return r; - - ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, - CP_RB1_RPTR, CP_RB1_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (r) - return r; - - ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, - CP_RB2_RPTR, CP_RB2_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (r) - return r; - - r = si_cp_load_microcode(rdev); - if (r) - return r; - r = si_cp_resume(rdev); - if (r) - return r; - - r = radeon_ib_pool_start(rdev); - if (r) - return r; - - r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d) on CP ring 0\n", r); - rdev->accel_working = false; - return r; - } - - r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d) on CP ring 1\n", r); - rdev->accel_working = false; - return r; - } - - r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d) on CP ring 2\n", r); - rdev->accel_working = false; - return r; - } - - r = radeon_vm_manager_start(rdev); - if (r) - return r; - - return 0; -} - -int si_resume(struct radeon_device *rdev) -{ - int r; - - /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, - * posting will perform necessary task to bring back GPU into good - * shape. - */ - /* post card */ - atom_asic_init(rdev->mode_info.atom_context); - - rdev->accel_working = true; - r = si_startup(rdev); - if (r) { - DRM_ERROR("si startup failed on resume\n"); - rdev->accel_working = false; - return r; - } - - return r; - -} - -int si_suspend(struct radeon_device *rdev) -{ - /* FIXME: we should wait for ring to be empty */ - radeon_ib_pool_suspend(rdev); - radeon_vm_manager_suspend(rdev); -#if 0 - r600_blit_suspend(rdev); -#endif - si_cp_enable(rdev, false); - rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; - si_irq_suspend(rdev); - radeon_wb_disable(rdev); - si_pcie_gart_disable(rdev); - return 0; -} - -/* Plan is to move initialization in that function and use - * helper function so that radeon_device_init pretty much - * do nothing more than calling asic specific function. This - * should also allow to remove a bunch of callback function - * like vram_info. - */ -int si_init(struct radeon_device *rdev) -{ - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - int r; - - /* This don't do much */ - r = radeon_gem_init(rdev); - if (r) - return r; - /* Read BIOS */ - if (!radeon_get_bios(rdev)) { - if (ASIC_IS_AVIVO(rdev)) - return -EINVAL; - } - /* Must be an ATOMBIOS */ - if (!rdev->is_atom_bios) { - dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); - return -EINVAL; - } - r = radeon_atombios_init(rdev); - if (r) - return r; - - /* Post card if necessary */ - if (!radeon_card_posted(rdev)) { - if (!rdev->bios) { - dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); - return -EINVAL; - } - DRM_INFO("GPU not posted. posting now...\n"); - atom_asic_init(rdev->mode_info.atom_context); - } - /* Initialize scratch registers */ - si_scratch_init(rdev); - /* Initialize surface registers */ - radeon_surface_init(rdev); - /* Initialize clocks */ - radeon_get_clock_info(rdev->ddev); - - /* Fence driver */ - r = radeon_fence_driver_init(rdev); - if (r) - return r; - - /* initialize memory controller */ - r = si_mc_init(rdev); - if (r) - return r; - /* Memory manager */ - r = radeon_bo_init(rdev); - if (r) - return r; - - r = radeon_irq_kms_init(rdev); - if (r) - return r; - - ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 1024 * 1024); - - ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 1024 * 1024); - - ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 1024 * 1024); - - rdev->ih.ring_obj = NULL; - r600_ih_ring_init(rdev, 64 * 1024); - - r = r600_pcie_gart_init(rdev); - if (r) - return r; - - r = radeon_ib_pool_init(rdev); - rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - r = radeon_vm_manager_init(rdev); - if (r) { - dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); - } - - r = si_startup(rdev); - if (r) { - dev_err(rdev->dev, "disabling GPU acceleration\n"); - si_cp_fini(rdev); - si_irq_fini(rdev); - si_rlc_fini(rdev); - radeon_wb_fini(rdev); - r100_ib_fini(rdev); - radeon_vm_manager_fini(rdev); - radeon_irq_kms_fini(rdev); - si_pcie_gart_fini(rdev); - rdev->accel_working = false; - } - - /* Don't start up if the MC ucode is missing. - * The default clocks and voltages before the MC ucode - * is loaded are not suffient for advanced operations. - */ - if (!rdev->mc_fw) { - DRM_ERROR("radeon: MC ucode required for NI+.\n"); - return -EINVAL; - } - - return 0; -} - -void si_fini(struct radeon_device *rdev) -{ -#if 0 - r600_blit_fini(rdev); -#endif - si_cp_fini(rdev); - si_irq_fini(rdev); - si_rlc_fini(rdev); - radeon_wb_fini(rdev); - radeon_vm_manager_fini(rdev); - r100_ib_fini(rdev); - radeon_irq_kms_fini(rdev); - si_pcie_gart_fini(rdev); - r600_vram_scratch_fini(rdev); - radeon_gem_fini(rdev); - radeon_semaphore_driver_fini(rdev); - radeon_fence_driver_fini(rdev); - radeon_bo_fini(rdev); - radeon_atombios_fini(rdev); - kfree(rdev->bios); - rdev->bios = NULL; -} - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.c b/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.c deleted file mode 100644 index ec415e7d..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2011 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Alex Deucher - */ - -#include -#include -#include - -const u32 si_default_state[] = -{ - 0xc0066900, - 0x00000000, - 0x00000060, /* DB_RENDER_CONTROL */ - 0x00000000, /* DB_COUNT_CONTROL */ - 0x00000000, /* DB_DEPTH_VIEW */ - 0x0000002a, /* DB_RENDER_OVERRIDE */ - 0x00000000, /* DB_RENDER_OVERRIDE2 */ - 0x00000000, /* DB_HTILE_DATA_BASE */ - - 0xc0046900, - 0x00000008, - 0x00000000, /* DB_DEPTH_BOUNDS_MIN */ - 0x00000000, /* DB_DEPTH_BOUNDS_MAX */ - 0x00000000, /* DB_STENCIL_CLEAR */ - 0x00000000, /* DB_DEPTH_CLEAR */ - - 0xc0036900, - 0x0000000f, - 0x00000000, /* DB_DEPTH_INFO */ - 0x00000000, /* DB_Z_INFO */ - 0x00000000, /* DB_STENCIL_INFO */ - - 0xc0016900, - 0x00000080, - 0x00000000, /* PA_SC_WINDOW_OFFSET */ - - 0xc00d6900, - 0x00000083, - 0x0000ffff, /* PA_SC_CLIPRECT_RULE */ - 0x00000000, /* PA_SC_CLIPRECT_0_TL */ - 0x20002000, /* PA_SC_CLIPRECT_0_BR */ - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0x00000000, - 0x20002000, - 0xaaaaaaaa, /* PA_SC_EDGERULE */ - 0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */ - 0x0000000f, /* CB_TARGET_MASK */ - 0x0000000f, /* CB_SHADER_MASK */ - - 0xc0226900, - 0x00000094, - 0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */ - 0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */ - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x80000000, - 0x20002000, - 0x00000000, /* PA_SC_VPORT_ZMIN_0 */ - 0x3f800000, /* PA_SC_VPORT_ZMAX_0 */ - - 0xc0026900, - 0x000000d9, - 0x00000000, /* CP_RINGID */ - 0x00000000, /* CP_VMID */ - - 0xc0046900, - 0x00000100, - 0xffffffff, /* VGT_MAX_VTX_INDX */ - 0x00000000, /* VGT_MIN_VTX_INDX */ - 0x00000000, /* VGT_INDX_OFFSET */ - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */ - - 0xc0046900, - 0x00000105, - 0x00000000, /* CB_BLEND_RED */ - 0x00000000, /* CB_BLEND_GREEN */ - 0x00000000, /* CB_BLEND_BLUE */ - 0x00000000, /* CB_BLEND_ALPHA */ - - 0xc0016900, - 0x000001e0, - 0x00000000, /* CB_BLEND0_CONTROL */ - - 0xc00e6900, - 0x00000200, - 0x00000000, /* DB_DEPTH_CONTROL */ - 0x00000000, /* DB_EQAA */ - 0x00cc0010, /* CB_COLOR_CONTROL */ - 0x00000210, /* DB_SHADER_CONTROL */ - 0x00010000, /* PA_CL_CLIP_CNTL */ - 0x00000004, /* PA_SU_SC_MODE_CNTL */ - 0x00000100, /* PA_CL_VTE_CNTL */ - 0x00000000, /* PA_CL_VS_OUT_CNTL */ - 0x00000000, /* PA_CL_NANINF_CNTL */ - 0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */ - 0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */ - 0x00000000, /* PA_SU_PRIM_FILTER_CNTL */ - 0x00000000, /* */ - 0x00000000, /* */ - - 0xc0116900, - 0x00000280, - 0x00000000, /* PA_SU_POINT_SIZE */ - 0x00000000, /* PA_SU_POINT_MINMAX */ - 0x00000008, /* PA_SU_LINE_CNTL */ - 0x00000000, /* PA_SC_LINE_STIPPLE */ - 0x00000000, /* VGT_OUTPUT_PATH_CNTL */ - 0x00000000, /* VGT_HOS_CNTL */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, /* VGT_GS_MODE */ - - 0xc0026900, - 0x00000292, - 0x00000000, /* PA_SC_MODE_CNTL_0 */ - 0x00000000, /* PA_SC_MODE_CNTL_1 */ - - 0xc0016900, - 0x000002a1, - 0x00000000, /* VGT_PRIMITIVEID_EN */ - - 0xc0016900, - 0x000002a5, - 0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */ - - 0xc0026900, - 0x000002a8, - 0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */ - 0x00000000, - - 0xc0026900, - 0x000002ad, - 0x00000000, /* VGT_REUSE_OFF */ - 0x00000000, - - 0xc0016900, - 0x000002d5, - 0x00000000, /* VGT_SHADER_STAGES_EN */ - - 0xc0016900, - 0x000002dc, - 0x0000aa00, /* DB_ALPHA_TO_MASK */ - - 0xc0066900, - 0x000002de, - 0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - - 0xc0026900, - 0x000002e5, - 0x00000000, /* VGT_STRMOUT_CONFIG */ - 0x00000000, - - 0xc01b6900, - 0x000002f5, - 0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */ - 0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */ - 0x00000000, /* PA_SC_LINE_CNTL */ - 0x00000000, /* PA_SC_AA_CONFIG */ - 0x00000005, /* PA_SU_VTX_CNTL */ - 0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */ - 0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */ - 0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */ - 0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */ - 0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */ - 0xffffffff, - - 0xc0026900, - 0x00000316, - 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - 0x00000010, /* */ -}; - -const u32 si_default_size = ARRAY_SIZE(si_default_state); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.h deleted file mode 100644 index c739e51e..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_blit_shaders.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef SI_BLIT_SHADERS_H -#define SI_BLIT_SHADERS_H - -extern const u32 si_default_state[]; - -extern const u32 si_default_size; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_reg.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_reg.h deleted file mode 100644 index eda938a7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/si_reg.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2010 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#ifndef __SI_REG_H__ -#define __SI_REG_H__ - -/* SI */ -#define SI_DC_GPIO_HPD_MASK 0x65b0 -#define SI_DC_GPIO_HPD_A 0x65b4 -#define SI_DC_GPIO_HPD_EN 0x65b8 -#define SI_DC_GPIO_HPD_Y 0x65bc - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/radeon/sid.h b/ANDROID_3.4.5/drivers/gpu/drm/radeon/sid.h deleted file mode 100644 index 53ea2c42..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/radeon/sid.h +++ /dev/null @@ -1,886 +0,0 @@ -/* - * Copyright 2011 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Alex Deucher - */ -#ifndef SI_H -#define SI_H - -#define CG_MULT_THERMAL_STATUS 0x714 -#define ASIC_MAX_TEMP(x) ((x) << 0) -#define ASIC_MAX_TEMP_MASK 0x000001ff -#define ASIC_MAX_TEMP_SHIFT 0 -#define CTF_TEMP(x) ((x) << 9) -#define CTF_TEMP_MASK 0x0003fe00 -#define CTF_TEMP_SHIFT 9 - -#define SI_MAX_SH_GPRS 256 -#define SI_MAX_TEMP_GPRS 16 -#define SI_MAX_SH_THREADS 256 -#define SI_MAX_SH_STACK_ENTRIES 4096 -#define SI_MAX_FRC_EOV_CNT 16384 -#define SI_MAX_BACKENDS 8 -#define SI_MAX_BACKENDS_MASK 0xFF -#define SI_MAX_BACKENDS_PER_SE_MASK 0x0F -#define SI_MAX_SIMDS 12 -#define SI_MAX_SIMDS_MASK 0x0FFF -#define SI_MAX_SIMDS_PER_SE_MASK 0x00FF -#define SI_MAX_PIPES 8 -#define SI_MAX_PIPES_MASK 0xFF -#define SI_MAX_PIPES_PER_SIMD_MASK 0x3F -#define SI_MAX_LDS_NUM 0xFFFF -#define SI_MAX_TCC 16 -#define SI_MAX_TCC_MASK 0xFFFF - -#define VGA_HDP_CONTROL 0x328 -#define VGA_MEMORY_DISABLE (1 << 4) - -#define DMIF_ADDR_CONFIG 0xBD4 - -#define SRBM_STATUS 0xE50 - -#define CC_SYS_RB_BACKEND_DISABLE 0xe80 -#define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 - -#define VM_L2_CNTL 0x1400 -#define ENABLE_L2_CACHE (1 << 0) -#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -#define L2_CACHE_PTE_ENDIAN_SWAP_MODE(x) ((x) << 2) -#define L2_CACHE_PDE_ENDIAN_SWAP_MODE(x) ((x) << 4) -#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -#define ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE (1 << 10) -#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 15) -#define CONTEXT1_IDENTITY_ACCESS_MODE(x) (((x) & 3) << 19) -#define VM_L2_CNTL2 0x1404 -#define INVALIDATE_ALL_L1_TLBS (1 << 0) -#define INVALIDATE_L2_CACHE (1 << 1) -#define INVALIDATE_CACHE_MODE(x) ((x) << 26) -#define INVALIDATE_PTE_AND_PDE_CACHES 0 -#define INVALIDATE_ONLY_PTE_CACHES 1 -#define INVALIDATE_ONLY_PDE_CACHES 2 -#define VM_L2_CNTL3 0x1408 -#define BANK_SELECT(x) ((x) << 0) -#define L2_CACHE_UPDATE_MODE(x) ((x) << 6) -#define L2_CACHE_BIGK_FRAGMENT_SIZE(x) ((x) << 15) -#define L2_CACHE_BIGK_ASSOCIATIVITY (1 << 20) -#define VM_L2_STATUS 0x140C -#define L2_BUSY (1 << 0) -#define VM_CONTEXT0_CNTL 0x1410 -#define ENABLE_CONTEXT (1 << 0) -#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -#define VM_CONTEXT1_CNTL 0x1414 -#define VM_CONTEXT0_CNTL2 0x1430 -#define VM_CONTEXT1_CNTL2 0x1434 -#define VM_CONTEXT8_PAGE_TABLE_BASE_ADDR 0x1438 -#define VM_CONTEXT9_PAGE_TABLE_BASE_ADDR 0x143c -#define VM_CONTEXT10_PAGE_TABLE_BASE_ADDR 0x1440 -#define VM_CONTEXT11_PAGE_TABLE_BASE_ADDR 0x1444 -#define VM_CONTEXT12_PAGE_TABLE_BASE_ADDR 0x1448 -#define VM_CONTEXT13_PAGE_TABLE_BASE_ADDR 0x144c -#define VM_CONTEXT14_PAGE_TABLE_BASE_ADDR 0x1450 -#define VM_CONTEXT15_PAGE_TABLE_BASE_ADDR 0x1454 - -#define VM_INVALIDATE_REQUEST 0x1478 -#define VM_INVALIDATE_RESPONSE 0x147c - -#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 -#define VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR 0x151c - -#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c -#define VM_CONTEXT1_PAGE_TABLE_BASE_ADDR 0x1540 -#define VM_CONTEXT2_PAGE_TABLE_BASE_ADDR 0x1544 -#define VM_CONTEXT3_PAGE_TABLE_BASE_ADDR 0x1548 -#define VM_CONTEXT4_PAGE_TABLE_BASE_ADDR 0x154c -#define VM_CONTEXT5_PAGE_TABLE_BASE_ADDR 0x1550 -#define VM_CONTEXT6_PAGE_TABLE_BASE_ADDR 0x1554 -#define VM_CONTEXT7_PAGE_TABLE_BASE_ADDR 0x1558 -#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c -#define VM_CONTEXT1_PAGE_TABLE_START_ADDR 0x1560 - -#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C -#define VM_CONTEXT1_PAGE_TABLE_END_ADDR 0x1580 - -#define MC_SHARED_CHMAP 0x2004 -#define NOOFCHAN_SHIFT 12 -#define NOOFCHAN_MASK 0x0000f000 -#define MC_SHARED_CHREMAP 0x2008 - -#define MC_VM_FB_LOCATION 0x2024 -#define MC_VM_AGP_TOP 0x2028 -#define MC_VM_AGP_BOT 0x202C -#define MC_VM_AGP_BASE 0x2030 -#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C - -#define MC_VM_MX_L1_TLB_CNTL 0x2064 -#define ENABLE_L1_TLB (1 << 0) -#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) -#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) -#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) -#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -#define ENABLE_ADVANCED_DRIVER_MODEL (1 << 6) - -#define MC_SHARED_BLACKOUT_CNTL 0x20ac - -#define MC_ARB_RAMCFG 0x2760 -#define NOOFBANK_SHIFT 0 -#define NOOFBANK_MASK 0x00000003 -#define NOOFRANK_SHIFT 2 -#define NOOFRANK_MASK 0x00000004 -#define NOOFROWS_SHIFT 3 -#define NOOFROWS_MASK 0x00000038 -#define NOOFCOLS_SHIFT 6 -#define NOOFCOLS_MASK 0x000000C0 -#define CHANSIZE_SHIFT 8 -#define CHANSIZE_MASK 0x00000100 -#define CHANSIZE_OVERRIDE (1 << 11) -#define NOOFGROUPS_SHIFT 12 -#define NOOFGROUPS_MASK 0x00001000 - -#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x2808 -#define TRAIN_DONE_D0 (1 << 30) -#define TRAIN_DONE_D1 (1 << 31) - -#define MC_SEQ_SUP_CNTL 0x28c8 -#define RUN_MASK (1 << 0) -#define MC_SEQ_SUP_PGM 0x28cc - -#define MC_IO_PAD_CNTL_D0 0x29d0 -#define MEM_FALL_OUT_CMD (1 << 8) - -#define MC_SEQ_IO_DEBUG_INDEX 0x2a44 -#define MC_SEQ_IO_DEBUG_DATA 0x2a48 - -#define HDP_HOST_PATH_CNTL 0x2C00 -#define HDP_NONSURFACE_BASE 0x2C04 -#define HDP_NONSURFACE_INFO 0x2C08 -#define HDP_NONSURFACE_SIZE 0x2C0C - -#define HDP_ADDR_CONFIG 0x2F48 -#define HDP_MISC_CNTL 0x2F4C -#define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) - -#define IH_RB_CNTL 0x3e00 -# define IH_RB_ENABLE (1 << 0) -# define IH_IB_SIZE(x) ((x) << 1) /* log2 */ -# define IH_RB_FULL_DRAIN_ENABLE (1 << 6) -# define IH_WPTR_WRITEBACK_ENABLE (1 << 8) -# define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */ -# define IH_WPTR_OVERFLOW_ENABLE (1 << 16) -# define IH_WPTR_OVERFLOW_CLEAR (1 << 31) -#define IH_RB_BASE 0x3e04 -#define IH_RB_RPTR 0x3e08 -#define IH_RB_WPTR 0x3e0c -# define RB_OVERFLOW (1 << 0) -# define WPTR_OFFSET_MASK 0x3fffc -#define IH_RB_WPTR_ADDR_HI 0x3e10 -#define IH_RB_WPTR_ADDR_LO 0x3e14 -#define IH_CNTL 0x3e18 -# define ENABLE_INTR (1 << 0) -# define IH_MC_SWAP(x) ((x) << 1) -# define IH_MC_SWAP_NONE 0 -# define IH_MC_SWAP_16BIT 1 -# define IH_MC_SWAP_32BIT 2 -# define IH_MC_SWAP_64BIT 3 -# define RPTR_REARM (1 << 4) -# define MC_WRREQ_CREDIT(x) ((x) << 15) -# define MC_WR_CLEAN_CNT(x) ((x) << 20) -# define MC_VMID(x) ((x) << 25) - -#define CONFIG_MEMSIZE 0x5428 - -#define INTERRUPT_CNTL 0x5468 -# define IH_DUMMY_RD_OVERRIDE (1 << 0) -# define IH_DUMMY_RD_EN (1 << 1) -# define IH_REQ_NONSNOOP_EN (1 << 3) -# define GEN_IH_INT_EN (1 << 8) -#define INTERRUPT_CNTL2 0x546c - -#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 - -#define BIF_FB_EN 0x5490 -#define FB_READ_EN (1 << 0) -#define FB_WRITE_EN (1 << 1) - -#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 - -#define DC_LB_MEMORY_SPLIT 0x6b0c -#define DC_LB_MEMORY_CONFIG(x) ((x) << 20) - -#define PRIORITY_A_CNT 0x6b18 -#define PRIORITY_MARK_MASK 0x7fff -#define PRIORITY_OFF (1 << 16) -#define PRIORITY_ALWAYS_ON (1 << 20) -#define PRIORITY_B_CNT 0x6b1c - -#define DPG_PIPE_ARBITRATION_CONTROL3 0x6cc8 -# define LATENCY_WATERMARK_MASK(x) ((x) << 16) -#define DPG_PIPE_LATENCY_CONTROL 0x6ccc -# define LATENCY_LOW_WATERMARK(x) ((x) << 0) -# define LATENCY_HIGH_WATERMARK(x) ((x) << 16) - -/* 0x6bb8, 0x77b8, 0x103b8, 0x10fb8, 0x11bb8, 0x127b8 */ -#define VLINE_STATUS 0x6bb8 -# define VLINE_OCCURRED (1 << 0) -# define VLINE_ACK (1 << 4) -# define VLINE_STAT (1 << 12) -# define VLINE_INTERRUPT (1 << 16) -# define VLINE_INTERRUPT_TYPE (1 << 17) -/* 0x6bbc, 0x77bc, 0x103bc, 0x10fbc, 0x11bbc, 0x127bc */ -#define VBLANK_STATUS 0x6bbc -# define VBLANK_OCCURRED (1 << 0) -# define VBLANK_ACK (1 << 4) -# define VBLANK_STAT (1 << 12) -# define VBLANK_INTERRUPT (1 << 16) -# define VBLANK_INTERRUPT_TYPE (1 << 17) - -/* 0x6b40, 0x7740, 0x10340, 0x10f40, 0x11b40, 0x12740 */ -#define INT_MASK 0x6b40 -# define VBLANK_INT_MASK (1 << 0) -# define VLINE_INT_MASK (1 << 4) - -#define DISP_INTERRUPT_STATUS 0x60f4 -# define LB_D1_VLINE_INTERRUPT (1 << 2) -# define LB_D1_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD1_INTERRUPT (1 << 17) -# define DC_HPD1_RX_INTERRUPT (1 << 18) -# define DACA_AUTODETECT_INTERRUPT (1 << 22) -# define DACB_AUTODETECT_INTERRUPT (1 << 23) -# define DC_I2C_SW_DONE_INTERRUPT (1 << 24) -# define DC_I2C_HW_DONE_INTERRUPT (1 << 25) -#define DISP_INTERRUPT_STATUS_CONTINUE 0x60f8 -# define LB_D2_VLINE_INTERRUPT (1 << 2) -# define LB_D2_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD2_INTERRUPT (1 << 17) -# define DC_HPD2_RX_INTERRUPT (1 << 18) -# define DISP_TIMER_INTERRUPT (1 << 24) -#define DISP_INTERRUPT_STATUS_CONTINUE2 0x60fc -# define LB_D3_VLINE_INTERRUPT (1 << 2) -# define LB_D3_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD3_INTERRUPT (1 << 17) -# define DC_HPD3_RX_INTERRUPT (1 << 18) -#define DISP_INTERRUPT_STATUS_CONTINUE3 0x6100 -# define LB_D4_VLINE_INTERRUPT (1 << 2) -# define LB_D4_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD4_INTERRUPT (1 << 17) -# define DC_HPD4_RX_INTERRUPT (1 << 18) -#define DISP_INTERRUPT_STATUS_CONTINUE4 0x614c -# define LB_D5_VLINE_INTERRUPT (1 << 2) -# define LB_D5_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD5_INTERRUPT (1 << 17) -# define DC_HPD5_RX_INTERRUPT (1 << 18) -#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150 -# define LB_D6_VLINE_INTERRUPT (1 << 2) -# define LB_D6_VBLANK_INTERRUPT (1 << 3) -# define DC_HPD6_INTERRUPT (1 << 17) -# define DC_HPD6_RX_INTERRUPT (1 << 18) - -/* 0x6858, 0x7458, 0x10058, 0x10c58, 0x11858, 0x12458 */ -#define GRPH_INT_STATUS 0x6858 -# define GRPH_PFLIP_INT_OCCURRED (1 << 0) -# define GRPH_PFLIP_INT_CLEAR (1 << 8) -/* 0x685c, 0x745c, 0x1005c, 0x10c5c, 0x1185c, 0x1245c */ -#define GRPH_INT_CONTROL 0x685c -# define GRPH_PFLIP_INT_MASK (1 << 0) -# define GRPH_PFLIP_INT_TYPE (1 << 8) - -#define DACA_AUTODETECT_INT_CONTROL 0x66c8 - -#define DC_HPD1_INT_STATUS 0x601c -#define DC_HPD2_INT_STATUS 0x6028 -#define DC_HPD3_INT_STATUS 0x6034 -#define DC_HPD4_INT_STATUS 0x6040 -#define DC_HPD5_INT_STATUS 0x604c -#define DC_HPD6_INT_STATUS 0x6058 -# define DC_HPDx_INT_STATUS (1 << 0) -# define DC_HPDx_SENSE (1 << 1) -# define DC_HPDx_RX_INT_STATUS (1 << 8) - -#define DC_HPD1_INT_CONTROL 0x6020 -#define DC_HPD2_INT_CONTROL 0x602c -#define DC_HPD3_INT_CONTROL 0x6038 -#define DC_HPD4_INT_CONTROL 0x6044 -#define DC_HPD5_INT_CONTROL 0x6050 -#define DC_HPD6_INT_CONTROL 0x605c -# define DC_HPDx_INT_ACK (1 << 0) -# define DC_HPDx_INT_POLARITY (1 << 8) -# define DC_HPDx_INT_EN (1 << 16) -# define DC_HPDx_RX_INT_ACK (1 << 20) -# define DC_HPDx_RX_INT_EN (1 << 24) - -#define DC_HPD1_CONTROL 0x6024 -#define DC_HPD2_CONTROL 0x6030 -#define DC_HPD3_CONTROL 0x603c -#define DC_HPD4_CONTROL 0x6048 -#define DC_HPD5_CONTROL 0x6054 -#define DC_HPD6_CONTROL 0x6060 -# define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) -# define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) -# define DC_HPDx_EN (1 << 28) - -/* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ -#define CRTC_STATUS_FRAME_COUNT 0x6e98 - -#define GRBM_CNTL 0x8000 -#define GRBM_READ_TIMEOUT(x) ((x) << 0) - -#define GRBM_STATUS2 0x8008 -#define RLC_RQ_PENDING (1 << 0) -#define RLC_BUSY (1 << 8) -#define TC_BUSY (1 << 9) - -#define GRBM_STATUS 0x8010 -#define CMDFIFO_AVAIL_MASK 0x0000000F -#define RING2_RQ_PENDING (1 << 4) -#define SRBM_RQ_PENDING (1 << 5) -#define RING1_RQ_PENDING (1 << 6) -#define CF_RQ_PENDING (1 << 7) -#define PF_RQ_PENDING (1 << 8) -#define GDS_DMA_RQ_PENDING (1 << 9) -#define GRBM_EE_BUSY (1 << 10) -#define DB_CLEAN (1 << 12) -#define CB_CLEAN (1 << 13) -#define TA_BUSY (1 << 14) -#define GDS_BUSY (1 << 15) -#define VGT_BUSY (1 << 17) -#define IA_BUSY_NO_DMA (1 << 18) -#define IA_BUSY (1 << 19) -#define SX_BUSY (1 << 20) -#define SPI_BUSY (1 << 22) -#define BCI_BUSY (1 << 23) -#define SC_BUSY (1 << 24) -#define PA_BUSY (1 << 25) -#define DB_BUSY (1 << 26) -#define CP_COHERENCY_BUSY (1 << 28) -#define CP_BUSY (1 << 29) -#define CB_BUSY (1 << 30) -#define GUI_ACTIVE (1 << 31) -#define GRBM_STATUS_SE0 0x8014 -#define GRBM_STATUS_SE1 0x8018 -#define SE_DB_CLEAN (1 << 1) -#define SE_CB_CLEAN (1 << 2) -#define SE_BCI_BUSY (1 << 22) -#define SE_VGT_BUSY (1 << 23) -#define SE_PA_BUSY (1 << 24) -#define SE_TA_BUSY (1 << 25) -#define SE_SX_BUSY (1 << 26) -#define SE_SPI_BUSY (1 << 27) -#define SE_SC_BUSY (1 << 29) -#define SE_DB_BUSY (1 << 30) -#define SE_CB_BUSY (1 << 31) - -#define GRBM_SOFT_RESET 0x8020 -#define SOFT_RESET_CP (1 << 0) -#define SOFT_RESET_CB (1 << 1) -#define SOFT_RESET_RLC (1 << 2) -#define SOFT_RESET_DB (1 << 3) -#define SOFT_RESET_GDS (1 << 4) -#define SOFT_RESET_PA (1 << 5) -#define SOFT_RESET_SC (1 << 6) -#define SOFT_RESET_BCI (1 << 7) -#define SOFT_RESET_SPI (1 << 8) -#define SOFT_RESET_SX (1 << 10) -#define SOFT_RESET_TC (1 << 11) -#define SOFT_RESET_TA (1 << 12) -#define SOFT_RESET_VGT (1 << 14) -#define SOFT_RESET_IA (1 << 15) - -#define GRBM_GFX_INDEX 0x802C - -#define GRBM_INT_CNTL 0x8060 -# define RDERR_INT_ENABLE (1 << 0) -# define GUI_IDLE_INT_ENABLE (1 << 19) - -#define SCRATCH_REG0 0x8500 -#define SCRATCH_REG1 0x8504 -#define SCRATCH_REG2 0x8508 -#define SCRATCH_REG3 0x850C -#define SCRATCH_REG4 0x8510 -#define SCRATCH_REG5 0x8514 -#define SCRATCH_REG6 0x8518 -#define SCRATCH_REG7 0x851C - -#define SCRATCH_UMSK 0x8540 -#define SCRATCH_ADDR 0x8544 - -#define CP_SEM_WAIT_TIMER 0x85BC - -#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 - -#define CP_ME_CNTL 0x86D8 -#define CP_CE_HALT (1 << 24) -#define CP_PFP_HALT (1 << 26) -#define CP_ME_HALT (1 << 28) - -#define CP_COHER_CNTL2 0x85E8 - -#define CP_RB2_RPTR 0x86f8 -#define CP_RB1_RPTR 0x86fc -#define CP_RB0_RPTR 0x8700 -#define CP_RB_WPTR_DELAY 0x8704 - -#define CP_QUEUE_THRESHOLDS 0x8760 -#define ROQ_IB1_START(x) ((x) << 0) -#define ROQ_IB2_START(x) ((x) << 8) -#define CP_MEQ_THRESHOLDS 0x8764 -#define MEQ1_START(x) ((x) << 0) -#define MEQ2_START(x) ((x) << 8) - -#define CP_PERFMON_CNTL 0x87FC - -#define VGT_VTX_VECT_EJECT_REG 0x88B0 - -#define VGT_CACHE_INVALIDATION 0x88C4 -#define CACHE_INVALIDATION(x) ((x) << 0) -#define VC_ONLY 0 -#define TC_ONLY 1 -#define VC_AND_TC 2 -#define AUTO_INVLD_EN(x) ((x) << 6) -#define NO_AUTO 0 -#define ES_AUTO 1 -#define GS_AUTO 2 -#define ES_AND_GS_AUTO 3 -#define VGT_ESGS_RING_SIZE 0x88C8 -#define VGT_GSVS_RING_SIZE 0x88CC - -#define VGT_GS_VERTEX_REUSE 0x88D4 - -#define VGT_PRIMITIVE_TYPE 0x8958 -#define VGT_INDEX_TYPE 0x895C - -#define VGT_NUM_INDICES 0x8970 -#define VGT_NUM_INSTANCES 0x8974 - -#define VGT_TF_RING_SIZE 0x8988 - -#define VGT_HS_OFFCHIP_PARAM 0x89B0 - -#define VGT_TF_MEMORY_BASE 0x89B8 - -#define CC_GC_SHADER_ARRAY_CONFIG 0x89bc -#define GC_USER_SHADER_ARRAY_CONFIG 0x89c0 - -#define PA_CL_ENHANCE 0x8A14 -#define CLIP_VTX_REORDER_ENA (1 << 0) -#define NUM_CLIP_SEQ(x) ((x) << 1) - -#define PA_SU_LINE_STIPPLE_VALUE 0x8A60 - -#define PA_SC_LINE_STIPPLE_STATE 0x8B10 - -#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 -#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -#define FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) - -#define PA_SC_FIFO_SIZE 0x8BCC -#define SC_FRONTEND_PRIM_FIFO_SIZE(x) ((x) << 0) -#define SC_BACKEND_PRIM_FIFO_SIZE(x) ((x) << 6) -#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 15) -#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 23) - -#define PA_SC_ENHANCE 0x8BF0 - -#define SQ_CONFIG 0x8C00 - -#define SQC_CACHES 0x8C08 - -#define SX_DEBUG_1 0x9060 - -#define SPI_STATIC_THREAD_MGMT_1 0x90E0 -#define SPI_STATIC_THREAD_MGMT_2 0x90E4 -#define SPI_STATIC_THREAD_MGMT_3 0x90E8 -#define SPI_PS_MAX_WAVE_ID 0x90EC - -#define SPI_CONFIG_CNTL 0x9100 - -#define SPI_CONFIG_CNTL_1 0x913C -#define VTX_DONE_DELAY(x) ((x) << 0) -#define INTERP_ONE_PRIM_PER_ROW (1 << 4) - -#define CGTS_TCC_DISABLE 0x9148 -#define CGTS_USER_TCC_DISABLE 0x914C -#define TCC_DISABLE_MASK 0xFFFF0000 -#define TCC_DISABLE_SHIFT 16 - -#define TA_CNTL_AUX 0x9508 - -#define CC_RB_BACKEND_DISABLE 0x98F4 -#define BACKEND_DISABLE(x) ((x) << 16) -#define GB_ADDR_CONFIG 0x98F8 -#define NUM_PIPES(x) ((x) << 0) -#define NUM_PIPES_MASK 0x00000007 -#define NUM_PIPES_SHIFT 0 -#define PIPE_INTERLEAVE_SIZE(x) ((x) << 4) -#define PIPE_INTERLEAVE_SIZE_MASK 0x00000070 -#define PIPE_INTERLEAVE_SIZE_SHIFT 4 -#define NUM_SHADER_ENGINES(x) ((x) << 12) -#define NUM_SHADER_ENGINES_MASK 0x00003000 -#define NUM_SHADER_ENGINES_SHIFT 12 -#define SHADER_ENGINE_TILE_SIZE(x) ((x) << 16) -#define SHADER_ENGINE_TILE_SIZE_MASK 0x00070000 -#define SHADER_ENGINE_TILE_SIZE_SHIFT 16 -#define NUM_GPUS(x) ((x) << 20) -#define NUM_GPUS_MASK 0x00700000 -#define NUM_GPUS_SHIFT 20 -#define MULTI_GPU_TILE_SIZE(x) ((x) << 24) -#define MULTI_GPU_TILE_SIZE_MASK 0x03000000 -#define MULTI_GPU_TILE_SIZE_SHIFT 24 -#define ROW_SIZE(x) ((x) << 28) -#define ROW_SIZE_MASK 0x30000000 -#define ROW_SIZE_SHIFT 28 - -#define GB_TILE_MODE0 0x9910 -# define MICRO_TILE_MODE(x) ((x) << 0) -# define ADDR_SURF_DISPLAY_MICRO_TILING 0 -# define ADDR_SURF_THIN_MICRO_TILING 1 -# define ADDR_SURF_DEPTH_MICRO_TILING 2 -# define ARRAY_MODE(x) ((x) << 2) -# define ARRAY_LINEAR_GENERAL 0 -# define ARRAY_LINEAR_ALIGNED 1 -# define ARRAY_1D_TILED_THIN1 2 -# define ARRAY_2D_TILED_THIN1 4 -# define PIPE_CONFIG(x) ((x) << 6) -# define ADDR_SURF_P2 0 -# define ADDR_SURF_P4_8x16 4 -# define ADDR_SURF_P4_16x16 5 -# define ADDR_SURF_P4_16x32 6 -# define ADDR_SURF_P4_32x32 7 -# define ADDR_SURF_P8_16x16_8x16 8 -# define ADDR_SURF_P8_16x32_8x16 9 -# define ADDR_SURF_P8_32x32_8x16 10 -# define ADDR_SURF_P8_16x32_16x16 11 -# define ADDR_SURF_P8_32x32_16x16 12 -# define ADDR_SURF_P8_32x32_16x32 13 -# define ADDR_SURF_P8_32x64_32x32 14 -# define TILE_SPLIT(x) ((x) << 11) -# define ADDR_SURF_TILE_SPLIT_64B 0 -# define ADDR_SURF_TILE_SPLIT_128B 1 -# define ADDR_SURF_TILE_SPLIT_256B 2 -# define ADDR_SURF_TILE_SPLIT_512B 3 -# define ADDR_SURF_TILE_SPLIT_1KB 4 -# define ADDR_SURF_TILE_SPLIT_2KB 5 -# define ADDR_SURF_TILE_SPLIT_4KB 6 -# define BANK_WIDTH(x) ((x) << 14) -# define ADDR_SURF_BANK_WIDTH_1 0 -# define ADDR_SURF_BANK_WIDTH_2 1 -# define ADDR_SURF_BANK_WIDTH_4 2 -# define ADDR_SURF_BANK_WIDTH_8 3 -# define BANK_HEIGHT(x) ((x) << 16) -# define ADDR_SURF_BANK_HEIGHT_1 0 -# define ADDR_SURF_BANK_HEIGHT_2 1 -# define ADDR_SURF_BANK_HEIGHT_4 2 -# define ADDR_SURF_BANK_HEIGHT_8 3 -# define MACRO_TILE_ASPECT(x) ((x) << 18) -# define ADDR_SURF_MACRO_ASPECT_1 0 -# define ADDR_SURF_MACRO_ASPECT_2 1 -# define ADDR_SURF_MACRO_ASPECT_4 2 -# define ADDR_SURF_MACRO_ASPECT_8 3 -# define NUM_BANKS(x) ((x) << 20) -# define ADDR_SURF_2_BANK 0 -# define ADDR_SURF_4_BANK 1 -# define ADDR_SURF_8_BANK 2 -# define ADDR_SURF_16_BANK 3 - -#define CB_PERFCOUNTER0_SELECT0 0x9a20 -#define CB_PERFCOUNTER0_SELECT1 0x9a24 -#define CB_PERFCOUNTER1_SELECT0 0x9a28 -#define CB_PERFCOUNTER1_SELECT1 0x9a2c -#define CB_PERFCOUNTER2_SELECT0 0x9a30 -#define CB_PERFCOUNTER2_SELECT1 0x9a34 -#define CB_PERFCOUNTER3_SELECT0 0x9a38 -#define CB_PERFCOUNTER3_SELECT1 0x9a3c - -#define GC_USER_RB_BACKEND_DISABLE 0x9B7C -#define BACKEND_DISABLE_MASK 0x00FF0000 -#define BACKEND_DISABLE_SHIFT 16 - -#define TCP_CHAN_STEER_LO 0xac0c -#define TCP_CHAN_STEER_HI 0xac10 - -#define CP_RB0_BASE 0xC100 -#define CP_RB0_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define BUF_SWAP_32BIT (2 << 16) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) - -#define CP_RB0_RPTR_ADDR 0xC10C -#define CP_RB0_RPTR_ADDR_HI 0xC110 -#define CP_RB0_WPTR 0xC114 - -#define CP_PFP_UCODE_ADDR 0xC150 -#define CP_PFP_UCODE_DATA 0xC154 -#define CP_ME_RAM_RADDR 0xC158 -#define CP_ME_RAM_WADDR 0xC15C -#define CP_ME_RAM_DATA 0xC160 - -#define CP_CE_UCODE_ADDR 0xC168 -#define CP_CE_UCODE_DATA 0xC16C - -#define CP_RB1_BASE 0xC180 -#define CP_RB1_CNTL 0xC184 -#define CP_RB1_RPTR_ADDR 0xC188 -#define CP_RB1_RPTR_ADDR_HI 0xC18C -#define CP_RB1_WPTR 0xC190 -#define CP_RB2_BASE 0xC194 -#define CP_RB2_CNTL 0xC198 -#define CP_RB2_RPTR_ADDR 0xC19C -#define CP_RB2_RPTR_ADDR_HI 0xC1A0 -#define CP_RB2_WPTR 0xC1A4 -#define CP_INT_CNTL_RING0 0xC1A8 -#define CP_INT_CNTL_RING1 0xC1AC -#define CP_INT_CNTL_RING2 0xC1B0 -# define CNTX_BUSY_INT_ENABLE (1 << 19) -# define CNTX_EMPTY_INT_ENABLE (1 << 20) -# define WAIT_MEM_SEM_INT_ENABLE (1 << 21) -# define TIME_STAMP_INT_ENABLE (1 << 26) -# define CP_RINGID2_INT_ENABLE (1 << 29) -# define CP_RINGID1_INT_ENABLE (1 << 30) -# define CP_RINGID0_INT_ENABLE (1 << 31) -#define CP_INT_STATUS_RING0 0xC1B4 -#define CP_INT_STATUS_RING1 0xC1B8 -#define CP_INT_STATUS_RING2 0xC1BC -# define WAIT_MEM_SEM_INT_STAT (1 << 21) -# define TIME_STAMP_INT_STAT (1 << 26) -# define CP_RINGID2_INT_STAT (1 << 29) -# define CP_RINGID1_INT_STAT (1 << 30) -# define CP_RINGID0_INT_STAT (1 << 31) - -#define CP_DEBUG 0xC1FC - -#define RLC_CNTL 0xC300 -# define RLC_ENABLE (1 << 0) -#define RLC_RL_BASE 0xC304 -#define RLC_RL_SIZE 0xC308 -#define RLC_LB_CNTL 0xC30C -#define RLC_SAVE_AND_RESTORE_BASE 0xC310 -#define RLC_LB_CNTR_MAX 0xC314 -#define RLC_LB_CNTR_INIT 0xC318 - -#define RLC_CLEAR_STATE_RESTORE_BASE 0xC320 - -#define RLC_UCODE_ADDR 0xC32C -#define RLC_UCODE_DATA 0xC330 - -#define RLC_MC_CNTL 0xC344 -#define RLC_UCODE_CNTL 0xC348 - -#define VGT_EVENT_INITIATOR 0x28a90 -# define SAMPLE_STREAMOUTSTATS1 (1 << 0) -# define SAMPLE_STREAMOUTSTATS2 (2 << 0) -# define SAMPLE_STREAMOUTSTATS3 (3 << 0) -# define CACHE_FLUSH_TS (4 << 0) -# define CACHE_FLUSH (6 << 0) -# define CS_PARTIAL_FLUSH (7 << 0) -# define VGT_STREAMOUT_RESET (10 << 0) -# define END_OF_PIPE_INCR_DE (11 << 0) -# define END_OF_PIPE_IB_END (12 << 0) -# define RST_PIX_CNT (13 << 0) -# define VS_PARTIAL_FLUSH (15 << 0) -# define PS_PARTIAL_FLUSH (16 << 0) -# define CACHE_FLUSH_AND_INV_TS_EVENT (20 << 0) -# define ZPASS_DONE (21 << 0) -# define CACHE_FLUSH_AND_INV_EVENT (22 << 0) -# define PERFCOUNTER_START (23 << 0) -# define PERFCOUNTER_STOP (24 << 0) -# define PIPELINESTAT_START (25 << 0) -# define PIPELINESTAT_STOP (26 << 0) -# define PERFCOUNTER_SAMPLE (27 << 0) -# define SAMPLE_PIPELINESTAT (30 << 0) -# define SAMPLE_STREAMOUTSTATS (32 << 0) -# define RESET_VTX_CNT (33 << 0) -# define VGT_FLUSH (36 << 0) -# define BOTTOM_OF_PIPE_TS (40 << 0) -# define DB_CACHE_FLUSH_AND_INV (42 << 0) -# define FLUSH_AND_INV_DB_DATA_TS (43 << 0) -# define FLUSH_AND_INV_DB_META (44 << 0) -# define FLUSH_AND_INV_CB_DATA_TS (45 << 0) -# define FLUSH_AND_INV_CB_META (46 << 0) -# define CS_DONE (47 << 0) -# define PS_DONE (48 << 0) -# define FLUSH_AND_INV_CB_PIXEL_DATA (49 << 0) -# define THREAD_TRACE_START (51 << 0) -# define THREAD_TRACE_STOP (52 << 0) -# define THREAD_TRACE_FLUSH (54 << 0) -# define THREAD_TRACE_FINISH (55 << 0) - -/* - * PM4 - */ -#define PACKET_TYPE0 0 -#define PACKET_TYPE1 1 -#define PACKET_TYPE2 2 -#define PACKET_TYPE3 3 - -#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ - (((reg) >> 2) & 0xFFFF) | \ - ((n) & 0x3FFF) << 16) -#define CP_PACKET2 0x80000000 -#define PACKET2_PAD_SHIFT 0 -#define PACKET2_PAD_MASK (0x3fffffff << 0) - -#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) - -#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ - (((op) & 0xFF) << 8) | \ - ((n) & 0x3FFF) << 16) - -#define PACKET3_COMPUTE(op, n) (PACKET3(op, n) | 1 << 1) - -/* Packet 3 types */ -#define PACKET3_NOP 0x10 -#define PACKET3_SET_BASE 0x11 -#define PACKET3_BASE_INDEX(x) ((x) << 0) -#define GDS_PARTITION_BASE 2 -#define CE_PARTITION_BASE 3 -#define PACKET3_CLEAR_STATE 0x12 -#define PACKET3_INDEX_BUFFER_SIZE 0x13 -#define PACKET3_DISPATCH_DIRECT 0x15 -#define PACKET3_DISPATCH_INDIRECT 0x16 -#define PACKET3_ALLOC_GDS 0x1B -#define PACKET3_WRITE_GDS_RAM 0x1C -#define PACKET3_ATOMIC_GDS 0x1D -#define PACKET3_ATOMIC 0x1E -#define PACKET3_OCCLUSION_QUERY 0x1F -#define PACKET3_SET_PREDICATION 0x20 -#define PACKET3_REG_RMW 0x21 -#define PACKET3_COND_EXEC 0x22 -#define PACKET3_PRED_EXEC 0x23 -#define PACKET3_DRAW_INDIRECT 0x24 -#define PACKET3_DRAW_INDEX_INDIRECT 0x25 -#define PACKET3_INDEX_BASE 0x26 -#define PACKET3_DRAW_INDEX_2 0x27 -#define PACKET3_CONTEXT_CONTROL 0x28 -#define PACKET3_INDEX_TYPE 0x2A -#define PACKET3_DRAW_INDIRECT_MULTI 0x2C -#define PACKET3_DRAW_INDEX_AUTO 0x2D -#define PACKET3_DRAW_INDEX_IMMD 0x2E -#define PACKET3_NUM_INSTANCES 0x2F -#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30 -#define PACKET3_INDIRECT_BUFFER_CONST 0x31 -#define PACKET3_INDIRECT_BUFFER 0x32 -#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 -#define PACKET3_DRAW_INDEX_OFFSET_2 0x35 -#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 -#define PACKET3_WRITE_DATA 0x37 -#define PACKET3_DRAW_INDEX_INDIRECT_MULTI 0x38 -#define PACKET3_MEM_SEMAPHORE 0x39 -#define PACKET3_MPEG_INDEX 0x3A -#define PACKET3_COPY_DW 0x3B -#define PACKET3_WAIT_REG_MEM 0x3C -#define PACKET3_MEM_WRITE 0x3D -#define PACKET3_COPY_DATA 0x40 -#define PACKET3_PFP_SYNC_ME 0x42 -#define PACKET3_SURFACE_SYNC 0x43 -# define PACKET3_DEST_BASE_0_ENA (1 << 0) -# define PACKET3_DEST_BASE_1_ENA (1 << 1) -# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) -# define PACKET3_CB1_DEST_BASE_ENA (1 << 7) -# define PACKET3_CB2_DEST_BASE_ENA (1 << 8) -# define PACKET3_CB3_DEST_BASE_ENA (1 << 9) -# define PACKET3_CB4_DEST_BASE_ENA (1 << 10) -# define PACKET3_CB5_DEST_BASE_ENA (1 << 11) -# define PACKET3_CB6_DEST_BASE_ENA (1 << 12) -# define PACKET3_CB7_DEST_BASE_ENA (1 << 13) -# define PACKET3_DB_DEST_BASE_ENA (1 << 14) -# define PACKET3_DEST_BASE_2_ENA (1 << 19) -# define PACKET3_DEST_BASE_3_ENA (1 << 21) -# define PACKET3_TCL1_ACTION_ENA (1 << 22) -# define PACKET3_TC_ACTION_ENA (1 << 23) -# define PACKET3_CB_ACTION_ENA (1 << 25) -# define PACKET3_DB_ACTION_ENA (1 << 26) -# define PACKET3_SH_KCACHE_ACTION_ENA (1 << 27) -# define PACKET3_SH_ICACHE_ACTION_ENA (1 << 29) -#define PACKET3_ME_INITIALIZE 0x44 -#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -#define PACKET3_COND_WRITE 0x45 -#define PACKET3_EVENT_WRITE 0x46 -#define EVENT_TYPE(x) ((x) << 0) -#define EVENT_INDEX(x) ((x) << 8) - /* 0 - any non-TS event - * 1 - ZPASS_DONE - * 2 - SAMPLE_PIPELINESTAT - * 3 - SAMPLE_STREAMOUTSTAT* - * 4 - *S_PARTIAL_FLUSH - * 5 - EOP events - * 6 - EOS events - * 7 - CACHE_FLUSH, CACHE_FLUSH_AND_INV_EVENT - */ -#define INV_L2 (1 << 20) - /* INV TC L2 cache when EVENT_INDEX = 7 */ -#define PACKET3_EVENT_WRITE_EOP 0x47 -#define DATA_SEL(x) ((x) << 29) - /* 0 - discard - * 1 - send low 32bit data - * 2 - send 64bit data - * 3 - send 64bit counter value - */ -#define INT_SEL(x) ((x) << 24) - /* 0 - none - * 1 - interrupt only (DATA_SEL = 0) - * 2 - interrupt when data write is confirmed - */ -#define PACKET3_EVENT_WRITE_EOS 0x48 -#define PACKET3_PREAMBLE_CNTL 0x4A -# define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE (2 << 28) -# define PACKET3_PREAMBLE_END_CLEAR_STATE (3 << 28) -#define PACKET3_ONE_REG_WRITE 0x57 -#define PACKET3_LOAD_CONFIG_REG 0x5F -#define PACKET3_LOAD_CONTEXT_REG 0x60 -#define PACKET3_LOAD_SH_REG 0x61 -#define PACKET3_SET_CONFIG_REG 0x68 -#define PACKET3_SET_CONFIG_REG_START 0x00008000 -#define PACKET3_SET_CONFIG_REG_END 0x0000b000 -#define PACKET3_SET_CONTEXT_REG 0x69 -#define PACKET3_SET_CONTEXT_REG_START 0x00028000 -#define PACKET3_SET_CONTEXT_REG_END 0x00029000 -#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 -#define PACKET3_SET_RESOURCE_INDIRECT 0x74 -#define PACKET3_SET_SH_REG 0x76 -#define PACKET3_SET_SH_REG_START 0x0000b000 -#define PACKET3_SET_SH_REG_END 0x0000c000 -#define PACKET3_SET_SH_REG_OFFSET 0x77 -#define PACKET3_ME_WRITE 0x7A -#define PACKET3_SCRATCH_RAM_WRITE 0x7D -#define PACKET3_SCRATCH_RAM_READ 0x7E -#define PACKET3_CE_WRITE 0x7F -#define PACKET3_LOAD_CONST_RAM 0x80 -#define PACKET3_WRITE_CONST_RAM 0x81 -#define PACKET3_WRITE_CONST_RAM_OFFSET 0x82 -#define PACKET3_DUMP_CONST_RAM 0x83 -#define PACKET3_INCREMENT_CE_COUNTER 0x84 -#define PACKET3_INCREMENT_DE_COUNTER 0x85 -#define PACKET3_WAIT_ON_CE_COUNTER 0x86 -#define PACKET3_WAIT_ON_DE_COUNTER 0x87 -#define PACKET3_WAIT_ON_DE_COUNTER_DIFF 0x88 -#define PACKET3_SET_CE_DE_COUNTERS 0x89 -#define PACKET3_WAIT_ON_AVAIL_BUFFER 0x8A - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/savage/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/savage/Makefile deleted file mode 100644 index d8f84ac7..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/savage/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y = -Iinclude/drm -savage-y := savage_drv.o savage_bci.o savage_state.o - -obj-$(CONFIG_DRM_SAVAGE)+= savage.o - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_bci.c b/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_bci.c deleted file mode 100644 index cb1ee4e0..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_bci.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* savage_bci.c -- BCI support for Savage - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" - -/* Need a long timeout for shadow status updates can take a while - * and so can waiting for events when the queue is full. */ -#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */ -#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ -#define SAVAGE_FREELIST_DEBUG 0 - -static int savage_do_cleanup_bci(struct drm_device *dev); - -static int -savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n) -{ - uint32_t mask = dev_priv->status_used_mask; - uint32_t threshold = dev_priv->bci_threshold_hi; - uint32_t status; - int i; - -#if SAVAGE_BCI_DEBUG - if (n > dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - threshold) - DRM_ERROR("Trying to emit %d words " - "(more than guaranteed space in COB)\n", n); -#endif - - for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { - DRM_MEMORYBARRIER(); - status = dev_priv->status_ptr[0]; - if ((status & mask) < threshold) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x, threshold=0x%08x\n", status, threshold); -#endif - return -EBUSY; -} - -static int -savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n) -{ - uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { - status = SAVAGE_READ(SAVAGE_STATUS_WORD0); - if ((status & SAVAGE_FIFO_USED_MASK_S3D) <= maxUsed) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x\n", status); -#endif - return -EBUSY; -} - -static int -savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n) -{ - uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n; - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) { - status = SAVAGE_READ(SAVAGE_ALT_STATUS_WORD0); - if ((status & SAVAGE_FIFO_USED_MASK_S4) <= maxUsed) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x\n", status); -#endif - return -EBUSY; -} - -/* - * Waiting for events. - * - * The BIOSresets the event tag to 0 on mode changes. Therefore we - * never emit 0 to the event tag. If we find a 0 event tag we know the - * BIOS stomped on it and return success assuming that the BIOS waited - * for engine idle. - * - * Note: if the Xserver uses the event tag it has to follow the same - * rule. Otherwise there may be glitches every 2^16 events. - */ -static int -savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e) -{ - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) { - DRM_MEMORYBARRIER(); - status = dev_priv->status_ptr[1]; - if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff || - (status & 0xffff) == 0) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); -#endif - - return -EBUSY; -} - -static int -savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e) -{ - uint32_t status; - int i; - - for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) { - status = SAVAGE_READ(SAVAGE_STATUS_WORD1); - if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff || - (status & 0xffff) == 0) - return 0; - DRM_UDELAY(1); - } - -#if SAVAGE_BCI_DEBUG - DRM_ERROR("failed!\n"); - DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e); -#endif - - return -EBUSY; -} - -uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv, - unsigned int flags) -{ - uint16_t count; - BCI_LOCALS; - - if (dev_priv->status_ptr) { - /* coordinate with Xserver */ - count = dev_priv->status_ptr[1023]; - if (count < dev_priv->event_counter) - dev_priv->event_wrap++; - } else { - count = dev_priv->event_counter; - } - count = (count + 1) & 0xffff; - if (count == 0) { - count++; /* See the comment above savage_wait_event_*. */ - dev_priv->event_wrap++; - } - dev_priv->event_counter = count; - if (dev_priv->status_ptr) - dev_priv->status_ptr[1023] = (uint32_t) count; - - if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) { - unsigned int wait_cmd = BCI_CMD_WAIT; - if ((flags & SAVAGE_WAIT_2D)) - wait_cmd |= BCI_CMD_WAIT_2D; - if ((flags & SAVAGE_WAIT_3D)) - wait_cmd |= BCI_CMD_WAIT_3D; - BEGIN_BCI(2); - BCI_WRITE(wait_cmd); - } else { - BEGIN_BCI(1); - } - BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count); - - return count; -} - -/* - * Freelist management - */ -static int savage_freelist_init(struct drm_device * dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *buf; - drm_savage_buf_priv_t *entry; - int i; - DRM_DEBUG("count=%d\n", dma->buf_count); - - dev_priv->head.next = &dev_priv->tail; - dev_priv->head.prev = NULL; - dev_priv->head.buf = NULL; - - dev_priv->tail.next = NULL; - dev_priv->tail.prev = &dev_priv->head; - dev_priv->tail.buf = NULL; - - for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[i]; - entry = buf->dev_private; - - SET_AGE(&entry->age, 0, 0); - entry->buf = buf; - - entry->next = dev_priv->head.next; - entry->prev = &dev_priv->head; - dev_priv->head.next->prev = entry; - dev_priv->head.next = entry; - } - - return 0; -} - -static struct drm_buf *savage_freelist_get(struct drm_device * dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_buf_priv_t *tail = dev_priv->tail.prev; - uint16_t event; - unsigned int wrap; - DRM_DEBUG("\n"); - - UPDATE_EVENT_COUNTER(); - if (dev_priv->status_ptr) - event = dev_priv->status_ptr[1] & 0xffff; - else - event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; - wrap = dev_priv->event_wrap; - if (event > dev_priv->event_counter) - wrap--; /* hardware hasn't passed the last wrap yet */ - - DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap); - DRM_DEBUG(" head=0x%04x %d\n", event, wrap); - - if (tail->buf && (TEST_AGE(&tail->age, event, wrap) || event == 0)) { - drm_savage_buf_priv_t *next = tail->next; - drm_savage_buf_priv_t *prev = tail->prev; - prev->next = next; - next->prev = prev; - tail->next = tail->prev = NULL; - return tail->buf; - } - - DRM_DEBUG("returning NULL, tail->buf=%p!\n", tail->buf); - return NULL; -} - -void savage_freelist_put(struct drm_device * dev, struct drm_buf * buf) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next; - - DRM_DEBUG("age=0x%04x wrap=%d\n", entry->age.event, entry->age.wrap); - - if (entry->next != NULL || entry->prev != NULL) { - DRM_ERROR("entry already on freelist.\n"); - return; - } - - prev = &dev_priv->head; - next = prev->next; - prev->next = entry; - next->prev = entry; - entry->prev = prev; - entry->next = next; -} - -/* - * Command DMA - */ -static int savage_dma_init(drm_savage_private_t * dev_priv) -{ - unsigned int i; - - dev_priv->nr_dma_pages = dev_priv->cmd_dma->size / - (SAVAGE_DMA_PAGE_SIZE * 4); - dev_priv->dma_pages = kmalloc(sizeof(drm_savage_dma_page_t) * - dev_priv->nr_dma_pages, GFP_KERNEL); - if (dev_priv->dma_pages == NULL) - return -ENOMEM; - - for (i = 0; i < dev_priv->nr_dma_pages; ++i) { - SET_AGE(&dev_priv->dma_pages[i].age, 0, 0); - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - SET_AGE(&dev_priv->last_dma_age, 0, 0); - - dev_priv->first_dma_page = 0; - dev_priv->current_dma_page = 0; - - return 0; -} - -void savage_dma_reset(drm_savage_private_t * dev_priv) -{ - uint16_t event; - unsigned int wrap, i; - event = savage_bci_emit_event(dev_priv, 0); - wrap = dev_priv->event_wrap; - for (i = 0; i < dev_priv->nr_dma_pages; ++i) { - SET_AGE(&dev_priv->dma_pages[i].age, event, wrap); - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - SET_AGE(&dev_priv->last_dma_age, event, wrap); - dev_priv->first_dma_page = dev_priv->current_dma_page = 0; -} - -void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page) -{ - uint16_t event; - unsigned int wrap; - - /* Faked DMA buffer pages don't age. */ - if (dev_priv->cmd_dma == &dev_priv->fake_dma) - return; - - UPDATE_EVENT_COUNTER(); - if (dev_priv->status_ptr) - event = dev_priv->status_ptr[1] & 0xffff; - else - event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; - wrap = dev_priv->event_wrap; - if (event > dev_priv->event_counter) - wrap--; /* hardware hasn't passed the last wrap yet */ - - if (dev_priv->dma_pages[page].age.wrap > wrap || - (dev_priv->dma_pages[page].age.wrap == wrap && - dev_priv->dma_pages[page].age.event > event)) { - if (dev_priv->wait_evnt(dev_priv, - dev_priv->dma_pages[page].age.event) - < 0) - DRM_ERROR("wait_evnt failed!\n"); - } -} - -uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n) -{ - unsigned int cur = dev_priv->current_dma_page; - unsigned int rest = SAVAGE_DMA_PAGE_SIZE - - dev_priv->dma_pages[cur].used; - unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) / - SAVAGE_DMA_PAGE_SIZE; - uint32_t *dma_ptr; - unsigned int i; - - DRM_DEBUG("cur=%u, cur->used=%u, n=%u, rest=%u, nr_pages=%u\n", - cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages); - - if (cur + nr_pages < dev_priv->nr_dma_pages) { - dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + - cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used; - if (n < rest) - rest = n; - dev_priv->dma_pages[cur].used += rest; - n -= rest; - cur++; - } else { - dev_priv->dma_flush(dev_priv); - nr_pages = - (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE; - for (i = cur; i < dev_priv->nr_dma_pages; ++i) { - dev_priv->dma_pages[i].age = dev_priv->last_dma_age; - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle; - dev_priv->first_dma_page = cur = 0; - } - for (i = cur; nr_pages > 0; ++i, --nr_pages) { -#if SAVAGE_DMA_DEBUG - if (dev_priv->dma_pages[i].used) { - DRM_ERROR("unflushed page %u: used=%u\n", - i, dev_priv->dma_pages[i].used); - } -#endif - if (n > SAVAGE_DMA_PAGE_SIZE) - dev_priv->dma_pages[i].used = SAVAGE_DMA_PAGE_SIZE; - else - dev_priv->dma_pages[i].used = n; - n -= SAVAGE_DMA_PAGE_SIZE; - } - dev_priv->current_dma_page = --i; - - DRM_DEBUG("cur=%u, cur->used=%u, n=%u\n", - i, dev_priv->dma_pages[i].used, n); - - savage_dma_wait(dev_priv, dev_priv->current_dma_page); - - return dma_ptr; -} - -static void savage_dma_flush(drm_savage_private_t * dev_priv) -{ - unsigned int first = dev_priv->first_dma_page; - unsigned int cur = dev_priv->current_dma_page; - uint16_t event; - unsigned int wrap, pad, align, len, i; - unsigned long phys_addr; - BCI_LOCALS; - - if (first == cur && - dev_priv->dma_pages[cur].used == dev_priv->dma_pages[cur].flushed) - return; - - /* pad length to multiples of 2 entries - * align start of next DMA block to multiles of 8 entries */ - pad = -dev_priv->dma_pages[cur].used & 1; - align = -(dev_priv->dma_pages[cur].used + pad) & 7; - - DRM_DEBUG("first=%u, cur=%u, first->flushed=%u, cur->used=%u, " - "pad=%u, align=%u\n", - first, cur, dev_priv->dma_pages[first].flushed, - dev_priv->dma_pages[cur].used, pad, align); - - /* pad with noops */ - if (pad) { - uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + - cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used; - dev_priv->dma_pages[cur].used += pad; - while (pad != 0) { - *dma_ptr++ = BCI_CMD_WAIT; - pad--; - } - } - - DRM_MEMORYBARRIER(); - - /* do flush ... */ - phys_addr = dev_priv->cmd_dma->offset + - (first * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[first].flushed) * 4; - len = (cur - first) * SAVAGE_DMA_PAGE_SIZE + - dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed; - - DRM_DEBUG("phys_addr=%lx, len=%u\n", - phys_addr | dev_priv->dma_type, len); - - BEGIN_BCI(3); - BCI_SET_REGISTERS(SAVAGE_DMABUFADDR, 1); - BCI_WRITE(phys_addr | dev_priv->dma_type); - BCI_DMA(len); - - /* fix alignment of the start of the next block */ - dev_priv->dma_pages[cur].used += align; - - /* age DMA pages */ - event = savage_bci_emit_event(dev_priv, 0); - wrap = dev_priv->event_wrap; - for (i = first; i < cur; ++i) { - SET_AGE(&dev_priv->dma_pages[i].age, event, wrap); - dev_priv->dma_pages[i].used = 0; - dev_priv->dma_pages[i].flushed = 0; - } - /* age the current page only when it's full */ - if (dev_priv->dma_pages[cur].used == SAVAGE_DMA_PAGE_SIZE) { - SET_AGE(&dev_priv->dma_pages[cur].age, event, wrap); - dev_priv->dma_pages[cur].used = 0; - dev_priv->dma_pages[cur].flushed = 0; - /* advance to next page */ - cur++; - if (cur == dev_priv->nr_dma_pages) - cur = 0; - dev_priv->first_dma_page = dev_priv->current_dma_page = cur; - } else { - dev_priv->first_dma_page = cur; - dev_priv->dma_pages[cur].flushed = dev_priv->dma_pages[i].used; - } - SET_AGE(&dev_priv->last_dma_age, event, wrap); - - DRM_DEBUG("first=cur=%u, cur->used=%u, cur->flushed=%u\n", cur, - dev_priv->dma_pages[cur].used, - dev_priv->dma_pages[cur].flushed); -} - -static void savage_fake_dma_flush(drm_savage_private_t * dev_priv) -{ - unsigned int i, j; - BCI_LOCALS; - - if (dev_priv->first_dma_page == dev_priv->current_dma_page && - dev_priv->dma_pages[dev_priv->current_dma_page].used == 0) - return; - - DRM_DEBUG("first=%u, cur=%u, cur->used=%u\n", - dev_priv->first_dma_page, dev_priv->current_dma_page, - dev_priv->dma_pages[dev_priv->current_dma_page].used); - - for (i = dev_priv->first_dma_page; - i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used; - ++i) { - uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle + - i * SAVAGE_DMA_PAGE_SIZE; -#if SAVAGE_DMA_DEBUG - /* Sanity check: all pages except the last one must be full. */ - if (i < dev_priv->current_dma_page && - dev_priv->dma_pages[i].used != SAVAGE_DMA_PAGE_SIZE) { - DRM_ERROR("partial DMA page %u: used=%u", - i, dev_priv->dma_pages[i].used); - } -#endif - BEGIN_BCI(dev_priv->dma_pages[i].used); - for (j = 0; j < dev_priv->dma_pages[i].used; ++j) { - BCI_WRITE(dma_ptr[j]); - } - dev_priv->dma_pages[i].used = 0; - } - - /* reset to first page */ - dev_priv->first_dma_page = dev_priv->current_dma_page = 0; -} - -int savage_driver_load(struct drm_device *dev, unsigned long chipset) -{ - drm_savage_private_t *dev_priv; - - dev_priv = kzalloc(sizeof(drm_savage_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev->dev_private = (void *)dev_priv; - - dev_priv->chipset = (enum savage_family)chipset; - - return 0; -} - - -/* - * Initialize mappings. On Savage4 and SavageIX the alignment - * and size of the aperture is not suitable for automatic MTRR setup - * in drm_addmap. Therefore we add them manually before the maps are - * initialized, and tear them down on last close. - */ -int savage_driver_firstopen(struct drm_device *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - unsigned long mmio_base, fb_base, fb_size, aperture_base; - /* fb_rsrc and aper_rsrc aren't really used currently, but still exist - * in case we decide we need information on the BAR for BSD in the - * future. - */ - unsigned int fb_rsrc, aper_rsrc; - int ret = 0; - - dev_priv->mtrr[0].handle = -1; - dev_priv->mtrr[1].handle = -1; - dev_priv->mtrr[2].handle = -1; - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - fb_rsrc = 0; - fb_base = pci_resource_start(dev->pdev, 0); - fb_size = SAVAGE_FB_SIZE_S3; - mmio_base = fb_base + SAVAGE_FB_SIZE_S3; - aper_rsrc = 0; - aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; - /* this should always be true */ - if (pci_resource_len(dev->pdev, 0) == 0x08000000) { - /* Don't make MMIO write-cobining! We need 3 - * MTRRs. */ - dev_priv->mtrr[0].base = fb_base; - dev_priv->mtrr[0].size = 0x01000000; - dev_priv->mtrr[0].handle = - drm_mtrr_add(dev_priv->mtrr[0].base, - dev_priv->mtrr[0].size, DRM_MTRR_WC); - dev_priv->mtrr[1].base = fb_base + 0x02000000; - dev_priv->mtrr[1].size = 0x02000000; - dev_priv->mtrr[1].handle = - drm_mtrr_add(dev_priv->mtrr[1].base, - dev_priv->mtrr[1].size, DRM_MTRR_WC); - dev_priv->mtrr[2].base = fb_base + 0x04000000; - dev_priv->mtrr[2].size = 0x04000000; - dev_priv->mtrr[2].handle = - drm_mtrr_add(dev_priv->mtrr[2].base, - dev_priv->mtrr[2].size, DRM_MTRR_WC); - } else { - DRM_ERROR("strange pci_resource_len %08llx\n", - (unsigned long long) - pci_resource_len(dev->pdev, 0)); - } - } else if (dev_priv->chipset != S3_SUPERSAVAGE && - dev_priv->chipset != S3_SAVAGE2000) { - mmio_base = pci_resource_start(dev->pdev, 0); - fb_rsrc = 1; - fb_base = pci_resource_start(dev->pdev, 1); - fb_size = SAVAGE_FB_SIZE_S4; - aper_rsrc = 1; - aperture_base = fb_base + SAVAGE_APERTURE_OFFSET; - /* this should always be true */ - if (pci_resource_len(dev->pdev, 1) == 0x08000000) { - /* Can use one MTRR to cover both fb and - * aperture. */ - dev_priv->mtrr[0].base = fb_base; - dev_priv->mtrr[0].size = 0x08000000; - dev_priv->mtrr[0].handle = - drm_mtrr_add(dev_priv->mtrr[0].base, - dev_priv->mtrr[0].size, DRM_MTRR_WC); - } else { - DRM_ERROR("strange pci_resource_len %08llx\n", - (unsigned long long) - pci_resource_len(dev->pdev, 1)); - } - } else { - mmio_base = pci_resource_start(dev->pdev, 0); - fb_rsrc = 1; - fb_base = pci_resource_start(dev->pdev, 1); - fb_size = pci_resource_len(dev->pdev, 1); - aper_rsrc = 2; - aperture_base = pci_resource_start(dev->pdev, 2); - /* Automatic MTRR setup will do the right thing. */ - } - - ret = drm_addmap(dev, mmio_base, SAVAGE_MMIO_SIZE, _DRM_REGISTERS, - _DRM_READ_ONLY, &dev_priv->mmio); - if (ret) - return ret; - - ret = drm_addmap(dev, fb_base, fb_size, _DRM_FRAME_BUFFER, - _DRM_WRITE_COMBINING, &dev_priv->fb); - if (ret) - return ret; - - ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE, - _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING, - &dev_priv->aperture); - return ret; -} - -/* - * Delete MTRRs and free device-private data. - */ -void savage_driver_lastclose(struct drm_device *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - int i; - - for (i = 0; i < 3; ++i) - if (dev_priv->mtrr[i].handle >= 0) - drm_mtrr_del(dev_priv->mtrr[i].handle, - dev_priv->mtrr[i].base, - dev_priv->mtrr[i].size, DRM_MTRR_WC); -} - -int savage_driver_unload(struct drm_device *dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - - kfree(dev_priv); - - return 0; -} - -static int savage_do_init_bci(struct drm_device * dev, drm_savage_init_t * init) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - - if (init->fb_bpp != 16 && init->fb_bpp != 32) { - DRM_ERROR("invalid frame buffer bpp %d!\n", init->fb_bpp); - return -EINVAL; - } - if (init->depth_bpp != 16 && init->depth_bpp != 32) { - DRM_ERROR("invalid depth buffer bpp %d!\n", init->fb_bpp); - return -EINVAL; - } - if (init->dma_type != SAVAGE_DMA_AGP && - init->dma_type != SAVAGE_DMA_PCI) { - DRM_ERROR("invalid dma memory type %d!\n", init->dma_type); - return -EINVAL; - } - - dev_priv->cob_size = init->cob_size; - dev_priv->bci_threshold_lo = init->bci_threshold_lo; - dev_priv->bci_threshold_hi = init->bci_threshold_hi; - dev_priv->dma_type = init->dma_type; - - dev_priv->fb_bpp = init->fb_bpp; - dev_priv->front_offset = init->front_offset; - dev_priv->front_pitch = init->front_pitch; - dev_priv->back_offset = init->back_offset; - dev_priv->back_pitch = init->back_pitch; - dev_priv->depth_bpp = init->depth_bpp; - dev_priv->depth_offset = init->depth_offset; - dev_priv->depth_pitch = init->depth_pitch; - - dev_priv->texture_offset = init->texture_offset; - dev_priv->texture_size = init->texture_size; - - dev_priv->sarea = drm_getsarea(dev); - if (!dev_priv->sarea) { - DRM_ERROR("could not find sarea!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - if (init->status_offset != 0) { - dev_priv->status = drm_core_findmap(dev, init->status_offset); - if (!dev_priv->status) { - DRM_ERROR("could not find shadow status region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - } else { - dev_priv->status = NULL; - } - if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) { - dev->agp_buffer_token = init->buffers_offset; - dev->agp_buffer_map = drm_core_findmap(dev, - init->buffers_offset); - if (!dev->agp_buffer_map) { - DRM_ERROR("could not find DMA buffer region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - drm_core_ioremap(dev->agp_buffer_map, dev); - if (!dev->agp_buffer_map) { - DRM_ERROR("failed to ioremap DMA buffer region!\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - } - if (init->agp_textures_offset) { - dev_priv->agp_textures = - drm_core_findmap(dev, init->agp_textures_offset); - if (!dev_priv->agp_textures) { - DRM_ERROR("could not find agp texture region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - } else { - dev_priv->agp_textures = NULL; - } - - if (init->cmd_dma_offset) { - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - DRM_ERROR("command DMA not supported on " - "Savage3D/MX/IX.\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - if (dev->dma && dev->dma->buflist) { - DRM_ERROR("command and vertex DMA not supported " - "at the same time.\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - dev_priv->cmd_dma = drm_core_findmap(dev, init->cmd_dma_offset); - if (!dev_priv->cmd_dma) { - DRM_ERROR("could not find command DMA region!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - if (dev_priv->dma_type == SAVAGE_DMA_AGP) { - if (dev_priv->cmd_dma->type != _DRM_AGP) { - DRM_ERROR("AGP command DMA region is not a " - "_DRM_AGP map!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - drm_core_ioremap(dev_priv->cmd_dma, dev); - if (!dev_priv->cmd_dma->handle) { - DRM_ERROR("failed to ioremap command " - "DMA region!\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - } else if (dev_priv->cmd_dma->type != _DRM_CONSISTENT) { - DRM_ERROR("PCI command DMA region is not a " - "_DRM_CONSISTENT map!\n"); - savage_do_cleanup_bci(dev); - return -EINVAL; - } - } else { - dev_priv->cmd_dma = NULL; - } - - dev_priv->dma_flush = savage_dma_flush; - if (!dev_priv->cmd_dma) { - DRM_DEBUG("falling back to faked command DMA.\n"); - dev_priv->fake_dma.offset = 0; - dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE; - dev_priv->fake_dma.type = _DRM_SHM; - dev_priv->fake_dma.handle = kmalloc(SAVAGE_FAKE_DMA_SIZE, - GFP_KERNEL); - if (!dev_priv->fake_dma.handle) { - DRM_ERROR("could not allocate faked DMA buffer!\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - dev_priv->cmd_dma = &dev_priv->fake_dma; - dev_priv->dma_flush = savage_fake_dma_flush; - } - - dev_priv->sarea_priv = - (drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle + - init->sarea_priv_offset); - - /* setup bitmap descriptors */ - { - unsigned int color_tile_format; - unsigned int depth_tile_format; - unsigned int front_stride, back_stride, depth_stride; - if (dev_priv->chipset <= S3_SAVAGE4) { - color_tile_format = dev_priv->fb_bpp == 16 ? - SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; - depth_tile_format = dev_priv->depth_bpp == 16 ? - SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP; - } else { - color_tile_format = SAVAGE_BD_TILE_DEST; - depth_tile_format = SAVAGE_BD_TILE_DEST; - } - front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8); - back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8); - depth_stride = - dev_priv->depth_pitch / (dev_priv->depth_bpp / 8); - - dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | - (color_tile_format << SAVAGE_BD_TILE_SHIFT); - - dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) | - (color_tile_format << SAVAGE_BD_TILE_SHIFT); - - dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE | - (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) | - (depth_tile_format << SAVAGE_BD_TILE_SHIFT); - } - - /* setup status and bci ptr */ - dev_priv->event_counter = 0; - dev_priv->event_wrap = 0; - dev_priv->bci_ptr = (volatile uint32_t *) - ((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET); - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D; - } else { - dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S4; - } - if (dev_priv->status != NULL) { - dev_priv->status_ptr = - (volatile uint32_t *)dev_priv->status->handle; - dev_priv->wait_fifo = savage_bci_wait_fifo_shadow; - dev_priv->wait_evnt = savage_bci_wait_event_shadow; - dev_priv->status_ptr[1023] = dev_priv->event_counter; - } else { - dev_priv->status_ptr = NULL; - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - dev_priv->wait_fifo = savage_bci_wait_fifo_s3d; - } else { - dev_priv->wait_fifo = savage_bci_wait_fifo_s4; - } - dev_priv->wait_evnt = savage_bci_wait_event_reg; - } - - /* cliprect functions */ - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) - dev_priv->emit_clip_rect = savage_emit_clip_rect_s3d; - else - dev_priv->emit_clip_rect = savage_emit_clip_rect_s4; - - if (savage_freelist_init(dev) < 0) { - DRM_ERROR("could not initialize freelist\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - - if (savage_dma_init(dev_priv) < 0) { - DRM_ERROR("could not initialize command DMA\n"); - savage_do_cleanup_bci(dev); - return -ENOMEM; - } - - return 0; -} - -static int savage_do_cleanup_bci(struct drm_device * dev) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - - if (dev_priv->cmd_dma == &dev_priv->fake_dma) { - kfree(dev_priv->fake_dma.handle); - } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle && - dev_priv->cmd_dma->type == _DRM_AGP && - dev_priv->dma_type == SAVAGE_DMA_AGP) - drm_core_ioremapfree(dev_priv->cmd_dma, dev); - - if (dev_priv->dma_type == SAVAGE_DMA_AGP && - dev->agp_buffer_map && dev->agp_buffer_map->handle) { - drm_core_ioremapfree(dev->agp_buffer_map, dev); - /* make sure the next instance (which may be running - * in PCI mode) doesn't try to use an old - * agp_buffer_map. */ - dev->agp_buffer_map = NULL; - } - - kfree(dev_priv->dma_pages); - - return 0; -} - -static int savage_bci_init(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_init_t *init = data; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - switch (init->func) { - case SAVAGE_INIT_BCI: - return savage_do_init_bci(dev, init); - case SAVAGE_CLEANUP_BCI: - return savage_do_cleanup_bci(dev); - } - - return -EINVAL; -} - -static int savage_bci_event_emit(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_event_emit_t *event = data; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - event->count = savage_bci_emit_event(dev_priv, event->flags); - event->count |= dev_priv->event_wrap << 16; - - return 0; -} - -static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - drm_savage_event_wait_t *event = data; - unsigned int event_e, hw_e; - unsigned int event_w, hw_w; - - DRM_DEBUG("\n"); - - UPDATE_EVENT_COUNTER(); - if (dev_priv->status_ptr) - hw_e = dev_priv->status_ptr[1] & 0xffff; - else - hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff; - hw_w = dev_priv->event_wrap; - if (hw_e > dev_priv->event_counter) - hw_w--; /* hardware hasn't passed the last wrap yet */ - - event_e = event->count & 0xffff; - event_w = event->count >> 16; - - /* Don't need to wait if - * - event counter wrapped since the event was emitted or - * - the hardware has advanced up to or over the event to wait for. - */ - if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e)) - return 0; - else - return dev_priv->wait_evnt(dev_priv, event_e); -} - -/* - * DMA buffer management - */ - -static int savage_bci_get_buffers(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_dma *d) -{ - struct drm_buf *buf; - int i; - - for (i = d->granted_count; i < d->request_count; i++) { - buf = savage_freelist_get(dev); - if (!buf) - return -EAGAIN; - - buf->file_priv = file_priv; - - if (DRM_COPY_TO_USER(&d->request_indices[i], - &buf->idx, sizeof(buf->idx))) - return -EFAULT; - if (DRM_COPY_TO_USER(&d->request_sizes[i], - &buf->total, sizeof(buf->total))) - return -EFAULT; - - d->granted_count++; - } - return 0; -} - -int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - struct drm_dma *d = data; - int ret = 0; - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - /* Please don't send us buffers. - */ - if (d->send_count != 0) { - DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", - DRM_CURRENTPID, d->send_count); - return -EINVAL; - } - - /* We'll send you buffers. - */ - if (d->request_count < 0 || d->request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - DRM_CURRENTPID, d->request_count, dma->buf_count); - return -EINVAL; - } - - d->granted_count = 0; - - if (d->request_count) { - ret = savage_bci_get_buffers(dev, file_priv, d); - } - - return ret; -} - -void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) -{ - struct drm_device_dma *dma = dev->dma; - drm_savage_private_t *dev_priv = dev->dev_private; - int i; - - if (!dma) - return; - if (!dev_priv) - return; - if (!dma->buflist) - return; - - /*i830_flush_queue(dev); */ - - for (i = 0; i < dma->buf_count; i++) { - struct drm_buf *buf = dma->buflist[i]; - drm_savage_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->file_priv == file_priv && buf_priv && - buf_priv->next == NULL && buf_priv->prev == NULL) { - uint16_t event; - DRM_DEBUG("reclaimed from client\n"); - event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D); - SET_AGE(&buf_priv->age, event, dev_priv->event_wrap); - savage_freelist_put(dev, buf); - } - } - - drm_core_reclaim_buffers(dev, file_priv); -} - -struct drm_ioctl_desc savage_ioctls[] = { - DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), - DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), - DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), -}; - -int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.c deleted file mode 100644 index 89afe0b8..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.c +++ /dev/null @@ -1,90 +0,0 @@ -/* savage_drv.c -- Savage driver for Linux - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include - -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - savage_PCI_IDS -}; - -static const struct file_operations savage_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .llseek = noop_llseek, -}; - -static struct drm_driver driver = { - .driver_features = - DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA, - .dev_priv_size = sizeof(drm_savage_buf_priv_t), - .load = savage_driver_load, - .firstopen = savage_driver_firstopen, - .lastclose = savage_driver_lastclose, - .unload = savage_driver_unload, - .reclaim_buffers = savage_reclaim_buffers, - .ioctls = savage_ioctls, - .dma_ioctl = savage_bci_buffers, - .fops = &savage_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct pci_driver savage_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, -}; - -static int __init savage_init(void) -{ - driver.num_ioctls = savage_max_ioctl; - return drm_pci_init(&driver, &savage_pci_driver); -} - -static void __exit savage_exit(void) -{ - drm_pci_exit(&driver, &savage_pci_driver); -} - -module_init(savage_init); -module_exit(savage_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.h deleted file mode 100644 index df2aac66..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_drv.h +++ /dev/null @@ -1,575 +0,0 @@ -/* savage_drv.h -- Private header for the savage driver */ -/* - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __SAVAGE_DRV_H__ -#define __SAVAGE_DRV_H__ - -#define DRIVER_AUTHOR "Felix Kuehling" - -#define DRIVER_NAME "savage" -#define DRIVER_DESC "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]" -#define DRIVER_DATE "20050313" - -#define DRIVER_MAJOR 2 -#define DRIVER_MINOR 4 -#define DRIVER_PATCHLEVEL 1 -/* Interface history: - * - * 1.x The DRM driver from the VIA/S3 code drop, basically a dummy - * 2.0 The first real DRM - * 2.1 Scissors registers managed by the DRM, 3D operations clipped by - * cliprects of the cmdbuf ioctl - * 2.2 Implemented SAVAGE_CMD_DMA_IDX and SAVAGE_CMD_VB_IDX - * 2.3 Event counters used by BCI_EVENT_EMIT/WAIT ioctls are now 32 bits - * wide and thus very long lived (unlikely to ever wrap). The size - * in the struct was 32 bits before, but only 16 bits were used - * 2.4 Implemented command DMA. Now drm_savage_init_t.cmd_dma_offset is - * actually used - */ - -typedef struct drm_savage_age { - uint16_t event; - unsigned int wrap; -} drm_savage_age_t; - -typedef struct drm_savage_buf_priv { - struct drm_savage_buf_priv *next; - struct drm_savage_buf_priv *prev; - drm_savage_age_t age; - struct drm_buf *buf; -} drm_savage_buf_priv_t; - -typedef struct drm_savage_dma_page { - drm_savage_age_t age; - unsigned int used, flushed; -} drm_savage_dma_page_t; -#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */ -/* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command - * size of 16kbytes or 4k entries. Minimum requirement would be - * 10kbytes for 255 40-byte vertices in one drawing command. */ -#define SAVAGE_FAKE_DMA_SIZE (SAVAGE_DMA_PAGE_SIZE*4*4) - -/* interesting bits of hardware state that are saved in dev_priv */ -typedef union { - struct drm_savage_common_state { - uint32_t vbaddr; - } common; - struct { - unsigned char pad[sizeof(struct drm_savage_common_state)]; - uint32_t texctrl, texaddr; - uint32_t scstart, new_scstart; - uint32_t scend, new_scend; - } s3d; - struct { - unsigned char pad[sizeof(struct drm_savage_common_state)]; - uint32_t texdescr, texaddr0, texaddr1; - uint32_t drawctrl0, new_drawctrl0; - uint32_t drawctrl1, new_drawctrl1; - } s4; -} drm_savage_state_t; - -/* these chip tags should match the ones in the 2D driver in savage_regs.h. */ -enum savage_family { - S3_UNKNOWN = 0, - S3_SAVAGE3D, - S3_SAVAGE_MX, - S3_SAVAGE4, - S3_PROSAVAGE, - S3_TWISTER, - S3_PROSAVAGEDDR, - S3_SUPERSAVAGE, - S3_SAVAGE2000, - S3_LAST -}; - -extern struct drm_ioctl_desc savage_ioctls[]; -extern int savage_max_ioctl; - -#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) - -#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \ - || (chip==S3_PROSAVAGE) \ - || (chip==S3_TWISTER) \ - || (chip==S3_PROSAVAGEDDR)) - -#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) - -#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) - -#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \ - ||(chip==S3_PROSAVAGEDDR)) - -/* flags */ -#define SAVAGE_IS_AGP 1 - -typedef struct drm_savage_private { - drm_savage_sarea_t *sarea_priv; - - drm_savage_buf_priv_t head, tail; - - /* who am I? */ - enum savage_family chipset; - - unsigned int cob_size; - unsigned int bci_threshold_lo, bci_threshold_hi; - unsigned int dma_type; - - /* frame buffer layout */ - unsigned int fb_bpp; - unsigned int front_offset, front_pitch; - unsigned int back_offset, back_pitch; - unsigned int depth_bpp; - unsigned int depth_offset, depth_pitch; - - /* bitmap descriptors for swap and clear */ - unsigned int front_bd, back_bd, depth_bd; - - /* local textures */ - unsigned int texture_offset; - unsigned int texture_size; - - /* memory regions in physical memory */ - drm_local_map_t *sarea; - drm_local_map_t *mmio; - drm_local_map_t *fb; - drm_local_map_t *aperture; - drm_local_map_t *status; - drm_local_map_t *agp_textures; - drm_local_map_t *cmd_dma; - drm_local_map_t fake_dma; - - struct { - int handle; - unsigned long base, size; - } mtrr[3]; - - /* BCI and status-related stuff */ - volatile uint32_t *status_ptr, *bci_ptr; - uint32_t status_used_mask; - uint16_t event_counter; - unsigned int event_wrap; - - /* Savage4 command DMA */ - drm_savage_dma_page_t *dma_pages; - unsigned int nr_dma_pages, first_dma_page, current_dma_page; - drm_savage_age_t last_dma_age; - - /* saved hw state for global/local check on S3D */ - uint32_t hw_draw_ctrl, hw_zbuf_ctrl; - /* and for scissors (global, so don't emit if not changed) */ - uint32_t hw_scissors_start, hw_scissors_end; - - drm_savage_state_t state; - - /* after emitting a wait cmd Savage3D needs 63 nops before next DMA */ - unsigned int waiting; - - /* config/hardware-dependent function pointers */ - int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n); - int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e); - /* Err, there is a macro wait_event in include/linux/wait.h. - * Avoid unwanted macro expansion. */ - void (*emit_clip_rect) (struct drm_savage_private * dev_priv, - const struct drm_clip_rect * pbox); - void (*dma_flush) (struct drm_savage_private * dev_priv); -} drm_savage_private_t; - -/* ioctls */ -extern int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); - -/* BCI functions */ -extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv, - unsigned int flags); -extern void savage_freelist_put(struct drm_device * dev, struct drm_buf * buf); -extern void savage_dma_reset(drm_savage_private_t * dev_priv); -extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page); -extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, - unsigned int n); -extern int savage_driver_load(struct drm_device *dev, unsigned long chipset); -extern int savage_driver_firstopen(struct drm_device *dev); -extern void savage_driver_lastclose(struct drm_device *dev); -extern int savage_driver_unload(struct drm_device *dev); -extern void savage_reclaim_buffers(struct drm_device *dev, - struct drm_file *file_priv); - -/* state functions */ -extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox); -extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox); - -#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */ -#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */ -#define SAVAGE_MMIO_SIZE 0x00080000 /* 512kB */ -#define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */ -#define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */ - -#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region - * inside the MMIO region */ -#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip - * BCI FIFO */ - -/* - * MMIO registers - */ -#define SAVAGE_STATUS_WORD0 0x48C00 -#define SAVAGE_STATUS_WORD1 0x48C04 -#define SAVAGE_ALT_STATUS_WORD0 0x48C60 - -#define SAVAGE_FIFO_USED_MASK_S3D 0x0001ffff -#define SAVAGE_FIFO_USED_MASK_S4 0x001fffff - -/* Copied from savage_bci.h in the 2D driver with some renaming. */ - -/* Bitmap descriptors */ -#define SAVAGE_BD_STRIDE_SHIFT 0 -#define SAVAGE_BD_BPP_SHIFT 16 -#define SAVAGE_BD_TILE_SHIFT 24 -#define SAVAGE_BD_BW_DISABLE (1<<28) -/* common: */ -#define SAVAGE_BD_TILE_LINEAR 0 -/* savage4, MX, IX, 3D */ -#define SAVAGE_BD_TILE_16BPP 2 -#define SAVAGE_BD_TILE_32BPP 3 -/* twister, prosavage, DDR, supersavage, 2000 */ -#define SAVAGE_BD_TILE_DEST 1 -#define SAVAGE_BD_TILE_TEXTURE 2 -/* GBD - BCI enable */ -/* savage4, MX, IX, 3D */ -#define SAVAGE_GBD_BCI_ENABLE 8 -/* twister, prosavage, DDR, supersavage, 2000 */ -#define SAVAGE_GBD_BCI_ENABLE_TWISTER 0 - -#define SAVAGE_GBD_BIG_ENDIAN 4 -#define SAVAGE_GBD_LITTLE_ENDIAN 0 -#define SAVAGE_GBD_64 1 - -/* Global Bitmap Descriptor */ -#define SAVAGE_BCI_GLB_BD_LOW 0x8168 -#define SAVAGE_BCI_GLB_BD_HIGH 0x816C - -/* - * BCI registers - */ -/* Savage4/Twister/ProSavage 3D registers */ -#define SAVAGE_DRAWLOCALCTRL_S4 0x1e -#define SAVAGE_TEXPALADDR_S4 0x1f -#define SAVAGE_TEXCTRL0_S4 0x20 -#define SAVAGE_TEXCTRL1_S4 0x21 -#define SAVAGE_TEXADDR0_S4 0x22 -#define SAVAGE_TEXADDR1_S4 0x23 -#define SAVAGE_TEXBLEND0_S4 0x24 -#define SAVAGE_TEXBLEND1_S4 0x25 -#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */ -#define SAVAGE_TEXDESCR_S4 0x27 -#define SAVAGE_FOGTABLE_S4 0x28 -#define SAVAGE_FOGCTRL_S4 0x30 -#define SAVAGE_STENCILCTRL_S4 0x31 -#define SAVAGE_ZBUFCTRL_S4 0x32 -#define SAVAGE_ZBUFOFF_S4 0x33 -#define SAVAGE_DESTCTRL_S4 0x34 -#define SAVAGE_DRAWCTRL0_S4 0x35 -#define SAVAGE_DRAWCTRL1_S4 0x36 -#define SAVAGE_ZWATERMARK_S4 0x37 -#define SAVAGE_DESTTEXRWWATERMARK_S4 0x38 -#define SAVAGE_TEXBLENDCOLOR_S4 0x39 -/* Savage3D/MX/IX 3D registers */ -#define SAVAGE_TEXPALADDR_S3D 0x18 -#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */ -#define SAVAGE_TEXADDR_S3D 0x1A -#define SAVAGE_TEXDESCR_S3D 0x1B -#define SAVAGE_TEXCTRL_S3D 0x1C -#define SAVAGE_FOGTABLE_S3D 0x20 -#define SAVAGE_FOGCTRL_S3D 0x30 -#define SAVAGE_DRAWCTRL_S3D 0x31 -#define SAVAGE_ZBUFCTRL_S3D 0x32 -#define SAVAGE_ZBUFOFF_S3D 0x33 -#define SAVAGE_DESTCTRL_S3D 0x34 -#define SAVAGE_SCSTART_S3D 0x35 -#define SAVAGE_SCEND_S3D 0x36 -#define SAVAGE_ZWATERMARK_S3D 0x37 -#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38 -/* common stuff */ -#define SAVAGE_VERTBUFADDR 0x3e -#define SAVAGE_BITPLANEWTMASK 0xd7 -#define SAVAGE_DMABUFADDR 0x51 - -/* texture enable bits (needed for tex addr checking) */ -#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */ -#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */ -#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */ - -/* Global fields in Savage4/Twister/ProSavage 3D registers: - * - * All texture registers and DrawLocalCtrl are local. All other - * registers are global. */ - -/* Global fields in Savage3D/MX/IX 3D registers: - * - * All texture registers are local. DrawCtrl and ZBufCtrl are - * partially local. All other registers are global. - * - * DrawCtrl global fields: cullMode, alphaTestCmpFunc, alphaTestEn, alphaRefVal - * ZBufCtrl global fields: zCmpFunc, zBufEn - */ -#define SAVAGE_DRAWCTRL_S3D_GLOBAL 0x03f3c00c -#define SAVAGE_ZBUFCTRL_S3D_GLOBAL 0x00000027 - -/* Masks for scissor bits (drawCtrl[01] on s4, scissorStart/End on s3d) - */ -#define SAVAGE_SCISSOR_MASK_S4 0x00fff7ff -#define SAVAGE_SCISSOR_MASK_S3D 0x07ff07ff - -/* - * BCI commands - */ -#define BCI_CMD_NOP 0x40000000 -#define BCI_CMD_RECT 0x48000000 -#define BCI_CMD_RECT_XP 0x01000000 -#define BCI_CMD_RECT_YP 0x02000000 -#define BCI_CMD_SCANLINE 0x50000000 -#define BCI_CMD_LINE 0x5C000000 -#define BCI_CMD_LINE_LAST_PIXEL 0x58000000 -#define BCI_CMD_BYTE_TEXT 0x63000000 -#define BCI_CMD_NT_BYTE_TEXT 0x67000000 -#define BCI_CMD_BIT_TEXT 0x6C000000 -#define BCI_CMD_GET_ROP(cmd) (((cmd) >> 16) & 0xFF) -#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16)) -#define BCI_CMD_SEND_COLOR 0x00008000 - -#define BCI_CMD_CLIP_NONE 0x00000000 -#define BCI_CMD_CLIP_CURRENT 0x00002000 -#define BCI_CMD_CLIP_LR 0x00004000 -#define BCI_CMD_CLIP_NEW 0x00006000 - -#define BCI_CMD_DEST_GBD 0x00000000 -#define BCI_CMD_DEST_PBD 0x00000800 -#define BCI_CMD_DEST_PBD_NEW 0x00000C00 -#define BCI_CMD_DEST_SBD 0x00001000 -#define BCI_CMD_DEST_SBD_NEW 0x00001400 - -#define BCI_CMD_SRC_TRANSPARENT 0x00000200 -#define BCI_CMD_SRC_SOLID 0x00000000 -#define BCI_CMD_SRC_GBD 0x00000020 -#define BCI_CMD_SRC_COLOR 0x00000040 -#define BCI_CMD_SRC_MONO 0x00000060 -#define BCI_CMD_SRC_PBD_COLOR 0x00000080 -#define BCI_CMD_SRC_PBD_MONO 0x000000A0 -#define BCI_CMD_SRC_PBD_COLOR_NEW 0x000000C0 -#define BCI_CMD_SRC_PBD_MONO_NEW 0x000000E0 -#define BCI_CMD_SRC_SBD_COLOR 0x00000100 -#define BCI_CMD_SRC_SBD_MONO 0x00000120 -#define BCI_CMD_SRC_SBD_COLOR_NEW 0x00000140 -#define BCI_CMD_SRC_SBD_MONO_NEW 0x00000160 - -#define BCI_CMD_PAT_TRANSPARENT 0x00000010 -#define BCI_CMD_PAT_NONE 0x00000000 -#define BCI_CMD_PAT_COLOR 0x00000002 -#define BCI_CMD_PAT_MONO 0x00000003 -#define BCI_CMD_PAT_PBD_COLOR 0x00000004 -#define BCI_CMD_PAT_PBD_MONO 0x00000005 -#define BCI_CMD_PAT_PBD_COLOR_NEW 0x00000006 -#define BCI_CMD_PAT_PBD_MONO_NEW 0x00000007 -#define BCI_CMD_PAT_SBD_COLOR 0x00000008 -#define BCI_CMD_PAT_SBD_MONO 0x00000009 -#define BCI_CMD_PAT_SBD_COLOR_NEW 0x0000000A -#define BCI_CMD_PAT_SBD_MONO_NEW 0x0000000B - -#define BCI_BD_BW_DISABLE 0x10000000 -#define BCI_BD_TILE_MASK 0x03000000 -#define BCI_BD_TILE_NONE 0x00000000 -#define BCI_BD_TILE_16 0x02000000 -#define BCI_BD_TILE_32 0x03000000 -#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF) -#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16)) -#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF) -#define BCI_BD_SET_STRIDE(bd, st) ((bd) |= ((st) & 0xFFFF)) - -#define BCI_CMD_SET_REGISTER 0x96000000 - -#define BCI_CMD_WAIT 0xC0000000 -#define BCI_CMD_WAIT_3D 0x00010000 -#define BCI_CMD_WAIT_2D 0x00020000 - -#define BCI_CMD_UPDATE_EVENT_TAG 0x98000000 - -#define BCI_CMD_DRAW_PRIM 0x80000000 -#define BCI_CMD_DRAW_INDEXED_PRIM 0x88000000 -#define BCI_CMD_DRAW_CONT 0x01000000 -#define BCI_CMD_DRAW_TRILIST 0x00000000 -#define BCI_CMD_DRAW_TRISTRIP 0x02000000 -#define BCI_CMD_DRAW_TRIFAN 0x04000000 -#define BCI_CMD_DRAW_SKIPFLAGS 0x000000ff -#define BCI_CMD_DRAW_NO_Z 0x00000001 -#define BCI_CMD_DRAW_NO_W 0x00000002 -#define BCI_CMD_DRAW_NO_CD 0x00000004 -#define BCI_CMD_DRAW_NO_CS 0x00000008 -#define BCI_CMD_DRAW_NO_U0 0x00000010 -#define BCI_CMD_DRAW_NO_V0 0x00000020 -#define BCI_CMD_DRAW_NO_UV0 0x00000030 -#define BCI_CMD_DRAW_NO_U1 0x00000040 -#define BCI_CMD_DRAW_NO_V1 0x00000080 -#define BCI_CMD_DRAW_NO_UV1 0x000000c0 - -#define BCI_CMD_DMA 0xa8000000 - -#define BCI_W_H(w, h) ((((h) << 16) | (w)) & 0x0FFF0FFF) -#define BCI_X_Y(x, y) ((((y) << 16) | (x)) & 0x0FFF0FFF) -#define BCI_X_W(x, y) ((((w) << 16) | (x)) & 0x0FFF0FFF) -#define BCI_CLIP_LR(l, r) ((((r) << 16) | (l)) & 0x0FFF0FFF) -#define BCI_CLIP_TL(t, l) ((((t) << 16) | (l)) & 0x0FFF0FFF) -#define BCI_CLIP_BR(b, r) ((((b) << 16) | (r)) & 0x0FFF0FFF) - -#define BCI_LINE_X_Y(x, y) (((y) << 16) | ((x) & 0xFFFF)) -#define BCI_LINE_STEPS(diag, axi) (((axi) << 16) | ((diag) & 0xFFFF)) -#define BCI_LINE_MISC(maj, ym, xp, yp, err) \ - (((maj) & 0x1FFF) | \ - ((ym) ? 1<<13 : 0) | \ - ((xp) ? 1<<14 : 0) | \ - ((yp) ? 1<<15 : 0) | \ - ((err) << 16)) - -/* - * common commands - */ -#define BCI_SET_REGISTERS( first, n ) \ - BCI_WRITE(BCI_CMD_SET_REGISTER | \ - ((uint32_t)(n) & 0xff) << 16 | \ - ((uint32_t)(first) & 0xffff)) -#define DMA_SET_REGISTERS( first, n ) \ - DMA_WRITE(BCI_CMD_SET_REGISTER | \ - ((uint32_t)(n) & 0xff) << 16 | \ - ((uint32_t)(first) & 0xffff)) - -#define BCI_DRAW_PRIMITIVE(n, type, skip) \ - BCI_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \ - ((n) << 16)) -#define DMA_DRAW_PRIMITIVE(n, type, skip) \ - DMA_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \ - ((n) << 16)) - -#define BCI_DRAW_INDICES_S3D(n, type, i0) \ - BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \ - ((n) << 16) | (i0)) - -#define BCI_DRAW_INDICES_S4(n, type, skip) \ - BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \ - (skip) | ((n) << 16)) - -#define BCI_DMA(n) \ - BCI_WRITE(BCI_CMD_DMA | (((n) >> 1) - 1)) - -/* - * access to MMIO - */ -#define SAVAGE_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define SAVAGE_WRITE(reg) DRM_WRITE32( dev_priv->mmio, (reg) ) - -/* - * access to the burst command interface (BCI) - */ -#define SAVAGE_BCI_DEBUG 1 - -#define BCI_LOCALS volatile uint32_t *bci_ptr; - -#define BEGIN_BCI( n ) do { \ - dev_priv->wait_fifo(dev_priv, (n)); \ - bci_ptr = dev_priv->bci_ptr; \ -} while(0) - -#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val) - -/* - * command DMA support - */ -#define SAVAGE_DMA_DEBUG 1 - -#define DMA_LOCALS uint32_t *dma_ptr; - -#define BEGIN_DMA( n ) do { \ - unsigned int cur = dev_priv->current_dma_page; \ - unsigned int rest = SAVAGE_DMA_PAGE_SIZE - \ - dev_priv->dma_pages[cur].used; \ - if ((n) > rest) { \ - dma_ptr = savage_dma_alloc(dev_priv, (n)); \ - } else { /* fast path for small allocations */ \ - dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + \ - cur * SAVAGE_DMA_PAGE_SIZE + \ - dev_priv->dma_pages[cur].used; \ - if (dev_priv->dma_pages[cur].used == 0) \ - savage_dma_wait(dev_priv, cur); \ - dev_priv->dma_pages[cur].used += (n); \ - } \ -} while(0) - -#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val) - -#define DMA_COPY(src, n) do { \ - memcpy(dma_ptr, (src), (n)*4); \ - dma_ptr += n; \ -} while(0) - -#if SAVAGE_DMA_DEBUG -#define DMA_COMMIT() do { \ - unsigned int cur = dev_priv->current_dma_page; \ - uint32_t *expected = (uint32_t *)dev_priv->cmd_dma->handle + \ - cur * SAVAGE_DMA_PAGE_SIZE + \ - dev_priv->dma_pages[cur].used; \ - if (dma_ptr != expected) { \ - DRM_ERROR("DMA allocation and use don't match: " \ - "%p != %p\n", expected, dma_ptr); \ - savage_dma_reset(dev_priv); \ - } \ -} while(0) -#else -#define DMA_COMMIT() do {/* nothing */} while(0) -#endif - -#define DMA_FLUSH() dev_priv->dma_flush(dev_priv) - -/* Buffer aging via event tag - */ - -#define UPDATE_EVENT_COUNTER( ) do { \ - if (dev_priv->status_ptr) { \ - uint16_t count; \ - /* coordinate with Xserver */ \ - count = dev_priv->status_ptr[1023]; \ - if (count < dev_priv->event_counter) \ - dev_priv->event_wrap++; \ - dev_priv->event_counter = count; \ - } \ -} while(0) - -#define SET_AGE( age, e, w ) do { \ - (age)->event = e; \ - (age)->wrap = w; \ -} while(0) - -#define TEST_AGE( age, e, w ) \ - ( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) ) - -#endif /* __SAVAGE_DRV_H__ */ diff --git a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_state.c b/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_state.c deleted file mode 100644 index b6d86083..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/savage/savage_state.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* savage_state.c -- State and drawing support for Savage - * - * Copyright 2004 Felix Kuehling - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "drmP.h" -#include "savage_drm.h" -#include "savage_drv.h" - -void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox) -{ - uint32_t scstart = dev_priv->state.s3d.new_scstart; - uint32_t scend = dev_priv->state.s3d.new_scend; - scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) | - ((uint32_t) pbox->x1 & 0x000007ff) | - (((uint32_t) pbox->y1 << 16) & 0x07ff0000); - scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) | - (((uint32_t) pbox->x2 - 1) & 0x000007ff) | - ((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000); - if (scstart != dev_priv->state.s3d.scstart || - scend != dev_priv->state.s3d.scend) { - DMA_LOCALS; - BEGIN_DMA(4); - DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); - DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2); - DMA_WRITE(scstart); - DMA_WRITE(scend); - dev_priv->state.s3d.scstart = scstart; - dev_priv->state.s3d.scend = scend; - dev_priv->waiting = 1; - DMA_COMMIT(); - } -} - -void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv, - const struct drm_clip_rect * pbox) -{ - uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0; - uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1; - drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) | - ((uint32_t) pbox->x1 & 0x000007ff) | - (((uint32_t) pbox->y1 << 12) & 0x00fff000); - drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) | - (((uint32_t) pbox->x2 - 1) & 0x000007ff) | - ((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000); - if (drawctrl0 != dev_priv->state.s4.drawctrl0 || - drawctrl1 != dev_priv->state.s4.drawctrl1) { - DMA_LOCALS; - BEGIN_DMA(4); - DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); - DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2); - DMA_WRITE(drawctrl0); - DMA_WRITE(drawctrl1); - dev_priv->state.s4.drawctrl0 = drawctrl0; - dev_priv->state.s4.drawctrl1 = drawctrl1; - dev_priv->waiting = 1; - DMA_COMMIT(); - } -} - -static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit, - uint32_t addr) -{ - if ((addr & 6) != 2) { /* reserved bits */ - DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr); - return -EINVAL; - } - if (!(addr & 1)) { /* local */ - addr &= ~7; - if (addr < dev_priv->texture_offset || - addr >= dev_priv->texture_offset + dev_priv->texture_size) { - DRM_ERROR - ("bad texAddr%d %08x (local addr out of range)\n", - unit, addr); - return -EINVAL; - } - } else { /* AGP */ - if (!dev_priv->agp_textures) { - DRM_ERROR("bad texAddr%d %08x (AGP not available)\n", - unit, addr); - return -EINVAL; - } - addr &= ~7; - if (addr < dev_priv->agp_textures->offset || - addr >= (dev_priv->agp_textures->offset + - dev_priv->agp_textures->size)) { - DRM_ERROR - ("bad texAddr%d %08x (AGP addr out of range)\n", - unit, addr); - return -EINVAL; - } - } - return 0; -} - -#define SAVE_STATE(reg,where) \ - if(start <= reg && start+count > reg) \ - dev_priv->state.where = regs[reg - start] -#define SAVE_STATE_MASK(reg,where,mask) do { \ - if(start <= reg && start+count > reg) { \ - uint32_t tmp; \ - tmp = regs[reg - start]; \ - dev_priv->state.where = (tmp & (mask)) | \ - (dev_priv->state.where & ~(mask)); \ - } \ -} while (0) - -static int savage_verify_state_s3d(drm_savage_private_t * dev_priv, - unsigned int start, unsigned int count, - const uint32_t *regs) -{ - if (start < SAVAGE_TEXPALADDR_S3D || - start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) { - DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", - start, start + count - 1); - return -EINVAL; - } - - SAVE_STATE_MASK(SAVAGE_SCSTART_S3D, s3d.new_scstart, - ~SAVAGE_SCISSOR_MASK_S3D); - SAVE_STATE_MASK(SAVAGE_SCEND_S3D, s3d.new_scend, - ~SAVAGE_SCISSOR_MASK_S3D); - - /* if any texture regs were changed ... */ - if (start <= SAVAGE_TEXCTRL_S3D && - start + count > SAVAGE_TEXPALADDR_S3D) { - /* ... check texture state */ - SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl); - SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr); - if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK) - return savage_verify_texaddr(dev_priv, 0, - dev_priv->state.s3d.texaddr); - } - - return 0; -} - -static int savage_verify_state_s4(drm_savage_private_t * dev_priv, - unsigned int start, unsigned int count, - const uint32_t *regs) -{ - int ret = 0; - - if (start < SAVAGE_DRAWLOCALCTRL_S4 || - start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) { - DRM_ERROR("invalid register range (0x%04x-0x%04x)\n", - start, start + count - 1); - return -EINVAL; - } - - SAVE_STATE_MASK(SAVAGE_DRAWCTRL0_S4, s4.new_drawctrl0, - ~SAVAGE_SCISSOR_MASK_S4); - SAVE_STATE_MASK(SAVAGE_DRAWCTRL1_S4, s4.new_drawctrl1, - ~SAVAGE_SCISSOR_MASK_S4); - - /* if any texture regs were changed ... */ - if (start <= SAVAGE_TEXDESCR_S4 && - start + count > SAVAGE_TEXPALADDR_S4) { - /* ... check texture state */ - SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr); - SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0); - SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1); - if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK) - ret |= savage_verify_texaddr(dev_priv, 0, - dev_priv->state.s4.texaddr0); - if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK) - ret |= savage_verify_texaddr(dev_priv, 1, - dev_priv->state.s4.texaddr1); - } - - return ret; -} - -#undef SAVE_STATE -#undef SAVE_STATE_MASK - -static int savage_dispatch_state(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint32_t *regs) -{ - unsigned int count = cmd_header->state.count; - unsigned int start = cmd_header->state.start; - unsigned int count2 = 0; - unsigned int bci_size; - int ret; - DMA_LOCALS; - - if (!count) - return 0; - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - ret = savage_verify_state_s3d(dev_priv, start, count, regs); - if (ret != 0) - return ret; - /* scissor regs are emitted in savage_dispatch_draw */ - if (start < SAVAGE_SCSTART_S3D) { - if (start + count > SAVAGE_SCEND_S3D + 1) - count2 = count - (SAVAGE_SCEND_S3D + 1 - start); - if (start + count > SAVAGE_SCSTART_S3D) - count = SAVAGE_SCSTART_S3D - start; - } else if (start <= SAVAGE_SCEND_S3D) { - if (start + count > SAVAGE_SCEND_S3D + 1) { - count -= SAVAGE_SCEND_S3D + 1 - start; - start = SAVAGE_SCEND_S3D + 1; - } else - return 0; - } - } else { - ret = savage_verify_state_s4(dev_priv, start, count, regs); - if (ret != 0) - return ret; - /* scissor regs are emitted in savage_dispatch_draw */ - if (start < SAVAGE_DRAWCTRL0_S4) { - if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) - count2 = count - - (SAVAGE_DRAWCTRL1_S4 + 1 - start); - if (start + count > SAVAGE_DRAWCTRL0_S4) - count = SAVAGE_DRAWCTRL0_S4 - start; - } else if (start <= SAVAGE_DRAWCTRL1_S4) { - if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) { - count -= SAVAGE_DRAWCTRL1_S4 + 1 - start; - start = SAVAGE_DRAWCTRL1_S4 + 1; - } else - return 0; - } - } - - bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255; - - if (cmd_header->state.global) { - BEGIN_DMA(bci_size + 1); - DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D); - dev_priv->waiting = 1; - } else { - BEGIN_DMA(bci_size); - } - - do { - while (count > 0) { - unsigned int n = count < 255 ? count : 255; - DMA_SET_REGISTERS(start, n); - DMA_COPY(regs, n); - count -= n; - start += n; - regs += n; - } - start += 2; - regs += 2; - count = count2; - count2 = 0; - } while (count); - - DMA_COMMIT(); - - return 0; -} - -static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const struct drm_buf * dmabuf) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->prim.prim; - unsigned int skip = cmd_header->prim.skip; - unsigned int n = cmd_header->prim.count; - unsigned int start = cmd_header->prim.start; - unsigned int i; - BCI_LOCALS; - - if (!dmabuf) { - DRM_ERROR("called without dma buffers!\n"); - return -EINVAL; - } - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of vertices %u in TRILIST\n", - n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of vertices %u in TRIFAN/STRIP\n", - n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip != 0) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - } else { - unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - - (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - - (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); - if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - if (reorder) { - DRM_ERROR("TRILIST_201 used on Savage4 hardware\n"); - return -EINVAL; - } - } - - if (start + n > dmabuf->total / 32) { - DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", - start, start + n - 1, dmabuf->total / 32); - return -EINVAL; - } - - /* Vertex DMA doesn't work with command DMA at the same time, - * so we use BCI_... to submit commands here. Flush buffered - * faked DMA first. */ - DMA_FLUSH(); - - if (dmabuf->bus_address != dev_priv->state.common.vbaddr) { - BEGIN_BCI(2); - BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1); - BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type); - dev_priv->state.common.vbaddr = dmabuf->bus_address; - } - if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) { - /* Workaround for what looks like a hardware bug. If a - * WAIT_3D_IDLE was emitted some time before the - * indexed drawing command then the engine will lock - * up. There are two known workarounds: - * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */ - BEGIN_BCI(63); - for (i = 0; i < 63; ++i) - BCI_WRITE(BCI_CMD_WAIT); - dev_priv->waiting = 0; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 indices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - if (reorder) { - /* Need to reorder indices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { -1, -1, -1 }; - reorder[start % 3] = 2; - - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, start + 2); - - for (i = start + 1; i + 1 < start + count; i += 2) - BCI_WRITE((i + reorder[i % 3]) | - ((i + 1 + - reorder[(i + 1) % 3]) << 16)); - if (i < start + count) - BCI_WRITE(i + reorder[i % 3]); - } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, start); - - for (i = start + 1; i + 1 < start + count; i += 2) - BCI_WRITE(i | ((i + 1) << 16)); - if (i < start + count) - BCI_WRITE(i); - } else { - BEGIN_BCI((count + 2 + 1) / 2); - BCI_DRAW_INDICES_S4(count, prim, skip); - - for (i = start; i + 1 < start + count; i += 2) - BCI_WRITE(i | ((i + 1) << 16)); - if (i < start + count) - BCI_WRITE(i); - } - - start += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint32_t *vtxbuf, unsigned int vb_size, - unsigned int vb_stride) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->prim.prim; - unsigned int skip = cmd_header->prim.skip; - unsigned int n = cmd_header->prim.count; - unsigned int start = cmd_header->prim.start; - unsigned int vtx_size; - unsigned int i; - DMA_LOCALS; - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of vertices %u in TRILIST\n", - n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of vertices %u in TRIFAN/STRIP\n", - n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip > SAVAGE_SKIP_ALL_S3D) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 8; /* full vertex */ - } else { - if (skip > SAVAGE_SKIP_ALL_S4) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 10; /* full vertex */ - } - - vtx_size -= (skip & 1) + (skip >> 1 & 1) + - (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + - (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); - - if (vtx_size > vb_stride) { - DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", - vtx_size, vb_stride); - return -EINVAL; - } - - if (start + n > vb_size / (vb_stride * 4)) { - DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n", - start, start + n - 1, vb_size / (vb_stride * 4)); - return -EINVAL; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 vertices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - if (reorder) { - /* Need to reorder vertices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { -1, -1, -1 }; - reorder[start % 3] = 2; - - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - for (i = start; i < start + count; ++i) { - unsigned int j = i + reorder[i % 3]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); - } - - DMA_COMMIT(); - } else { - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - if (vb_stride == vtx_size) { - DMA_COPY(&vtxbuf[vb_stride * start], - vtx_size * count); - } else { - for (i = start; i < start + count; ++i) { - DMA_COPY(&vtxbuf [vb_stride * i], - vtx_size); - } - } - - DMA_COMMIT(); - } - - start += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint16_t *idx, - const struct drm_buf * dmabuf) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->idx.prim; - unsigned int skip = cmd_header->idx.skip; - unsigned int n = cmd_header->idx.count; - unsigned int i; - BCI_LOCALS; - - if (!dmabuf) { - DRM_ERROR("called without dma buffers!\n"); - return -EINVAL; - } - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of indices %u in TRILIST\n", n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of indices %u in TRIFAN/STRIP\n", n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip != 0) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - } else { - unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) - - (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) - - (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1); - if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) { - DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip); - return -EINVAL; - } - if (reorder) { - DRM_ERROR("TRILIST_201 used on Savage4 hardware\n"); - return -EINVAL; - } - } - - /* Vertex DMA doesn't work with command DMA at the same time, - * so we use BCI_... to submit commands here. Flush buffered - * faked DMA first. */ - DMA_FLUSH(); - - if (dmabuf->bus_address != dev_priv->state.common.vbaddr) { - BEGIN_BCI(2); - BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1); - BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type); - dev_priv->state.common.vbaddr = dmabuf->bus_address; - } - if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) { - /* Workaround for what looks like a hardware bug. If a - * WAIT_3D_IDLE was emitted some time before the - * indexed drawing command then the engine will lock - * up. There are two known workarounds: - * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */ - BEGIN_BCI(63); - for (i = 0; i < 63; ++i) - BCI_WRITE(BCI_CMD_WAIT); - dev_priv->waiting = 0; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 indices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - - /* check indices */ - for (i = 0; i < count; ++i) { - if (idx[i] > dmabuf->total / 32) { - DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", - i, idx[i], dmabuf->total / 32); - return -EINVAL; - } - } - - if (reorder) { - /* Need to reorder indices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { 2, -1, -1 }; - - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, idx[2]); - - for (i = 1; i + 1 < count; i += 2) - BCI_WRITE(idx[i + reorder[i % 3]] | - (idx[i + 1 + - reorder[(i + 1) % 3]] << 16)); - if (i < count) - BCI_WRITE(idx[i + reorder[i % 3]]); - } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - BEGIN_BCI((count + 1 + 1) / 2); - BCI_DRAW_INDICES_S3D(count, prim, idx[0]); - - for (i = 1; i + 1 < count; i += 2) - BCI_WRITE(idx[i] | (idx[i + 1] << 16)); - if (i < count) - BCI_WRITE(idx[i]); - } else { - BEGIN_BCI((count + 2 + 1) / 2); - BCI_DRAW_INDICES_S4(count, prim, skip); - - for (i = 0; i + 1 < count; i += 2) - BCI_WRITE(idx[i] | (idx[i + 1] << 16)); - if (i < count) - BCI_WRITE(idx[i]); - } - - idx += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const uint16_t *idx, - const uint32_t *vtxbuf, - unsigned int vb_size, unsigned int vb_stride) -{ - unsigned char reorder = 0; - unsigned int prim = cmd_header->idx.prim; - unsigned int skip = cmd_header->idx.skip; - unsigned int n = cmd_header->idx.count; - unsigned int vtx_size; - unsigned int i; - DMA_LOCALS; - - if (!n) - return 0; - - switch (prim) { - case SAVAGE_PRIM_TRILIST_201: - reorder = 1; - prim = SAVAGE_PRIM_TRILIST; - case SAVAGE_PRIM_TRILIST: - if (n % 3 != 0) { - DRM_ERROR("wrong number of indices %u in TRILIST\n", n); - return -EINVAL; - } - break; - case SAVAGE_PRIM_TRISTRIP: - case SAVAGE_PRIM_TRIFAN: - if (n < 3) { - DRM_ERROR - ("wrong number of indices %u in TRIFAN/STRIP\n", n); - return -EINVAL; - } - break; - default: - DRM_ERROR("invalid primitive type %u\n", prim); - return -EINVAL; - } - - if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) { - if (skip > SAVAGE_SKIP_ALL_S3D) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 8; /* full vertex */ - } else { - if (skip > SAVAGE_SKIP_ALL_S4) { - DRM_ERROR("invalid skip flags 0x%04x\n", skip); - return -EINVAL; - } - vtx_size = 10; /* full vertex */ - } - - vtx_size -= (skip & 1) + (skip >> 1 & 1) + - (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) + - (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1); - - if (vtx_size > vb_stride) { - DRM_ERROR("vertex size greater than vb stride (%u > %u)\n", - vtx_size, vb_stride); - return -EINVAL; - } - - prim <<= 25; - while (n != 0) { - /* Can emit up to 255 vertices (85 triangles) at once. */ - unsigned int count = n > 255 ? 255 : n; - - /* Check indices */ - for (i = 0; i < count; ++i) { - if (idx[i] > vb_size / (vb_stride * 4)) { - DRM_ERROR("idx[%u]=%u out of range (0-%u)\n", - i, idx[i], vb_size / (vb_stride * 4)); - return -EINVAL; - } - } - - if (reorder) { - /* Need to reorder vertices for correct flat - * shading while preserving the clock sense - * for correct culling. Only on Savage3D. */ - int reorder[3] = { 2, -1, -1 }; - - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - for (i = 0; i < count; ++i) { - unsigned int j = idx[i + reorder[i % 3]]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); - } - - DMA_COMMIT(); - } else { - BEGIN_DMA(count * vtx_size + 1); - DMA_DRAW_PRIMITIVE(count, prim, skip); - - for (i = 0; i < count; ++i) { - unsigned int j = idx[i]; - DMA_COPY(&vtxbuf[vb_stride * j], vtx_size); - } - - DMA_COMMIT(); - } - - idx += count; - n -= count; - - prim |= BCI_CMD_DRAW_CONT; - } - - return 0; -} - -static int savage_dispatch_clear(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t * cmd_header, - const drm_savage_cmd_header_t *data, - unsigned int nbox, - const struct drm_clip_rect *boxes) -{ - unsigned int flags = cmd_header->clear0.flags; - unsigned int clear_cmd; - unsigned int i, nbufs; - DMA_LOCALS; - - if (nbox == 0) - return 0; - - clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | - BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW; - BCI_CMD_SET_ROP(clear_cmd, 0xCC); - - nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) + - ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0); - if (nbufs == 0) - return 0; - - if (data->clear1.mask != 0xffffffff) { - /* set mask */ - BEGIN_DMA(2); - DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); - DMA_WRITE(data->clear1.mask); - DMA_COMMIT(); - } - for (i = 0; i < nbox; ++i) { - unsigned int x, y, w, h; - unsigned int buf; - x = boxes[i].x1, y = boxes[i].y1; - w = boxes[i].x2 - boxes[i].x1; - h = boxes[i].y2 - boxes[i].y1; - BEGIN_DMA(nbufs * 6); - for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) { - if (!(flags & buf)) - continue; - DMA_WRITE(clear_cmd); - switch (buf) { - case SAVAGE_FRONT: - DMA_WRITE(dev_priv->front_offset); - DMA_WRITE(dev_priv->front_bd); - break; - case SAVAGE_BACK: - DMA_WRITE(dev_priv->back_offset); - DMA_WRITE(dev_priv->back_bd); - break; - case SAVAGE_DEPTH: - DMA_WRITE(dev_priv->depth_offset); - DMA_WRITE(dev_priv->depth_bd); - break; - } - DMA_WRITE(data->clear1.value); - DMA_WRITE(BCI_X_Y(x, y)); - DMA_WRITE(BCI_W_H(w, h)); - } - DMA_COMMIT(); - } - if (data->clear1.mask != 0xffffffff) { - /* reset mask */ - BEGIN_DMA(2); - DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1); - DMA_WRITE(0xffffffff); - DMA_COMMIT(); - } - - return 0; -} - -static int savage_dispatch_swap(drm_savage_private_t * dev_priv, - unsigned int nbox, const struct drm_clip_rect *boxes) -{ - unsigned int swap_cmd; - unsigned int i; - DMA_LOCALS; - - if (nbox == 0) - return 0; - - swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | - BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD; - BCI_CMD_SET_ROP(swap_cmd, 0xCC); - - for (i = 0; i < nbox; ++i) { - BEGIN_DMA(6); - DMA_WRITE(swap_cmd); - DMA_WRITE(dev_priv->back_offset); - DMA_WRITE(dev_priv->back_bd); - DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); - DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1)); - DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1, - boxes[i].y2 - boxes[i].y1)); - DMA_COMMIT(); - } - - return 0; -} - -static int savage_dispatch_draw(drm_savage_private_t * dev_priv, - const drm_savage_cmd_header_t *start, - const drm_savage_cmd_header_t *end, - const struct drm_buf * dmabuf, - const unsigned int *vtxbuf, - unsigned int vb_size, unsigned int vb_stride, - unsigned int nbox, - const struct drm_clip_rect *boxes) -{ - unsigned int i, j; - int ret; - - for (i = 0; i < nbox; ++i) { - const drm_savage_cmd_header_t *cmdbuf; - dev_priv->emit_clip_rect(dev_priv, &boxes[i]); - - cmdbuf = start; - while (cmdbuf < end) { - drm_savage_cmd_header_t cmd_header; - cmd_header = *cmdbuf; - cmdbuf++; - switch (cmd_header.cmd.cmd) { - case SAVAGE_CMD_DMA_PRIM: - ret = savage_dispatch_dma_prim( - dev_priv, &cmd_header, dmabuf); - break; - case SAVAGE_CMD_VB_PRIM: - ret = savage_dispatch_vb_prim( - dev_priv, &cmd_header, - vtxbuf, vb_size, vb_stride); - break; - case SAVAGE_CMD_DMA_IDX: - j = (cmd_header.idx.count + 3) / 4; - /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_dma_idx(dev_priv, - &cmd_header, (const uint16_t *)cmdbuf, - dmabuf); - cmdbuf += j; - break; - case SAVAGE_CMD_VB_IDX: - j = (cmd_header.idx.count + 3) / 4; - /* j was check in savage_bci_cmdbuf */ - ret = savage_dispatch_vb_idx(dev_priv, - &cmd_header, (const uint16_t *)cmdbuf, - (const uint32_t *)vtxbuf, vb_size, - vb_stride); - cmdbuf += j; - break; - default: - /* What's the best return code? EFAULT? */ - DRM_ERROR("IMPLEMENTATION ERROR: " - "non-drawing-command %d\n", - cmd_header.cmd.cmd); - return -EINVAL; - } - - if (ret != 0) - return ret; - } - } - - return 0; -} - -int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - drm_savage_private_t *dev_priv = dev->dev_private; - struct drm_device_dma *dma = dev->dma; - struct drm_buf *dmabuf; - drm_savage_cmdbuf_t *cmdbuf = data; - drm_savage_cmd_header_t *kcmd_addr = NULL; - drm_savage_cmd_header_t *first_draw_cmd; - unsigned int *kvb_addr = NULL; - struct drm_clip_rect *kbox_addr = NULL; - unsigned int i, j; - int ret = 0; - - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - - if (dma && dma->buflist) { - if (cmdbuf->dma_idx > dma->buf_count) { - DRM_ERROR - ("vertex buffer index %u out of range (0-%u)\n", - cmdbuf->dma_idx, dma->buf_count - 1); - return -EINVAL; - } - dmabuf = dma->buflist[cmdbuf->dma_idx]; - } else { - dmabuf = NULL; - } - - /* Copy the user buffers into kernel temporary areas. This hasn't been - * a performance loss compared to VERIFYAREA_READ/ - * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct - * for locking on FreeBSD. - */ - if (cmdbuf->size) { - kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL); - if (kcmd_addr == NULL) - return -ENOMEM; - - if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr, - cmdbuf->size * 8)) - { - kfree(kcmd_addr); - return -EFAULT; - } - cmdbuf->cmd_addr = kcmd_addr; - } - if (cmdbuf->vb_size) { - kvb_addr = kmalloc(cmdbuf->vb_size, GFP_KERNEL); - if (kvb_addr == NULL) { - ret = -ENOMEM; - goto done; - } - - if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf->vb_addr, - cmdbuf->vb_size)) { - ret = -EFAULT; - goto done; - } - cmdbuf->vb_addr = kvb_addr; - } - if (cmdbuf->nbox) { - kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect), - GFP_KERNEL); - if (kbox_addr == NULL) { - ret = -ENOMEM; - goto done; - } - - if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf->box_addr, - cmdbuf->nbox * sizeof(struct drm_clip_rect))) { - ret = -EFAULT; - goto done; - } - cmdbuf->box_addr = kbox_addr; - } - - /* Make sure writes to DMA buffers are finished before sending - * DMA commands to the graphics hardware. */ - DRM_MEMORYBARRIER(); - - /* Coming from user space. Don't know if the Xserver has - * emitted wait commands. Assuming the worst. */ - dev_priv->waiting = 1; - - i = 0; - first_draw_cmd = NULL; - while (i < cmdbuf->size) { - drm_savage_cmd_header_t cmd_header; - cmd_header = *(drm_savage_cmd_header_t *)cmdbuf->cmd_addr; - cmdbuf->cmd_addr++; - i++; - - /* Group drawing commands with same state to minimize - * iterations over clip rects. */ - j = 0; - switch (cmd_header.cmd.cmd) { - case SAVAGE_CMD_DMA_IDX: - case SAVAGE_CMD_VB_IDX: - j = (cmd_header.idx.count + 3) / 4; - if (i + j > cmdbuf->size) { - DRM_ERROR("indexed drawing command extends " - "beyond end of command buffer\n"); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - /* fall through */ - case SAVAGE_CMD_DMA_PRIM: - case SAVAGE_CMD_VB_PRIM: - if (!first_draw_cmd) - first_draw_cmd = cmdbuf->cmd_addr - 1; - cmdbuf->cmd_addr += j; - i += j; - break; - default: - if (first_draw_cmd) { - ret = savage_dispatch_draw( - dev_priv, first_draw_cmd, - cmdbuf->cmd_addr - 1, - dmabuf, cmdbuf->vb_addr, cmdbuf->vb_size, - cmdbuf->vb_stride, - cmdbuf->nbox, cmdbuf->box_addr); - if (ret != 0) - goto done; - first_draw_cmd = NULL; - } - } - if (first_draw_cmd) - continue; - - switch (cmd_header.cmd.cmd) { - case SAVAGE_CMD_STATE: - j = (cmd_header.state.count + 1) / 2; - if (i + j > cmdbuf->size) { - DRM_ERROR("command SAVAGE_CMD_STATE extends " - "beyond end of command buffer\n"); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - ret = savage_dispatch_state(dev_priv, &cmd_header, - (const uint32_t *)cmdbuf->cmd_addr); - cmdbuf->cmd_addr += j; - i += j; - break; - case SAVAGE_CMD_CLEAR: - if (i + 1 > cmdbuf->size) { - DRM_ERROR("command SAVAGE_CMD_CLEAR extends " - "beyond end of command buffer\n"); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - ret = savage_dispatch_clear(dev_priv, &cmd_header, - cmdbuf->cmd_addr, - cmdbuf->nbox, - cmdbuf->box_addr); - cmdbuf->cmd_addr++; - i++; - break; - case SAVAGE_CMD_SWAP: - ret = savage_dispatch_swap(dev_priv, cmdbuf->nbox, - cmdbuf->box_addr); - break; - default: - DRM_ERROR("invalid command 0x%x\n", - cmd_header.cmd.cmd); - DMA_FLUSH(); - ret = -EINVAL; - goto done; - } - - if (ret != 0) { - DMA_FLUSH(); - goto done; - } - } - - if (first_draw_cmd) { - ret = savage_dispatch_draw ( - dev_priv, first_draw_cmd, cmdbuf->cmd_addr, dmabuf, - cmdbuf->vb_addr, cmdbuf->vb_size, cmdbuf->vb_stride, - cmdbuf->nbox, cmdbuf->box_addr); - if (ret != 0) { - DMA_FLUSH(); - goto done; - } - } - - DMA_FLUSH(); - - if (dmabuf && cmdbuf->discard) { - drm_savage_buf_priv_t *buf_priv = dmabuf->dev_private; - uint16_t event; - event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D); - SET_AGE(&buf_priv->age, event, dev_priv->event_wrap); - savage_freelist_put(dev, dmabuf); - } - -done: - /* If we didn't need to allocate them, these'll be NULL */ - kfree(kcmd_addr); - kfree(kvb_addr); - kfree(kbox_addr); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/gpu/drm/sis/Makefile b/ANDROID_3.4.5/drivers/gpu/drm/sis/Makefile deleted file mode 100644 index 441c061c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/sis/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the drm device driver. This driver provides support for the -# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - -ccflags-y = -Iinclude/drm -sis-y := sis_drv.o sis_mm.o - -obj-$(CONFIG_DRM_SIS) += sis.o - - diff --git a/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.c b/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.c deleted file mode 100644 index dd14cd1a..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.c +++ /dev/null @@ -1,144 +0,0 @@ -/* sis.c -- sis driver -*- linux-c -*- - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include - -#include "drmP.h" -#include "sis_drm.h" -#include "sis_drv.h" - -#include "drm_pciids.h" - -static struct pci_device_id pciidlist[] = { - sisdrv_PCI_IDS -}; - -static int sis_driver_load(struct drm_device *dev, unsigned long chipset) -{ - drm_sis_private_t *dev_priv; - - pci_set_master(dev->pdev); - - dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - idr_init(&dev_priv->object_idr); - dev->dev_private = (void *)dev_priv; - dev_priv->chipset = chipset; - - return 0; -} - -static int sis_driver_unload(struct drm_device *dev) -{ - drm_sis_private_t *dev_priv = dev->dev_private; - - idr_remove_all(&dev_priv->object_idr); - idr_destroy(&dev_priv->object_idr); - - kfree(dev_priv); - - return 0; -} - -static const struct file_operations sis_driver_fops = { - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = drm_mmap, - .poll = drm_poll, - .fasync = drm_fasync, - .llseek = noop_llseek, -}; - -static int sis_driver_open(struct drm_device *dev, struct drm_file *file) -{ - struct sis_file_private *file_priv; - - DRM_DEBUG_DRIVER("\n"); - file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); - if (!file_priv) - return -ENOMEM; - - file->driver_priv = file_priv; - - INIT_LIST_HEAD(&file_priv->obj_list); - - return 0; -} - -void sis_driver_postclose(struct drm_device *dev, struct drm_file *file) -{ - struct sis_file_private *file_priv = file->driver_priv; - - kfree(file_priv); -} - -static struct drm_driver driver = { - .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, - .load = sis_driver_load, - .unload = sis_driver_unload, - .open = sis_driver_open, - .postclose = sis_driver_postclose, - .dma_quiescent = sis_idle, - .reclaim_buffers = NULL, - .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, - .lastclose = sis_lastclose, - .ioctls = sis_ioctls, - .fops = &sis_driver_fops, - .name = DRIVER_NAME, - .desc = DRIVER_DESC, - .date = DRIVER_DATE, - .major = DRIVER_MAJOR, - .minor = DRIVER_MINOR, - .patchlevel = DRIVER_PATCHLEVEL, -}; - -static struct pci_driver sis_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, -}; - -static int __init sis_init(void) -{ - driver.num_ioctls = sis_max_ioctl; - return drm_pci_init(&driver, &sis_pci_driver); -} - -static void __exit sis_exit(void) -{ - drm_pci_exit(&driver, &sis_pci_driver); -} - -module_init(sis_init); -module_exit(sis_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.h b/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.h deleted file mode 100644 index 573758b2..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_drv.h +++ /dev/null @@ -1,76 +0,0 @@ -/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */ -/* - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef _SIS_DRV_H_ -#define _SIS_DRV_H_ - -/* General customization: - */ - -#define DRIVER_AUTHOR "SIS, Tungsten Graphics" -#define DRIVER_NAME "sis" -#define DRIVER_DESC "SIS 300/630/540 and XGI V3XE/V5/V8" -#define DRIVER_DATE "20070626" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 3 -#define DRIVER_PATCHLEVEL 0 - -enum sis_family { - SIS_OTHER = 0, - SIS_CHIP_315 = 1, -}; - -#include "drm_mm.h" - - -#define SIS_BASE (dev_priv->mmio) -#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg) -#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val) - -typedef struct drm_sis_private { - drm_local_map_t *mmio; - unsigned int idle_fault; - unsigned int chipset; - int vram_initialized; - int agp_initialized; - unsigned long vram_offset; - unsigned long agp_offset; - struct drm_mm vram_mm; - struct drm_mm agp_mm; - /** Mapping of userspace keys to mm objects */ - struct idr object_idr; -} drm_sis_private_t; - -extern int sis_idle(struct drm_device *dev); -extern void sis_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); -extern void sis_lastclose(struct drm_device *dev); - -extern struct drm_ioctl_desc sis_ioctls[]; -extern int sis_max_ioctl; - -#endif diff --git a/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_mm.c b/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_mm.c deleted file mode 100644 index dd4a316c..00000000 --- a/ANDROID_3.4.5/drivers/gpu/drm/sis/sis_mm.c +++ /dev/null @@ -1,358 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "sis_drm.h" -#include "sis_drv.h" - -#include